diff --git a/config/GZ2E01/rels/d_a_e_mb/symbols.txt b/config/GZ2E01/rels/d_a_e_mb/symbols.txt index b386dcb63e..d82e3e6c7a 100644 --- a/config/GZ2E01/rels/d_a_e_mb/symbols.txt +++ b/config/GZ2E01/rels/d_a_e_mb/symbols.txt @@ -5,8 +5,8 @@ __register_global_object = .text:0x00000078; // type:function size:0x1C scope:gl __destroy_global_chain = .text:0x00000094; // type:function size:0x58 scope:global __ct__12daE_MB_HIO_cFv = .text:0x000000EC; // type:function size:0x48 scope:global anm_init__FP10e_mb_classifUcf = .text:0x00000134; // type:function size:0xAC scope:global -daE_MB_Draw__FP10e_mb_class = .text:0x000001E0; // type:function size:0x150 scope:global -e_mb_standby__FP10e_mb_class = .text:0x00000330; // type:function size:0x26C scope:global +daE_MB_Draw__FP10e_mb_class = .text:0x000001E0; // type:function size:0x150 scope:local +e_mb_standby__FP10e_mb_class = .text:0x00000330; // type:function size:0x26C scope:local e_mb_walk1__FP10e_mb_class = .text:0x0000059C; // type:function size:0x27C scope:global __dt__4cXyzFv = .text:0x00000818; // type:function size:0x3C scope:global e_mb_move__FP10e_mb_class = .text:0x00000854; // type:function size:0x6BC scope:global @@ -14,12 +14,12 @@ e_mb_walk2__FP10e_mb_class = .text:0x00000F10; // type:function size:0x2AC scope e_mb_firstdemo__FP10e_mb_class = .text:0x000011BC; // type:function size:0x324 scope:global e_mb_end__FP10e_mb_class = .text:0x000014E0; // type:function size:0x10 scope:global action__FP10e_mb_class = .text:0x000014F0; // type:function size:0x110 scope:global -daE_MB_Execute__FP10e_mb_class = .text:0x00001600; // type:function size:0xAC8 scope:global -daE_MB_IsDelete__FP10e_mb_class = .text:0x000020C8; // type:function size:0x8 scope:global -daE_MB_Delete__FP10e_mb_class = .text:0x000020D0; // type:function size:0x68 scope:global -useHeapInit__FP10fopAc_ac_c = .text:0x00002138; // type:function size:0x384 scope:global +daE_MB_Execute__FP10e_mb_class = .text:0x00001600; // type:function size:0xAC8 scope:local +daE_MB_IsDelete__FP10e_mb_class = .text:0x000020C8; // type:function size:0x8 scope:local +daE_MB_Delete__FP10e_mb_class = .text:0x000020D0; // type:function size:0x68 scope:local +useHeapInit__FP10fopAc_ac_c = .text:0x00002138; // type:function size:0x384 scope:local __dt__12J3DFrameCtrlFv = .text:0x000024BC; // type:function size:0x48 scope:global -daE_MB_Create__FP10fopAc_ac_c = .text:0x00002504; // type:function size:0x218 scope:global +daE_MB_Create__FP10fopAc_ac_c = .text:0x00002504; // type:function size:0x218 scope:local __dt__8cM3dGSphFv = .text:0x0000271C; // type:function size:0x48 scope:global __dt__8cM3dGAabFv = .text:0x00002764; // type:function size:0x48 scope:global __dt__12daE_MB_HIO_cFv = .text:0x000027AC; // type:function size:0x48 scope:global @@ -82,7 +82,7 @@ _dtors = .dtors:0x00000000; // type:label scope:global l_color$3793 = .data:0x00000000; // type:object size:0x4 scope:local @3884 = .data:0x00000004; // type:object size:0x1C scope:local cc_sph_src$4733 = .data:0x00000020; // type:object size:0x40 scope:local -l_daE_MB_Method = .data:0x00000060; // type:object size:0x20 scope:global +l_daE_MB_Method = .data:0x00000060; // type:object size:0x20 scope:local g_profile_E_MB = .data:0x00000080; // type:object size:0x30 scope:global __vt__8cM3dGSph = .data:0x000000B0; // type:object size:0xC scope:global __vt__8cM3dGAab = .data:0x000000BC; // type:object size:0xC scope:global @@ -107,23 +107,23 @@ __global_destructor_chain = .bss:0x00000000; // type:object size:0x4 scope:globa @1012 = .bss:0x0000003C; // type:object size:0x1 scope:local @1010 = .bss:0x00000040; // type:object size:0x1 scope:local @1009 = .bss:0x00000044; // type:object size:0x1 scope:local -lbl_207_bss_45 = .bss:0x00000045; // type:object size:0x1 data:byte +lbl_207_bss_45 = .bss:0x00000045; // type:object size:0x1 scope:local data:byte @3759 = .bss:0x00000048; // type:object size:0xC scope:local -l_HIO = .bss:0x00000054; // type:object size:0x1C scope:global data:byte +l_HIO = .bss:0x00000054; // type:object size:0x1C scope:local data:byte @3824 = .bss:0x00000070; // type:object size:0xC scope:local -L_pos1 = .bss:0x0000007C; // type:object size:0xC scope:global +L_pos1 = .bss:0x0000007C; // type:object size:0xC scope:local @3825 = .bss:0x00000088; // type:object size:0xC scope:local -L_pos2 = .bss:0x00000094; // type:object size:0xC scope:global data:float +L_pos2 = .bss:0x00000094; // type:object size:0xC scope:local data:float @3826 = .bss:0x000000A0; // type:object size:0xC scope:local -L_Hpos = .bss:0x000000AC; // type:object size:0xC scope:global +L_Hpos = .bss:0x000000AC; // type:object size:0xC scope:local @3827 = .bss:0x000000B8; // type:object size:0xC scope:local -R_pos1 = .bss:0x000000C4; // type:object size:0xC scope:global +R_pos1 = .bss:0x000000C4; // type:object size:0xC scope:local @3828 = .bss:0x000000D0; // type:object size:0xC scope:local -R_pos2 = .bss:0x000000DC; // type:object size:0xC scope:global data:float +R_pos2 = .bss:0x000000DC; // type:object size:0xC scope:local data:float @3829 = .bss:0x000000E8; // type:object size:0xC scope:local -R_Hpos = .bss:0x000000F4; // type:object size:0xC scope:global +R_Hpos = .bss:0x000000F4; // type:object size:0xC scope:local @3830 = .bss:0x00000100; // type:object size:0xC scope:local -c_pos = .bss:0x0000010C; // type:object size:0xC scope:global +c_pos = .bss:0x0000010C; // type:object size:0xC scope:local sInstance__40JASGlobalInstance<19JASDefaultBankTable> = .bss:0x00000118; // type:object size:0x4 scope:global sInstance__35JASGlobalInstance<14JASAudioThread> = .bss:0x0000011C; // type:object size:0x4 scope:global sInstance__27JASGlobalInstance<7Z2SeMgr> = .bss:0x00000120; // type:object size:0x4 scope:global diff --git a/config/GZ2E01/splits.txt b/config/GZ2E01/splits.txt index 1adfa5bf15..f7b512d914 100644 --- a/config/GZ2E01/splits.txt +++ b/config/GZ2E01/splits.txt @@ -2338,7 +2338,7 @@ Z2AudioLib/Z2AudioMgr.cpp: dolphin/gf/GFGeometry.cpp: .text start:0x802CDDC8 end:0x802CDE54 - .sdata start:0x804508A8 end:0x804508B8 + .sdata start:0x804508A8 end:0x804508B0 dolphin/gf/GFLight.cpp: .text start:0x802CDE54 end:0x802CDE9C @@ -2354,6 +2354,7 @@ JSystem/JKernel/JKRHeap.cpp: .text start:0x802CE138 end:0x802CEDB4 .rodata start:0x8039CAD8 end:0x8039CAF0 .data start:0x803CBF70 end:0x803CBFD0 + .sdata start:0x804508B0 end:0x804508B8 .sbss start:0x80451370 end:0x80451398 JSystem/JKernel/JKRExpHeap.cpp: diff --git a/configure.py b/configure.py index 3a6955dc9d..cfff19ee80 100755 --- a/configure.py +++ b/configure.py @@ -201,6 +201,7 @@ cflags_base = [ "-i include", f"-i build/{config.version}/include", "-i src", + "-ir src/dolphin", "-i src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include", "-i src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Include", "-i src/PowerPC_EABI_Support/MSL/MSL_C/PPC_EABI/Include", @@ -209,6 +210,7 @@ cflags_base = [ "-i src/PowerPC_EABI_Support/MetroTRK", "-Iinclude/dolphin", f"-DVERSION={version_num}", + "-D__GEKKO__", ] if config.version == "ShieldD": @@ -262,10 +264,33 @@ cflags_trk = [ # Dolphin library flags cflags_dolphin = [ - *cflags_base, - "-use_lmw_stmw on", - "-str reuse,pool,readonly", + "-nodefaults", + "-proc gekko", + "-align powerpc", + "-enum int", + "-fp hardware", + "-Cpp_exceptions off", + '-pragma "cats off"', + '-pragma "warn_notinlined off"', + "-maxerrors 1", + "-nosyspath", + "-char unsigned", + "-O4,p", + "-sym on", "-inline auto", + "-i include", + f"-i build/{config.version}/include", + "-ir src/dolphin", + "-i src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include", + "-i src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Include", + "-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", + "-Iinclude/dolphin", + f"-DVERSION={version_num}", + "-D__GEKKO__", + "-DSDK_REVISION=2", ] # Framework flags @@ -309,7 +334,7 @@ def DolphinLib(lib_name: str, objects: List[Object]) -> Dict[str, Any]: return { "lib": lib_name, "mw_version": "GC/1.2.5n", - "cflags": cflags_base, + "cflags": cflags_dolphin, "progress_category": "sdk", "objects": objects, } @@ -899,7 +924,7 @@ config.libs = [ "cflags": cflags_noopt, "progress_category": "sdk", "objects": [ - Object(NonMatching, "dolphin/gf/GFGeometry.cpp", extra_cflags=["-O3"]), + Object(MatchingFor("GZ2E01"), "dolphin/gf/GFGeometry.cpp", extra_cflags=["-O3"]), Object(MatchingFor("GZ2E01"), "dolphin/gf/GFLight.cpp", extra_cflags=["-O3"]), Object(MatchingFor("GZ2E01"), "dolphin/gf/GFPixel.cpp", extra_cflags=["-O3"]), Object(MatchingFor("GZ2E01"), "dolphin/gf/GFTev.cpp", extra_cflags=["-O3"]), @@ -1135,24 +1160,24 @@ config.libs = [ DolphinLib( "mtx", [ - Object(MatchingFor("GZ2E01"), "dolphin/mtx/mtx.c", extra_cflags=["-fp_contract off"]), + Object(MatchingFor("GZ2E01"), "dolphin/mtx/mtx.c", extra_cflags=["-char signed"]), Object(MatchingFor("GZ2E01"), "dolphin/mtx/mtxvec.c"), - Object(MatchingFor("GZ2E01"), "dolphin/mtx/mtx44.c"), - Object(MatchingFor("GZ2E01"), "dolphin/mtx/vec.c", extra_cflags=["-fp_contract off"]), - Object(MatchingFor("GZ2E01"), "dolphin/mtx/quat.c", extra_cflags=["-fp_contract off"]), + Object(MatchingFor("GZ2E01"), "dolphin/mtx/mtx44.c", extra_cflags=["-char signed"]), + Object(MatchingFor("GZ2E01"), "dolphin/mtx/vec.c"), + Object(MatchingFor("GZ2E01"), "dolphin/mtx/quat.c"), ], ), DolphinLib( "dvd", [ - Object(MatchingFor("GZ2E01"), "dolphin/dvd/dvdlow.c"), - Object(MatchingFor("GZ2E01"), "dolphin/dvd/dvdfs.c"), - Object(MatchingFor("GZ2E01"), "dolphin/dvd/dvd.c"), - Object(MatchingFor("GZ2E01"), "dolphin/dvd/dvdqueue.c"), - Object(MatchingFor("GZ2E01"), "dolphin/dvd/dvderror.c"), - Object(MatchingFor("GZ2E01"), "dolphin/dvd/dvdidutils.c"), - Object(MatchingFor("GZ2E01"), "dolphin/dvd/dvdFatal.c"), - Object(MatchingFor("GZ2E01"), "dolphin/dvd/fstload.c"), + Object(MatchingFor("GZ2E01"), "dolphin/dvd/dvdlow.c", extra_cflags=["-char signed"]), + Object(MatchingFor("GZ2E01"), "dolphin/dvd/dvdfs.c", extra_cflags=["-char signed"]), + Object(MatchingFor("GZ2E01"), "dolphin/dvd/dvd.c", extra_cflags=["-char signed"]), + Object(MatchingFor("GZ2E01"), "dolphin/dvd/dvdqueue.c", extra_cflags=["-char signed"]), + Object(MatchingFor("GZ2E01"), "dolphin/dvd/dvderror.c", extra_cflags=["-char signed"]), + Object(MatchingFor("GZ2E01"), "dolphin/dvd/dvdidutils.c", extra_cflags=["-char signed"]), + Object(MatchingFor("GZ2E01"), "dolphin/dvd/dvdFatal.c", extra_cflags=["-char signed"]), + Object(MatchingFor("GZ2E01"), "dolphin/dvd/fstload.c", extra_cflags=["-char signed"]), ], ), DolphinLib( @@ -1164,8 +1189,8 @@ config.libs = [ DolphinLib( "pad", [ - Object(MatchingFor("GZ2E01"), "dolphin/pad/Padclamp.c", extra_cflags=["-fp_contract off"]), - Object(MatchingFor("GZ2E01"), "dolphin/pad/Pad.c", extra_cflags=["-inline noauto"]), + Object(MatchingFor("GZ2E01"), "dolphin/pad/Padclamp.c"), + Object(MatchingFor("GZ2E01"), "dolphin/pad/Pad.c"), ], ), DolphinLib( @@ -1200,7 +1225,7 @@ config.libs = [ Object(MatchingFor("GZ2E01"), "dolphin/card/CARDCheck.c"), Object(MatchingFor("GZ2E01"), "dolphin/card/CARDMount.c"), Object(MatchingFor("GZ2E01"), "dolphin/card/CARDFormat.c"), - Object(MatchingFor("GZ2E01"), "dolphin/card/CARDOpen.c", extra_cflags=["-inline noauto"]), + Object(MatchingFor("GZ2E01"), "dolphin/card/CARDOpen.c", extra_cflags=["-char signed"]), Object(MatchingFor("GZ2E01"), "dolphin/card/CARDCreate.c"), Object(MatchingFor("GZ2E01"), "dolphin/card/CARDRead.c"), Object(MatchingFor("GZ2E01"), "dolphin/card/CARDWrite.c"), @@ -1543,7 +1568,7 @@ config.libs = [ ActorRel(NonMatching, "d_a_L7demo_dr"), ActorRel(NonMatching, "d_a_L7low_dr"), ActorRel(NonMatching, "d_a_L7op_demo_dr"), - ActorRel(NonMatching, "d_a_b_bh"), + ActorRel(MatchingFor("GZ2E01"), "d_a_b_bh"), ActorRel(NonMatching, "d_a_b_bq"), ActorRel(NonMatching, "d_a_b_dr"), ActorRel(Equivalent, "d_a_b_dre"), # weak func order @@ -1612,7 +1637,7 @@ config.libs = [ ActorRel(NonMatching, "d_a_e_kg"), ActorRel(NonMatching, "d_a_e_kk"), ActorRel(NonMatching, "d_a_e_kr"), - ActorRel(NonMatching, "d_a_e_mb"), + ActorRel(MatchingFor("GZ2E01"), "d_a_e_mb"), ActorRel(NonMatching, "d_a_e_md"), ActorRel(NonMatching, "d_a_e_mf"), ActorRel(NonMatching, "d_a_e_mk"), diff --git a/include/JSystem/J2DGraph/J2DPane.h b/include/JSystem/J2DGraph/J2DPane.h index 61989f4f58..1278e455a9 100644 --- a/include/JSystem/J2DGraph/J2DPane.h +++ b/include/JSystem/J2DGraph/J2DPane.h @@ -3,7 +3,7 @@ #include "JSystem/JGeometry.h" #include "JSystem/JSupport/JSUList.h" -#include "dolphin/gx/GXEnum.h" +#include #include "dolphin/mtx.h" class J2DAnmBase; diff --git a/include/JSystem/J2DGraph/J2DTevs.h b/include/JSystem/J2DGraph/J2DTevs.h index 3b91bf4e62..a1c31301f9 100644 --- a/include/JSystem/J2DGraph/J2DTevs.h +++ b/include/JSystem/J2DGraph/J2DTevs.h @@ -1,7 +1,7 @@ #ifndef J2DTEVS_H #define J2DTEVS_H -#include "dolphin/gx/GXStruct.h" +#include #include "dolphin/mtx.h" /** diff --git a/include/JSystem/J3DGraphAnimator/J3DAnimation.h b/include/JSystem/J3DGraphAnimator/J3DAnimation.h index 7f21d3d1fe..493da73dd3 100644 --- a/include/JSystem/J3DGraphAnimator/J3DAnimation.h +++ b/include/JSystem/J3DGraphAnimator/J3DAnimation.h @@ -3,6 +3,7 @@ #include "JSystem/J3DGraphAnimator/J3DModelData.h" #include "JSystem/JUtility/JUTNameTab.h" +#include "global.h" struct JUTDataBlockHeader { /* 0x0 */ u32 mType; diff --git a/include/JSystem/J3DGraphBase/J3DGD.h b/include/JSystem/J3DGraphBase/J3DGD.h index eef2b7b223..854cecef65 100644 --- a/include/JSystem/J3DGraphBase/J3DGD.h +++ b/include/JSystem/J3DGraphBase/J3DGD.h @@ -1,6 +1,7 @@ #ifndef J3DGD_H #define J3DGD_H +#include #include "dolphin/gd/GDBase.h" inline void J3DGDWrite_u8(u8 param) { @@ -116,7 +117,7 @@ inline void J3DGDSetNumTexGens(u8 numTexGens) { J3DGDWriteXFCmd(0x103f, numTexGens); } -inline void J3DGDSetTevKonstantSel_SwapModeTable(GXTevStageID stage, GXTevKColorSel colorSel1, GXTevKAlphaSel alphaSel1, GXTevKColorSel colorSel2, GXTevKAlphaSel alphaSel2, GXTevColor chan1, GXTevColor chan2) { +inline void J3DGDSetTevKonstantSel_SwapModeTable(GXTevStageID stage, GXTevKColorSel colorSel1, GXTevKAlphaSel alphaSel1, GXTevKColorSel colorSel2, GXTevKAlphaSel alphaSel2, GXTevColorChan chan1, GXTevColorChan chan2) { J3DGDWriteBPCmd((stage / 2 + 0xf6) << 24 | (chan1 | chan2 << 2 | colorSel1 << 4 | alphaSel1 << 9 | colorSel2 << 14 | alphaSel2 << 19) & 0x00FFFFFF); } diff --git a/include/JSystem/J3DGraphBase/J3DShape.h b/include/JSystem/J3DGraphBase/J3DShape.h index 91e9b4484a..467ac67a0d 100644 --- a/include/JSystem/J3DGraphBase/J3DShape.h +++ b/include/JSystem/J3DGraphBase/J3DShape.h @@ -16,13 +16,13 @@ public: }; static inline void J3DFifoWriteCPCmd(u8 cmd, u32 param) { - GXWGFifo.u8 = GX_CMD_LOAD_CP_REG; + GXWGFifo.u8 = GX_LOAD_CP_REG; GXWGFifo.u8 = cmd; GXWGFifo.u32 = param; } static inline void J3DFifoWriteXFCmd(u16 cmd, u16 len) { - GXWGFifo.u8 = GX_CMD_LOAD_XF_REG; + GXWGFifo.u8 = GX_LOAD_XF_REG; GXWGFifo.u16 = (len - 1); GXWGFifo.u16 = cmd; } diff --git a/include/JSystem/J3DGraphBase/J3DStruct.h b/include/JSystem/J3DGraphBase/J3DStruct.h index 29fd75b208..4e483ddb11 100644 --- a/include/JSystem/J3DGraphBase/J3DStruct.h +++ b/include/JSystem/J3DGraphBase/J3DStruct.h @@ -1,9 +1,9 @@ #ifndef J3DSTRUCT_H #define J3DSTRUCT_H -#include "dolphin/gx/GXStruct.h" +#include +#include "dolphin/mtx.h" #include "dolphin/mtx.h" -#include "dolphin/mtx/vec.h" /** * @ingroup jsystem-j3d diff --git a/include/JSystem/J3DGraphBase/J3DSys.h b/include/JSystem/J3DGraphBase/J3DSys.h index 2a2f667109..421abc603f 100644 --- a/include/JSystem/J3DGraphBase/J3DSys.h +++ b/include/JSystem/J3DGraphBase/J3DSys.h @@ -1,7 +1,8 @@ #ifndef J3DSYS_H #define J3DSYS_H -#include "dolphin/gx.h" +#include +#include // Perhaps move to a new J3DEnum.h? enum J3DError { diff --git a/include/JSystem/J3DGraphBase/J3DTevs.h b/include/JSystem/J3DGraphBase/J3DTevs.h index f25c0a1a11..176c0a6a20 100644 --- a/include/JSystem/J3DGraphBase/J3DTevs.h +++ b/include/JSystem/J3DGraphBase/J3DTevs.h @@ -2,7 +2,7 @@ #define J3DTEVS_H #include "dolphin/types.h" -#include "dolphin/gx/GXStruct.h" +#include #include "JSystem/J3DGraphBase/J3DGD.h" /** diff --git a/include/JSystem/J3DGraphBase/J3DTransform.h b/include/JSystem/J3DGraphBase/J3DTransform.h index 28b79d8a9a..384e132385 100644 --- a/include/JSystem/J3DGraphBase/J3DTransform.h +++ b/include/JSystem/J3DGraphBase/J3DTransform.h @@ -13,7 +13,7 @@ struct J3DTextureSRTInfo; struct J3DTransformInfo { /* 0x00 */ Vec mScale; - /* 0x0C */ SVec mRotation; + /* 0x0C */ S16Vec mRotation; /* 0x14 */ Vec mTranslate; /* inline J3DTransformInfo& operator=(const J3DTransformInfo& b) { @@ -162,7 +162,7 @@ inline void J3DPSMulMtxVec(register MtxP mtx, register Vec* vec, register Vec* d } // regalloc issues -inline void J3DPSMulMtxVec(register MtxP mtx, register SVec* vec, register SVec* dst) { +inline void J3DPSMulMtxVec(register MtxP mtx, register S16Vec* vec, register S16Vec* dst) { register f32 fr12; register f32 fr11; register f32 fr10; @@ -252,7 +252,7 @@ inline void J3DPSMulMtxVec(register Mtx3P mtx, register Vec* vec, register Vec* } // regalloc issues -inline void J3DPSMulMtxVec(register Mtx3P mtx, register SVec* vec, register SVec* dst) { +inline void J3DPSMulMtxVec(register Mtx3P mtx, register S16Vec* vec, register S16Vec* dst) { register f32* punit; register f32 unit; register f32 fr6; diff --git a/include/JSystem/J3DGraphBase/J3DVertex.h b/include/JSystem/J3DGraphBase/J3DVertex.h index f100736965..ccc247c0dd 100644 --- a/include/JSystem/J3DGraphBase/J3DVertex.h +++ b/include/JSystem/J3DGraphBase/J3DVertex.h @@ -1,8 +1,8 @@ #ifndef J3DVERTEX_H #define J3DVERTEX_H -#include "dolphin/gx/GXAttr.h" -#include "dolphin/mtx/vec.h" +#include +#include "dolphin/mtx.h" typedef struct _GXColor GXColor; class J3DModel; diff --git a/include/JSystem/J3DGraphLoader/J3DMaterialFactory.h b/include/JSystem/J3DGraphLoader/J3DMaterialFactory.h index 99e5edc7d5..f871acfced 100644 --- a/include/JSystem/J3DGraphLoader/J3DMaterialFactory.h +++ b/include/JSystem/J3DGraphLoader/J3DMaterialFactory.h @@ -3,7 +3,7 @@ #include "JSystem/J3DGraphBase/J3DMatBlock.h" #include "JSystem/J3DGraphLoader/J3DModelLoader.h" -#include "dolphin/gx/GXStruct.h" +#include class J3DMaterial; diff --git a/include/JSystem/J3DGraphLoader/J3DMaterialFactory_v21.h b/include/JSystem/J3DGraphLoader/J3DMaterialFactory_v21.h index a2dc9c8f42..7a95300953 100644 --- a/include/JSystem/J3DGraphLoader/J3DMaterialFactory_v21.h +++ b/include/JSystem/J3DGraphLoader/J3DMaterialFactory_v21.h @@ -3,7 +3,7 @@ #include "JSystem/J3DGraphBase/J3DMatBlock.h" #include "JSystem/J3DGraphLoader/J3DModelLoader.h" -#include "dolphin/gx/GXStruct.h" +#include class J3DMaterial; struct J3DTexCoord2Info; diff --git a/include/JSystem/J3DGraphLoader/J3DShapeFactory.h b/include/JSystem/J3DGraphLoader/J3DShapeFactory.h index 47ab5f6991..4887730363 100644 --- a/include/JSystem/J3DGraphLoader/J3DShapeFactory.h +++ b/include/JSystem/J3DGraphLoader/J3DShapeFactory.h @@ -2,7 +2,7 @@ #define J3DSHAPEFACTORY_H #include "JSystem/J3DGraphLoader/J3DModelLoader.h" -#include "dolphin/gx/GXAttr.h" +#include class J3DShape; class J3DShapeMtx; @@ -74,4 +74,4 @@ struct J3DShapeFactory { }; -#endif /* J3DSHAPEFACTORY_H */ \ No newline at end of file +#endif /* J3DSHAPEFACTORY_H */ diff --git a/include/JSystem/JAudio2/JASChannel.h b/include/JSystem/JAudio2/JASChannel.h index 54e5201ab1..6e721a11a2 100644 --- a/include/JSystem/JAudio2/JASChannel.h +++ b/include/JSystem/JAudio2/JASChannel.h @@ -6,7 +6,7 @@ #include "JSystem/JAudio2/JASOscillator.h" #include "JSystem/JAudio2/JASSoundParams.h" #include "JSystem/JAudio2/JASWaveInfo.h" -#include "dolphin/os/OSMessage.h" +#include class JASDSPChannel; diff --git a/include/JSystem/JAudio2/JASCriticalSection.h b/include/JSystem/JAudio2/JASCriticalSection.h index d737eb79a6..44f5f21f4a 100644 --- a/include/JSystem/JAudio2/JASCriticalSection.h +++ b/include/JSystem/JAudio2/JASCriticalSection.h @@ -1,7 +1,7 @@ #ifndef JASCRITICALSECTION_H #define JASCRITICALSECTION_H -#include "dolphin/os/OSInterrupt.h" +#include /** * @ingroup jsystem-jaudio diff --git a/include/JSystem/JAudio2/JASHeapCtrl.h b/include/JSystem/JAudio2/JASHeapCtrl.h index 5eae318da5..a2bd2d056a 100644 --- a/include/JSystem/JAudio2/JASHeapCtrl.h +++ b/include/JSystem/JAudio2/JASHeapCtrl.h @@ -3,8 +3,8 @@ #include "JSystem/JKernel/JKRHeap.h" #include "JSystem/JSupport/JSUList.h" -#include "dolphin/os/OSInterrupt.h" -#include "dolphin/os/OSMutex.h" +#include +#include class JASDisposer; class JKRHeap; diff --git a/include/JSystem/JAudio2/JASMutex.h b/include/JSystem/JAudio2/JASMutex.h index b8c21c35fa..5134534361 100644 --- a/include/JSystem/JAudio2/JASMutex.h +++ b/include/JSystem/JAudio2/JASMutex.h @@ -1,7 +1,7 @@ #ifndef JASMUTEX_H #define JASMUTEX_H -#include "dolphin/os/OSMutex.h" +#include /** * @ingroup jsystem-jaudio diff --git a/include/JSystem/JAudio2/JASResArcLoader.h b/include/JSystem/JAudio2/JASResArcLoader.h index 9f247a0f95..7d745a00e9 100644 --- a/include/JSystem/JAudio2/JASResArcLoader.h +++ b/include/JSystem/JAudio2/JASResArcLoader.h @@ -2,6 +2,7 @@ #define JASRESARCLOADER_H #include "JSystem/JKernel/JKRArchive.h" +#include namespace JASResArcLoader { /* 80290BD0 */ size_t getResSize(JKRArchive const*, u16); @@ -10,7 +11,6 @@ namespace JASResArcLoader { /* 80290D18 */ int loadResourceAsync(JKRArchive*, u16, u8*, u32, void (*)(u32, u32), u32); }; -typedef struct OSMessageQueue OSMessageQueue; class JKRArchive; // from pikmin2 diff --git a/include/JSystem/JAudio2/JASWaveArcLoader.h b/include/JSystem/JAudio2/JASWaveArcLoader.h index c16721bb74..9536e12400 100644 --- a/include/JSystem/JAudio2/JASWaveArcLoader.h +++ b/include/JSystem/JAudio2/JASWaveArcLoader.h @@ -3,7 +3,7 @@ #include "JSystem/JAudio2/JASHeapCtrl.h" #include "dol2asm.h" -#include "dolphin/os/OSMutex.h" +#include class JKRHeap; class JKRSolidHeap; diff --git a/include/JSystem/JAudio2/osdsp.h b/include/JSystem/JAudio2/osdsp.h index a7aefab3c8..7c3c91d0a3 100644 --- a/include/JSystem/JAudio2/osdsp.h +++ b/include/JSystem/JAudio2/osdsp.h @@ -1,11 +1,7 @@ #ifndef OSDSP_H #define OSDSP_H -#include "dolphin/dsp.h" - -struct STRUCT_DSP_TASK { - /* 0x00 */ DSPTaskInfo info; -}; +#include extern "C" DSPTaskInfo* DSPAddTask(DSPTaskInfo*); void DSPAddPriorTask(STRUCT_DSP_TASK*); diff --git a/include/JSystem/JAudio2/osdsp_task.h b/include/JSystem/JAudio2/osdsp_task.h index 3252dadd65..6c662b50a3 100644 --- a/include/JSystem/JAudio2/osdsp_task.h +++ b/include/JSystem/JAudio2/osdsp_task.h @@ -1,9 +1,7 @@ #ifndef OSDSP_TASK_H #define OSDSP_TASK_H -#include "dolphin/dsp.h" - -struct DSPTaskInfo; +#include extern DSPTaskInfo* DSP_prior_task; diff --git a/include/JSystem/JFramework/JFWDisplay.h b/include/JSystem/JFramework/JFWDisplay.h index 69ae5bfc37..cb43d8e07e 100644 --- a/include/JSystem/JFramework/JFWDisplay.h +++ b/include/JSystem/JFramework/JFWDisplay.h @@ -5,7 +5,7 @@ #include "JSystem/JUtility/JUTDirectPrint.h" #include "JSystem/JUtility/JUTFader.h" #include "JSystem/JUtility/JUTXfb.h" -#include "dolphin/os/OSAlarm.h" +#include typedef struct _GXColor GXColor; typedef struct _GXRenderModeObj GXRenderModeObj; diff --git a/include/JSystem/JGeometry.h b/include/JSystem/JGeometry.h index 281f7d5b40..a34ec2b705 100644 --- a/include/JSystem/JGeometry.h +++ b/include/JSystem/JGeometry.h @@ -1,7 +1,7 @@ #ifndef JGEOMETRY_H #define JGEOMETRY_H -#include "dolphin/mtx/vec.h" +#include "dolphin/mtx.h" #include "math.h" #include "JSystem/JMath/JMath.h" @@ -175,7 +175,7 @@ struct TVec3 : public Vec { } inline void add(const TVec3& b) { - C_VECAdd((Vec*)&x, (Vec*)&b.x, (Vec*)&x); + JMathInlineVEC::C_VECAdd((Vec*)&x, (Vec*)&b.x, (Vec*)&x); } void zero() { x = y = z = 0.0f; } @@ -236,7 +236,7 @@ struct TVec3 : public Vec { // } f32 squared() const { - return C_VECSquareMag((Vec*)&x); + return JMathInlineVEC::C_VECSquareMag((Vec*)&x); } void normalize() { @@ -333,11 +333,11 @@ struct TVec3 : public Vec { } void sub(const TVec3& b) { - C_VECSubtract((Vec*)&x, (Vec*)&b.x, (Vec*)&x); + JMathInlineVEC::C_VECSubtract((Vec*)&x, (Vec*)&b.x, (Vec*)&x); } void sub(const TVec3& a, const TVec3& b) { - C_VECSubtract((Vec*)&a.x, (Vec*)&b.x, (Vec*)&x); + JMathInlineVEC::C_VECSubtract((Vec*)&a.x, (Vec*)&b.x, (Vec*)&x); } bool isZero() const { diff --git a/include/JSystem/JKernel/JKRAramHeap.h b/include/JSystem/JKernel/JKRAramHeap.h index 44f3b10d58..14f786a21f 100644 --- a/include/JSystem/JKernel/JKRAramHeap.h +++ b/include/JSystem/JKernel/JKRAramHeap.h @@ -3,7 +3,7 @@ #include "JSystem/JKernel/JKRAramBlock.h" #include "JSystem/JKernel/JKRDisposer.h" -#include "dolphin/os/OSMutex.h" +#include /** * @ingroup jsystem-jkernel diff --git a/include/JSystem/JKernel/JKRAramPiece.h b/include/JSystem/JKernel/JKRAramPiece.h index 9c1d2d2fb4..a75f63adef 100644 --- a/include/JSystem/JKernel/JKRAramPiece.h +++ b/include/JSystem/JKernel/JKRAramPiece.h @@ -2,9 +2,9 @@ #define JKRARAMPIECE_H #include "JSystem/JSupport/JSUList.h" -#include "dolphin/arq.h" -#include "dolphin/os/OSMessage.h" -#include "dolphin/os/OSMutex.h" +#include +#include +#include class JKRAramBlock; class JKRDecompCommand; diff --git a/include/JSystem/JKernel/JKRDvdFile.h b/include/JSystem/JKernel/JKRDvdFile.h index 8a4eafafbe..faf5120097 100644 --- a/include/JSystem/JKernel/JKRDvdFile.h +++ b/include/JSystem/JKernel/JKRDvdFile.h @@ -3,8 +3,8 @@ #include "JSystem/JKernel/JKRFile.h" #include "dolphin/dvd.h" -#include "dolphin/os/OSMessage.h" -#include "dolphin/os/OSMutex.h" +#include +#include struct OSThread; @@ -26,9 +26,9 @@ public: void initiate(void); s32 sync(void); - u32 getFileID() const { return mFileInfo.start_address; } + u32 getFileID() const { return mFileInfo.startAddr; } DVDFileInfo* getFileInfo() { return &mFileInfo; } - int getStatus() { return DVDGetCommandBlockStatus(&mFileInfo.block); } + int getStatus() { return DVDGetCommandBlockStatus(&mFileInfo.cb); } public: /* vt[03] */ virtual bool open(const char*); /* override */ diff --git a/include/JSystem/JKernel/JKRFileFinder.h b/include/JSystem/JKernel/JKRFileFinder.h index 961b7eab48..24af7c7027 100644 --- a/include/JSystem/JKernel/JKRFileFinder.h +++ b/include/JSystem/JKernel/JKRFileFinder.h @@ -69,7 +69,7 @@ private: /* 0x00 */ // JKRFileFinder_UnknownBase /* 0x0C */ // vtable /* 0x10 */ // JKRFileFinder - /* 0x14 */ DVDDirectory mDvdDirectory; + /* 0x14 */ DVDDir mDvdDirectory; /* 0x20 */ bool mDvdIsOpen; /* 0x21 */ u8 field_0x21[3]; }; diff --git a/include/JSystem/JKernel/JKRHeap.h b/include/JSystem/JKernel/JKRHeap.h index 7764c5baf8..f18fa60b31 100644 --- a/include/JSystem/JKernel/JKRHeap.h +++ b/include/JSystem/JKernel/JKRHeap.h @@ -2,7 +2,7 @@ #define JKRHEAP_H #include "JSystem/JKernel/JKRDisposer.h" -#include "dolphin/os/OSMutex.h" +#include class JKRHeap; typedef void (*JKRErrorHandler)(void*, u32, int); diff --git a/include/JSystem/JKernel/JKRThread.h b/include/JSystem/JKernel/JKRThread.h index d5d2136594..83f837b585 100644 --- a/include/JSystem/JKernel/JKRThread.h +++ b/include/JSystem/JKernel/JKRThread.h @@ -2,8 +2,8 @@ #define JKRTHREAD_H #include "JSystem/JKernel/JKRHeap.h" -#include "dolphin/os/OSMessage.h" -#include "dolphin/os/OSTime.h" +#include +#include /** * @ingroup jsystem-jkernel diff --git a/include/JSystem/JMath/JMath.h b/include/JSystem/JMath/JMath.h index 0968feed00..2c4cd35b29 100644 --- a/include/JSystem/JMath/JMath.h +++ b/include/JSystem/JMath/JMath.h @@ -171,4 +171,63 @@ inline void gekko_ps_copy16(register void* dst, register const void* src) { }; // namespace JMath +namespace JMathInlineVEC { + inline void C_VECAdd(register const Vec* a, register const Vec* b, register Vec* ab) { + register f32 axy; + register f32 bxy; + register f32 az; + register f32 sumz; + register f32 bz; + #ifdef __MWERKS__ + asm { + psq_l axy, 0(a), 0, 0 + psq_l bxy, 0(b), 0, 0 + ps_add bxy, axy, bxy + psq_st bxy, 0(ab), 0, 0 + psq_l az, 8(a), 1, 0 + psq_l bz, 8(b), 1, 0 + ps_add sumz, az, bz + psq_st sumz, 8(ab), 1, 0 + } + #endif + } + + inline void C_VECSubtract(register const Vec* a, register const Vec* b, register Vec* ab) { + register f32 axy; + register f32 bxy; + register f32 az; + register f32 subz; + register f32 bz; + #ifdef __MWERKS__ + asm { + psq_l axy, 0(a), 0, 0 + psq_l bxy, 0(b), 0, 0 + ps_sub bxy, axy, bxy + psq_st bxy, 0(ab), 0, 0 + psq_l az, 8(a), 1, 0 + psq_l bz, 8(b), 1, 0 + ps_sub subz, az, bz + psq_st subz, 8(ab), 1, 0 + } + #endif + } + + inline f32 C_VECSquareMag(const Vec* v) { + register f32 x_y; + register f32 z; + register f32 res; + register const f32* src = &v->x; + #ifdef __MWERKS__ + asm { + psq_l x_y, 0(src), 0, 0 + ps_mul x_y, x_y, x_y + lfs z, 8(src) + ps_madd res, z, z, x_y + ps_sum0 res, res, x_y, x_y + } + #endif + return res; + } +}; + #endif /* JMATH_H */ diff --git a/include/JSystem/JParticle/JPABaseShape.h b/include/JSystem/JParticle/JPABaseShape.h index 9f72c68a33..3ce4f3d2e7 100644 --- a/include/JSystem/JParticle/JPABaseShape.h +++ b/include/JSystem/JParticle/JPABaseShape.h @@ -1,7 +1,7 @@ #ifndef JPABASESHAPE_H #define JPABASESHAPE_H -#include "dolphin/gx/GXStruct.h" +#include class JPAEmitterWorkData; class JPABaseParticle; diff --git a/include/JSystem/JParticle/JPAChildShape.h b/include/JSystem/JParticle/JPAChildShape.h index 899cde4d18..2761a56759 100644 --- a/include/JSystem/JParticle/JPAChildShape.h +++ b/include/JSystem/JParticle/JPAChildShape.h @@ -1,7 +1,7 @@ #ifndef JPACHILDSHAPE_H #define JPACHILDSHAPE_H -#include "dolphin/gx/GXStruct.h" +#include class JPAEmitterWorkData; class JPABaseParticle; diff --git a/include/JSystem/JParticle/JPAEmitter.h b/include/JSystem/JParticle/JPAEmitter.h index 697cf042bf..ac693c1325 100644 --- a/include/JSystem/JParticle/JPAEmitter.h +++ b/include/JSystem/JParticle/JPAEmitter.h @@ -1,7 +1,7 @@ #ifndef JPAEMITTER_H #define JPAEMITTER_H -#include "dolphin/gx/GXStruct.h" +#include #include "JSystem/JParticle/JPAResource.h" #include "JSystem/JParticle/JPAList.h" #include "JSystem/JParticle/JPARandom.h" diff --git a/include/JSystem/JParticle/JPAParticle.h b/include/JSystem/JParticle/JPAParticle.h index c02b11fc93..26cb4830f2 100644 --- a/include/JSystem/JParticle/JPAParticle.h +++ b/include/JSystem/JParticle/JPAParticle.h @@ -1,7 +1,7 @@ #ifndef JPAPARTICLE_H #define JPAPARTICLE_H -#include "dolphin/gx/GXStruct.h" +#include #include "JSystem/JGeometry.h" class JKRHeap; diff --git a/include/JSystem/JStage/JSGAmbientLight.h b/include/JSystem/JStage/JSGAmbientLight.h index 1a764b5de3..08d8bba82a 100644 --- a/include/JSystem/JStage/JSGAmbientLight.h +++ b/include/JSystem/JStage/JSGAmbientLight.h @@ -2,7 +2,7 @@ #define JSGAMBIENTLIGHT_H #include "JSystem/JStage/JSGObject.h" -#include "dolphin/gx/GXStruct.h" +#include namespace JStage { diff --git a/include/JSystem/JStage/JSGFog.h b/include/JSystem/JStage/JSGFog.h index d2602993cb..99a8ce4e6e 100644 --- a/include/JSystem/JStage/JSGFog.h +++ b/include/JSystem/JStage/JSGFog.h @@ -2,7 +2,7 @@ #define JSGFOG_H #include "JSystem/JStage/JSGObject.h" -#include "dolphin/gx/GXStruct.h" +#include namespace JStage { diff --git a/include/JSystem/JStage/JSGLight.h b/include/JSystem/JStage/JSGLight.h index 06485a3717..92c9c15386 100644 --- a/include/JSystem/JStage/JSGLight.h +++ b/include/JSystem/JStage/JSGLight.h @@ -2,7 +2,7 @@ #define JSGLIGHT_H #include "JSystem/JStage/JSGObject.h" -#include "dolphin/gx/GXStruct.h" +#include namespace JStage { enum TELight { diff --git a/include/JSystem/JStudio/JStudio/jstudio-control.h b/include/JSystem/JStudio/JStudio/jstudio-control.h index 20db5602ed..e67c533f52 100644 --- a/include/JSystem/JStudio/JStudio/jstudio-control.h +++ b/include/JSystem/JStudio/JStudio/jstudio-control.h @@ -4,7 +4,8 @@ #include "JSystem/JStudio/JStudio/fvb.h" #include "JSystem/JStudio/JStudio/stb.h" #include "JSystem/JStudio/JStudio/ctb.h" -#include "dolphin/gx.h" +#include +#include namespace JStudio { struct TObject; diff --git a/include/JSystem/JUtility/JUTCacheFont.h b/include/JSystem/JUtility/JUTCacheFont.h index 7685f8460f..47fa00fc8d 100644 --- a/include/JSystem/JUtility/JUTCacheFont.h +++ b/include/JSystem/JUtility/JUTCacheFont.h @@ -2,6 +2,7 @@ #define JUTCACHEFONT_H #include "JSystem/JUtility/JUTResFont.h" +#include "global.h" class JKRAramBlock; diff --git a/include/JSystem/JUtility/JUTException.h b/include/JSystem/JUtility/JUTException.h index 3f568afd77..6ef9bfc3ca 100644 --- a/include/JSystem/JUtility/JUTException.h +++ b/include/JSystem/JUtility/JUTException.h @@ -4,8 +4,8 @@ #include "JSystem/JKernel/JKRThread.h" #include "JSystem/JUtility/JUTGamePad.h" #include "__va_arg.h" -#include "dolphin/gx/GXEnum.h" -#include "dolphin/os/OSError.h" +#include +#include #include "global.h" typedef struct _GXRenderModeObj GXRenderModeObj; @@ -42,6 +42,9 @@ STATIC_ASSERT(sizeof(JUTExternalFB) == 0x14); * @ingroup jsystem-jutility * */ + +typedef void (*JUTExceptionUserCallback)(u16, OSContext*, u32, u32); + class JUTException : public JKRThread { public: enum EInfoPage { @@ -87,8 +90,8 @@ public: /* 802E21FC */ static void panic_f(char const*, int, char const*, ...); /* 802E227C */ static void setFPException(u32); /* 802E2578 */ static bool searchPartialModule(u32, u32*, u32*, u32*, u32*); - /* 802E3AEC */ static OSErrorHandler setPreUserCallback(OSErrorHandler); - /* 802E3AFC */ static OSErrorHandler setPostUserCallback(OSErrorHandler); + /* 802E3AEC */ static JUTExceptionUserCallback setPreUserCallback(JUTExceptionUserCallback); + /* 802E3AFC */ static JUTExceptionUserCallback setPostUserCallback(JUTExceptionUserCallback); /* 802E3B0C */ static void appendMapFile(char const*); /* 802E3BA0 */ static bool queryMapAddress(char*, u32, s32, u32*, u32*, char*, u32, bool, bool); /* 802E3C90 */ static bool queryMapAddress_single(char*, u32, s32, u32*, u32*, char*, u32, bool, @@ -120,8 +123,8 @@ private: static JSUList sMapFileList; static OSMessage sMessageBuffer[1]; static JUTException* sErrorManager; - static OSErrorHandler sPreUserCallback; - static OSErrorHandler sPostUserCallback; + static JUTExceptionUserCallback sPreUserCallback; + static JUTExceptionUserCallback sPostUserCallback; static void* sConsoleBuffer; static u32 sConsoleBufferSize; static JUTConsole* sConsole; diff --git a/include/JSystem/JUtility/JUTGamePad.h b/include/JSystem/JUtility/JUTGamePad.h index f43b17bea9..87a6b4d28d 100644 --- a/include/JSystem/JUtility/JUTGamePad.h +++ b/include/JSystem/JUtility/JUTGamePad.h @@ -110,7 +110,7 @@ public: void stopMotor() { mRumble.stopMotor(mPortNum, false); } void stopMotorHard() { mRumble.stopMotorHard(mPortNum); } - static s8 getPortStatus(u32 port) { return mPadStatus[port].error; } + static s8 getPortStatus(u32 port) { return mPadStatus[port].err; } struct CButton { CButton() { clear(); } diff --git a/include/JSystem/JUtility/JUTPalette.h b/include/JSystem/JUtility/JUTPalette.h index 3702cbafa8..3319dd919b 100644 --- a/include/JSystem/JUtility/JUTPalette.h +++ b/include/JSystem/JUtility/JUTPalette.h @@ -1,7 +1,7 @@ #ifndef JUTPALETTE_H #define JUTPALETTE_H -#include "dolphin/gx/GXStruct.h" +#include enum JUTTransparency { UNK0, UNK1 }; diff --git a/include/JSystem/JUtility/JUTProcBar.h b/include/JSystem/JUtility/JUTProcBar.h index b38ad82b1a..42111ee765 100644 --- a/include/JSystem/JUtility/JUTProcBar.h +++ b/include/JSystem/JUtility/JUTProcBar.h @@ -2,7 +2,7 @@ #define JUTPROCBAR_H #include "JSystem/JUtility/TColor.h" -#include "dolphin/os/OSTime.h" +#include class JKRHeap; diff --git a/include/JSystem/JUtility/JUTTexture.h b/include/JSystem/JUtility/JUTTexture.h index b9a02b00b5..47d5638cd6 100644 --- a/include/JSystem/JUtility/JUTTexture.h +++ b/include/JSystem/JUtility/JUTTexture.h @@ -1,7 +1,7 @@ #ifndef JUTTEXTURE_H #define JUTTEXTURE_H -#include "dolphin/gx/GXStruct.h" +#include class JUTPalette; diff --git a/include/JSystem/JUtility/JUTVideo.h b/include/JSystem/JUtility/JUTVideo.h index 2c1727ab2b..10ae432b4b 100644 --- a/include/JSystem/JUtility/JUTVideo.h +++ b/include/JSystem/JUtility/JUTVideo.h @@ -1,9 +1,9 @@ #ifndef JUTVIDEO_H #define JUTVIDEO_H -#include "dolphin/gx/GXStruct.h" -#include "dolphin/os/OSMessage.h" -#include "dolphin/os/OSTime.h" +#include +#include +#include typedef u8 (*Pattern)[2]; @@ -30,14 +30,14 @@ public: /* 802E5144 */ static void postRetraceProc(u32); /* 802E50BC */ static void drawDoneCallback(); - u16 getFbWidth() const { return mRenderObj->fb_width; } - u16 getEfbHeight() const { return mRenderObj->efb_height; } + u16 getFbWidth() const { return mRenderObj->fbWidth; } + u16 getEfbHeight() const { return mRenderObj->efbHeight; } void getBounds(u16& width, u16& height) const { width = (u16)getFbWidth(); height = (u16)getEfbHeight(); } - u16 getXfbHeight() const { return mRenderObj->xfb_height; } - u32 isAntiAliasing() const { return mRenderObj->antialiasing; } + u16 getXfbHeight() const { return mRenderObj->xfbHeight; } + u32 isAntiAliasing() const { return mRenderObj->aa; } Pattern getSamplePattern() const { return mRenderObj->sample_pattern; } u8* getVFilter() const { return mRenderObj->vfilter; } OSMessageQueue* getMessageQueue() { return &mMessageQueue; } diff --git a/include/JSystem/JUtility/TColor.h b/include/JSystem/JUtility/TColor.h index e8bf44d45f..2691dff536 100644 --- a/include/JSystem/JUtility/TColor.h +++ b/include/JSystem/JUtility/TColor.h @@ -1,7 +1,7 @@ #ifndef TCOLOR_H #define TCOLOR_H -#include "dolphin/gx/GXStruct.h" +#include namespace JUtility { @@ -32,4 +32,4 @@ struct TColor : public GXColor { }; } // namespace JUtility -#endif \ No newline at end of file +#endif diff --git a/include/SSystem/SComponent/c_bg_s_chk.h b/include/SSystem/SComponent/c_bg_s_chk.h index 3bacd16583..3ba9867669 100644 --- a/include/SSystem/SComponent/c_bg_s_chk.h +++ b/include/SSystem/SComponent/c_bg_s_chk.h @@ -1,7 +1,7 @@ #ifndef C_BG_S_CHK_H #define C_BG_S_CHK_H -#include "dolphin/mtx/vec.h" +#include "dolphin/mtx.h" #include "f_pc/f_pc_base.h" struct cBgD_Vtx_t : public Vec {}; diff --git a/include/SSystem/SComponent/c_m3d.h b/include/SSystem/SComponent/c_m3d.h index 0f5c929f04..fefbb8108d 100644 --- a/include/SSystem/SComponent/c_m3d.h +++ b/include/SSystem/SComponent/c_m3d.h @@ -2,7 +2,7 @@ #define C_M3D_H_ #include "math.h" -#include "dolphin/mtx/vec.h" +#include "dolphin/mtx.h" class cM3dGAab; class cM3dGCps; @@ -19,8 +19,6 @@ struct cM3d_Range { /* 0x4 */ f32 mMax; }; -struct Vec; - extern const f32 G_CM3D_F_ABS_MIN; static void cM3d_InDivPos1(const Vec*, const Vec*, f32, Vec*); diff --git a/include/SSystem/SComponent/c_sxyz.h b/include/SSystem/SComponent/c_sxyz.h index 2597254527..7f0ebc23dc 100644 --- a/include/SSystem/SComponent/c_sxyz.h +++ b/include/SSystem/SComponent/c_sxyz.h @@ -1,7 +1,11 @@ #ifndef C_SXYZ_H #define C_SXYZ_H -#include "dolphin/mtx/vec.h" +#include "dolphin/mtx.h" + +struct SVec { + s16 x, y, z; +}; class csXyz : public SVec { public: diff --git a/include/SSystem/SComponent/c_xyz.h b/include/SSystem/SComponent/c_xyz.h index 4f4e89a9cb..5198010436 100644 --- a/include/SSystem/SComponent/c_xyz.h +++ b/include/SSystem/SComponent/c_xyz.h @@ -1,7 +1,7 @@ #ifndef C_XYZ_H #define C_XYZ_H -#include "dolphin/mtx/vec.h" +#include "dolphin/mtx.h" #include "math.h" struct cXyz : Vec { diff --git a/include/TRK_MINNOW_DOLPHIN/Os/dolphin/DDH_Stubs.h b/include/TRK_MINNOW_DOLPHIN/Os/dolphin/DDH_Stubs.h index 8d1a4aa772..93035ade09 100644 --- a/include/TRK_MINNOW_DOLPHIN/Os/dolphin/DDH_Stubs.h +++ b/include/TRK_MINNOW_DOLPHIN/Os/dolphin/DDH_Stubs.h @@ -1,13 +1,13 @@ #ifndef OS_DOLPHIN_DDH_STUBS_H #define OS_DOLPHIN_DDH_STUBS_H -#include "amcstubs/AmcExi2Stubs.h" +#include #ifdef __cplusplus extern "C" { #endif -int ddh_cc_initialize(void* inputPendingPtrRef, AmcEXICallback monitorCallback); +int ddh_cc_initialize(void* inputPendingPtrRef, EXICallback monitorCallback); int ddh_cc_shutdown(); int ddh_cc_open(); int ddh_cc_close(); diff --git a/include/TRK_MINNOW_DOLPHIN/Os/dolphin/GDEV_Stubs.h b/include/TRK_MINNOW_DOLPHIN/Os/dolphin/GDEV_Stubs.h index c0dcde4c78..4179c1754d 100644 --- a/include/TRK_MINNOW_DOLPHIN/Os/dolphin/GDEV_Stubs.h +++ b/include/TRK_MINNOW_DOLPHIN/Os/dolphin/GDEV_Stubs.h @@ -1,13 +1,13 @@ #ifndef OS_DOLPHIN_GDEV_STUBS_H #define OS_DOLPHIN_GDEV_STUBS_H -#include "amcstubs/AmcExi2Stubs.h" +#include #ifdef __cplusplus extern "C" { #endif -int gdev_cc_initialize(void* inputPendingPtrRef, AmcEXICallback monitorCallback); +int gdev_cc_initialize(void* inputPendingPtrRef, EXICallback monitorCallback); int gdev_cc_shutdown(); int gdev_cc_open(); int gdev_cc_close(); diff --git a/include/Z2AudioLib/Z2SoundObject.h b/include/Z2AudioLib/Z2SoundObject.h index 1e51f6c774..cfb2f66c50 100644 --- a/include/Z2AudioLib/Z2SoundObject.h +++ b/include/Z2AudioLib/Z2SoundObject.h @@ -24,6 +24,9 @@ public: virtual Z2SoundHandlePool* startSound(JAISoundID, u32, s8); virtual Z2SoundHandlePool* startLevelSound(JAISoundID, u32, s8); +#if VERSION == VERSION_SHIELD_DEBUG + /* 0x14 */ u8 unk_0x14[0x24 - 0x14]; +#endif /* 0x14 */ Z2SoundStarter* mSoundStarter; /* 0x18 */ JGeometry::TVec3* mSoundPos; /* 0x1C */ u16 field_0x1c; diff --git a/include/Z2AudioLib/Z2StatusMgr.h b/include/Z2AudioLib/Z2StatusMgr.h index 3ba39baa96..ea732811f5 100644 --- a/include/Z2AudioLib/Z2StatusMgr.h +++ b/include/Z2AudioLib/Z2StatusMgr.h @@ -2,7 +2,7 @@ #define Z2STATUSMGR_H #include "JSystem/JAudio2/JASGadget.h" -#include "dolphin/mtx/vec.h" +#include "dolphin/mtx.h" struct Z2StatusMgr : public JASGlobalInstance { Z2StatusMgr(); diff --git a/include/d/actor/d_a_b_bh.h b/include/d/actor/d_a_b_bh.h index 9d4d67b5b3..969e3f2b29 100644 --- a/include/d/actor/d_a_b_bh.h +++ b/include/d/actor/d_a_b_bh.h @@ -1,26 +1,113 @@ #ifndef D_A_B_BH_H #define D_A_B_BH_H + #include "f_op/f_op_actor_mng.h" +#include "JSystem/JHostIO/JORMContext.h" +#include "d/d_cc_d.h" +#include "d/d_cc_uty.h" +#include "d/d_bg_s_acch.h" /** * @ingroup actors-enemies * @class b_bh_class - * @brief Big Baba + * @brief Diababa - Baba Hand * * @details Forest Temple enemy. * */ class b_bh_class : public fopEn_enemy_c { -private: - /* 0x5AC */ u8 field_0x568[0xf4c - 0x5AC]; +public: + /* 0x5AC */ request_of_phase_process_class mPhase; + /* 0x5B4 */ u8 mID; + /* 0x5B5 */ u8 field_0x5b5; + /* 0x5B6 */ u8 field_0x5b6; + /* 0x5B7 */ u8 field_0x5b7; + /* 0x5B8 */ mDoExt_McaMorfSO* mpModelMorf; + /* 0x5BC */ Z2CreatureEnemy mSound; + /* 0x660 */ int mAnm; + /* 0x664 */ u8 field_0x664[0x668 - 0x664]; + /* 0x668 */ s16 field_0x668; + /* 0x66A */ s16 mAction; + /* 0x66C */ s16 mMode; + /* 0x66E */ u8 field_0x66E[0x674 - 0x66E]; + /* 0x674 */ cXyz field_0x674; + /* 0x680 */ u8 field_0x680[0x684 - 0x680]; + /* 0x684 */ s16 field_0x684; + /* 0x686 */ s16 field_0x686; + /* 0x688 */ f32 field_0x688; + /* 0x68C */ f32 field_0x68c; + /* 0x690 */ f32 field_0x690; + /* 0x694 */ s16 mTimers[5]; + /* 0x69E */ s16 field_0x69e; + /* 0x6A0 */ s8 field_0x6a0; + /* 0x6A4 */ cXyz mBasePos; + /* 0x6B0 */ cXyz field_0x6b0; + /* 0x6BC */ cXyz field_0x6bc[18]; + /* 0x794 */ csXyz field_0x794[18]; + /* 0x800 */ J3DModel* mpStemModels[17]; + /* 0x844 */ u8 field_0x844[0x88C - 0x844]; + /* 0x88C */ f32 field_0x88c[17]; + /* 0x8D0 */ u8 field_0x8D0[0x8D4 - 0x8D0]; + /* 0x8D4 */ s16 field_0x8d4[17]; + /* 0x8F6 */ u8 field_0x8f6[0x8F8 - 0x8F6]; + /* 0x8F8 */ s16 field_0x8f8; + /* 0x8FC */ f32 field_0x8fc; + /* 0x900 */ s16 field_0x900[3]; + /* 0x906 */ s8 field_0x906[3]; + /* 0x909 */ s8 field_0x909[3]; + /* 0x90C */ s8 field_0x90c; + /* 0x910 */ f32 field_0x910; + /* 0x914 */ f32 field_0x914; + /* 0x918 */ f32 field_0x918; + /* 0x91C */ J3DModel* mpLeafModels[17]; + /* 0x960 */ f32 field_0x960[17]; + /* 0x9A4 */ u8 field_0x9A4[0x9A8 - 0x9A4]; + /* 0x9A8 */ csXyz field_0x9a8[18]; + /* 0xA14 */ u8 field_0xA14[0xA20 - 0xA14]; + /* 0xA20 */ f32 field_0xa20; + /* 0xA24 */ s8 field_0xa24; + /* 0xA25 */ s8 field_0xa25; + /* 0xA26 */ csXyz field_0xa26; + /* 0xA2C */ s8 mAnmSeTimer; + /* 0xA30 */ u32 mAnmSe; + /* 0xA34 */ dCcD_Stts mColliderStts; + /* 0xA70 */ dCcD_Sph mCcSph; + /* 0xBA8 */ dCcD_Sph mTgSph; + /* 0xCE0 */ s8 field_0xce0; + /* 0xCE4 */ dCcU_AtInfo mAtInfo; + /* 0xD08 */ dBgS_AcchCir mAcchCir; + /* 0xD48 */ dBgS_ObjAcch mAcch; + /* 0xF20 */ s8 field_0xf20; + /* 0xF21 */ s8 field_0xf21; + /* 0xF22 */ s8 field_0xf22; + /* 0xF24 */ u32 field_0xf24; + /* 0xF28 */ u8 field_0xF28[0xF30 - 0xF28]; + /* 0xF30 */ u32 mMouthMizuEmitterIDs[5]; + /* 0xF44 */ f32 mMouthMizuParticleSize; + /* 0xF48 */ u8 mInitHIO; }; STATIC_ASSERT(sizeof(b_bh_class) == 0xf4c); -class daB_BH_HIO_c { +class daB_BH_HIO_c +#ifdef DEBUG +: public JORReflexible +#endif +{ public: /* 805AE26C */ daB_BH_HIO_c(); - /* 805B3098 */ ~daB_BH_HIO_c(); + /* 805B3098 */ virtual ~daB_BH_HIO_c() {} + +#ifdef DEBUG + virtual void genMessage(JORMContext*); +#endif + + /* 0x04 */ s8 no; + /* 0x08 */ f32 model_size; + /* 0x0C */ u8 unk_0xc[0x10 - 0xC]; + /* 0x10 */ s16 attack_freq_a; + /* 0x12 */ s16 attack_freq_b; + /* 0x14 */ s16 down_revive_time; }; diff --git a/include/d/actor/d_a_b_bq.h b/include/d/actor/d_a_b_bq.h index 6c3d46aaf6..c9ea4ae7fd 100644 --- a/include/d/actor/d_a_b_bq.h +++ b/include/d/actor/d_a_b_bq.h @@ -41,16 +41,17 @@ public: /* 0x06DE */ s16 field_0x6de; /* 0x06E0 */ fpc_ProcID mTentacleIDs[2]; /* 0x06E8 */ fpc_ProcID mMonkeyBombID; - /* 0x06EC */ u8 field_0x6ec; + /* 0x06EC */ s8 field_0x6ec; /* 0x06ED */ s8 mColpatType; /* 0x06F0 */ f32 mColpatBlend; /* 0x06F4 */ s16 mHeadRot; /* 0x06F6 */ s16 field_0x6f6; /* 0x06F8 */ s8 mDisableDraw; - /* 0x06F9 */ u8 field_0x6f9; - /* 0x06FA */ u8 field_0x6fa; - /* 0x06FB */ u8 field_0x6fb; + /* 0x06F9 */ s8 field_0x6f9; + /* 0x06FA */ s8 field_0x6fa; + /* 0x06FB */ s8 field_0x6fb; /* 0x06FC */ s8 field_0x6fc; + /* 0x06FD */ s8 field_0x6fd; /* 0x06FE */ s16 field_0x6fe; /* 0x0700 */ dCcD_Stts mCcStts; /* 0x073C */ dCcD_Sph mCcSph; diff --git a/include/d/actor/d_a_e_mb.h b/include/d/actor/d_a_e_mb.h index 5a6be495fd..d39a6c484d 100644 --- a/include/d/actor/d_a_e_mb.h +++ b/include/d/actor/d_a_e_mb.h @@ -1,6 +1,9 @@ #ifndef D_A_E_MB_H #define D_A_E_MB_H + #include "f_op/f_op_actor_mng.h" +#include "d/d_cc_d.h" +#include "d/d_cc_uty.h" /** * @ingroup actors-enemies @@ -11,15 +14,59 @@ * */ class e_mb_class : public fopEn_enemy_c { -private: - /* 0x5ac */ u8 field_0x5ac[0x8cc - 0x5ac]; +public: + /* 0x5AC */ request_of_phase_process_class mPhase; + /* 0x5B4 */ s16 mMode; + /* 0x5B6 */ u8 field_0x5b6; + /* 0x5B8 */ cXyz field_0x5b8; + /* 0x5C4 */ u8 field_0x5C4[0x5C8 - 0x5C4]; + /* 0x5C8 */ mDoExt_McaMorfSO* mpModelMorf; + /* 0x5CC */ int mAnm; + /* 0x5D0 */ mDoExt_btpAnm* mpBtp; + /* 0x5D4 */ s16 field_0x5d4; + /* 0x5D8 */ f32 mBtpFrame; + /* 0x5DC */ cXyz field_0x5dc; + /* 0x5E8 */ Z2CreatureEnemy mSound; + /* 0x68C */ s8 field_0x68c; + /* 0x690 */ mDoExt_McaMorf* mpBombModelMorf; + /* 0x694 */ mDoExt_McaMorf* mpBombModel2Morf; + /* 0x698 */ s16 mCounter; + /* 0x69A */ s16 mAction; + /* 0x69C */ s16 mTimers[3]; + /* 0x6A2 */ s16 field_0x6a2; + /* 0x6A4 */ cXyz field_0x6a4; + /* 0x6B0 */ s8 field_0x6b0; + /* 0x6B4 */ mDoExt_3DlineMat1_c mRopeMat; + /* 0x6F0 */ f32 field_0x6f0; + /* 0x6F4 */ dCcD_Stts mColliderStts; + /* 0x730 */ dCcD_Sph mCcSph; + /* 0x868 */ dCcU_AtInfo mAtInfo; + /* 0x88C */ u8 field_0x88C[0x8C8 - 0x88C]; + /* 0x8C8 */ s8 field_0x8c8; + /* 0x8C9 */ u8 mInitHIO; }; STATIC_ASSERT(sizeof(e_mb_class) == 0x8cc); -class daE_MB_HIO_c { +class daE_MB_HIO_c +#ifdef DEBUG +: public JORReflexible +#endif +{ +public: /* 8070616C */ daE_MB_HIO_c(); - /* 8070882C */ ~daE_MB_HIO_c(); + /* 8070882C */ virtual ~daE_MB_HIO_c() {} + +#ifdef DEBUG + virtual void genMessage(JORMContext*); +#endif + + /* 0x04 */ s8 no; + /* 0x08 */ f32 base_size; + /* 0x0C */ f32 swing_speed; + /* 0x10 */ f32 swing_descend; + /* 0x14 */ f32 swing_correction; + /* 0x18 */ f32 reappear_time; }; diff --git a/include/d/actor/d_a_ykgr.h b/include/d/actor/d_a_ykgr.h index 62f2abc9c1..93e80820e9 100644 --- a/include/d/actor/d_a_ykgr.h +++ b/include/d/actor/d_a_ykgr.h @@ -29,12 +29,7 @@ struct dPa_YkgrPcallBack : public JPAParticleCallBack { /* 805A848C */ void draw(JPABaseEmitter*, JPABaseParticle*); /* 805A84D4 */ void setParam(f32); - /* 0x04 */ f32 field_0x4; - /* 0x08 */ f32 field_0x8; - /* 0x0C */ f32 field_0xc; - /* 0x10 */ f32 field_0x10; - /* 0x14 */ f32 field_0x14; - /* 0x18 */ f32 field_0x18; + /* 0x04 */ f32 field_0x4[2][3]; /* 0x1C */ s8 field_0x1c; }; diff --git a/include/d/d_bg_s_acch.h b/include/d/d_bg_s_acch.h index 955a172c39..fa6838d185 100644 --- a/include/d/d_bg_s_acch.h +++ b/include/d/d_bg_s_acch.h @@ -199,6 +199,9 @@ public: /* 0x02C */ u32 m_flags; /* 0x030 */ cXyz* pm_pos; /* 0x034 */ cXyz* pm_old_pos; +#ifdef DEBUG + /* 0x038 */ cXyz unk_0x38; +#endif /* 0x038 */ cXyz* pm_speed; /* 0x03C */ csXyz* pm_angle; /* 0x040 */ csXyz* pm_shape_angle; @@ -224,6 +227,9 @@ public: /* 0x0CC */ f32 field_0xcc; /* 0x0D0 */ f32 m_wtr_chk_offset; /* 0x0D4 */ cBgS_PolyInfo* pm_out_poly_info; +#ifdef DEBUG + /* 0x0E4 */ cXyz unk_0xe4; +#endif /* 0x0D8 */ f32 field_0xd8; /* 0x0DC */ dBgS_GndChk m_gnd; /* 0x130 */ dBgS_RoofChk m_roof; diff --git a/include/d/d_bomb.h b/include/d/d_bomb.h index b03b9ddc66..c3ce9ff36d 100644 --- a/include/d/d_bomb.h +++ b/include/d/d_bomb.h @@ -64,6 +64,11 @@ public: NULL, NULL); } + static fopAc_ac_c* createEnemyBombBoomerang(cXyz* i_pos, csXyz* i_angle, int i_roomNo) { + return (fopAc_ac_c*)fopAcM_fastCreate(PROC_NBOMB, 12, i_pos, i_roomNo, i_angle, NULL, -1, + NULL, NULL); + } + static fopAc_ac_c* createWaterBombExplode(cXyz* i_pos) { return (fopAc_ac_c*)fopAcM_fastCreate(PROC_NBOMB, 18, i_pos, -1, NULL, NULL, -1, NULL, NULL); diff --git a/include/d/d_gameover.h b/include/d/d_gameover.h index 2a231ecf89..91f071b812 100644 --- a/include/d/d_gameover.h +++ b/include/d/d_gameover.h @@ -5,6 +5,7 @@ #include "d/d_menu_save.h" #include "f_op/f_op_msg.h" #include "f_op/f_op_msg_mng.h" +#include "f_pc/f_pc_manager.h" #include "m_Do/m_Do_hostIO.h" class dDlst_Gameover_CAPTURE_c : public dDlst_base_c { @@ -84,7 +85,7 @@ s32 d_GameOver_Create(u8 param_0); bool d_GameOver_Delete(fpc_ProcID& i_id); inline s32 d_GameOver_CheckDelete(fpc_ProcID& id) { - if (id != UINT32_MAX) { + if (id != fpcM_ERROR_PROCESS_ID_e) { dGameover_c* gameover = (dGameover_c*)fopMsgM_SearchByID(id); if (gameover != NULL) { @@ -98,7 +99,7 @@ inline s32 d_GameOver_CheckDelete(fpc_ProcID& id) { } inline s32 d_GameOver_animeStart(fpc_ProcID& id) { - if (id != UINT32_MAX) { + if (id != fpcM_ERROR_PROCESS_ID_e) { dGameover_c* gameover = (dGameover_c*)fopMsgM_SearchByID(id); if (gameover != NULL) { diff --git a/include/d/d_lib.h b/include/d/d_lib.h index 9cef33cfef..ad8babf29d 100644 --- a/include/d/d_lib.h +++ b/include/d/d_lib.h @@ -2,8 +2,8 @@ #define D_D_LIB_H #include "SSystem/SComponent/c_xyz.h" -#include "dolphin/mtx/quat.h" -#include "dolphin/os/OSTime.h" +#include +#include class fopAc_ac_c; diff --git a/include/d/d_menu_window.h b/include/d/d_menu_window.h index 90dceda47d..c7b5b0595c 100644 --- a/include/d/d_menu_window.h +++ b/include/d/d_menu_window.h @@ -58,7 +58,7 @@ public: GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetZCompLoc(GX_TRUE); GXSetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_OR); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_OR); GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); GXSetFog(GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, g_clearColor); GXSetFogRangeAdj(GX_FALSE, 0, NULL); diff --git a/include/d/d_meter_HIO.h b/include/d/d_meter_HIO.h index 2cca81d0ee..799633c439 100644 --- a/include/d/d_meter_HIO.h +++ b/include/d/d_meter_HIO.h @@ -4,6 +4,7 @@ #include "JSystem/JUtility/TColor.h" #include "SSystem/SComponent/c_sxyz.h" #include "SSystem/SComponent/c_xyz.h" +#include "global.h" class JKRAramArchive; diff --git a/include/d/d_save.h b/include/d/d_save.h index d51bd1f9ab..6419052425 100644 --- a/include/d/d_save.h +++ b/include/d/d_save.h @@ -3,7 +3,7 @@ #include "string.h" #include "SSystem/SComponent/c_xyz.h" -#include "dolphin/os/OSTime.h" +#include #include "global.h" #include "f_pc/f_pc_name.h" diff --git a/include/d/d_tresure.h b/include/d/d_tresure.h index 7e5f017d31..4a8859909b 100644 --- a/include/d/d_tresure.h +++ b/include/d/d_tresure.h @@ -1,7 +1,7 @@ #ifndef D_D_TRESURE_H #define D_D_TRESURE_H -#include "dolphin/mtx/vec.h" +#include "dolphin/mtx.h" class dTres_c { public: diff --git a/include/dolphin/G2D.h b/include/dolphin/G2D.h new file mode 100644 index 0000000000..18772ed009 --- /dev/null +++ b/include/dolphin/G2D.h @@ -0,0 +1,88 @@ +#ifndef _DOLPHIN_G2D_H_ +#define _DOLPHIN_G2D_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum G2DMatCtg { + G2D_CTG_TEXTURE, + G2D_CTG_RGB_DIRECT, + G2D_CTG_RGBA_INDEX8, + G2D_CTG_EMPTY, +} G2DMatCtg; + +typedef struct G2DSprite { + u16 nTlcS; // "Top Left Corner" + u16 nTlcT; + u16 nWidth; + u16 nHeight; + GXTexObj* to; + f32 rS0; + f32 rT0; + f32 rS1; + f32 rT1; +} G2DSprite; + +typedef struct G2DPosOri { + f32 rPosX; + f32 rPosY; + f32 rOriX; + f32 rOriY; +} G2DPosOri; + +typedef struct G2DGlob { + u16 nViewportTlcX; + u16 nViewportTlcY; + u16 nViewportWidth; + u16 nViewportHeight; + G2DPosOri poCam; + f32 rWorldX; + f32 rWorldY; + f32 rHalfX; + f32 rHalfY; +} G2DGlob; + +typedef struct G2DMatDesc { + s32 nReserved; + G2DMatCtg nCategory; + GXColor* color; + GXTexObj* to; + u8* clut; // Color Look-Up Table +} G2DMatDesc; + +typedef struct G2DTileDesc { + u8 nMaterial; + u8 nS; + u8 nT; + u8 nCI; // Color Index + u8 aUser[4]; +} G2DTileDesc; + +typedef struct G2DLayer { + void* map; + s8 nHS; + s8 nVS; + s8 nBPI; + s16 nTileWidth; + s16 nTileHeight; + s8 bWrap; + u8 nNumMaterials; + G2DTileDesc* tileDesc; + G2DMatDesc* matDesc; +} G2DLayer; + +void G2DInitSprite(G2DSprite* sprite); +void G2DDrawSprite(G2DSprite* sprite, G2DPosOri* po); +void G2DDrawLayer(G2DLayer* layer, s8* aSortBuffer); +void G2DSetCamera(G2DPosOri* po); +void G2DInitWorld(u32 nWorldX, u32 nWorldY); +void G2DSetViewport(u16 nLeft, u16 nTop, u16 nWidth, u16 nHeight); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_G2D_H_ diff --git a/include/dolphin/ai.h b/include/dolphin/ai.h index 0de6e2d9cc..84db3343b0 100644 --- a/include/dolphin/ai.h +++ b/include/dolphin/ai.h @@ -1,7 +1,7 @@ -#ifndef AI_H -#define AI_H +#ifndef _DOLPHIN_AI_H_ +#define _DOLPHIN_AI_H_ -#include "dolphin/types.h" +#include #ifdef __cplusplus extern "C" { @@ -10,24 +10,41 @@ extern "C" { typedef void (*AISCallback)(u32 count); typedef void (*AIDCallback)(); +#define AI_STREAM_START 1 +#define AI_STREAM_STOP 0 + +#define AI_SAMPLERATE_32KHZ 0 +#define AI_SAMPLERATE_48KHZ 1 + AIDCallback AIRegisterDMACallback(AIDCallback callback); -void AIInitDMA(u32 addr, u32 length); +void AIInitDMA(u32 start_addr, u32 length); +BOOL AIGetDMAEnableFlag(void); void AIStartDMA(void); void AIStopDMA(void); +u32 AIGetDMABytesLeft(void); +u32 AIGetDMAStartAddr(void); +u32 AIGetDMALength(void); +BOOL AICheckInit(void); +AISCallback AIRegisterStreamCallback(AISCallback callback); +u32 AIGetStreamSampleCount(void); +void AIResetStreamSampleCount(void); +void AISetStreamTrigger(u32 trigger); +u32 AIGetStreamTrigger(void); void AISetStreamPlayState(u32 state); -inline u32 AIGetStreamPlayState(void); +u32 AIGetStreamPlayState(void); void AISetDSPSampleRate(u32 rate); u32 AIGetDSPSampleRate(void); -void __AI_set_stream_sample_rate(u32 rate); +void AISetStreamSampleRate(u32 rate); u32 AIGetStreamSampleRate(void); void AISetStreamVolLeft(u8 vol); u8 AIGetStreamVolLeft(void); void AISetStreamVolRight(u8 vol); u8 AIGetStreamVolRight(void); void AIInit(u8* stack); +void AIReset(void); #ifdef __cplusplus -}; +} #endif -#endif /* AI_H */ +#endif diff --git a/include/dolphin/am.h b/include/dolphin/am.h new file mode 100644 index 0000000000..153553b11f --- /dev/null +++ b/include/dolphin/am.h @@ -0,0 +1,26 @@ +#ifndef _DOLPHIN_AM_H_ +#define _DOLPHIN_AM_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*AMCallback)(char* path); + +void* AMLoadFile(char* path, u32* length); +u32 AMPush(char* path); +u32 AMPushData(void* buffer, u32 length); +void AMPop(void); +u32 AMGetZeroBuffer(void); +u32 AMGetReadStatus(void); +u32 AMGetFreeSize(void); +u32 AMGetStackPointer(void); +void AMInit(u32 aramBase, u32 aramBytes); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/amc/AmcExi2Comm.h b/include/dolphin/amc/AmcExi2Comm.h new file mode 100644 index 0000000000..c38c8a6a1c --- /dev/null +++ b/include/dolphin/amc/AmcExi2Comm.h @@ -0,0 +1,123 @@ +#ifndef _DOLPHIN_AMC_AMCEXI2COMM_H_ +#define _DOLPHIN_AMC_AMCEXI2COMM_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + AMC_EXI_NO_ERROR = 0, + AMC_EXI_UNSELECTED, +} AmcExiError; + +// --------------------------------------------------------------------------- +// +// void EXI2_Init( volatile unsigned char **inputPendingPtrRef, +// EXICallback monitorCallback ); +// +// Description: Initialize the EXI2 driver (without interrupts). The +// parameter 'inputPendingPtrref' is a flag showing whether input +// is waiting in the EXI2 buffer and 'monitorCallback' is a +// pointer to a callback function that is invoked at the end of +// the EXI2 ISR. +// +// --------------------------------------------------------------------------- +void EXI2_Init(volatile unsigned char **inputPendingPtrRef, EXICallback monitorCallback); + +// --------------------------------------------------------------------------- +// +// void EXI2_EnableInterrupts( void ); +// +// Description: Enable EXI2 interrupts. This function must be called to use +// interrupts on the EXI2 interface. Call this function only +// after EXI2_Init() has been invoked. +// +// --------------------------------------------------------------------------- +void EXI2_EnableInterrupts( void ); + + + +// --------------------------------------------------------------------------- +// +// int EXI2_Poll( void ); +// +// Description: Returns the number of bytes waiting to be read in the EXI2 +// buffer. +// +// --------------------------------------------------------------------------- +int EXI2_Poll( void ); + + + +// --------------------------------------------------------------------------- +// +// AmcExiError EXI2_ReadN( void *bytes, unsigned long length ); +// +// Description: Read length bytes and return in bytes[] array. +// +// Returns: One of AMC_EXI_*. +// +// --------------------------------------------------------------------------- +AmcExiError EXI2_ReadN( void *bytes, unsigned long length); + + + +// --------------------------------------------------------------------------- +// +// AmcExiError EXI2_WriteN( const void *bytes, unsigned long length ); +// +// Description: Write length bytes stored in bytes[] array. +// +// Returns: One of AMC_EXI_*. +// +// --------------------------------------------------------------------------- +AmcExiError EXI2_WriteN( const void *bytes, unsigned long length); + + + +// --------------------------------------------------------------------------- +// +// void EXI2_Reserve( void ); +// +// Description: Disable non-monitor communications over the EXI2 port. +// This function must be called before the monitor takes +// control of the processor. +// +// --------------------------------------------------------------------------- +void EXI2_Reserve( void ); + + + +// --------------------------------------------------------------------------- +// +// void EXI2_Unreserve( void ); +// +// Description: Re-enable non-monitor communications over the EXI2 port. +// This function must be called just before the monitor +// gives control of the processor back to the application. +// +// --------------------------------------------------------------------------- +void EXI2_Unreserve( void ); + + + +// --------------------------------------------------------------------------- +// +// AmcExiError EXI2_GetStatusReg( u16* pu16StatusReg ); +// +// Description: Read and store the value of the status register into +// *pu16StatusReg. +// +// Returns: One of AMC_EXI_*. +// --------------------------------------------------------------------------- +AmcExiError EXI2_GetStatusReg( u16* pu16StatusReg ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/amc/AmcTypes.h b/include/dolphin/amc/AmcTypes.h new file mode 100644 index 0000000000..c11d8c49a4 --- /dev/null +++ b/include/dolphin/amc/AmcTypes.h @@ -0,0 +1,9 @@ +#ifndef _INCLUDE_DOLPHIN_AMCTYPES_H_ +#define _INCLUDE_DOLPHIN_AMCTYPES_H_ + +#include + +// EXI callback function pointer type +typedef void (*EXICallback)(s32 chan, OSContext* context); + +#endif diff --git a/include/dolphin/amcstubs/AmcExi2Stubs.h b/include/dolphin/amcstubs/AmcExi2Stubs.h deleted file mode 100644 index 99d61b1e7f..0000000000 --- a/include/dolphin/amcstubs/AmcExi2Stubs.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef AMCEXI2STUBS_H -#define AMCEXI2STUBS_H - -#include "dolphin/os.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef __OSInterruptHandler AmcEXICallback; - -typedef enum { - AMC_EXI_NO_ERROR = 0, - AMC_EXI_UNSELECTED -} AmcExiError; - -void EXI2_Init(vu8**, AmcEXICallback); -void EXI2_EnableInterrupts(void); -int EXI2_Poll(void); -AmcExiError EXI2_ReadN(void*, u32); -AmcExiError EXI2_WriteN(const void*, u32); -void EXI2_Reserve(void); -void EXI2_Unreserve(void); -BOOL AMC_IsStub(void); - -#ifdef __cplusplus -}; -#endif - -#endif /* AMCEXI2STUBS_H */ diff --git a/include/dolphin/ar.h b/include/dolphin/ar.h index 6b707e678a..d65a282811 100644 --- a/include/dolphin/ar.h +++ b/include/dolphin/ar.h @@ -1,24 +1,71 @@ -#ifndef AR_H -#define AR_H +#ifndef _DOLPHIN_AR_H_ +#define _DOLPHIN_AR_H_ -#include "dolphin/types.h" +#include #ifdef __cplusplus extern "C" { #endif -typedef void (*ARCallback)(void); +typedef void (*ARQCallback)(u32 pointerToARQRequest); -ARCallback ARRegisterDMACallback(ARCallback callback); +struct ARQRequest { + /* 0x00 */ struct ARQRequest *next; + /* 0x04 */ u32 owner; + /* 0x08 */ u32 type; + /* 0x0C */ u32 priority; + /* 0x10 */ u32 source; + /* 0x14 */ u32 dest; + /* 0x18 */ u32 length; + /* 0x1C */ ARQCallback callback; +}; + +#define ARQ_DMA_ALIGNMENT 32 + +#define ARAM_DIR_MRAM_TO_ARAM 0x00 +#define ARAM_DIR_ARAM_TO_MRAM 0x01 + +#define ARStartDMARead(mmem, aram, len) \ + ARStartDMA(ARAM_DIR_ARAM_TO_MRAM, mmem, aram, len) +#define ARStartDMAWrite(mmem, aram, len) \ + ARStartDMA(ARAM_DIR_MRAM_TO_ARAM, mmem, aram, len) + +typedef struct ARQRequest ARQRequest; + +#define ARQ_TYPE_MRAM_TO_ARAM ARAM_DIR_MRAM_TO_ARAM +#define ARQ_TYPE_ARAM_TO_MRAM ARAM_DIR_ARAM_TO_MRAM + +#define ARQ_PRIORITY_LOW 0 +#define ARQ_PRIORITY_HIGH 1 + +// AR +ARQCallback ARRegisterDMACallback(ARQCallback callback); u32 ARGetDMAStatus(void); void ARStartDMA(u32 type, u32 mainmem_addr, u32 aram_addr, u32 length); -u32 ARInit(u32* stack_index_addr, u32 num_entries); u32 ARAlloc(u32 length); +u32 ARFree(u32* length); +BOOL ARCheckInit(void); +u32 ARInit(u32* stack_index_addr, u32 num_entries); +void ARReset(void); +void ARSetSize(void); +u32 ARGetBaseAddress(void); u32 ARGetSize(void); -u16 __ARGetInterruptStatus(); +u32 ARGetInternalSize(void); +void ARClear(u32 flag); + +// ARQ +void ARQInit(void); +void ARQReset(void); +void ARQPostRequest(ARQRequest* request, u32 owner, u32 type, u32 priority, u32 source, u32 dest, u32 length, ARQCallback callback); +void ARQRemoveRequest(ARQRequest* request); +void ARQRemoveOwnerRequest(u32 owner); +void ARQFlushQueue(void); +void ARQSetChunkSize(u32 size); +u32 ARQGetChunkSize(void); +BOOL ARQCheckInit(void); #ifdef __cplusplus -}; +} #endif -#endif /* AR_H */ +#endif diff --git a/include/dolphin/arq.h b/include/dolphin/arq.h deleted file mode 100644 index 083c118a4a..0000000000 --- a/include/dolphin/arq.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef ARQ_H -#define ARQ_H - -#include "dolphin/types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ARQ_CHUNK_SIZE_DEFAULT 4096 - -typedef void (*ARQCallback)(u32 request_address); - -typedef enum _ARamType { - ARAM_DIR_MRAM_TO_ARAM, - ARAM_DIR_ARAM_TO_MRAM, -} ARamType; - -typedef enum _ArqPriotity { - ARQ_PRIORITY_LOW, - ARQ_PRIORITY_HIGH, -} ArqPriotity; - -typedef struct ARQRequest { - struct ARQRequest* next; - u32 owner; - u32 type; - u32 priority; - u32 source; - u32 destination; - u32 length; - ARQCallback callback; -} ARQRequest; - -void ARQInit(void); -void ARQPostRequest(ARQRequest* task, u32 owner, u32 type, u32 priority, u32 source, - u32 destination, u32 length, ARQCallback callback); - -#ifdef __cplusplus -}; -#endif - -#endif /* ARQ_H */ diff --git a/include/dolphin/ax.h b/include/dolphin/ax.h new file mode 100644 index 0000000000..0148446ee8 --- /dev/null +++ b/include/dolphin/ax.h @@ -0,0 +1,325 @@ +#ifndef _DOLPHIN_AX_H_ +#define _DOLPHIN_AX_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _AXPBMIX { + /* 0x00 */ u16 vL; + /* 0x02 */ u16 vDeltaL; + /* 0x04 */ u16 vR; + /* 0x06 */ u16 vDeltaR; + /* 0x08 */ u16 vAuxAL; + /* 0x0A */ u16 vDeltaAuxAL; + /* 0x0C */ u16 vAuxAR; + /* 0x0E */ u16 vDeltaAuxAR; + /* 0x10 */ u16 vAuxBL; + /* 0x12 */ u16 vDeltaAuxBL; + /* 0x14 */ u16 vAuxBR; + /* 0x16 */ u16 vDeltaAuxBR; + /* 0x18 */ u16 vAuxBS; + /* 0x1A */ u16 vDeltaAuxBS; + /* 0x1C */ u16 vS; + /* 0x1E */ u16 vDeltaS; + /* 0x20 */ u16 vAuxAS; + /* 0x22 */ u16 vDeltaAuxAS; +} AXPBMIX; + +typedef struct _AXPBITD { + /* 0x00 */ u16 flag; + /* 0x02 */ u16 bufferHi; + /* 0x04 */ u16 bufferLo; + /* 0x06 */ u16 shiftL; + /* 0x08 */ u16 shiftR; + /* 0x0A */ u16 targetShiftL; + /* 0x0C */ u16 targetShiftR; +} AXPBITD; + +typedef struct _AXPBUPDATE { + /* 0x00 */ u16 updNum[5]; + /* 0x0A */ u16 dataHi; + /* 0x0C */ u16 dataLo; +} AXPBUPDATE; + +typedef struct _AXPBDPOP { + /* 0x00 */ s16 aL; + /* 0x02 */ s16 aAuxAL; + /* 0x04 */ s16 aAuxBL; + /* 0x06 */ s16 aR; + /* 0x08 */ s16 aAuxAR; + /* 0x0A */ s16 aAuxBR; + /* 0x0C */ s16 aS; + /* 0x0E */ s16 aAuxAS; + /* 0x10 */ s16 aAuxBS; +} AXPBDPOP; + +typedef struct _AXPBVE { + /* 0x00 */ u16 currentVolume; + /* 0x02 */ s16 currentDelta; +} AXPBVE; + +typedef struct _AXPBFIR { + /* 0x00 */ u16 numCoefs; + /* 0x02 */ u16 coefsHi; + /* 0x04 */ u16 coefsLo; +} AXPBFIR; + +typedef struct _AXPBADDR { + /* 0x00 */ u16 loopFlag; + /* 0x02 */ u16 format; + /* 0x04 */ u16 loopAddressHi; + /* 0x06 */ u16 loopAddressLo; + /* 0x08 */ u16 endAddressHi; + /* 0x0A */ u16 endAddressLo; + /* 0x0C */ u16 currentAddressHi; + /* 0x0E */ u16 currentAddressLo; +} AXPBADDR; + +typedef struct _AXPBADPCM { + /* 0x00 */ u16 a[8][2]; + /* 0x20 */ u16 gain; + /* 0x22 */ u16 pred_scale; + /* 0x24 */ u16 yn1; + /* 0x26 */ u16 yn2; +} AXPBADPCM; + +typedef struct _AXPBSRC { + /* 0x00 */ u16 ratioHi; + /* 0x02 */ u16 ratioLo; + /* 0x04 */ u16 currentAddressFrac; + /* 0x06 */ u16 last_samples[4]; +} AXPBSRC; + +typedef struct _AXPBADPCMLOOP { + /* 0x00 */ u16 loop_pred_scale; + /* 0x02 */ u16 loop_yn1; + /* 0x04 */ u16 loop_yn2; +} AXPBADPCMLOOP; + +typedef struct _AXPBLPF { + u16 on; + u16 yn1; + u16 a0; + u16 b0; +} AXPBLPF; + +typedef struct _AXPB { + /* 0x00 */ u16 nextHi; + /* 0x02 */ u16 nextLo; + /* 0x04 */ u16 currHi; + /* 0x06 */ u16 currLo; + /* 0x08 */ u16 srcSelect; + /* 0x0A */ u16 coefSelect; + /* 0x0C */ u16 mixerCtrl; + /* 0x0E */ u16 state; + /* 0x10 */ u16 type; + /* 0x12 */ AXPBMIX mix; + /* 0x36 */ AXPBITD itd; + /* 0x44 */ AXPBUPDATE update; + /* 0x52 */ AXPBDPOP dpop; + /* 0x64 */ AXPBVE ve; + /* 0x68 */ AXPBFIR fir; + /* 0x6E */ AXPBADDR addr; + /* 0x7E */ AXPBADPCM adpcm; + /* 0xA6 */ AXPBSRC src; + /* 0xB4 */ AXPBADPCMLOOP adpcmLoop; + /* 0xBA */ AXPBLPF lpf; + /* 0xC2 */ u16 pad[25]; +} AXPB; + +typedef struct _AXVPB { + /* 0x000 */ void* next; + /* 0x004 */ void* prev; + /* 0x008 */ void* next1; + /* 0x00C */ u32 priority; + /* 0x010 */ void (*callback)(void*); + /* 0x014 */ u32 userContext; + /* 0x018 */ u32 index; + /* 0x01C */ u32 sync; + /* 0x020 */ u32 depop; + /* 0x024 */ u32 updateMS; + /* 0x028 */ u32 updateCounter; + /* 0x02C */ u32 updateTotal; + /* 0x030 */ u16* updateWrite; + /* 0x034 */ u16 updateData[128]; + /* 0x134 */ void* itdBuffer; + /* 0x138 */ AXPB pb; +} AXVPB; + +typedef struct _AXPBITDBUFFER { + /* 0x00 */ s16 data[32]; +} AXPBITDBUFFER; + +typedef struct _AXPBU { + /* 0x00 */ u16 data[128]; +} AXPBU; + +typedef struct _AXSPB { + /* 0x00 */ u16 dpopLHi; + /* 0x02 */ u16 dpopLLo; + /* 0x04 */ s16 dpopLDelta; + /* 0x06 */ u16 dpopRHi; + /* 0x08 */ u16 dpopRLo; + /* 0x0A */ s16 dpopRDelta; + /* 0x0C */ u16 dpopSHi; + /* 0x0E */ u16 dpopSLo; + /* 0x10 */ s16 dpopSDelta; + /* 0x12 */ u16 dpopALHi; + /* 0x14 */ u16 dpopALLo; + /* 0x16 */ s16 dpopALDelta; + /* 0x18 */ u16 dpopARHi; + /* 0x1A */ u16 dpopARLo; + /* 0x1C */ s16 dpopARDelta; + /* 0x1E */ u16 dpopASHi; + /* 0x20 */ u16 dpopASLo; + /* 0x22 */ s16 dpopASDelta; + /* 0x24 */ u16 dpopBLHi; + /* 0x26 */ u16 dpopBLLo; + /* 0x28 */ s16 dpopBLDelta; + /* 0x2A */ u16 dpopBRHi; + /* 0x2C */ u16 dpopBRLo; + /* 0x2E */ s16 dpopBRDelta; + /* 0x30 */ u16 dpopBSHi; + /* 0x32 */ u16 dpopBSLo; + /* 0x34 */ s16 dpopBSDelta; +} AXSPB; + +typedef struct _AXPROFILE { + /* 0x00 */ u64 axFrameStart; + /* 0x08 */ u64 auxProcessingStart; + /* 0x10 */ u64 auxProcessingEnd; + /* 0x18 */ u64 userCallbackStart; + /* 0x20 */ u64 userCallbackEnd; + /* 0x28 */ u64 axFrameEnd; + /* 0x30 */ u32 axNumVoices; +} AXPROFILE; + +typedef struct AX_AUX_DATA { + /* 0x00 */ s32* l; + /* 0x00 */ s32* r; + /* 0x00 */ s32* s; +} AX_AUX_DATA; + +typedef struct AX_AUX_DATA_DPL2 { + /* 0x00 */ s32* l; + /* 0x00 */ s32* r; + /* 0x00 */ s32* ls; + /* 0x00 */ s32* rs; +} AX_AUX_DATA_DPL2; + +typedef void (*AXCallback)(); + +#define AX_DSP_SLAVE_LENGTH 0xF80 +#define AX_MAX_VOICES 64 + +#define AX_SRC_TYPE_NONE 0 +#define AX_SRC_TYPE_LINEAR 1 +#define AX_SRC_TYPE_4TAP_8K 2 +#define AX_SRC_TYPE_4TAP_12K 3 +#define AX_SRC_TYPE_4TAP_16K 4 + +// sync flags +#define AX_SYNC_FLAG_COPYALL (1 << 31) +#define AX_SYNC_FLAG_UNK1 (1 << 30) // reserved, unused? +#define AX_SYNC_FLAG_UNK2 (1 << 29) // reserved, unused? +#define AX_SYNC_FLAG_UNK3 (1 << 28) // reserved, unused? +#define AX_SYNC_FLAG_UNK4 (1 << 27) // reserved, unused? +#define AX_SYNC_FLAG_UNK5 (1 << 26) // reserved, unused? +#define AX_SYNC_FLAG_UNK6 (1 << 25) // reserved, unused? +#define AX_SYNC_FLAG_UNK7 (1 << 24) // reserved, unused? +#define AX_SYNC_FLAG_UNK8 (1 << 23) // reserved, unused? +#define AX_SYNC_FLAG_UNK9 (1 << 22) // reserved, unused? +#define AX_SYNC_FLAG_UNK10 (1 << 21) // reserved, unused? +#define AX_SYNC_FLAG_COPYADPCMLOOP (1 << 20) +#define AX_SYNC_FLAG_COPYRATIO (1 << 19) +#define AX_SYNC_FLAG_COPYSRC (1 << 18) +#define AX_SYNC_FLAG_COPYADPCM (1 << 17) +#define AX_SYNC_FLAG_COPYCURADDR (1 << 16) +#define AX_SYNC_FLAG_COPYENDADDR (1 << 15) +#define AX_SYNC_FLAG_COPYLOOPADDR (1 << 14) +#define AX_SYNC_FLAG_COPYLOOP (1 << 13) +#define AX_SYNC_FLAG_COPYADDR (1 << 12) +#define AX_SYNC_FLAG_COPYFIR (1 << 11) +#define AX_SYNC_FLAG_SWAPVOL (1 << 10) +#define AX_SYNC_FLAG_COPYVOL (1 << 9) +#define AX_SYNC_FLAG_COPYDPOP (1 << 8) +#define AX_SYNC_FLAG_COPYUPDATE (1 << 7) +#define AX_SYNC_FLAG_COPYTSHIFT (1 << 6) +#define AX_SYNC_FLAG_COPYITD (1 << 5) +#define AX_SYNC_FLAG_COPYAXPBMIX (1 << 4) +#define AX_SYNC_FLAG_COPYTYPE (1 << 3) +#define AX_SYNC_FLAG_COPYSTATE (1 << 2) +#define AX_SYNC_FLAG_COPYMXRCTRL (1 << 1) +#define AX_SYNC_FLAG_COPYSELECT (1 << 0) + +#define AX_PRIORITY_STACKS 32 + +// AX +void AXInit(void); +void AXInitEx(u32 outputBufferMode); +void AXQuit(void); + +// AXAlloc +void AXFreeVoice(AXVPB* p); +AXVPB* AXAcquireVoice(u32 priority, void (*callback)(void *), u32 userContext); +void AXSetVoicePriority(AXVPB* p, u32 priority); + +// AXAux +void AXRegisterAuxACallback(void (*callback)(void*, void*), void* context); +void AXRegisterAuxBCallback(void (*callback)(void*, void*), void* context); + +// AXCL +void AXSetMode(u32 mode); +u32 AXGetMode(void); + +// AXOut +extern AXPROFILE __AXLocalProfile; + +void AXSetStepMode(u32 i); +AXCallback AXRegisterCallback(AXCallback callback); + +// AXProf +void AXInitProfile(AXPROFILE* profile, u32 maxProfiles); +u32 AXGetProfile(void); + +// AXVPB +void AXSetVoiceSrcType(AXVPB* p, u32 type); +void AXSetVoiceState(AXVPB* p, u16 state); +void AXSetVoiceType(AXVPB* p, u16 type); +void AXSetVoiceMix(AXVPB* p, AXPBMIX* mix); +void AXSetVoiceItdOn(AXVPB* p); +void AXSetVoiceItdTarget(AXVPB* p, u16 lShift, u16 rShift); +void AXSetVoiceUpdateIncrement(AXVPB* p); +void AXSetVoiceUpdateWrite(AXVPB* p, u16 param, u16 data); +void AXSetVoiceDpop(AXVPB* p, AXPBDPOP* dpop); +void AXSetVoiceVe(AXVPB* p, AXPBVE* ve); +void AXSetVoiceVeDelta(AXVPB* p, s16 delta); +void AXSetVoiceFir(AXVPB* p, AXPBFIR* fir); +void AXSetVoiceAddr(AXVPB* p, AXPBADDR* addr); +void AXSetVoiceLoop(AXVPB* p, u16 loop); +void AXSetVoiceLoopAddr(AXVPB* p, u32 addr); +void AXSetVoiceEndAddr(AXVPB* p, u32 addr); +void AXSetVoiceCurrentAddr(AXVPB* p, u32 addr); +void AXSetVoiceAdpcm(AXVPB* p, AXPBADPCM* adpcm); +void AXSetVoiceSrc(AXVPB* p, AXPBSRC* src_); +void AXSetVoiceSrcRatio(AXVPB* p, f32 ratio); +void AXSetVoiceAdpcmLoop(AXVPB* p, AXPBADPCMLOOP* adpcmloop); +void AXSetMaxDspCycles(u32 cycles); +u32 AXGetMaxDspCycles(void); +u32 AXGetDspCycles(void); +void AXSetVoiceLpf(AXVPB* p, AXPBLPF* lpf); +void AXSetVoiceLpfCoefs(AXVPB* p, u16 a0, u16 b0); +void AXGetLpfCoefs(u16 freq, u16* a0, u16* b0); + +// DSPCode +extern u16 axDspSlaveLength; +extern u16 axDspSlave[AX_DSP_SLAVE_LENGTH]; + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_AX_H_ diff --git a/include/dolphin/axart.h b/include/dolphin/axart.h new file mode 100644 index 0000000000..46c375f71c --- /dev/null +++ b/include/dolphin/axart.h @@ -0,0 +1,224 @@ +#ifndef _DOLPHIN_AXART_H_ +#define _DOLPHIN_AXART_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum __axart_type { + AXART_TYPE_NONE, + AXART_TYPE_3D, + AXART_TYPE_PANNING, + AXART_TYPE_ITD, + AXART_TYPE_SRC, + AXART_TYPE_PITCH, + AXART_TYPE_PITCH_ENV, + AXART_TYPE_PITCH_MOD, + AXART_TYPE_VOLUME, + AXART_TYPE_AUX_A_VOLUME, + AXART_TYPE_AUX_B_VOLUME, + AXART_TYPE_VOLUME_ENV, + AXART_TYPE_AUX_A_VOLUME_ENV, + AXART_TYPE_AUX_B_VOLUME_ENV, + AXART_TYPE_VOLUME_MOD, + AXART_TYPE_AUX_A_VOLUME_MOD, + AXART_TYPE_AUX_B_VOLUME_MOD, + AXART_TYPE_LPF, + + AXART_TYPE_NUM +}; + +typedef struct { + void* next; + u32 type; +} AXART_ART; + +typedef struct { + f32* lfo; + u32 length; + f32 delta; + u32 sampleIndex; + f32 counter; + f32 sample1; + f32 sample; + f32 output; +} AXART_LFO; + +typedef struct { + AXART_ART art; + f32 hAngle; + f32 vAngle; + f32 dist; + f32 closingSpeed; + u32 update; + u8 pan; + u8 span; + u8 src; + u16 itdL; + u16 itdR; + f32 pitch; + s32 attenuation; +} AXART_3D; + +typedef struct { + AXART_ART art; + u8 pan; + u8 span; +} AXART_PANNING; + +typedef struct { + AXART_ART art; + u16 itdL; + u16 itdR; +} AXART_ITD; + +typedef struct { + AXART_ART art; + u8 src; +} AXART_SRC; + +typedef struct { + AXART_ART art; + s32 cents; +} AXART_PITCH; + +typedef struct { + AXART_ART art; + s32 delta; + s32 target; + s32 cents; +} AXART_PITCH_ENV; + +typedef struct { + AXART_ART art; + AXART_LFO lfo; + s32 cents; +} AXART_PITCH_MOD; + +typedef struct { + AXART_ART art; + s32 attenuation; +} AXART_VOLUME; + +typedef struct { + AXART_ART art; + s32 attenuation; +} AXART_AUXA_VOLUME; + +typedef struct { + AXART_ART art; + s32 attenuation; +} AXART_AUXB_VOLUME; + +typedef struct { + AXART_ART art; + s32 delta; + s32 target; + s32 attenuation; +} AXART_VOLUME_ENV; + +typedef struct { + AXART_ART art; + s32 delta; + s32 target; + s32 attenuation; +} AXART_AUXA_VOLUME_ENV; + +typedef struct { + AXART_ART art; + s32 delta; + s32 target; + s32 attenuation; +} AXART_AUXB_VOLUME_ENV; + +typedef struct { + AXART_ART art; + AXART_LFO lfo; + s32 attenuation; +} AXART_VOLUME_MOD; + +typedef struct { + AXART_ART art; + AXART_LFO lfo; + s32 attenuation; +} AXART_AUXA_VOLUME_MOD; + +typedef struct { + AXART_ART art; + AXART_LFO lfo; + s32 attenuation; +} AXART_AUXB_VOLUME_MOD; + +typedef struct { + AXART_ART art; + u32 initLPF; + u32 frequency; + u32 update; +} AXART_LPF; + +typedef struct { + void* next; + void* prev; + AXVPB* axvpb; + f32 sampleRate; + AXART_ART* articulators; +} AXART_SOUND; + +#define AXART_SINE_CNT 64 +extern f32 AXARTSine[AXART_SINE_CNT]; + +// axart +void AXARTInit(void); +void AXARTQuit(void); +void AXARTServiceSounds(void); +void AXARTAddSound(AXART_SOUND* sound); +void AXARTRemoveSound(AXART_SOUND* sound); +void AXARTInitLfo(AXART_LFO* lfo, f32* samples, u32 length, f32 delta); +void AXARTInitArt3D(AXART_3D* articulator); +void AXARTInitArtPanning(AXART_PANNING* articulator); +void AXARTInitArtItd(AXART_ITD* articulator); +void AXARTInitArtSrctype(AXART_SRC* articulator); +void AXARTInitArtPitch(AXART_PITCH* articulator); +void AXARTInitArtPitchEnv(AXART_PITCH_ENV* articulator); +void AXARTInitArtPitchMod(AXART_PITCH_MOD* articulator); +void AXARTInitArtVolume(AXART_VOLUME* articulator); +void AXARTInitArtAuxAVolume(AXART_AUXA_VOLUME* articulator); +void AXARTInitArtAuxBVolume(AXART_AUXB_VOLUME* articulator); +void AXARTInitArtVolumeEnv(AXART_VOLUME_ENV* articulator); +void AXARTInitArtAuxAVolumeEnv(AXART_AUXA_VOLUME_ENV* articulator); +void AXARTInitArtAuxBVolumeEnv(AXART_AUXB_VOLUME_ENV* articulator); +void AXARTInitArtVolumeMod(AXART_VOLUME_MOD* articulator); +void AXARTInitArtAuxAVolumeMod(AXART_AUXA_VOLUME_MOD* articulator); +void AXARTInitArtAuxBVolumeMod(AXART_AUXB_VOLUME_MOD* articulator); +void AXARTInitArtLpf(AXART_LPF* articulator); + +// axart3d +void AXARTSet3DDistanceScale(f32 scale); +void AXARTSet3DDopplerScale(f32 scale); +void AXART3DSound(AXART_3D* articulator); + +// axartcents +f32 AXARTCents(s32 cents); + +// axartenv +void AXARTPitchEnv(AXART_PITCH_ENV* articulator); +void AXARTVolumeEnv(AXART_VOLUME_ENV* articulator); + +// axartlfo +void AXARTLfo(AXART_LFO* lfo); + +// axartsound +void AXARTServiceSound(AXART_SOUND* sound); +void AXARTAddArticulator(AXART_SOUND* sound, AXART_ART* articulator); + +// axartlpf +void AXARTLpf(AXART_LPF*, AXVPB*); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_AXART_H_ diff --git a/include/dolphin/axfx.h b/include/dolphin/axfx.h new file mode 100644 index 0000000000..53933c858f --- /dev/null +++ b/include/dolphin/axfx.h @@ -0,0 +1,196 @@ +#ifndef _DOLPHIN_AXFX_H_ +#define _DOLPHIN_AXFX_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct AXFX_REVSTD_DELAYLINE { + /* 0x00 */ s32 inPoint; + /* 0x04 */ s32 outPoint; + /* 0x08 */ s32 length; + /* 0x0C */ f32* inputs; + /* 0x10 */ f32 lastOutput; +} AXFX_REVSTD_DELAYLINE; + +typedef struct AXFX_REVSTD_WORK { + /* 0x000 */ AXFX_REVSTD_DELAYLINE AP[6]; + /* 0x078 */ AXFX_REVSTD_DELAYLINE C[6]; + /* 0x0F0 */ f32 allPassCoeff; + /* 0x0F4 */ f32 combCoef[6]; + /* 0x10C */ f32 lpLastout[3]; + /* 0x118 */ f32 level; + /* 0x11C */ f32 damping; + /* 0x120 */ s32 preDelayTime; + /* 0x124 */ f32* preDelayLine[3]; + /* 0x130 */ f32* preDelayPtr[3]; +} AXFX_REVSTD_WORK; + +typedef struct AXFX_REVERBSTD { + /* 0x000 */ AXFX_REVSTD_WORK rv; + /* 0x13C */ u8 tempDisableFX; + /* 0x140 */ f32 coloration; + /* 0x144 */ f32 mix; + /* 0x148 */ f32 time; + /* 0x14C */ f32 damping; + /* 0x150 */ f32 preDelay; +} AXFX_REVERBSTD; + +typedef struct AXFX_BUFFERUPDATE { + /* 0x00 */ s32* left; + /* 0x04 */ s32* right; + /* 0x08 */ s32* surround; +} AXFX_BUFFERUPDATE; + +typedef struct AXFX_BUFFERUPDATE_DPL2 { + /* 0x00 */ s32* L; + /* 0x04 */ s32* R; + /* 0x08 */ s32* Ls; + /* 0x0C */ s32* Rs; +} AXFX_BUFFERUPDATE_DPL2; + +// REVHI Structs + +typedef struct AXFX_REVHI_DELAYLINE { + /* 0x00 */ s32 inPoint; + /* 0x04 */ s32 outPoint; + /* 0x08 */ s32 length; + /* 0x0C */ f32* inputs; + /* 0x10 */ f32 lastOutput; +} AXFX_REVHI_DELAYLINE; + +typedef struct AXFX_REVHI_WORK { + /* 0x000 */ AXFX_REVHI_DELAYLINE AP[9]; + /* 0x0B4 */ AXFX_REVHI_DELAYLINE C[9]; + /* 0x168 */ f32 allPassCoeff; + /* 0x16C */ f32 combCoef[9]; + /* 0x190 */ f32 lpLastout[3]; + /* 0x19C */ f32 level; + /* 0x1A0 */ f32 damping; + /* 0x1A4 */ s32 preDelayTime; + /* 0x1A8 */ f32 crosstalk; + /* 0x1AC */ f32* preDelayLine[3]; + /* 0x1B8 */ f32* preDelayPtr[3]; +} AXFX_REVHI_WORK; + +typedef struct AXFX_REVHI_WORK_DPL2 { + /* 0x000 */ AXFX_REVHI_DELAYLINE AP[12]; + /* 0x0F0 */ AXFX_REVHI_DELAYLINE C[12]; + /* 0x1E0 */ f32 allPassCoeff; + /* 0x1E4 */ f32 combCoef[12]; + /* 0x214 */ f32 lpLastout[4]; + /* 0x224 */ f32 level; + /* 0x228 */ f32 damping; + /* 0x22C */ s32 preDelayTime; + /* 0x230 */ f32 crosstalk; + /* 0x234 */ f32* preDelayLine[4]; + /* 0x244 */ f32* preDelayPtr[4]; +} AXFX_REVHI_WORK_DPL2; + +typedef struct AXFX_REVERBHI { + /* 0x000 */ AXFX_REVHI_WORK rv; + /* 0x1C4 */ u8 tempDisableFX; + /* 0x1C8 */ f32 coloration; + /* 0x1CC */ f32 mix; + /* 0x1D0 */ f32 time; + /* 0x1D4 */ f32 damping; + /* 0x1D8 */ f32 preDelay; + /* 0x1DC */ f32 crosstalk; +} AXFX_REVERBHI; + +typedef struct AXFX_REVERBHI_DPL2 { + /* 0x000 */ AXFX_REVHI_WORK_DPL2 rv; + /* 0x254 */ u8 tempDisableFX; + /* 0x258 */ f32 coloration; + /* 0x25C */ f32 mix; + /* 0x260 */ f32 time; + /* 0x264 */ f32 damping; + /* 0x268 */ f32 preDelay; +} AXFX_REVERBHI_DPL2; + +typedef struct AXFX_DELAY { + /* 0x00 */ u32 currentSize[3]; + /* 0x0C */ u32 currentPos[3]; + /* 0x18 */ u32 currentFeedback[3]; + /* 0x24 */ u32 currentOutput[3]; + /* 0x30 */ s32* left; + /* 0x34 */ s32* right; + /* 0x38 */ s32* sur; + /* 0x3C */ u32 delay[3]; + /* 0x48 */ u32 feedback[3]; + /* 0x54 */ u32 output[3]; +} AXFX_DELAY; + +typedef struct AXFX_CHORUS_SRCINFO { + /* 0x00 */ s32* dest; + /* 0x04 */ s32* smpBase; + /* 0x08 */ s32* old; + /* 0x0C */ u32 posLo; + /* 0x10 */ u32 posHi; + /* 0x14 */ u32 pitchLo; + /* 0x18 */ u32 pitchHi; + /* 0x1C */ u32 trigger; + /* 0x20 */ u32 target; +} AXFX_CHORUS_SRCINFO; + +typedef struct AXFX_CHORUS_WORK { + /* 0x00 */ s32* lastLeft[3]; + /* 0x0C */ s32* lastRight[3]; + /* 0x18 */ s32* lastSur[3]; + /* 0x24 */ u8 currentLast; + /* 0x28 */ s32 oldLeft[4]; + /* 0x38 */ s32 oldRight[4]; + /* 0x48 */ s32 oldSur[4]; + /* 0x58 */ u32 currentPosLo; + /* 0x5C */ u32 currentPosHi; + /* 0x60 */ s32 pitchOffset; + /* 0x64 */ u32 pitchOffsetPeriodCount; + /* 0x68 */ u32 pitchOffsetPeriod; + /* 0x6C */ AXFX_CHORUS_SRCINFO src; +} AXFX_CHORUS_WORK; + +typedef struct AXFX_CHORUS { + /* 0x00 */ AXFX_CHORUS_WORK work; + /* 0x90 */ u32 baseDelay; + /* 0x94 */ u32 variation; + /* 0x98 */ u32 period; +} AXFX_CHORUS; + +// chorus +int AXFXChorusInit(AXFX_CHORUS* c); +int AXFXChorusShutdown(AXFX_CHORUS* c); +int AXFXChorusSettings(AXFX_CHORUS* c); +void AXFXChorusCallback(AXFX_BUFFERUPDATE* bufferUpdate, AXFX_CHORUS* chorus); + +// delay +void AXFXDelayCallback(AXFX_BUFFERUPDATE* bufferUpdate, AXFX_DELAY* delay); +int AXFXDelaySettings(AXFX_DELAY* delay); +int AXFXDelayInit(AXFX_DELAY* delay); +int AXFXDelayShutdown(AXFX_DELAY* delay); + +// reverb_hi +void DoCrossTalk(s32* l, s32* r, f32 cross, f32 invcross); +int AXFXReverbHiInit(AXFX_REVERBHI* rev); +int AXFXReverbHiShutdown(AXFX_REVERBHI* rev); +int AXFXReverbHiSettings(AXFX_REVERBHI* rev); +void AXFXReverbHiCallback(AXFX_BUFFERUPDATE* bufferUpdate, AXFX_REVERBHI* reverb); + +// reverb_hi_4ch +int AXFXReverbHiInitDpl2(AXFX_REVERBHI_DPL2* reverb); +int AXFXReverbHiShutdownDpl2(AXFX_REVERBHI_DPL2* reverb); +int AXFXReverbHiSettingsDpl2(AXFX_REVERBHI_DPL2* rev); +void AXFXReverbHiCallbackDpl2(AXFX_BUFFERUPDATE_DPL2* bufferUpdate, AXFX_REVERBHI_DPL2* reverb); + +// reverb_std +int AXFXReverbStdInit(AXFX_REVERBSTD* rev); +int AXFXReverbStdShutdown(AXFX_REVERBSTD* rev); +int AXFXReverbStdSettings(AXFX_REVERBSTD* rev); +void AXFXReverbStdCallback(AXFX_BUFFERUPDATE* bufferUpdate, AXFX_REVERBSTD* reverb); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_AXFX_H_ diff --git a/include/dolphin/base/PPCArch.h b/include/dolphin/base/PPCArch.h index 120ba92252..35f5da9c71 100644 --- a/include/dolphin/base/PPCArch.h +++ b/include/dolphin/base/PPCArch.h @@ -1,5 +1,5 @@ -#ifndef PPCARCH_H -#define PPCARCH_H +#ifndef _DOLPHIN_PPCARCH +#define _DOLPHIN_PPCARCH #include "dolphin/types.h" @@ -139,32 +139,32 @@ extern "C" { /*---------------------------------------------------------------------------* HID0 bits *---------------------------------------------------------------------------*/ -#define HID0_EMCP 0x80000000 // Enable MCP -#define HID0_DBP 0x40000000 // Enable 60x bus address and data parity chk -#define HID0_EBA 0x20000000 // Enable 60x address parity checking -#define HID0_EBD 0x10000000 // Enable 60x data parity checking -#define HID0_BCLK 0x08000000 // CLK_OUT output enable and clk selection -#define HID0_ECLK 0x02000000 // CLK_OUT output enable and clk selection -#define HID0_PAR 0x01000000 // Disable !ARTRY precharge -#define HID0_DOZE 0x00800000 // Doze mode enable -#define HID0_NAP 0x00400000 // Nap mode enable -#define HID0_SLEEP 0x00200000 // Sleep mode enable -#define HID0_DPM 0x00100000 // Dynamic power management enable -#define HID0_NHR 0x00010000 // Not hard reset (0 hard reset if s/w set it) -#define HID0_ICE 0x00008000 // Instruction cache enable -#define HID0_DCE 0x00004000 // Data cache enable -#define HID0_ILOCK 0x00002000 // ICache lock -#define HID0_DLOCK 0x00001000 // DCache lock -#define HID0_ICFI 0x00000800 // ICache flash invalidate -#define HID0_DCFI 0x00000400 // DCache flash invalidate -#define HID0_SPD 0x00000200 // Speculative cache access enable (0 enable) -#define HID0_IFEM 0x00000100 // Enable M bit on bus for Ifetch -#define HID0_SGE 0x00000080 // Store gathering enable -#define HID0_DCFA 0x00000040 // DCache flush assist - set before a flush -#define HID0_BTIC 0x00000020 // Branch target icache enable -#define HID0_ABE 0x00000008 // Address bcast enable -#define HID0_BHT 0x00000004 // Branch history table enable -#define HID0_NOOPTI 0x00000001 // No-op Dcache touch instructions +#define HID0_EMCP 0x80000000u // Enable MCP +#define HID0_DBP 0x40000000u // Enable 60x bus address and data parity chk +#define HID0_EBA 0x20000000u // Enable 60x address parity checking +#define HID0_EBD 0x10000000u // Enable 60x data parity checking +#define HID0_BCLK 0x08000000u // CLK_OUT output enable and clk selection +#define HID0_ECLK 0x02000000u // CLK_OUT output enable and clk selection +#define HID0_PAR 0x01000000u // Disable !ARTRY precharge +#define HID0_DOZE 0x00800000u // Doze mode enable +#define HID0_NAP 0x00400000u // Nap mode enable +#define HID0_SLEEP 0x00200000u // Sleep mode enable +#define HID0_DPM 0x00100000u // Dynamic power management enable +#define HID0_NHR 0x00010000u // Not hard reset (0 hard reset if s/w set it) +#define HID0_ICE 0x00008000u // Instruction cache enable +#define HID0_DCE 0x00004000u // Data cache enable +#define HID0_ILOCK 0x00002000u // ICache lock +#define HID0_DLOCK 0x00001000u // DCache lock +#define HID0_ICFI 0x00000800u // ICache flash invalidate +#define HID0_DCFI 0x00000400u // DCache flash invalidate +#define HID0_SPD 0x00000200u // Speculative cache access enable (0 enable) +#define HID0_IFEM 0x00000100u // Enable M bit on bus for Ifetch +#define HID0_SGE 0x00000080u // Store gathering enable +#define HID0_DCFA 0x00000040u // DCache flush assist - set before a flush +#define HID0_BTIC 0x00000020u // Branch target icache enable +#define HID0_ABE 0x00000008u // Address bcast enable +#define HID0_BHT 0x00000004u // Branch history table enable +#define HID0_NOOPTI 0x00000001u // No-op Dcache touch instructions #define HID0_ICE_BIT 16 // Instruction cache enable #define HID0_DCE_BIT 17 // Data cache enable @@ -207,7 +207,8 @@ extern "C" { #define GQR_STORE_SCALE_MASK 0x00003F00 // store scale field #define GQR_STORE_TYPE_MASK 0x00000007 // store type field -typedef struct { +typedef struct +{ u32 _pad0 :2; u32 loadScale :6; u32 _pad1 :5; @@ -218,7 +219,8 @@ typedef struct { u32 storeType :3; } PPC_GQR_t; -typedef union { +typedef union +{ u32 val; PPC_GQR_t f; } PPC_GQR_u; @@ -234,18 +236,21 @@ typedef union { #define DMA_L_TRIGGER 0x00000002 // 0 - cmd inactive, 1 - cmd rdy #define DMA_L_FLUSH 0x00000001 // 1 - Flush DMA queue -typedef struct { +typedef struct +{ u32 memAddr :27; u32 dmaLenU :5; } PPC_DMA_U_t; -typedef union { +typedef union +{ u32 val; PPC_DMA_U_t f; } PPC_DMA_U_u; -typedef struct { +typedef struct +{ u32 lcAddr :27; u32 dmaLd :1; u32 dmaLenL :2; @@ -254,7 +259,8 @@ typedef struct { } PPC_DMA_L_t; -typedef union { +typedef union +{ u32 val; PPC_DMA_L_t f; } PPC_DMA_L_u; @@ -466,39 +472,71 @@ typedef union { #define FPSCR_NI_BIT 29 // Non-IEEE mode #endif -u32 PPCMfmsr(void); -void PPCMtmsr(register u32 newMSR); -u32 PPCMfhid0(void); -void PPCMthid0(register u32 newHID0); -u32 PPCMfl2cr(void); -void PPCMtl2cr(register u32 newL2cr); -void PPCMtdec(register u32 newDec); -void PPCSync(void); -void PPCHalt(void); -void PPCMtmmcr0(register u32 newMmcr0); -void PPCMtmmcr1(register u32 newMmcr1); -void PPCMtpmc1(register u32 newPmc1); -void PPCMtpmc2(register u32 newPmc2); -void PPCMtpmc3(register u32 newPmc3); -void PPCMtpmc4(register u32 newPmc4); -u32 PPCMffpscr(void); -void PPCMtfpscr(register u32 newFPSCR); -u32 PPCMfhid2(void); -void PPCMthid2(register u32 newhid2); -void PPCMtwpar(register u32 newwpar); -void PPCDisableSpeculation(void); -void PPCSetFpNonIEEEMode(void); - union FpscrUnion { f64 f; struct { u32 fpscr_pad; u32 fpscr; - } u; + } u; }; +// PPCArch +u32 PPCMfmsr(); +void PPCMtmsr(u32 newMSR); +u32 PPCOrMsr(u32 value); +u32 PPCMfhid0(); +void PPCMthid0(u32 newHID0); +u32 PPCMfl2cr(); +void PPCMtl2cr(u32 newL2cr); +void PPCMtdec(u32 newDec); +void PPCSync(); +void PPCHalt(); +u32 PPCMffpscr(); +void PPCMtfpscr(u32 newFPSCR); +u32 PPCMfhid2(); +void PPCMthid2(u32 newhid2); +u32 PPCMfwpar(); +void PPCMtwpar(u32 newwpar); +void PPCEnableSpeculation(); +void PPCDisableSpeculation(); +void PPCSetFpIEEEMode(); +void PPCSetFpNonIEEEMode(); +u32 PPCMfpmc4(); +u32 PPCMfpmc3(); +u32 PPCMfpmc1(); +void PPCMtpmc1(u32 newPmc1); +void PPCMtpmc2(u32 newPmc1); +void PPCMtpmc3(u32 newPmc1); +void PPCMtpmc4(u32 newPmc1); +void PPCMtmmcr0(u32 newMmcr0); +void PPCMtmmcr1(u32 newMmcr0); +void PPCMtdmaU(u32 newdmau); +void PPCMtdmaL(u32 newdmal); +u32 PPCMfdec(void); +u32 PPCMfpmc2(void); +u32 PPCAndMsr(u32 value); +u32 PPCAndCMsr(u32 value); +u32 PPCMfhid1(); +void PPCEieio(); +u32 PPCMfmmcr0(); +u32 PPCMfmmcr1(); +u32 PPCMfpmc2(); +u32 PPCMfsia(); +void PPCMtsia(u32 newSia); +u32 PPCMfdmaL(); +u32 PPCMfpvr(); +u32 PPCMfdmaU(); + +// PPCPm +void PMBegin(void); +void PMEnd(void); +void PMCycles(void); +void PML1FetchMisses(void); +void PML1MissCycles(void); +void PMInstructions(void); + #ifdef __cplusplus -}; +} #endif -#endif /* PPCARCH_H */ +#endif // _DOLPHIN_PPCARCH diff --git a/include/dolphin/card.h b/include/dolphin/card.h index b4caf50616..6ed175b71c 100644 --- a/include/dolphin/card.h +++ b/include/dolphin/card.h @@ -1,67 +1,193 @@ -#ifndef CARD_H -#define CARD_H +#ifndef _DOLPHIN_CARD_H_ +#define _DOLPHIN_CARD_H_ -#include "dolphin/types.h" +#include +#include +#include #ifdef __cplusplus extern "C" { #endif -#define CARD_ENCODE_ANSI 0u -#define CARD_ENCODE_SJIS 1u - -/* Sizes */ -#define CARD_WORKAREA_SIZE (5 * 8 * 1024) -#define CARD_READ_SIZE 512 -#define CARD_MAX_FILE 127 -#define CARD_COMMENT_SIZE 64 #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 { + s32 chan; + s32 fileNo; + s32 offset; + s32 length; + u16 iBlock; +} CARDFileInfo; + +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 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 CARDDecParam { + /* 0x00 */ u8* inputAddr; + /* 0x04 */ u32 inputLength; + /* 0x08 */ u32 aramAddr; + /* 0x0C */ u8* outputAddr; +} CARDDecParam; + +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 CARDDirCheck { + /* 0x00 */ u8 padding0[56]; + /* 0x38 */ u16 padding1; + /* 0x3A */ s16 checkCode; + /* 0x3C */ u16 checkSum; + /* 0x3E */ u16 checkSumInv; +} CARDDirCheck; + +typedef struct CARDStat { + /* 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 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 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 -/* Icon animation */ -#define CARD_MODE_NORMAL 0 -#define CARD_MODE_FAST 1 - -#define CARDGetBannerFormat(stat) (((stat)->bannerFormat) & CARD_STAT_BANNER_MASK) -#define CARDGetIconAnim(stat) (((stat)->bannerFormat) & CARD_STAT_ANIM_MASK) -#define CARDGetIconFormat(stat, n) (((stat)->iconFormat >> (2 * (n))) & CARD_STAT_ICON_MASK) -#define CARDGetIconSpeed(stat, n) (((stat)->iconSpeed >> (2 * (n))) & CARD_STAT_SPEED_MASK) -#define CARDSetBannerFormat(stat, f) \ - ((stat)->bannerFormat = (u8)(((stat)->bannerFormat & ~CARD_STAT_BANNER_MASK) | (f))) -#define CARDSetIconAnim(stat, f) \ - ((stat)->bannerFormat = (u8)(((stat)->bannerFormat & ~CARD_STAT_ANIM_MASK) | (f))) -#define CARDSetIconFormat(stat, n, f) \ - ((stat)->iconFormat = \ - (u16)(((stat)->iconFormat & ~(CARD_STAT_ICON_MASK << (2 * (n)))) | ((f) << (2 * (n))))) -#define CARDSetIconSpeed(stat, n, f) \ - ((stat)->iconSpeed = \ - (u16)(((stat)->iconSpeed & ~(CARD_STAT_SPEED_MASK << (2 * (n)))) | ((f) << (2 * (n))))) -#define CARDSetIconAddress(stat, addr) ((stat)->iconAddr = (u32)(addr)) -#define CARDSetCommentAddress(stat, addr) ((stat)->commentAddr = (u32)(addr)) -#define CARDGetFileNo(fileInfo) ((fileInfo)->fileNo) - -#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 CARD_STAT_ICON_NONE 0 #define CARD_STAT_ICON_C8 1 #define CARD_STAT_ICON_RGB5A3 2 @@ -72,103 +198,125 @@ extern "C" { #define CARD_STAT_BANNER_RGB5A3 2 #define CARD_STAT_BANNER_MASK 3 -#define CARD_STAT_ANIM_LOOP 0x00 -#define CARD_STAT_ANIM_BOUNCE 0x04 -#define CARD_STAT_ANIM_MASK 0x04 +#define CARD_ENCODE_ANSI 0 +#define CARD_ENCODE_SJIS 1 -#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 CARDGetDirCheck(dir) ((CARDDirCheck*)&(dir)[CARD_MAX_FILE]) +#define CARDGetBannerFormat(stat) (((stat)->bannerFormat) & CARD_STAT_BANNER_MASK) +#define CARDGetIconAnim(stat) (((stat)->bannerFormat) & CARD_STAT_ANIM_MASK) +#define CARDGetIconFormat(stat, n) (((stat)->iconFormat >> (2 * (n))) & CARD_STAT_ICON_MASK) +#define CARDGetIconSpeed(stat, n) (((stat)->iconSpeed >> (2 * (n))) & CARD_STAT_SPEED_MASK) +#define CARDSetBannerFormat(stat, f) \ + ((stat)->bannerFormat = (u8)(((stat)->bannerFormat & ~CARD_STAT_BANNER_MASK) | (f))) +#define CARDSetIconAnim(stat, f) \ + ((stat)->bannerFormat = (u8)(((stat)->bannerFormat & ~CARD_STAT_ANIM_MASK) | (f))) +#define CARDSetIconFormat(stat, n, f) \ + ((stat)->iconFormat = \ + (u16)(((stat)->iconFormat & ~(CARD_STAT_ICON_MASK << (2 * (n)))) | ((f) << (2 * (n))))) +#define CARDSetIconSpeed(stat, n, f) \ + ((stat)->iconSpeed = \ + (u16)(((stat)->iconSpeed & ~(CARD_STAT_SPEED_MASK << (2 * (n)))) | ((f) << (2 * (n))))) +#define CARDSetIconAddress(stat, addr) ((stat)->iconAddr = (u32)(addr)) +#define CARDSetCommentAddress(stat, addr) ((stat)->commentAddr = (u32)(addr)) +#define CARDGetFileNo(fileInfo) ((fileInfo)->fileNo) -#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 +extern u32 __CARDFreq; -typedef struct CARDFileInfo { - s32 chan; - s32 fileNo; +#if DEBUG +#define CARDFreq __CARDFreq +#else +#define CARDFreq EXI_FREQ_16M +#endif - s32 offset; - s32 length; - u16 iBlock; - u16 __padding; -} CARDFileInfo; - -typedef struct CARDStat { - char fileName[CARD_FILENAME_MAX]; - u32 length; - u32 time; // seconds since 01/01/2000 midnight - u8 gameName[4]; - u8 company[2]; - - u8 bannerFormat; - u8 __padding; - u32 iconAddr; // offset to the banner, bannerTlut, icon, iconTlut data set. - u16 iconFormat; - u16 iconSpeed; - u32 commentAddr; // offset to the pair of 32 byte character strings. - - u32 offsetBanner; - u32 offsetBannerTlut; - u32 offsetIcon[CARD_ICON_MAX]; - u32 offsetIconTlut; - u32 offsetData; -} CARDStat; - -typedef void (*CARDCallback)(s32 chan, s32 result); - -/* CARDBios */ void CARDInit(void); -BOOL CARDGetFastMode(void); +s32 CARDGetResultCode(s32 chan); +s32 CARDCheckAsync(s32 chan, CARDCallback callback); s32 CARDFreeBlocks(s32 chan, s32* byteNotUsed, s32* filesNotUsed); +s32 CARDRenameAsync(s32 chan, const char* oldName, const char* newName, CARDCallback callback); -/* CARDCheck */ +// CARDBios +void CARDInit(void); +s32 CARDGetResultCode(s32 chan); +s32 CARDFreeBlocks(s32 chan, s32* byteNotUsed, s32* filesNotUsed); +s32 CARDGetEncoding(s32 chan, u16* encode); +s32 CARDGetMemSize(s32 chan, u16* size); +s32 CARDGetSectorSize(s32 chan, u32* size); +const DVDDiskID* CARDGetDiskID(s32 chan); +s32 CARDSetDiskID(s32 chan, const DVDDiskID* diskID); +BOOL CARDSetFastMode(BOOL enable); +BOOL CARDGetFastMode(void); +s32 CARDGetCurrentMode(s32 chan, u32* mode); + +// CARDCheck +s32 CARDCheckExAsync(s32 chan, s32* xferBytes, CARDCallback callback); +s32 CARDCheckAsync(s32 chan, CARDCallback callback); +s32 CARDCheckEx(s32 chan, s32* xferBytes); s32 CARDCheck(s32 chan); -static s32 CARDCheckExAsync(s32 chan, s32* xferBytes, CARDCallback callback); -/* CARDCreate */ -static s32 CARDCreateAsync(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo, - CARDCallback callback); +// CARDCreate +s32 CARDCreateAsync(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo, CARDCallback callback); s32 CARDCreate(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo); -/* CARDFormat */ +// CARDDelete +s32 CARDFastDeleteAsync(s32 chan, s32 fileNo, CARDCallback callback); +s32 CARDFastDelete(s32 chan, s32 fileNo); +s32 CARDDeleteAsync(s32 chan, const char* fileName, CARDCallback callback); +s32 CARDDelete(s32 chan, const char* fileName); + +// CARDErase +s32 CARDEraseAsync(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDCallback callback); +s32 CARDErase(CARDFileInfo* fileInfo, s32 length, s32 offset); + +// CARDFormat s32 CARDFormat(s32 chan); -/* CARDMount */ -s32 CARDProbe(s32 chan); +// CARDMount +int CARDProbe(s32 chan); s32 CARDProbeEx(s32 chan, s32* memSize, s32* sectorSize); -s32 CARDMount(s32 chan, void* workArea, CARDCallback attachCb); +s32 CARDMountAsync(s32 chan, void* workArea, CARDCallback detachCallback, CARDCallback attachCallback); +s32 CARDMount(s32 chan, void* workArea, CARDCallback detachCallback); s32 CARDUnmount(s32 chan); -static s32 CARDMountAsync(s32 chan, void* workArea, CARDCallback detachCb, CARDCallback attachCb); -/* CARDNet */ +// CARDNet +u16 CARDSetVendorID(u16 vendorID); +u16 CARDGetVendorID(); s32 CARDGetSerialNo(s32 chan, u64* serialNo); +s32 CARDGetUniqueCode(s32 chan, u64* uniqueCode); +s32 CARDGetAttributes(s32 chan, s32 fileNo, u8* attr); +s32 CARDSetAttributesAsync(s32 chan, s32 fileNo, u8 attr, CARDCallback callback); +s32 CARDSetAttributes(s32 chan, s32 fileNo, u8 attr); -/* CARDOpen */ +// CARDOpen +s32 CARDFastOpen(s32 chan, s32 fileNo, CARDFileInfo* fileInfo); s32 CARDOpen(s32 chan, const char* fileName, CARDFileInfo* fileInfo); s32 CARDClose(CARDFileInfo* fileInfo); -/* CARDRead */ -static s32 CARDReadAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, - CARDCallback callback); -s32 CARDRead(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset); +// CARDProgram +s32 CARDProgramAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, CARDCallback callback); +s32 CARDProgram(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset); -/* CARDStat */ -s32 CARDSetStatus(s32 chan, s32 fileNo, CARDStat* stat); +// CARDRdwr +s32 CARDGetXferredBytes(s32 chan); + +// CARDRead +s32 CARDReadAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, CARDCallback callback); +s32 CARDRead(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset); +s32 CARDCancel(CARDFileInfo* fileInfo); + +// CARDRename +s32 CARDRename(s32 chan, const char* oldName, const char* newName); + +// CARDStat s32 CARDGetStatus(s32 chan, s32 fileNo, CARDStat* stat); -static s32 CARDSetStatusAsync(s32 chan, s32 fileNo, CARDStat* stat, CARDCallback callback); +s32 CARDSetStatusAsync(s32 chan, s32 fileNo, CARDStat* stat, CARDCallback callback); +s32 CARDSetStatus(s32 chan, s32 fileNo, CARDStat* stat); -/* CARDWrite */ -static s32 CARDWriteAsync(CARDFileInfo* fileInfo, const void* buf, s32 length, s32 offset, - CARDCallback callback); -s32 CARDWrite(CARDFileInfo* fileInfo, const void* buf, s32 length, s32 offset); +// CARDWrite +s32 CARDWriteAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, CARDCallback callback); +s32 CARDWrite(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset); #ifdef __cplusplus } #endif -#endif /* CARD_H */ +#endif diff --git a/include/dolphin/card/CARDBios.h b/include/dolphin/card/CARDBios.h deleted file mode 100644 index e63ef34a39..0000000000 --- a/include/dolphin/card/CARDBios.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef CARDBIOS_H -#define CARDBIOS_H - - -#endif /* CARDBIOS_H */ diff --git a/include/dolphin/card/CARDBlock.h b/include/dolphin/card/CARDBlock.h deleted file mode 100644 index ce5374ad72..0000000000 --- a/include/dolphin/card/CARDBlock.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef CARDBLOCK_H -#define CARDBLOCK_H - - -#endif /* CARDBLOCK_H */ diff --git a/include/dolphin/card/CARDCheck.h b/include/dolphin/card/CARDCheck.h deleted file mode 100644 index 67de6dfd0c..0000000000 --- a/include/dolphin/card/CARDCheck.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef CARDCHECK_H -#define CARDCHECK_H - - -#endif /* CARDCHECK_H */ diff --git a/include/dolphin/card/CARDCreate.h b/include/dolphin/card/CARDCreate.h deleted file mode 100644 index 7a7d1717eb..0000000000 --- a/include/dolphin/card/CARDCreate.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef CARDCREATE_H -#define CARDCREATE_H - - -#endif /* CARDCREATE_H */ diff --git a/include/dolphin/card/CARDDir.h b/include/dolphin/card/CARDDir.h deleted file mode 100644 index 86a4a9a5ce..0000000000 --- a/include/dolphin/card/CARDDir.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef CARDDIR_H -#define CARDDIR_H - - -#endif /* CARDDIR_H */ diff --git a/include/dolphin/card/CARDFormat.h b/include/dolphin/card/CARDFormat.h deleted file mode 100644 index 61d5c4d178..0000000000 --- a/include/dolphin/card/CARDFormat.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef CARDFORMAT_H -#define CARDFORMAT_H - - -#endif /* CARDFORMAT_H */ diff --git a/include/dolphin/card/CARDMount.h b/include/dolphin/card/CARDMount.h deleted file mode 100644 index 739eb062d3..0000000000 --- a/include/dolphin/card/CARDMount.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef CARDMOUNT_H -#define CARDMOUNT_H - - -#endif /* CARDMOUNT_H */ diff --git a/include/dolphin/card/CARDNet.h b/include/dolphin/card/CARDNet.h deleted file mode 100644 index 4416a463fb..0000000000 --- a/include/dolphin/card/CARDNet.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef CARDNET_H -#define CARDNET_H - - -#endif /* CARDNET_H */ diff --git a/include/dolphin/card/CARDOpen.h b/include/dolphin/card/CARDOpen.h deleted file mode 100644 index c4be4d33d0..0000000000 --- a/include/dolphin/card/CARDOpen.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef CARDOPEN_H -#define CARDOPEN_H - - -#endif /* CARDOPEN_H */ diff --git a/include/dolphin/card/CARDPriv.h b/include/dolphin/card/CARDPriv.h deleted file mode 100644 index 86585faf87..0000000000 --- a/include/dolphin/card/CARDPriv.h +++ /dev/null @@ -1,184 +0,0 @@ -#ifndef CARDPRIV_H -#define CARDPRIV_H - -#include "dolphin/os/OSAlarm.h" -#include "dolphin/os/OSThread.h" -#include "dolphin/dsp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#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_PAGE_SIZE 128u -#define CARD_SEG_SIZE 512u - -#define CARD_NUM_SYSTEM_BLOCK 5 -#define CARD_SYSTEM_BLOCK_SIZE (8 * 1024u) - -#define CARD_MAX_MOUNT_STEP (CARD_NUM_SYSTEM_BLOCK + 2) - -typedef struct DVDDiskID DVDDiskID; - -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 CARDDirCheck { - u8 padding0[64 - 2 * 4]; - u16 padding1; - s16 checkCode; - u16 checkSum; - u16 checkSumInv; -} CARDDirCheck; - -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; - /* 0x02C */ u32 scramble; - /* 0x030 */ DSPTaskInfo task; - /* 0x080 */ void* workArea; - /* 0x084 */ CARDDir* currentDir; - /* 0x088 */ u16* currentFat; - /* 0x08C */ OSThreadQueue threadQueue; - /* 0x094 */ u8 cmd[9]; - /* 0x0A0 */ s32 cmdlen; - /* 0x0A4 */ vu32 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 CARDID { - u8 serial[32]; // flashID[12] + timebase[8] + counterBias[4] + language[4] + XXX[4] - u16 deviceID; - u16 size; - u16 encode; // character set -- 0: S-JIS, 1: ANSI - - u8 padding[512 - 32 - 5 * 2]; - - u16 checkSum; - u16 checkSumInv; -} CARDID; - -void __CARDDefaultApiCallback(s32 chan, s32 result); -s32 __CARDEraseSector(s32 chan, u32 addr, CARDCallback callback); -s32 __CARDPutControlBlock(struct CARDControl* card, s32 result); -void __CARDSyncCallback(s32 chan, s32 result); -u16* __CARDGetFatBlock(CARDControl* card); - -/* CARDBios */ -void __CARDExtHandler(s32 chan, OSContext* context); -void __CARDExiHandler(s32 chan, OSContext* context); -void __CARDTxHandler(s32 chan, OSContext* context); -void __CARDUnlockedHandler(s32 chan, OSContext* context); -s32 __CARDEnableInterrupt(s32 chan, BOOL enable); -s32 __CARDReadStatus(s32 chan, u8* status); -s32 __CARDReadVendorID(s32 chan, u16* vendorId); -s32 __CARDClearStatus(s32 chan); -s32 __CARDStart(s32 chan, CARDCallback txCallback, CARDCallback exiCallback); -s32 __CARDReadSegment(s32 chan, CARDCallback callback); -s32 __CARDWritePage(s32 chan, CARDCallback callback); -u16 __CARDGetFontEncode(void); -void __CARDSetDiskID(const DVDDiskID* id); -s32 __CARDGetControlBlock(s32 chan, struct CARDControl** pcard); -s32 __CARDSync(s32 chan); - -/* CARDBlock */ -s32 __CARDAllocBlock(s32 chan, u32 cBlock, CARDCallback callback); -s32 __CARDUpdateFatBlock(s32 chan, u16* fat, CARDCallback callback); - -/* CARDCheck */ -void __CARDCheckSum(void* ptr, int length, u16* checksum, u16* checksumInv); -s32 __CARDVerify(CARDControl* card); - -/* CARDDir */ -CARDDir* __CARDGetDirBlock(CARDControl* card); -s32 __CARDUpdateDir(s32 chan, CARDCallback callback); - -/* CARDFormat */ -s32 __CARDFormatRegionAsync(s32 chan, u16 encode, CARDCallback callback); - -/* CARDMount */ -void __CARDMountCallback(s32 chan, s32 result); - -/* CARDOpen */ -BOOL __CARDCompareFileName(CARDDir* ent, const char* fileName); -s32 __CARDAccess(CARDControl* card, CARDDir* ent); -s32 __CARDIsWritable(CARDControl* card, CARDDir* ent); -s32 __CARDIsReadable(CARDControl* card, CARDDir* ent); - -/* CARDRdwr */ -s32 __CARDRead(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback); -s32 __CARDWrite(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback); - -/* CARDRead */ -s32 __CARDSeek(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDControl** pcard); - -/* CARDUnlock */ -s32 __CARDUnlock(s32 chan, u8 flashID[12]); - -#define CARDIsValidBlockNo(card, iBlock) \ - (CARD_NUM_SYSTEM_BLOCK <= (iBlock) && (iBlock) < (card)->cBlock) -#define __CARDGetDirCheck(dir) ((CARDDirCheck*)&(dir)[CARD_MAX_FILE]) - -#define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) -#define OFFSET(n, a) (((u32)(n)) & ((a)-1)) - -extern CARDControl __CARDBlock[2]; -extern DVDDiskID __CARDDiskNone; -extern u16 __CARDVendorID; -extern u8 data_80450A72; - -#ifdef __cplusplus -} -#endif - -#endif /* CARDPRIV_H */ diff --git a/include/dolphin/card/CARDRdwr.h b/include/dolphin/card/CARDRdwr.h deleted file mode 100644 index bf7e0fba48..0000000000 --- a/include/dolphin/card/CARDRdwr.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef CARDRDWR_H -#define CARDRDWR_H - - -#endif /* CARDRDWR_H */ diff --git a/include/dolphin/card/CARDRead.h b/include/dolphin/card/CARDRead.h deleted file mode 100644 index 5793be2649..0000000000 --- a/include/dolphin/card/CARDRead.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef CARDREAD_H -#define CARDREAD_H - - -#endif /* CARDREAD_H */ diff --git a/include/dolphin/card/CARDStat.h b/include/dolphin/card/CARDStat.h deleted file mode 100644 index 73d846efef..0000000000 --- a/include/dolphin/card/CARDStat.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef CARDSTAT_H -#define CARDSTAT_H - - -#endif /* CARDSTAT_H */ diff --git a/include/dolphin/card/CARDUnlock.h b/include/dolphin/card/CARDUnlock.h deleted file mode 100644 index 753eb3f26f..0000000000 --- a/include/dolphin/card/CARDUnlock.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef CARDUNLOCK_H -#define CARDUNLOCK_H - - -#endif /* CARDUNLOCK_H */ diff --git a/include/dolphin/card/CARDWrite.h b/include/dolphin/card/CARDWrite.h deleted file mode 100644 index a6614b53bd..0000000000 --- a/include/dolphin/card/CARDWrite.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef CARDWRITE_H -#define CARDWRITE_H - - -#endif /* CARDWRITE_H */ diff --git a/include/dolphin/charPipeline/fileCache.h b/include/dolphin/charPipeline/fileCache.h new file mode 100644 index 0000000000..edae41b8f0 --- /dev/null +++ b/include/dolphin/charPipeline/fileCache.h @@ -0,0 +1,42 @@ +#ifndef _CHARPIPELINE_FILECACHE_H_ +#define _CHARPIPELINE_FILECACHE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define DS_AUTO_PURGE 0 +#define DS_NO_PURGE 1 + +typedef struct { + DSLink Link; + void (*Free)(Ptr* data); + char* Name; + Ptr Data; + u16 ReferenceCount; +} DSCacheNode, *DSCacheNodePtr; + +typedef struct { + u8 PurgeFlag; + DSList CacheNodeList; +} DSCache, *DSCachePtr; + +extern u8 DOCacheInitialized; +extern DSCache DODisplayCache; + +DSCacheNodePtr DSAddCacheNode(DSCachePtr cache, char* name, Ptr data, Ptr OSFreeFunc); +void DSEmptyCache(DSCachePtr cache); +Ptr DSGetCacheObj(DSCachePtr cache, char* name); +void DSInitCache(DSCachePtr cache); +void DSPurgeCache(DSCachePtr cache); +void DSReleaseCacheObj(DSCachePtr cache, Ptr data); +void DSSetCachePurgeFlag(DSCachePtr cache, u8 purgeFlag); +void CSHInitDisplayCache(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/charPipeline/structures.h b/include/dolphin/charPipeline/structures.h new file mode 100644 index 0000000000..622ca5539d --- /dev/null +++ b/include/dolphin/charPipeline/structures.h @@ -0,0 +1,9 @@ +#ifndef _CHARPIPELINE_STRUCTURES_H_ +#define _CHARPIPELINE_STRUCTURES_H_ + +#include +#include +#include +#include + +#endif diff --git a/include/dolphin/charPipeline/structures/HTable.h b/include/dolphin/charPipeline/structures/HTable.h new file mode 100644 index 0000000000..e0f5bac1b6 --- /dev/null +++ b/include/dolphin/charPipeline/structures/HTable.h @@ -0,0 +1,29 @@ +#ifndef _CHARPIPELINE_STRUCTURES_HTABLE_H_ +#define _CHARPIPELINE_STRUCTURES_HTABLE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef u16 (DSHashFunc)(Ptr); + +typedef struct { + DSList* table; + u16 tableSize; + DSHashFunc* hash; +} DSHashTable; + +void DSInitHTable(DSHashTable* hTable, u16 size, DSList* listArray, DSHashFunc* hashFunc, Ptr obj, DSLinkPtr link); +void DSInsertHTableObj(DSHashTable* hTable, Ptr obj); +void DSHTableToList(DSHashTable* hTable, DSList* list); +void* DSNextHTableObj(DSHashTable* hTable, Ptr obj); +s32 DSHTableIndex(DSHashTable* hTable, Ptr obj); +void* DSHTableHead(DSHashTable* hTable, s32 index); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/charPipeline/structures/List.h b/include/dolphin/charPipeline/structures/List.h new file mode 100644 index 0000000000..2ddcd10f98 --- /dev/null +++ b/include/dolphin/charPipeline/structures/List.h @@ -0,0 +1,31 @@ +#ifndef _CHARPIPELINE_STRUCTURES_LIST_H_ +#define _CHARPIPELINE_STRUCTURES_LIST_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + Ptr Prev; + Ptr Next; +} DSLink, *DSLinkPtr; + +typedef struct { + u32 Offset; + Ptr Head; + Ptr Tail; +} DSList, *DSListPtr; + +void DSInitList(DSListPtr list, Ptr obj, DSLinkPtr link); +void DSInsertListObject(DSListPtr list, Ptr cursor, Ptr obj); +void DSRemoveListObject(DSListPtr list, Ptr obj); +void DSAttachList(DSListPtr baseList, DSListPtr attachList); +void* DSNextListObj(DSListPtr list, Ptr obj); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/charPipeline/structures/Tree.h b/include/dolphin/charPipeline/structures/Tree.h new file mode 100644 index 0000000000..5ac570fcd3 --- /dev/null +++ b/include/dolphin/charPipeline/structures/Tree.h @@ -0,0 +1,32 @@ +#ifndef _CHARPIPELINE_STRUCTURES_TREE_H_ +#define _CHARPIPELINE_STRUCTURES_TREE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + Ptr Prev; + Ptr Next; + Ptr Parent; + Ptr Children; +} DSBranch, *DSBranchPtr; + +typedef struct { + u32 Offset; + Ptr Root; +} DSTree, *DSTreePtr; + +void DSExtractBranch(DSTreePtr tree, Ptr obj); +void DSInitTree(DSTreePtr tree, Ptr obj, DSBranchPtr branch); +void DSInsertBranchBelow(DSTreePtr tree, Ptr cursor, Ptr obj); +void DSInsertBranchBeside(DSTreePtr tree, Ptr cursor, Ptr obj); +void DSRemoveBranch(DSTreePtr tree, Ptr obj); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/charPipeline/structures/dolphinString.h b/include/dolphin/charPipeline/structures/dolphinString.h new file mode 100644 index 0000000000..b204ee5ee4 --- /dev/null +++ b/include/dolphin/charPipeline/structures/dolphinString.h @@ -0,0 +1,19 @@ +#ifndef _CHARPIPELINE_STRUCTURES_DOLPHINSTRING_H_ +#define _CHARPIPELINE_STRUCTURES_DOLPHINSTRING_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +u8 Strcat(char* str1, char* str2, char* dst); +void Strcpy(char* dst, char* src); +s8 Strcmp(char* str1, char* str2); +u32 Strlen(char* str); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/charPipeline/texPalette.h b/include/dolphin/charPipeline/texPalette.h new file mode 100644 index 0000000000..72369ef2f6 --- /dev/null +++ b/include/dolphin/charPipeline/texPalette.h @@ -0,0 +1,55 @@ +#ifndef _CHARPIPELINE_TEXPALETTE_H_ +#define _CHARPIPELINE_TEXPALETTE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + u16 numEntries; + u8 unpacked; + u8 pad8; + GXTlutFmt format; + Ptr data; +} CLUTHeader, *CLUTHeaderPtr; + +typedef struct { + u16 height; + u16 width; + u32 format; + Ptr data; + GXTexWrapMode wrapS; + GXTexWrapMode wrapT; + GXTexFilter minFilter; + GXTexFilter magFilter; + f32 LODBias; + u8 edgeLODEnable; + u8 minLOD; + u8 maxLOD; + u8 unpacked; +} TEXHeader, *TEXHeaderPtr; + +typedef struct { + TEXHeaderPtr textureHeader; + CLUTHeaderPtr CLUTHeader; +} TEXDescriptor, *TEXDescriptorPtr; + +typedef struct { + u32 versionNumber; + u32 numDescriptors; + TEXDescriptorPtr descriptorArray; +} TEXPalette, *TEXPalettePtr; + +void TEXGetPalette(TEXPalettePtr* pal, char* name); +TEXDescriptorPtr TEXGet(TEXPalettePtr pal, u32 id); +void TEXReleasePalette(TEXPalettePtr* pal); +void TEXGetGXTexObjFromPalette(TEXPalettePtr pal, GXTexObj* to, u32 id); +void TEXGetGXTexObjFromPaletteCI(TEXPalettePtr pal, GXTexObj* to, GXTlutObj* tlo, GXTlut tluts, u32 id); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/db.h b/include/dolphin/db.h index 663f0cebab..c62f188e40 100644 --- a/include/dolphin/db.h +++ b/include/dolphin/db.h @@ -1,7 +1,8 @@ -#ifndef DB_H -#define DB_H +#ifndef _DOLPHIN_DB_H_ +#define _DOLPHIN_DB_H_ -#include "amcstubs/AmcExi2Stubs.h" +#include +#include #ifdef __cplusplus extern "C" { @@ -9,30 +10,13 @@ extern "C" { #define OS_DBINTERFACE_ADDR 0x00000040 -typedef struct DBInterface { - /* 0x0 */ u32 bPresent; - /* 0x4 */ u32 exceptionMask; - /* 0x8 */ void (*ExceptionDestination)(void); - /* 0xC */ void* exceptionReturn; -} DBInterface; - -extern DBInterface* __DBInterface; - -void DBInit(void); -void __DBExceptionDestinationAux(void); -void __DBExceptionDestination(void); -BOOL __DBIsExceptionMarked(__OSException); -void DBPrintf(char* format, ...); -void DBInitComm(vu8**, AmcEXICallback); // possibly not this type, but some similar construction -void DBInitInterrupts(); -u32 DBQueryData(); -BOOL DBRead(void*, u32); -BOOL DBWrite(const void*, u32); -void DBOpen(); -void DBClose(); +BOOL DBIsDebuggerPresent(void); +void DBPrintf(char* str, ...); +s32 DBQueryData(void); +u32 DBRead(u8*, u32); #ifdef __cplusplus } #endif -#endif /* DB_H */ +#endif // _DOLPHIN_DB_H_ diff --git a/include/dolphin/db/DBInterface.h b/include/dolphin/db/DBInterface.h new file mode 100644 index 0000000000..7bfa354272 --- /dev/null +++ b/include/dolphin/db/DBInterface.h @@ -0,0 +1,31 @@ +#ifndef _DOLPHIN_DBINTERFACE_H_ +#define _DOLPHIN_DBINTERFACE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct DBInterface { + u32 bPresent; + u32 exceptionMask; + void (*ExceptionDestination)(void); + void* exceptionReturn; +} DBInterface; + +extern DBInterface* __DBInterface; + +void DBInit(void); +void DBInitComm(int* inputFlagPtr, int* mtrCallback); +void __DBExceptionDestination(void); +void __DBExceptionDestinationAux(void); +BOOL __DBIsExceptionMarked(__OSException exception); +void __DBMarkException(u8 exception, int value); +void __DBSetPresent(u32 value); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/demo.h b/include/dolphin/demo.h new file mode 100644 index 0000000000..43a7efbf7f --- /dev/null +++ b/include/dolphin/demo.h @@ -0,0 +1,21 @@ +#ifndef _DOLPHIN_DEMO_H_ +#define _DOLPHIN_DEMO_H_ + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern u32 DEMOFontBitmap[768]; + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_DEMO_H_ diff --git a/include/dolphin/demo/DEMOAVX.h b/include/dolphin/demo/DEMOAVX.h new file mode 100644 index 0000000000..2f5e77960b --- /dev/null +++ b/include/dolphin/demo/DEMOAVX.h @@ -0,0 +1,20 @@ +#ifndef _DOLPHIN_DEMOAVX_H_ +#define _DOLPHIN_DEMOAVX_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void DEMOAVXAttach(void* buffer, u32 num_frames); +u32 DEMOAVXGetNumFilled(void); +u32 DEMOAVXGetFrameCounter(void); +u32 DEMOAVXRefreshBuffer(u32* start_index, u32* end_index); +void DEMOAVXInit(s16* left, s16* right, u32 size); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_DEMOAVX_H_ diff --git a/include/dolphin/demo/DEMOInit.h b/include/dolphin/demo/DEMOInit.h new file mode 100644 index 0000000000..a555cb215a --- /dev/null +++ b/include/dolphin/demo/DEMOInit.h @@ -0,0 +1,30 @@ +#ifndef _DOLPHIN_DEMOINIT_H_ +#define _DOLPHIN_DEMOINIT_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern void* DemoFrameBuffer1; +extern void* DemoFrameBuffer2; +extern void* DemoCurrentBuffer; + +void DEMOInit(GXRenderModeObj* mode); +void DEMOBeforeRender(void); +void DEMODoneRender(void); +void DEMOSwapBuffers(void); +void DEMOSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, GXTevColorArg d); +void DEMOSetTevOp(GXTevStageID id, GXTevMode mode); +GXRenderModeObj* DEMOGetRenderModeObj(void); +u32 DEMOGetCurrentBuffer(void); +void DEMOSetGPHangMetric(u8 enable); +void DEMOEnableGPHangWorkaround(u32 timeoutFrames); +void DEMOReInit(GXRenderModeObj* mode); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_DEMOINIT_H_ diff --git a/include/dolphin/demo/DEMOPad.h b/include/dolphin/demo/DEMOPad.h new file mode 100644 index 0000000000..ed690cbbf6 --- /dev/null +++ b/include/dolphin/demo/DEMOPad.h @@ -0,0 +1,33 @@ +#ifndef _DOLPHIN_DEMOPAD_H_ +#define _DOLPHIN_DEMOPAD_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + /* 0x00 */ PADStatus pst; + /* 0x0C */ u16 buttonDown; + /* 0x0E */ u16 buttonUp; + /* 0x10 */ u16 dirs; + /* 0x12 */ u16 dirsNew; + /* 0x14 */ u16 dirsReleased; + /* 0x16 */ s16 stickDeltaX; + /* 0x18 */ s16 stickDeltaY; + /* 0x1A */ s16 substickDeltaX; + /* 0x1C */ s16 substickDeltaY; +} DEMODMPad; + +extern DEMODMPad DemoPad[4]; +extern u32 DemoNumValidPads; + +void DEMOPadRead(void); +void DEMOPadInit(void); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_DEMOPAD_H_ diff --git a/include/dolphin/demo/DEMOPuts.h b/include/dolphin/demo/DEMOPuts.h new file mode 100644 index 0000000000..07017b4c1b --- /dev/null +++ b/include/dolphin/demo/DEMOPuts.h @@ -0,0 +1,40 @@ +#ifndef _DOLPHIN_DEMOPUTS_H_ +#define _DOLPHIN_DEMOPUTS_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + DMTF_POINTSAMPLE, + DMTF_BILERP, +} DMTexFlt; + +typedef enum { + DM_FT_OPQ, + DM_FT_RVS, + DM_FT_XLU +} DMFontType; + +void DEMOSetFontType(s32 attr); +void DEMOLoadFont(GXTexMapID texMap, GXTexMtx texMtx, DMTexFlt texFlt); +void DEMOSetupScrnSpc(s32 width, s32 height, f32 depth); +void DEMOInitCaption(s32 font_type, s32 width, s32 height); +void DEMOPuts(s16 x, s16 y, s16 z, char* string); +void DEMOPrintf(s16 x, s16 y, s16 z, char* fmt, ...); +OSFontHeader* DEMOInitROMFont(void); +void DEMOSetROMFontSize(s16 size, s16 space); +int DEMORFPuts(s16 x, s16 y, s16 z, char* string); +int DEMORFPutsEx(s16 x, s16 y, s16 z, char* string, s16 maxWidth, int length); +int DEMORFPrintf(s16 x, s16 y, s16 z, char* fmt, ...); +char* DEMODumpROMFont(char* string); +int DEMOGetRFTextWidth(char* string); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/demo/DEMOStats.h b/include/dolphin/demo/DEMOStats.h new file mode 100644 index 0000000000..346fb65a74 --- /dev/null +++ b/include/dolphin/demo/DEMOStats.h @@ -0,0 +1,48 @@ +#ifndef _DOLPHIN_DEMOSTATS_H_ +#define _DOLPHIN_DEMOSTATS_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum DEMO_STAT_TYPE { + DEMO_STAT_GP0 = 0, + DEMO_STAT_GP1 = 1, + DEMO_STAT_MEM = 2, + DEMO_STAT_PIX = 3, + DEMO_STAT_VC = 4, + DEMO_STAT_FR = 5, + DEMO_STAT_TBW = 6, + DEMO_STAT_TBP = 7, + DEMO_STAT_MYC = 8, + DEMO_STAT_MYR = 9, +} DEMO_STAT_TYPE; + +typedef struct DemoStatData { + char text[50]; + DEMO_STAT_TYPE stat_type; + u32 stat; + u32 count; +} DemoStatData; + +typedef enum { + DEMO_STAT_TL = 0, + DEMO_STAT_BL = 1, + DEMO_STAT_TLD = 2, + DEMO_STAT_BLD = 3, + DEMO_STAT_IO = 4, +} DEMO_STAT_DISP; + +extern u8 DemoStatEnable; + +void DEMOSetStats(DemoStatData* stat, u32 nstats, DEMO_STAT_DISP disp); +void DEMOUpdateStats(u8 inc); +void DEMOPrintStats(void); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_DEMOSTATS_H_ diff --git a/include/dolphin/demo/DEMOWin.h b/include/dolphin/demo/DEMOWin.h new file mode 100644 index 0000000000..cf1710fe3c --- /dev/null +++ b/include/dolphin/demo/DEMOWin.h @@ -0,0 +1,137 @@ +#ifndef _DOLPHIN_DEMOWIN_H_ +#define _DOLPHIN_DEMOWIN_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define DEMOWIN_ITEM_CAP 0 +#define DEMOWIN_ITEM_BKGND 1 +#define DEMOWIN_ITEM_BORDER 2 +#define DEMOWIN_ITEM_DEFAULT 3 + +// flags +#define DEMOWIN_FLAGS_INIT (1 << 0) +#define DEMOWIN_FLAGS_OPENED (1 << 1) + +typedef struct { + /* 0x00 */ PADStatus pads[4]; + /* 0x30 */ u32 button[4]; + /* 0x40 */ u32 old_button[4]; + /* 0x50 */ u32 changed_button[4]; + /* 0x60 */ u32 repeat_button[4]; + /* 0x70 */ u32 repeat_ctr[4]; +} DEMOWinPadInfo; + +typedef struct STRUCT_DEMOWIN DEMOWindow; +typedef struct STRUCT_DEMOWIN { + /* 0x00 */ s32 x1; + /* 0x04 */ s32 y1; + /* 0x08 */ s32 x2; + /* 0x0C */ s32 y2; + /* 0x10 */ u32 priority; + /* 0x14 */ u32 flags; + /* 0x18 */ u16 x_cal; + /* 0x1A */ u16 y_cal; + /* 0x1C */ u16 pixel_width; + /* 0x1E */ u16 pixel_height; + /* 0x20 */ u16 char_width; + /* 0x22 */ u16 char_height; + /* 0x24 */ u16 num_scroll_lines; + /* 0x26 */ u16 total_lines; + /* 0x28 */ u16 curr_output_line; + /* 0x2A */ u16 curr_output_col; + /* 0x2C */ u16 curr_view_line; + /* 0x2E */ s16 cursor_line; + /* 0x30 */ char* caption; + /* 0x34 */ u8* buffer; + /* 0x38 */ GXColor bkgnd; + /* 0x3C */ GXColor cap; + /* 0x40 */ GXColor border; + /* 0x44 */ void (*refresh)(DEMOWindow *); + /* 0x48 */ DEMOWindow* next; + /* 0x4C */ DEMOWindow* prev; + /* 0x50 */ void* parent; + /* 0x54 */ DEMOWinPadInfo pad; +} DEMOWindow; + +typedef struct STRUCT_MENU DEMOWinMenu; +typedef struct STRUCT_MENU_ITEM { + /* 0x00 */ char* name; + /* 0x04 */ u32 flags; + /* 0x08 */ void (*function)(DEMOWinMenu*, u32, u32*); + /* 0x0C */ DEMOWinMenu* link; +} DEMOWinMenuItem; + +typedef struct STRUCT_MENU { + /* 0x00 */ char* title; + /* 0x04 */ DEMOWindow* handle; + /* 0x08 */ DEMOWinMenuItem* items; + /* 0x0C */ s32 max_display_items; + /* 0x10 */ u32 flags; + /* 0x14 */ void (*cb_open)(DEMOWinMenu*, u32); + /* 0x18 */ void (*cb_move)(DEMOWinMenu*, u32); + /* 0x1C */ void (*cb_select)(DEMOWinMenu*, u32); + /* 0x20 */ void (*cb_cancel)(DEMOWinMenu*, u32); + /* 0x24 */ s32 num_display_items; + /* 0x28 */ s32 num_items; + /* 0x2C */ u32 max_str_len; + /* 0x30 */ s32 curr_pos; + /* 0x34 */ s32 display_pos; +} DEMOWinMenu; + +typedef struct STRUCT_LISTBOX_ITEM { + /* 0x00 */ char* name; // offset 0x0, size 0x4 + /* 0x04 */ u32 flags; // offset 0x4, size 0x4 +} DEMOWinListboxItem; + +typedef struct STRUCT_LISTBOX { + /* 0x00 */ char* title; // offset 0x0, size 0x4 + /* 0x04 */ DEMOWindow* handle; // offset 0x4, size 0x4 + /* 0x08 */ DEMOWinListboxItem* items; // offset 0x8, size 0x4 + /* 0x0C */ s32 max_display_items; // offset 0xC, size 0x4 + /* 0x10 */ u32 flags; // offset 0x10, size 0x4 + /* 0x14 */ s32 num_display_items; // offset 0x14, size 0x4 + /* 0x18 */ s32 num_items; // offset 0x18, size 0x4 + /* 0x1C */ u32 max_str_len; // offset 0x1C, size 0x4 + /* 0x20 */ s32 curr_pos; // offset 0x20, size 0x4 + /* 0x24 */ s32 display_pos; // offset 0x24, size 0x4 + /* 0x28 */ int cursor_state; // offset 0x28, size 0x4 +} DEMOWinListbox; + +void DEMOWinInit(void); +DEMOWindow* DEMOWinCreateWindow(s32 x1, s32 y1, s32 x2, s32 y2, char* caption, u16 scroll, void* func); +void DEMOWinDestroyWindow(DEMOWindow* handle); +void DEMOWinOpenWindow(DEMOWindow* handle); +void DEMOWinCloseWindow(DEMOWindow* handle); +void DEMOWinSetWindowColor(DEMOWindow* handle, u32 item, u8 r, u8 g, u8 b, u8 a); +void DEMOWinLogPrintf(DEMOWindow* handle, char* fmt, ...); +void DEMOWinPrintfXY(DEMOWindow* handle, u16 col, u16 row, char* fmt, ...); +void DEMOWinScrollWindow(DEMOWindow* handle, u32 dir); +void DEMOWinBringToFront(DEMOWindow* handle); +void DEMOWinSendToBack(DEMOWindow* handle); +void DEMOWinClearRow(DEMOWindow* handle, u16 row); +void DEMOWinClearWindow(DEMOWindow* handle); +void DEMOWinClearBuffer(DEMOWindow* handle); +void DEMOWinRefresh(void); +DEMOWinMenu* DEMOWinCreateMenuWindow(DEMOWinMenu* menu, u16 x, u16 y); +void DEMOWinDestroyMenuWindow(DEMOWinMenu* menu); +u32 DEMOWinMenuChild(DEMOWinMenu* menu, int child_flag); +void DEMOWinPadInit(DEMOWinPadInfo* p); +void DEMOWinPadRead(DEMOWinPadInfo* p); +void DEMOWinSetRepeat(u32 threshold, u32 rate); +void DEMOWinResetRepeat(void); +DEMOWinListbox* DEMOWinCreateListWindow(DEMOWinListbox* list, u16 x, u16 y); +void DEMOWinDestroyListWindow(DEMOWinListbox* list); +void DEMOWinListSetCursor(DEMOWinListbox* list, int x); +s32 DEMOWinListScrollList(DEMOWinListbox* list, u32 dir); +s32 DEMOWinListMoveCursor(DEMOWinListbox* list, u32 dir); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_DEMOWIN_H_ diff --git a/include/dolphin/dolphin.h b/include/dolphin/dolphin.h index 45beac4b57..ac1ebcf7b0 100644 --- a/include/dolphin/dolphin.h +++ b/include/dolphin/dolphin.h @@ -6,20 +6,19 @@ #include #include #include -#include -//#include +#include #include #include #include -//#include +#include #include #include #include #include -//#include +#include #include -//#include - -#include "macros.h" +#include +#include +#include #endif diff --git a/include/dolphin/dsp.h b/include/dolphin/dsp.h index 0658f7b921..e3a20b9088 100644 --- a/include/dolphin/dsp.h +++ b/include/dolphin/dsp.h @@ -1,90 +1,57 @@ -#ifndef DSP_H -#define DSP_H +#ifndef _DOLPHIN_DSP_H_ +#define _DOLPHIN_DSP_H_ -#include "dolphin/os/OSTime.h" -#include "dolphin/os/OSInterrupt.h" +#include #ifdef __cplusplus extern "C" { #endif -volatile u16 __DSPRegs[32] AT_ADDRESS(0xCC005000); -volatile u32 __AIRegs[8] AT_ADDRESS(0xCC006C00); - -#define DSP_TASK_FLAG_CLEARALL 0x00000000 -#define DSP_TASK_FLAG_ATTACHED 0x00000001 -#define DSP_TASK_FLAG_CANCEL 0x00000002 - -#define DSP_TASK_STATE_INIT 0 -#define DSP_TASK_STATE_RUN 1 -#define DSP_TASK_STATE_YIELD 2 -#define DSP_TASK_STATE_DONE 3 - -#define DSP_MAILBOX_IN_HI (0) -#define DSP_MAILBOX_IN_LO (1) -#define DSP_MAILBOX_OUT_HI (2) -#define DSP_MAILBOX_OUT_LO (3) -#define DSP_CONTROL_STATUS (5) - -#define DSP_ARAM_SIZE (9) -#define DSP_ARAM_MODE (11) -#define DSP_ARAM_REFRESH (13) -#define DSP_ARAM_DMA_MM_HI (16) // Main mem address -#define DSP_ARAM_DMA_MM_LO (17) -#define DSP_ARAM_DMA_ARAM_HI (18) // ARAM address -#define DSP_ARAM_DMA_ARAM_LO (19) -#define DSP_ARAM_DMA_SIZE_HI (20) // DMA buffer size -#define DSP_ARAM_DMA_SIZE_LO (21) - -#define DSP_DMA_START_HI (24) // DMA start address -#define DSP_DMA_START_LO (25) -#define DSP_DMA_CONTROL_LEN (27) -#define DSP_DMA_BYTES_LEFT (29) - -#define DSP_DMA_START_FLAG (0x8000) // set to start DSP - typedef void (*DSPCallback)(void* task); +typedef struct STRUCT_DSP_TASK DSPTaskInfo; -typedef struct DSPTaskInfo DSPTaskInfo; - -typedef struct DSPTaskInfo { - /* 0x00 */ vu32 state; - /* 0x04 */ vu32 priority; - /* 0x08 */ vu32 flags; +typedef struct STRUCT_DSP_TASK { + /* 0x00 */ volatile u32 state; + /* 0x04 */ volatile u32 priority; + /* 0x08 */ volatile u32 flags; /* 0x0C */ u16* iram_mmem_addr; /* 0x10 */ u32 iram_length; /* 0x14 */ u32 iram_addr; - /* 0x18 */ u16* dram_mmem_addr; /* 0x1C */ u32 dram_length; /* 0x20 */ u32 dram_addr; - /* 0x24 */ u16 dsp_init_vector; /* 0x26 */ u16 dsp_resume_vector; - /* 0x28 */ DSPCallback init_cb; /* 0x2C */ DSPCallback res_cb; /* 0x30 */ DSPCallback done_cb; /* 0x34 */ DSPCallback req_cb; - - /* 0x38 */ struct DSPTaskInfo* next; - /* 0x3C */ struct DSPTaskInfo* prev; - + /* 0x38 */ DSPTaskInfo* next; + /* 0x3C */ DSPTaskInfo* prev; /* 0x40 */ OSTime t_context; /* 0x48 */ OSTime t_task; } DSPTaskInfo; u32 DSPCheckMailToDSP(void); u32 DSPCheckMailFromDSP(void); +u32 DSPReadCPUToDSPMbox(void); u32 DSPReadMailFromDSP(void); void DSPSendMailToDSP(u32 mail); -void DSPAssertInt(); +void DSPAssertInt(void); void DSPInit(void); +BOOL DSPCheckInit(void); +void DSPReset(void); +void DSPHalt(void); +void DSPUnhalt(void); +u32 DSPGetDMAStatus(void); +__declspec(weak) DSPTaskInfo* DSPAddTask(DSPTaskInfo* task); +DSPTaskInfo* DSPCancelTask(DSPTaskInfo* task); +DSPTaskInfo* DSPAssertTask(DSPTaskInfo* task); -void __DSPHandler(__OSInterrupt interrupt, OSContext* context); +DSPTaskInfo* __DSPGetCurrentTask(void); #ifdef __cplusplus } #endif -#endif /* DSP_H */ +#endif diff --git a/include/dolphin/dsp/dsp_debug.h b/include/dolphin/dsp/dsp_debug.h deleted file mode 100644 index ef86da0aa6..0000000000 --- a/include/dolphin/dsp/dsp_debug.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef DSP_DEBUG_H -#define DSP_DEBUG_H - - -#ifdef __cplusplus -extern "C" { -#endif - -void __DSP_debug_printf(const char* fmt, ...); - -#ifdef __cplusplus -} -#endif - -#endif /* DSP_DEBUG_H */ diff --git a/include/dolphin/dsp/dsp_task.h b/include/dolphin/dsp/dsp_task.h deleted file mode 100644 index a3a8b33dd1..0000000000 --- a/include/dolphin/dsp/dsp_task.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef DSP_TASK_H -#define DSP_TASK_H - -#include "dolphin/dsp.h" - -extern DSPTaskInfo* __DSP_tmp_task; -extern DSPTaskInfo* __DSP_last_task; -extern DSPTaskInfo* __DSP_first_task; -extern DSPTaskInfo* __DSP_curr_task; - -#ifdef __cplusplus -extern "C" { -#endif - -void __DSP_boot_task(DSPTaskInfo* task); -void __DSP_insert_task(DSPTaskInfo* task); -void __DSP_exec_task(DSPTaskInfo* curr, DSPTaskInfo* next); -void __DSP_remove_task(DSPTaskInfo* task); - -#ifdef __cplusplus -} - -#endif - -#endif /* DSP_TASK_H */ diff --git a/include/dolphin/dtk.h b/include/dolphin/dtk.h new file mode 100644 index 0000000000..3a76a0ff7d --- /dev/null +++ b/include/dolphin/dtk.h @@ -0,0 +1,56 @@ +#ifndef _DOLPHIN_DTK_H_ +#define _DOLPHIN_DTK_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*DTKCallback)(u32 eventMask); +typedef void (*DTKFlushCallback)(void); + +typedef struct DTKTrack { + /* 0x00 */ struct DTKTrack* prev; + /* 0x04 */ struct DTKTrack* next; + /* 0x08 */ char* fileName; + /* 0x0C */ u32 eventMask; + /* 0x10 */ DTKCallback callback; + /* 0x14 */ DVDFileInfo dvdFileInfo; +} DTKTrack; + +#define DTK_STATE_STOP 0 +#define DTK_STATE_RUN 1 +#define DTK_STATE_PAUSE 2 +#define DTK_STATE_BUSY 3 +#define DTK_STATE_PREPARE 4 + +#define DTK_MODE_NOREPEAT 0 +#define DTK_MODE_ALLREPEAT 1 +#define DTK_MODE_REPEAT1 2 + +void DTKInit(void); +void DTKShutdown(void); +u32 DTKQueueTrack(char* fileName, DTKTrack* track, u32 eventMask, DTKCallback callback); +u32 DTKRemoveTrack(DTKTrack* track); +int DTKFlushTracks(DTKFlushCallback callback); +void DTKSetSampleRate(u32 samplerate); +void DTKSetInterruptFrequency(u32 samples); +void DTKSetRepeatMode(u32 repeat); +int DTKSetState(u32 state); +int DTKNextTrack(void); +int DTKPrevTrack(void); +u32 DTKGetSampleRate(void); +u32 DTKGetRepeatMode(void); +u32 DTKGetState(void); +u32 DTKGetPosition(void); +u32 DTKGetInterruptFrequency(void); +DTKTrack* DTKGetCurrentTrack(void); +void DTKSetVolume(u8 left, u8 right); +u16 DTKGetVolume(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/dvd.h b/include/dolphin/dvd.h index 53b3047552..ae036cad3f 100644 --- a/include/dolphin/dvd.h +++ b/include/dolphin/dvd.h @@ -1,148 +1,236 @@ -#ifndef DVD_H -#define DVD_H +#ifndef _DOLPHIN_DVD_H_ +#define _DOLPHIN_DVD_H_ -#include "dolphin/types.h" +#include #ifdef __cplusplus extern "C" { #endif -typedef enum DVDState { - DVD_STATE_END = 0x0, - DVD_STATE_BUSY = 0x1, - DVD_STATE_WAITING = 0x2, - DVD_STATE_COVER_CLOSED = 0x3, - DVD_STATE_NO_DISK = 0x4, - DVD_STATE_COVER_OPEN = 0x5, - DVD_STATE_WRONG_DISK = 0x6, - DVD_STATE_MOTOR_STOPPED = 0x7, - DVD_STATE_IGNORED = 0x8, - DVD_STATE_CANCELED = 0xa, // lmao they skipped 9 - DVD_STATE_RETRY = 0xb, - DVD_STATE_FATAL_ERROR = -1, -} DVDState; +#define DVD_ASSERTMSGLINE(line, cond, msg) \ + if (!(cond)) \ + OSPanic(__FILE__, line, msg) +#define DVD_ASSERTMSG1LINE(line, cond, msg, arg1) \ + if (!(cond)) \ + OSPanic(__FILE__, line, msg, arg1) -typedef enum DVDResult { - DVD_RESULT_GOOD = 0, - DVD_RESULT_FATAL_ERROR = -1, - DVD_RESULT_IGNORED = -2, - DVD_RESULT_CANCELED = -3, -} DVDResult; +#define DVD_ASSERTMSG2LINE(line, cond, msg, arg1, arg2) \ + if (!(cond)) \ + OSPanic(__FILE__, line, msg, arg1, arg2) -typedef struct DVDDirectory { - /* 0x0 */ u32 entry_number; - /* 0x4 */ u32 location; - /* 0x8 */ u32 next; -} DVDDirectory; +#define DVD_RESULT_GOOD 0 +#define DVD_RESULT_FATAL_ERROR -1 +#define DVD_RESULT_IGNORED -2 +#define DVD_RESULT_CANCELED -6 -typedef struct DVDDirectoryEntry { - /* 0x0 */ u32 entry_number; - /* 0x4 */ BOOL is_directory; - /* 0x8 */ char* name; -} DVDDirectoryEntry; +#define DVD_STATE_FATAL_ERROR -1 +#define DVD_STATE_END 0 +#define DVD_STATE_BUSY 1 +#define DVD_STATE_WAITING 2 +#define DVD_STATE_COVER_CLOSED 3 +#define DVD_STATE_NO_DISK 4 +#define DVD_STATE_COVER_OPEN 5 +#define DVD_STATE_WRONG_DISK 6 +#define DVD_STATE_MOTOR_STOPPED 7 +#define DVD_STATE_PAUSING 8 +#define DVD_STATE_IGNORED 9 +#define DVD_STATE_CANCELED 10 +#define DVD_STATE_RETRY 11 + +#define DVD_MIN_TRANSFER_SIZE 32 + +// could be bitfields +#define DVD_INTTYPE_TC 1 +#define DVD_INTTYPE_DE 2 +// unk type 3 +#define DVD_INTTYPE_CVR 4 + +// DVD Commands +#define DVD_COMMAND_NONE 0 +#define DVD_COMMAND_READ 1 +#define DVD_COMMAND_SEEK 2 +#define DVD_COMMAND_CHANGE_DISK 3 +#define DVD_COMMAND_BSREAD 4 +#define DVD_COMMAND_READID 5 +#define DVD_COMMAND_INITSTREAM 6 +#define DVD_COMMAND_CANCELSTREAM 7 +#define DVD_COMMAND_STOP_STREAM_AT_END 8 +#define DVD_COMMAND_REQUEST_AUDIO_ERROR 9 +#define DVD_COMMAND_REQUEST_PLAY_ADDR 10 +#define DVD_COMMAND_REQUEST_START_ADDR 11 +#define DVD_COMMAND_REQUEST_LENGTH 12 +#define DVD_COMMAND_AUDIO_BUFFER_CONFIG 13 +#define DVD_COMMAND_INQUIRY 14 +#define DVD_COMMAND_BS_CHANGE_DISK 15 +#define DVD_COMMAND_UNK_16 16 typedef struct DVDDiskID { - /* 0x00 */ char game_name[4]; - /* 0x04 */ char company[2]; - /* 0x06 */ u8 disk_number; - /* 0x07 */ u8 game_version; - /* 0x08 */ u8 is_streaming; - /* 0x09 */ u8 streaming_buffer_size; - /* 0x0A */ u8 padding[22]; + char gameName[4]; + char company[2]; + u8 diskNumber; + u8 gameVersion; + u8 streaming; + u8 streamingBufSize; + u8 padding[22]; } DVDDiskID; -struct DVDFileInfo; -struct DVDCommandBlock; -typedef void (*DVDCBCallback)(s32 result, struct DVDCommandBlock* block); -typedef void (*DVDCallback)(s32 result, struct DVDFileInfo* info); +typedef struct DVDCommandBlock DVDCommandBlock; +typedef void (*DVDCBCallback)(s32 result, DVDCommandBlock* block); +typedef void (*DVDLowCallback)(u32); -typedef struct DVDCommandBlock { - /* 0x00 */ struct DVDCommandBlock* next; - /* 0x04 */ struct DVDCommandBlock* prev; +typedef void (*DVDCommandCheckerCallback)(u32); +typedef void (*DVDCommandChecker)(DVDCommandBlock*, DVDCommandCheckerCallback); + +struct DVDCommandBlock { + /* 0x00 */ DVDCommandBlock* next; + /* 0x04 */ DVDCommandBlock* prev; /* 0x08 */ u32 command; /* 0x0C */ s32 state; /* 0x10 */ u32 offset; /* 0x14 */ u32 length; - /* 0x18 */ void* buffer; - /* 0x1C */ u32 current_transfer_size; - /* 0x20 */ u32 transferred_size; - /* 0x24 */ DVDDiskID* disk_id; + /* 0x18 */ void* addr; + /* 0x1C */ u32 currTransferSize; + /* 0x20 */ u32 transferredSize; + /* 0x24 */ DVDDiskID* id; /* 0x28 */ DVDCBCallback callback; - /* 0x2C */ void* user_data; -} DVDCommandBlock; + /* 0x2C */ void* userData; +}; -typedef struct DVDFileInfo { - /* 0x00 */ DVDCommandBlock block; - /* 0x30 */ u32 start_address; +typedef struct DVDFileInfo DVDFileInfo; +typedef void (*DVDCallback)(s32 result, DVDFileInfo *fileInfo); +struct DVDFileInfo { + /* 0x00 */ DVDCommandBlock cb; + /* 0x30 */ u32 startAddr; /* 0x34 */ u32 length; /* 0x38 */ DVDCallback callback; -} DVDFileInfo; +}; + +typedef struct { + u32 entryNum; + u32 location; + u32 next; +} DVDDir; + +typedef struct { + u32 entryNum; + BOOL isDir; + char* name; +} DVDDirEntry; + +typedef struct DVDBB2 { + /* 0x00 */ u32 bootFilePosition; + /* 0x04 */ u32 FSTPosition; + /* 0x08 */ u32 FSTLength; + /* 0x0C */ u32 FSTMaxLength; + /* 0x10 */ void* FSTAddress; + /* 0x14 */ u32 userPosition; + /* 0x18 */ u32 userLength; + /* 0x1C */ u32 padding0; +} DVDBB2; typedef struct DVDDriveInfo { - /* 0x00 */ u16 revision_level; - /* 0x02 */ u16 device_code; - /* 0x04 */ u32 release_date; + /* 0x00 */ u16 revisionLevel; + /* 0x02 */ u16 deviceCode; + /* 0x04 */ u32 releaseDate; /* 0x08 */ u8 padding[24]; } DVDDriveInfo; -typedef struct DVDBB1 { - u32 appLoaderLength; - void* appLoaderFunc1; - void* appLoaderFunc2; - void* appLoaderFunc3; -} DVDBB1; - -typedef struct DVDBB2 { - u32 bootFilePosition; - u32 FSTPosition; - u32 FSTLength; - u32 FSTMaxLength; - void* FSTAddress; - u32 userPosition; - u32 userLength; - - u32 padding0; -} DVDBB2; - -#define DVD_MIN_TRANSFER_SIZE 32 - -typedef void (*DVDOptionalCommandChecker)(DVDCommandBlock* block, void (*cb)(u32 intType)); - +// DVD void DVDInit(void); -BOOL DVDOpen(const char* filename, DVDFileInfo* fileinfo); -BOOL DVDClose(DVDFileInfo* fileinfo); -BOOL DVDReadPrio(DVDFileInfo* fileinfo, void*, s32, s32, s32); -DVDDiskID* DVDGetCurrentDiskID(void); -BOOL DVDFastOpen(long, DVDFileInfo* fileinfo); -s32 DVDGetCommandBlockStatus(const DVDCommandBlock* block); -BOOL DVDReadAsyncPrio(DVDFileInfo* fileinfo, void*, long, long, DVDCallback, long); -int DVDConvertPathToEntrynum(const char*); -s32 DVDGetDriveStatus(void); -BOOL DVDCheckDisk(void); -BOOL DVDChangeDir(const char* dirname); -BOOL DVDCloseDir(DVDDirectory* dir); -BOOL DVDOpenDir(const char*, DVDDirectory* dir); -BOOL DVDReadDir(DVDDirectory* dir, DVDDirectoryEntry* entry); -BOOL DVDReadAbsAsyncPrio(DVDCommandBlock* block, void* addr, s32 length, s32 offset, - DVDCBCallback callback, s32 prio); -BOOL DVDReadAbsAsyncForBS(DVDCommandBlock* block, void* addr, s32 length, s32 offset, - DVDCBCallback callback); -BOOL DVDReadDiskID(DVDCommandBlock* block, DVDDiskID* diskID, DVDCBCallback callback); -BOOL DVDCancelStreamAsync(DVDCommandBlock* block, DVDCBCallback callback); -BOOL DVDInquiryAsync(DVDCommandBlock* block, DVDDriveInfo* info, DVDCBCallback callback); +int DVDReadAbsAsyncPrio(DVDCommandBlock* block, void* addr, s32 length, s32 offset, DVDCBCallback callback, s32 prio); +int DVDSeekAbsAsyncPrio(DVDCommandBlock* block, s32 offset, DVDCBCallback callback, s32 prio); +int DVDReadAbsAsyncForBS(DVDCommandBlock* block, void* addr, s32 length, s32 offset, DVDCBCallback callback); +int DVDReadDiskID(DVDCommandBlock* block, DVDDiskID* diskID, DVDCBCallback callback); +int DVDPrepareStreamAbsAsync(DVDCommandBlock* block, u32 length, u32 offset, DVDCBCallback callback); +int DVDCancelStreamAsync(DVDCommandBlock* block, DVDCBCallback callback); +s32 DVDCancelStream(DVDCommandBlock* block); +int DVDStopStreamAtEndAsync(DVDCommandBlock* block, DVDCBCallback callback); +s32 DVDStopStreamAtEnd(DVDCommandBlock* block); +int DVDGetStreamErrorStatusAsync(DVDCommandBlock* block, DVDCBCallback callback); +s32 DVDGetStreamErrorStatus(DVDCommandBlock* block); +int DVDGetStreamPlayAddrAsync(DVDCommandBlock* block, DVDCBCallback callback); +s32 DVDGetStreamPlayAddr(DVDCommandBlock* block); +int DVDGetStreamStartAddrAsync(DVDCommandBlock* block, DVDCBCallback callback); +s32 DVDGetStreamStartAddr(DVDCommandBlock* block); +int DVDGetStreamLengthAsync(DVDCommandBlock* block, DVDCBCallback callback); +s32 DVDGetStreamLength(DVDCommandBlock* block); +int DVDChangeDiskAsyncForBS(DVDCommandBlock* block, DVDCBCallback callback); +int DVDChangeDiskAsync(DVDCommandBlock* block, DVDDiskID* id, DVDCBCallback callback); +s32 DVDChangeDisk(DVDCommandBlock* block, DVDDiskID* id); +int DVDStopMotorAsync(DVDCommandBlock* block, DVDCBCallback callback); +s32 DVDStopMotor(DVDCommandBlock* block); +int DVDInquiryAsync(DVDCommandBlock* block, DVDDriveInfo* info, DVDCBCallback callback); +s32 DVDInquiry(DVDCommandBlock* block, DVDDriveInfo* info); void DVDReset(void); +int DVDResetRequired(void); +s32 DVDGetCommandBlockStatus(const DVDCommandBlock* block); +s32 DVDGetDriveStatus(void); BOOL DVDSetAutoInvalidation(BOOL autoInval); +void DVDPause(void); void DVDResume(void); -static BOOL DVDCancelAsync(DVDCommandBlock* block, DVDCBCallback callback); -s32 DVDCancel(DVDCommandBlock* block); -void __DVDPrepareResetAsync(DVDCBCallback callbac); -BOOL DVDCompareDiskID(DVDDiskID* id1, DVDDiskID* id2); +int DVDCancelAsync(DVDCommandBlock* block, DVDCBCallback callback); +s32 DVDCancel(volatile DVDCommandBlock* block); +int DVDCancelAllAsync(DVDCBCallback callback); +s32 DVDCancelAll(void); +DVDDiskID* DVDGetCurrentDiskID(void); +BOOL DVDCheckDisk(void); -DVDCommandBlock* __DVDPopWaitingQueue(void); +// DVD FATAL +int DVDSetAutoFatalMessaging(BOOL enable); + +// DVD FS +s32 DVDConvertPathToEntrynum(const char* pathPtr); +BOOL DVDFastOpen(s32 entrynum, DVDFileInfo* fileInfo); +BOOL DVDOpen(const char* fileName, DVDFileInfo* fileInfo); +BOOL DVDClose(DVDFileInfo* fileInfo); +BOOL DVDGetCurrentDir(char* path, u32 maxlen); +BOOL DVDChangeDir(const char* dirName); +BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, + DVDCallback callback, s32 prio); +s32 DVDReadPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, s32 prio); +int DVDSeekAsyncPrio(DVDFileInfo* fileInfo, s32 offset, void (* callback)(s32, DVDFileInfo *), s32 prio); +s32 DVDSeekPrio(DVDFileInfo* fileInfo, s32 offset, s32 prio); +s32 DVDGetFileInfoStatus(const DVDFileInfo* fileInfo); +BOOL DVDFastOpenDir(s32 entrynum, DVDDir* dir); +int DVDOpenDir(const char* dirName, DVDDir* dir); +int DVDReadDir(DVDDir* dir, DVDDirEntry* dirent); +int DVDCloseDir(DVDDir* dir); +void DVDRewindDir(DVDDir* dir); +void* DVDGetFSTLocation(void); +BOOL DVDPrepareStreamAsync(DVDFileInfo* fileInfo, u32 length, u32 offset, DVDCallback callback); +s32 DVDPrepareStream(DVDFileInfo* fileInfo, u32 length, u32 offset); +s32 DVDGetTransferredSize(DVDFileInfo* fileinfo); + +#define DVDReadAsync(fileInfo, addr, length, offset, callback) \ + DVDReadAsyncPrio((fileInfo), (addr), (length), (offset), (callback), 2) + +// DVD ID UTILS +int DVDCompareDiskID(const DVDDiskID* id1, const DVDDiskID* id2); +DVDDiskID* DVDGenerateDiskID(DVDDiskID* id, const char* game, const char* company, u8 diskNum, u8 version); + +// DVD LOW +BOOL DVDLowRead(void* addr, u32 length, u32 offset, DVDLowCallback callback); +BOOL DVDLowSeek(u32 offset, DVDLowCallback callback); +BOOL DVDLowWaitCoverClose(DVDLowCallback callback); +BOOL DVDLowReadDiskID(DVDDiskID* diskID, DVDLowCallback callback); +BOOL DVDLowStopMotor(DVDLowCallback callback); +BOOL DVDLowRequestError(DVDLowCallback callback); +BOOL DVDLowInquiry(DVDDriveInfo* info, DVDLowCallback callback); +BOOL DVDLowAudioStream(u32 subcmd, u32 length, u32 offset, DVDLowCallback callback); +BOOL DVDLowRequestAudioStatus(u32 subcmd, DVDLowCallback callback); +BOOL DVDLowAudioBufferConfig(BOOL enable, u32 size, DVDLowCallback callback); +void DVDLowReset(void); +DVDLowCallback DVDLowSetResetCoverCallback(DVDLowCallback callback); +BOOL DVDLowBreak(void); +DVDLowCallback DVDLowClearCallback(void); +u32 DVDLowGetCoverStatus(void); + +// DVD QUEUE +void DVDDumpWaitingQueue(void); #ifdef __cplusplus -}; +} #endif -#endif /* DVD_H */ +#endif diff --git a/include/dolphin/dvd/dvdFatal.h b/include/dolphin/dvd/dvdFatal.h deleted file mode 100644 index 44f70330de..0000000000 --- a/include/dolphin/dvd/dvdFatal.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef DVDFATAL_H -#define DVDFATAL_H - - -#endif /* DVDFATAL_H */ diff --git a/include/dolphin/dvd/dvderror.h b/include/dolphin/dvd/dvderror.h deleted file mode 100644 index 0ae4b572ce..0000000000 --- a/include/dolphin/dvd/dvderror.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef DVDERROR_H -#define DVDERROR_H - - -#endif /* DVDERROR_H */ diff --git a/include/dolphin/dvd/dvdfs.h b/include/dolphin/dvd/dvdfs.h deleted file mode 100644 index aeeec2fe03..0000000000 --- a/include/dolphin/dvd/dvdfs.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef DVDFS_H -#define DVDFS_H - -#include "dolphin/types.h" - -extern u32 __DVDLongFileNameFlag; - -#endif /* DVDFS_H */ diff --git a/include/dolphin/dvd/dvdidutils.h b/include/dolphin/dvd/dvdidutils.h deleted file mode 100644 index 09ae281927..0000000000 --- a/include/dolphin/dvd/dvdidutils.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef DVDIDUTILS_H -#define DVDIDUTILS_H - - -#endif /* DVDIDUTILS_H */ diff --git a/include/dolphin/dvd/dvdlow.h b/include/dolphin/dvd/dvdlow.h deleted file mode 100644 index 1d70757805..0000000000 --- a/include/dolphin/dvd/dvdlow.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef DVDLOW_H -#define DVDLOW_H - -#include "dolphin/types.h" - -typedef void (*DVDLowCallback)(u32 intType); -vu32 __DIRegs[16] AT_ADDRESS(0xCC006000); - -#endif /* DVDLOW_H */ diff --git a/include/dolphin/dvd/dvdqueue.h b/include/dolphin/dvd/dvdqueue.h deleted file mode 100644 index da8b26027e..0000000000 --- a/include/dolphin/dvd/dvdqueue.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef DVDQUEUE_H -#define DVDQUEUE_H - - -#endif /* DVDQUEUE_H */ diff --git a/include/dolphin/dvd/fstload.h b/include/dolphin/dvd/fstload.h deleted file mode 100644 index e69d00ad61..0000000000 --- a/include/dolphin/dvd/fstload.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef FSTLOAD_H -#define FSTLOAD_H - - -#endif /* FSTLOAD_H */ diff --git a/include/dolphin/exi/EXIBios.h b/include/dolphin/exi.h similarity index 53% rename from include/dolphin/exi/EXIBios.h rename to include/dolphin/exi.h index 3e7178e275..f094c36130 100644 --- a/include/dolphin/exi/EXIBios.h +++ b/include/dolphin/exi.h @@ -1,16 +1,12 @@ -#ifndef EXIBIOS_H -#define EXIBIOS_H +#ifndef _DOLPHIN_EXI_H_ +#define _DOLPHIN_EXI_H_ -#include "dolphin/types.h" +#include #ifdef __cplusplus extern "C" { #endif -typedef struct OSContext OSContext; - -vu32 __EXIRegs[16] AT_ADDRESS(0xCC006800); - #define EXI_MEMORY_CARD_59 0x00000004 #define EXI_MEMORY_CARD_123 0x00000008 #define EXI_MEMORY_CARD_251 0x00000010 @@ -38,8 +34,11 @@ vu32 __EXIRegs[16] AT_ADDRESS(0xCC006800); #define EXI_USB_ADAPTER 0x01010000 #define EXI_NPDP_GDEV 0x01020000 -#define EXI_MODEM 0x02020000 -#define EXI_ETHER 0x04020200 +#define EXI_MODEM 0x02020000 +#define EXI_ETHER 0x04020200 +#define EXI_MIC 0x04060000 +#define EXI_AD16 0x04120000 +#define EXI_RS232C 0x04040404 #define EXI_ETHER_VIEWER 0x04220001 #define EXI_STREAM_HANGER 0x04130000 @@ -47,31 +46,22 @@ vu32 __EXIRegs[16] AT_ADDRESS(0xCC006800); #define EXI_IS_VIEWER 0x05070000 -#define EXI_FREQ_1M 0 -#define EXI_FREQ_2M 1 -#define EXI_FREQ_4M 2 -#define EXI_FREQ_8M 3 +#define EXI_READ 0 +#define EXI_WRITE 1 + +#define EXI_FREQ_1M 0 +#define EXI_FREQ_2M 1 +#define EXI_FREQ_4M 2 +#define EXI_FREQ_8M 3 #define EXI_FREQ_16M 4 #define EXI_FREQ_32M 5 -#define EXI_READ 0 -#define EXI_WRITE 1 - -#define EXI_STATE_IDLE 0x00 -#define EXI_STATE_DMA 0x01 -#define EXI_STATE_IMM 0x02 -#define EXI_STATE_BUSY (EXI_STATE_DMA | EXI_STATE_IMM) -#define EXI_STATE_SELECTED 0x04 -#define EXI_STATE_ATTACHED 0x08 -#define EXI_STATE_LOCKED 0x10 - typedef void (*EXICallback)(s32 chan, OSContext* context); - -typedef struct EXIControl { +typedef struct EXIControl { EXICallback exiCallback; EXICallback tcCallback; EXICallback extCallback; - vu32 state; + volatile u32 state; int immLen; u8* immBuf; u32 dev; @@ -84,26 +74,30 @@ typedef struct EXIControl { } queue[3]; } EXIControl; -s32 EXIImm(s32 chan, void* buf, s32 len, u32 type, EXICallback callback); -s32 EXIImmEx(s32 chan, void* buf, s32 len, u32 mode); -BOOL EXIDma(s32 chan, void* buf, s32 len, u32 type, EXICallback callback); -BOOL EXISync(s32 chan); -EXICallback EXISetExiCallback(s32 chan, EXICallback exiCallback); -BOOL EXIProbe(s32 chan); -s32 EXIProbeEx(s32 chan); -BOOL EXIAttach(s32 chan, EXICallback extCallback); -BOOL EXIDetach(s32 chan); -BOOL EXISelect(s32 chan, u32 dev, u32 freq); -BOOL EXIDeselect(s32 chan); +EXICallback EXISetExiCallback(s32 channel, EXICallback callback); + void EXIInit(void); -BOOL EXILock(s32 chan, u32 dev, EXICallback unlockedCallback); -BOOL EXIUnlock(s32 chan); -u32 EXIGetState(s32 chan); -static void UnlockedHandler(s32 chan, OSContext* context); -s32 EXIGetID(s32 chan, u32 dev, u32* id); +BOOL EXILock(s32 channel, u32 device, EXICallback callback); +BOOL EXIUnlock(s32 channel); +BOOL EXISelect(s32 channel, u32 device, u32 frequency); +BOOL EXIDeselect(s32 channel); +BOOL EXIImm(s32 channel, void* buffer, s32 length, u32 type, EXICallback callback); +BOOL EXIImmEx(s32 channel, void* buffer, s32 length, u32 type); +BOOL EXIDma(s32 channel, void* buffer, s32 length, u32 type, EXICallback callback); +BOOL EXISync(s32 channel); +BOOL EXIProbe(s32 channel); +s32 EXIProbeEx(s32 channel); +BOOL EXIAttach(s32 channel, EXICallback callback); +BOOL EXIDetach(s32 channel); +u32 EXIGetState(s32 channel); +s32 EXIGetID(s32 channel, u32 device, u32* id); +void EXIProbeReset(void); +int EXISelectSD(s32 chan, u32 dev, u32 freq); +s32 EXIGetType(s32 chan, u32 dev, u32* type); +char* EXIGetTypeString(u32 type); #ifdef __cplusplus -}; +} #endif -#endif /* EXIBIOS_H */ +#endif diff --git a/include/dolphin/exi/EXIUart.h b/include/dolphin/exi/EXIUart.h deleted file mode 100644 index 53ebe6ea6d..0000000000 --- a/include/dolphin/exi/EXIUart.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef EXIUART_H -#define EXIUART_H - - -#endif /* EXIUART_H */ diff --git a/include/dolphin/fake_tgmath.h b/include/dolphin/fake_tgmath.h new file mode 100644 index 0000000000..41a982106d --- /dev/null +++ b/include/dolphin/fake_tgmath.h @@ -0,0 +1,66 @@ +#pragma cplusplus on + +extern inline float sqrtf(float x) { + static const double _half=.5; + static const double _three=3.0; + volatile float y; + if(x > 0.0f) { + double guess = __frsqrte((double)x); // returns an approximation to + guess = _half*guess*(_three - guess*guess*x); // now have 12 sig bits + guess = _half*guess*(_three - guess*guess*x); // now have 24 sig bits + guess = _half*guess*(_three - guess*guess*x); // now have 32 sig bits + y=(float)(x*guess); + return y ; + } + return x ; +} + +extern inline float sqrt(float x) { + static const double _half=.5; + static const double _three=3.0; + volatile float y; + if(x > 0.0f) { + double guess = __frsqrte((double)x); // returns an approximation to + guess = _half*guess*(_three - guess*guess*x); // now have 12 sig bits + guess = _half*guess*(_three - guess*guess*x); // now have 24 sig bits + guess = _half*guess*(_three - guess*guess*x); // now have 32 sig bits + guess = _half*guess*(_three - guess*guess*x); // now have 32 sig bits + + y=(float)(x*guess); + return y ; + } + return x ; +} + +extern inline float fabs(float x) { +#if __MIPS__ + return fabsf(x); +#else + (*(int*)&x)&=0x7fffffff; + return x; +#endif +} + +extern inline float fabsf(float x) { + return __fabsf(x); +} + +extern float cosf(float); +extern inline float cos(float x) { + return cosf(x); +} + +inline float floor(float x) { + int i=(int)x; + float y=x-(float)i; + + if(!y || x > 8388608.0f) + return x ; // x is already an int + + if(x < 0) + return (float)--i; + // x < 0 -> int conversion of x above rounded toward zero(so decrement) + return (float)i; +} + +#pragma cplusplus reset diff --git a/include/dolphin/gd.h b/include/dolphin/gd.h index a35a19b8ac..57c929dad6 100644 --- a/include/dolphin/gd.h +++ b/include/dolphin/gd.h @@ -1,26 +1,14 @@ -#ifndef GD_H -#define GD_H +#ifndef _DOLPHIN_GD_H_ +#define _DOLPHIN_GD_H_ -#include "dolphin/gd/GDBase.h" -#include "dolphin/gd/GDGeometry.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include -#ifdef __cplusplus -extern "C" { #endif - -static inline u16 __GDLightID2Index(GXLightID id) { - u16 lightIdx = (31 - __cntlzw(id)); - if (lightIdx > 7) - lightIdx = 0; - return lightIdx; -} - -static inline u16 __GDLightID2Offset(GXLightID id) { - return __GDLightID2Index(id) * 0x10; -} - -#ifdef __cplusplus -}; -#endif - -#endif /* GD_H */ diff --git a/include/dolphin/gd/GDBase.h b/include/dolphin/gd/GDBase.h index 250e5b339a..3e148c3228 100644 --- a/include/dolphin/gd/GDBase.h +++ b/include/dolphin/gd/GDBase.h @@ -1,96 +1,151 @@ -#ifndef GDBASE_H -#define GDBASE_H +#ifndef _DOLPHIN_GD_BASE_H +#define _DOLPHIN_GD_BASE_H -#include "dolphin/gx.h" +#include +#include +#include #ifdef __cplusplus extern "C" { #endif -typedef struct GDLObj { - /* 0x0 */ u8* start; - /* 0x4 */ u32 length; - /* 0x8 */ u8* ptr; - /* 0xC */ u8* end; -} GDLObj; // Size: 0x10 +typedef void (*GDOverflowCb)(void); + +typedef struct _GDLObj { + u8* start; + u32 length; + u8* ptr; + u8* top; +} GDLObj; extern GDLObj* __GDCurrentDL; -typedef void (*GDOverflowCallback)(void); - -void GDInitGDLObj(GDLObj*, u8*, u32); -void GDFlushCurrToMem(); -void GDPadCurr32(); +void GDInitGDLObj(GDLObj* dl, void* start, u32 length); +void GDFlushCurrToMem(void); +void GDPadCurr32(void); void GDOverflowed(void); +void GDSetOverflowCallback(GDOverflowCb callback); +GDOverflowCb GDGetOverflowCallback(void); -static inline void __GDWrite(u8 data) { - *__GDCurrentDL->ptr++ = data; -} - -static inline void GDSetCurrent(GDLObj* obj) { - __GDCurrentDL = obj; -} - -static inline u32 GDGetGDLObjOffset(GDLObj* obj) { - return (u32)(obj->ptr - obj->start); -} - -static inline u8* GDGetCurrPointer() { - return __GDCurrentDL->ptr; -} - -static inline s32 GDGetCurrOffset() { - return __GDCurrentDL->ptr - __GDCurrentDL->start; -} - -static inline void GDSetCurrOffset(s32 offs) { - __GDCurrentDL->ptr = __GDCurrentDL->start + offs; -} - -static inline void GDAdvCurrOffset(s32 offs) { - __GDCurrentDL->ptr += offs; -} - -static inline void GDOverflowCheck(u32 len) { - if (__GDCurrentDL->ptr + len > __GDCurrentDL->end) { +inline static void GDOverflowCheck(u32 size) { + if (__GDCurrentDL->ptr + size > __GDCurrentDL->top) { GDOverflowed(); } } -static inline void GDWrite_u32(u32 v) { - GDOverflowCheck(4); - __GDWrite((v >> 24) & 0xff); - __GDWrite((v >> 16) & 0xff); - __GDWrite((v >> 8) & 0xff); - __GDWrite((v >> 0) & 0xff); +inline static void __GDWrite(u8 data) { + *__GDCurrentDL->ptr++ = data; } -static inline void GDWrite_u16(u16 v) { - GDOverflowCheck(2); - __GDWrite(v >> 8); - __GDWrite(v & 0xff); +inline static void GDWrite_u8(u8 data) { + GDOverflowCheck(sizeof(u8)); + __GDWrite(data); } -static inline void GDWrite_u8(u8 v) { - GDOverflowCheck(1); - __GDWrite(v); +inline static void GDWrite_u16(u16 data) { + GDOverflowCheck(sizeof(u16)); + __GDWrite((u8)((data >> 8))); + __GDWrite((u8)((data >> 0) & 0xFF)); } -static inline void GDWriteCPCmd(u8 addr, u32 v) { - GDWrite_u8(8); - GDWrite_u8(addr); - GDWrite_u32(v); +inline static void GDWrite_u24(u32 data) { + GDOverflowCheck(3); + __GDWrite((u8)((data >> 16) & 0xFF)); + __GDWrite((u8)((data >> 8) & 0xFF)); + __GDWrite((u8)((data >> 0) & 0xFF)); } -static inline void GDWriteXFCmd(u16 addr, u32 v) { - GDWrite_u8(0x10); +inline static void GDWrite_u32(u32 data) { + GDOverflowCheck(sizeof(u32)); + __GDWrite((u8)((data >> 24) & 0xFF)); + __GDWrite((u8)((data >> 16) & 0xFF)); + __GDWrite((u8)((data >> 8) & 0xFF)); + __GDWrite((u8)((data >> 0) & 0xFF)); +} + +inline static void GDWrite_f32(f32 data) { + union { + f32 f; + u32 u; + } fid; + fid.f = data; + GDWrite_u32(fid.u); +} + +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(v); + 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); +} + +inline static void GDSetCurrent(GDLObj* dl) { + __GDCurrentDL = dl; +} + +static inline u32 GDGetCurrOffset(void) { + return (u32)(__GDCurrentDL->ptr - __GDCurrentDL->start); +} + +static inline void GDSetCurrOffset(u32 offset) { + __GDCurrentDL->ptr = __GDCurrentDL->start + offset; +} + +static inline void* GDGetCurrPointer(void) { + return (void*)__GDCurrentDL->ptr; +} + +static inline u8* GDGetCurrPointer2(void) { + return __GDCurrentDL->ptr; +} + +static inline u32 GDGetGDLObjOffset(const GDLObj* dl) { + return (u32)(dl->ptr - dl->start); } #ifdef __cplusplus -}; +} #endif -#endif /* GDBASE_H */ +#endif diff --git a/include/dolphin/gd/GDFile.h b/include/dolphin/gd/GDFile.h new file mode 100644 index 0000000000..3589fbb7ee --- /dev/null +++ b/include/dolphin/gd/GDFile.h @@ -0,0 +1,31 @@ +#ifndef _DOLPHIN_GD_FILE_H +#define _DOLPHIN_GD_FILE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define GD_FILE_VERSION_NUMBER 0x11223344 + +typedef struct _GDGList { + void* ptr; + u32 byteLength; +} GDGList; + +typedef struct _GDFileHeader { + u32 versionNumber; + u32 numDLs; + u32 numPLs; + GDGList* DLDescArray; + GDGList* PLDescArray; +} GDFileHeader; + +s32 GDReadDLFile(const char* fName, u32* numDLs, u32* numPLs, GDGList** DLDescArray, GDGList** PLDescArray); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/gd/GDGeometry.h b/include/dolphin/gd/GDGeometry.h index e0c34ef727..3b0424fbd4 100644 --- a/include/dolphin/gd/GDGeometry.h +++ b/include/dolphin/gd/GDGeometry.h @@ -1,19 +1,524 @@ -#ifndef GDGEOMETRY_H -#define GDGEOMETRY_H +#ifndef _DOLPHIN_GD_GEOMETRY_H_ +#define _DOLPHIN_GD_GEOMETRY_H_ +#include #ifdef __cplusplus extern "C" { #endif -typedef struct _GXVtxDescList GXVtxDescList; +// 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 -void GDSetVtxDescv(GXVtxDescList*); -void GDSetArray(GXAttr attr, const void* data, u8 stride); -void GDSetArrayRaw(GXAttr attr, u32 data, u8 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 \ + ) + +void GDSetVtxDescv(const GXVtxDescList* attrPtr); +void GDSetVtxAttrFmtv(GXVtxFmt vtxfmt, const GXVtxAttrFmtList* list); +void GDSetArray(GXAttr attr, void* base_ptr, u8 stride); +void GDSetArrayRaw(GXAttr attr, u32 base_ptr_raw, u8 stride); +void GDPatchArrayPtr(void* base_ptr); +void GDSetTexCoordGen(GXTexCoordID dst_coord, GXTexGenType func, GXTexGenSrc src_param, u8 normalize, u32 postmtx); +void GDSetCullMode(GXCullMode mode); +void GDSetGenMode(u8 nTexGens, u8 nChans, u8 nTevs); +void GDSetGenMode2(u8 nTexGens, u8 nChans, u8 nTevs, u8 nInds, GXCullMode cm); +void GDSetLPSize(u8 lineWidth, u8 pointSize, GXTexOffset lineOffset, GXTexOffset pointOffset, u8 lineHalfAspect); +void GDSetCoPlanar(u8 enable); #ifdef __cplusplus -}; +} #endif -#endif /* GDGEOMETRY_H */ +#endif diff --git a/include/dolphin/gd/GDIndirect.h b/include/dolphin/gd/GDIndirect.h new file mode 100644 index 0000000000..4ca854c31b --- /dev/null +++ b/include/dolphin/gd/GDIndirect.h @@ -0,0 +1,91 @@ +#ifndef _DOLPHIN_GD_INDIRECT_H_ +#define _DOLPHIN_GD_INDIRECT_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define BP_TEV_INDIRECT(ind_stage, format, bias_sel, alpha_sel, mtx_sel, wrap_s, wrap_t, utc_lod, add_prev, id) \ + ( \ + (u32)(ind_stage) << 0 | \ + (u32)(format) << 2 | \ + (u32)(bias_sel) << 4 | \ + (u32)(alpha_sel) << 7 | \ + (u32)(mtx_sel) << 9 | \ + (u32)(wrap_s) << 13 | \ + (u32)(wrap_t) << 16 | \ + (u32)(utc_lod) << 19 | \ + (u32)(add_prev) << 20 | \ + (u32)(id) << 24 \ + ) + +#define BP_IND_MTX(m0, m1, scale_exp, id) \ + ( \ + (u32)(m0) << 0 | \ + (u32)(m1) << 11 | \ + (u32)(scale_exp) << 22 | \ + (u32)(id) << 24 \ + ) + +#define BP_IND_TEXCOORD_SCALE(scaleS0, scaleT0, scaleS1, scaleT1, id) \ + ( \ + (u32)(scaleS0) << 0 | \ + (u32)(scaleT0) << 4 | \ + (u32)(scaleS1) << 8 | \ + (u32)(scaleT1) << 12 | \ + (u32)(id) << 24 \ + ) + +#define BP_IND_TEX_ORDER(map0, coord0, map1, coord1, map2, coord2, map3, coord3, id) \ + ( \ + (u32)(map0) << 0 | \ + (u32)(coord0) << 3 | \ + (u32)(map1) << 6 | \ + (u32)(coord1) << 9 | \ + (u32)(map2) << 12 | \ + (u32)(coord2) << 15 | \ + (u32)(map3) << 18 | \ + (u32)(coord3) << 21 | \ + (u32)(id) << 24 \ + ) + +#define BP_IND_MASK(mask, id) \ + ( \ + (u32)(mask) << 0 | \ + (u32)(id) << 24 \ + ) + +void GDSetTevIndirect(GXTevStageID tev_stage, GXIndTexStageID ind_stage, + GXIndTexFormat format, GXIndTexBiasSel bias_sel, + GXIndTexMtxID matrix_sel, GXIndTexWrap wrap_s, + GXIndTexWrap wrap_t, u8 add_prev, u8 utc_lod, + GXIndTexAlphaSel alpha_sel); +void GDSetIndTexMtx(GXIndTexMtxID mtx_id, const f32 offset[2][3], s8 scale_exp); +void GDSetIndTexCoordScale(GXIndTexStageID indStageEven, GXIndTexScale scaleS0, + GXIndTexScale scaleT0, GXIndTexScale scaleS1, + GXIndTexScale scaleT1); +void GDSetIndTexOrder(GXTexCoordID texCoord0, GXTexMapID texMap0, + GXTexCoordID texCoord1, GXTexMapID texMap1, + GXTexCoordID texCoord2, GXTexMapID texMap2, + GXTexCoordID texCoord3, GXTexMapID texMap3); +void GDSetTevDirect(GXTevStageID tev_stage); +void GDSetTevIndWarp(GXTevStageID tev_stage, GXIndTexStageID ind_stage, u8 signed_offset, u8 replace_mode, GXIndTexMtxID matrix_sel); +void GDSetTevIndTile(GXTevStageID tev_stage, GXIndTexStageID ind_stage, + u16 tilesize_s, u16 tilesize_t, u16 tilespacing_s, + u16 tilespacing_t, GXIndTexFormat format, + GXIndTexMtxID matrix_sel, GXIndTexBiasSel bias_sel, + GXIndTexAlphaSel alpha_sel); +void GDSetTevIndBumpST(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel); +void GDSetTevIndBumpXYZ(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel); +void GDSetTevIndRepeat(GXTevStageID tev_stage); +void __GDSetIndTexMask(u32 mask); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/gd/GDLight.h b/include/dolphin/gd/GDLight.h new file mode 100644 index 0000000000..b67d385c6f --- /dev/null +++ b/include/dolphin/gd/GDLight.h @@ -0,0 +1,73 @@ +#ifndef _DOLPHIN_GD_LIGHT_H_ +#define _DOLPHIN_GD_LIGHT_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define XF_LIGHT_ID 0x0600 +#define XF_LIGHT_COLOR_ID 0x0603 +#define XF_LIGHT_ATTN_ID 0x0604 +#define XF_LIGHT_DISTATTN_ID 0x0607 +#define XF_LIGHT_POS_ID 0x060A +#define XF_LIGHT_SPEC_DIR_ID 0x060A +#define XF_LIGHT_DIR_ID 0x060D + +#define XF_REG_AMBIENT0_ID 0x100A +#define XF_REG_AMBIENT1_ID 0x100B +#define XF_REG_MATERIAL0_ID 0x100C +#define XF_REG_MATERIAL1_ID 0x100D +#define XF_REG_COLOR0CNTRL_ID 0x100E +#define XF_REG_COLOR1CNTRL_ID 0x100F +#define XF_REG_ALPHA0CNTRL_ID 0x1010 +#define XF_REG_ALPHA1CNTRL_ID 0x1011 + +#define XF_REG_CHAN_CTRL(matsrc, enable, lightmask0, ambsrc, diff_fn, p5, p6, lightmask4) \ + ( \ + (u32)(matsrc) << 0 | \ + (u32)(enable) << 1 | \ + (u32)(lightmask0) << 2 | \ + (u32)(ambsrc) << 6 | \ + (u32)(diff_fn) << 7 | \ + (u32)(p5) << 9 | \ + (u32)(p6) << 10 | \ + (u32)(lightmask4) << 11 \ + ) + +void GDSetLightAttn(GXLightID light, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2); +void GDSetLightSpot(GXLightID light, f32 cutoff, GXSpotFn spot_func); +void GDSetLightDistAttn(GXLightID light, f32 ref_dist, f32 ref_br, GXDistAttnFn dist_func); +void GDSetLightColor(GXLightID light, GXColor color); +void GDSetLightPos(GXLightID light, f32 x, f32 y, f32 z); +void GDSetLightDir(GXLightID light, f32 nx, f32 ny, f32 nz); +void GDSetSpecularDirHA(GXLightID light, f32 nx, f32 ny, f32 nz, f32 hx, f32 hy, f32 hz); +void GDSetSpecularDir(GXLightID light, f32 nx, f32 ny, f32 nz); +void GDLoadLightObjIndx(u32 lt_obj_indx, GXLightID light); +void GDSetChanAmbColor(GXChannelID chan, GXColor color); +void GDSetChanMatColor(GXChannelID chan, GXColor color); +void GDSetChanCtrl(GXChannelID chan, u8 enable, GXColorSrc amb_src, + GXColorSrc mat_src, u32 light_mask, GXDiffuseFn diff_fn, + GXAttnFn attn_fn); + +inline static u16 __GDLightID2Index(GXLightID id) { + u16 idx; + + idx = 0x1F - __cntlzw(id); + if (idx > 7) { + idx = 0; + } + return idx; +} + +inline static u16 __GDLightID2Offset(GXLightID id) { + return __GDLightID2Index(id) * 16; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/gd/GDPixel.h b/include/dolphin/gd/GDPixel.h new file mode 100644 index 0000000000..158b04ec1f --- /dev/null +++ b/include/dolphin/gd/GDPixel.h @@ -0,0 +1,95 @@ +#ifndef _DOLPHIN_GD_PIXEL_H +#define _DOLPHIN_GD_PIXEL_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#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 GDSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color); +void GDSetBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor, GXLogicOp logic_op); +void GDSetBlendModeEtc(GXBlendMode type, GXBlendFactor src_factor, + GXBlendFactor dst_factor, GXLogicOp logic_op, + u8 color_update_enable, + u8 alpha_update_enable, + u8 dither_enable); +void GDSetZMode(u8 compare_enable, GXCompare func, u8 update_enable); +void GDSetDstAlpha(u8 enable, u8 alpha); +void GDSetDrawSync(u16 token); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/gd/GDTev.h b/include/dolphin/gd/GDTev.h new file mode 100644 index 0000000000..baec8b5e2e --- /dev/null +++ b/include/dolphin/gd/GDTev.h @@ -0,0 +1,133 @@ +#ifndef _DOLPHIN_GD_TEV_H +#define _DOLPHIN_GD_TEV_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#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 GDSetTevOp(GXTevStageID stage, GXTevMode mode); +void GDSetTevColorCalc(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, + GXTevColorArg c, GXTevColorArg d, GXTevOp op, + GXTevBias bias, GXTevScale scale, u8 clamp, + GXTevRegID out_reg); +void GDSetTevAlphaCalcAndSwap(GXTevStageID stage, GXTevAlphaArg a, + GXTevAlphaArg b, GXTevAlphaArg c, GXTevAlphaArg d, + GXTevOp op, GXTevBias bias, GXTevScale scale, + u8 clamp, GXTevRegID out_reg, + GXTevSwapSel ras_sel, GXTevSwapSel tex_sel); +void GDSetTevColor(GXTevRegID reg, GXColor color); +void GDSetTevColorS10(GXTevRegID reg, GXColorS10 color); +void GDSetTevKColor(GXTevKColorID reg, GXColor color); +void GDSetTevKonstantSel(GXTevStageID evenStage, GXTevKColorSel kcsel0, + GXTevKAlphaSel kasel0, GXTevKColorSel kcsel1, + GXTevKAlphaSel kasel1); +void GDSetTevSwapModeTable(GXTevSwapSel table, GXTevColorChan red, + GXTevColorChan green, GXTevColorChan blue, + GXTevColorChan alpha); +void GDSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1); +void GDSetZTexture(GXZTexOp op, GXTexFmt fmt, u32 bias); +void GDSetTevOrder(GXTevStageID evenStage, GXTexCoordID coord0, GXTexMapID map0, + GXChannelID color0, GXTexCoordID coord1, GXTexMapID map1, + GXChannelID color1); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/gd/GDTexture.h b/include/dolphin/gd/GDTexture.h new file mode 100644 index 0000000000..2370cbb52b --- /dev/null +++ b/include/dolphin/gd/GDTexture.h @@ -0,0 +1,127 @@ +#ifndef _DOLPHIN_GD_TEXTURE_H +#define _DOLPHIN_GD_TEXTURE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define BP_TEX_MODE0(wrap_s, wrap_t, mag_filt, min_filt, edge_lod, lod_bias, max_aniso, bias_clamp, id) \ + ( \ + (u32)(wrap_s) << 0 | \ + (u32)(wrap_t) << 2 | \ + (u32)(mag_filt) << 4 | \ + (u32)(min_filt) << 5 | \ + (u32)(edge_lod) << 8 | \ + (u32)(lod_bias) << 9 | \ + (u32)(max_aniso) << 19 | \ + (u32)(bias_clamp) << 21 | \ + (u32)(id) << 24 \ + ) + +#define BP_TEX_MODE1(min_lod, max_lod, id) \ + ( \ + (u32)(min_lod) << 0 | \ + (u32)(max_lod) << 8 | \ + (u32)(id) << 24 \ + ) + +#define BP_IMAGE_ATTR(width, height, format, id) \ + ( \ + (u32)(width) << 0 | \ + (u32)(height) << 10 | \ + (u32)(format) << 20 | \ + (u32)(id) << 24 \ + ) + +#define BP_IMAGE_PTR(ptr, id) \ + ( \ + (u32)(ptr) << 0 | \ + (u32)(id) << 24 \ + ) + +#define BP_TEX_CACHE_EVEN(tmem, size0, size1, type, id) \ + ( \ + (u32)(tmem) << 0 | \ + (u32)(size0) << 15 | \ + (u32)(size1) << 18 | \ + (u32)(type) << 21 | \ + (u32)(id) << 24 \ + ) + +#define BP_TEX_CACHE_ODD(tmem, size0, size1, id) \ + ( \ + (u32)(tmem) << 0 | \ + (u32)(size0) << 15 | \ + (u32)(size1) << 18 | \ + (u32)(id) << 24 \ + ) + +#define BP_TEX_TLUT(tmem, format, id) \ + ( \ + (u32)(tmem) << 0 | \ + (u32)(format) << 10 | \ + (u32)(id) << 24 \ + ) + +#define BP_TEXCOORD_S_SCALE(s_scale, s_bias, s_wrap, line_offset, point_offset, id) \ + ( \ + (u32)(s_scale) << 0 | \ + (u32)(s_bias) << 16 | \ + (u32)(s_wrap) << 17 | \ + (u32)(line_offset) << 18 | \ + (u32)(point_offset) << 19 | \ + (u32)(id) << 24 \ + ) + +#define BP_TEXCOORD_T_SCALE(t_scale, t_bias, t_wrap, id) \ + ( \ + (u32)(t_scale) << 0 | \ + (u32)(t_bias) << 16 | \ + (u32)(t_wrap) << 17 | \ + (u32)(id) << 24 \ + ) + +#define BP_LOAD_TLUT0(ptr, id) \ + ( \ + (u32)(ptr) << 0 | \ + (u32)(id) << 24 \ + ) + +#define BP_LOAD_TLUT1(ptr, size, id) \ + ( \ + (u32)(ptr) << 0 | \ + (u32)(size) << 10 | \ + (u32)(id) << 24 \ + ) + +void GDSetTexLookupMode(GXTexMapID id, GXTexWrapMode wrap_s, + GXTexWrapMode wrap_t, GXTexFilter min_filt, + GXTexFilter mag_filt, f32 min_lod, f32 max_lod, + f32 lod_bias, u8 bias_clamp, u8 do_edge_lod, + GXAnisotropy max_aniso); + +void GDSetTexImgAttr(GXTexMapID id, u16 width, u16 height, GXTexFmt format); +void GDSetTexImgPtr(GXTexMapID id, void* image_ptr); +void GDSetTexImgPtrRaw(GXTexMapID id, u32 image_ptr_raw); +void GDPatchTexImgPtr(void* image_ptr); +void GDSetTexCached(GXTexMapID id, u32 tmem_even, GXTexCacheSize size_even, + u32 tmem_odd, GXTexCacheSize size_odd); +void GDSetTexPreLoaded(GXTexMapID id, u32 tmem_even, u32 tmem_odd); +void GDSetTexTlut(GXTexMapID id, u32 tmem_addr, GXTlutFmt format); +void GDSetTexCoordScale(GXTexCoordID coord, u16 s_scale, u16 t_scale); +void GDSetTexCoordScale2(GXTexCoordID coord, u16 s_scale, u8 s_bias, + u8 s_wrap, u16 t_scale, u8 t_bias, u8 t_wrap); +void GDSetTexCoordScaleAndTOEs(GXTexCoordID coord, u16 s_scale, u8 s_bias, + u8 s_wrap, u16 t_scale, u8 t_bias, u8 t_wrap, + u8 line_offset, u8 point_offset); +void GDLoadTlut(void* tlut_ptr, u32 tmem_addr, GXTlutSize size); +void GDLoadTlutRaw(u32 tlut_ptr_raw, u32 tmem_addr, GXTlutSize size); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/gd/GDTransform.h b/include/dolphin/gd/GDTransform.h new file mode 100644 index 0000000000..8d0159fdb0 --- /dev/null +++ b/include/dolphin/gd/GDTransform.h @@ -0,0 +1,56 @@ +#ifndef _DOLPHIN_GD_TRANSFORM_H_ +#define _DOLPHIN_GD_TRANSFORM_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define CP_MTX_REG_A_ID 0x30 +#define CP_MTX_REG_B_ID 0x40 + +#define XF_REG_MATRIXINDEX0_ID 0x1018 +#define XF_REG_MATRIXINDEX1_ID 0x1019 +#define XF_REG_PROJECTIONA_ID 0x1020 +#define XF_REG_PROJECTIONB_ID 0x1021 +#define XF_REG_PROJECTIONC_ID 0x1022 +#define XF_REG_PROJECTIOND_ID 0x1023 +#define XF_REG_PROJECTIONE_ID 0x1024 +#define XF_REG_PROJECTIONF_ID 0x1025 +#define XF_REG_PROJECTORTHO_ID 0x1026 + +#define CP_MTX_REG_A(pn, t0, t1, t2, t3) \ + ( \ + (u32)(pn) << 0 | \ + (u32)(t0) << 6 | \ + (u32)(t1) << 12 | \ + (u32)(t2) << 18 | \ + (u32)(t3) << 24 \ + ) + +#define CP_MTX_REG_B(t4, t5, t6, t7) \ + ( \ + (u32)(t4) << 0 | \ + (u32)(t5) << 6 | \ + (u32)(t6) << 12 | \ + (u32)(t7) << 18 \ + ) + +void GDLoadPosMtxImm(const Mtx mtx, u32 id); +void GDLoadPosMtxIndx(u16 mtx_indx, u32 id); +void GDLoadNrmMtxImm(const Mtx mtx, u32 id); +void GDLoadNrmMtxImm3x3(const f32 mtx[3][3], u32 id); +void GDLoadNrmMtxIndx3x3(u16 mtx_indx, u32 id); +void GDLoadTexMtxImm(const Mtx mtx, u32 id, GXTexMtxType type); +void GDLoadTexMtxIndx(u16 mtx_indx, u32 id, GXTexMtxType type); +void GDSetCurrentMtx(u32 pn, u32 t0, u32 t1, u32 t2, u32 t3, u32 t4, u32 t5, u32 t6, u32 t7); +void GDSetProjection(const Mtx44 mtx, GXProjectionType type); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/gf.h b/include/dolphin/gf.h new file mode 100644 index 0000000000..50676aeab8 --- /dev/null +++ b/include/dolphin/gf.h @@ -0,0 +1,9 @@ +#ifndef _DOLPHIN_GF_H_ +#define _DOLPHIN_GF_H_ + +#include +#include +#include +#include + +#endif diff --git a/include/dolphin/gf/GFGeometry.h b/include/dolphin/gf/GFGeometry.h index 44626de942..759d18c355 100644 --- a/include/dolphin/gf/GFGeometry.h +++ b/include/dolphin/gf/GFGeometry.h @@ -1,8 +1,41 @@ #ifndef GFGEOMETRY_H #define GFGEOMETRY_H -#include "dolphin/gx.h" +#include -void GFSetGenMode2(u8 param_0, u8 param_1, u8 param_2, u8 param_3, _GXCullMode param_4); +#define GF_GEN_MODE(nTexGens, nChans, nTevs, cm, nInds) \ + ( \ + (u32)(nTexGens) << 0 | \ + (u32)(nChans) << 4 | \ + (u32)(nTevs) << 10 | \ + (u32)(cm) << 14 | \ + (u32)(nInds) << 16 \ + ) + +static inline void GFWrite_u8(u8 data) { + GXCmd1u8(data); +} + +static inline void GFWrite_u32(u32 data) { + GXCmd1u32(data); +} + +static inline void GFWrite_u16(u16 data) { + GXCmd1u16(data); +} + +static inline void GFWriteBPCmd(u32 regval) { + GFWrite_u8(GX_LOAD_BP_REG); + GFWrite_u32(regval); +} + +static inline void GFWriteXFCmd(u16 addr, u32 val) { + GFWrite_u8(GX_LOAD_XF_REG); + GFWrite_u16(0); + GFWrite_u16(addr); + GFWrite_u32(val); +} + +void GFSetGenMode2(u8 nTexGens, u8 nChans, u8 nTevs, u8 nInds, GXCullMode cm); #endif /* GFGEOMETRY_H */ diff --git a/include/dolphin/gf/GFLight.h b/include/dolphin/gf/GFLight.h index d027ec11be..15d9644340 100644 --- a/include/dolphin/gf/GFLight.h +++ b/include/dolphin/gf/GFLight.h @@ -1,8 +1,8 @@ #ifndef GFLIGHT_H #define GFLIGHT_H -#include "dolphin/gx/GXStruct.h" +#include -void GFSetChanAmbColor(_GXChannelID param_0, _GXColor param_1); +void GFSetChanAmbColor(GXChannelID chan, GXColor color); #endif /* GFLIGHT_H */ diff --git a/include/dolphin/gf/GFPixel.h b/include/dolphin/gf/GFPixel.h index 8af003ea82..9260dcf348 100644 --- a/include/dolphin/gf/GFPixel.h +++ b/include/dolphin/gf/GFPixel.h @@ -3,10 +3,11 @@ #include -void GFSetFog(GXFogType param_0, f32 param_1, f32 param_2, f32 param_3, f32 param_4, - GXColor param_5); -void GFSetBlendModeEtc(GXBlendMode param_0, GXBlendFactor param_1, GXBlendFactor param_2, - GXLogicOp param_3, u8 param_4, u8 param_5, u8 param_6); -void GFSetZMode(u8 param_0, GXCompare param_1, u8 param_2); +void GFSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color); +void GFSetBlendModeEtc(GXBlendMode type, GXBlendFactor src_factor, + GXBlendFactor dst_factor, GXLogicOp logic_op, + u8 color_update_enable, u8 alpha_update_enable, + u8 dither_enable); +void GFSetZMode(u8 compare_enable, GXCompare func, u8 update_enable); #endif /* GFPIXEL_H */ diff --git a/include/dolphin/gf/GFTev.h b/include/dolphin/gf/GFTev.h index bfc56ac1b8..49921795e8 100644 --- a/include/dolphin/gf/GFTev.h +++ b/include/dolphin/gf/GFTev.h @@ -1,5 +1,8 @@ #ifndef GFTEV_H #define GFTEV_H +#include + +void GFSetTevColorS10(GXTevRegID reg, GXColorS10 color); #endif /* GFTEV_H */ diff --git a/include/dolphin/gx.h b/include/dolphin/gx.h index e59235b372..0e90e543e1 100644 --- a/include/dolphin/gx.h +++ b/include/dolphin/gx.h @@ -1,238 +1,40 @@ -#ifndef GX_H_ -#define GX_H_ +#ifndef _DOLPHIN_GX_H_ +#define _DOLPHIN_GX_H_ -#include "dolphin/gx/GXAttr.h" -#include "dolphin/gx/GXBump.h" -#include "dolphin/gx/GXDisplayList.h" -#include "dolphin/gx/GXFifo.h" -#include "dolphin/gx/GXFrameBuf.h" -#include "dolphin/gx/GXGeometry.h" -#include "dolphin/gx/GXInit.h" -#include "dolphin/gx/GXLight.h" -#include "dolphin/gx/GXMisc.h" -#include "dolphin/gx/GXPerf.h" -#include "dolphin/gx/GXPixel.h" -#include "dolphin/gx/GXTev.h" -#include "dolphin/gx/GXTransform.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// unsorted GX externs #ifdef __cplusplus extern "C" { #endif -// Pack value into bitfield -// clang-format off -#define GX_BITFIELD_SET(field, pos, size, value) (field) = __rlwimi((field), (value), 31 - (pos) - (size) + 1, (pos), (pos) + (size)-1) -#define GX_BITFIELD_TRUNC(field, pos, size, value) (__rlwimi((field), (value), 0, (pos), (pos) + (size)-1)) - -#define GX_BITGET(field, pos, size) ((field) >> (31 - (pos) - (size) + 1) & ((1 << (size)) - 1)) -#define GX_GET_REG(reg, st, end) GX_BITGET(reg, st, (end - st + 1)) -#define GX_SET_REG(reg, x, st, end) GX_BITFIELD_SET(reg, st, (end - st + 1), x) -#define GX_SET_TRUNC(reg, x, st, end) GX_BITFIELD_TRUNC((reg), (st), ((end) - (st) + 1), (x)) - -#define GXCOLOR_AS_U32(color) (*((u32*)&(color))) - -#define INSERT_FIELD(reg, value, nbits, shift) \ - (reg) = ((u32) (reg) & ~(((1 << (nbits)) - 1) << (shift))) | \ - ((u32) (value) << (shift)); - -#define FAST_FLAG_SET(regOrg, newFlag, shift, size) \ - do { \ - (regOrg) = (u32)__rlwimi((int)(regOrg), (int)(newFlag), (shift), (32 - (shift) - (size)), (31 - (shift))); \ - } while (0); -// clang-format on - -#define GX_LOAD_BP_REG 0x61 -#define GX_NOP 0 - -typedef union { - u8 u8; - u16 u16; - u32 u32; - u64 u64; - s8 s8; - s16 s16; - s32 s32; - s64 s64; - f32 f32; - f64 f64; -} PPCWGPipe; - -#define GXFIFO_ADDR 0xCC008000 -volatile PPCWGPipe GXWGFifo AT_ADDRESS(GXFIFO_ADDR); - -#define GX_WRITE_U8(data) GXWGFifo.u8 = data; -#define GX_WRITE_U32(data) GXWGFifo.u32 = data; -#define GX_WRITE_F32(val) (GXWGFifo.f32 = (f32)val) - -#define GX_CP_LOAD_REG(addr, data) \ - GXWGFifo.s8 = GX_FIFO_CMD_LOAD_CP_REG; \ - GXWGFifo.s8 = (addr); \ - GXWGFifo.s32 = (data); - -/** - * Header for an XF register load - */ -#define GX_XF_LOAD_REG_HDR(addr) \ - GXWGFifo.s8 = GX_FIFO_CMD_LOAD_XF_REG; \ - GXWGFifo.s32 = (addr); - -/** - * Load immediate value into XF register - */ -#define GX_XF_LOAD_REG(addr, data) \ - GX_XF_LOAD_REG_HDR(addr); \ - GXWGFifo.s32 = (data); - -/** - * Load immediate value into BP register - */ -#define GX_BP_LOAD_REG(data) \ - GXWGFifo.s8 = GX_FIFO_CMD_LOAD_BP_REG; \ - GXWGFifo.s32 = (data); - -/** - * Load immediate values into multiple XF registers - */ -#define GX_XF_LOAD_REGS(size, addr) \ - { \ - u32 cmd = (size) << 16 | addr; \ - GX_XF_LOAD_REG_HDR(cmd); \ - } - -static inline void GXPosition3f32(const f32 x, const f32 y, const f32 z) { - GXWGFifo.f32 = x; - GXWGFifo.f32 = y; - GXWGFifo.f32 = z; -} - -static inline void GXNormal3f32(const f32 x, const f32 y, const f32 z) { - GXWGFifo.f32 = x; - GXWGFifo.f32 = y; - GXWGFifo.f32 = z; -} - -static inline void GXNormal1x16(const u16 x) { - GXWGFifo.u16 = x; -} - -static inline void GXPosition2f32(const f32 x, const f32 z) { - GXWGFifo.f32 = x; - GXWGFifo.f32 = z; -} - -static inline void GXColor1u32(const u32 c) { - GXWGFifo.u32 = c; -} - -static inline void GXColor4u8(const u8 r, const u8 g, const u8 b, const u8 a) { - GXWGFifo.u8 = r; - GXWGFifo.u8 = g; - GXWGFifo.u8 = b; - GXWGFifo.u8 = a; -} - -static inline void GXTexCoord2f32(const f32 s, const f32 t) { - GXWGFifo.f32 = s; - GXWGFifo.f32 = t; -} - -static inline void GXTexCoord2u8(const u8 s, const u8 t) { - GXWGFifo.u8 = s; - GXWGFifo.u8 = t; -} - -static inline void GXTexCoord1x8(const u8 s) { - GXWGFifo.u8 = s; -} - -static inline void GXTexCoord1x16(const u16 s) { - GXWGFifo.u16 = s; -} - -static inline void GXPosition2u16(const u16 x, const u16 y) { - GXWGFifo.u16 = x; - GXWGFifo.u16 = y; -} - -static inline void GXPosition1x16(const u16 x) { - GXWGFifo.u16 = x; -} - -static inline void GXPosition1x8(const u8 x) { - GXWGFifo.u8 = x; -} - -static inline void GXPosition3s8(const s8 x, const s8 y, const s8 z) { - GXWGFifo.s8 = x; - GXWGFifo.s8 = y; - GXWGFifo.s8 = z; -} - -static inline void GXPosition2s8(const s8 x, const s8 y) { - GXWGFifo.s8 = x; - GXWGFifo.s8 = y; -} - -static inline void GXPosition2s16(const s16 x, const s16 y) { - GXWGFifo.s16 = x; - GXWGFifo.s16 = y; -} - -static inline void GXPosition3s16(const s16 x, const s16 y, const s16 z) { - GXWGFifo.s16 = x; - GXWGFifo.s16 = y; - GXWGFifo.s16 = z; -} - -static inline void GXTexCoord2s8(const s8 x, const s8 y) { - GXWGFifo.s8 = x; - GXWGFifo.s8 = y; -} - -static inline void GXTexCoord2u16(const u16 x, const u16 y) { - GXWGFifo.u16 = x; - GXWGFifo.u16 = y; -} - -static inline void GXTexCoord2s16(const s16 u, const s16 v) { - GXWGFifo.s16 = u; - GXWGFifo.s16 = v; -} - -static inline void GFWriteBPCmd(u32 param_1) { - GXWGFifo.u8 = 0x61; - GXWGFifo.u32 = param_1; -} - -static inline u32 GXReadCPReg(u32 addrLo, u32 addrHi) { - u32 hiStart, hiNew, lo; - hiStart = GX_GET_CP_REG(addrHi); - do { - hiNew = hiStart; - lo = GX_GET_CP_REG(addrLo); - hiStart = GX_GET_CP_REG(addrHi); - } while (hiStart != hiNew); - - return ((hiStart << 16) | lo); -} - -inline void GFFill(u16 param_1, u32 param_2) { - GXWGFifo.u8 = 0x10; - GXWGFifo.u16 = 0; - GXWGFifo.u16 = param_1; - GXWGFifo.u32 = param_2; -} - -static inline void GXEnd(void) {} - -extern GXRenderModeObj GXNtsc480IntDf; -extern GXRenderModeObj GXNtsc480Int; -extern GXRenderModeObj GXMpal480IntDf; -extern GXRenderModeObj GXPal528IntDf; -extern GXRenderModeObj GXEurgb60Hz480IntDf; +// GXMisc +void (*GXSetDrawSyncCallback(void (*cb)(u16)))(u16); +void GXSetDrawSync(u16 token); #ifdef __cplusplus -}; +} #endif #endif diff --git a/include/dolphin/gx/GXAttr.h b/include/dolphin/gx/GXAttr.h deleted file mode 100644 index 667c7f33db..0000000000 --- a/include/dolphin/gx/GXAttr.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef GXATTR_H -#define GXATTR_H - -#include "dolphin/gx/GXEnum.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _GXVtxDescList { - /* 0x0 */ GXAttr attr; - /* 0x4 */ GXAttrType type; -} GXVtxDescList; // Size: 0x08 - -typedef struct _GXVtxAttrFmtList { - /* 0x00 */ GXAttr mAttrib; - /* 0x04 */ GXCompCnt mCompCnt; - /* 0x08 */ GXCompType mCompType; - /* 0x0C */ u8 mCompShift; -} GXVtxAttrFmtList; // Size: 0x10 - -void GXSetVtxDesc(GXAttr attr, GXAttrType type); -void GXSetVtxDescv(GXVtxDescList* list); -void __GXSetVCD(void); -void __GXCalculateVLim(void); -void GXClearVtxDesc(void); -void GXSetVtxAttrFmt(GXVtxFmt fmt, GXAttr attr, GXCompCnt cnt, GXCompType type, u8); -void GXSetVtxAttrFmtv(GXVtxFmt fmt, GXVtxAttrFmtList* list); -void __GXSetVAT(void); -void GXSetArray(GXAttr attr, void* base, u8); -void GXInvalidateVtxCache(void); -void GXSetTexCoordGen2(GXTexCoordID dst, GXTexGenType type, GXTexGenSrc src, u32 mtx, - GXBool renormalize, u32 pt_mtx); -void GXSetNumTexGens(u8 numTexGens); - -void GXGetVtxAttrFmtv(GXVtxFmt param_0, GXVtxAttrFmtList* param_1); -void GXGetVtxAttrFmt(GXVtxFmt param_0, int param_1, GXCompCnt* param_2, GXCompType* param_3, - u8* param_4); -void GXGetVtxDescv(GXVtxDescList* attrPtr); - -static inline void GXSetTexCoordGen(GXTexCoordID dst, GXTexGenType type, GXTexGenSrc src, u32 mtx) { - GXSetTexCoordGen2(dst, type, src, mtx, GX_FALSE, GX_PTIDENTITY); -} - -#ifdef __cplusplus -}; -#endif - -#endif /* GXATTR_H */ diff --git a/include/dolphin/gx/GXBump.h b/include/dolphin/gx/GXBump.h index ddb8d67749..2a24dc69f8 100644 --- a/include/dolphin/gx/GXBump.h +++ b/include/dolphin/gx/GXBump.h @@ -1,23 +1,29 @@ -#ifndef GXBUMP_H -#define GXBUMP_H +#ifndef _DOLPHIN_GX_GXBUMP_H_ +#define _DOLPHIN_GX_GXBUMP_H_ -#include "dolphin/gx/GXEnum.h" +#include #ifdef __cplusplus extern "C" { #endif -void GXSetTevIndirect(GXTevStageID tevStage, GXIndTexStageID texStage, GXIndTexFormat texFmt, - GXIndTexBiasSel biasSel, GXIndTexMtxID mtxID, GXIndTexWrap wrapS, - GXIndTexWrap wrapT, u8 addPrev, u8 utcLod, GXIndTexAlphaSel alphaSel); -void GXSetIndTexMtx(GXIndTexMtxID mtxID, f32 offset[6], s8 scale_exp); -void GXSetIndTexCoordScale(GXIndTexStageID texStage, GXIndTexScale scaleS, GXIndTexScale scaleT); -void GXSetIndTexOrder(GXIndTexStageID stage, GXTexCoordID coord, GXTexMapID map); -void GXSetNumIndStages(u8 num); -void GXSetTevDirect(GXTevStageID stage); +void GXSetTevIndirect(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexFormat format, GXIndTexBiasSel bias_sel, GXIndTexMtxID matrix_sel, GXIndTexWrap wrap_s, GXIndTexWrap wrap_t, GXBool add_prev, GXBool utc_lod, GXIndTexAlphaSel alpha_sel); +void GXSetIndTexMtx(GXIndTexMtxID mtx_id, const f32 offset[2][3], s8 scale_exp); +void GXSetIndTexCoordScale(GXIndTexStageID ind_state, GXIndTexScale scale_s, GXIndTexScale scale_t); +void GXSetIndTexOrder(GXIndTexStageID ind_stage, GXTexCoordID tex_coord, GXTexMapID tex_map); +void GXSetNumIndStages(u8 nIndStages); +void GXSetTevDirect(GXTevStageID tev_stage); +void GXSetTevIndWarp(GXTevStageID tev_stage, GXIndTexStageID ind_stage, u8 signed_offset, u8 replace_mode, GXIndTexMtxID matrix_sel); +void GXSetTevIndTile(GXTevStageID tev_stage, GXIndTexStageID ind_stage, u16 tilesize_s, + u16 tilesize_t, u16 tilespacing_s, u16 tilespacing_t, GXIndTexFormat format, + GXIndTexMtxID matrix_sel, GXIndTexBiasSel bias_sel, GXIndTexAlphaSel alpha_sel); +void GXSetTevIndBumpST(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel); +void GXSetTevIndBumpXYZ(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel); +void GXSetTevIndRepeat(GXTevStageID tev_stage); +void __GXSetIndirectMask(u32 mask); #ifdef __cplusplus -}; +} #endif -#endif /* GXBUMP_H */ +#endif diff --git a/include/dolphin/gx/GXCommandList.h b/include/dolphin/gx/GXCommandList.h new file mode 100644 index 0000000000..9adae3cb79 --- /dev/null +++ b/include/dolphin/gx/GXCommandList.h @@ -0,0 +1,37 @@ +#ifndef _DOLPHIN_GX_GXCOMMANDLIST_H_ +#define _DOLPHIN_GX_GXCOMMANDLIST_H_ + +#include + +#define GX_NOP 0x00 +#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 + +#define GX_DRAW_QUADS 0x80 +#define GX_DRAW_TRIANGLES 0x90 +#define GX_DRAW_TRIANGLE_STRIP 0x98 +#define GX_DRAW_TRIANGLE_FAN 0xA0 +#define GX_DRAW_LINES 0xA8 +#define GX_DRAW_LINE_STRIP 0xB0 +#define GX_DRAW_POINTS 0xB8 + +#define GX_CMD_CALL_DL 0x40 +#define GX_CMD_INVAL_VTX 0x48 + +#define GX_OPCODE_MASK 0xF8 +#define GX_VAT_MASK 0x07 + +extern u8 GXTexMode0Ids[8]; +extern u8 GXTexMode1Ids[8]; +extern u8 GXTexImage0Ids[8]; +extern u8 GXTexImage1Ids[8]; +extern u8 GXTexImage2Ids[8]; +extern u8 GXTexImage3Ids[8]; +extern u8 GXTexTlutIds[8]; + +#endif diff --git a/include/dolphin/gx/GXCpu2Efb.h b/include/dolphin/gx/GXCpu2Efb.h new file mode 100644 index 0000000000..46aa3e3369 --- /dev/null +++ b/include/dolphin/gx/GXCpu2Efb.h @@ -0,0 +1,29 @@ +#ifndef _DOLPHIN_GX_GXCPU2EFB_H_ +#define _DOLPHIN_GX_GXCPU2EFB_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void GXPokeAlphaMode(GXCompare func, u8 threshold); +void GXPokeAlphaRead(GXAlphaReadMode mode); +void GXPokeAlphaUpdate(GXBool update_enable); +void GXPokeBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor, GXLogicOp op); +void GXPokeColorUpdate(GXBool update_enable); +void GXPokeDstAlpha(GXBool enable, u8 alpha); +void GXPokeDither(GXBool dither); +void GXPokeZMode(GXBool compare_enable, GXCompare func, GXBool update_enable); +void GXPeekARGB(u16 x, u16 y, u32* color); +void GXPokeARGB(u16 x, u16 y, u32 color); +void GXPeekZ(u16 x, u16 y, u32* z); +void GXPokeZ(u16 x, u16 y, u32 z); +u32 GXCompressZ16(u32 z24, GXZFmt16 zfmt); +u32 GXDecompressZ16(u32 z16, GXZFmt16 zfmt); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/gx/GXCull.h b/include/dolphin/gx/GXCull.h new file mode 100644 index 0000000000..cac4381812 --- /dev/null +++ b/include/dolphin/gx/GXCull.h @@ -0,0 +1,18 @@ +#ifndef _DOLPHIN_GX_GXCULL_H_ +#define _DOLPHIN_GX_GXCULL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void GXSetScissor(u32 left, u32 top, u32 wd, u32 ht); +void GXSetCullMode(GXCullMode mode); +void GXSetCoPlanar(GXBool enable); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/gx/GXDispList.h b/include/dolphin/gx/GXDispList.h new file mode 100644 index 0000000000..357fb8f7e0 --- /dev/null +++ b/include/dolphin/gx/GXDispList.h @@ -0,0 +1,18 @@ +#ifndef _DOLPHIN_GX_GXDISPLIST_H_ +#define _DOLPHIN_GX_GXDISPLIST_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void GXBeginDisplayList(void* list, u32 size); +u32 GXEndDisplayList(void); +void GXCallDisplayList(void* list, u32 nbytes); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/gx/GXDisplayList.h b/include/dolphin/gx/GXDisplayList.h deleted file mode 100644 index fc8a4d5358..0000000000 --- a/include/dolphin/gx/GXDisplayList.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef GXDISPLAYLIST_H -#define GXDISPLAYLIST_H - -#include "dolphin/types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void GXBeginDisplayList(void* list, u32 capacity); -void GXEndDisplayList(void); -void GXCallDisplayList(void* list, u32 nbytes); - -#ifdef __cplusplus -}; -#endif - -#endif /* GXDISPLAYLIST_H */ diff --git a/include/dolphin/gx/GXDraw.h b/include/dolphin/gx/GXDraw.h index c3e113760d..c8e779345a 100644 --- a/include/dolphin/gx/GXDraw.h +++ b/include/dolphin/gx/GXDraw.h @@ -1,16 +1,24 @@ -#ifndef GXDRAW_H -#define GXDRAW_H +#ifndef _DOLPHIN_GX_GXDRAW_H_ +#define _DOLPHIN_GX_GXDRAW_H_ -#include "dolphin/gx/GXEnum.h" +#include #ifdef __cplusplus extern "C" { #endif void GXDrawCylinder(u8 numEdges); +void GXDrawTorus(f32 rc, u8 numc, u8 numt); +void GXDrawSphere(u8 numMajor, u8 numMinor); +void GXDrawCube(void); +void GXDrawDodeca(void); +void GXDrawOctahedron(void); +void GXDrawIcosahedron(void); +void GXDrawSphere1(u8 depth); +u32 GXGenNormalTable(u8 depth, f32* table); #ifdef __cplusplus -}; +} #endif -#endif /* GXDRAW_H */ +#endif diff --git a/include/dolphin/gx/GXEnum.h b/include/dolphin/gx/GXEnum.h index 27a141a481..cd84f22399 100644 --- a/include/dolphin/gx/GXEnum.h +++ b/include/dolphin/gx/GXEnum.h @@ -1,1894 +1,805 @@ -#ifndef GXENUM_H -#define GXENUM_H +#ifndef _DOLPHIN_GX_GXENUM_H_ +#define _DOLPHIN_GX_GXENUM_H_ -#include "dolphin/types.h" - -typedef enum _GXPrimitive { - /* 0x80 */ GX_QUADS = 0x80, - /* 0x90 */ GX_TRIANGLES = 0x90, - /* 0x98 */ GX_TRIANGLESTRIP = 0x98, - /* 0xA0 */ GX_TRIANGLEFAN = 0xA0, - /* 0xA8 */ GX_LINES = 0xA8, - /* 0xB0 */ GX_LINESTRIP = 0xB0, - /* 0xB8 */ GX_POINTS = 0xB8, -} GXPrimitive; - -typedef enum _GXCullMode { - /* 0x0 */ GX_CULL_NONE, - /* 0x1 */ GX_CULL_FRONT, - /* 0x2 */ GX_CULL_BACK, - /* 0x3 */ GX_CULL_ALL -} GXCullMode; +#include typedef u8 GXBool; -#define GX_TRUE ((GXBool)1) #define GX_FALSE ((GXBool)0) +#define GX_TRUE ((GXBool)1) + #define GX_ENABLE ((GXBool)1) #define GX_DISABLE ((GXBool)0) -typedef enum _GXTexMapID { - /* 0x000 */ GX_TEXMAP0, - /* 0x001 */ GX_TEXMAP1, - /* 0x002 */ GX_TEXMAP2, - /* 0x003 */ GX_TEXMAP3, - /* 0x004 */ GX_TEXMAP4, - /* 0x005 */ GX_TEXMAP5, - /* 0x006 */ GX_TEXMAP6, - /* 0x007 */ GX_TEXMAP7, - /* 0x008 */ GX_MAX_TEXMAP, - /* 0x0FF */ GX_TEXMAP_NULL = 255, - /* 0x100 */ GX_TEXMAP_DISABLE, -} GXTexMapID; - -typedef enum _GXTevStageID { - /* 0x00 */ GX_TEVSTAGE0, - /* 0x01 */ GX_TEVSTAGE1, - /* 0x02 */ GX_TEVSTAGE2, - /* 0x03 */ GX_TEVSTAGE3, - /* 0x04 */ GX_TEVSTAGE4, - /* 0x05 */ GX_TEVSTAGE5, - /* 0x06 */ GX_TEVSTAGE6, - /* 0x07 */ GX_TEVSTAGE7, - /* 0x08 */ GX_TEVSTAGE8, - /* 0x09 */ GX_TEVSTAGE9, - /* 0x0A */ GX_TEVSTAGE10, - /* 0x0B */ GX_TEVSTAGE11, - /* 0x0C */ GX_TEVSTAGE12, - /* 0x0D */ GX_TEVSTAGE13, - /* 0x0E */ GX_TEVSTAGE14, - /* 0x0F */ GX_TEVSTAGE15, - /* 0x10 */ GX_MAX_TEVSTAGE, -} GXTevStageID; - -typedef enum _GXTexCoordID { - /* 0x00 */ GX_TEXCOORD0, - /* 0x01 */ GX_TEXCOORD1, - /* 0x02 */ GX_TEXCOORD2, - /* 0x03 */ GX_TEXCOORD3, - /* 0x04 */ GX_TEXCOORD4, - /* 0x05 */ GX_TEXCOORD5, - /* 0x06 */ GX_TEXCOORD6, - /* 0x07 */ GX_TEXCOORD7, - /* 0x08 */ GX_MAXCOORD, - /* 0xFF */ GX_TEXCOORD_NULL = 255, -} GXTexCoordID; - -typedef enum _GXChannelID { - /* 0x00 */ GX_COLOR0, - /* 0x01 */ GX_COLOR1, - /* 0x02 */ GX_ALPHA0, - /* 0x03 */ GX_ALPHA1, - /* 0x04 */ GX_COLOR0A0, - /* 0x05 */ GX_COLOR1A1, - /* 0x06 */ GX_COLOR_ZERO, - /* 0x07 */ GX_ALPHA_BUMP, - /* 0x08 */ GX_ALPHA_BUMPN, - /* 0xFF */ GX_COLOR_NULL = 255, -} GXChannelID; - -typedef enum _GXColorSrc { - /* 0x0 */ GX_SRC_REG, - /* 0x1 */ GX_SRC_VTX, -} GXColorSrc; - -typedef enum _GXLightID { - /* 0x000 */ GX_LIGHT_NULL = 0, - /* 0x001 */ GX_LIGHT0 = 1 << 0, - /* 0x002 */ GX_LIGHT1 = 1 << 1, - /* 0x004 */ GX_LIGHT2 = 1 << 2, - /* 0x008 */ GX_LIGHT3 = 1 << 3, - /* 0x010 */ GX_LIGHT4 = 1 << 4, - /* 0x020 */ GX_LIGHT5 = 1 << 5, - /* 0x040 */ GX_LIGHT6 = 1 << 6, - /* 0x080 */ GX_LIGHT7 = 1 << 7, - /* 0x100 */ GX_MAX_LIGHT = 1 << 8, -} GXLightID; - -typedef enum _GXDiffuseFn { - /* 0x0 */ GX_DF_NONE, - /* 0x1 */ GX_DF_SIGN, - /* 0x2 */ GX_DF_CLAMP, -} GXDiffuseFn; - -typedef enum _GXAttnFn { - /* 0x0 */ GX_AF_SPEC, - /* 0x1 */ GX_AF_SPOT, - /* 0x2 */ GX_AF_NONE, -} GXAttnFn; - -typedef enum _GXDistAttnFn { - /* 0x0 */ GX_DA_OFF, - /* 0x1 */ GX_DA_GENTLE, - /* 0x2 */ GX_DA_MEDIUM, - /* 0x3 */ GX_DA_STEEP -} GXDistAttnFn; - -typedef enum _GXSpotFn { - /* 0x0 */ GX_SP_OFF, - /* 0x1 */ GX_SP_FLAT, - /* 0x2 */ GX_SP_COS, - /* 0x3 */ GX_SP_COS2, - /* 0x4 */ GX_SP_SHARP, - /* 0x5 */ GX_SP_RING1, - /* 0x6 */ GX_SP_RING2 -} GXSpotFn; - -typedef enum _GXTevMode { - /* 0x0 */ GX_MODULATE, - /* 0x1 */ GX_DECAL, - /* 0x2 */ GX_BLEND, - /* 0x3 */ GX_REPLACE, - /* 0x4 */ GX_PASSCLR, -} GXTevMode; - -typedef enum _GXBlendMode { - /* 0x0 */ GX_BM_NONE, - /* 0x1 */ GX_BM_BLEND, - /* 0x2 */ GX_BM_LOGIC, - /* 0x3 */ GX_BM_SUBTRACT, - /* 0x4 */ GX_MAX_BLENDMODE, -} GXBlendMode; - -typedef enum _GXBlendFactor { - /* 0x0 */ GX_BL_ZERO, - /* 0x1 */ GX_BL_ONE, - /* 0x2 */ GX_BL_SRC_COLOR, - /* 0x2 */ GX_BL_DST_COLOR = 2, - /* 0x3 */ GX_BL_INV_SRC_COLOR, - /* 0x3 */ GX_BL_INV_DST_COLOR = 3, - /* 0x4 */ GX_BL_SRC_ALPHA, - /* 0x5 */ GX_BL_INV_SRC_ALPHA, - /* 0x6 */ GX_BL_DST_ALPHA, - /* 0x7 */ GX_BL_INV_DST_ALPHA, -} GXBlendFactor; - -typedef enum _GXLogicOp { - /* 0x0 */ GX_LO_CLEAR, - /* 0x1 */ GX_LO_AND, - /* 0x2 */ GX_LO_REV_AND, - /* 0x3 */ GX_LO_COPY, - /* 0x4 */ GX_LO_INV_AND, - /* 0x5 */ GX_LO_NOOP, - /* 0x6 */ GX_LO_XOR, - /* 0x7 */ GX_LO_OR, - /* 0x8 */ GX_LO_NOR, - /* 0x9 */ GX_LO_EQUIV, - /* 0xA */ GX_LO_INV, - /* 0xB */ GX_LO_REV_OR, - /* 0xC */ GX_LO_INV_COPY, - /* 0xD */ GX_LO_INV_OR, - /* 0xE */ GX_LO_NAND, - /* 0xF */ GX_LO_SET, -} GXLogicOp; - -typedef enum _GXVtxFmt { - /* 0x0 */ GX_VTXFMT0, - /* 0x1 */ GX_VTXFMT1, - /* 0x2 */ GX_VTXFMT2, - /* 0x3 */ GX_VTXFMT3, - /* 0x4 */ GX_VTXFMT4, - /* 0x5 */ GX_VTXFMT5, - /* 0x6 */ GX_VTXFMT6, - /* 0x7 */ GX_VTXFMT7, - /* 0x8 */ GX_MAX_VTXFMT, -} GXVtxFmt; - -typedef enum _GXAttr { - /* 0x00 */ GX_VA_PNMTXIDX, - /* 0x01 */ GX_VA_TEX0MTXIDX, - /* 0x02 */ GX_VA_TEX1MTXIDX, - /* 0x03 */ GX_VA_TEX2MTXIDX, - /* 0x04 */ GX_VA_TEX3MTXIDX, - /* 0x05 */ GX_VA_TEX4MTXIDX, - /* 0x06 */ GX_VA_TEX5MTXIDX, - /* 0x07 */ GX_VA_TEX6MTXIDX, - /* 0x08 */ GX_VA_TEX7MTXIDX, - /* 0x09 */ GX_VA_POS, - /* 0x0A */ GX_VA_NRM, - /* 0x0B */ GX_VA_CLR0, - /* 0x0C */ GX_VA_CLR1, - /* 0x0D */ GX_VA_TEX0, - /* 0x0E */ GX_VA_TEX1, - /* 0x0F */ GX_VA_TEX2, - /* 0x10 */ GX_VA_TEX3, - /* 0x11 */ GX_VA_TEX4, - /* 0x12 */ GX_VA_TEX5, - /* 0x13 */ GX_VA_TEX6, - /* 0x14 */ GX_VA_TEX7, - /* 0x15 */ GX_POS_MTX_ARRAY, - /* 0x16 */ GX_NRM_MTX_ARRAY, - /* 0x17 */ GX_TEX_MTX_ARRAY, - /* 0x18 */ GX_LIGHT_ARRAY, - /* 0x19 */ GX_VA_NBT, - /* 0x1A */ GX_VA_MAX_ATTR, - /* 0xFF */ GX_VA_NULL = 255, -} GXAttr; - -typedef enum _GXCompCnt { - GX_POS_XY = 0, // Position X, Y (two components). - GX_POS_XYZ = 1, // Position X, Y, Z (three components). - - GX_NRM_XYZ = 0, // Normal X, Y, Z (three components). - GX_NRM_NBT = 1, // Normal, binormal, tangent (three components). - GX_NRM_NBT3 = 2, // Normal, binormal, tangent (three components). Use when NBT - // normal is indexed independently. - - GX_CLR_RGB = 0, // RGB (three components). - GX_CLR_RGBA = 1, // RGBA (four components). - - GX_TEX_S = 0, // Texture coordinate S (one component). - GX_TEX_ST = 1, // Texture coordinates S, T (two components). - - GX_COMPCNT_NULL = 0, // Null count. -} GXCompCnt; - -typedef enum _GXCompType { - GX_U8 = 0, // Unsigned 8-bit. - GX_S8 = 1, // Signed 8-bit. - GX_U16 = 2, // Unsigned 16-bit. - GX_S16 = 3, // Signed 16-bit. - GX_F32 = 4, // Floating-point 32-bit. - - GX_RGB565 = 0, // RGB565 16-bit. - GX_RGB8 = 1, // RGB888 24-bit. - GX_RGBX8 = 2, // RGB888x 32-bit. - GX_RGBA4 = 3, // RGBA4444 16-bit. - GX_RGBA6 = 4, // RGBA6666 24-bit. - GX_RGBA8 = 5, // RGBA8888 32-bit. - - GX_COMP_NULL = 0, // Null type. -} GXCompType; - -typedef enum _GXAttrType { - /* 0x0 */ GX_NONE, - /* 0x1 */ GX_DIRECT, - /* 0x2 */ GX_INDEX8, - /* 0x3 */ GX_INDEX16, -} GXAttrType; - -typedef enum _GXTevOp { - /* 0x0 */ GX_TEV_ADD, - /* 0x1 */ GX_TEV_SUB, - /* 0x8 */ GX_TEV_COMP_R8_GT = 8, - /* 0x9 */ GX_TEV_COMP_R8_EQ, - /* 0xA */ GX_TEV_COMP_GR16_GT, - /* 0xB */ GX_TEV_COMP_GR16_EQ, - /* 0xC */ GX_TEV_COMP_BGR24_GT, - /* 0xD */ GX_TEV_COMP_BGR24_EQ, - /* 0xE */ GX_TEV_COMP_A8_GT, - /* 0xE */ GX_TEV_COMP_RGB8_GT = 14, - /* 0xF */ GX_TEV_COMP_RGB8_EQ, - /* 0xF */ GX_TEV_COMP_A8_EQ = 15, -} GXTevOp; - -typedef enum _GXTevBias { - /* 0x0 */ GX_TB_ZERO, - /* 0x1 */ GX_TB_ADDHALF, - /* 0x2 */ GX_TB_SUBHALF, - /* 0x3 */ GX_MAX_TEVBIAS, -} GXTevBias; - -typedef enum _GXTevColorArg { - /* 0x0 */ GX_CC_CPREV, - /* 0x1 */ GX_CC_APREV, - /* 0x2 */ GX_CC_C0, - /* 0x3 */ GX_CC_A0, - /* 0x4 */ GX_CC_C1, - /* 0x5 */ GX_CC_A1, - /* 0x6 */ GX_CC_C2, - /* 0x7 */ GX_CC_A2, - /* 0x8 */ GX_CC_TEXC, - /* 0x9 */ GX_CC_TEXA, - /* 0xA */ GX_CC_RASC, - /* 0xB */ GX_CC_RASA, - /* 0xC */ GX_CC_ONE, - /* 0xD */ GX_CC_HALF, - /* 0xE */ GX_CC_KONST, - /* 0xF */ GX_CC_ZERO, -} GXTevColorArg; - -typedef enum _GXTevColor { - /* 0x0 */ GX_CH_RED, - /* 0x1 */ GX_CH_GREEN, - /* 0x2 */ GX_CH_BLUE, - /* 0x3 */ GX_CH_ALPHA, -} GXTevColor; - -typedef enum _GXTevScale { - /* 0x0 */ GX_CS_SCALE_1, - /* 0x1 */ GX_CS_SCALE_2, - /* 0x2 */ GX_CS_SCALE_4, - /* 0x3 */ GX_CS_DIVIDE_2, - /* 0x4 */ GX_MAX_TEVSCALE -} GXTevScale; - -typedef enum _GXTevRegID { - /* 0x0 */ GX_TEVPREV, - /* 0x1 */ GX_TEVREG0, - /* 0x2 */ GX_TEVREG1, - /* 0x3 */ GX_TEVREG2, - /* 0x4 */ GX_MAX_TEVREG -} GXTevRegID; - -typedef enum _GXTevAlphaArg { - /* 0x0 */ GX_CA_APREV, - /* 0x1 */ GX_CA_A0, - /* 0x2 */ GX_CA_A1, - /* 0x3 */ GX_CA_A2, - /* 0x4 */ GX_CA_TEXA, - /* 0x5 */ GX_CA_RASA, - /* 0x6 */ GX_CA_KONST, - /* 0x7 */ GX_CA_ZERO, -} GXTevAlphaArg; - -/** - * RGB, RGBA, Intensity, Intensity/Alpha, Compressed, and Z texture format - * types. See GXCITexFmt for information on color index formats. The CTF format - * is used only by the GXSetTexCopyDst function to specify how data is copied - * out of the EFB into a texture in main memory. In order to actually use that - * texture, you must specify a non-copy format of matching size. For example, if - * copying using GX_CTF_RG8, you would apply the resulting texture using - * GX_TF_IA8. - */ -typedef enum _GXTexFmt { - // Intensities (I) and RGB/RGBA. - GX_TF_I4 = 0x0, // 4-bit I - GX_TF_I8 = 0x1, // 8-bit I - GX_TF_IA4 = 0x2, // 8-bit I + alpha (4+4). - GX_TF_IA8 = 0x3, // 16-bit I + alpha (8+8). - GX_TF_RGB565 = 0x4, // 16-bit RGB. - GX_TF_RGB5A3 = 0x5, // MSB=1, RGB555 (opaque). MSB=0, RGBA4443 (transparent). - GX_TF_RGBA8 = 0x6, // 32-bit RGB. - GX_TF_CI14 = 0x9, - GX_TF_CMPR = 0xE, // Compressed 4-bit texel. - - // Z-texture format. - GX_TF_Z8 = 0x11, // Unsigned 8-bit Z. For texture copies, specify the upper 8 bits of Z. - GX_TF_Z16 = 0x13, // Unsigned 16-bit Z. For texture copies, specify the upper 16 bits of Z. - GX_TF_Z24X8 = 0x16, // Unsigned 24-bit (32-bit texture) Z. For texture copies, copy the 24-bit - // Z and 0xff. - - // Copy-texture format. - GX_CTF_R4 = 0x20, // 4-bit red. For copying 4 bits from red. - GX_CTF_RA4 = 0x22, // 4-bit red + 4-bit alpha. For copying 4 bits from red, 4 bits from alpha. - GX_CTF_RA8 = 0x23, // 8-bit red + 8-bit alpha. For copying 8 bits from red, 8 bits from alpha. - GX_CTF_YUVA8 = 0x26, // 8-bit YUV + alpha. For copying 8 bits from YUV, 8 bits from alpha. - GX_CTF_A8 = 0x26, // 8-bit alpha. For copying 8 bits from alpha. - GX_CTF_R8 = 0x27, // 8-bit red. For copying 8 bits from red. - GX_CTF_G8 = 0x28, // 8-bit green. For copying 8 bits from green. - GX_CTF_B8 = 0x29, // 8-bit blue. For copying 8 bits from blue. - GX_CTF_RG8 = 0x2A, // 8-bit red +8-bit green. For copying 8 bits from red, 8 bits from green. - GX_CTF_GB8 = 0x2B, // 8-bit green +8-bit blue. For copying 8 bits from green, 8 bits from blue. - - // Copy-Z-texture format. - GX_CTF_Z4 = 0x30, // 4-bit Z. For copying the 4 upper bits from Z. - GX_CTF_Z8M = 0x39, // 8-bit Z (median byte). For copying the middle 8 bits of Z. - GX_CTF_Z8L = 0x3A, // 8-bit Z (lower byte). For copying the lower 8 bits of Z. - GX_CTF_Z16L = 0x3C, // 16-bit Z (lower portion). For copying the lower 16 bits of Z. -} GXTexFmt; - -typedef enum _GXGamma { - /* 0x0 */ GX_GM_1_0, - /* 0x0 */ GX_GM_1_7, - /* 0x0 */ GX_GM_2_2, -} GXGamma; - -typedef enum _GXTlutFmt { - /* 0x0 */ GX_TL_IA8, - /* 0x1 */ GX_TL_RGB565, - /* 0x2 */ GX_TL_RGB5A3, -} GXTlutFmt; - -typedef enum _GXTlut { - /* 0x00 */ GX_TLUT0, - /* 0x01 */ GX_TLUT1, - /* 0x02 */ GX_TLUT2, - /* 0x03 */ GX_TLUT3, - /* 0x04 */ GX_TLUT4, - /* 0x05 */ GX_TLUT5, - /* 0x06 */ GX_TLUT6, - /* 0x07 */ GX_TLUT7, - /* 0x08 */ GX_TLUT8, - /* 0x09 */ GX_TLUT9, - /* 0x0A */ GX_TLUT10, - /* 0x0B */ GX_TLUT11, - /* 0x0C */ GX_TLUT12, - /* 0x0D */ GX_TLUT13, - /* 0x0E */ GX_TLUT14, - /* 0x0F */ GX_TLUT15, - /* 0x10 */ GX_MAX_TLUT, - /* 0x10 */ GX_BIGTLUT0 = 0x10, - /* 0x11 */ GX_BIGTLUT1, - /* 0x12 */ GX_BIGTLUT2, - /* 0x13 */ GX_BIGTLUT3, - /* 0x13 */ GX_MAX_BIGTLUT = 4, - - GX_MAX_TLUT_ALL = GX_MAX_TLUT + GX_MAX_BIGTLUT, -} GXTlut; - -typedef enum _GXTexWrapMode { - /* 0x0 */ GX_CLAMP, - /* 0x1 */ GX_REPEAT, - /* 0x2 */ GX_MIRROR, - /* 0x3 */ GX_MAX_TEXWRAP_MODE, -} GXTexWrapMode; - -typedef enum _GXTexFilter { - /* 0x0 */ GX_NEAR, - /* 0x1 */ GX_LINEAR, - /* 0x2 */ GX_NEAR_MIP_NEAR, - /* 0x3 */ GX_LIN_MIP_NEAR, - /* 0x4 */ GX_NEAR_MIP_LIN, - /* 0x5 */ GX_LIN_MIP_LIN, -} GXTexFilter; - -typedef enum _GXAnisotropy { - /* 0x0 */ GX_ANISO_1, - /* 0x1 */ GX_ANISO_2, - /* 0x2 */ GX_ANISO_4, - /* 0x3 */ GX_MAX_ANISOTROPY, -} GXAnisotropy; - -typedef enum _GXCITexFmt { - /* 0x8 */ GX_TF_C4 = 8, - /* 0x8 */ GX_TF_C8, - /* 0xA */ GX_TF_C14X2 -} GXCITexFmt; - -typedef enum _GXTexMtxType { - /* 0x0 */ GX_MTX3x4, - /* 0x1 */ GX_MTX2x4 -} GXTexMtxType; +typedef enum _GXProjectionType { + GX_PERSPECTIVE, + GX_ORTHOGRAPHIC, +} GXProjectionType; typedef enum _GXCompare { - /* 0x0 */ GX_NEVER, - /* 0x1 */ GX_LESS, - /* 0x2 */ GX_EQUAL, - /* 0x3 */ GX_LEQUAL, - /* 0x4 */ GX_GREATER, - /* 0x5 */ GX_NEQUAL, - /* 0x6 */ GX_GEQUAL, - /* 0x7 */ GX_ALWAYS, + GX_NEVER, + GX_LESS, + GX_EQUAL, + GX_LEQUAL, + GX_GREATER, + GX_NEQUAL, + GX_GEQUAL, + GX_ALWAYS, } GXCompare; typedef enum _GXAlphaOp { - /* 0x0 */ GX_AOP_AND, - /* 0x1 */ GX_AOP_OR, - /* 0x2 */ GX_AOP_XOR, - /* 0x3 */ GX_AOP_XNOR, - /* 0x4 */ GX_MAX_ALPHAOP + GX_AOP_AND, + GX_AOP_OR, + GX_AOP_XOR, + GX_AOP_XNOR, + GX_MAX_ALPHAOP, } GXAlphaOp; -typedef enum _GXFogType { - /* 0x0 */ GX_FOG_NONE, - /* 0x2 */ GX_FOG_LIN = 2, - /* 0x2 */ GX_FOG_PERSP_LIN = 2, - /* 0x4 */ GX_FOG_EXP = 4, - /* 0x4 */ GX_FOG_PERSP_EXP = 4, - /* 0x5 */ GX_FOG_EXP2, - /* 0x5 */ GX_FOG_PERSP_EXP2 = 5, - /* 0x6 */ GX_FOG_REVEXP, - /* 0x6 */ GX_FOG_PERSP_REVEXP = 6, - /* 0x7 */ GX_FOG_REVEXP2, - /* 0x7 */ GX_FOG_PERSP_REVEXP2 = 7, - /* 0xA */ GX_FOG_ORTHO_LIN = 10, - /* 0xC */ GX_FOG_ORTHO_EXP = 12, - /* 0xD */ GX_FOG_ORTHO_EXP2, - /* 0xE */ GX_FOG_ORTHO_REVEXP, - /* 0xF */ GX_FOG_ORTHO_REVEXP2, -} GXFogType; +typedef enum _GXZFmt16 { + GX_ZC_LINEAR, + GX_ZC_NEAR, + GX_ZC_MID, + GX_ZC_FAR, +} GXZFmt16; -typedef enum _GXProjectionType { - /* 0x0 */ GX_PERSPECTIVE, - /* 0x1 */ GX_ORTHOGRAPHIC -} GXProjectionType; +typedef enum _GXGamma { + GX_GM_1_0, + GX_GM_1_7, + GX_GM_2_2, +} GXGamma; -typedef enum _GXTevKAlphaSel { - /* 0x00 */ GX_TEV_KASEL_1, - /* 0x01 */ GX_TEV_KASEL_7_8, - /* 0x02 */ GX_TEV_KASEL_3_4, - /* 0x03 */ GX_TEV_KASEL_5_8, - /* 0x04 */ GX_TEV_KASEL_1_2, - /* 0x05 */ GX_TEV_KASEL_3_8, - /* 0x06 */ GX_TEV_KASEL_1_4, - /* 0x07 */ GX_TEV_KASEL_1_8, +typedef enum _GXPixelFmt { + GX_PF_RGB8_Z24, + GX_PF_RGBA6_Z24, + GX_PF_RGB565_Z16, + GX_PF_Z24, + GX_PF_Y8, + GX_PF_U8, + GX_PF_V8, + GX_PF_YUV420, +} GXPixelFmt; - /* 0x10 */ GX_TEV_KASEL_K0_R = 0x10, - /* 0x11 */ GX_TEV_KASEL_K1_R, - /* 0x12 */ GX_TEV_KASEL_K2_R, - /* 0x13 */ GX_TEV_KASEL_K3_R, - /* 0x14 */ GX_TEV_KASEL_K0_G, - /* 0x15 */ GX_TEV_KASEL_K1_G, - /* 0x16 */ GX_TEV_KASEL_K2_G, - /* 0x17 */ GX_TEV_KASEL_K3_G, - /* 0x18 */ GX_TEV_KASEL_K0_B, - /* 0x19 */ GX_TEV_KASEL_K1_B, - /* 0x1A */ GX_TEV_KASEL_K2_B, - /* 0x1B */ GX_TEV_KASEL_K3_B, - /* 0x1C */ GX_TEV_KASEL_K0_A, - /* 0x1D */ GX_TEV_KASEL_K1_A, - /* 0x1E */ GX_TEV_KASEL_K2_A, - /* 0x1F */ GX_TEV_KASEL_K3_A, -} GXTevKAlphaSel; +typedef enum _GXPrimitive { + GX_QUADS = 0x80, + GX_TRIANGLES = 0x90, + GX_TRIANGLESTRIP = 0x98, + GX_TRIANGLEFAN = 0xA0, + GX_LINES = 0xA8, + GX_LINESTRIP = 0xB0, + GX_POINTS = 0xB8, +} GXPrimitive; -typedef enum _GXTevKColorSel { - /* 0x00 */ GX_TEV_KCSEL_1, - /* 0x01 */ GX_TEV_KCSEL_7_8, - /* 0x02 */ GX_TEV_KCSEL_3_4, - /* 0x03 */ GX_TEV_KCSEL_5_8, - /* 0x04 */ GX_TEV_KCSEL_1_2, - /* 0x05 */ GX_TEV_KCSEL_3_8, - /* 0x06 */ GX_TEV_KCSEL_1_4, - /* 0x07 */ GX_TEV_KCSEL_1_8, - /* 0x0C */ GX_TEV_KCSEL_K0 = 0xC, - /* 0x0D */ GX_TEV_KCSEL_K1, - /* 0x0E */ GX_TEV_KCSEL_K2, - /* 0x0F */ GX_TEV_KCSEL_K3, - /* 0x10 */ GX_TEV_KCSEL_K0_R, - /* 0x11 */ GX_TEV_KCSEL_K1_R, - /* 0x12 */ GX_TEV_KCSEL_K2_R, - /* 0x13 */ GX_TEV_KCSEL_K3_R, - /* 0x14 */ GX_TEV_KCSEL_K0_G, - /* 0x15 */ GX_TEV_KCSEL_K1_G, - /* 0x16 */ GX_TEV_KCSEL_K2_G, - /* 0x17 */ GX_TEV_KCSEL_K3_G, - /* 0x18 */ GX_TEV_KCSEL_K0_B, - /* 0x19 */ GX_TEV_KCSEL_K1_B, - /* 0x1A */ GX_TEV_KCSEL_K2_B, - /* 0x1B */ GX_TEV_KCSEL_K3_B, - /* 0x1C */ GX_TEV_KCSEL_K0_A, - /* 0x1D */ GX_TEV_KCSEL_K1_A, - /* 0x1E */ GX_TEV_KCSEL_K2_A, - /* 0x1F */ GX_TEV_KCSEL_K3_A, -} GXTevKColorSel; +typedef enum _GXVtxFmt { + GX_VTXFMT0, + GX_VTXFMT1, + GX_VTXFMT2, + GX_VTXFMT3, + GX_VTXFMT4, + GX_VTXFMT5, + GX_VTXFMT6, + GX_VTXFMT7, + GX_MAX_VTXFMT, +} GXVtxFmt; -typedef enum _GXTevSwapSel { - /* 0x0 */ GX_TEV_SWAP0, - /* 0x1 */ GX_TEV_SWAP1, - /* 0x2 */ GX_TEV_SWAP2, - /* 0x3 */ GX_TEV_SWAP3, - /* 0x4 */ GX_MAX_TEVSWAP, -} GXTevSwapSel; +typedef enum _GXAttr { + GX_VA_PNMTXIDX, + GX_VA_TEX0MTXIDX, + GX_VA_TEX1MTXIDX, + GX_VA_TEX2MTXIDX, + GX_VA_TEX3MTXIDX, + GX_VA_TEX4MTXIDX, + GX_VA_TEX5MTXIDX, + GX_VA_TEX6MTXIDX, + GX_VA_TEX7MTXIDX, + GX_VA_POS, + GX_VA_NRM, + GX_VA_CLR0, + GX_VA_CLR1, + GX_VA_TEX0, + GX_VA_TEX1, + GX_VA_TEX2, + GX_VA_TEX3, + GX_VA_TEX4, + GX_VA_TEX5, + GX_VA_TEX6, + GX_VA_TEX7, + GX_POS_MTX_ARRAY, + GX_NRM_MTX_ARRAY, + GX_TEX_MTX_ARRAY, + GX_LIGHT_ARRAY, + GX_VA_NBT, + GX_VA_MAX_ATTR, + GX_VA_NULL = 0xFF, +} GXAttr; + +typedef enum _GXAttrType { + GX_NONE, + GX_DIRECT, + GX_INDEX8, + GX_INDEX16, +} GXAttrType; + +#define _GX_TF_CTF 0x20 +#define _GX_TF_ZTF 0x10 + +typedef enum _GXTexFmt { + GX_TF_I4 = 0x0, + GX_TF_I8 = 0x1, + GX_TF_IA4 = 0x2, + GX_TF_IA8 = 0x3, + GX_TF_RGB565 = 0x4, + GX_TF_RGB5A3 = 0x5, + GX_TF_RGBA8 = 0x6, + GX_TF_CMPR = 0xE, + + GX_CTF_R4 = 0x0 | _GX_TF_CTF, + GX_CTF_RA4 = 0x2 | _GX_TF_CTF, + GX_CTF_RA8 = 0x3 | _GX_TF_CTF, + GX_CTF_YUVA8 = 0x6 | _GX_TF_CTF, + GX_CTF_A8 = 0x7 | _GX_TF_CTF, + GX_CTF_R8 = 0x8 | _GX_TF_CTF, + GX_CTF_G8 = 0x9 | _GX_TF_CTF, + GX_CTF_B8 = 0xA | _GX_TF_CTF, + GX_CTF_RG8 = 0xB | _GX_TF_CTF, + GX_CTF_GB8 = 0xC | _GX_TF_CTF, + + GX_TF_Z8 = 0x1 | _GX_TF_ZTF, + GX_TF_Z16 = 0x3 | _GX_TF_ZTF, + GX_TF_Z24X8 = 0x6 | _GX_TF_ZTF, + + GX_CTF_Z4 = 0x0 | _GX_TF_ZTF | _GX_TF_CTF, + GX_CTF_Z8M = 0x9 | _GX_TF_ZTF | _GX_TF_CTF, + GX_CTF_Z8L = 0xA | _GX_TF_ZTF | _GX_TF_CTF, + GX_CTF_Z16L = 0xC | _GX_TF_ZTF | _GX_TF_CTF, + + GX_TF_A8 = GX_CTF_A8, +} GXTexFmt; + +typedef enum _GXCITexFmt { + GX_TF_C4 = 0x8, + GX_TF_C8 = 0x9, + GX_TF_C14X2 = 0xA, +} GXCITexFmt; + +typedef enum _GXTexWrapMode { + GX_CLAMP, + GX_REPEAT, + GX_MIRROR, + GX_MAX_TEXWRAPMODE, +} GXTexWrapMode; + +typedef enum _GXTexFilter { + GX_NEAR, + GX_LINEAR, + GX_NEAR_MIP_NEAR, + GX_LIN_MIP_NEAR, + GX_NEAR_MIP_LIN, + GX_LIN_MIP_LIN, +} GXTexFilter; + +typedef enum _GXAnisotropy { + GX_ANISO_1, + GX_ANISO_2, + GX_ANISO_4, + GX_MAX_ANISOTROPY, +} GXAnisotropy; + +typedef enum _GXTexMapID { + GX_TEXMAP0, + GX_TEXMAP1, + GX_TEXMAP2, + GX_TEXMAP3, + GX_TEXMAP4, + GX_TEXMAP5, + GX_TEXMAP6, + GX_TEXMAP7, + GX_MAX_TEXMAP, + GX_TEXMAP_NULL = 0xFF, + GX_TEX_DISABLE = 0x100, +} GXTexMapID; + +typedef enum _GXTexCoordID { + GX_TEXCOORD0, + GX_TEXCOORD1, + GX_TEXCOORD2, + GX_TEXCOORD3, + GX_TEXCOORD4, + GX_TEXCOORD5, + GX_TEXCOORD6, + GX_TEXCOORD7, + GX_MAX_TEXCOORD, + GX_TEXCOORD_NULL = 0xFF, +} GXTexCoordID; + +typedef enum _GXTevStageID { + GX_TEVSTAGE0, + GX_TEVSTAGE1, + GX_TEVSTAGE2, + GX_TEVSTAGE3, + GX_TEVSTAGE4, + GX_TEVSTAGE5, + GX_TEVSTAGE6, + GX_TEVSTAGE7, + GX_TEVSTAGE8, + GX_TEVSTAGE9, + GX_TEVSTAGE10, + GX_TEVSTAGE11, + GX_TEVSTAGE12, + GX_TEVSTAGE13, + GX_TEVSTAGE14, + GX_TEVSTAGE15, + GX_MAX_TEVSTAGE, +} GXTevStageID; + +typedef enum _GXTevMode { + GX_MODULATE, + GX_DECAL, + GX_BLEND, + GX_REPLACE, + GX_PASSCLR, +} GXTevMode; + +typedef enum _GXTexMtxType { + GX_MTX3x4, + GX_MTX2x4, +} GXTexMtxType; typedef enum _GXTexGenType { - /* 0x0 */ GX_TG_MTX3x4, - /* 0x1 */ GX_TG_MTX2x4, - /* 0x2 */ GX_TG_BUMP0, - /* 0x3 */ GX_TG_BUMP1, - /* 0x4 */ GX_TG_BUMP2, - /* 0x5 */ GX_TG_BUMP3, - /* 0x6 */ GX_TG_BUMP4, - /* 0x7 */ GX_TG_BUMP5, - /* 0x8 */ GX_TG_BUMP6, - /* 0x9 */ GX_TG_BUMP7, - /* 0xA */ GX_TG_SRTG, + GX_TG_MTX3x4, + GX_TG_MTX2x4, + GX_TG_BUMP0, + GX_TG_BUMP1, + GX_TG_BUMP2, + GX_TG_BUMP3, + GX_TG_BUMP4, + GX_TG_BUMP5, + GX_TG_BUMP6, + GX_TG_BUMP7, + GX_TG_SRTG, } GXTexGenType; -typedef enum _GXTexGenSrc { - /* 0x00 */ GX_TG_POS, - /* 0x01 */ GX_TG_NRM, - /* 0x02 */ GX_TG_BINRM, - /* 0x03 */ GX_TG_TANGENT, - /* 0x04 */ GX_TG_TEX0, - /* 0x05 */ GX_TG_TEX1, - /* 0x06 */ GX_TG_TEX2, - /* 0x07 */ GX_TG_TEX3, - /* 0x08 */ GX_TG_TEX4, - /* 0x09 */ GX_TG_TEX5, - /* 0x0A */ GX_TG_TEX6, - /* 0x0B */ GX_TG_TEX7, - /* 0x0C */ GX_TG_TEXCOORD0, - /* 0x0D */ GX_TG_TEXCOORD1, - /* 0x0E */ GX_TG_TEXCOORD2, - /* 0x0F */ GX_TG_TEXCOORD3, - /* 0x10 */ GX_TG_TEXCOORD4, - /* 0x11 */ GX_TG_TEXCOORD5, - /* 0x12 */ GX_TG_TEXCOORD6, - /* 0x13 */ GX_TG_COLOR0, - /* 0x14 */ GX_TG_COLOR1, -} GXTexGenSrc; - -typedef enum _GXZTexOp { - /* 0x0 */ GX_ZT_DISABLE, - /* 0x1 */ GX_ZT_ADD, - /* 0x2 */ GX_ZT_REPLACE, - /* 0x3 */ GX_MAX_ZTEXOP, -} GXZTexOp; - -typedef enum _GXIndTexStageID { - /* 0x0 */ GX_INDTEXSTAGE0, - /* 0x1 */ GX_INDTEXSTAGE1, - /* 0x2 */ GX_INDTEXSTAGE2, - /* 0x3 */ GX_INDTEXSTAGE3, - /* 0x4 */ GX_MAX_INDTEXSTAGE, -} GXIndTexStageID; - -typedef enum _GXIndTexScale { - /* 0x0 */ GX_ITS_1, - /* 0x1 */ GX_ITS_2, - /* 0x2 */ GX_ITS_4, - /* 0x3 */ GX_ITS_8, - /* 0x4 */ GX_ITS_16, - /* 0x5 */ GX_ITS_32, - /* 0x6 */ GX_ITS_64, - /* 0x7 */ GX_ITS_128, - /* 0x8 */ GX_ITS_256, - /* 0x9 */ GX_MAX_ITSCALE, -} GXIndTexScale; - -typedef enum _GXIndTexMtxID { - /* 0x0 */ GX_ITM_OFF, - /* 0x1 */ GX_ITM_0, - /* 0x2 */ GX_ITM_1, - /* 0x3 */ GX_ITM_2, - /* 0x4 */ GX_ITM_3, - /* 0x5 */ GX_ITM_S0 = 5, - /* 0x6 */ GX_ITM_S1, - /* 0x7 */ GX_ITM_S2, - /* 0x8 */ GX_ITM_S3, - /* 0x9 */ GX_ITM_T0 = 9, - /* 0xA */ GX_ITM_T1, - /* 0xB */ GX_ITM_T2, -} GXIndTexMtxID; - -typedef enum _GXIndTexFormat { - /* 0x0 */ GX_ITF_8, - /* 0x1 */ GX_ITF_5, - /* 0x2 */ GX_ITF_4, - /* 0x3 */ GX_ITF_3, -} GXIndTexFormat; - -typedef enum _GXIndTexBiasSel { - /* 0x0 */ GX_ITB_NONE, - /* 0x1 */ GX_ITB_S, - /* 0x2 */ GX_ITB_T, - /* 0x3 */ GX_ITB_ST, - /* 0x4 */ GX_ITB_U, - /* 0x5 */ GX_ITB_SU, - /* 0x6 */ GX_ITB_TU, - /* 0x7 */ GX_ITB_STU, -} GXIndTexBiasSel; - -typedef enum _GXIndTexAlphaSel { - /* 0x0 */ GX_ITBA_OFF, - /* 0x1 */ GX_ITBA_S, - /* 0x2 */ GX_ITBA_T, - /* 0x3 */ GX_ITBA_U, -} GXIndTexAlphaSel; - -typedef enum _GXIndTexWrap { - /* 0x0 */ GX_ITW_OFF, - /* 0x1 */ GX_ITW_256, - /* 0x2 */ GX_ITW_128, - /* 0x3 */ GX_ITW_64, - /* 0x4 */ GX_ITW_32, - /* 0x5 */ GX_ITW_16, - /* 0x6 */ GX_ITW_0, -} GXIndTexWrap; - -typedef enum _GXTexOffset { - /* 0x0 */ GX_TO_ZERO, - /* 0x1 */ GX_TO_SIXTEENTH, - /* 0x2 */ GX_TO_EIGHTH, - /* 0x3 */ GX_TO_FOURTH, - /* 0x4 */ GX_TO_HALF, - /* 0x5 */ GX_TO_ONE, - /* 0x6 */ GX_MAX_TEXOFFSET, -} GXTexOffset; - -typedef enum _GXTevKColorID { - /* 0x0 */ GX_KCOLOR0, - /* 0x1 */ GX_KCOLOR1, - /* 0x2 */ GX_KCOLOR2, - /* 0x3 */ GX_KCOLOR3, -} GXTevKColorID; - -typedef enum _GXTexCacheSize { - /* 0x0 */ GX_TEXCACHE_32K, - /* 0x1 */ GX_TEXCACHE_128K, - /* 0x2 */ GX_TEXCACHE_512K, - /* 0x3 */ GX_TEXCACHE_NONE, -} GXTexCacheSize; - typedef enum _GXPosNrmMtx { - GX_PNMTX0 = 3 * 0, - GX_PNMTX1 = 3 * 1, - GX_PNMTX2 = 3 * 2, - GX_PNMTX3 = 3 * 3, - GX_PNMTX4 = 3 * 4, - GX_PNMTX5 = 3 * 5, - GX_PNMTX6 = 3 * 6, - GX_PNMTX7 = 3 * 7, - GX_PNMTX8 = 3 * 8, - GX_PNMTX9 = 3 * 9, + GX_PNMTX0 = 0, + GX_PNMTX1 = 3, + GX_PNMTX2 = 6, + GX_PNMTX3 = 9, + GX_PNMTX4 = 12, + GX_PNMTX5 = 15, + GX_PNMTX6 = 18, + GX_PNMTX7 = 21, + GX_PNMTX8 = 24, + GX_PNMTX9 = 27, } GXPosNrmMtx; typedef enum _GXTexMtx { - GX_TEXMTX0 = 30 + 0 * 3, - GX_TEXMTX1 = 30 + 1 * 3, - GX_TEXMTX2 = 30 + 2 * 3, - GX_TEXMTX3 = 30 + 3 * 3, - GX_TEXMTX4 = 30 + 4 * 3, - GX_TEXMTX5 = 30 + 5 * 3, - GX_TEXMTX6 = 30 + 6 * 3, - GX_TEXMTX7 = 30 + 7 * 3, - GX_TEXMTX8 = 30 + 8 * 3, - GX_TEXMTX9 = 30 + 9 * 3, + GX_TEXMTX0 = 30, + GX_TEXMTX1 = 33, + GX_TEXMTX2 = 36, + GX_TEXMTX3 = 39, + GX_TEXMTX4 = 42, + GX_TEXMTX5 = 45, + GX_TEXMTX6 = 48, + GX_TEXMTX7 = 51, + GX_TEXMTX8 = 54, + GX_TEXMTX9 = 57, GX_IDENTITY = 60, } GXTexMtx; +typedef enum _GXChannelID { + GX_COLOR0, + GX_COLOR1, + GX_ALPHA0, + GX_ALPHA1, + GX_COLOR0A0, + GX_COLOR1A1, + GX_COLOR_ZERO, + GX_ALPHA_BUMP, + GX_ALPHA_BUMPN, + GX_COLOR_NULL = 0xFF, +} GXChannelID; + +typedef enum _GXTexGenSrc { + GX_TG_POS, + GX_TG_NRM, + GX_TG_BINRM, + GX_TG_TANGENT, + GX_TG_TEX0, + GX_TG_TEX1, + GX_TG_TEX2, + GX_TG_TEX3, + GX_TG_TEX4, + GX_TG_TEX5, + GX_TG_TEX6, + GX_TG_TEX7, + GX_TG_TEXCOORD0, + GX_TG_TEXCOORD1, + GX_TG_TEXCOORD2, + GX_TG_TEXCOORD3, + GX_TG_TEXCOORD4, + GX_TG_TEXCOORD5, + GX_TG_TEXCOORD6, + GX_TG_COLOR0, + GX_TG_COLOR1, +} GXTexGenSrc; + +typedef enum _GXBlendMode { + GX_BM_NONE, + GX_BM_BLEND, + GX_BM_LOGIC, + GX_BM_SUBTRACT, + GX_MAX_BLENDMODE, +} GXBlendMode; + +typedef enum _GXBlendFactor { + GX_BL_ZERO, + GX_BL_ONE, + GX_BL_SRCCLR, + GX_BL_INVSRCCLR, + GX_BL_SRCALPHA, + GX_BL_INVSRCALPHA, + GX_BL_DSTALPHA, + GX_BL_INVDSTALPHA, + GX_BL_DSTCLR = GX_BL_SRCCLR, + GX_BL_INVDSTCLR = GX_BL_INVSRCCLR, +} GXBlendFactor; + +typedef enum _GXLogicOp { + GX_LO_CLEAR, + GX_LO_AND, + GX_LO_REVAND, + GX_LO_COPY, + GX_LO_INVAND, + GX_LO_NOOP, + GX_LO_XOR, + GX_LO_OR, + GX_LO_NOR, + GX_LO_EQUIV, + GX_LO_INV, + GX_LO_REVOR, + GX_LO_INVCOPY, + GX_LO_INVOR, + GX_LO_NAND, + GX_LO_SET, +} GXLogicOp; + +typedef enum _GXCompCnt { + GX_POS_XY = 0, + GX_POS_XYZ = 1, + GX_NRM_XYZ = 0, + GX_NRM_NBT = 1, + GX_NRM_NBT3 = 2, + GX_CLR_RGB = 0, + GX_CLR_RGBA = 1, + GX_TEX_S = 0, + GX_TEX_ST = 1, +} GXCompCnt; + +typedef enum _GXCompType { + GX_U8 = 0, + GX_S8 = 1, + GX_U16 = 2, + GX_S16 = 3, + GX_F32 = 4, + GX_RGB565 = 0, + GX_RGB8 = 1, + GX_RGBX8 = 2, + GX_RGBA4 = 3, + GX_RGBA6 = 4, + GX_RGBA8 = 5, +} GXCompType; + typedef enum _GXPTTexMtx { - GX_PTTEXMTX0 = 64 + 0 * 3, - GX_PTTEXMTX1 = 64 + 1 * 3, - GX_PTTEXMTX2 = 64 + 2 * 3, - GX_PTTEXMTX3 = 64 + 3 * 3, - GX_PTTEXMTX4 = 64 + 4 * 3, - GX_PTTEXMTX5 = 64 + 5 * 3, - GX_PTTEXMTX6 = 64 + 6 * 3, - GX_PTTEXMTX7 = 64 + 7 * 3, - GX_PTTEXMTX8 = 64 + 8 * 3, - GX_PTTEXMTX9 = 64 + 9 * 3, - GX_PTTEXMTX10 = 64 + 10 * 3, - GX_PTTEXMTX11 = 64 + 11 * 3, - GX_PTTEXMTX12 = 64 + 12 * 3, - GX_PTTEXMTX13 = 64 + 13 * 3, - GX_PTTEXMTX14 = 64 + 14 * 3, - GX_PTTEXMTX15 = 64 + 15 * 3, - GX_PTTEXMTX16 = 64 + 16 * 3, - GX_PTTEXMTX17 = 64 + 17 * 3, - GX_PTTEXMTX18 = 64 + 18 * 3, - GX_PTTEXMTX19 = 64 + 19 * 3, + GX_PTTEXMTX0 = 64, + GX_PTTEXMTX1 = 67, + GX_PTTEXMTX2 = 70, + GX_PTTEXMTX3 = 73, + GX_PTTEXMTX4 = 76, + GX_PTTEXMTX5 = 79, + GX_PTTEXMTX6 = 82, + GX_PTTEXMTX7 = 85, + GX_PTTEXMTX8 = 88, + GX_PTTEXMTX9 = 91, + GX_PTTEXMTX10 = 94, + GX_PTTEXMTX11 = 97, + GX_PTTEXMTX12 = 100, + GX_PTTEXMTX13 = 103, + GX_PTTEXMTX14 = 106, + GX_PTTEXMTX15 = 109, + GX_PTTEXMTX16 = 112, + GX_PTTEXMTX17 = 115, + GX_PTTEXMTX18 = 118, + GX_PTTEXMTX19 = 121, GX_PTIDENTITY = 125, } GXPTTexMtx; -typedef enum _GXFBClamp { - /* 0x0 */ GX_CLAMP_NONE, - /* 0x1 */ GX_CLAMP_TOP, - /* 0x2 */ GX_CLAMP_BOTTOM, - GX_CLAMP_BOTH = GX_CLAMP_TOP | GX_CLAMP_BOTTOM, -} GXFBClamp; +typedef enum _GXTevRegID { + GX_TEVPREV, + GX_TEVREG0, + GX_TEVREG1, + GX_TEVREG2, + GX_MAX_TEVREG, +} GXTevRegID; + +typedef enum _GXDiffuseFn { + GX_DF_NONE, + GX_DF_SIGN, + GX_DF_CLAMP, +} GXDiffuseFn; + +typedef enum _GXColorSrc { + GX_SRC_REG, + GX_SRC_VTX, +} GXColorSrc; + +typedef enum _GXAttnFn { + GX_AF_SPEC, + GX_AF_SPOT, + GX_AF_NONE, +} GXAttnFn; + +typedef enum _GXLightID { + GX_LIGHT0 = 0x001, + GX_LIGHT1 = 0x002, + GX_LIGHT2 = 0x004, + GX_LIGHT3 = 0x008, + GX_LIGHT4 = 0x010, + GX_LIGHT5 = 0x020, + GX_LIGHT6 = 0x040, + GX_LIGHT7 = 0x080, + GX_MAX_LIGHT = 0x100, + GX_LIGHT_NULL = 0, +} GXLightID; + +typedef enum _GXTexOffset { + GX_TO_ZERO, + GX_TO_SIXTEENTH, + GX_TO_EIGHTH, + GX_TO_FOURTH, + GX_TO_HALF, + GX_TO_ONE, + GX_MAX_TEXOFFSET, +} GXTexOffset; + +typedef enum _GXSpotFn { + GX_SP_OFF, + GX_SP_FLAT, + GX_SP_COS, + GX_SP_COS2, + GX_SP_SHARP, + GX_SP_RING1, + GX_SP_RING2, +} GXSpotFn; + +typedef enum _GXDistAttnFn { + GX_DA_OFF, + GX_DA_GENTLE, + GX_DA_MEDIUM, + GX_DA_STEEP, +} GXDistAttnFn; + +typedef enum _GXCullMode { + GX_CULL_NONE, + GX_CULL_FRONT, + GX_CULL_BACK, + GX_CULL_ALL +} GXCullMode; + +typedef enum _GXTevSwapSel { + GX_TEV_SWAP0 = 0, + GX_TEV_SWAP1, + GX_TEV_SWAP2, + GX_TEV_SWAP3, + GX_MAX_TEVSWAP +} GXTevSwapSel; + +typedef enum _GXTevColorChan { + GX_CH_RED = 0, + GX_CH_GREEN, + GX_CH_BLUE, + GX_CH_ALPHA +} GXTevColorChan; + +typedef enum _GXFogType { + GX_FOG_NONE = 0, + GX_FOG_PERSP_LIN = 2, + GX_FOG_PERSP_EXP = 4, + GX_FOG_PERSP_EXP2 = 5, + GX_FOG_PERSP_REVEXP = 6, + GX_FOG_PERSP_REVEXP2 = 7, + GX_FOG_ORTHO_LIN = 10, + GX_FOG_ORTHO_EXP = 12, + GX_FOG_ORTHO_EXP2 = 13, + GX_FOG_ORTHO_REVEXP = 14, + GX_FOG_ORTHO_REVEXP2 = 15, + GX_FOG_LIN = 2, + GX_FOG_EXP = 4, + GX_FOG_EXP2 = 5, + GX_FOG_REVEXP = 6, + GX_FOG_REVEXP2 = 7, +} GXFogType; + +typedef enum _GXTevColorArg { + GX_CC_CPREV = 0, + GX_CC_APREV = 1, + GX_CC_C0 = 2, + GX_CC_A0 = 3, + GX_CC_C1 = 4, + GX_CC_A1 = 5, + GX_CC_C2 = 6, + GX_CC_A2 = 7, + GX_CC_TEXC = 8, + GX_CC_TEXA = 9, + GX_CC_RASC = 10, + GX_CC_RASA = 11, + GX_CC_ONE = 12, + GX_CC_HALF = 13, + GX_CC_KONST = 14, + GX_CC_ZERO = 15, + GX_CC_TEXRRR = 16, + GX_CC_TEXGGG = 17, + GX_CC_TEXBBB = 18, + GX_CC_QUARTER = 14, +} GXTevColorArg; + +typedef enum _GXTevAlphaArg { + GX_CA_APREV = 0, + GX_CA_A0 = 1, + GX_CA_A1 = 2, + GX_CA_A2 = 3, + GX_CA_TEXA = 4, + GX_CA_RASA = 5, + GX_CA_KONST = 6, + GX_CA_ZERO = 7, + GX_CA_ONE = 6, +} GXTevAlphaArg; + +typedef enum _GXTevOp { + GX_TEV_ADD = 0, + GX_TEV_SUB = 1, + GX_TEV_COMP_R8_GT = 8, + GX_TEV_COMP_R8_EQ = 9, + GX_TEV_COMP_GR16_GT = 10, + GX_TEV_COMP_GR16_EQ = 11, + GX_TEV_COMP_BGR24_GT = 12, + GX_TEV_COMP_BGR24_EQ = 13, + GX_TEV_COMP_RGB8_GT = 14, + GX_TEV_COMP_RGB8_EQ = 15, + GX_TEV_COMP_A8_GT = GX_TEV_COMP_RGB8_GT, + GX_TEV_COMP_A8_EQ = GX_TEV_COMP_RGB8_EQ +} GXTevOp; + +typedef enum _GXTevBias { + GX_TB_ZERO, + GX_TB_ADDHALF, + GX_TB_SUBHALF, + GX_MAX_TEVBIAS +} GXTevBias; + +typedef enum _GXTevScale { + GX_CS_SCALE_1, + GX_CS_SCALE_2, + GX_CS_SCALE_4, + GX_CS_DIVIDE_2, + GX_MAX_TEVSCALE +} GXTevScale; + +typedef enum _GXTevKColorSel { + GX_TEV_KCSEL_1 = 0x00, + GX_TEV_KCSEL_7_8 = 0x01, + GX_TEV_KCSEL_3_4 = 0x02, + GX_TEV_KCSEL_5_8 = 0x03, + GX_TEV_KCSEL_1_2 = 0x04, + GX_TEV_KCSEL_3_8 = 0x05, + GX_TEV_KCSEL_1_4 = 0x06, + GX_TEV_KCSEL_1_8 = 0x07, + GX_TEV_KCSEL_K0 = 0x0C, + GX_TEV_KCSEL_K1 = 0x0D, + GX_TEV_KCSEL_K2 = 0x0E, + GX_TEV_KCSEL_K3 = 0x0F, + GX_TEV_KCSEL_K0_R = 0x10, + GX_TEV_KCSEL_K1_R = 0x11, + GX_TEV_KCSEL_K2_R = 0x12, + GX_TEV_KCSEL_K3_R = 0x13, + GX_TEV_KCSEL_K0_G = 0x14, + GX_TEV_KCSEL_K1_G = 0x15, + GX_TEV_KCSEL_K2_G = 0x16, + GX_TEV_KCSEL_K3_G = 0x17, + GX_TEV_KCSEL_K0_B = 0x18, + GX_TEV_KCSEL_K1_B = 0x19, + GX_TEV_KCSEL_K2_B = 0x1A, + GX_TEV_KCSEL_K3_B = 0x1B, + GX_TEV_KCSEL_K0_A = 0x1C, + GX_TEV_KCSEL_K1_A = 0x1D, + GX_TEV_KCSEL_K2_A = 0x1E, + GX_TEV_KCSEL_K3_A = 0x1F +} GXTevKColorSel; + +typedef enum _GXTevKAlphaSel { + GX_TEV_KASEL_1 = 0x00, + GX_TEV_KASEL_7_8 = 0x01, + GX_TEV_KASEL_3_4 = 0x02, + GX_TEV_KASEL_5_8 = 0x03, + GX_TEV_KASEL_1_2 = 0x04, + GX_TEV_KASEL_3_8 = 0x05, + GX_TEV_KASEL_1_4 = 0x06, + GX_TEV_KASEL_1_8 = 0x07, + GX_TEV_KASEL_K0_R = 0x10, + GX_TEV_KASEL_K1_R = 0x11, + GX_TEV_KASEL_K2_R = 0x12, + GX_TEV_KASEL_K3_R = 0x13, + GX_TEV_KASEL_K0_G = 0x14, + GX_TEV_KASEL_K1_G = 0x15, + GX_TEV_KASEL_K2_G = 0x16, + GX_TEV_KASEL_K3_G = 0x17, + GX_TEV_KASEL_K0_B = 0x18, + GX_TEV_KASEL_K1_B = 0x19, + GX_TEV_KASEL_K2_B = 0x1A, + GX_TEV_KASEL_K3_B = 0x1B, + GX_TEV_KASEL_K0_A = 0x1C, + GX_TEV_KASEL_K1_A = 0x1D, + GX_TEV_KASEL_K2_A = 0x1E, + GX_TEV_KASEL_K3_A = 0x1F +} GXTevKAlphaSel; + +typedef enum _GXTevKColorID { + GX_KCOLOR0 = 0, + GX_KCOLOR1, + GX_KCOLOR2, + GX_KCOLOR3, + GX_MAX_KCOLOR +} GXTevKColorID; + +typedef enum _GXZTexOp { + GX_ZT_DISABLE, + GX_ZT_ADD, + GX_ZT_REPLACE, + GX_MAX_ZTEXOP, +} GXZTexOp; + +typedef enum _GXIndTexFormat { + GX_ITF_8, + GX_ITF_5, + GX_ITF_4, + GX_ITF_3, + GX_MAX_ITFORMAT, +} GXIndTexFormat; + +typedef enum _GXIndTexBiasSel { + GX_ITB_NONE, + GX_ITB_S, + GX_ITB_T, + GX_ITB_ST, + GX_ITB_U, + GX_ITB_SU, + GX_ITB_TU, + GX_ITB_STU, + GX_MAX_ITBIAS, +} GXIndTexBiasSel; + +typedef enum _GXIndTexAlphaSel { + GX_ITBA_OFF, + GX_ITBA_S, + GX_ITBA_T, + GX_ITBA_U, + GX_MAX_ITBALPHA, +} GXIndTexAlphaSel; + +typedef enum _GXIndTexMtxID { + GX_ITM_OFF, + GX_ITM_0, + GX_ITM_1, + GX_ITM_2, + GX_ITM_S0 = 5, + GX_ITM_S1, + GX_ITM_S2, + GX_ITM_T0 = 9, + GX_ITM_T1, + GX_ITM_T2, +} GXIndTexMtxID; + +typedef enum _GXIndTexWrap { + GX_ITW_OFF, + GX_ITW_256, + GX_ITW_128, + GX_ITW_64, + GX_ITW_32, + GX_ITW_16, + GX_ITW_0, + GX_MAX_ITWRAP, +} GXIndTexWrap; + +typedef enum _GXIndTexStageID { + GX_INDTEXSTAGE0, + GX_INDTEXSTAGE1, + GX_INDTEXSTAGE2, + GX_INDTEXSTAGE3, + GX_MAX_INDTEXSTAGE, +} GXIndTexStageID; + +typedef enum _GXIndTexScale { + GX_ITS_1, + GX_ITS_2, + GX_ITS_4, + GX_ITS_8, + GX_ITS_16, + GX_ITS_32, + GX_ITS_64, + GX_ITS_128, + GX_ITS_256, + GX_MAX_ITSCALE, +} GXIndTexScale; -typedef enum _GXPixelFmt { - /* 0x0 */ GX_PF_RGB8_Z24, - /* 0x1 */ GX_PF_RGBA6_Z24, - /* 0x2 */ GX_PF_RGB565_Z16, - /* 0x3 */ GX_PF_Z24, - /* 0x4 */ GX_PF_Y8, - /* 0x5 */ GX_PF_U8, - /* 0x6 */ GX_PF_V8, - /* 0x7 */ GX_PF_YUV420, - /* 0x8 */ GX_PF_MAX, -} GXPixelFmt; - -typedef enum _GXZFmt16 { - /* 0x0 */ GX_ZC_LINEAR, - /* 0x1 */ GX_ZC_NEAR, - /* 0x2 */ GX_ZC_MID, - /* 0x3 */ GX_ZC_FAR, -} GXZFmt16; - -typedef enum _GXCommand { - GX_CMD_LOAD_INDX_A = 0x20, - GX_CMD_LOAD_INDX_B = 0x28, - GX_CMD_LOAD_INDX_C = 0x30, - GX_CMD_LOAD_INDX_D = 0x38, - - GX_CMD_LOAD_CP_REG = 0x08, - GX_CMD_LOAD_XF_REG = 0x10, - GX_CMD_LOAD_BP_REG = 0x61, -} GXCommand; - -typedef enum _GXClipMode { - /* 0x0 */ GX_CLIP_ENABLE, - /* 0x1 */ GX_CLIP_DISABLE, -} GXClipMode; - -typedef enum _GXCopyMode { - /* 0x0 */ GX_COPY_PROGRESSIVE, - /* 0x1 */ GX_COPY_INTLC_EVEN, - /* 0x2 */ GX_COPY_INTLC_ODD, -} GXCopyMode; - -typedef enum _GXAlphaReadMode { - /* 0x0 */ GX_READ_00, - /* 0x1 */ GX_READ_FF, - /* 0x2 */ GX_READ_NONE, -} GXAlphaReadMode; - -typedef enum _GXTlutSize { - /* 0x001 */ GX_TLUT_16 = 1, - /* 0x002 */ GX_TLUT_32 = 2, - /* 0x004 */ GX_TLUT_64 = 4, - /* 0x008 */ GX_TLUT_128 = 8, - /* 0x010 */ GX_TLUT_256 = 16, - /* 0x020 */ GX_TLUT_512 = 32, - /* 0x040 */ GX_TLUT_1K = 64, - /* 0x080 */ GX_TLUT_2K = 128, - /* 0x100 */ GX_TLUT_4K = 256, - /* 0x200 */ GX_TLUT_8K = 512, - /* 0x400 */ GX_TLUT_16K = 1024, -} GXTlutSize; - -typedef enum _GXDirtyFlag { - GX_DIRTY_SU_TEX = (1 << 0), - GX_DIRTY_BP_MASK = (1 << 1), - GX_DIRTY_GEN_MODE = (1 << 2), - GX_DIRTY_VCD = (1 << 3), - GX_DIRTY_VAT = (1 << 4), - GX_DIRTY_AMB_COLOR0 = (1 << 8), - GX_DIRTY_AMB_COLOR1 = (1 << 9), - GX_DIRTY_MAT_COLOR0 = (1 << 10), - GX_DIRTY_MAT_COLOR1 = (1 << 11), - GX_DIRTY_MTX_IDX = (1 << 26), - GX_DIRTY_PROJECTION = (1 << 27), - GX_DIRTY_VIEWPORT = (1 << 28), - - GX_DIRTY_VLIM = GX_DIRTY_VCD | GX_DIRTY_VAT, - - GX_AMB_MAT_MASK = - GX_DIRTY_AMB_COLOR0 | GX_DIRTY_AMB_COLOR1 | GX_DIRTY_MAT_COLOR0 | GX_DIRTY_MAT_COLOR1, - GX_LIGHT_CHAN_MASK = 0x100F000, - GX_TEX_GEN_MASK = 0x2FF0000, -} GXDirtyFlag; - -// CP locator for vertex descriptor (lo). -typedef enum _GXCPVCDLo { - // Position matrix idx [31] - GX_CP_VCD_LO_POSMTXIDX_ST = 31, - GX_CP_VCD_LO_POSMTXIDX_END = 31, - - // Tex 0 matrix idx [30] - GX_CP_VCD_LO_TEX0MTXIDX_ST = 30, - GX_CP_VCD_LO_TEX0MTXIDX_END = 30, - - // Tex 1 matrix idx [29] - GX_CP_VCD_LO_TEX1MTXIDX_ST = 29, - GX_CP_VCD_LO_TEX1MTXIDX_END = 29, - - // Tex 2 matrix idx [28] - GX_CP_VCD_LO_TEX2MTXIDX_ST = 28, - GX_CP_VCD_LO_TEX2MTXIDX_END = 28, - - // Tex 3 matrix idx [27] - GX_CP_VCD_LO_TEX3MTXIDX_ST = 27, - GX_CP_VCD_LO_TEX3MTXIDX_END = 27, - - // Tex 4 matrix idx [26] - GX_CP_VCD_LO_TEX4MTXIDX_ST = 26, - GX_CP_VCD_LO_TEX4MTXIDX_END = 26, - - // Tex 5 matrix idx [25] - GX_CP_VCD_LO_TEX5MTXIDX_ST = 25, - GX_CP_VCD_LO_TEX5MTXIDX_END = 25, - - // Tex 6 matrix idx [24] - GX_CP_VCD_LO_TEX6MTXIDX_ST = 24, - GX_CP_VCD_LO_TEX6MTXIDX_END = 24, - - // Tex 7 matrix idx [23] - GX_CP_VCD_LO_TEX7MTXIDX_ST = 23, - GX_CP_VCD_LO_TEX7MTXIDX_END = 23, - - // Position [21-22] - GX_CP_VCD_LO_POS_ST = 21, - GX_CP_VCD_LO_POS_END = 22, - - // Normal [19-20] - GX_CP_VCD_LO_NRM_ST = 19, - GX_CP_VCD_LO_NRM_END = 20, - - // Color diffused [17-18] - GX_CP_VCD_LO_CLRDIF_ST = 17, - GX_CP_VCD_LO_CLRDIF_END = 18, - - // Color specular [15-16] - GX_CP_VCD_LO_CLRSPEC_ST = 15, - GX_CP_VCD_LO_CLRSPEC_END = 16, -} GXCPVCDLo; - -// CP locators for vertex descriptor (hi). -typedef enum _GXCPVCDHi { - // Tex0 coordinates [30-31] - GX_CP_VCD_HI_TEX0COORD_ST = 30, - GX_CP_VCD_HI_TEX0COORD_END = 31, - - // Tex1 coordinates [28-29] - GX_CP_VCD_HI_TEX1COORD_ST = 28, - GX_CP_VCD_HI_TEX1COORD_END = 29, - - // Tex2 coordinates [26-27] - GX_CP_VCD_HI_TEX2COORD_ST = 26, - GX_CP_VCD_HI_TEX2COORD_END = 27, - - // Tex3 coordinates [24-25] - GX_CP_VCD_HI_TEX3COORD_ST = 24, - GX_CP_VCD_HI_TEX3COORD_END = 25, - - // Tex4 coordinates [22-23] - GX_CP_VCD_HI_TEX4COORD_ST = 22, - GX_CP_VCD_HI_TEX4COORD_END = 23, - - // Tex5 coordinates [20-21] - GX_CP_VCD_HI_TEX5COORD_ST = 20, - GX_CP_VCD_HI_TEX5COORD_END = 21, - - // Tex6 coordinates [18-19] - GX_CP_VCD_HI_TEX6COORD_ST = 18, - GX_CP_VCD_HI_TEX6COORD_END = 19, - - // Tex7 coordinates [16-17] - GX_CP_VCD_HI_TEX7COORD_ST = 16, - GX_CP_VCD_HI_TEX7COORD_END = 17, -} GXCPVCDHi; - -// Command processor registers. -typedef enum _GXCPRegs { - GX_CP_REG_MTXIDXA = 0x30, // Matrix index A - GX_CP_REG_MTXIDXB = 0x40, // Matrix index B - GX_CP_REG_VCD_LO = 0x50, // Vertex descriptor (lo) - GX_CP_REG_VCD_HI = 0x60, // Vertex descriptor (hi) - GX_CP_REG_VAT_GRP0 = 0x70, // Vertex attribute table (group 0) - GX_CP_REG_VAT_GRP1 = 0x80, // Vertex attribute table (group 1) - GX_CP_REG_VAT_GRP2 = 0x90, // Vertex attribute table (group 2) - GX_CP_REG_ARRAYBASE = 0xA0, // Vertex array start/base - GX_CP_REG_ARRAYSTRIDE = 0xB0, // Vertex array stride -} GXCPRegs; - -// Transform unit registers. -typedef enum _GXXFRegs { - GX_XF_REG_ERROR = 0x1000, - GX_XF_REG_DIAGNOSTICS = 0x1001, - GX_XF_REG_STATE0 = 0x1002, - GX_XF_REG_STATE1 = 0x1003, - GX_XF_REG_CLOCK = 0x1004, - GX_XF_REG_CLIPDISABLE = 0x1005, - GX_XF_REG_PERF0 = 0x1006, - GX_XF_REG_PERF1 = 0x1007, - GX_XF_REG_INVERTEXSPEC = 0x1008, - GX_XF_REG_NUMCOLORS = 0x1009, - GX_XF_REG_AMBIENT0 = 0x100A, - GX_XF_REG_AMBIENT1 = 0x100B, - GX_XF_REG_MATERIAL0 = 0x100C, - GX_XF_REG_MATERIAL1 = 0x100D, - GX_XF_REG_COLOR0CNTRL = 0x100E, - GX_XF_REG_COLOR1CNTRL = 0x100F, - GX_XF_REG_ALPHA0CNTRL = 0x1010, - GX_XF_REG_ALPHA1CNTRL = 0x1011, - GX_XF_REG_DUALTEXTRAN = 0x1012, - GX_XF_REG_MATRIXINDEX0 = 0x1018, - GX_XF_REG_MATRIXINDEX1 = 0x1019, - GX_XF_REG_SCALEX = 0x101A, - GX_XF_REG_SCALEY = 0x101B, - GX_XF_REG_SCALEZ = 0x101C, - GX_XF_REG_OFFSETX = 0x101D, - GX_XF_REG_OFFSETY = 0x101E, - GX_XF_REG_OFFSETZ = 0x101F, - GX_XF_REG_PROJECTIONA = 0x1020, - GX_XF_REG_PROJECTIONB = 0x1021, - GX_XF_REG_PROJECTIONC = 0x1022, - GX_XF_REG_PROJECTIOND = 0x1023, - GX_XF_REG_PROJECTIONE = 0x1024, - GX_XF_REG_PROJECTIONF = 0x1025, - GX_XF_REG_PROJECTORTHO = 0x1026, - GX_XF_REG_NUMTEX = 0x103F, - GX_XF_REG_TEX0 = 0x1040, - GX_XF_REG_TEX1 = 0x1041, - GX_XF_REG_TEX2 = 0x1042, - GX_XF_REG_TEX3 = 0x1043, - GX_XF_REG_TEX4 = 0x1044, - GX_XF_REG_TEX5 = 0x1045, - GX_XF_REG_TEX6 = 0x1046, - GX_XF_REG_TEX7 = 0x1047, - GX_XF_REG_DUALTEX0 = 0x1050, - GX_XF_REG_DUALTEX1 = 0x1051, - GX_XF_REG_DUALTEX2 = 0x1052, - GX_XF_REG_DUALTEX3 = 0x1053, - GX_XF_REG_DUALTEX4 = 0x1054, - GX_XF_REG_DUALTEX5 = 0x1055, - GX_XF_REG_DUALTEX6 = 0x1056, - GX_XF_REG_DUALTEX7 = 0x1057, -} GXXFRegs; - -// Commands for interacting with the GXFifo pipe. -typedef enum _GXFifoCmd { - GX_FIFO_CMD_NOOP = 0x00, // no operation - - GX_FIFO_CMD_LOAD_BP_REG = 0x61, // load blitting processor reg - GX_FIFO_CMD_LOAD_CP_REG = 0x08, // load command processor reg - GX_FIFO_CMD_LOAD_XF_REG = 0x10, // load transform unit reg - - GX_FIFO_CMD_LOAD_INDX_A = 0x20, // load index A - GX_FIFO_CMD_LOAD_INDX_B = 0x28, // load index B - GX_FIFO_CMD_LOAD_INDX_C = 0x30, // load index C - GX_FIFO_CMD_LOAD_INDX_D = 0x38, // load index D - - GX_FIFO_CMD_CALL_DL = 0x40, // call displaylist - GX_FIFO_CMD_INVAL_VTX = 0x48, // invalid vertex - -} GXFifoCmd; - -// CP locator for vertex attribute table (group 0). -typedef enum _GXCPVATGrp0 { - // Position count [31-31] - GX_CP_VAT_GRP0_POS_CNT_ST = 31, - GX_CP_VAT_GRP0_POS_CNT_END = 31, - - // Position type [28-30] - GX_CP_VAT_GRP0_POS_TYPE_ST = 28, - GX_CP_VAT_GRP0_POS_TYPE_END = 30, - - // Position shift [23-27] - GX_CP_VAT_GRP0_POS_SHIFT_ST = 23, - GX_CP_VAT_GRP0_POS_SHIFT_END = 27, - - // Normal count [22-22] - GX_CP_VAT_GRP0_NRM_CNT_ST = 22, - GX_CP_VAT_GRP0_NRM_CNT_END = 22, - - // Normal type [19-21] - GX_CP_VAT_GRP0_NRM_TYPE_ST = 19, - GX_CP_VAT_GRP0_NRM_TYPE_END = 21, - - // Color diffused count [18-18] - GX_CP_VAT_GRP0_CLRDIFF_CNT_ST = 18, - GX_CP_VAT_GRP0_CLRDIFF_CNT_END = 18, - - // Color diffused type [15-17] - GX_CP_VAT_GRP0_CLRDIFF_TYPE_ST = 15, - GX_CP_VAT_GRP0_CLRDIFF_TYPE_END = 17, - - // Color specular count [14-14] - GX_CP_VAT_GRP0_CLRSPEC_CNT_ST = 14, - GX_CP_VAT_GRP0_CLRSPEC_CNT_END = 14, - - // Color specular type [11-13] - GX_CP_VAT_GRP0_CLRSPEC_TYPE_ST = 11, - GX_CP_VAT_GRP0_CLRSPEC_TYPE_END = 13, - - // Tex0 coord count [10-10] - GX_CP_VAT_GRP0_TXC0_CNT_ST = 10, - GX_CP_VAT_GRP0_TXC0_CNT_END = 10, - - // Tex0 coord type [7-9] - GX_CP_VAT_GRP0_TXC0_TYPE_ST = 7, - GX_CP_VAT_GRP0_TXC0_TYPE_END = 9, - - // Tex0 coord shift [2-6] - GX_CP_VAT_GRP0_TXC0_SHIFT_ST = 2, - GX_CP_VAT_GRP0_TXC0_SHIFT_END = 6, - - // Byte dequantised [1-1] - GX_CP_VAT_GRP0_BYTEDEQ_ST = 1, - GX_CP_VAT_GRP0_BYTEDEQ_END = 1, - - // Normal index 3 [0-0] (Input will be treated as three staggered indices (one per triple biased - // by component size) into normal table)) - GX_CP_VAT_GRP0_NRMIDX3_ST = 0, - GX_CP_VAT_GRP0_NRMIDX3_END = 0, -} GXCPVATGrp0; - -// CP locators for vertex attribute table (group 1). -typedef enum _GXCPVATGrp1 { - // Tex1 coord count [31-31] - GX_CP_VAT_GRP1_TXC1_CNT_ST = 31, - GX_CP_VAT_GRP1_TXC1_CNT_END = 31, - - // Tex1 coord type [28-30] - GX_CP_VAT_GRP1_TXC1_TYPE_ST = 28, - GX_CP_VAT_GRP1_TXC1_TYPE_END = 30, - - // Tex1 coord shift [23-27] - GX_CP_VAT_GRP1_TXC1_SHIFT_ST = 23, - GX_CP_VAT_GRP1_TXC1_SHIFT_END = 27, - - // Tex2 coord count [22-22] - GX_CP_VAT_GRP1_TXC2_CNT_ST = 22, - GX_CP_VAT_GRP1_TXC2_CNT_END = 22, - - // Tex2 coord type [19-21] - GX_CP_VAT_GRP1_TXC2_TYPE_ST = 19, - GX_CP_VAT_GRP1_TXC2_TYPE_END = 21, - - // Tex2 coord shift [14-18] - GX_CP_VAT_GRP1_TXC2_SHIFT_ST = 14, - GX_CP_VAT_GRP1_TXC2_SHIFT_END = 18, - - // Tex3 coord count [13-13] - GX_CP_VAT_GRP1_TXC3_CNT_ST = 13, - GX_CP_VAT_GRP1_TXC3_CNT_END = 13, - - // Tex3 coord type [10-12] - GX_CP_VAT_GRP1_TXC3_TYPE_ST = 10, - GX_CP_VAT_GRP1_TXC3_TYPE_END = 12, - - // Tex3 coord shift [5-9] - GX_CP_VAT_GRP1_TXC3_SHIFT_ST = 5, - GX_CP_VAT_GRP1_TXC3_SHIFT_END = 9, - - // Tex4 coord count [4-4] - GX_CP_VAT_GRP1_TXC4_CNT_ST = 4, - GX_CP_VAT_GRP1_TXC4_CNT_END = 4, - - // Tex4 coord type [1-3] - GX_CP_VAT_GRP1_TXC4_TYPE_ST = 1, - GX_CP_VAT_GRP1_TXC4_TYPE_END = 3, - -} GXCPVATGrp1; - -// CP locators for vertex attribute table (group 2). -typedef enum _GXCPVATGrp2 { - // Tex4 coord shift [27-31] - GX_CP_VAT_GRP2_TXC4_SHIFT_ST = 27, - GX_CP_VAT_GRP2_TXC4_SHIFT_END = 31, - - // Tex5 coord count [26-26] - GX_CP_VAT_GRP2_TXC5_CNT_ST = 26, - GX_CP_VAT_GRP2_TXC5_CNT_END = 26, - - // Tex5 coord type [23-25] - GX_CP_VAT_GRP2_TXC5_TYPE_ST = 23, - GX_CP_VAT_GRP2_TXC5_TYPE_END = 25, - - // Tex5 coord shift [18-22] - GX_CP_VAT_GRP2_TXC5_SHIFT_ST = 18, - GX_CP_VAT_GRP2_TXC5_SHIFT_END = 22, - - // Tex6 coord count [17-17] - GX_CP_VAT_GRP2_TXC6_CNT_ST = 17, - GX_CP_VAT_GRP2_TXC6_CNT_END = 17, - - // Tex6 coord type [14-16] - GX_CP_VAT_GRP2_TXC6_TYPE_ST = 14, - GX_CP_VAT_GRP2_TXC6_TYPE_END = 16, - - // Tex6 coord shift [9-13] - GX_CP_VAT_GRP2_TXC6_SHIFT_ST = 9, - GX_CP_VAT_GRP2_TXC6_SHIFT_END = 13, - - // Tex7 coord count [8-8] - GX_CP_VAT_GRP2_TXC7_CNT_ST = 8, - GX_CP_VAT_GRP2_TXC7_CNT_END = 8, - - // Tex7 coord type [5-7] - GX_CP_VAT_GRP2_TXC7_TYPE_ST = 5, - GX_CP_VAT_GRP2_TXC7_TYPE_END = 7, - - // Tex7 coord shift [0-4] - GX_CP_VAT_GRP2_TXC7_SHIFT_ST = 0, - GX_CP_VAT_GRP2_TXC7_SHIFT_END = 4, -} GXCPVATGrp2; - -// BP GenMode locators. -typedef enum _GXBPGenMode { - // Active texture counts [28-31] - GX_BP_GENMODE_NUMTEX_ST = 28, - GX_BP_GENMODE_NUMTEX_END = 31, - - // Color/channel counts [25-27] - GX_BP_GENMODE_NUMCOLORS_ST = 25, - GX_BP_GENMODE_NUMCOLORS_END = 27, - - // Multisample mode [22-22] - GX_BP_GENMODE_MULTISAMPLE_ST = 22, - GX_BP_GENMODE_MULTISAMPLE_END = 22, - - // Cull mode [16-17] - GX_BP_GENMODE_CULLMODE_ST = 16, - GX_BP_GENMODE_CULLMODE_END = 17, - - // Indirect stage counts [13-15] - GX_BP_GENMODE_NUMINDSTAGES_ST = 13, - GX_BP_GENMODE_NUMINDSTAGES_END = 15, - - // Toggle co-planar/Z-freeze [12-12] - GX_BP_GENMODE_COPLANAR_ST = 12, - GX_BP_GENMODE_COPLANAR_END = 12, -} GXBPGenMode; - -// Texture register fields for XF (transform) unit. -typedef enum _GXXfTexReg { - GX_XF_TEX_PROJ_ST = 0, // (s,t) (2x4) - GX_XF_TEX_PROJ_STQ = 1, // (s,t,q) (3x4) - - GX_XF_TEX_FORM_AB11 = 0, // (A, B, 1.0f, 1.0f), used for regular tex src - GX_XF_TEX_FORM_ABC1 = 1, // (A, B, C, 1.0f), used for geometry/normal src -} GXXfTexReg; - -// XF locators for textures. -typedef enum _GXXFTex { - // Projection type [30-30] - GX_XF_TEX_PROJTYPE_ST = 30, - GX_XF_TEX_PROJTYPE_END = 30, - - // Input format [29-29] - GX_XF_TEX_INPUTFORM_ST = 29, - GX_XF_TEX_INPUTFORM_END = 29, - - // Texture gen type [25-27] - GX_XF_TEX_TEXGENTYPE_ST = 25, - GX_XF_TEX_TEXGENTYPE_END = 27, - - // Source row [20-24] - GX_XF_TEX_SRCROW_ST = 20, - GX_XF_TEX_SRCROW_END = 24, - - // Bump source texture [17-19] - GX_XF_TEX_BUMPSRCTEX_ST = 17, - GX_XF_TEX_BUMPSRCTEX_END = 19, - - // Bump source light [14-16] - GX_XF_TEX_BUMPSRCLIGHT_ST = 14, - GX_XF_TEX_BUMPSRCLIGHT_END = 16, -} GXXFTex; - -// XF locators for dual textures. -typedef enum _GXXFDualTex { - // Base row of the transform matrix [26-31] - GX_XF_DUALTEX_BASEROW_ST = 26, - GX_XF_DUALTEX_BASEROW_END = 31, - - // Normalise texcoord before sending transform [23-23] - GX_XF_DUALTEX_NORMALISE_ST = 23, - GX_XF_DUALTEX_NORMALISE_END = 23, -} GXXFDualTex; - -// General texture commands. -typedef enum _GXXfTexGen { - GX_XF_TG_REGULAR = 0, // Regular; transform incoming data. - GX_XF_TG_BUMP = 1, // Texgen bump mapping. - GX_XF_TG_CLR0 = 2, // Color texgen for color 0 (s,t) = (r, g:b) - GX_XF_TG_CLR1 = 3, // Color texgen for color 1 (s,t) = (r, g:b) -} GXXfTexGen; - -// XF locators for matrix index 0. -typedef enum _GXXFMtxIdx0 { - // Geometry [26-31] - GX_XF_MTXIDX0_GEOM_ST = 26, - GX_XF_MTXIDX0_GEOM_END = 31, - - // Tex 0 [20-25] - GX_XF_MTXIDX0_TEX0_ST = 20, - GX_XF_MTXIDX0_TEX0_END = 25, - - // Tex 1 [14-19] - GX_XF_MTXIDX0_TEX1_ST = 14, - GX_XF_MTXIDX0_TEX1_END = 19, - - // Tex 2 [8-13] - GX_XF_MTXIDX0_TEX2_ST = 8, - GX_XF_MTXIDX0_TEX2_END = 13, - - // Tex 3 [2-7] - GX_XF_MTXIDX0_TEX3_ST = 2, - GX_XF_MTXIDX0_TEX3_END = 7, -} GXXFMtxIdx0; - -// XF locators for matrix index 1. -typedef enum _GXXFMtxIdx1 { - // Tex 4 [26-31] - GX_XF_MTXIDX1_TEX4_ST = 26, - GX_XF_MTXIDX1_TEX4_END = 31, - - // Tex 5 [20-25] - GX_XF_MTXIDX1_TEX5_ST = 20, - GX_XF_MTXIDX1_TEX5_END = 25, - - // Tex 6 [14-19] - GX_XF_MTXIDX1_TEX6_ST = 14, - GX_XF_MTXIDX1_TEX6_END = 19, - - // Tex 7 [8-13] - GX_XF_MTXIDX1_TEX7_ST = 8, - GX_XF_MTXIDX1_TEX7_END = 13, -} GXXFMtxIdx1; - -// Blitting processor registers. -typedef enum _GXBPRegs { - // gen mode - GX_BP_REG_GENMODE = 0x0, // gen mode - - // display copy filters - GX_BP_REG_DISPCOPYFILTER0 = 0x1, // display copy filter 0 - GX_BP_REG_DISPCOPYFILTER1 = 0x2, // display copy filter 1 - GX_BP_REG_DISPCOPYFILTER2 = 0x3, // display copy filter 2 - GX_BP_REG_DISPCOPYFILTER3 = 0x4, // display copy filter 3 - - // indirect matrices - GX_BP_REG_INDMTX0A = 0x6, // indirect matrix 0A - GX_BP_REG_INDMTX0B = 0x7, // indirect matrix 0B - GX_BP_REG_INDMTX0C = 0x8, // indirect matrix 0C - GX_BP_REG_INDMTX1A = 0x9, // indirect matrix 1A - GX_BP_REG_INDMTX1B = 0xA, // indirect matrix 1B - GX_BP_REG_INDMTX1C = 0xB, // indirect matrix 1C - GX_BP_REG_INDMTX2A = 0xC, // indirect matrix 2A - GX_BP_REG_INDMTX2B = 0xD, // indirect matrix 2B - GX_BP_REG_INDMTX2C = 0xE, // indirect matrix 2C - GX_BP_REG_INDIMASK = 0xF, // indirect mask - - // indirect TEV stages - GX_BP_REG_INDTEVSTAGE0 = 0x10, // indirect TEV stage 0 - GX_BP_REG_INDTEVSTAGE1 = 0x11, // indirect TEV stage 1 - GX_BP_REG_INDTEVSTAGE2 = 0x12, // indirect TEV stage 2 - GX_BP_REG_INDTEVSTAGE3 = 0x13, // indirect TEV stage 3 - GX_BP_REG_INDTEVSTAGE4 = 0x14, // indirect TEV stage 4 - GX_BP_REG_INDTEVSTAGE5 = 0x15, // indirect TEV stage 5 - GX_BP_REG_INDTEVSTAGE6 = 0x16, // indirect TEV stage 6 - GX_BP_REG_INDTEVSTAGE7 = 0x17, // indirect TEV stage 7 - GX_BP_REG_INDTEVSTAGE8 = 0x18, // indirect TEV stage 8 - GX_BP_REG_INDTEVSTAGE9 = 0x19, // indirect TEV stage 9 - GX_BP_REG_INDTEVSTAGE10 = 0x1A, // indirect TEV stage 10 - GX_BP_REG_INDTEVSTAGE11 = 0x1B, // indirect TEV stage 11 - GX_BP_REG_INDTEVSTAGE12 = 0x1C, // indirect TEV stage 12 - GX_BP_REG_INDTEVSTAGE13 = 0x1D, // indirect TEV stage 13 - GX_BP_REG_INDTEVSTAGE14 = 0x1E, // indirect TEV stage 14 - GX_BP_REG_INDTEVSTAGE15 = 0x1F, // indirect TEV stage 15 - - // performance manips - GX_BP_REG_SCISSORTL = 0x20, // scissor top left - GX_BP_REG_SCISSORBR = 0x21, // scissor bottom right - GX_BP_REG_LINEPTWIDTH = 0x22, // line point width - GX_BP_REG_PERF0TRI = 0x23, // performance 0 (triangle) - GX_BP_REG_PERF0QUAD = 0x24, // performance 0 (quad) - - // rasters - GX_BP_REG_RAS1_SS0 = 0x25, - GX_BP_REG_RAS1_SS1 = 0x26, - GX_BP_REG_RAS1_IREF = 0x27, - GX_BP_REG_RAS1_TREF0 = 0x28, - GX_BP_REG_RAS1_TREF1 = 0x29, - GX_BP_REG_RAS1_TREF2 = 0x2A, - GX_BP_REG_RAS1_TREF3 = 0x2B, - GX_BP_REG_RAS1_TREF4 = 0x2C, - GX_BP_REG_RAS1_TREF5 = 0x2D, - GX_BP_REG_RAS1_TREF6 = 0x2E, - GX_BP_REG_RAS1_TREF7 = 0x2F, - - // setup sizes - GX_BP_REG_SU_SSIZE0 = 0x30, - GX_BP_REG_SU_TSIZE0 = 0x31, - GX_BP_REG_SU_SSIZE1 = 0x32, - GX_BP_REG_SU_TSIZE1 = 0x33, - GX_BP_REG_SU_SSIZE2 = 0x34, - GX_BP_REG_SU_TSIZE2 = 0x35, - GX_BP_REG_SU_SSIZE3 = 0x36, - GX_BP_REG_SU_TSIZE3 = 0x37, - GX_BP_REG_SU_SSIZE4 = 0x38, - GX_BP_REG_SU_TSIZE4 = 0x39, - GX_BP_REG_SU_SSIZE5 = 0x3A, - GX_BP_REG_SU_TSIZE5 = 0x3B, - GX_BP_REG_SU_SSIZE6 = 0x3C, - GX_BP_REG_SU_TSIZE6 = 0x3D, - GX_BP_REG_SU_SSIZE7 = 0x3E, - GX_BP_REG_SU_TSIZE7 = 0x3F, - - // Z and blend controls - GX_BP_REG_ZMODE = 0x40, - GX_BP_REG_BLENDMODE = 0x41, - GX_BP_REG_DSTALPHA = 0x42, - GX_BP_REG_ZCONTROL = 0x43, - GX_BP_REG_FIELDMASK = 0x44, - GX_BP_REG_DRAWDONE = 0x45, - GX_BP_REG_PETOKEN = 0x47, - GX_BP_REG_PETOKENINT = 0x48, - - // copying - GX_BP_REG_TEXCOPYSRCXY = 0x49, - GX_BP_REG_TEXCOPYSRCWH = 0x4A, - GX_BP_REG_TEXCOPYDST = 0x4B, - GX_BP_REG_DISPCOPYSTRIDE = 0x4D, - GX_BP_REG_DISPCOPYSCALEY = 0x4E, - GX_BP_REG_COPYCLEARAR = 0x4F, - GX_BP_REG_COPYCLEARGB = 0x50, - GX_BP_REG_COPYCLEARZ = 0x51, - GX_BP_REG_COPYFILTER0 = 0x53, - GX_BP_REG_COPYFILTER1 = 0x54, - - // - GX_BP_REG_BOUNDINGBOX0 = 0x55, - GX_BP_REG_BOUNDINGBOX1 = 0x56, - - GX_BP_REG_SCISSOROFFSET = 0x59, - - // texture memory - GX_BP_REG_TMEMPRELOADADDR = 0x60, - GX_BP_REG_TMEMPRELOADEVEN = 0x61, - GX_BP_REG_TMEMPRELOADODD = 0x62, - GX_BP_REG_TMEMPRELOADMODE = 0x63, - GX_BP_REG_TMEMTLUTSRC = 0x64, - GX_BP_REG_TMEMTLUTDST = 0x65, - GX_BP_REG_TMEMTEXINVALIDATE = 0x66, - - // performance 1 - GX_BP_REG_PERF1 = 0x67, - GX_BP_REG_FIELDMODE = 0x68, - - // set modes - GX_BP_REG_SETMODE0_TEX0 = 0x80, - GX_BP_REG_SETMODE0_TEX1 = 0x81, - GX_BP_REG_SETMODE0_TEX2 = 0x82, - GX_BP_REG_SETMODE0_TEX3 = 0x83, - GX_BP_REG_SETMODE1_TEX0 = 0x84, - GX_BP_REG_SETMODE1_TEX1 = 0x85, - GX_BP_REG_SETMODE1_TEX2 = 0x86, - GX_BP_REG_SETMODE1_TEX3 = 0x87, - - // set images - GX_BP_REG_SETIMAGE0_TEX0 = 0x88, - GX_BP_REG_SETIMAGE0_TEX1 = 0x89, - GX_BP_REG_SETIMAGE0_TEX2 = 0x8A, - GX_BP_REG_SETIMAGE0_TEX3 = 0x8B, - GX_BP_REG_SETIMAGE1_TEX0 = 0x8C, - GX_BP_REG_SETIMAGE1_TEX1 = 0x8D, - GX_BP_REG_SETIMAGE1_TEX2 = 0x8E, - GX_BP_REG_SETIMAGE1_TEX3 = 0x8F, - GX_BP_REG_SETIMAGE2_TEX0 = 0x90, - GX_BP_REG_SETIMAGE2_TEX1 = 0x91, - GX_BP_REG_SETIMAGE2_TEX2 = 0x92, - GX_BP_REG_SETIMAGE2_TEX3 = 0x93, - GX_BP_REG_SETIMAGE3_TEX0 = 0x94, - GX_BP_REG_SETIMAGE3_TEX1 = 0x95, - GX_BP_REG_SETIMAGE3_TEX2 = 0x96, - GX_BP_REG_SETIMAGE3_TEX3 = 0x97, - - // set texture lookups - GX_BP_REG_SETTLUT_TEX0 = 0x98, - GX_BP_REG_SETTLUT_TEX1 = 0x99, - GX_BP_REG_SETTLUT_TEX2 = 0x9A, - GX_BP_REG_SETTLUT_TEX3 = 0x9B, - - // set modes continued - GX_BP_REG_SETMODE0_TEX4 = 0xA0, - GX_BP_REG_SETMODE0_TEX5 = 0xA1, - GX_BP_REG_SETMODE0_TEX6 = 0xA2, - GX_BP_REG_SETMODE0_TEX7 = 0xA3, - GX_BP_REG_SETMODE1_TEX4 = 0xA4, - GX_BP_REG_SETMODE1_TEX5 = 0xA5, - GX_BP_REG_SETMODE1_TEX6 = 0xA6, - GX_BP_REG_SETMODE1_TEX7 = 0xA7, - - // set images continued - GX_BP_REG_SETIMAGE0_TEX4 = 0xA8, - GX_BP_REG_SETIMAGE0_TEX5 = 0xA9, - GX_BP_REG_SETIMAGE0_TEX6 = 0xAA, - GX_BP_REG_SETIMAGE0_TEX7 = 0xAB, - GX_BP_REG_SETIMAGE1_TEX4 = 0xAC, - GX_BP_REG_SETIMAGE1_TEX5 = 0xAD, - GX_BP_REG_SETIMAGE1_TEX6 = 0xAE, - GX_BP_REG_SETIMAGE1_TEX7 = 0xAF, - GX_BP_REG_SETIMAGE2_TEX4 = 0xB0, - GX_BP_REG_SETIMAGE2_TEX5 = 0xB1, - GX_BP_REG_SETIMAGE2_TEX6 = 0xB2, - GX_BP_REG_SETIMAGE2_TEX7 = 0xB3, - GX_BP_REG_SETIMAGE3_TEX4 = 0xB4, - GX_BP_REG_SETIMAGE3_TEX5 = 0xB5, - GX_BP_REG_SETIMAGE3_TEX6 = 0xB6, - GX_BP_REG_SETIMAGE3_TEX7 = 0xB7, - - // set texture lookups continued - GX_BP_REG_SETTLUT_TEX4 = 0xB8, - GX_BP_REG_SETTLUT_TEX5 = 0xB9, - GX_BP_REG_SETTLUT_TEX6 = 0xBA, - GX_BP_REG_SETTLUT_TEX7 = 0xBB, - - // TEV color manips - GX_BP_REG_TEVCOLORCOMBINER0 = 0xC0, - GX_BP_REG_TEVALPHACOMBINER0 = 0xC1, - GX_BP_REG_TEVCOLORCOMBINER1 = 0xC2, - GX_BP_REG_TEVALPHACOMBINER1 = 0xC3, - GX_BP_REG_TEVCOLORCOMBINER2 = 0xC4, - GX_BP_REG_TEVALPHACOMBINER2 = 0xC5, - GX_BP_REG_TEVCOLORCOMBINER3 = 0xC6, - GX_BP_REG_TEVALPHACOMBINER3 = 0xC7, - GX_BP_REG_TEVCOLORCOMBINER4 = 0xC8, - GX_BP_REG_TEVALPHACOMBINER4 = 0xC9, - GX_BP_REG_TEVCOLORCOMBINER5 = 0xCA, - GX_BP_REG_TEVALPHACOMBINER5 = 0xCB, - GX_BP_REG_TEVCOLORCOMBINER6 = 0xCC, - GX_BP_REG_TEVALPHACOMBINER6 = 0xCD, - GX_BP_REG_TEVCOLORCOMBINER7 = 0xCE, - GX_BP_REG_TEVALPHACOMBINER7 = 0xCF, - GX_BP_REG_TEVCOLORCOMBINER8 = 0xD0, - GX_BP_REG_TEVALPHACOMBINER8 = 0xD1, - GX_BP_REG_TEVCOLORCOMBINER9 = 0xD2, - GX_BP_REG_TEVALPHACOMBINER9 = 0xD3, - GX_BP_REG_TEVCOLORCOMBINER10 = 0xD4, - GX_BP_REG_TEVALPHACOMBINER10 = 0xD5, - GX_BP_REG_TEVCOLORCOMBINER11 = 0xD6, - GX_BP_REG_TEVALPHACOMBINER11 = 0xD7, - GX_BP_REG_TEVCOLORCOMBINER12 = 0xD8, - GX_BP_REG_TEVALPHACOMBINER12 = 0xD9, - GX_BP_REG_TEVCOLORCOMBINER13 = 0xDA, - GX_BP_REG_TEVALPHACOMBINER13 = 0xDB, - GX_BP_REG_TEVCOLORCOMBINER14 = 0xDC, - GX_BP_REG_TEVALPHACOMBINER14 = 0xDD, - GX_BP_REG_TEVCOLORCOMBINER15 = 0xDE, - GX_BP_REG_TEVALPHACOMBINER15 = 0xDF, - - // TEV registers - GX_BP_REG_TEVREG0LO = 0xE0, - GX_BP_REG_TEVREG0HI = 0xE1, - GX_BP_REG_TEVREG1LO = 0xE2, - GX_BP_REG_TEVREG1HI = 0xE3, - GX_BP_REG_TEVREG2LO = 0xE4, - GX_BP_REG_TEVREG2HI = 0xE5, - GX_BP_REG_TEVREG3LO = 0xE6, - GX_BP_REG_TEVREG3HI = 0xE7, - - // fog registers - GX_BP_REG_FOGRANGE = 0xE8, - GX_BP_REG_FOGRANGEK0 = 0xE9, - GX_BP_REG_FOGRANGEK1 = 0xEA, - GX_BP_REG_FOGRANGEK2 = 0xEB, - GX_BP_REG_FOGRANGEK3 = 0xEC, - GX_BP_REG_FOGRANGEK4 = 0xED, - GX_BP_REG_FOGPARAM0 = 0xEE, - GX_BP_REG_FOGPARAM1 = 0xEF, - GX_BP_REG_FOGPARAM2 = 0xF0, - GX_BP_REG_FOGPARAM3 = 0xF1, - GX_BP_REG_FOGCOLOR = 0xF2, - - // performance manip registers - GX_BP_REG_ALPHACOMPARE = 0xF3, - GX_BP_REG_ZTEXTURE0 = 0xF4, - GX_BP_REG_ZTEXTURE1 = 0xF5, - - // TEV K selectors - GX_BP_REG_TEVKSEL0 = 0xF6, - GX_BP_REG_TEVKSEL1 = 0xF7, - GX_BP_REG_TEVKSEL2 = 0xF8, - GX_BP_REG_TEVKSEL3 = 0xF9, - GX_BP_REG_TEVKSEL4 = 0xFA, - GX_BP_REG_TEVKSEL5 = 0xFB, - GX_BP_REG_TEVKSEL6 = 0xFC, - GX_BP_REG_TEVKSEL7 = 0xFD, - - // SS mask - GX_BP_REG_SSMASK = 0xFE, -} GXBPRegs; - -// BP locators for fog parameter 0. -typedef enum _GXBPFogParam0 { - // A mantissa [21-31] - GX_BP_FOGPARAM0_A_MANT_ST = 21, - GX_BP_FOGPARAM0_A_MANT_END = 31, - - // A exponent [13-20] - GX_BP_FOGPARAM0_A_EXP_ST = 13, - GX_BP_FOGPARAM0_A_EXP_END = 20, - - // A sign [12-12] - GX_BP_FOGPARAM0_A_SIGN_ST = 12, - GX_BP_FOGPARAM0_A_SIGN_END = 12, -} GXBPFogParam0; - -// BP locators for fog parameter 1. -typedef enum _GXBPFogParam1 { - // B magnitude [8-31] - GX_BP_FOGPARAM1_B_MAG_ST = 8, - GX_BP_FOGPARAM1_B_MAG_END = 31, -} GXBPFogParam1; - -// BP locators for fog parameter 2. -typedef enum _GXBPFogParam2 { - // B shift [27-31] - GX_BP_FOGPARAM2_B_SHIFT_ST = 27, - GX_BP_FOGPARAM2_B_SHIFT_END = 31, -} GXBPFogParam2; - -// BP locators for fog parameter 3. -typedef enum _GXBPFogParam3 { - // C mantissa [21-31] - GX_BP_FOGPARAM3_C_MANT_ST = 21, - GX_BP_FOGPARAM3_C_MANT_END = 31, - - // C exponent [13-20] - GX_BP_FOGPARAM3_C_EXP_ST = 13, - GX_BP_FOGPARAM3_C_EXP_END = 20, - - // C sign [12-12] - GX_BP_FOGPARAM3_C_SIGN_ST = 12, - GX_BP_FOGPARAM3_C_SIGN_END = 12, - - // Projection [11] - GX_BP_FOGPARAM3_PROJ_ST = 11, - GX_BP_FOGPARAM3_PROJ_END = 11, - - // F select [8-10] - GX_BP_FOGPARAM3_FSEL_ST = 8, - GX_BP_FOGPARAM3_FSEL_END = 10, -} GXBPFogParam3; - -// BP locators for fog color. -typedef enum _GXBPFogColor { - // RGB components of color [8-31] - GX_BP_FOGCOLOR_RGB_ST = 8, - GX_BP_FOGCOLOR_RGB_END = 31, -} GXBPFogColor; - -// BP locators for fog range. -typedef enum _GXBPFogRange { - // Center [22-31] - GX_BP_FOGRANGE_CENTER_ST = 22, - GX_BP_FOGRANGE_CENTER_END = 31, - - // Enabled [21-21] - GX_BP_FOGRANGE_ENABLED_ST = 21, - GX_BP_FOGRANGE_ENABLED_END = 21, -} GXBPFogRange; - -// BP locators for fog range K. -typedef enum _GXBPFogRangeK { - // Hi [20-31] - GX_BP_FOGRANGEK_HI_ST = 20, - GX_BP_FOGRANGEK_HI_END = 31, - - // Lo [8-19] - GX_BP_FOGRANGEK_LO_ST = 8, - GX_BP_FOGRANGEK_LO_END = 19, -} GXBPFogRangeK; - -// BP locators for blend mode. -typedef enum _GXBPBlendMode { - // Blend enable [31-31] - GX_BP_BLENDMODE_ENABLE_ST = 31, - GX_BP_BLENDMODE_ENABLE_END = 31, - - // Logic operation enable [30-30] - GX_BP_BLENDMODE_LOGIC_OP_ST = 30, - GX_BP_BLENDMODE_LOGIC_OP_END = 30, - - // Dither [29-29] - GX_BP_BLENDMODE_DITHER_ST = 29, - GX_BP_BLENDMODE_DITHER_END = 29, - - // Color update [28-28] - GX_BP_BLENDMODE_COLOR_UPDATE_ST = 28, - GX_BP_BLENDMODE_COLOR_UPDATE_END = 28, - - // Alpha update [27-27] - GX_BP_BLENDMODE_ALPHA_UPDATE_ST = 27, - GX_BP_BLENDMODE_ALPHA_UPDATE_END = 27, - - // Destination factor [24-26] - GX_BP_BLENDMODE_DSTFACTOR_ST = 24, - GX_BP_BLENDMODE_DSTFACTOR_END = 26, - - // Source factor [21-23] - GX_BP_BLENDMODE_SRCFACTOR_ST = 21, - GX_BP_BLENDMODE_SRCFACTOR_END = 23, - - // Subtract [20-20] - GX_BP_BLENDMODE_SUBTRACT_ST = 20, - GX_BP_BLENDMODE_SUBTRACT_END = 20, - - // Logic mode [16-19] - GX_BP_BLENDMODE_LOGICMODE_ST = 16, - GX_BP_BLENDMODE_LOGICMODE_END = 19, -} GXBPBlendMode; - -// BP locators for Z mode. -typedef enum _GXBPZMode { - // Test enable [31-31] - GX_BP_ZMODE_TEST_ENABLE_ST = 31, - GX_BP_ZMODE_TEST_ENABLE_END = 31, - - // Compare [28-30] - GX_BP_ZMODE_COMPARE_ST = 28, - GX_BP_ZMODE_COMPARE_END = 30, - - // Update enable [27-27] - GX_BP_ZMODE_UPDATE_ENABLE_ST = 27, - GX_BP_ZMODE_UPDATE_ENABLE_END = 27, -} GXBPZMode; - -// BP locators for Z control. -typedef enum _GXBPZControl { - // Pixel format [29-31] - GX_BP_ZCONTROL_PIXEL_FMT_ST = 29, - GX_BP_ZCONTROL_PIXEL_FMT_END = 31, - - // Z format [26-28] - GX_BP_ZCONTROL_Z_FMT_ST = 26, - GX_BP_ZCONTROL_Z_FMT_END = 28, - - // Whether to do Z-buffering before or after texturing [25-25] - GX_BP_ZCONTROL_BEFORE_TEX_ST = 25, - GX_BP_ZCONTROL_BEFORE_TEX_END = 25, -} GXBPZControl; - -// BP locators for destination alpha. -typedef enum _GXBPDstAlpha { - // Alpha [24-31] - GX_BP_DSTALPHA_ALPHA_ST = 24, - GX_BP_DSTALPHA_ALPHA_END = 31, - - // Enable [23-23] - GX_BP_DSTALPHA_ENABLE_ST = 23, - GX_BP_DSTALPHA_ENABLE_END = 23, - - // YUV format [21-22] - GX_BP_DSTALPHA_YUV_FMT_ST = 21, - GX_BP_DSTALPHA_YUV_FMT_END = 22, -} GXBPDstAlpha; - -// BP locators for field mask. -typedef enum _GXBPFieldMask { - // Whether to write odd fields to the EFB [31-31] - GX_BP_FIELDMASK_ODD_ST = 31, - GX_BP_FIELDMASK_ODD_END = 31, - - // Whether to write even fields to the EFB [30-30] - GX_BP_FIELDMASK_EVEN_ST = 30, - GX_BP_FIELDMASK_EVEN_END = 30, -} GXBPFieldMask; - -// BP locators for line and point settings. -typedef enum _GXBPLinePtWidth { - // Line size/width [24-31] - GX_BP_LINEPTWIDTH_LINESZ_ST = 24, - GX_BP_LINEPTWIDTH_LINESZ_END = 31, - - // Point size [16-23] - GX_BP_LINEPTWIDTH_POINTSZ_ST = 16, - GX_BP_LINEPTWIDTH_POINTSZ_END = 23, - - // Line offset [13-15] - GX_BP_LINEPTWIDTH_LINEOFS_ST = 13, - GX_BP_LINEPTWIDTH_LINEOFS_END = 15, - - // Point offset [10-12] - GX_BP_LINEPTWIDTH_POINTOFS_ST = 10, - GX_BP_LINEPTWIDTH_POINTOFS_END = 12, - - // Interlacing adjustment for aspect ratio [9-9] - GX_BP_LINEPTWIDTH_ADJUST_ST = 9, - GX_BP_LINEPTWIDTH_ADJUST_END = 9, -} GXBPLinePtWidth; - -// Miscellaneous token types. -typedef enum _GXMiscToken { - GX_MT_NULL = 0, - GX_MT_XF_FLUSH = 1, - GX_MT_DL_SAVE_CONTEXT = 2, - GX_MT_ABORT_WAIT_COPYOUT = 3, -} GXMiscToken; - -// Transform memory types. -typedef enum _GXXfMem { - GX_XF_MEM_POSMTX = 0x000, // position coord matrix - GX_XF_MEM_NRMMTX = 0x400, // normal coord matrix - GX_XF_MEM_DUALTEXMTX = 0x500, // dual texture matrix - GX_XF_MEM_LIGHTOBJ = 0x600, // light object -} GXXfMem; - -// BP locators for top-left scissor. -typedef enum _GXBPScissorTL { - // Top component [21-31] - GX_BP_SCISSORTL_TOP_ST = 21, - GX_BP_SCISSORTL_TOP_END = 31, - - // Left component [9-19] - GX_BP_SCISSORTL_LEFT_ST = 9, - GX_BP_SCISSORTL_LEFT_END = 19, -} GXBPScissorTL; - -// BP locators for bottom-right scissor. -typedef enum _GXBPScissorBR { - // Bottom component [21-31] - GX_BP_SCISSORBR_BOT_ST = 21, - GX_BP_SCISSORBR_BOT_END = 31, - - // Right component [9-19] - GX_BP_SCISSORBR_RIGHT_ST = 9, - GX_BP_SCISSORBR_RIGHT_END = 19, -} GXBPScissorBR; - -// BP locators for scissor offset. -typedef enum _GXBPScissorOffset { - // X offset [22-31] - GX_BP_SCISSOROFS_OX_ST = 22, - GX_BP_SCISSOROFS_OX_END = 31, - - // Y offset [12-21] - GX_BP_SCISSOROFS_OY_ST = 12, - GX_BP_SCISSOROFS_OY_END = 21, -} GXBPScissorOffset; - -// Perf-0 types. typedef enum _GXPerf0 { - GX_PERF0_VERTICES = 0, - GX_PERF0_CLIP_VTX = 1, - GX_PERF0_CLIP_CLKS = 2, - GX_PERF0_XF_WAIT_IN = 3, - GX_PERF0_XF_WAIT_OUT = 4, - GX_PERF0_XF_XFRM_CLKS = 5, - GX_PERF0_XF_LIT_CLKS = 6, - GX_PERF0_XF_BOT_CLKS = 7, - GX_PERF0_XF_REGLD_CLKS = 8, - GX_PERF0_XF_REGRD_CLKS = 9, - GX_PERF0_CLIP_RATIO = 10, + GX_PERF0_VERTICES, + GX_PERF0_CLIP_VTX, + GX_PERF0_CLIP_CLKS, + GX_PERF0_XF_WAIT_IN, + GX_PERF0_XF_WAIT_OUT, + GX_PERF0_XF_XFRM_CLKS, + GX_PERF0_XF_LIT_CLKS, + GX_PERF0_XF_BOT_CLKS, + GX_PERF0_XF_REGLD_CLKS, + GX_PERF0_XF_REGRD_CLKS, + GX_PERF0_CLIP_RATIO, - GX_PERF0_TRIANGLES = 11, - GX_PERF0_TRIANGLES_CULLED = 12, - GX_PERF0_TRIANGLES_PASSED = 13, - GX_PERF0_TRIANGLES_SCISSORED = 14, - GX_PERF0_TRIANGLES_0TEX = 15, - GX_PERF0_TRIANGLES_1TEX = 16, - GX_PERF0_TRIANGLES_2TEX = 17, - GX_PERF0_TRIANGLES_3TEX = 18, - GX_PERF0_TRIANGLES_4TEX = 19, - GX_PERF0_TRIANGLES_5TEX = 20, - GX_PERF0_TRIANGLES_6TEX = 21, - GX_PERF0_TRIANGLES_7TEX = 22, - GX_PERF0_TRIANGLES_8TEX = 23, - GX_PERF0_TRIANGLES_0CLR = 24, - GX_PERF0_TRIANGLES_1CLR = 25, - GX_PERF0_TRIANGLES_2CLR = 26, + GX_PERF0_TRIANGLES, + GX_PERF0_TRIANGLES_CULLED, + GX_PERF0_TRIANGLES_PASSED, + GX_PERF0_TRIANGLES_SCISSORED, + GX_PERF0_TRIANGLES_0TEX, + GX_PERF0_TRIANGLES_1TEX, + GX_PERF0_TRIANGLES_2TEX, + GX_PERF0_TRIANGLES_3TEX, + GX_PERF0_TRIANGLES_4TEX, + GX_PERF0_TRIANGLES_5TEX, + GX_PERF0_TRIANGLES_6TEX, + GX_PERF0_TRIANGLES_7TEX, + GX_PERF0_TRIANGLES_8TEX, + GX_PERF0_TRIANGLES_0CLR, + GX_PERF0_TRIANGLES_1CLR, + GX_PERF0_TRIANGLES_2CLR, - GX_PERF0_QUAD_0CVG = 27, - GX_PERF0_QUAD_NON0CVG = 28, - GX_PERF0_QUAD_1CVG = 29, - GX_PERF0_QUAD_2CVG = 30, - GX_PERF0_QUAD_3CVG = 31, - GX_PERF0_QUAD_4CVG = 32, - GX_PERF0_AVG_QUAD_CNT = 33, + GX_PERF0_QUAD_0CVG, + GX_PERF0_QUAD_NON0CVG, + GX_PERF0_QUAD_1CVG, + GX_PERF0_QUAD_2CVG, + GX_PERF0_QUAD_3CVG, + GX_PERF0_QUAD_4CVG, + GX_PERF0_AVG_QUAD_CNT, - GX_PERF0_CLOCKS = 34, - GX_PERF0_NONE = 35, + GX_PERF0_CLOCKS, + GX_PERF0_NONE, } GXPerf0; -// Perf-1 types. typedef enum _GXPerf1 { - GX_PERF1_TEXELS = 0, - GX_PERF1_TX_IDLE = 1, - GX_PERF1_TX_REGS = 2, - GX_PERF1_TX_MEMSTALL = 3, - GX_PERF1_TC_CHECK1_2 = 4, - GX_PERF1_TC_CHECK3_4 = 5, - GX_PERF1_TC_CHECK5_6 = 6, - GX_PERF1_TC_CHECK7_8 = 7, - GX_PERF1_TC_MISS = 8, + GX_PERF1_TEXELS, + GX_PERF1_TX_IDLE, + GX_PERF1_TX_REGS, + GX_PERF1_TX_MEMSTALL, + GX_PERF1_TC_CHECK1_2, + GX_PERF1_TC_CHECK3_4, + GX_PERF1_TC_CHECK5_6, + GX_PERF1_TC_CHECK7_8, + GX_PERF1_TC_MISS, - GX_PERF1_VC_ELEMQ_FULL = 9, - GX_PERF1_VC_MISSQ_FULL = 10, - GX_PERF1_VC_MEMREQ_FULL = 11, - GX_PERF1_VC_STATUS7 = 12, - GX_PERF1_VC_MISSREP_FULL = 13, - GX_PERF1_VC_STREAMBUF_LOW = 14, - GX_PERF1_VC_ALL_STALLS = 15, - GX_PERF1_VERTICES = 16, + GX_PERF1_VC_ELEMQ_FULL, + GX_PERF1_VC_MISSQ_FULL, + GX_PERF1_VC_MEMREQ_FULL, + GX_PERF1_VC_STATUS7, + GX_PERF1_VC_MISSREP_FULL, + GX_PERF1_VC_STREAMBUF_LOW, + GX_PERF1_VC_ALL_STALLS, + GX_PERF1_VERTICES, - GX_PERF1_FIFO_REQ = 17, - GX_PERF1_CALL_REQ = 18, - GX_PERF1_VC_MISS_REQ = 19, - GX_PERF1_CP_ALL_REQ = 20, + GX_PERF1_FIFO_REQ, + GX_PERF1_CALL_REQ, + GX_PERF1_VC_MISS_REQ, + GX_PERF1_CP_ALL_REQ, - GX_PERF1_CLOCKS = 21, - GX_PERF1_NONE = 22, + GX_PERF1_CLOCKS, + GX_PERF1_NONE, } GXPerf1; -// Vertex cache perf types. typedef enum _GXVCachePerf { GX_VC_POS = 0, GX_VC_NRM = 1, @@ -1902,43 +813,112 @@ typedef enum _GXVCachePerf { GX_VC_TEX5 = 9, GX_VC_TEX6 = 10, GX_VC_TEX7 = 11, - - GX_VC_ALL = 15 + GX_VC_ALL = 15, } GXVCachePerf; -// XF locators for Color 0 control. -typedef enum _GXXFClr0Ctrl { - // Matrix source [31-31] - GX_XF_CLR0CTRL_MTXSRC_ST = 31, - GX_XF_CLR0CTRL_MTXSRC_END = 31, +typedef enum _GXClipMode { + GX_CLIP_ENABLE = 0, + GX_CLIP_DISABLE = 1, +} GXClipMode; - // Light [30-30] - GX_XF_CLR0CTRL_LIGHT_ST = 30, - GX_XF_CLR0CTRL_LIGHT_END = 30, +typedef enum _GXFBClamp { + GX_CLAMP_NONE = 0, + GX_CLAMP_TOP = 1, + GX_CLAMP_BOTTOM = 2, +} GXFBClamp; - // Light mask (hi) [26-29] - GX_XF_CLR0CTRL_LMASKHI_ST = 26, - GX_XF_CLR0CTRL_LMASKHI_END = 29, +typedef enum _GXCopyMode { + GX_COPY_PROGRESSIVE = 0, + GX_COPY_INTLC_EVEN = 2, + GX_COPY_INTLC_ODD = 3, +} GXCopyMode; - // Ambient source [25-25] - GX_XF_CLR0CTRL_AMBSRC_ST = 25, - GX_XF_CLR0CTRL_AMBSRC_END = 25, +typedef enum _GXAlphaReadMode { + GX_READ_00, + GX_READ_FF, + GX_READ_NONE, +} GXAlphaReadMode; - // Diffuse attenuation [23-24] - GX_XF_CLR0CTRL_DIFATTN_ST = 23, - GX_XF_CLR0CTRL_DIFATTN_END = 24, +typedef enum _GXTexCacheSize { + GX_TEXCACHE_32K, + GX_TEXCACHE_128K, + GX_TEXCACHE_512K, + GX_TEXCACHE_NONE, +} GXTexCacheSize; - // Enable attentuation [22-22] - GX_XF_CLR0CTRL_ATTNENABLE_ST = 22, - GX_XF_CLR0CTRL_ATTNENABLE_END = 22, +typedef enum _GXTlut { + GX_TLUT0, + GX_TLUT1, + GX_TLUT2, + GX_TLUT3, + GX_TLUT4, + GX_TLUT5, + GX_TLUT6, + GX_TLUT7, + GX_TLUT8, + GX_TLUT9, + GX_TLUT10, + GX_TLUT11, + GX_TLUT12, + GX_TLUT13, + GX_TLUT14, + GX_TLUT15, + GX_BIGTLUT0, + GX_BIGTLUT1, + GX_BIGTLUT2, + GX_BIGTLUT3, +} GXTlut; - // Select attentuation [21-21] - GX_XF_CLR0CTRL_ATTNSEL_ST = 21, - GX_XF_CLR0CTRL_ATTNSEL_END = 21, +typedef enum _GXTlutFmt { + GX_TL_IA8, + GX_TL_RGB565, + GX_TL_RGB5A3, + GX_MAX_TLUTFMT, +} GXTlutFmt; - // Light mask (lo) [17-20] - GX_XF_CLR0CTRL_LMASKLO_ST = 17, - GX_XF_CLR0CTRL_LMASKLO_END = 20, -} GXXFClr0Ctrl; +typedef enum _GXTlutSize { + GX_TLUT_16 = 1, + GX_TLUT_32 = 2, + GX_TLUT_64 = 4, + GX_TLUT_128 = 8, + GX_TLUT_256 = 16, + GX_TLUT_512 = 32, + GX_TLUT_1K = 64, + GX_TLUT_2K = 128, + GX_TLUT_4K = 256, + GX_TLUT_8K = 512, + GX_TLUT_16K = 1024, +} GXTlutSize; -#endif /* GXENUM_H */ +typedef enum _GXMiscToken { + GX_MT_XF_FLUSH = 1, + GX_MT_DL_SAVE_CONTEXT = 2, + GX_MT_ABORT_WAIT_COPYOUT = 3, + GX_MT_NULL = 0, +} GXMiscToken; + +// temporary +typedef enum _GXCommand { + GX_CMD_LOAD_INDX_A = 0x20, + GX_CMD_LOAD_INDX_B = 0x28, + GX_CMD_LOAD_INDX_C = 0x30, + GX_CMD_LOAD_INDX_D = 0x38, + + GX_CMD_LOAD_CP_REG = 0x08, + GX_CMD_LOAD_XF_REG = 0x10, + GX_CMD_LOAD_BP_REG = 0x61, +} GXCommand; + +typedef enum _GXCPRegs { + GX_CP_REG_MTXIDXA = 0x30, // Matrix index A + GX_CP_REG_MTXIDXB = 0x40, // Matrix index B + GX_CP_REG_VCD_LO = 0x50, // Vertex descriptor (lo) + GX_CP_REG_VCD_HI = 0x60, // Vertex descriptor (hi) + GX_CP_REG_VAT_GRP0 = 0x70, // Vertex attribute table (group 0) + GX_CP_REG_VAT_GRP1 = 0x80, // Vertex attribute table (group 1) + GX_CP_REG_VAT_GRP2 = 0x90, // Vertex attribute table (group 2) + GX_CP_REG_ARRAYBASE = 0xA0, // Vertex array start/base + GX_CP_REG_ARRAYSTRIDE = 0xB0, // Vertex array stride +} GXCPRegs; + +#endif diff --git a/include/dolphin/gx/GXFifo.h b/include/dolphin/gx/GXFifo.h index 942a954c1a..069f36a4ea 100644 --- a/include/dolphin/gx/GXFifo.h +++ b/include/dolphin/gx/GXFifo.h @@ -1,39 +1,46 @@ -#ifndef GXFIFO_H -#define GXFIFO_H +#ifndef _DOLPHIN_GX_GXFIFO_H_ +#define _DOLPHIN_GX_GXFIFO_H_ -#include "dolphin/gx/GXStruct.h" -#include "dolphin/os/OSThread.h" +#include +#include #ifdef __cplusplus extern "C" { #endif +typedef struct { + u8 pad[128]; +} GXFifoObj; + typedef void (*GXBreakPtCallback)(void); void GXInitFifoBase(GXFifoObj* fifo, void* base, u32 size); -void GXInitFifoPtrs(GXFifoObj* fifo, void* read_ptr, void* write_ptr); +void GXInitFifoPtrs(GXFifoObj* fifo, void* readPtr, void* writePtr); +void GXInitFifoLimits(GXFifoObj* fifo, u32 hiWatermark, u32 loWatermark); void GXSetCPUFifo(GXFifoObj* fifo); void GXSetGPFifo(GXFifoObj* fifo); void GXSaveCPUFifo(GXFifoObj* fifo); -void __GXSaveCPUFifoAux(GXFifoObj* fifo); -void GXGetGPStatus(GXBool* overhi, GXBool* underlo, GXBool* read_idle, GXBool* cmd_idle, GXBool* breakpoint); -void* GXGetFifoBase(GXFifoObj* fifo); -u32 GXGetFifoSize(GXFifoObj* fifo); +void GXSaveGPFifo(GXFifoObj* fifo); +void GXGetGPStatus(GXBool* overhi, GXBool* underlow, GXBool* readIdle, GXBool* cmdIdle, GXBool* brkpt); +void GXGetFifoStatus(GXFifoObj* fifo, GXBool* overhi, GXBool* underflow, u32* fifoCount, GXBool* cpuWrite, GXBool* gpRead, GXBool* fifowrap); +void GXGetFifoPtrs(GXFifoObj* fifo, void** readPtr, void** writePtr); +void* GXGetFifoBase(const GXFifoObj* fifo); +u32 GXGetFifoSize(const GXFifoObj* fifo); +void GXGetFifoLimits(const GXFifoObj* fifo, u32* hi, u32* lo); GXBreakPtCallback GXSetBreakPtCallback(GXBreakPtCallback cb); -void __GXFifoInit(void); -void __GXFifoReadEnable(void); -void __GXFifoReadDisable(void); -void __GXFifoLink(u8); -void __GXWriteFifoIntEnable(u32, u32); -void __GXWriteFifoIntReset(u32, u32); -void __GXCleanGPFifo(void); +void GXEnableBreakPt(void* break_pt); +void GXDisableBreakPt(void); OSThread* GXSetCurrentGXThread(void); OSThread* GXGetCurrentGXThread(void); GXFifoObj* GXGetCPUFifo(void); GXFifoObj* GXGetGPFifo(void); +u32 GXGetOverflowCount(void); +u32 GXResetOverflowCount(void); +volatile void* GXRedirectWriteGatherPipe(void* ptr); +void GXRestoreWriteGatherPipe(void); #ifdef __cplusplus -}; +} #endif -#endif /* GXFIFO_H */ +#endif diff --git a/include/dolphin/gx/GXFrameBuf.h b/include/dolphin/gx/GXFrameBuf.h deleted file mode 100644 index 5e28a80be1..0000000000 --- a/include/dolphin/gx/GXFrameBuf.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef GXFRAMEBUF_H -#define GXFRAMEBUF_H - -#include "dolphin/gx/GXStruct.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void GXSetDispCopySrc(u16 left, u16 top, u16 width, u16 height); -void GXSetTexCopySrc(u16 left, u16 top, u16 width, u16 height); -void GXSetDispCopyDst(u16 arg0, u16 arg1); -void GXSetTexCopyDst(u16 width, u16 height, GXTexFmt format, GXBool useMIPmap); -void GXSetDispCopyFrame2Field(GXCopyMode mode); -void GXSetCopyClamp(GXFBClamp clamp); -u16 GXGetNumXfbLines(u16 efbHeight, f32 yScale); -f32 GXGetYScaleFactor(u16 efb_height, u16 xfb_height); -u32 GXSetDispCopyYScale(f32 y_scale); -void GXSetCopyClear(GXColor color, u32 clear_z); -void GXSetCopyFilter(GXBool antialias, u8 pattern[12][2], GXBool vf, u8 vfilter[7]); -void GXSetDispCopyGamma(GXGamma gamma); -void GXCopyDisp(void* dst, GXBool clear); -void GXCopyTex(void* dst, GXBool clear); -void GXClearBoundingBox(void); - -#ifdef __cplusplus -}; -#endif - -#endif /* GXFRAMEBUF_H */ diff --git a/include/dolphin/gx/GXFrameBuffer.h b/include/dolphin/gx/GXFrameBuffer.h new file mode 100644 index 0000000000..73b513fa32 --- /dev/null +++ b/include/dolphin/gx/GXFrameBuffer.h @@ -0,0 +1,66 @@ +#ifndef _DOLPHIN_GX_GXFRAMEBUFFER_H_ +#define _DOLPHIN_GX_GXFRAMEBUFFER_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define GX_MAX_Z24 0x00ffffff + +extern GXRenderModeObj GXNtsc240Ds; +extern GXRenderModeObj GXNtsc240DsAa; +extern GXRenderModeObj GXNtsc240Int; +extern GXRenderModeObj GXNtsc240IntAa; +extern GXRenderModeObj GXNtsc480IntDf; +extern GXRenderModeObj GXNtsc480Int; +extern GXRenderModeObj GXNtsc480IntAa; +extern GXRenderModeObj GXNtsc480Prog; +extern GXRenderModeObj GXNtsc480ProgAa; +extern GXRenderModeObj GXMpal240Ds; +extern GXRenderModeObj GXMpal240DsAa; +extern GXRenderModeObj GXMpal240Int; +extern GXRenderModeObj GXMpal240IntAa; +extern GXRenderModeObj GXMpal480IntDf; +extern GXRenderModeObj GXMpal480Int; +extern GXRenderModeObj GXMpal480IntAa; +extern GXRenderModeObj GXPal264Ds; +extern GXRenderModeObj GXPal264DsAa; +extern GXRenderModeObj GXPal264Int; +extern GXRenderModeObj GXPal264IntAa; +extern GXRenderModeObj GXPal528IntDf; +extern GXRenderModeObj GXPal528Int; +extern GXRenderModeObj GXPal528IntAa; +extern GXRenderModeObj GXEurgb60Hz240Ds; +extern GXRenderModeObj GXEurgb60Hz240DsAa; +extern GXRenderModeObj GXEurgb60Hz240Int; +extern GXRenderModeObj GXEurgb60Hz240IntAa; +extern GXRenderModeObj GXEurgb60Hz480IntDf; +extern GXRenderModeObj GXEurgb60Hz480Int; +extern GXRenderModeObj GXEurgb60Hz480IntAa; + +void GXAdjustForOverscan(const GXRenderModeObj* rmin, GXRenderModeObj* rmout, u16 hor, u16 ver); +void GXSetDispCopySrc(u16 left, u16 top, u16 wd, u16 ht); +void GXSetTexCopySrc(u16 left, u16 top, u16 wd, u16 ht); +void GXSetDispCopyDst(u16 wd, u16 ht); +void GXSetTexCopyDst(u16 wd, u16 ht, GXTexFmt fmt, GXBool mipmap); +void GXSetDispCopyFrame2Field(GXCopyMode mode); +void GXSetCopyClamp(GXFBClamp clamp); +u32 GXSetDispCopyYScale(f32 vscale); +void GXSetCopyClear(GXColor clear_clr, u32 clear_z); +void GXSetCopyFilter(GXBool aa, const u8 sample_pattern[12][2], GXBool vf, const u8 vfilter[7]); +void GXSetDispCopyGamma(GXGamma gamma); +void GXCopyDisp(void* dest, GXBool clear); +void GXCopyTex(void* dest, GXBool clear); +void GXClearBoundingBox(void); +void GXReadBoundingBox(u16* left, u16* top, u16* right, u16* bottom); +u16 GXGetNumXfbLines(u16 efbHeight, f32 yScale); +f32 GXGetYScaleFactor(u16 efbHeight, u16 xfbHeight); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/gx/GXGeometry.h b/include/dolphin/gx/GXGeometry.h index a711eb4a9a..188fa7a590 100644 --- a/include/dolphin/gx/GXGeometry.h +++ b/include/dolphin/gx/GXGeometry.h @@ -1,24 +1,47 @@ -#ifndef GXGEOMETRY_H -#define GXGEOMETRY_H +#ifndef _DOLPHIN_GX_GXGEOMETRY_H_ +#define _DOLPHIN_GX_GXGEOMETRY_H_ -#include "dolphin/gx/GXEnum.h" +#include +#include #ifdef __cplusplus extern "C" { #endif -void __GXSetDirtyState(void); -void GXBegin(GXPrimitive type, GXVtxFmt fmt, u16 vert_num); -void __GXSendFlushPrim(void); -void GXSetLineWidth(u8 width, GXTexOffset offsets); -void GXSetPointSize(u8 size, GXTexOffset offsets); -void GXEnableTexOffsets(GXTexCoordID coord, GXBool line, GXBool point); -void GXSetCullMode(GXCullMode mode); -void GXSetCoPlanar(GXBool enable); -void __GXSetGenMode(void); +void __GXCalculateVLim(); +void GXSetVtxDesc(GXAttr attr, GXAttrType type); +void GXSetVtxDescv(const GXVtxDescList* attrPtr); +void GXClearVtxDesc(void); +void GXSetVtxAttrFmt(GXVtxFmt vtxfmt, GXAttr attr, GXCompCnt cnt, GXCompType type, u8 frac); +void GXSetVtxAttrFmtv(GXVtxFmt vtxfmt, const GXVtxAttrFmtList* list); +void GXSetArray(GXAttr attr, void* base_ptr, u8 stride); +void GXInvalidateVtxCache(void); +void GXSetTexCoordGen2(GXTexCoordID dst_coord, GXTexGenType func, GXTexGenSrc src_param, u32 mtx, GXBool normalize, u32 pt_texmtx); +void GXSetNumTexGens(u8 nTexGens); + +static inline void GXSetTexCoordGen(GXTexCoordID dst_coord, GXTexGenType func, GXTexGenSrc src_param, u32 mtx) { + GXSetTexCoordGen2(dst_coord, func, src_param, mtx, GX_FALSE, GX_PTIDENTITY); +} + +void GXBegin(GXPrimitive type, GXVtxFmt vtxfmt, u16 nverts); + +static inline void GXEnd(void) { +#if DEBUG + extern GXBool __GXinBegin; + extern void OSPanic(char* file, int line, char* msg, ...); + if (!__GXinBegin) { + OSPanic(__FILE__, 118, "GXEnd: called without a GXBegin"); + } + __GXinBegin = GX_FALSE; +#endif +} + +void GXSetLineWidth(u8 width, GXTexOffset texOffsets); +void GXSetPointSize(u8 pointSize, GXTexOffset texOffsets); +void GXEnableTexOffsets(GXTexCoordID coord, u8 line_enable, u8 point_enable); #ifdef __cplusplus -}; +} #endif -#endif /* GXGEOMETRY_H */ +#endif diff --git a/include/dolphin/gx/GXGet.h b/include/dolphin/gx/GXGet.h new file mode 100644 index 0000000000..d1ba630a46 --- /dev/null +++ b/include/dolphin/gx/GXGet.h @@ -0,0 +1,64 @@ +#ifndef _DOLPHIN_GX_GXGET_H_ +#define _DOLPHIN_GX_GXGET_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Attr +void GXGetVtxDesc(GXAttr attr, GXAttrType* type); +void GXGetVtxDescv(GXVtxDescList* vcd); +void GXGetVtxAttrFmt(GXVtxFmt fmt, GXAttr attr, GXCompCnt* cnt, GXCompType* type, u8* frac); +void GXGetVtxAttrFmtv(GXVtxFmt fmt, GXVtxAttrFmtList* vat); + +// Geometry +void GXGetLineWidth(u8* width, GXTexOffset* texOffsets); +void GXGetPointSize(u8* pointSize, GXTexOffset* texOffsets); +void GXGetCullMode(GXCullMode* mode); + +// Light +void GXGetLightAttnA(const GXLightObj* lt_obj, f32* a0, f32* a1, f32* a2); +void GXGetLightAttnK(const GXLightObj* lt_obj, f32* k0, f32* k1, f32* k2); +void GXGetLightPos(const GXLightObj* lt_obj, f32* x, f32* y, f32* z); +void GXGetLightDir(const GXLightObj* lt_obj, f32* nx, f32* ny, f32* nz); +void GXGetLightColor(const GXLightObj* lt_obj, GXColor* color); + +// Texture +GXBool GXGetTexObjMipMap(const GXTexObj* to); +GXTexFmt GXGetTexObjFmt(const GXTexObj* to); +u16 GXGetTexObjWidth(const GXTexObj* to); +u16 GXGetTexObjHeight(const GXTexObj* to); +GXTexWrapMode GXGetTexObjWrapS(const GXTexObj* to); +GXTexWrapMode GXGetTexObjWrapT(const GXTexObj* to); +void* GXGetTexObjData(const GXTexObj* to);; +void GXGetTexObjAll(const GXTexObj* obj, void** image_ptr, u16* width, u16* height, GXTexFmt* format, GXTexWrapMode* wrap_s, GXTexWrapMode* wrap_t, u8* mipmap); +void GXGetTexObjLODAll(const GXTexObj* tex_obj, GXTexFilter* min_filt, GXTexFilter* mag_filt, f32* min_lod, f32* max_lod, f32* lod_bias, u8* bias_clamp, u8* do_edge_lod, GXAnisotropy* max_aniso); +GXTexFilter GXGetTexObjMinFilt(const GXTexObj* tex_obj); +GXTexFilter GXGetTexObjMagFilt(const GXTexObj* tex_obj); +f32 GXGetTexObjMinLOD(const GXTexObj* tex_obj); +f32 GXGetTexObjMaxLOD(const GXTexObj* tex_obj); +f32 GXGetTexObjLODBias(const GXTexObj* tex_obj); +GXBool GXGetTexObjBiasClamp(const GXTexObj* tex_obj); +GXBool GXGetTexObjEdgeLOD(const GXTexObj* tex_obj); +GXAnisotropy GXGetTexObjMaxAniso(const GXTexObj* tex_obj); +u32 GXGetTexObjTlut(const GXTexObj* tex_obj); +void GXGetTlutObjAll(const GXTlutObj* tlut_obj, void** data, GXTlutFmt* format, u16* numEntries); +void* GXGetTlutObjData(const GXTlutObj* tlut_obj); +GXTlutFmt GXGetTlutObjFmt(const GXTlutObj* tlut_obj); +u16 GXGetTlutObjNumEntries(const GXTlutObj* tlut_obj); +void GXGetTexRegionAll(const GXTexRegion* region, u8* is_cached, u8* is_32b_mipmap, u32* tmem_even, u32* size_even, u32* tmem_odd, u32* size_odd); +void GXGetTlutRegionAll(const GXTlutRegion* region, u32* tmem_addr, GXTlutSize* tlut_size); + +// Transform +void GXGetProjectionv(f32* ptr); +void GXGetViewportv(f32* vp); +void GXGetScissor(u32* left, u32* top, u32* wd, u32* ht); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/gx/GXInit.h b/include/dolphin/gx/GXInit.h deleted file mode 100644 index d360345c1f..0000000000 --- a/include/dolphin/gx/GXInit.h +++ /dev/null @@ -1,187 +0,0 @@ -#ifndef GXINIT_H -#define GXINIT_H - -#include "dolphin/gx/GXTexture.h" - -typedef struct _GXData { - // Bypass and vertex info - u16 vNumNot; // _000, !(# flush verts to send) - u16 bpSentNot; // _002, !(bypass reg sent last?) - u16 vNum; // _004, # flush verts to send - u16 vLim; // _006, max vert size - - // Command process (CP) regs - u32 cpEnable; // _008 - u32 cpStatus; // _00C - u32 cpClr; // _010 - u32 vcdLo; // _014 - u32 vcdHi; // _018 - u32 vatA[8]; // _01C - u32 vatB[8]; // _03C - u32 vatC[8]; // _05C - u32 lpSize; // _07C - u32 matIdxA; // _080 - u32 matIdxB; // _084 - - // Index loading base/stride regs (pos, nrm, tex, light) - u32 indexBase[4]; // _088 - u32 indexStride[4]; // _098 - - // Transform and lighting regs - u32 ambColor[2]; // _0A8 - u32 matColor[2]; // _0B0 - - // Setup regs - u32 suTs0[8]; // _0B8 - u32 suTs1[8]; // _0D8 - u32 suScis0; // _0F8 - u32 suScis1; // _0FC - - // Raster regs - u32 tref[8]; // _100 - u32 iref; // _120 - - // Bump/Indirect texture regs - u32 bpMask; // _124 - u32 IndTexScale0; // _128 - u32 IndTexScale1; // _12C - - // Tev regs - u32 tevc[16]; // _130 - u32 teva[16]; // _170 - u32 tevKsel[8]; // _1B0 - - // Performance regs - u32 cmode0; // _1D0 - u32 cmode1; // _1D4 - u32 zmode; // _1D8 - u32 peCtrl; // _1DC - - // Display copy regs - u32 cpDispSrc; // _1E0 - u32 cpDispSize; // _1E4 - u32 cpDispStride; // _1E8 - u32 cpDisp; // _1EC - - // Texture copy regs - u32 cpTexSrc; // _1F0 - u32 cpTexSize; // _1F4 - u32 cpTexStride; // _1F8 - u32 cpTex; // _1FC - GXBool cpTexZ; // _200 - - // General raster mode - u32 genMode; // _204 - - // Texture regions - GXTexRegion TexRegions0[GX_MAX_TEXMAP]; // _208 - GXTexRegion TexRegions1[GX_MAX_TEXMAP]; // _288 - GXTexRegion TexRegions2[GX_MAX_TEXMAP]; // _308 - - // Texture lookup table regions - GXTlutRegion TlutRegions[GX_MAX_TLUT_ALL]; // _388 - GXTexRegionCallback texRegionCallback; // _4C8 - GXTlutRegionCallback tlutRegionCallback; // _4CC - - // Command processor vars - GXAttrType nrmType; // _4D0 - GXBool hasNrms; // _4D4 - GXBool hasBiNrms; // _4D5 - u32 projType; // _4D8 - f32 projMtx[6]; // _4DC - - // Viewport parms - f32 vpLeft; // _4F4 - f32 vpTop; // _4F8 - f32 vpWd; // _4FC - f32 vpHt; // _500 - f32 vpNearz; // _504 - f32 vpFarz; // _508 - f32 zOffset; // _50C - f32 zScale; // _510 - - // Texture regs - u32 tImage0[8]; // _514 - u32 tMode0[8]; // _534 - u32 texmapId[16]; // _554 - u32 tcsManEnab; // _594 - u32 tevTcEnab; // _598 - - // Performance metrics - GXPerf0 perf0; // _59C - GXPerf1 perf1; // _5A0 - u32 perfSel; // _5A4 - - // Flags - GXBool inDispList; // _5A8 - GXBool dlSaveContext; // _5A9 - GXBool abtWaitPECopy; // _5AA - u8 dirtyVAT; // _5AB - u32 dirtyState; // _5AC -} GXData; // Size: 0x5B0 - -STATIC_ASSERT(sizeof(GXData) == 0x5B0); - -extern GXData* const __GXData; - -// Define register addresses. -#define GX_CP_ADDR (0x0C000000) -#define GX_PE_ADDR (0x0C001000) -#define GX_PI_ADDR (0x0C003000) -#define GX_MEM_ADDR (0x0C004000) - -extern u32* __piReg; -extern u16* __cpReg; -extern u16* __peReg; -extern vu16* __memReg; - -#define GX_GET_MEM_REG(offset) (*(vu16*)((vu16*)(__memReg) + (offset))) -#define GX_GET_CP_REG(offset) (*(vu16*)((vu16*)(__cpReg) + (offset))) -#define GX_GET_PE_REG(offset) (*(vu16*)((vu16*)(__peReg) + (offset))) -#define GX_GET_PI_REG(offset) (*(vu32*)((vu32*)(__piReg) + (offset))) - -#define GX_SET_MEM_REG(offset, val) (*(vu16*)((vu16*)(__memReg) + (offset)) = val) -#define GX_SET_CP_REG(offset, val) (*(vu16*)((vu16*)(__cpReg) + (offset)) = val) -#define GX_SET_PE_REG(offset, val) (*(vu16*)((vu16*)(__peReg) + (offset)) = val) -#define GX_SET_PI_REG(offset, val) (*(vu32*)((vu32*)(__piReg) + (offset)) = val) - -inline void GXSetWasteFlags() { - GXData* data = __GXData; - data->dirtyState |= GX_DIRTY_SU_TEX | GX_DIRTY_BP_MASK; - data->bpSentNot = 0; -} - -static inline void set_x2(u16 value) -{ - __GXData->bpSentNot = value; -} - -#ifdef __cplusplus -extern "C" { -#endif - -static inline u32 GXReadMEMReg(u32 addrLo, u32 addrHi) -{ - u32 hiStart, hiNew, lo; - hiStart = GX_GET_MEM_REG(addrHi); - do { - hiNew = hiStart; - lo = GX_GET_MEM_REG(addrLo); - hiStart = GX_GET_MEM_REG(addrHi); - } while (hiStart != hiNew); - - return ((hiStart << 16) | lo); -} - -GXTexRegion* __GXDefaultTexRegionCallback(const GXTexObj* obj, GXTexMapID mapID); -GXTlutRegion* __GXDefaultTlutRegionCallback(u32 tlut); -BOOL __GXShutdown(BOOL); -void __GXInitRevisionBits(void); -GXFifoObj* GXInit(void* base, u32 size); -void __GXInitGX(void); - -#ifdef __cplusplus -}; -#endif - -#endif /* GXINIT_H */ diff --git a/include/dolphin/gx/GXLight.h b/include/dolphin/gx/GXLight.h deleted file mode 100644 index 4e04aad1d2..0000000000 --- a/include/dolphin/gx/GXLight.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef GXLIGHT_H -#define GXLIGHT_H - -#include "dolphin/gx/GXStruct.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void GXInitLightAttn(GXLightObj* obj, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2); -void GXInitLightSpot(GXLightObj* obj, f32 cutoff, GXSpotFn spot_fn); -void GXInitLightDistAttn(GXLightObj* obj, f32 dist, f32 brightness, GXDistAttnFn dist_fn); -void GXInitLightPos(GXLightObj* obj, f32 x, f32 y, f32 z); -void GXInitLightDir(GXLightObj* obj, f32 x, f32 y, f32 z); -void GXInitLightColor(GXLightObj* obj, GXColor color); -void GXLoadLightObjImm(GXLightObj* obj, GXLightID light); -void GXSetChanAmbColor(GXChannelID channel, GXColor color); -void GXSetChanMatColor(GXChannelID channel, GXColor color); -void GXSetNumChans(u8 chan_num); -void GXSetChanCtrl(GXChannelID channel, GXBool enable, GXColorSrc amb_src, GXColorSrc mat_src, u32 light_mask, GXDiffuseFn diff_fn, GXAttnFn attn_fn); - -#ifdef __cplusplus -}; -#endif - -#endif /* GXLIGHT_H */ diff --git a/include/dolphin/gx/GXLighting.h b/include/dolphin/gx/GXLighting.h new file mode 100644 index 0000000000..83c5aae423 --- /dev/null +++ b/include/dolphin/gx/GXLighting.h @@ -0,0 +1,32 @@ +#ifndef _DOLPHIN_GX_GXLIGHTING_H_ +#define _DOLPHIN_GX_GXLIGHTING_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void GXInitLightAttn(GXLightObj* lt_obj, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2); +void GXInitLightAttnA(GXLightObj* lt_obj, f32 a0, f32 a1, f32 a2); +void GXInitLightAttnK(GXLightObj* lt_obj, f32 k0, f32 k1, f32 k2); +void GXInitLightSpot(GXLightObj* lt_obj, f32 cutoff, GXSpotFn spot_func); +void GXInitLightDistAttn(GXLightObj* lt_obj, f32 ref_dist, f32 ref_br, GXDistAttnFn dist_func); +void GXInitLightPos(GXLightObj* lt_obj, f32 x, f32 y, f32 z); +void GXInitLightDir(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz); +void GXInitSpecularDir(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz); +void GXInitSpecularDirHA(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz, f32 hx, f32 hy, f32 hz); +void GXInitLightColor(GXLightObj* lt_obj, GXColor color); +void GXLoadLightObjImm(const GXLightObj* lt_obj, GXLightID light); +void GXLoadLightObjIndx(u32 lt_obj_indx, GXLightID light); +void GXSetChanAmbColor(GXChannelID chan, GXColor amb_color); +void GXSetChanMatColor(GXChannelID chan, GXColor mat_color); +void GXSetNumChans(u8 nChans); +void GXSetChanCtrl(GXChannelID chan, GXBool enable, GXColorSrc amb_src, GXColorSrc mat_src, u32 light_mask, GXDiffuseFn diff_fn, GXAttnFn attn_fn); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/gx/GXManage.h b/include/dolphin/gx/GXManage.h new file mode 100644 index 0000000000..fd899d3619 --- /dev/null +++ b/include/dolphin/gx/GXManage.h @@ -0,0 +1,36 @@ +#ifndef _DOLPHIN_GX_GXMANAGE_H_ +#define _DOLPHIN_GX_GXMANAGE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*GXDrawSyncCallback)(u16 token); +typedef void (*GXDrawDoneCallback)(void); + +// Init +BOOL IsWriteGatherBufferEmpty(void); +GXFifoObj* GXInit(void* base, u32 size); + +// Misc +void GXSetMisc(GXMiscToken token, u32 val); +void GXFlush(void); +void GXResetWriteGatherPipe(void); +void GXAbortFrame(void); +void GXSetDrawSync(u16 token); +u16 GXReadDrawSync(void); +void GXSetDrawDone(void); +void GXWaitDrawDone(void); +void GXDrawDone(void); +void GXPixModeSync(void); +void GXTexModeSync(void); +GXDrawSyncCallback GXSetDrawSyncCallback(GXDrawSyncCallback cb); +GXDrawDoneCallback GXSetDrawDoneCallback(GXDrawDoneCallback cb); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/gx/GXMisc.h b/include/dolphin/gx/GXMisc.h deleted file mode 100644 index 21b3aa0967..0000000000 --- a/include/dolphin/gx/GXMisc.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef GXMISC_H -#define GXMISC_H - -#include "dolphin/gx/GXEnum.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void GXSetMisc(GXMiscToken token, u32 val); -void GXFlush(void); -void __GXAbort(void); -void GXAbortFrame(void); -void GXSetDrawDone(void); -void GXDrawDone(void); -void GXPixModeSync(void); -void GXPokeAlphaMode(GXCompare comp, u8 threshold); -void GXPokeAlphaRead(GXAlphaReadMode mode); -void GXPokeAlphaUpdate(GXBool enable_update); -void GXPokeBlendMode(GXBlendMode mode, GXBlendFactor src_factor, GXBlendFactor dst_factor, GXLogicOp op); -void GXPokeColorUpdate(GXBool enable_update); -void GXPokeDstAlpha(GXBool enable, u8 alpha); -void GXPokeDither(GXBool enable); -void GXPokeZMode(GXBool enable_compare, GXCompare comp, GXBool update_enable); -void GXPeekZ(u16 x, u16 y, u32* z); - -typedef void (*GXDrawSyncCallback)(u16 token); -GXDrawSyncCallback GXSetDrawSyncCallback(GXDrawSyncCallback callback); - -typedef void (*GXDrawDoneCallback)(void); -GXDrawDoneCallback GXSetDrawDoneCallback(GXDrawDoneCallback callback); -void __GXPEInit(void); - -#ifdef __cplusplus -}; -#endif - -#endif /* GXMISC_H */ diff --git a/include/dolphin/gx/GXPerf.h b/include/dolphin/gx/GXPerf.h index 3edd9ea4f8..bd1b474aa8 100644 --- a/include/dolphin/gx/GXPerf.h +++ b/include/dolphin/gx/GXPerf.h @@ -1,18 +1,30 @@ -#ifndef GXPERF_H -#define GXPERF_H +#ifndef _DOLPHIN_GX_GXPERF_H_ +#define _DOLPHIN_GX_GXPERF_H_ -#include "dolphin/gx/GXEnum.h" +#include #ifdef __cplusplus extern "C" { #endif void GXSetGPMetric(GXPerf0 perf0, GXPerf1 perf1); +void GXReadGPMetric(u32* cnt0, u32* cnt1); void GXClearGPMetric(void); -void GXReadXfRasMetric(u32*, u32*, u32*, u32*); +u32 GXReadGP0Metric(void); +u32 GXReadGP1Metric(void); +void GXReadMemMetric(u32* cp_req, u32* tc_req, u32* cpu_rd_req, u32* cpu_wr_req, u32* dsp_req, u32* io_req, u32* vi_req, u32* pe_req, u32* rf_req, u32* fi_req); +void GXClearMemMetric(void); +void GXReadPixMetric(u32* top_pixels_in, u32* top_pixels_out, u32* bot_pixels_in, u32* bot_pixels_out, u32* clr_pixels_in, u32* copy_clks); +void GXClearPixMetric(void); +void GXSetVCacheMetric(GXVCachePerf attr); +void GXReadVCacheMetric(u32* check, u32* miss, u32* stall); +void GXClearVCacheMetric(void); +void GXInitXfRasMetric(void); +void GXReadXfRasMetric(u32* xf_wait_in, u32* xf_wait_out, u32* ras_busy, u32* clocks); +u32 GXReadClksPerVtx(void); #ifdef __cplusplus -}; +} #endif -#endif /* GXPERF_H */ +#endif diff --git a/include/dolphin/gx/GXPixel.h b/include/dolphin/gx/GXPixel.h index 3b0571f22f..d61838d1a9 100644 --- a/include/dolphin/gx/GXPixel.h +++ b/include/dolphin/gx/GXPixel.h @@ -1,27 +1,30 @@ -#ifndef GXPIXEL_H -#define GXPIXEL_H +#ifndef _DOLPHIN_GX_GXPIXEL_H_ +#define _DOLPHIN_GX_GXPIXEL_H_ -#include "dolphin/gx/GXStruct.h" +#include +#include #ifdef __cplusplus extern "C" { #endif -void GXSetFog(GXFogType type, f32 startZ, f32 endZ, f32 nearZ, f32 farZ, GXColor color); -void GXSetFogRangeAdj(GXBool enable, u16 center, GXFogAdjTable* table); -void GXSetBlendMode(GXBlendMode mode, GXBlendFactor src_factor, GXBlendFactor dst_factor, GXLogicOp op); -void GXSetColorUpdate(GXBool enable_update); -void GXSetAlphaUpdate(GXBool enable_update); -void GXSetZMode(GXBool enable_compare, GXCompare comp, GXBool enable_update); -void GXSetZCompLoc(GXBool z_buf_before_tex); -void GXSetPixelFmt(GXPixelFmt pixel_fmt, GXZFmt16 z_fmt); -void GXSetDither(GXBool enable_dither); +void GXSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color); +void GXInitFogAdjTable(GXFogAdjTable* table, u16 width, const f32 projmtx[4][4]); +void GXSetFogRangeAdj(GXBool enable, u16 center, const GXFogAdjTable* table); +void GXSetBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor, GXLogicOp op); +void GXSetColorUpdate(GXBool update_enable); +void GXSetAlphaUpdate(GXBool update_enable); +void GXSetZMode(GXBool compare_enable, GXCompare func, GXBool update_enable); +void GXSetZCompLoc(GXBool before_tex); +void GXSetPixelFmt(GXPixelFmt pix_fmt, GXZFmt16 z_fmt); +void GXSetDither(GXBool dither); void GXSetDstAlpha(GXBool enable, u8 alpha); void GXSetFieldMask(GXBool odd_mask, GXBool even_mask); void GXSetFieldMode(GXBool field_mode, GXBool half_aspect_ratio); +void GXSetFogColor(GXColor color); #ifdef __cplusplus -}; +} #endif -#endif /* GXPIXEL_H */ +#endif diff --git a/include/dolphin/gx/GXStruct.h b/include/dolphin/gx/GXStruct.h index 9672145963..0e7dc0be69 100644 --- a/include/dolphin/gx/GXStruct.h +++ b/include/dolphin/gx/GXStruct.h @@ -1,108 +1,75 @@ -#ifndef GXSTRUCT_H -#define GXSTRUCT_H +#ifndef _DOLPHIN_GX_GXSTRUCT_H_ +#define _DOLPHIN_GX_GXSTRUCT_H_ -#include "global.h" -#include "dolphin/gx/GXEnum.h" -#include "dolphin/vi.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _GXRenderModeObj { + /* 0x00 */ VITVMode viTVmode; + /* 0x04 */ u16 fbWidth; + /* 0x06 */ u16 efbHeight; + /* 0x08 */ u16 xfbHeight; + /* 0x0A */ u16 viXOrigin; + /* 0x0C */ u16 viYOrigin; + /* 0x0E */ u16 viWidth; + /* 0x10 */ u16 viHeight; + /* 0x14 */ VIXFBMode xFBmode; + /* 0x18 */ u8 field_rendering; + /* 0x19 */ u8 aa; + /* 0x20 */ u8 sample_pattern[12][2]; + /* 0x38 */ u8 vfilter[7]; +} GXRenderModeObj; typedef struct _GXColor { - /* 0x0 */ u8 r; - /* 0x1 */ u8 g; - /* 0x2 */ u8 b; - /* 0x3 */ u8 a; + u8 r, g, b, a; } GXColor; typedef struct _GXColorS10 { - /* 0x0 */ s16 r; - /* 0x2 */ s16 g; - /* 0x4 */ s16 b; - /* 0x6 */ s16 a; + s16 r, g, b, a; } GXColorS10; -typedef struct _GXRenderModeObj { - /* 0x00 */ VITVMode vi_tv_mode; - /* 0x04 */ u16 fb_width; - /* 0x06 */ u16 efb_height; - /* 0x08 */ u16 xfb_height; - /* 0x0A */ u16 vi_x_origin; - /* 0x0C */ u16 vi_y_origin; - /* 0x0E */ u16 vi_width; - /* 0x10 */ u16 vi_height; - /* 0x14 */ VIXFBMode xfb_mode; - /* 0x18 */ u8 field_rendering; - /* 0x19 */ u8 antialiasing; - /* 0x1A */ u8 sample_pattern[12][2]; - /* 0x32 */ u8 vfilter[7]; -} GXRenderModeObj; - -STATIC_ASSERT(sizeof(GXRenderModeObj) == 60); - typedef struct _GXTexObj { - /* 0x00 */ u32 texture_filter; - /* 0x04 */ u32 texture_lod; - /* 0x08 */ u32 texture_size; - /* 0x0C */ u32 texture_address; - /* 0x10 */ u32 user_data; - /* 0x14 */ u32 texture_format; - /* 0x18 */ u32 tlut_name; - /* 0x1C */ u16 texture_time_count; - /* 0x1E */ u8 texture_tile_type; - /* 0x1F */ u8 texture_flags; + u32 dummy[8]; } GXTexObj; -typedef struct _GXTlutObj { - /* 0x0 */ u32 format; - /* 0x4 */ u32 address; - /* 0x8 */ u16 numEntries; -} GXTlutObj; - typedef struct _GXLightObj { - /* 0x00 */ u8 field_0x0[0xc]; - /* 0x0C */ GXColor color; - /* 0x10 */ f32 a0; - /* 0x14 */ f32 a1; - /* 0x18 */ f32 a2; - /* 0x1C */ f32 k0; - /* 0x20 */ f32 k1; - /* 0x24 */ f32 k2; - /* 0x28 */ f32 posX; - /* 0x2C */ f32 posY; - /* 0x30 */ f32 posZ; - /* 0x34 */ f32 dirX; - /* 0x38 */ f32 dirY; - /* 0x3C */ f32 dirZ; + u32 dummy[16]; } GXLightObj; -typedef struct _GXFogAdjTable { - /* 0x0 */ u16 fogVals[10]; -} GXFogAdjTable; - -typedef struct _GXFifoObj { - /* 0x00 */ void* base; - /* 0x04 */ void* end; - /* 0x08 */ u32 size; - /* 0x0C */ u32 high_wtrmark; - /* 0x10 */ u32 low_wtrmark; - /* 0x14 */ void* read_ptr; - /* 0x18 */ void* write_ptr; - /* 0x1C */ s32 rw_dst; - /* 0x20 */ u8 fifo_wrap; - /* 0x21 */ u8 cpu_fifo_ready; - /* 0x22 */ u8 gp_fifo_ready; - /* 0x23 */ u8 field_0x23[93]; -} GXFifoObj; // Size: 0x80 - typedef struct _GXTexRegion { - u32 unk0; // _00 - u32 unk4; // _04 - u32 unk8; // _08 - u8 unkC; // _0C - u8 unkD; // _0D -} GXTexRegion; // Size: 0x10 + u32 dummy[4]; +} GXTexRegion; + +typedef struct _GXTlutObj { + u32 dummy[3]; +} GXTlutObj; typedef struct _GXTlutRegion { - /* 0x00 */ u32 unk0; - /* 0x04 */ GXTlutObj tlutObj; -} GXTlutRegion; // Size: 0x10 + u32 dummy[4]; +} GXTlutRegion; -#endif /* GXSTRUCT_H */ +typedef struct _GXFogAdjTable { + u16 r[10]; +} GXFogAdjTable; + +typedef struct _GXVtxDescList { + GXAttr attr; + GXAttrType type; +} GXVtxDescList; + +typedef struct _GXVtxAttrFmtList { + GXAttr attr; + GXCompCnt cnt; + GXCompType type; + u8 frac; +} GXVtxAttrFmtList; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/gx/GXTev.h b/include/dolphin/gx/GXTev.h index 5d8b63d7d2..8deb22d083 100644 --- a/include/dolphin/gx/GXTev.h +++ b/include/dolphin/gx/GXTev.h @@ -1,36 +1,33 @@ -#ifndef GXTEV_H -#define GXTEV_H +#ifndef _DOLPHIN_GX_GXTEV_H_ +#define _DOLPHIN_GX_GXTEV_H_ -#include "dolphin/gx/GXStruct.h" +#include +#include #ifdef __cplusplus extern "C" { #endif void GXSetTevOp(GXTevStageID id, GXTevMode mode); -void GXSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, - GXTevColorArg d); -void GXSetTevAlphaIn(GXTevStageID stage, GXTevAlphaArg a, GXTevAlphaArg b, GXTevAlphaArg c, - GXTevAlphaArg d); -void GXSetTevColorOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, - GXTevRegID out_reg); -void GXSetTevAlphaOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, - GXTevRegID out_reg); +void GXSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, GXTevColorArg d); +void GXSetTevAlphaIn(GXTevStageID stage, GXTevAlphaArg a, GXTevAlphaArg b, GXTevAlphaArg c, GXTevAlphaArg d); +void GXSetTevColorOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, GXTevRegID out_reg); +void GXSetTevAlphaOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, GXTevRegID out_reg); void GXSetTevColor(GXTevRegID id, GXColor color); void GXSetTevColorS10(GXTevRegID id, GXColorS10 color); void GXSetTevKColor(GXTevKColorID id, GXColor color); -void GXSetTevKColorSel(GXTevStageID stage, GXTevKColorSel color_sel); -void GXSetTevKAlphaSel(GXTevStageID stage, GXTevKAlphaSel alpha_sel); +void GXSetTevKColorSel(GXTevStageID stage, GXTevKColorSel sel); +void GXSetTevKAlphaSel(GXTevStageID stage, GXTevKAlphaSel sel); void GXSetTevSwapMode(GXTevStageID stage, GXTevSwapSel ras_sel, GXTevSwapSel tex_sel); -void GXSetTevSwapModeTable(GXTevSwapSel select, GXTevColor r, GXTevColor g, GXTevColor b, - GXTevColor a); +void GXSetTevSwapModeTable(GXTevSwapSel table, GXTevColorChan red, GXTevColorChan green, GXTevColorChan blue, GXTevColorChan alpha); +void GXSetTevClampMode(void); void GXSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1); void GXSetZTexture(GXZTexOp op, GXTexFmt fmt, u32 bias); void GXSetTevOrder(GXTevStageID stage, GXTexCoordID coord, GXTexMapID map, GXChannelID color); -void GXSetNumTevStages(u8 num_stages); +void GXSetNumTevStages(u8 nStages); #ifdef __cplusplus -}; +} #endif -#endif /* GXTEV_H */ +#endif diff --git a/include/dolphin/gx/GXTexture.h b/include/dolphin/gx/GXTexture.h index 709c3ed20b..f42dc2295a 100644 --- a/include/dolphin/gx/GXTexture.h +++ b/include/dolphin/gx/GXTexture.h @@ -1,50 +1,52 @@ -#ifndef GXTEXTURE_H -#define GXTEXTURE_H +#ifndef _DOLPHIN_GX_GXTEXTURE_H_ +#define _DOLPHIN_GX_GXTEXTURE_H_ -#include "dolphin/gx/GXStruct.h" +#include +#include #ifdef __cplusplus extern "C" { #endif -typedef GXTexRegion* (*GXTexRegionCallback)(const GXTexObj* t_obj, GXTexMapID id); -typedef GXTlutRegion* (*GXTlutRegionCallback)(u32 idx); +typedef GXTexRegion *(*GXTexRegionCallback)(GXTexObj* t_obj, GXTexMapID id); +typedef GXTlutRegion *(*GXTlutRegionCallback)(u32 idx); -u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, GXBool mipmap, u8 max_lod); -void __GetImageTileCount(GXTexFmt format, u16 width, u16 height, u32* a, u32* b, u32* c); -void GXInitTexObj(GXTexObj* obj, void* image, u16 width, u16 height, GXTexFmt fmt, - GXTexWrapMode wrapS, GXTexWrapMode wrapT, GXBool mipmap); -void GXInitTexObjCI(GXTexObj* obj, void* image, u16 width, u16 height, GXCITexFmt format, - GXTexWrapMode wrapS, GXTexWrapMode wrapT, GXBool mipmap, u32 tlut_name); -void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter min_filter, GXTexFilter max_filter, f32 min_lod, - f32 max_lod, f32 lod_bias, GXBool bias_clamp, GXBool edge_lod, - GXAnisotropy aniso); -u16 GXGetTexObjWidth(GXTexObj* obj); -u16 GXGetTexObjHeight(GXTexObj* obj); -GXTexFmt GXGetTexObjFmt(const GXTexObj* obj); -GXTexWrapMode GXGetTexObjWrapS(GXTexObj* obj); -GXTexWrapMode GXGetTexObjWrapT(GXTexObj* obj); -GXBool GXGetTexObjMipMap(const GXTexObj* obj); -u32 GXGetTexObjTlut(GXTexObj* obj); +u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, u8 mipmap, u8 max_lod); +void GXInitTexObj(GXTexObj* obj, void* image_ptr, u16 width, u16 height, GXTexFmt format, GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, u8 mipmap); +void GXInitTexObjCI(GXTexObj* obj, void* image_ptr, u16 width, u16 height, GXCITexFmt format, GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, u8 mipmap, u32 tlut_name); +void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter min_filt, GXTexFilter mag_filt, + f32 min_lod, f32 max_lod, f32 lod_bias, GXBool bias_clamp, + GXBool do_edge_lod, GXAnisotropy max_aniso); +void GXInitTexObjData(GXTexObj* obj, void* image_ptr); +void GXInitTexObjWrapMode(GXTexObj* obj, GXTexWrapMode s, GXTexWrapMode t); +void GXInitTexObjTlut(GXTexObj* obj, u32 tlut_name); +void GXInitTexObjUserData(GXTexObj* obj, void* user_data); +void* GXGetTexObjUserData(const GXTexObj* obj); +void GXLoadTexObjPreLoaded(GXTexObj* obj, GXTexRegion* region, GXTexMapID id); void GXLoadTexObj(GXTexObj* obj, GXTexMapID id); -void GXInitTlutObj(GXTlutObj* obj, void* lut, GXTlutFmt fmt, u16 entry_num); -void GXLoadTlut(GXTlutObj* obj, u32 tlut_name); -void GXInitTexCacheRegion(GXTexRegion* region, GXBool is_32b_mipmap, u32 tmem_even, - GXTexCacheSize size_even, u32 tmem_odd, GXTexCacheSize size_odd); +void GXInitTlutObj(GXTlutObj* tlut_obj, void* lut, GXTlutFmt fmt, u16 n_entries); +void GXLoadTlut(GXTlutObj* tlut_obj, u32 tlut_name); +void GXInitTexCacheRegion(GXTexRegion* region, u8 is_32b_mipmap, u32 tmem_even, GXTexCacheSize size_even, u32 tmem_odd, GXTexCacheSize size_odd); +void GXInitTexPreLoadRegion(GXTexRegion* region, u32 tmem_even, u32 size_even, u32 tmem_odd, u32 size_odd); void GXInitTlutRegion(GXTlutRegion* region, u32 tmem_addr, GXTlutSize tlut_size); +void GXInvalidateTexRegion(GXTexRegion* region); void GXInvalidateTexAll(void); - -GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback callback); -GXTlutRegionCallback GXSetTlutRegionCallback(GXTlutRegionCallback callback); - -void GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 s_scale, u16 t_scale); - -void __SetSURegs(); -void __GXSetSUTexRegs(); -void __GXSetTmemConfig(); +GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback f); +GXTlutRegionCallback GXSetTlutRegionCallback(GXTlutRegionCallback f); +void GXPreLoadEntireTexture(GXTexObj* tex_obj, GXTexRegion* region); +void GXSetTexCoordScaleManually(GXTexCoordID coord, u8 enable, u16 ss, u16 ts); +void GXSetTexCoordCylWrap(GXTexCoordID coord, u8 s_enable, u8 t_enable); +void GXSetTexCoordBias(GXTexCoordID coord, u8 s_enable, u8 t_enable); +void GXInitTexObjFilter(GXTexObj* obj, GXTexFilter min_filt, GXTexFilter mag_filt); +void GXInitTexObjMaxLOD(GXTexObj* obj, f32 max_lod); +void GXInitTexObjMinLOD(GXTexObj* obj, f32 min_lod); +void GXInitTexObjLODBias(GXTexObj* obj, f32 lod_bias); +void GXInitTexObjBiasClamp(GXTexObj* obj, u8 bias_clamp); +void GXInitTexObjEdgeLOD(GXTexObj* obj, u8 do_edge_lod); +void GXInitTexObjMaxAniso(GXTexObj* obj, GXAnisotropy max_aniso); #ifdef __cplusplus -}; +} #endif -#endif /* GXTEXTURE_H */ +#endif diff --git a/include/dolphin/gx/GXTransform.h b/include/dolphin/gx/GXTransform.h index d97a9468ee..1e7f94e579 100644 --- a/include/dolphin/gx/GXTransform.h +++ b/include/dolphin/gx/GXTransform.h @@ -1,31 +1,34 @@ -#ifndef GXTRANSFORM_H -#define GXTRANSFORM_H +#ifndef _DOLPHIN_GX_GXTRANSFORM_H_ +#define _DOLPHIN_GX_GXTRANSFORM_H_ -#include "dolphin/gx/GXEnum.h" -#include "dolphin/mtx.h" +#include #ifdef __cplusplus extern "C" { #endif -void GXProject(f32 model_x, f32 model_y, f32 model_z, Mtx model_mtx, f32* proj_mtx, f32* viewpoint, - f32* screen_x, f32* screen_y, f32* screen_z); -void GXSetProjection(const Mtx44 proj, GXProjectionType type); -void GXSetProjectionv(f32* p); -void GXGetProjectionv(f32* p); -void GXLoadPosMtxImm(Mtx mtx, u32 id); -void GXLoadNrmMtxImm(Mtx mtx, u32 id); +#define GX_PROJECTION_SZ 7 +#define GX_VIEWPORT_SZ 6 + +void GXProject(f32 x, f32 y, f32 z, const f32 mtx[3][4], const f32* pm, const f32* vp, f32* sx, f32* sy, f32* sz); +void GXSetProjection(const f32 mtx[4][4], GXProjectionType type); +void GXSetProjectionv(const f32* ptr); +void GXLoadPosMtxImm(const f32 mtx[3][4], u32 id); +void GXLoadPosMtxIndx(u16 mtx_indx, u32 id); +void GXLoadNrmMtxImm(const f32 mtx[3][4], u32 id); +void GXLoadNrmMtxImm3x3(const f32 mtx[3][3], u32 id); +void GXLoadNrmMtxIndx3x3(u16 mtx_indx, u32 id); void GXSetCurrentMtx(u32 id); -void GXLoadTexMtxImm(const Mtx mtx, u32 id, GXTexMtxType type); -void GXSetViewport(f32 x_orig, f32 y_orig, f32 width, f32 height, f32 near_z, f32 far_z); -void GXGetViewportv(f32* p); -void GXSetScissor(u32 left, u32 top, u32 width, u32 height); -void GXGetScissor(u32* left, u32* top, u32* width, u32* height); -void GXSetScissorBoxOffset(s32 x_offset, s32 y_offset); +void GXLoadTexMtxImm(const f32 mtx[][4], u32 id, GXTexMtxType type); +void GXLoadTexMtxIndx(u16 mtx_indx, u32 id, GXTexMtxType type); +void GXSetViewportJitter(f32 left, f32 top, f32 wd, f32 ht, f32 nearz, f32 farz, u32 field); +void GXSetViewport(f32 left, f32 top, f32 wd, f32 ht, f32 nearz, f32 farz); +void GXSetScissorBoxOffset(s32 x_off, s32 y_off); void GXSetClipMode(GXClipMode mode); +void GXSetZScaleOffset(f32 scale, f32 offset); #ifdef __cplusplus -}; +} #endif -#endif /* GXTRANSFORM_H */ +#endif diff --git a/include/dolphin/gx/GXVerify.h b/include/dolphin/gx/GXVerify.h new file mode 100644 index 0000000000..93a1b29e58 --- /dev/null +++ b/include/dolphin/gx/GXVerify.h @@ -0,0 +1,29 @@ +#ifndef _DOLPHIN_GX_GXVERIFY_H_ +#define _DOLPHIN_GX_GXVERIFY_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + GX_WARN_NONE, + GX_WARN_SEVERE, + GX_WARN_MEDIUM, + GX_WARN_ALL +} GXWarningLevel; + +typedef void (*GXVerifyCallback)(GXWarningLevel level, u32 id, char* msg); + +void GXSetVerifyLevel(GXWarningLevel level); +GXVerifyCallback GXSetVerifyCallback(GXVerifyCallback cb); + +void __GXVerifyVATImm(GXAttr attr, GXCompCnt cnt, GXCompType type, u8 frac); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/gx/GXVert.h b/include/dolphin/gx/GXVert.h new file mode 100644 index 0000000000..91b7d7cc0b --- /dev/null +++ b/include/dolphin/gx/GXVert.h @@ -0,0 +1,140 @@ +#ifndef _DOLPHIN_GX_GXVERT_H_ +#define _DOLPHIN_GX_GXVERT_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define GXFIFO_ADDR 0xCC008000 + +typedef union { + u8 u8; + u16 u16; + u32 u32; + u64 u64; + s8 s8; + s16 s16; + s32 s32; + s64 s64; + f32 f32; + f64 f64; +} PPCWGPipe; + +#ifdef __MWERKS__ +volatile PPCWGPipe GXWGFifo AT_ADDRESS(GXFIFO_ADDR); +#else +#define GXWGFifo (*(volatile PPCWGPipe *)GXFIFO_ADDR) +#endif + +#if DEBUG + +// external functions + +#define FUNC_1PARAM(name, T) void name##1##T(const T x); +#define FUNC_2PARAM(name, T) void name##2##T(const T x, const T y); +#define FUNC_3PARAM(name, T) void name##3##T(const T x, const T y, const T z); +#define FUNC_4PARAM(name, T) void name##4##T(const T x, const T y, const T z, const T w); +#define FUNC_INDEX8(name) void name##1x8(const u8 x); +#define FUNC_INDEX16(name) void name##1x16(const u16 x); + +#else + +// inline functions + +#define FUNC_1PARAM(name, T) \ +static inline void name##1##T(const T x) { GXWGFifo.T = x; } + +#define FUNC_2PARAM(name, T) \ +static inline void name##2##T(const T x, const T y) { GXWGFifo.T = x; GXWGFifo.T = y; } + +#define FUNC_3PARAM(name, T) \ +static inline void name##3##T(const T x, const T y, const T z) { GXWGFifo.T = x; GXWGFifo.T = y; GXWGFifo.T = z; } + +#define FUNC_4PARAM(name, T) \ +static inline void name##4##T(const T x, const T y, const T z, const T w) { GXWGFifo.T = x; GXWGFifo.T = y; GXWGFifo.T = z; GXWGFifo.T = w; } + +#define FUNC_INDEX8(name) \ +static inline void name##1x8(const u8 x) { GXWGFifo.u8 = x; } + +#define FUNC_INDEX16(name) \ +static inline void name##1x16(const u16 x) { GXWGFifo.u16 = x; } + +#endif + +// GXCmd +FUNC_1PARAM(GXCmd, u8) +FUNC_1PARAM(GXCmd, u16) +FUNC_1PARAM(GXCmd, u32) + +// GXParam +FUNC_1PARAM(GXParam, u8) +FUNC_1PARAM(GXParam, u16) +FUNC_1PARAM(GXParam, u32) +FUNC_1PARAM(GXParam, s8) +FUNC_1PARAM(GXParam, s16) +FUNC_1PARAM(GXParam, s32) +FUNC_1PARAM(GXParam, f32) +FUNC_3PARAM(GXParam, f32) +FUNC_4PARAM(GXParam, f32) + +// GXPosition +FUNC_3PARAM(GXPosition, f32) +FUNC_3PARAM(GXPosition, u8) +FUNC_3PARAM(GXPosition, s8) +FUNC_3PARAM(GXPosition, u16) +FUNC_3PARAM(GXPosition, s16) +FUNC_2PARAM(GXPosition, f32) +FUNC_2PARAM(GXPosition, u8) +FUNC_2PARAM(GXPosition, s8) +FUNC_2PARAM(GXPosition, u16) +FUNC_2PARAM(GXPosition, s16) +FUNC_INDEX16(GXPosition) +FUNC_INDEX8(GXPosition) + +// GXNormal +FUNC_3PARAM(GXNormal, f32) +FUNC_3PARAM(GXNormal, s16) +FUNC_3PARAM(GXNormal, s8) +FUNC_INDEX16(GXNormal) +FUNC_INDEX8(GXNormal) + +// GXColor +FUNC_4PARAM(GXColor, u8) +FUNC_1PARAM(GXColor, u32) +FUNC_3PARAM(GXColor, u8) +FUNC_1PARAM(GXColor, u16) +FUNC_INDEX16(GXColor) +FUNC_INDEX8(GXColor) + +// GXTexCoord +FUNC_2PARAM(GXTexCoord, f32) +FUNC_2PARAM(GXTexCoord, s16) +FUNC_2PARAM(GXTexCoord, u16) +FUNC_2PARAM(GXTexCoord, s8) +FUNC_2PARAM(GXTexCoord, u8) +FUNC_1PARAM(GXTexCoord, f32) +FUNC_1PARAM(GXTexCoord, s16) +FUNC_1PARAM(GXTexCoord, u16) +FUNC_1PARAM(GXTexCoord, s8) +FUNC_1PARAM(GXTexCoord, u8) +FUNC_INDEX16(GXTexCoord) +FUNC_INDEX8(GXTexCoord) + +// GXMatrixIndex +FUNC_1PARAM(GXMatrixIndex, u8) + +#undef FUNC_1PARAM +#undef FUNC_2PARAM +#undef FUNC_3PARAM +#undef FUNC_4PARAM +#undef FUNC_INDEX8 +#undef FUNC_INDEX16 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/hio.h b/include/dolphin/hio.h new file mode 100644 index 0000000000..dc83ee19a9 --- /dev/null +++ b/include/dolphin/hio.h @@ -0,0 +1,28 @@ +#ifndef _DOLPHIN_HIO_H_ +#define _DOLPHIN_HIO_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*HIOCallback)(void); +typedef BOOL (*HIOEnumCallback)(s32 chan); + +BOOL HIOEnumDevices(HIOEnumCallback callback); +BOOL HIOInit(s32 chan, HIOCallback callback); +BOOL HIOInitEx(s32 chan, u32 dev, HIOCallback callback); +BOOL HIOReadMailbox(u32* word); +BOOL HIOWriteMailbox(u32 word); +BOOL HIORead(u32 addr, void* buffer, s32 size); +BOOL HIOWrite(u32 addr, void* buffer, s32 size); +BOOL HIOReadAsync(u32 addr, void* buffer, s32 size, HIOCallback callback); +BOOL HIOWriteAsync(u32 addr, void* buffer, s32 size, HIOCallback callback); +BOOL HIOReadStatus(u32* status); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/hw_regs.h b/include/dolphin/hw_regs.h new file mode 100644 index 0000000000..1f5700a162 --- /dev/null +++ b/include/dolphin/hw_regs.h @@ -0,0 +1,116 @@ +#ifndef _DOLPHIN_HW_REGS_H_ +#define _DOLPHIN_HW_REGS_H_ + +#include + +#ifdef __MWERKS__ +volatile u16 __VIRegs[59] AT_ADDRESS(0xCC002000); +volatile u32 __PIRegs[12] AT_ADDRESS(0xCC003000); +volatile u16 __MEMRegs[64] AT_ADDRESS(0xCC004000); +volatile u16 __DSPRegs[] AT_ADDRESS(0xCC005000); +volatile u32 __DIRegs[] AT_ADDRESS(0xCC006000); +volatile u32 __SIRegs[0x100] AT_ADDRESS(0xCC006400); +volatile u32 __EXIRegs[0x40] AT_ADDRESS(0xCC006800); +volatile u32 __AIRegs[8] AT_ADDRESS(0xCC006C00); +#else +#define __VIRegs ((volatile u16 *)0xCC002000) +#define __PIRegs ((volatile u32 *)0xCC003000) +#define __MEMRegs ((volatile u16 *)0xCC004000) +#define __DSPRegs ((volatile u16 *)0xCC005000) +#define __DIRegs ((volatile u32 *)0xCC006000) +#define __SIRegs ((volatile u32 *)0xCC006400) +#define __EXIRegs ((volatile u32 *)0xCC006800) +#define __AIRegs ((volatile u32 *)0xCC006C00) +#endif + +// Offsets for __VIRegs + +// offsets for __VIRegs[i] +#define VI_VERT_TIMING (0) +#define VI_DISP_CONFIG (1) +#define VI_HORIZ_TIMING_0L (2) +#define VI_HORIZ_TIMING_0U (3) +#define VI_HORIZ_TIMING_1L (4) +#define VI_HORIZ_TIMING_1U (5) +#define VI_VERT_TIMING_ODD (6) +#define VI_VERT_TIMING_ODD_U (7) +#define VI_VERT_TIMING_EVEN (8) +#define VI_VERT_TIMING_EVEN_U (9) + +#define VI_BBI_ODD (10) // burst blanking interval +#define VI_BBI_ODD_U (11) // burst blanking interval +#define VI_BBI_EVEN (12) // burst blanking interval +#define VI_BBI_EVEN_U (13) // burst blanking interval + +#define VI_TOP_FIELD_BASE_LEFT (14) // top in 2d, top of left pic in 3d +#define VI_TOP_FIELD_BASE_LEFT_U (15) // top in 2d, top of left pic in 3d + +#define VI_TOP_FIELD_BASE_RIGHT (16) // top of right pic in 3d +#define VI_TOP_FIELD_BASE_RIGHT_U (17) // top of right pic in 3d + +#define VI_BTTM_FIELD_BASE_LEFT (18) // bottom in 2d, bottom of left pic in 3d +#define VI_BTTM_FIELD_BASE_LEFT_U (19) // bottom in 2d, bottom of left pic in 3d + +#define VI_BTTM_FIELD_BASE_RIGHT (20) // bottom of right pic in 3d +#define VI_BTTM_FIELD_BASE_RIGHT_U (21) // bottom of right pic in 3d + +#define VI_VERT_COUNT (22) // vertical display position +#define VI_HORIZ_COUNT (23) // horizontal display position + +#define VI_DISP_INT_0 (24) // display interrupt 0L +#define VI_DISP_INT_0U (25) // display interrupt 0U +#define VI_DISP_INT_1 (26) // display interrupt 1L +#define VI_DISP_INT_1U (27) // display interrupt 1U +#define VI_DISP_INT_2 (28) // display interrupt 2L +#define VI_DISP_INT_2U (29) // display interrupt 2U +#define VI_DISP_INT_3 (30) // display interrupt 3L +#define VI_DISP_INT_3U (31) // display interrupt 3U + +#define VI_HSW (36) // horizontal scaling width +#define VI_HSR (37) // horizontal scaling register + +#define VI_FCT_0 (38) // filter coefficient table 0L +#define VI_FCT_0U (39) // filter coefficient table 0U +#define VI_FCT_1 (40) // filter coefficient table 1L +#define VI_FCT_1U (41) // filter coefficient table 1U +#define VI_FCT_2 (42) // filter coefficient table 2L +#define VI_FCT_2U (43) // filter coefficient table 2U +#define VI_FCT_3 (44) // filter coefficient table 3L +#define VI_FCT_3U (45) // filter coefficient table 3U +#define VI_FCT_4 (46) // filter coefficient table 4L +#define VI_FCT_4U (47) // filter coefficient table 4U +#define VI_FCT_5 (48) // filter coefficient table 5L +#define VI_FCT_5U (49) // filter coefficient table 5U +#define VI_FCT_6 (50) // filter coefficient table 6L +#define VI_FCT_6U (51) // filter coefficient table 6U + +#define VI_CLOCK_SEL (54) // clock select +#define VI_DTV_STAT (55) // DTV status + +#define VI_WIDTH (56) + +// offsets for __DSPRegs[i] +#define DSP_MAILBOX_IN_HI (0) +#define DSP_MAILBOX_IN_LO (1) +#define DSP_MAILBOX_OUT_HI (2) +#define DSP_MAILBOX_OUT_LO (3) +#define DSP_CONTROL_STATUS (5) + +#define DSP_ARAM_SIZE (9) +#define DSP_ARAM_MODE (11) +#define DSP_ARAM_REFRESH (13) +#define DSP_ARAM_DMA_MM_HI (16) // Main mem address +#define DSP_ARAM_DMA_MM_LO (17) +#define DSP_ARAM_DMA_ARAM_HI (18) // ARAM address +#define DSP_ARAM_DMA_ARAM_LO (19) +#define DSP_ARAM_DMA_SIZE_HI (20) // DMA buffer size +#define DSP_ARAM_DMA_SIZE_LO (21) + +#define DSP_DMA_START_HI (24) // DMA start address +#define DSP_DMA_START_LO (25) +#define DSP_DMA_CONTROL_LEN (27) +#define DSP_DMA_BYTES_LEFT (29) + +#define DSP_DMA_START_FLAG (0x8000) // set to start DSP + +#endif diff --git a/include/dolphin/macros.h b/include/dolphin/macros.h deleted file mode 100644 index 251e9df5e2..0000000000 --- a/include/dolphin/macros.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _H_MACROS_ -#define _H_MACROS_ - -#ifdef DEBUG -#define ASSERTLINE(line, cond) \ - ((cond) || (OSPanic(__FILE__, line, "Failed assertion " #cond), 0)) - -#define ASSERTMSGLINE(line, cond, msg) \ - ((cond) || (OSPanic(__FILE__, line, msg), 0)) - -// This is dumb but we dont have a Metrowerks way to do variadic macros in the macro to make this done in a not scrubby way. -#define ASSERTMSG1LINE(line, cond, msg, arg1) \ - ((cond) || (OSPanic(__FILE__, line, msg, arg1), 0)) - -#define ASSERTMSG2LINE(line, cond, msg, arg1, arg2) \ - ((cond) || (OSPanic(__FILE__, line, msg, arg1, arg2), 0)) - -#define ASSERTMSGLINEV(line, cond, ...) \ - ((cond) || (OSPanic(__FILE__, line, __VA_ARGS__), 0)) - -#else -#define ASSERTLINE(line, cond) (void)0 -#define ASSERTMSGLINE(line, cond, msg) (void)0 -#define ASSERTMSG1LINE(line, cond, msg, arg1) (void)0 -#define ASSERTMSG2LINE(line, cond, msg, arg1, arg2) (void)0 -#define ASSERTMSGLINEV(line, cond, ...) (void)0 -#endif - -#define ASSERT(cond) ASSERTLINE(__LINE__, cond) - -#endif // _H_MACROS_ diff --git a/include/dolphin/mcc.h b/include/dolphin/mcc.h new file mode 100644 index 0000000000..3e53b463ed --- /dev/null +++ b/include/dolphin/mcc.h @@ -0,0 +1,211 @@ +#ifndef _DOLPHIN_MCC_H_ +#define _DOLPHIN_MCC_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + MCC_CHANNEL_SYSTEM = 0, + MCC_CHANNEL_1 = 1, + MCC_CHANNEL_2 = 2, + MCC_CHANNEL_3 = 3, + MCC_CHANNEL_4 = 4, + MCC_CHANNEL_5 = 5, + MCC_CHANNEL_6 = 6, + MCC_CHANNEL_7 = 7, + MCC_CHANNEL_8 = 8, + MCC_CHANNEL_9 = 9, + MCC_CHANNEL_10 = 10, + MCC_CHANNEL_11 = 11, + MCC_CHANNEL_12 = 12, + MCC_CHANNEL_13 = 13, + MCC_CHANNEL_14 = 14, + MCC_CHANNEL_15 = 15, +} MCC_CHANNEL; + +typedef struct { + /* 0x00 */ u8 firstBlock; + /* 0x01 */ u8 blockLength; + /* 0x02 */ u8 connect; + /* 0x03 */ u8 isLocked; +} MCC_Info; + +typedef enum { + MCC_EXI_0 = 0, + MCC_EXI_1 = 1, + MCC_EXI_2 = 2, +} MCC_EXI; + +typedef enum { + MCC_SYSEVENT_UNKNOWN = 0, + MCC_SYSEVENT_REBOOT = 1, + MCC_SYSEVENT_INITIALIZED = 2, + MCC_SYSEVENT_PING = 3, + MCC_SYSEVENT_PING_RESULT = 4, + MCC_SYSEVENT_FLUSH = 5, +} MCC_SYSEVENT; + +typedef void (*MCC_CBEvent)(MCC_CHANNEL channel, u32, u32); +typedef void (*MCC_CBSysEvent)(MCC_SYSEVENT sysEvent); +typedef int (*MCC_CBEnumDevices)(s32); + +typedef struct { + /* 0x00 */ u32 length; + /* 0x04 */ u16 rsvd; + /* 0x06 */ u16 protocol; +} MCC_Hdr; + +typedef struct { + /* 0x00 */ u32 code; + /* 0x04 */ u32 number; +} MCC_HdrFio; + +typedef struct { + /* 0x00 */ MCC_Info info; + /* 0x04 */ MCC_CBEvent callbackEvent; + /* 0x08 */ u32 eventMask; + /* 0x0C */ int isStreamDone; + /* 0x10 */ int isStreamConnection; + /* 0x14 */ int isStreamOpened; +} MCC_ChannelInfo; + +typedef enum { + MCC_MODE_MIN = 0, + MCC_MODE_MAX = 1, + MCC_MODE_ALL = 2, +} MCC_MODE; + +typedef enum { + MCC_CONNECT_DISCONNECT = 0, + MCC_CONNECT_HOST_OPEN = 1, + MCC_CONNECT_TARGET_OPEN = 2, + MCC_CONNECT_CONNECTED = 3, +} MCC_CONNECT; + +typedef enum { + MCC_EVENT_CONNECT = 0x1, + MCC_EVENT_DISCONNECT = 0x2, + MCC_EVENT_LOCK = 0x4, + MCC_EVENT_UNLOCK = 0x8, + MCC_EVENT_READ = 0x10, + MCC_EVENT_WRITE = 0x20, + MCC_EVENT_READ_DONE_INSIDE = 0x40, + MCC_EVENT_WRITE_DONE_INSIDE = 0x80, + MCC_EVENT_UNK_0x100 = 0x100, +} MCC_EVENT; + +typedef enum { + MCC_SYNC = 0, + MCC_ASYNC = 1, +} MCC_SYNC_STATE; + +typedef enum { + FIO_ASYNC_STATE_IDOL = 0, + FIO_ASYNC_STATE_BUSY = 1, + FIO_ASYNC_STATE_DONE = 2, +} FIO_ASYNC_STATE; + +typedef struct { + /* 0x00 */ u16 year; + /* 0x02 */ u8 month; + /* 0x03 */ u8 day; +} FIO_Date; + +typedef struct { + /* 0x00 */ u8 hour; + /* 0x01 */ u8 minute; + /* 0x02 */ u8 second; + /* 0x03 */ u8 reserved; +} FIO_Daytime; + +typedef struct { + /* 0x00 */ FIO_Date date; + /* 0x04 */ FIO_Daytime time; +} FIO_Timestamp; + +typedef struct { + /* 0x00 */ u32 fileAttributes; + /* 0x04 */ FIO_Timestamp creationTime; + /* 0x0C */ FIO_Timestamp lastAccessTime; + /* 0x14 */ FIO_Timestamp lastWriteTime; + /* 0x1C */ u32 fileSizeHigh; + /* 0x20 */ u32 fileSizeLow; +} FIO_Stat; + +typedef struct { + /* 0x00 */ FIO_Stat stat; + /* 0x24 */ char filename[256]; +} FIO_Finddata; + +#define FIO_ERROR_NONE 0x00 +#define FIO_ERROR_WRONG_CODE 0x81 +#define FIO_ERROR_WRONG_SEQUENCE 0x82 +#define FIO_ERROR_PACKET_WRITE 0x83 +#define FIO_ERROR_PACKET_READ 0x84 +#define FIO_ERROR_MCC 0x87 +#define FIO_ERROR_TIMEOUT 0x88 +#define FIO_ERROR_MSG_TOO_LONG 0x89 +#define FIO_ERROR_UNK_0x91 0x91 +#define FIO_ERROR_ASYNC_SIZE_TOO_BIG 0xA0 +#define FIO_ERROR_ASYNC_BUSY 0xA1 +#define FIO_ERROR_INVALID_PARAMETERS 0xB0 + +// FIO +int FIOInit(MCC_EXI exiChannel, MCC_CHANNEL chID, u8 blockSize); +void FIOExit(void); +int FIOQuery(void); +u8 FIOGetLastError(); +int FIOFopen(const char* filename, u32 mode); +int FIOFclose(int handle); +u32 FIOFread(int handle, void* data, u32 size); +u32 FIOFwrite(int handle, void* data, u32 size); +u32 FIOFseek(int handle, s32 offset, u32 mode); +int FIOFprintf(int handle, const char* format, ...); +int FIOFflush(int handle); +int FIOFstat(int handle, FIO_Stat* stat); +int FIOFerror(int handle); +int FIOFindFirst(const char* filename, FIO_Finddata* finddata); +int FIOFindNext(FIO_Finddata* finddata); +u32 FIOGetAsyncBufferSize(void); +int FIOFreadAsync(int handle, void* data, u32 size); +int FIOFwriteAsync(int handle, void* data, u32 size); +int FIOCheckAsyncDone(u32* result); + +// MCC +BOOL MCCStreamOpen(MCC_CHANNEL chID, u8 blockSize); +int MCCStreamClose(MCC_CHANNEL chID); +int MCCStreamWrite(MCC_CHANNEL chID, void* data, u32 dataBlockSize); +u32 MCCStreamRead(MCC_CHANNEL chID, void* data); +int MCCInit(MCC_EXI exiChannel, u8 timeout, MCC_CBSysEvent callbackSysEvent); +void MCCExit(void); +int MCCPing(void); +int MCCEnumDevices(MCC_CBEnumDevices callbackEnumDevices); +u8 MCCGetFreeBlocks(MCC_MODE mode); +u8 MCCGetLastError(void); +int MCCGetChannelInfo(MCC_CHANNEL chID, MCC_Info* info); +int MCCGetConnectionStatus(MCC_CHANNEL chID, MCC_CONNECT* connect); +int MCCNotify(MCC_CHANNEL chID, u32 notify); +u32 MCCSetChannelEventMask(MCC_CHANNEL chID, u32 event); +int MCCOpen(MCC_CHANNEL chID, u8 blockSize, MCC_CBEvent callbackEvent); +int MCCClose(MCC_CHANNEL chID); +int MCCLock(MCC_CHANNEL chID); +int MCCUnlock(MCC_CHANNEL chID); +int MCCRead(MCC_CHANNEL chID, u32 offset, void* data, s32 size, MCC_SYNC_STATE async); +int MCCWrite(MCC_CHANNEL chID, u32 offset, void* data, s32 size, MCC_SYNC_STATE async); +int MCCCheckAsyncDone(); + +// TTY +int TTYInit(MCC_EXI exiChannel, MCC_CHANNEL chID); +void TTYExit(void); +int TTYQuery(void); +int TTYPrintf(const char* format, ...); +int TTYFlush(void); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_MCC_H_ diff --git a/include/dolphin/mix.h b/include/dolphin/mix.h new file mode 100644 index 0000000000..f58b3d63dc --- /dev/null +++ b/include/dolphin/mix.h @@ -0,0 +1,95 @@ +#ifndef _DOLPHIN_MIX_H_ +#define _DOLPHIN_MIX_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define MIX_SOUND_MODE_MONO 0 +#define MIX_SOUND_MODE_STEREO 1 +#define MIX_SOUND_MODE_SURROUND 2 +#define MIX_SOUND_MODE_DPL2 3 + +typedef struct MIXChannel { + /* 0x00 */ AXVPB* axvpb; + /* 0x04 */ u32 mode; + /* 0x08 */ int input; + /* 0x0C */ int auxA; + /* 0x10 */ int auxB; + /* 0x14 */ int pan; + /* 0x18 */ int span; + /* 0x1C */ int fader; + /* 0x20 */ int l; + /* 0x24 */ int r; + /* 0x28 */ int f; + /* 0x2C */ int b; + /* 0x30 */ int l1; + /* 0x34 */ int r1; + /* 0x38 */ u16 v; + /* 0x3A */ u16 v1; + /* 0x3C */ u16 vL; + /* 0x3E */ u16 vL1; + /* 0x40 */ u16 vR; + /* 0x42 */ u16 vR1; + /* 0x44 */ u16 vS; + /* 0x46 */ u16 vS1; + /* 0x48 */ u16 vAL; + /* 0x4A */ u16 vAL1; + /* 0x4C */ u16 vAR; + /* 0x4E */ u16 vAR1; + /* 0x50 */ u16 vAS; + /* 0x52 */ u16 vAS1; + /* 0x54 */ u16 vBL; + /* 0x56 */ u16 vBL1; + /* 0x58 */ u16 vBR; + /* 0x5A */ u16 vBR1; + /* 0x5C */ u16 vBS; + /* 0x5E */ u16 vBS1; +} MIXChannel; + +void MIXInit(void); +void MIXQuit(void); +void MIXSetSoundMode(u32 mode); +u32 MIXGetSoundMode(void); +void MIXInitChannel(AXVPB* axvpb, u32 mode, int input, int auxA, int auxB, int pan, int span, int fader); +void MIXReleaseChannel(AXVPB* axvpb); +void MIXResetControls(AXVPB* p); +void MIXSetInput(AXVPB* p, int dB); +void MIXAdjustInput(AXVPB* p, int dB); +int MIXGetInput(AXVPB* p); +void MIXAuxAPostFader(AXVPB* p); +void MIXAuxAPreFader(AXVPB* p); +int MIXAuxAIsPostFader(AXVPB* p); +void MIXSetAuxA(AXVPB* p, int dB); +void MIXAdjustAuxA(AXVPB* p, int dB); +int MIXGetAuxA(AXVPB* p); +void MIXAuxBPostFader(AXVPB* p); +void MIXAuxBPreFader(AXVPB* p); +int MIXAuxBIsPostFader(AXVPB* p); +void MIXSetAuxB(AXVPB* p, int dB); +void MIXAdjustAuxB(AXVPB* p, int dB); +int MIXGetAuxB(AXVPB* p); +void MIXSetPan(AXVPB* p, int pan); +void MIXAdjustPan(AXVPB* p, int pan); +int MIXGetPan(AXVPB* p); +void MIXSetSPan(AXVPB* p, int span); +void MIXAdjustSPan(AXVPB* p, int span); +int MIXGetSPan(AXVPB* p); +void MIXMute(AXVPB* p); +void MIXUnMute(AXVPB* p); +int MIXIsMute(AXVPB* p); +void MIXSetFader(AXVPB* p, int dB); +void MIXAdjustFader(AXVPB* p, int dB); +int MIXGetFader(AXVPB* p); +void MIXSetDvdStreamFader(int dB); +int MIXGetDvdStreamFader(void); +void MIXUpdateSettings(void); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_MIX_H_ diff --git a/include/dolphin/mtx.h b/include/dolphin/mtx.h index feec7a71ef..22cf63667c 100644 --- a/include/dolphin/mtx.h +++ b/include/dolphin/mtx.h @@ -1,118 +1,383 @@ -#ifndef MTX_H -#define MTX_H +#ifndef _DOLPHIN_MTX_H_ +#define _DOLPHIN_MTX_H_ -#include "dolphin/mtx/mtx44.h" -#include "dolphin/mtx/quat.h" +#include #ifdef __cplusplus extern "C" { #endif -// ====== MATRIX ====== // +typedef struct { + f32 x, y, z; +} Vec, *VecPtr, Point3d, *Point3dPtr; -#define MTXDegToRad(a) ((a)*0.01745329252f) +typedef struct { + s16 x, y, z; +} S16Vec, *S16VecPtr; + +typedef struct { + f32 x, y, z, w; +} Quaternion, *QuaternionPtr, Qtrn, *QtrnPtr; typedef f32 Mtx[3][4]; +typedef f32 (*MtxPtr)[4]; + +typedef f32 Mtx44[4][4]; +typedef f32 (*Mtx44Ptr)[4]; + +typedef f32 ROMtx[4][3]; +typedef f32 (*ROMtxPtr)[4]; + +// do these belong in the sdk? typedef f32 Mtx33[3][3]; typedef f32 Mtx23[2][3]; -typedef f32 (*MtxP)[4]; typedef f32 (*Mtx3P)[3]; -typedef const f32 (*CMtxP)[4]; // Change name later? +typedef f32 (*MtxP)[4]; +typedef const f32 (*CMtxP)[4]; +typedef f32 QuaternionP[4]; +typedef struct { + u32 numMtx; + MtxPtr stackBase; + MtxPtr stackPtr; +} MTXStack; + +#define MTXDegToRad(d) (d * 0.01745329252f) +#define MTXRadToDeg(r) (r * 57.29577951f) + +// MTX +// C version +void C_MTXIdentity(Mtx m); +void C_MTXCopy(const Mtx src, Mtx dst); +void C_MTXConcat(const Mtx a, const Mtx b, Mtx ab); +void C_MTXConcatArray(const Mtx a, const Mtx* srcBase, Mtx* dstBase, u32 count); +void C_MTXTranspose(const Mtx src, Mtx xPose); +u32 C_MTXInverse(const Mtx src, Mtx inv); +u32 C_MTXInvXpose(const Mtx src, Mtx invX); +void C_MTXRotRad(Mtx m, char axis, f32 rad); +void C_MTXRotTrig(Mtx m, char axis, f32 sinA, f32 cosA); +void C_MTXRotAxisRad(Mtx m, const Vec* axis, f32 rad); +void C_MTXTrans(Mtx m, f32 xT, f32 yT, f32 zT); +void C_MTXTransApply(const Mtx src, Mtx dst, f32 xT, f32 yT, f32 zT); +void C_MTXScale(Mtx m, f32 xS, f32 yS, f32 zS); +void C_MTXScaleApply(const Mtx src, Mtx dst, f32 xS, f32 yS, f32 zS); +void C_MTXQuat(Mtx m, const Quaternion* q); +void C_MTXReflect(Mtx m, const Vec* p, const Vec* n); + +// PS version void PSMTXIdentity(Mtx m); void PSMTXCopy(const Mtx src, Mtx dst); void PSMTXConcat(const Mtx a, const Mtx b, Mtx ab); +void PSMTXConcatArray(const Mtx a, const Mtx* srcBase, Mtx* dstBase, u32 count); +void PSMTXTranspose(const Mtx src, Mtx xPose); u32 PSMTXInverse(const Mtx src, Mtx inv); +u32 PSMTXInvXpose(const Mtx src, Mtx invX); void PSMTXRotRad(Mtx m, char axis, f32 rad); -void PSMTXRotTrig(Mtx m, char axis, f32 sin, f32 cos); +void PSMTXRotTrig(Mtx m, char axis, f32 sinA, f32 cosA); void PSMTXRotAxisRad(Mtx m, const Vec* axis, f32 rad); -void PSMTXTrans(Mtx m, f32 x, f32 y, f32 z); -void PSMTXTransApply(const Mtx src, Mtx dst, f32 x, f32 y, f32 z); -void PSMTXScale(Mtx m, f32 x, f32 y, f32 z); -void PSMTXScaleApply(const Mtx src, Mtx dst, f32 x, f32 y, f32 z); -void PSMTXQuat(Mtx m, const PSQuaternion* q); +void PSMTXTrans(Mtx m, f32 xT, f32 yT, f32 zT); +void PSMTXTransApply(const Mtx src, Mtx dst, f32 xT, f32 yT, f32 zT); +void PSMTXScale(Mtx m, f32 xS, f32 yS, f32 zS); +void PSMTXScaleApply(const Mtx src, Mtx dst, f32 xS, f32 yS, f32 zS); +void PSMTXQuat(Mtx m, const Quaternion* q); +void PSMTXReflect(Mtx m, const Vec* p, const Vec* n); -void C_MTXLookAt(Mtx m, const Vec* camPos, const Vec* camUp, const Vec* target); -void C_MTXLightPerspective(Mtx m, f32 fovY, f32 aspect, f32 scale_s, f32 scale_t, f32 trans_s, - f32 trans_t); -void C_MTXLightOrtho(Mtx m, f32 top, f32 bottom, f32 left, f32 right, f32 scale_s, f32 scale_t, - f32 trans_s, f32 trans_t); - -inline void C_MTXRotAxisRad(Mtx m, const Vec* axis, f32 rad) { - PSMTXRotAxisRad(m, axis, rad); -} - -/* When compiling in debug mode, use C implementations */ #ifdef DEBUG -// TODO: Add debug rom C implementations -/* #define MTXIdentity C_MTXIdentity -#define MTXCopy C_MTXCopy -#define MTXConcat C_MTXConcat -#define MTXInverse C_MTXInverse -#define MTXRotRad C_MTXRotRad -#define MTXRotTrig C_MTXRotTrig +#define MTXIdentity C_MTXIdentity +#define MTXCopy C_MTXCopy +#define MTXConcat C_MTXConcat +#define MTXInverse C_MTXInverse +#define MTXTranspose C_MTXTranspose +#define MTXInverse C_MTXInverse +#define MTXInvXpose C_MTXInvXpose +#define MTXRotRad C_MTXRotRad +#define MTXRotTrig C_MTXRotTrig #define MTXRotAxisRad C_MTXRotAxisRad -#define MTXTrans C_MTXTrans +#define MTXTrans C_MTXTrans #define MTXTransApply C_MTXTransApply -#define MTXScale C_MTXScale +#define MTXScale C_MTXScale #define MTXScaleApply C_MTXScaleApply -#define MTXQuat C_MTXQuat */ - -#define MTXIdentity PSMTXIdentity -#define MTXCopy PSMTXCopy -#define MTXConcat PSMTXConcat -#define MTXInverse PSMTXInverse -#define MTXRotRad PSMTXRotRad -#define MTXRotTrig PSMTXRotTrig -#define MTXRotAxisRad PSMTXRotAxisRad -#define MTXTrans PSMTXTrans -#define MTXTransApply PSMTXTransApply -#define MTXScale PSMTXScale -#define MTXScaleApply PSMTXScaleApply -#define MTXQuat PSMTXQuat +#define MTXQuat C_MTXQuat +#define MTXReflect C_MTXReflect #else -#define MTXIdentity PSMTXIdentity -#define MTXCopy PSMTXCopy -#define MTXConcat PSMTXConcat -#define MTXInverse PSMTXInverse -#define MTXRotRad PSMTXRotRad -#define MTXRotTrig PSMTXRotTrig +#define MTXIdentity PSMTXIdentity +#define MTXCopy PSMTXCopy +#define MTXConcat PSMTXConcat +#define MTXInverse PSMTXInverse +#define MTXTranspose PSMTXTranspose +#define MTXInverse PSMTXInverse +#define MTXInvXpose PSMTXInvXpose +#define MTXRotRad PSMTXRotRad +#define MTXRotTrig PSMTXRotTrig #define MTXRotAxisRad PSMTXRotAxisRad -#define MTXTrans PSMTXTrans +#define MTXTrans PSMTXTrans #define MTXTransApply PSMTXTransApply -#define MTXScale PSMTXScale +#define MTXScale PSMTXScale #define MTXScaleApply PSMTXScaleApply -#define MTXQuat PSMTXQuat +#define MTXQuat PSMTXQuat +#define MTXReflect PSMTXReflect #endif -// ====== MATRIX VECTOR ====== // +// C versions only +void C_MTXLookAt(Mtx m, const Point3d* camPos, const Vec* camUp, const Point3d* target); +void C_MTXLightFrustum(Mtx m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 scaleS, f32 scaleT, f32 transS, f32 transT); +void C_MTXLightPerspective(Mtx m, f32 fovY, f32 aspect, f32 scaleS, f32 scaleT, f32 transS, f32 transT); +void C_MTXLightOrtho(Mtx m, f32 t, f32 b, f32 l, f32 r, f32 scaleS, f32 scaleT, f32 transS, f32 transT); +#define MTXLookAt C_MTXLookAt +#define MTXLightFrustum C_MTXLightFrustum +#define MTXLightPerspective C_MTXLightPerspective +#define MTXLightOrtho C_MTXLightOrtho + +// MTXVEC +// C versions +void C_MTXMultVec(const Mtx m, const Vec* src, Vec* dst); +void C_MTXMultVecArray(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count); +void C_MTXMultVecSR(const Mtx m, const Vec* src, Vec* dst); +void C_MTXMultVecArraySR(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count); + +// PS versions void PSMTXMultVec(const Mtx m, const Vec* src, Vec* dst); -void PSMTXMultVecSR(const Mtx m, const Vec* src, Vec* dst); void PSMTXMultVecArray(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count); +void PSMTXMultVecSR(const Mtx m, const Vec* src, Vec* dst); void PSMTXMultVecArraySR(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count); -/* When compiling in debug mode, use C implementations */ #ifdef DEBUG -// TODO: Add debug rom C implementations -/* #define MTXMultVec C_MTXMultVec -#define MTXMultVecSR C_MTXMultVecSR -#define MTXMultVecArray C_MTXMultVecArray -#define MTXMultVecArraySR C_MTXMultVecArraySR */ - -#define MTXMultVec PSMTXMultVec -#define MTXMultVecSR PSMTXMultVecSR -#define MTXMultVecArray PSMTXMultVecArray -#define MTXMultVecArraySR PSMTXMultVecArraySR +#define MTXMultVec C_MTXMultVec +#define MTXMultVecArray C_MTXMultVecArray +#define MTXMultVecSR C_MTXMultVecSR +#define MTXMultVecArraySR C_MTXMultVecArraySR #else -#define MTXMultVec PSMTXMultVec -#define MTXMultVecSR PSMTXMultVecSR -#define MTXMultVecArray PSMTXMultVecArray +#define MTXMultVec PSMTXMultVec +#define MTXMultVecArray PSMTXMultVecArray +#define MTXMultVecSR PSMTXMultVecSR #define MTXMultVecArraySR PSMTXMultVecArraySR #endif +// MTX44 +// C versions +void C_MTX44Identity(Mtx44 m); +void C_MTX44Copy(const Mtx44 src, Mtx44 dst); +void C_MTX44Concat(const Mtx44 a, const Mtx44 b, Mtx44 ab); +void C_MTX44Transpose(const Mtx44 src, Mtx44 xPose); +void C_MTX44Trans(Mtx44 m, f32 xT, f32 yT, f32 zT); +void C_MTX44TransApply(const Mtx44 src, Mtx44 dst, f32 xT, f32 yT, f32 zT); +void C_MTX44Scale(Mtx44 m, f32 xS, f32 yS, f32 zS); +void C_MTX44ScaleApply(const Mtx44 src, Mtx44 dst, f32 xS, f32 yS, f32 zS); +void C_MTX44RotRad(Mtx44 m, char axis, f32 rad); +void C_MTX44RotTrig(Mtx44 m, char axis, f32 sinA, f32 cosA); +void C_MTX44RotAxisRad(Mtx44 m, const Vec* axis, f32 rad); + +// PS versions +void PSMTX44Identity(Mtx44 m); +void PSMTX44Copy(const Mtx44 src, Mtx44 dst); +void PSMTX44Concat(const Mtx44 a, const Mtx44 b, Mtx44 ab); +void PSMTX44Transpose(const Mtx44 src, Mtx44 xPose); +void PSMTX44Trans(Mtx44 m, f32 xT, f32 yT, f32 zT); +void PSMTX44TransApply(const Mtx44 src, Mtx44 dst, f32 xT, f32 yT, f32 zT); +void PSMTX44Scale(Mtx44 m, f32 xS, f32 yS, f32 zS); +void PSMTX44ScaleApply(const Mtx44 src, Mtx44 dst, f32 xS, f32 yS, f32 zS); +void PSMTX44RotRad(Mtx44 m, char axis, f32 rad); +void PSMTX44RotTrig(Mtx44 m, char axis, f32 sinA, f32 cosA); +void PSMTX44RotAxisRad(Mtx44 m, const Vec* axis, f32 rad); + +#ifdef DEBUG +#define MTX44Identity C_MTX44Identity +#define MTX44Copy C_MTX44Copy +#define MTX44Concat C_MTX44Concat +#define MTX44Transpose C_MTX44Transpose +#define MTX44Trans C_MTX44Trans +#define MTX44TransApply C_MTX44TransApply +#define MTX44Scale C_MTX44Scale +#define MTX44ScaleApply C_MTX44ScaleApply +#define MTX44RotRad C_MTX44RotRad +#define MTX44RotTrig C_MTX44RotTrig +#define MTX44RotAxisRad C_MTX44RotAxisRad +#else +#define MTX44Identity PSMTX44Identity +#define MTX44Copy PSMTX44Copy +#define MTX44Concat PSMTX44Concat +#define MTX44Transpose PSMTX44Transpose +#define MTX44Trans PSMTX44Trans +#define MTX44TransApply PSMTX44TransApply +#define MTX44Scale PSMTX44Scale +#define MTX44ScaleApply PSMTX44ScaleApply +#define MTX44RotRad PSMTX44RotRad +#define MTX44RotTrig PSMTX44RotTrig +#define MTX44RotAxisRad PSMTX44RotAxisRad +#endif + +// C versions only +void C_MTXFrustum(Mtx44 m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f); +void C_MTXPerspective(Mtx44 m, f32 fovY, f32 aspect, f32 n, f32 f); +void C_MTXOrtho(Mtx44 m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f); +u32 C_MTX44Inverse(const Mtx44 src, Mtx44 inv); + +#define MTXFrustum C_MTXFrustum +#define MTXPerspective C_MTXPerspective +#define MTXOrtho C_MTXOrtho +#define MTX44Inverse C_MTX44Inverse + +// MTX44VEC +// C versions +void C_MTX44MultVec(const Mtx44 m, const Vec* src, Vec* dst); +void C_MTX44MultVecArray(const Mtx44 m, const Vec* srcBase, Vec* dstBase, u32 count); +void C_MTX44MultVecSR(const Mtx44 m, const Vec* src, Vec* dst); +void C_MTX44MultVecArraySR(const Mtx44 m, const Vec* srcBase, Vec* dstBase, u32 count); + +// PS versions +void PSMTX44MultVec(const Mtx44 m, const Vec* src, Vec* dst); +void PSMTX44MultVecArray(const Mtx44 m, const Vec* srcBase, Vec* dstBase, u32 count); +void PSMTX44MultVecSR(const Mtx44 m, const Vec* src, Vec* dst); +void PSMTX44MultVecArraySR(const Mtx44 m, const Vec* srcBase, Vec* dstBase, u32 count); + +#ifdef DEBUG +#define MTX44MultVec C_MTX44MultVec +#define MTX44MultVecArray C_MTX44MultVecArray +#define MTX44MultVecSR C_MTX44MultVecSR +#define MTX44MultVecArraySR C_MTX44MultVecArraySR +#else +#define MTX44MultVec PSMTX44MultVec +#define MTX44MultVecArray PSMTX44MultVecArray +#define MTX44MultVecSR PSMTX44MultVecSR +#define MTX44MultVecArraySR PSMTX44MultVecArraySR +#endif + +// PSMTX +void PSMTXReorder(const Mtx src, ROMtx dest); +void PSMTXROMultVecArray(const ROMtx m, const Vec* srcBase, Vec* dstBase, u32 count); +void PSMTXROSkin2VecArray(const ROMtx m0, const ROMtx m1, const f32* wtBase, const Vec* srcBase, Vec* dstBase, u32 count); +void PSMTXROMultS16VecArray(const Mtx m, const S16Vec* srcBase, Vec* dstBase, u32 count); +void PSMTXMultS16VecArray(const ROMtx* m, const S16Vec* srcBase, Vec* dstBase, u32 count); + +// MTXSTACK +void MTXInitStack(MTXStack* sPtr, u32 numMtx); +MtxPtr MTXPush(MTXStack* sPtr, const Mtx m); +MtxPtr MTXPushFwd(MTXStack* sPtr, const Mtx m); +MtxPtr MTXPushInv(MTXStack* sPtr, const Mtx m); +MtxPtr MTXPushInvXpose(MTXStack* sPtr, const Mtx m); +MtxPtr MTXPop(MTXStack* sPtr); +MtxPtr MTXGetStackPtr(const MTXStack* sPtr); + +// VEC +// C versions +void C_VECAdd(const Vec* a, const Vec* b, Vec* ab); +void C_VECSubtract(const Vec* a, const Vec* b, Vec* a_b); +void C_VECScale(const Vec* src, Vec* dst, f32 scale); +void C_VECNormalize(const Vec* src, Vec* unit); +f32 C_VECSquareMag(const Vec* v); +f32 C_VECMag(const Vec* v); +f32 C_VECDotProduct(const Vec* a, const Vec* b); +void C_VECCrossProduct(const Vec* a, const Vec* b, Vec* axb); +f32 C_VECSquareDistance(const Vec* a, const Vec* b); +f32 C_VECDistance(const Vec* a, const Vec* b); + +// PS versions +void PSVECAdd(const Vec* a, const Vec* b, Vec* ab); +void PSVECSubtract(const Vec* a, const Vec* b, Vec* a_b); +void PSVECScale(const Vec* src, Vec* dst, f32 scale); +void PSVECNormalize(const Vec* src, Vec* dst); +f32 PSVECSquareMag(const Vec* v); +f32 PSVECMag(const Vec* v); +f32 PSVECDotProduct(const Vec* a, const Vec* b); +void PSVECCrossProduct(const Vec* a, const Vec* b, Vec* axb); +f32 PSVECSquareDistance(const Vec* a, const Vec* b); +f32 PSVECDistance(const Vec* a, const Vec* b); + +#ifdef DEBUG +#define VECAdd C_VECAdd +#define VECSubtract C_VECSubtract +#define VECScale C_VECScale +#define VECNormalize C_VECNormalize +#define VECSquareMag C_VECSquareMag +#define VECMag C_VECMag +#define VECDotProduct C_VECDotProduct +#define VECCrossProduct C_VECCrossProduct +#define VECSquareDistance C_VECSquareDistance +#define VECDistance C_VECDistance +#else +#define VECAdd PSVECAdd +#define VECSubtract PSVECSubtract +#define VECScale PSVECScale +#define VECNormalize PSVECNormalize +#define VECSquareMag PSVECSquareMag +#define VECMag PSVECMag +#define VECDotProduct PSVECDotProduct +#define VECCrossProduct PSVECCrossProduct +#define VECSquareDistance PSVECSquareDistance +#define VECDistance PSVECDistance +#endif + +void C_VECHalfAngle(const Vec* a, const Vec* b, Vec* half); +void C_VECReflect(const Vec* src, const Vec* normal, Vec* dst); + +#define VECHalfAngle C_VECHalfAngle +#define VECReflect C_VECReflect + +// QUAT +// C versions +void C_QUATAdd(const Quaternion* p, const Quaternion* q, Quaternion* r); +void C_QUATSubtract(const Quaternion* p, const Quaternion* q, Quaternion* r); +void C_QUATMultiply(const Quaternion* p, const Quaternion* q, Quaternion* pq); +void C_QUATScale(const Quaternion* q, Quaternion* r, f32 scale); +f32 C_QUATDotProduct(const Quaternion* p, const Quaternion* q); +void C_QUATNormalize(const Quaternion* src, Quaternion* unit); +void C_QUATInverse(const Quaternion* src, Quaternion* inv); +void C_QUATDivide(const Quaternion* p, const Quaternion* q, Quaternion* r); + +// PS versions +void PSQUATAdd(const Quaternion* p, const Quaternion* q, Quaternion* r); +void PSQUATSubtract(const Quaternion* p, const Quaternion* q, Quaternion* r); +void PSQUATMultiply(const Quaternion* p, const Quaternion* q, Quaternion* pq); +void PSQUATScale(const Quaternion* q, Quaternion* r, f32 scale); +f32 PSQUATDotProduct(const Quaternion* p, const Quaternion* q); +void PSQUATNormalize(const Quaternion* src, Quaternion* unit); +void PSQUATInverse(const Quaternion* src, Quaternion* inv); +void PSQUATDivide(const Quaternion* p, const Quaternion* q, Quaternion* r); + +#ifdef DEBUG +#define QUATAdd C_QUATAdd +#define QUATSubtract C_QUATSubtract +#define QUATMultiply C_QUATMultiply +#define QUATScale C_QUATScale +#define QUATDotProduct C_QUATDotProduct +#define QUATNormalize C_QUATNormalize +#define QUATInverse C_QUATInverse +#define QUATDivide C_QUATDivide +#else +#define QUATAdd PSQUATAdd +#define QUATSubtract PSQUATSubtract +#define QUATMultiply PSQUATMultiply +#define QUATScale PSQUATScale +#define QUATDotProduct PSQUATDotProduct +#define QUATNormalize PSQUATNormalize +#define QUATInverse PSQUATInverse +#define QUATDivide PSQUATDivide +#endif + +// C versions only +void C_QUATExp(const Quaternion* q, Quaternion* r); +void C_QUATLogN(const Quaternion* q, Quaternion* r); +void C_QUATMakeClosest(const Quaternion* q, const Quaternion* qto, Quaternion* r); +void C_QUATRotAxisRad(Quaternion* r, const Vec* axis, f32 rad); +void C_QUATMtx(Quaternion* r, const Mtx m); +void C_QUATLerp(const Quaternion* p, const Quaternion* q, Quaternion* r, f32 t); +void C_QUATSlerp(const Quaternion* p, const Quaternion* q, Quaternion* r, f32 t); +void C_QUATSquad(const Quaternion* p, const Quaternion* a, const Quaternion* b, const Quaternion* q, Quaternion* r, f32 t); +void C_QUATCompA(const Quaternion* qprev, const Quaternion* q, const Quaternion* qnext, Quaternion* a); + +#define QUATExp C_QUATExp +#define QUATLogN C_QUATLogN +#define QUATMakeClosest C_QUATMakeClosest +#define QUATRotAxisRad C_QUATRotAxisRad +#define QUATMtx C_QUATMtx +#define QUATLerp C_QUATLerp +#define QUATSlerp C_QUATSlerp +#define QUATSquad C_QUATSquad +#define QUATCompA C_QUATCompA + #ifdef __cplusplus -}; +} #endif -#endif /* MTX_H */ +#endif diff --git a/include/dolphin/mtx/mtx44.h b/include/dolphin/mtx/mtx44.h deleted file mode 100644 index 44ed7c7e22..0000000000 --- a/include/dolphin/mtx/mtx44.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef MTX44_H -#define MTX44_H - -#include "dolphin/types.h" - -typedef f32 Mtx44[4][4]; - -#ifdef __cplusplus -extern "C" { -#endif - -void C_MTXPerspective(Mtx44 m, f32 fovy, f32 aspect, f32 near, f32 far); -void C_MTXOrtho(Mtx44 m, f32 top, f32 bottom, f32 left, f32 right, f32 near, f32 far); - -#ifdef __cplusplus -}; -#endif - -#endif /* MTX44_H */ diff --git a/include/dolphin/mtx/quat.h b/include/dolphin/mtx/quat.h deleted file mode 100644 index f5ab841f5e..0000000000 --- a/include/dolphin/mtx/quat.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef QUAT_H -#define QUAT_H - -#include "dolphin/mtx/vec.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct Quaternion { - f32 x, y, z, w; -} Quaternion; - -typedef f32 PSQuaternion[4]; - -void PSQUATMultiply(const Quaternion* a, const Quaternion* b, Quaternion* ab); -void C_QUATRotAxisRad(Quaternion* q, const Vec* axis, f32 rad); -void C_QUATSlerp(const Quaternion* p, const Quaternion* q, Quaternion* r, f32 t); - -/* When compiling in debug mode, use C implementations */ -#ifdef DEBUG -// TODO: Add debug rom C implementations -/* #define QUATMultiply C_QUATMultiply */ - -#define QUATMultiply PSQUATMultiply -#else -#define QUATMultiply PSQUATMultiply -#endif - -#ifdef __cplusplus -}; -#endif - -#endif /* QUAT_H */ diff --git a/include/dolphin/mtx/vec.h b/include/dolphin/mtx/vec.h deleted file mode 100644 index d3f7a8e365..0000000000 --- a/include/dolphin/mtx/vec.h +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef VEC_H -#define VEC_H - -#include "dolphin/types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct Vec { - f32 x, y, z; -} Vec; - -typedef Vec* VecPtr; -typedef Vec Point3d; -typedef Vec* Point3dPtr; - -typedef struct SVec { - s16 x, y, z; -} SVec; - -void PSVECAdd(const Vec* a, const Vec* b, Vec* ab); -void PSVECSubtract(const Vec* a, const Vec* b, Vec* a_b); -void PSVECScale(const Vec* src, Vec* dst, f32 scale); -void PSVECNormalize(const Vec* src, Vec* unit); -f32 PSVECSquareMag(const Vec* v); -f32 PSVECMag(const Vec* v); -f32 PSVECDotProduct(const Vec* a, const Vec* b); -void PSVECCrossProduct(const Vec* a, const Vec* b, Vec* axb); -f32 PSVECSquareDistance(const Vec* a, const Vec* b); -f32 PSVECDistance(const Vec* a, const Vec* b); - -void C_VECHalfAngle(const Vec* a, const Vec* b, Vec* half); -void C_VECReflect(const Vec* src, const Vec* normal, Vec* dst); - -inline void C_VECAdd(register const Vec* a, register const Vec* b, register Vec* ab) { - register f32 axy; - register f32 bxy; - register f32 az; - register f32 sumz; - register f32 bz; -#ifdef __MWERKS__ - asm { - psq_l axy, 0(a), 0, 0 - psq_l bxy, 0(b), 0, 0 - ps_add bxy, axy, bxy - psq_st bxy, 0(ab), 0, 0 - psq_l az, 8(a), 1, 0 - psq_l bz, 8(b), 1, 0 - ps_add sumz, az, bz - psq_st sumz, 8(ab), 1, 0 - } -#endif -} - -inline void C_VECSubtract(register const Vec* a, register const Vec* b, register Vec* ab) { - register f32 axy; - register f32 bxy; - register f32 az; - register f32 subz; - register f32 bz; -#ifdef __MWERKS__ - asm { - psq_l axy, 0(a), 0, 0 - psq_l bxy, 0(b), 0, 0 - ps_sub bxy, axy, bxy - psq_st bxy, 0(ab), 0, 0 - psq_l az, 8(a), 1, 0 - psq_l bz, 8(b), 1, 0 - ps_sub subz, az, bz - psq_st subz, 8(ab), 1, 0 - } -#endif -} - -inline f32 C_VECSquareMag(const Vec* v) { - register f32 x_y; - register f32 z; - register f32 res; - register const f32* src = &v->x; -#ifdef __MWERKS__ - asm { - psq_l x_y, 0(src), 0, 0 - ps_mul x_y, x_y, x_y - lfs z, 8(src) - ps_madd res, z, z, x_y - ps_sum0 res, res, x_y, x_y - } -#endif - return res; -} - -/* When compiling in debug mode, use C implementations */ -#ifdef DEBUG -// TODO: Add debug rom C implementations -/* #define VECAdd C_VECAdd -#define VECSubtract C_VECSubtract -#define VECScale C_VECScale -#define VECNormalize C_VECNormalize -#define VECSquareMag C_VECSquareMag -#define VECMag C_VECMag -#define VECDotProduct C_VECDotProduct -#define VECCrossProduct C_VECCrossProduct -#define VECSquareDistance C_VECSquareDistance -#define VECDistance C_VECDistance */ - -#define VECAdd PSVECAdd -#define VECSubtract PSVECSubtract -#define VECScale PSVECScale -#define VECNormalize PSVECNormalize -#define VECSquareMag PSVECSquareMag -#define VECMag PSVECMag -#define VECDotProduct PSVECDotProduct -#define VECCrossProduct PSVECCrossProduct -#define VECSquareDistance PSVECSquareDistance -#define VECDistance PSVECDistance -#else -#define VECAdd PSVECAdd -#define VECSubtract PSVECSubtract -#define VECScale PSVECScale -#define VECNormalize PSVECNormalize -#define VECSquareMag PSVECSquareMag -#define VECMag PSVECMag -#define VECDotProduct PSVECDotProduct -#define VECCrossProduct PSVECCrossProduct -#define VECSquareDistance PSVECSquareDistance -#define VECDistance PSVECDistance -#endif - -#ifdef __cplusplus -}; -#endif - -#endif /* VEC_H */ diff --git a/include/dolphin/odemuexi2/Src/OdemuExi2Lib/DebuggerDriver.h b/include/dolphin/odemuexi2/Src/OdemuExi2Lib/DebuggerDriver.h deleted file mode 100644 index 2f621cafbd..0000000000 --- a/include/dolphin/odemuexi2/Src/OdemuExi2Lib/DebuggerDriver.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef SRC_ODEMUEXI2LIB_DEBUGGERDRIVER_H -#define SRC_ODEMUEXI2LIB_DEBUGGERDRIVER_H - -#endif /* SRC_ODEMUEXI2LIB_DEBUGGERDRIVER_H */ diff --git a/include/dolphin/os.h b/include/dolphin/os.h index 0fbf83fce4..75094d3119 100644 --- a/include/dolphin/os.h +++ b/include/dolphin/os.h @@ -1,32 +1,10 @@ -#ifndef OS_H_ -#define OS_H_ +#ifndef _DOLPHIN_OS_H_ +#define _DOLPHIN_OS_H_ -#include "__va_arg.h" -#include "macros.h" -#include "dolphin/dvd.h" - -#include "dolphin/os/OSAlarm.h" // IWYU pragma: export -#include "dolphin/os/OSAlloc.h" // IWYU pragma: export -#include "dolphin/os/OSArena.h" // IWYU pragma: export -#include "dolphin/os/OSAudioSystem.h" // IWYU pragma: export -#include "dolphin/os/OSCache.h" // IWYU pragma: export -#include "dolphin/os/OSContext.h" // IWYU pragma: export -#include "dolphin/os/OSError.h" // IWYU pragma: export -#include "dolphin/os/OSExec.h" // IWYU pragma: export -#include "dolphin/os/OSFont.h" // IWYU pragma: export -#include "dolphin/os/OSInterrupt.h" // IWYU pragma: export -#include "dolphin/os/OSLink.h" // IWYU pragma: export -#include "dolphin/os/OSMemory.h" // IWYU pragma: export -#include "dolphin/os/OSMessage.h" // IWYU pragma: export -#include "dolphin/os/OSMutex.h" // IWYU pragma: export -#include "dolphin/os/OSReboot.h" // IWYU pragma: export -#include "dolphin/os/OSReset.h" // IWYU pragma: export -#include "dolphin/os/OSResetSW.h" // IWYU pragma: export -#include "dolphin/os/OSRtc.h" // IWYU pragma: export -#include "dolphin/os/OSSync.h" // IWYU pragma: export -#include "dolphin/os/OSThread.h" // IWYU pragma: export -#include "dolphin/os/OSTime.h" // IWYU pragma: export +#include +#include +#include void OSReportInit(void); void OSSwitchFiberEx(u32, u32, u32, u32, u32, u32); void OSVAttention(const char* fmt, va_list args); @@ -35,79 +13,208 @@ void OSVAttention(const char* fmt, va_list args); extern "C" { #endif +typedef s64 OSTime; +typedef u32 OSTick; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// private macro, maybe shouldn't be defined here? +#define OFFSET(addr, align) (((u32)(addr) & ((align)-1))) + +#define DOLPHIN_ALIGNMENT 32 + // Upper words of the masks, since UIMM is only 16 bits -#define OS_CACHED_REGION_PREFIX 0x8000 +#define OS_CACHED_REGION_PREFIX 0x8000 #define OS_UNCACHED_REGION_PREFIX 0xC000 #define OS_PHYSICAL_MASK 0x3FFF -#define OS_BASE_CACHED (OS_CACHED_REGION_PREFIX << 16) +#define OS_BASE_CACHED (OS_CACHED_REGION_PREFIX << 16) #define OS_BASE_UNCACHED (OS_UNCACHED_REGION_PREFIX << 16) -#define OS_CONSOLE_MASK 0xf0000000 -#define OS_CONSOLE_RETAIL 0x00000000 -#define OS_CONSOLE_DEVELOPMENT 0x10000000 -#define OS_CONSOLE_TDEV 0x20000000 +#ifdef __MWERKS__ +u32 __OSPhysicalMemSize AT_ADDRESS(OS_BASE_CACHED | 0x0028); +volatile int __OSTVMode AT_ADDRESS(OS_BASE_CACHED | 0x00CC); +OSThreadQueue __OSActiveThreadQueue AT_ADDRESS(OS_BASE_CACHED | 0x00DC); +OSThread* __OSCurrentThread AT_ADDRESS(OS_BASE_CACHED | 0x00E4); +u32 __OSSimulatedMemSize AT_ADDRESS(OS_BASE_CACHED | 0x00F0); +u32 __OSBusClock AT_ADDRESS(OS_BASE_CACHED | 0x00F8); +u32 __OSCoreClock AT_ADDRESS(OS_BASE_CACHED | 0x00FC); +volatile u16 __OSDeviceCode AT_ADDRESS(OS_BASE_CACHED | 0x30E6); +u16 __OSWirelessPadFixMode AT_ADDRESS(OS_BASE_CACHED | 0x30E0); -#define OS_CONSOLE_RETAIL4 0x00000004 -#define OS_CONSOLE_RETAIL3 0x00000003 -#define OS_CONSOLE_RETAIL2 0x00000002 -#define OS_CONSOLE_RETAIL1 0x00000001 -#define OS_CONSOLE_TDEVHW4 0x20000007 -#define OS_CONSOLE_TDEVHW3 0x20000006 -#define OS_CONSOLE_TDEVHW2 0x20000005 -#define OS_CONSOLE_TDEVHW1 0x20000004 -#define OS_CONSOLE_DEVHW4 0x10000007 -#define OS_CONSOLE_DEVHW3 0x10000006 -#define OS_CONSOLE_DEVHW2 0x10000005 -#define OS_CONSOLE_DEVHW1 0x10000004 -#define OS_CONSOLE_MINNOW 0x10000003 -#define OS_CONSOLE_ARTHUR 0x10000002 -#define OS_CONSOLE_PC_EMULATOR 0x10000001 -#define OS_CONSOLE_EMULATOR 0x10000000 +// unknowns +OSThread* __gUnkThread1 AT_ADDRESS(OS_BASE_CACHED | 0x00D8); +int __gUnknown800030C0[2] AT_ADDRESS(OS_BASE_CACHED | 0x30C0); +u8 __gUnknown800030E3 AT_ADDRESS(OS_BASE_CACHED | 0x30E3); +#else +#define __OSBusClock (*(u32 *)(OS_BASE_CACHED | 0x00F8)) +#define __OSCoreClock (*(u32 *)(OS_BASE_CACHED | 0x00FC)) +#endif -volatile u16 __OSDeviceCode AT_ADDRESS(0x800030E6); +#define OS_BUS_CLOCK __OSBusClock +#define OS_CORE_CLOCK __OSCoreClock +#define OS_TIMER_CLOCK (OS_BUS_CLOCK/4) -volatile u32 OS_PI_INTR_CAUSE AT_ADDRESS(0xCC003000); -volatile u32 OS_PI_INTR_MASK AT_ADDRESS(0xCC003004); - -volatile u16 OS_MI_INTR_MASK AT_ADDRESS(0xCC00401C); - -volatile u16 OS_DSP_DMA_ADDR_HI AT_ADDRESS(0xCC005030); -volatile u16 OS_DSP_DMA_ADDR_LO AT_ADDRESS(0xCC005032); -volatile u16 OS_DSP_INTR_MASK AT_ADDRESS(0xCC00500A); - -volatile u16 OS_ARAM_DMA_ADDR_HI AT_ADDRESS(0xCC005020); -volatile u16 OS_ARAM_DMA_ADDR_LO AT_ADDRESS(0xCC005022); - -BOOL OSIsThreadSuspended(OSThread* thread); +#define OSTicksToSeconds(ticks) ((ticks) / (OS_TIMER_CLOCK)) +#define OSTicksToMilliseconds(ticks) ((ticks) / (OS_TIMER_CLOCK/1000)) +#define OSTicksToMicroseconds(ticks) ((ticks) * 8 / (OS_TIMER_CLOCK/125000)) +#define OSSecondsToTicks(sec) ((sec) * (OS_TIMER_CLOCK)) +#define OSMillisecondsToTicks(msec) ((msec) * (OS_TIMER_CLOCK / 1000)) +#define OSNanosecondsToTicks(nsec) (((nsec) * (OS_TIMER_CLOCK / 125000)) / 8000) +#define OSMicrosecondsToTicks(usec) (((usec) * (OS_TIMER_CLOCK / 125000)) / 8) u32 OSGetConsoleType(void); +void OSInit(void); +void OSRegisterVersion(const char* id); -void OSAttention(const char* msg, ...); -void OSPanic(const char* file, s32 line, const char* fmt, ...); -void OSReport(char* fmt, ...); -void OSReport_Error(const char* fmt, ...); -void OSReport_FatalError(const char* fmt, ...); -void OSReport_System(const char* fmt, ...); -void OSReport_Warning(const char* fmt, ...); -void OSReportDisable(void); -void OSReportEnable(void); -void OSReportForceEnableOff(void); -void OSReportForceEnableOn(void); -void OSVReport(const char* format, va_list list); +void* OSGetArenaHi(void); +void* OSGetArenaLo(void); +void OSSetArenaHi(void* newHi); +void OSSetArenaLo(void* newLo); +void* OSAllocFromArenaLo(u32 size, u32 align); +void* OSAllocFromArenaHi(u32 size, u32 align); + +u32 OSGetPhysicalMemSize(void); + +void __OSPSInit(void); +void __OSFPRInit(void); +u32 __OSGetDIConfig(void); + +void OSDefaultExceptionHandler(__OSException exception, OSContext* context); + +typedef struct OSCalendarTime { + /* 0x00 */ int sec; + /* 0x04 */ int min; + /* 0x08 */ int hour; + /* 0x0C */ int mday; + /* 0x10 */ int mon; + /* 0x14 */ int year; + /* 0x18 */ int wday; + /* 0x1C */ int yday; + /* 0x20 */ int msec; + /* 0x24 */ int usec; +} OSCalendarTime; + +#include +typedef struct OSBootInfo_s { + DVDDiskID DVDDiskID; + u32 magic; + u32 version; + u32 memorySize; + u32 consoleType; + void* arenaLo; + void* arenaHi; + void* FSTLocation; + u32 FSTMaxLength; +} OSBootInfo; + +typedef struct OSStopwatch { + char* name; + u32 hits; + OSTime total; + OSTime min; + OSTime max; + OSTime last; + BOOL running; + u32 _padding; +} OSStopwatch; + +void OSInitStopwatch(OSStopwatch* sw, char* name); +void OSStartStopwatch(OSStopwatch* sw); +void OSStopStopwatch(OSStopwatch* sw); +OSTime OSCheckStopwatch(OSStopwatch* sw); +void OSResetStopwatch(OSStopwatch* sw); +void OSDumpStopwatch(OSStopwatch* sw); + +OSTick OSGetTick(void); +OSTime OSGetTime(void); +void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* td); +OSTime OSCalendarTimeToTicks(OSCalendarTime* td); +BOOL OSEnableInterrupts(void); +BOOL OSDisableInterrupts(void); +BOOL OSRestoreInterrupts(BOOL level); + +#define OS_CONSOLE_MASK 0xF0000000 +#define OS_CONSOLE_RETAIL 0x00000000 +#define OS_CONSOLE_DEVELOPMENT 0x10000000 +#define OS_CONSOLE_TDEV 0x20000000 + +#define OS_CONSOLE_RETAIL4 0x00000004 +#define OS_CONSOLE_RETAIL3 0x00000003 +#define OS_CONSOLE_RETAIL2 0x00000002 +#define OS_CONSOLE_RETAIL1 0x00000001 +#define OS_CONSOLE_TDEVHW4 0x20000007 +#define OS_CONSOLE_TDEVHW3 0x20000006 +#define OS_CONSOLE_TDEVHW2 0x20000005 +#define OS_CONSOLE_TDEVHW1 0x20000004 +#define OS_CONSOLE_DEVHW4 0x10000007 +#define OS_CONSOLE_DEVHW3 0x10000006 +#define OS_CONSOLE_DEVHW2 0x10000005 +#define OS_CONSOLE_DEVHW1 0x10000004 +#define OS_CONSOLE_MINNOW 0x10000003 +#define OS_CONSOLE_ARTHUR 0x10000002 +#define OS_CONSOLE_PC_EMULATOR 0x10000001 +#define OS_CONSOLE_EMULATOR 0x10000000 + +#define OS_SOUND_MODE_MONO 0 +#define OS_SOUND_MODE_STEREO 1 + +u32 OSGetSoundMode(void); +void OSSetSoundMode(u32 mode); + +__declspec(weak) void OSReport(const char* msg, ...); +__declspec(weak) void OSVReport(const char* msg, va_list list); +__declspec(weak) void OSPanic(const char* file, int line, const char* msg, ...); +void OSFatal(GXColor fg, GXColor bg, const char* msg); + +// do these belong here? +__declspec(weak) void OSAttention(const char* msg, ...); +__declspec(weak) void OSReport_Error(const char* fmt, ...); +__declspec(weak) void OSReport_FatalError(const char* fmt, ...); +__declspec(weak) void OSReport_System(const char* fmt, ...); +__declspec(weak) void OSReport_Warning(const char* fmt, ...); +__declspec(weak) void OSReportDisable(void); +__declspec(weak) void OSReportEnable(void); +__declspec(weak) void OSReportForceEnableOff(void); +__declspec(weak) void OSReportForceEnableOn(void); +__declspec(weak) void OSVReport(const char* format, va_list list); #ifdef DEBUG #define OS_REPORT(...) OSReport(__VA_ARGS__) #define OS_WARNING(...) OSReport_Warning(__VA_ARGS__) #define OS_REPORT_ERROR(...) OSReport_Error(__VA_ARGS__) #define OS_PANIC(msg) OSPanic(__FILE__, __LINE__, msg) -#define ASSERTMSG(exp, msg) (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg)), 0)) #else #define OS_REPORT(...) #define OS_WARNING(...) #define OS_REPORT_ERROR(...) #define OS_PANIC(...) -#define ASSERTMSG(exp, msg) ((void)0) #endif extern u8 __OSReport_disable; @@ -116,29 +223,67 @@ extern u8 __OSReport_Warning_disable; extern u8 __OSReport_System_disable; extern u8 __OSReport_enable; -extern BOOL __OSIsGcam; +#define OSRoundUp32B(x) (((u32)(x) + 32 - 1) & ~(32 - 1)) +#define OSRoundDown32B(x) (((u32)(x)) & ~(32 - 1)) -void OSReportInit__Fv(void); // needed for inline asm +void* OSPhysicalToCached(u32 paddr); +void* OSPhysicalToUncached(u32 paddr); +u32 OSCachedToPhysical(void* caddr); +u32 OSUncachedToPhysical(void* ucaddr); +void* OSCachedToUncached(void* caddr); +void* OSUncachedToCached(void* ucaddr); -u8* OSGetStackPointer(void); -void __OSFPRInit(void); -static void InquiryCallback(s32 param_0, DVDCommandBlock* param_1); -void OSInit(void); -static void OSExceptionInit(void); -void __OSDBIntegrator(void); -void __OSDBJump(void); +#if !DEBUG +#define OSPhysicalToCached(paddr) ((void*) ((u32)(OS_BASE_CACHED + (u32)(paddr)))) +#define OSPhysicalToUncached(paddr) ((void*) ((u32)(OS_BASE_UNCACHED + (u32)(paddr)))) +#define OSCachedToPhysical(caddr) ((u32) ((u32)(caddr) - OS_BASE_CACHED)) +#define OSUncachedToPhysical(ucaddr) ((u32) ((u32)(ucaddr) - OS_BASE_UNCACHED)) +#define OSCachedToUncached(caddr) ((void*) ((u8*)(caddr) + (OS_BASE_UNCACHED - OS_BASE_CACHED))) +#define OSUncachedToCached(ucaddr) ((void*) ((u8*)(ucaddr) - (OS_BASE_UNCACHED - OS_BASE_CACHED))) +#endif -typedef void (*OSExceptionHandler)(__OSException, OSContext*); -OSExceptionHandler __OSSetExceptionHandler(__OSException exception, OSExceptionHandler handler); -OSExceptionHandler __OSGetExceptionHandler(__OSException exception); -static void OSExceptionVector(void); -void __DBVECTOR(); -void __OSEVSetNumber(); -void __OSEVEnd(); -static void OSDefaultExceptionHandler(__OSException exception, OSContext* context); -void __OSPSInit(void); -u32 __OSGetDIConfig(void); -void OSRegisterVersion(const char* version); +// unsorted externs +extern OSTime __OSGetSystemTime(void); +__declspec(weak) extern int __OSIsGcam; +extern OSExecParams __OSRebootParams; +extern OSTime __OSStartTime; +extern int __OSInIPL; + +// helper for assert line numbers in different revisions +#if SDK_REVISION < 1 + #define LINE(l0, l1, l2) (l0) +#elif SDK_REVISION < 2 + #define LINE(l0, l1, l2) (l1) +#else + #define LINE(l0, l1, l2) (l2) +#endif + +#ifdef DEBUG +#define ASSERTLINE(line, cond) \ + ((cond) || (OSPanic(__FILE__, line, "Failed assertion " #cond), 0)) + +#define ASSERTMSGLINE(line, cond, msg) \ + ((cond) || (OSPanic(__FILE__, line, msg), 0)) + +// This is dumb but we dont have a Metrowerks way to do variadic macros in the macro to make this done in a not scrubby way. +#define ASSERTMSG1LINE(line, cond, msg, arg1) \ + ((cond) || (OSPanic(__FILE__, line, msg, arg1), 0)) + +#define ASSERTMSG2LINE(line, cond, msg, arg1, arg2) \ + ((cond) || (OSPanic(__FILE__, line, msg, arg1, arg2), 0)) + +#define ASSERTMSGLINEV(line, cond, ...) \ + ((cond) || (OSPanic(__FILE__, line, __VA_ARGS__), 0)) + +#else +#define ASSERTLINE(line, cond) (void)0 +#define ASSERTMSGLINE(line, cond, msg) (void)0 +#define ASSERTMSG1LINE(line, cond, msg, arg1) (void)0 +#define ASSERTMSG2LINE(line, cond, msg, arg1, arg2) (void)0 +#define ASSERTMSGLINEV(line, cond, ...) (void)0 +#endif + +#define ASSERT(cond) ASSERTLINE(__LINE__, cond) inline s16 __OSf32tos16(register f32 inF) { register s16 out; @@ -201,126 +346,8 @@ static inline void OSInitFastCast(void) { // clang-format on } -typedef struct OSBootInfo { - /* 0x00 */ DVDDiskID disk_info; - /* 0x20 */ u32 boot_code; - /* 0x24 */ u32 version; - /* 0x28 */ u32 memory_size; - /* 0x2C */ u32 console_type; - /* 0x30 */ void* arena_lo; - /* 0x34 */ void* arena_hi; - /* 0x38 */ void* fst_location; - /* 0x3C */ u32 fst_max_length; -} OSBootInfo; - -typedef struct BI2Debug { - /* 0x00 */ s32 debugMonSize; - /* 0x04 */ s32 simMemSize; - /* 0x08 */ u32 argOffset; - /* 0x0C */ u32 debugFlag; - /* 0x10 */ int trackLocation; - /* 0x14 */ int trackSize; - /* 0x18 */ u32 countryCode; - /* 0x1C */ u8 unk[8]; - /* 0x24 */ u32 padSpec; -} BI2Debug; - -struct GLOBAL_MEMORY { - DVDDiskID disk; - u32 nintendo_boot_code; /* Nintendo Standard Boot Code. */ - u32 field_0x24; /* Version (set by apploader) */ - u32 memory_size; /* Memory Size (Physical) 24MB */ - u32 field_0x2c; /* Production Board Model */ - u32 arena_low; /* Arena Low */ - u32 arena_high; /* Arena High */ - u32 field_0x38; /* Start of FST (varies in all games) */ - u32 field_0x3c; /* Maximum FST Size (varies in all games) */ - u8 padding_0x40[32]; - u8 field_0x60[36]; /* Hook is PPC assembler used by Debugger. */ - u8 padding_0x84[84]; - OSContext* field_0xd8; /* Current OSContext instance. */ - OSThread* field_0xdc; /* OSThread pointer, previously created thread. */ - OSThread* field_0xe0; /* OSThread pointer, most recently created thread. */ - OSThread* field_0xe4; /* Current thread pointer. */ - u32 field_0xe8; /* Dev Debugger Monitor Address (If present) */ - u32 field_0xec; /* Simulated Memory Size */ - u32 field_0xf0; /* Pointer to data read from partition's bi2.bin, set by apploader */ - u32 field_0xf4; /* Console Bus Speed */ - u32 field_0xf8; /* Console CPU Speed */ - u8 padding_0xfc[5892]; - u8 field_0x1800[6144]; /* Unused Exception Vector */ - u8 padding_0x3000[64]; - u32 field_0x3040[34]; /* __OSInterrupt table. */ - u32 field_0x30c8; /* Pointer to the first loaded REL file. */ - u32 field_0x30cc; /* Pointer to the last loaded REL file. */ - u32 field_0x30d0; /* Pointer to a REL module name table, or 0. */ - u8 padding_0x30d8[4]; - u64 field_0x30d8; /* System time */ - u8 padding_0x30e0[4]; - u32 field_0x30e4; /* __OSPADButton */ - u8 padding_0x30ec[8]; - OSExecParams* field_0x30f0; /* DOL Execute Parameters */ - u8 padding_0x30f4[12]; - u32 field_0x3100; /* Physical MEM1 size */ - u32 field_0x3104; /* Simulated MEM1 size */ - u8 padding_0x3108[8]; - u32 field_0x3110; /* Heap pointer (end of usable memory by the game) */ - u8 padding_0x3114[4]; - u32 field_0x3118; /* Physical MEM2 size */ - u32 field_0x311c; /* Simulated MEM2 size */ - u8 padding_0x3120[16]; - u32 field_0x3130; /* IOS Heap Range (start) */ - u32 field_0x3134; /* IOS Heap Range (end) */ - u32 field_0x3138; /* Hollywood Version */ - u8 padding_0x313c[4]; - u32 field_0x3140; /* IOS version */ - u32 field_0x3144; /* IOS Build Date */ - u8 padding_0x3148[16]; - u32 field_0x3158; /* GDDR Vendor Code */ - u32 field_0x315c; /* During the boot process, */ - u32 field_0x3160; /* Init semaphore (1-2 main() waits for this to clear) */ - u32 field_0x3164; /* GC (MIOS) mode flag? */ - u8 padding_0x3168[24]; - u32 field_0x3180; /* Game ID */ - u8 field_0x3184; /* Application type. 0x80 for disc games, 0x81 for channels. */ - u8 padding_0x3185; - u8 field_0x3186; /* Application type 2 */ - u8 padding_0x3187; - u32 field_0x3188; /* Minimum IOS version */ - u32 field_0x318c; /* Title Booted from NAND (Launch Code) */ - u32 field_0x3190; /* Title Booted from NAND (Return Code) */ - u32 field_0x3194; /* While reading a disc, the system menu reads the first partition table (0x20 - bytes from 0x00040020) and stores a pointer to the data partition entry. - When launching the disc game, it copies the partition type to 0x3194. The - partition type for data partitions is 0, so typically this location always - has 0. */ - u32 field_0x3198; /* While reading a disc, the system menu reads the first partition table (0x20 - bytes from 0x00040020) and stores a pointer to the data partition entry. - When launching the disc game, it copies the partition offset to 0x3198. */ - u32 field_0x319c; /* Set by the apploader to 0x80 for single-layer discs and 0x81 for dual-layer - discs (determined by whether 0x7ed40000 is the value at offset 0x30 in the - partition's bi2.bin; it seems that that value is 0 for single-layer discs). - Early titles' apploaders do not set it at all, leaving the value as 0. This - controls the /dev/di#0x8D_DVDLowUnencryptedRead out-of-bounds Error #001 - read for titles that do make such a read: they try to read at 0x7ed40000 - for dual-layer discs and 0x460a0000 for single-layer discs. */ - u8 field_0x31a0[3424]; -}; - -#define OS_ASSERT(...) - -#define OSPhysicalToCached(paddr) ((void*)((u32)(paddr) + OS_BASE_CACHED)) -#define OSPhysicalToUncached(paddr) ((void*)((u32)(paddr) + OS_BASE_UNCACHED)) -#define OSCachedToPhysical(caddr) ((u32)((u8*)(caddr)-OS_BASE_CACHED)) -#define OSUncachedToPhysical(ucaddr) ((u32)((u8*)(ucaddr)-OS_BASE_UNCACHED)) -#define OSCachedToUncached(caddr) ((void*)((u8*)(caddr) + (OS_BASE_UNCACHED - OS_BASE_CACHED))) -#define OSUncachedToCached(ucaddr) ((void*)((u8*)(ucaddr) - (OS_BASE_UNCACHED - OS_BASE_CACHED))) - -extern OSTime __OSStartTime; -extern BOOL __OSInIPL; - #ifdef __cplusplus -}; +} #endif #endif diff --git a/include/dolphin/os/OSAlarm.h b/include/dolphin/os/OSAlarm.h index 658e988e62..3105039181 100644 --- a/include/dolphin/os/OSAlarm.h +++ b/include/dolphin/os/OSAlarm.h @@ -1,46 +1,36 @@ -#ifndef OSALARM_H -#define OSALARM_H +#ifndef _DOLPHIN_OSALARM_H_ +#define _DOLPHIN_OSALARM_H_ -#include "dolphin/os/OSError.h" -#include "dolphin/os/OSTime.h" +#include #ifdef __cplusplus extern "C" { #endif -typedef struct OSAlarmLink { - /* 0x0 */ struct OSAlarm* prev; - /* 0x4 */ struct OSAlarm* next; -} OSAlarmLink; - -typedef struct OSAlarm; -typedef void (*OSAlarmHandler)(struct OSAlarm* alarm, OSContext* context); - -typedef struct OSAlarm { - /* 0x00 */ OSAlarmHandler handler; - /* 0x04 */ u32 tag; - /* 0x08 */ OSTime fire_time; - /* 0x10 */ OSAlarmLink link; - /* 0x18 */ OSTime period_time; - /* 0x20 */ OSTime start_time; -} OSAlarm; // Size: 0x28 - -typedef struct OSAlarmQueue { - OSAlarm* head; - OSAlarm* tail; -} OSAlarmQueue; +typedef struct OSAlarm OSAlarm; +typedef void (*OSAlarmHandler)(OSAlarm* alarm, OSContext* context); +struct OSAlarm { + OSAlarmHandler handler; + u32 tag; + OSTime fire; + OSAlarm* prev; + OSAlarm* next; + OSTime period; + OSTime start; +}; +BOOL OSCheckAlarmQueue(void); void OSInitAlarm(void); void OSCreateAlarm(OSAlarm* alarm); -static void InsertAlarm(OSAlarm* alarm, s64 time, OSAlarmHandler handler); -void OSSetAlarm(OSAlarm* alarm, s64 time, OSAlarmHandler handler); -void OSSetPeriodicAlarm(OSAlarm* alarm, s64 start, s64 period, OSAlarmHandler handler); -void OSCancelAlarm(OSAlarm* alarm); -static void DecrementerExceptionCallback(__OSException exception, OSContext* context); -static void DecrementerExceptionHandler(__OSException exception, OSContext* context); +void OSSetAlarm(OSAlarm* alarm, OSTime tick, OSAlarmHandler handler); +void OSSetAbsAlarm(OSAlarm* alarm, OSTime time, OSAlarmHandler handler); +void OSSetPeriodicAlarm(OSAlarm* alarm, OSTime start, OSTime period, OSAlarmHandler handler); +void OSCancelAlarm(OSAlarm *alarm); +void OSSetAlarmTag(OSAlarm* alarm, u32 tag); +void OSCancelAlarms(u32 tag); #ifdef __cplusplus -}; +} #endif -#endif /* OSALARM_H */ +#endif // _DOLPHIN_OSALARM_H_ diff --git a/include/dolphin/os/OSAlloc.h b/include/dolphin/os/OSAlloc.h index ffb5e0c9c0..77eb88661f 100644 --- a/include/dolphin/os/OSAlloc.h +++ b/include/dolphin/os/OSAlloc.h @@ -1,48 +1,34 @@ -#ifndef OSALLOC_H -#define OSALLOC_H +#ifndef _DOLPHIN_OSALLOC_H_ +#define _DOLPHIN_OSALLOC_H_ -#include "dolphin/types.h" +#include #ifdef __cplusplus extern "C" { #endif -typedef struct OSHeapDescriptor { - /* 0x0 */ s32 size; - /* 0x4 */ struct OSHeapCell* freeList; - /* 0x8 */ struct OSHeapCell* usedList; -} OSHeapDescriptor; +typedef int OSHeapHandle; -typedef struct OSHeapCell { - /* 0x00 */ struct OSHeapCell* prev; - /* 0x04 */ struct OSHeapCell* next; - /* 0x08 */ s32 size; - /* 0x0C */ struct OSHeapDescriptor* hd; - /* 0x10 */ s32 usedSize; - /* 0x14 */ char field_0x14[0x20 - 0x14]; -} OSHeapCell; +extern volatile OSHeapHandle __OSCurrHeap; -typedef u32 OSHeapHandle; +void* OSAllocFromHeap(int heap, u32 size); +void* OSAllocFixed(void* rstart, void* rend); +void OSFreeToHeap(int heap, void* ptr); +int OSSetCurrentHeap(int heap); +void* OSInitAlloc(void* arenaStart, void* arenaEnd, int maxHeaps); +int OSCreateHeap(void* start, void* end); +void OSDestroyHeap(int heap); +void OSAddToHeap(int heap, void* start, void* end); +s32 OSCheckHeap(int heap); +u32 OSReferentSize(void* ptr); +void OSDumpHeap(int heap); +void OSVisitAllocated(void (*visitor)(void*, u32)); -extern volatile s32 __OSCurrHeap; - -#define OSRoundUp32B(x) (((u32)(x) + 0x1F) & ~(0x1F)) -#define OSRoundDown32B(x) (((u32)(x)) & ~(0x1F)) - -#define OSRoundUp(x, align) (((x) + (align)-1) & (-(align))) -#define OSRoundUpPtr(x, align) ((void*)((((u32)(x)) + (align)-1) & (~((align)-1)))) - -#define OSRoundDown(x, align) ((x) & (-(align))) -#define OSRoundDownPtr(x, align) ((void*)(((u32)(x)) & (~((align)-1)))) - -static OSHeapCell* DLInsert(OSHeapCell* list, OSHeapCell* child); -void OSFreeToHeap(OSHeapHandle handle, void* ptr); -s32 OSSetCurrentHeap(OSHeapHandle handle); -void* OSInitAlloc(void* lo, void* hi, s32 maxHeaps); -OSHeapHandle OSCreateHeap(void* start, void* end); +#define OSAlloc(size) OSAllocFromHeap(__OSCurrHeap, (size)) +#define OSFree(ptr) OSFreeToHeap(__OSCurrHeap, (ptr)) #ifdef __cplusplus -}; +} #endif -#endif /* OSALLOC_H */ +#endif diff --git a/include/dolphin/os/OSArena.h b/include/dolphin/os/OSArena.h deleted file mode 100644 index 4e5a76c294..0000000000 --- a/include/dolphin/os/OSArena.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef OSARENA_H -#define OSARENA_H - -#include "dolphin/types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void* OSGetArenaHi(void); -void* OSGetArenaLo(void); -void OSSetArenaHi(void* hi); -void OSSetArenaLo(void* lo); -void* OSAllocFromArenaLo(u32 size, s32 alignment); - -#ifdef __cplusplus -}; -#endif - -#endif /* OSARENA_H */ diff --git a/include/dolphin/os/OSAudioSystem.h b/include/dolphin/os/OSAudioSystem.h deleted file mode 100644 index cf1f3ed03a..0000000000 --- a/include/dolphin/os/OSAudioSystem.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef OSAUDIOSYSTEM_H -#define OSAUDIOSYSTEM_H - - -#ifdef __cplusplus -extern "C" { -#endif - -void __OSInitAudioSystem(void); -void __OSStopAudioSystem(void); - -#ifdef __cplusplus -}; -#endif - -#endif /* OSAUDIOSYSTEM_H */ diff --git a/include/dolphin/os/OSCache.h b/include/dolphin/os/OSCache.h index 23885420be..89e7ce96ba 100644 --- a/include/dolphin/os/OSCache.h +++ b/include/dolphin/os/OSCache.h @@ -1,34 +1,38 @@ -#ifndef OSCACHE_H -#define OSCACHE_H +#ifndef _DOLPHIN_OSCACHE_H_ +#define _DOLPHIN_OSCACHE_H_ -#include "dolphin/types.h" +#include #ifdef __cplusplus extern "C" { #endif -static void DCEnable(void); -void DCInvalidateRange(void* start, u32 nBytes); -void DCFlushRange(void* start, u32 nBytes); -void DCStoreRange(void* start, u32 nBytes); -void DCFlushRangeNoSync(void* start, u32 nBytes); -void DCStoreRangeNoSync(void* start, u32 nBytes); -void DCZeroRange(void* start, u32 nBytes); -void ICInvalidateRange(void* start, u32 nBytes); -void ICFlashInvalidate(void); -static void ICEnable(void); -void __LCEnable(void); +void DCInvalidateRange(void* addr, u32 nBytes); +void DCFlushRange(void* addr, u32 nBytes); +void DCStoreRange(void* addr, u32 nBytes); +void DCFlushRangeNoSync(void* addr, u32 nBytes); +void DCStoreRangeNoSync(void* addr, u32 nBytes); +void DCZeroRange(void* addr, u32 nBytes); +void DCTouchRange(void* addr, u32 nBytes); +void ICInvalidateRange(void* addr, u32 nBytes); + +#define LC_BASE_PREFIX 0xE000 +#define LC_BASE (LC_BASE_PREFIX << 16) +#define LCGetBase() ((void*)LC_BASE) + void LCEnable(void); void LCDisable(void); -static void LCStoreBlocks(void* destAddr, void* srcAddr, u32 blockNum); +void LCLoadBlocks(void* destTag, void* srcAddr, u32 numBlocks); +void LCStoreBlocks(void* destAddr, void* srcTag, u32 numBlocks); +u32 LCLoadData(void* destAddr, void* srcAddr, u32 nBytes); u32 LCStoreData(void* destAddr, void* srcAddr, u32 nBytes); +u32 LCQueueLength(void); void LCQueueWait(u32 len); -static void L2GlobalInvalidate(void); -static void DMAErrorHandler(u16 error, struct OSContext* context, ...); +void LCFlushQueue(void); void __OSCacheInit(void); #ifdef __cplusplus -}; +} #endif -#endif /* OSCACHE_H */ +#endif diff --git a/include/dolphin/os/OSContext.h b/include/dolphin/os/OSContext.h index 4137d90b2c..cbb0b92e4e 100644 --- a/include/dolphin/os/OSContext.h +++ b/include/dolphin/os/OSContext.h @@ -1,7 +1,7 @@ -#ifndef OSCONTEXT_H -#define OSCONTEXT_H +#ifndef _DOLPHIN_OSCONTEXT_H_ +#define _DOLPHIN_OSCONTEXT_H_ -#include "dolphin/types.h" +#include #ifdef __cplusplus extern "C" { @@ -141,35 +141,33 @@ typedef struct OSContext { /* 0x088 */ u32 ctr; /* 0x08C */ u32 xer; /* 0x090 */ f64 fpr[32]; - /* 0x190 */ u32 field_0x190; + /* 0x190 */ u32 fpscr_pad; /* 0x194 */ u32 fpscr; /* 0x198 */ u32 srr0; /* 0x19C */ u32 srr1; /* 0x1A0 */ u16 mode; /* 0x1A2 */ u16 state; /* 0x1A4 */ u32 gqr[8]; - /* 0x1C4 */ f64 ps[32]; + /* 0x1C4 */ u32 psf_pad; + /* 0x1C8 */ f64 psf[32]; } OSContext; -OSContext* OS_CURRENT_CONTEXT AT_ADDRESS(0x800000D4); -OSContext* OS_CURRENT_FPU_CONTEXT AT_ADDRESS(0x800000D8); - -void __OSLoadFPUContext(void); -void __OSSaveFPUContext(s32 unused0, s32 unused1, OSContext* context); -void OSSaveFPUContext(OSContext* context); -void OSSetCurrentContext(OSContext* context); -OSContext* OSGetCurrentContext(void); -u32 OSSaveContext(OSContext* context); -void OSLoadContext(OSContext* context); -void OSClearContext(OSContext* context); -void OSInitContext(OSContext* context, u32 pc, u32 lr); +u32 OSGetStackPointer(void); void OSDumpContext(OSContext* context); -static void OSSwitchFPUContext(u8 err, OSContext* context); -void __OSContextInit(void); +void OSLoadContext(OSContext* context); +u32 OSSaveContext(OSContext* context); +void OSClearContext(OSContext* context); +OSContext* OSGetCurrentContext(void); +void OSSetCurrentContext(OSContext* context); +void OSLoadFPUContext(OSContext* fpucontext); +void OSSaveFPUContext(OSContext* fpucontext); +u32 OSSwitchStack(u32 newsp); +int OSSwitchFiber(u32 pc, u32 newsp); +void OSInitContext(OSContext* context, u32 pc, u32 newsp); void OSFillFPUContext(OSContext* context); #ifdef __cplusplus -}; +} #endif -#endif /* OSCONTEXT_H */ +#endif diff --git a/include/dolphin/os/OSDC.h b/include/dolphin/os/OSDC.h new file mode 100644 index 0000000000..bab2d68edc --- /dev/null +++ b/include/dolphin/os/OSDC.h @@ -0,0 +1,23 @@ +#ifndef _DOLPHIN_OSDC_H_ +#define _DOLPHIN_OSDC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void DCFlashInvalidate(void); +void DCEnable(void); +void DCDisable(void); +void DCFreeze(void); +void DCUnfreeze(void); +void DCTouchLoad(void* addr); +void DCBlockZero(void* addr); +void DCBlockStore(void* addr); +void DCBlockFlush(void* addr); +void DCBlockInvalidate(void* addr); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/os/OSError.h b/include/dolphin/os/OSError.h index 833ce34633..4a2fc7bd71 100644 --- a/include/dolphin/os/OSError.h +++ b/include/dolphin/os/OSError.h @@ -1,66 +1,38 @@ -#ifndef OSERROR_H -#define OSERROR_H +#ifndef _DOLPHIN_OSERROR_H_ +#define _DOLPHIN_OSERROR_H_ -#include "dolphin/types.h" +#include #ifdef __cplusplus extern "C" { #endif -typedef struct OSContext OSContext; - -extern u32 __OSFpscrEnableBits; typedef u16 OSError; +typedef void (*OSErrorHandler)(OSError error, OSContext* context, ...); -#define OS_ERROR_SYSTEM_RESET 0 -#define OS_ERROR_MACHINE_CHECK 1 -#define OS_ERROR_DSI 2 -#define OS_ERROR_ISI 3 -#define OS_ERROR_INTERRUPT 4 -#define OS_ERROR_ALIGNMENT 5 -#define OS_ERROR_PROGRAM 6 -#define OS_ERROR_FLOATING_POINT 7 -#define OS_ERROR_DECREMENTER 8 -#define OS_ERROR_SYSTEM_CALL 9 -#define OS_ERROR_TRACE 10 -#define OS_ERROR_PERFORMANCE_MONITOR 11 -#define OS_ERROR_BREAKPOINT 12 -#define OS_ERROR_RESERVED 13 -#define OS_ERROR_THERMAL_INTERRUPT 14 -#define OS_ERROR_MEMORY_PROTECTION 15 -#define OS_ERROR_FLOATING_POINT_EXCEPTION 16 - -typedef enum { - EXCEPTION_SYSTEM_RESET, - EXCEPTION_MACHINE_CHECK, - EXCEPTION_DSI, - EXCEPTION_ISI, - EXCEPTION_EXTERNAL_INTERRUPT, - EXCEPTION_ALIGNMENT, - EXCEPTION_PROGRAM, - EXCEPTION_FLOATING_POINT, - EXCEPTION_DECREMENTER, - EXCEPTION_SYSTEM_CALL, - EXCEPTION_TRACE , - EXCEPTION_PERFORMANCE_MONITOR, - EXCEPTION_BREAKPOINT, - EXCEPTION_RESERVED, - EXCEPTION_THERMAL_INTERRUPT, - EXCEPTION_MEMORY_PROTECTION, - EXCEPTION_FLOATING_POINT_EXCEPTION, -} OSException; - -typedef u8 __OSException; - -typedef void (*OSErrorHandler)(OSError error, OSContext* context, u32, u32); -// Using this type for the C++ handlers makes stuff not match -typedef void (*OSErrorHandlerEx)(OSError error, OSContext* context, u32, u32, ...); +#define OS_ERROR_SYSTEM_RESET 0 +#define OS_ERROR_MACHINE_CHECK 1 +#define OS_ERROR_DSI 2 +#define OS_ERROR_ISI 3 +#define OS_ERROR_EXTERNAL_INTERRUPT 4 +#define OS_ERROR_ALIGNMENT 5 +#define OS_ERROR_PROGRAM 6 +#define OS_ERROR_FLOATING_POINT 7 +#define OS_ERROR_DECREMENTER 8 +#define OS_ERROR_SYSTEM_CALL 9 +#define OS_ERROR_TRACE 10 +#define OS_ERROR_PERFORMACE_MONITOR 11 +#define OS_ERROR_BREAKPOINT 12 +#define OS_ERROR_SYSTEM_INTERRUPT 13 +#define OS_ERROR_THERMAL_INTERRUPT 14 +#define OS_ERROR_MAX (OS_ERROR_THERMAL_INTERRUPT + 1) OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler); -void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar); +extern u32 __OSFpscrEnableBits; +extern OSErrorHandler __OSErrorTable[17]; #ifdef __cplusplus -}; +} #endif -#endif /* OSERROR_H */ +#endif diff --git a/include/dolphin/os/OSException.h b/include/dolphin/os/OSException.h new file mode 100644 index 0000000000..e9a2f22569 --- /dev/null +++ b/include/dolphin/os/OSException.h @@ -0,0 +1,61 @@ +#ifndef _DOLPHIN_OSEXCEPTION_H_ +#define _DOLPHIN_OSEXCEPTION_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define __OS_EXCEPTION_SYSTEM_RESET 0 +#define __OS_EXCEPTION_MACHINE_CHECK 1 +#define __OS_EXCEPTION_DSI 2 +#define __OS_EXCEPTION_ISI 3 +#define __OS_EXCEPTION_EXTERNAL_INTERRUPT 4 +#define __OS_EXCEPTION_ALIGNMENT 5 +#define __OS_EXCEPTION_PROGRAM 6 +#define __OS_EXCEPTION_FLOATING_POINT 7 +#define __OS_EXCEPTION_DECREMENTER 8 +#define __OS_EXCEPTION_SYSTEM_CALL 9 +#define __OS_EXCEPTION_TRACE 10 +#define __OS_EXCEPTION_PERFORMACE_MONITOR 11 +#define __OS_EXCEPTION_BREAKPOINT 12 +#define __OS_EXCEPTION_SYSTEM_INTERRUPT 13 +#define __OS_EXCEPTION_THERMAL_INTERRUPT 14 +#define __OS_EXCEPTION_MEMORY_PROTECTION 15 +#define __OS_EXCEPTION_FLOATING_POINT_EXCEPTION 16 +#define __OS_EXCEPTION_MAX \ + (__OS_EXCEPTION_THERMAL_INTERRUPT+1) + +typedef u8 __OSException; +typedef void (*__OSExceptionHandler)(__OSException exception, OSContext* context); + +__OSExceptionHandler __OSSetExceptionHandler(__OSException exception, __OSExceptionHandler handler); +__OSExceptionHandler __OSGetExceptionHandler(__OSException exception); + +#define OS_EXCEPTION_SAVE_GPRS(context) \ + stw r0, OS_CONTEXT_R0(context); \ + stw r1, OS_CONTEXT_R1(context); \ + stw r2, OS_CONTEXT_R2(context); \ + stmw r6, OS_CONTEXT_R6(context); \ + mfspr r0, GQR1; \ + stw r0, OS_CONTEXT_GQR1(context); \ + mfspr r0, GQR2; \ + stw r0, OS_CONTEXT_GQR2(context); \ + mfspr r0, GQR3; \ + stw r0, OS_CONTEXT_GQR3(context); \ + mfspr r0, GQR4; \ + stw r0, OS_CONTEXT_GQR4(context); \ + mfspr r0, GQR5; \ + stw r0, OS_CONTEXT_GQR5(context); \ + mfspr r0, GQR6; \ + stw r0, OS_CONTEXT_GQR6(context); \ + mfspr r0, GQR7; \ + stw r0, OS_CONTEXT_GQR7(context); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_OSEXCEPTION_H_ diff --git a/include/dolphin/os/OSExec.h b/include/dolphin/os/OSExec.h index 23d6efb649..af0dc4da0c 100644 --- a/include/dolphin/os/OSExec.h +++ b/include/dolphin/os/OSExec.h @@ -1,20 +1,20 @@ -#ifndef OSEXEC_H -#define OSEXEC_H +#ifndef _DOLPHIN_OSEXEC_H_ +#define _DOLPHIN_OSEXEC_H_ -#include "dolphin/types.h" +#include #ifdef __cplusplus extern "C" { #endif typedef struct { - /* 0x00 */ BOOL valid; - /* 0x04 */ u32 restartCode; - /* 0x08 */ u32 bootDol; - /* 0x0C */ void* regionStart; - /* 0x10 */ void* regionEnd; - /* 0x18 */ BOOL argsUseDefault; - /* 0x14 */ void* argsAddr; // valid only when argsUseDefault = FALSE + BOOL valid; + u32 restartCode; + u32 bootDol; + void* regionStart; + void* regionEnd; + int argsUseDefault; + void* argsAddr; } OSExecParams; typedef int (*appGetNextCallback)(void*, u32*, u32*); @@ -22,12 +22,14 @@ typedef void (*appInitCallback)(void (*)(char*)); typedef void* (*appGetEntryCallback)(); typedef void (*AppLoaderCallback)(appInitCallback*, appGetNextCallback*, appGetEntryCallback*); -void __OSGetExecParams(OSExecParams* param_0); -void __OSBootDolSimple(u32 doloffset, u32 restartCode, void* regionStart, void* regionEnd, BOOL argsUseDefault, s32 argc, char** argv); -void __OSBootDol(u32 doloffset, u32 restartCode, const char** argv); +OSExecParams* __OSExecParams AT_ADDRESS(0x800030F0); +s32 __OSAppLoaderOffset AT_ADDRESS(0x800030F4); + +void OSExecv(const char* dolfile, const char** argv); +void OSExecl(const char* dolfile, const char* arg0, ...); #ifdef __cplusplus -}; +} #endif -#endif /* OSEXEC_H */ +#endif diff --git a/include/dolphin/os/OSFont.h b/include/dolphin/os/OSFont.h index c83f573049..1fff41a629 100644 --- a/include/dolphin/os/OSFont.h +++ b/include/dolphin/os/OSFont.h @@ -1,54 +1,58 @@ -#ifndef OSFONT_H -#define OSFONT_H +#ifndef _DOLPHIN_OSFONT_H_ +#define _DOLPHIN_OSFONT_H_ -#include "dolphin/types.h" +#include +#include #ifdef __cplusplus extern "C" { #endif -typedef enum { - OS_FONT_ENCODE_ANSI, - OS_FONT_ENCODE_SJIS, - OS_FONT_ENCODE_2, - OS_FONT_ENCODE_UTF8, - OS_FONT_ENCODE_UTF16, - OS_FONT_ENCODE_UTF32, - OS_FONT_ENCODE_MAX -} OSFontEncode; +#define OS_FONT_ENCODE_ANSI 0u +#define OS_FONT_ENCODE_SJIS 1u +#define OS_FONT_ENCODE_MAX 5u +#define OS_FONT_SIZE_ANSI (288 + 131072) // 9 sheets +#define OS_FONT_SIZE_SJIS (3840 + 1179648) // 1 sheet +#define OS_FONT_ROM_SIZE_ANSI 0x03000 +#define OS_FONT_ROM_SIZE_SJIS 0x4D000 typedef struct OSFontHeader { - /* 0x00 */ u16 type; - /* 0x02 */ u16 firstChar; - /* 0x04 */ u16 lastChar; - /* 0x06 */ u16 invalidChar; - /* 0x08 */ u16 ascent; - /* 0x0A */ u16 descent; - /* 0x0C */ u16 width; - /* 0x0E */ u16 leading; - /* 0x10 */ u16 cellWidth; - /* 0x12 */ u16 cellHeight; - /* 0x14 */ u32 sheetSize; - /* 0x18 */ u16 sheetFormat; - /* 0x1A */ u16 sheetNumCol; - /* 0x1C */ u16 sheetNumRow; - /* 0x1E */ u16 sheetWidth; - /* 0x20 */ u16 sheetHeight; - /* 0x22 */ u16 widthTableOfs; - /* 0x24 */ u32 sheetImageOfs; - /* 0x28 */ u32 sheetFullSize; - /* 0x2C */ u8 c0; - /* 0x2D */ u8 c1; - /* 0x2E */ u8 c2; - /* 0x2F */ u8 c3; + u16 fontType; + u16 firstChar; + u16 lastChar; + u16 invalChar; + u16 ascent; + u16 descent; + u16 width; + u16 leading; + u16 cellWidth; + u16 cellHeight; + u32 sheetSize; + u16 sheetFormat; + u16 sheetColumn; + u16 sheetRow; + u16 sheetWidth; + u16 sheetHeight; + u16 widthTable; + u32 sheetImage; + u32 sheetFullSize; + u8 c0; + u8 c1; + u8 c2; + u8 c3; } OSFontHeader; -static u32 GetFontCode(u16 param_0, u16 param_1); u16 OSGetFontEncode(void); -static const u8* ParseStringS(u16 encode, const u8* str, OSFontHeader** fontOut, u32* codeOut); +u16 OSSetFontEncode(u16 encode); +BOOL OSInitFont(OSFontHeader* fontData); +u32 OSLoadFont(OSFontHeader* fontData, void* tmp); +char* OSGetFontTexture(const char* string, void** image, s32* x, s32* y, s32* width); +char* OSGetFontWidth(const char* string, s32* width); +char* OSGetFontTexel(const char* string, void* image, s32 pos, s32 stride, s32* width); +int OSSetFontWidth(int fixed); #ifdef __cplusplus -}; +} #endif -#endif /* OSFONT_H */ +#endif diff --git a/include/dolphin/os/OSIC.h b/include/dolphin/os/OSIC.h new file mode 100644 index 0000000000..3309d3a6f1 --- /dev/null +++ b/include/dolphin/os/OSIC.h @@ -0,0 +1,20 @@ +#ifndef _DOLPHIN_OSIC_H_ +#define _DOLPHIN_OSIC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void ICFlashInvalidate(void); +void ICEnable(void); +void ICDisable(void); +void ICFreeze(void); +void ICUnfreeze(void); +void ICBlockInvalidate(void *addr); +void ICSync(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/os/OSInterrupt.h b/include/dolphin/os/OSInterrupt.h index 34b68a1eec..fb74135a2b 100644 --- a/include/dolphin/os/OSInterrupt.h +++ b/include/dolphin/os/OSInterrupt.h @@ -1,134 +1,118 @@ -#ifndef OSINTERRUPT_H -#define OSINTERRUPT_H +#ifndef _DOLPHIN_OSINTERRUPT_H_ +#define _DOLPHIN_OSINTERRUPT_H_ -#include "dolphin/types.h" +#include +#include #ifdef __cplusplus extern "C" { #endif -typedef struct OSContext OSContext; +typedef s16 __OSInterrupt; +typedef u32 OSInterruptMask; -typedef enum { - OS_INTR_MEM_0, - OS_INTR_MEM_1, - OS_INTR_MEM_2, - OS_INTR_MEM_3, - OS_INTR_MEM_ADDRESS, - OS_INTR_DSP_AI, - OS_INTR_DSP_ARAM, - OS_INTR_DSP_DSP, - OS_INTR_AI_AI, - OS_INTR_EXI_0_EXI, - OS_INTR_EXI_0_TC, - OS_INTR_EXI_0_EXT, - OS_INTR_EXI_1_EXI, - OS_INTR_EXI_1_TC, - OS_INTR_EXI_1_EXT, - OS_INTR_EXI_2_EXI, - OS_INTR_EXI_2_TC, - OS_INTR_PI_CP, - OS_INTR_PI_PE_TOKEN, - OS_INTR_PI_PE_FINISH, - OS_INTR_PI_SI, - OS_INTR_PI_DI, - OS_INTR_PI_RSW, - OS_INTR_PI_ERROR, - OS_INTR_PI_VI, - OS_INTR_PI_DEBUG, - OS_INTR_PI_HSP, - OS_INTR_PI_ACR, - OS_INTR_28, - OS_INTR_29, - OS_INTR_30, - OS_INTR_31, - - OS_INTR_MAX -} OSInterruptType; +#define __OS_INTERRUPT_MEM_0 0 +#define __OS_INTERRUPT_MEM_1 1 +#define __OS_INTERRUPT_MEM_2 2 +#define __OS_INTERRUPT_MEM_3 3 +#define __OS_INTERRUPT_MEM_ADDRESS 4 +#define __OS_INTERRUPT_DSP_AI 5 +#define __OS_INTERRUPT_DSP_ARAM 6 +#define __OS_INTERRUPT_DSP_DSP 7 +#define __OS_INTERRUPT_AI_AI 8 +#define __OS_INTERRUPT_EXI_0_EXI 9 +#define __OS_INTERRUPT_EXI_0_TC 10 +#define __OS_INTERRUPT_EXI_0_EXT 11 +#define __OS_INTERRUPT_EXI_1_EXI 12 +#define __OS_INTERRUPT_EXI_1_TC 13 +#define __OS_INTERRUPT_EXI_1_EXT 14 +#define __OS_INTERRUPT_EXI_2_EXI 15 +#define __OS_INTERRUPT_EXI_2_TC 16 +#define __OS_INTERRUPT_PI_CP 17 +#define __OS_INTERRUPT_PI_PE_TOKEN 18 +#define __OS_INTERRUPT_PI_PE_FINISH 19 +#define __OS_INTERRUPT_PI_SI 20 +#define __OS_INTERRUPT_PI_DI 21 +#define __OS_INTERRUPT_PI_RSW 22 +#define __OS_INTERRUPT_PI_ERROR 23 +#define __OS_INTERRUPT_PI_VI 24 +#define __OS_INTERRUPT_PI_DEBUG 25 +#define __OS_INTERRUPT_PI_HSP 26 +#define __OS_INTERRUPT_MAX 32 #define OS_INTERRUPTMASK(interrupt) (0x80000000u >> (interrupt)) -#define OS_INTERRUPTMASK_MEM_0 OS_INTERRUPTMASK(OS_INTR_MEM_0) -#define OS_INTERRUPTMASK_MEM_1 OS_INTERRUPTMASK(OS_INTR_MEM_1) -#define OS_INTERRUPTMASK_MEM_2 OS_INTERRUPTMASK(OS_INTR_MEM_2) -#define OS_INTERRUPTMASK_MEM_3 OS_INTERRUPTMASK(OS_INTR_MEM_3) -#define OS_INTERRUPTMASK_MEM_ADDRESS OS_INTERRUPTMASK(OS_INTR_MEM_ADDRESS) +#define OS_INTERRUPTMASK_MEM_0 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_0) +#define OS_INTERRUPTMASK_MEM_1 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_1) +#define OS_INTERRUPTMASK_MEM_2 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_2) +#define OS_INTERRUPTMASK_MEM_3 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_3) +#define OS_INTERRUPTMASK_MEM_ADDRESS OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_ADDRESS) #define OS_INTERRUPTMASK_MEM_RESET \ (OS_INTERRUPTMASK_MEM_0 | OS_INTERRUPTMASK_MEM_1 | OS_INTERRUPTMASK_MEM_2 | \ OS_INTERRUPTMASK_MEM_3) #define OS_INTERRUPTMASK_MEM \ - (OS_INTERRUPTMASK_MEM_0 | OS_INTERRUPTMASK_MEM_1 | OS_INTERRUPTMASK_MEM_2 | \ - OS_INTERRUPTMASK_MEM_3 | OS_INTERRUPTMASK_MEM_ADDRESS) - -#define OS_INTERRUPTMASK_DSP_AI OS_INTERRUPTMASK(OS_INTR_DSP_AI) -#define OS_INTERRUPTMASK_DSP_ARAM OS_INTERRUPTMASK(OS_INTR_DSP_ARAM) -#define OS_INTERRUPTMASK_DSP_DSP OS_INTERRUPTMASK(OS_INTR_DSP_DSP) + (OS_INTERRUPTMASK_MEM_0 | OS_INTERRUPTMASK_MEM_1 | OS_INTERRUPTMASK_MEM_2 | \ + OS_INTERRUPTMASK_MEM_3 | OS_INTERRUPTMASK_MEM_ADDRESS) +#define OS_INTERRUPTMASK_DSP_AI OS_INTERRUPTMASK(__OS_INTERRUPT_DSP_AI) +#define OS_INTERRUPTMASK_DSP_ARAM OS_INTERRUPTMASK(__OS_INTERRUPT_DSP_ARAM) +#define OS_INTERRUPTMASK_DSP_DSP OS_INTERRUPTMASK(__OS_INTERRUPT_DSP_DSP) #define OS_INTERRUPTMASK_DSP \ - (OS_INTERRUPTMASK_DSP_AI | OS_INTERRUPTMASK_DSP_ARAM | OS_INTERRUPTMASK_DSP_DSP) - -#define OS_INTERRUPTMASK_AI_AI OS_INTERRUPTMASK(OS_INTR_AI_AI) + (OS_INTERRUPTMASK_DSP_AI | OS_INTERRUPTMASK_DSP_ARAM | OS_INTERRUPTMASK_DSP_DSP) +#define OS_INTERRUPTMASK_AI_AI OS_INTERRUPTMASK(__OS_INTERRUPT_AI_AI) #define OS_INTERRUPTMASK_AI (OS_INTERRUPTMASK_AI_AI) - -#define OS_INTERRUPTMASK_EXI_0_EXI OS_INTERRUPTMASK(OS_INTR_EXI_0_EXI) -#define OS_INTERRUPTMASK_EXI_0_TC OS_INTERRUPTMASK(OS_INTR_EXI_0_TC) -#define OS_INTERRUPTMASK_EXI_0_EXT OS_INTERRUPTMASK(OS_INTR_EXI_0_EXT) +#define OS_INTERRUPTMASK_EXI_0_EXI OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_0_EXI) +#define OS_INTERRUPTMASK_EXI_0_TC OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_0_TC) +#define OS_INTERRUPTMASK_EXI_0_EXT OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_0_EXT) #define OS_INTERRUPTMASK_EXI_0 \ - (OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_0_TC | OS_INTERRUPTMASK_EXI_0_EXT) - -#define OS_INTERRUPTMASK_EXI_1_EXI OS_INTERRUPTMASK(OS_INTR_EXI_1_EXI) -#define OS_INTERRUPTMASK_EXI_1_TC OS_INTERRUPTMASK(OS_INTR_EXI_1_TC) -#define OS_INTERRUPTMASK_EXI_1_EXT OS_INTERRUPTMASK(OS_INTR_EXI_1_EXT) + (OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_0_TC | OS_INTERRUPTMASK_EXI_0_EXT) +#define OS_INTERRUPTMASK_EXI_1_EXI OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_1_EXI) +#define OS_INTERRUPTMASK_EXI_1_TC OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_1_TC) +#define OS_INTERRUPTMASK_EXI_1_EXT OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_1_EXT) #define OS_INTERRUPTMASK_EXI_1 \ - (OS_INTERRUPTMASK_EXI_1_EXI | OS_INTERRUPTMASK_EXI_1_TC | OS_INTERRUPTMASK_EXI_1_EXT) - -#define OS_INTERRUPTMASK_EXI_2_EXI OS_INTERRUPTMASK(OS_INTR_EXI_2_EXI) -#define OS_INTERRUPTMASK_EXI_2_TC OS_INTERRUPTMASK(OS_INTR_EXI_2_TC) + (OS_INTERRUPTMASK_EXI_1_EXI | OS_INTERRUPTMASK_EXI_1_TC | OS_INTERRUPTMASK_EXI_1_EXT) +#define OS_INTERRUPTMASK_EXI_2_EXI OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_2_EXI) +#define OS_INTERRUPTMASK_EXI_2_TC OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_2_TC) #define OS_INTERRUPTMASK_EXI_2 (OS_INTERRUPTMASK_EXI_2_EXI | OS_INTERRUPTMASK_EXI_2_TC) #define OS_INTERRUPTMASK_EXI \ - (OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_0_TC | OS_INTERRUPTMASK_EXI_0_EXT | \ - OS_INTERRUPTMASK_EXI_1_EXI | OS_INTERRUPTMASK_EXI_1_TC | OS_INTERRUPTMASK_EXI_1_EXT | \ - OS_INTERRUPTMASK_EXI_2_EXI | OS_INTERRUPTMASK_EXI_2_TC) - -#define OS_INTERRUPTMASK_PI_PE_TOKEN OS_INTERRUPTMASK(OS_INTR_PI_PE_TOKEN) -#define OS_INTERRUPTMASK_PI_PE_FINISH OS_INTERRUPTMASK(OS_INTR_PI_PE_FINISH) + (OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_0_TC | OS_INTERRUPTMASK_EXI_0_EXT | \ + OS_INTERRUPTMASK_EXI_1_EXI | OS_INTERRUPTMASK_EXI_1_TC | OS_INTERRUPTMASK_EXI_1_EXT | \ + OS_INTERRUPTMASK_EXI_2_EXI | OS_INTERRUPTMASK_EXI_2_TC) +#define OS_INTERRUPTMASK_PI_PE_TOKEN OS_INTERRUPTMASK(__OS_INTERRUPT_PI_PE_TOKEN) +#define OS_INTERRUPTMASK_PI_PE_FINISH OS_INTERRUPTMASK(__OS_INTERRUPT_PI_PE_FINISH) #define OS_INTERRUPTMASK_PI_PE (OS_INTERRUPTMASK_PI_PE_TOKEN | OS_INTERRUPTMASK_PI_PE_FINISH) - -#define OS_INTERRUPTMASK_PI_CP OS_INTERRUPTMASK(OS_INTR_PI_CP) -#define OS_INTERRUPTMASK_PI_SI OS_INTERRUPTMASK(OS_INTR_PI_SI) -#define OS_INTERRUPTMASK_PI_DI OS_INTERRUPTMASK(OS_INTR_PI_DI) -#define OS_INTERRUPTMASK_PI_RSW OS_INTERRUPTMASK(OS_INTR_PI_RSW) -#define OS_INTERRUPTMASK_PI_ERROR OS_INTERRUPTMASK(OS_INTR_PI_ERROR) -#define OS_INTERRUPTMASK_PI_VI OS_INTERRUPTMASK(OS_INTR_PI_VI) -#define OS_INTERRUPTMASK_PI_DEBUG OS_INTERRUPTMASK(OS_INTR_PI_DEBUG) -#define OS_INTERRUPTMASK_PI_HSP OS_INTERRUPTMASK(OS_INTR_PI_HSP) +#define OS_INTERRUPTMASK_PI_CP OS_INTERRUPTMASK(__OS_INTERRUPT_PI_CP) +#define OS_INTERRUPTMASK_PI_SI OS_INTERRUPTMASK(__OS_INTERRUPT_PI_SI) +#define OS_INTERRUPTMASK_PI_DI OS_INTERRUPTMASK(__OS_INTERRUPT_PI_DI) +#define OS_INTERRUPTMASK_PI_RSW OS_INTERRUPTMASK(__OS_INTERRUPT_PI_RSW) +#define OS_INTERRUPTMASK_PI_ERROR OS_INTERRUPTMASK(__OS_INTERRUPT_PI_ERROR) +#define OS_INTERRUPTMASK_PI_VI OS_INTERRUPTMASK(__OS_INTERRUPT_PI_VI) +#define OS_INTERRUPTMASK_PI_DEBUG OS_INTERRUPTMASK(__OS_INTERRUPT_PI_DEBUG) +#define OS_INTERRUPTMASK_PI_HSP OS_INTERRUPTMASK(__OS_INTERRUPT_PI_HSP) #define OS_INTERRUPTMASK_PI \ - (OS_INTERRUPTMASK_PI_CP | OS_INTERRUPTMASK_PI_SI | OS_INTERRUPTMASK_PI_DI | \ - OS_INTERRUPTMASK_PI_RSW | OS_INTERRUPTMASK_PI_ERROR | OS_INTERRUPTMASK_PI_VI | \ - OS_INTERRUPTMASK_PI_PE_TOKEN | OS_INTERRUPTMASK_PI_PE_FINISH | OS_INTERRUPTMASK_PI_DEBUG | \ - OS_INTERRUPTMASK_PI_HSP) + (OS_INTERRUPTMASK_PI_CP | OS_INTERRUPTMASK_PI_SI | OS_INTERRUPTMASK_PI_DI | \ + OS_INTERRUPTMASK_PI_RSW | OS_INTERRUPTMASK_PI_ERROR | OS_INTERRUPTMASK_PI_VI | \ + OS_INTERRUPTMASK_PI_PE_TOKEN | OS_INTERRUPTMASK_PI_PE_FINISH | OS_INTERRUPTMASK_PI_DEBUG | \ + OS_INTERRUPTMASK_PI_HSP) -typedef s16 __OSInterrupt; -typedef u32 OSInterruptMask; typedef void (*__OSInterruptHandler)(__OSInterrupt interrupt, OSContext* context); -BOOL OSDisableInterrupts(void); -void __RAS_OSDisableInterrupts_end(void); -BOOL OSEnableInterrupts(void); -BOOL OSRestoreInterrupts(BOOL enable); +extern volatile __OSInterrupt __OSLastInterrupt; +extern volatile u32 __OSLastInterruptSrr0; +extern volatile OSTime __OSLastInterruptTime; + __OSInterruptHandler __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler); -__OSInterruptHandler __OSGetInterruptHandler(s16 index); -void __OSInterruptInit(void); -static OSInterruptMask SetInterruptMask(OSInterruptMask param_0, OSInterruptMask param_1); + +__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt); + +void __OSDispatchInterrupt(__OSException exception, OSContext* context); + +OSInterruptMask OSGetInterruptMask(void); +OSInterruptMask OSSetInterruptMask(OSInterruptMask mask); OSInterruptMask __OSMaskInterrupts(OSInterruptMask mask); OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask mask); -void __OSDispatchInterrupt(u8 interrupt, OSContext* context); -static void ExternalInterruptHandler(__OSInterrupt interrupt, OSContext* context); - -void __RAS_OSDisableInterrupts_begin(void); -void __RAS_OSDisableInterrupts_end(void); #ifdef __cplusplus -}; +} #endif -#endif /* OSINTERRUPT_H */ +#endif diff --git a/include/dolphin/os/OSL2.h b/include/dolphin/os/OSL2.h new file mode 100644 index 0000000000..01b4a620c0 --- /dev/null +++ b/include/dolphin/os/OSL2.h @@ -0,0 +1,20 @@ +#ifndef _DOLPHIN_OSL2_H_ +#define _DOLPHIN_OSL2_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void L2Enable(void); +void L2Disable(void); +void L2GlobalInvalidate(void); +void L2SetDataOnly(BOOL dataOnly); +void L2SetWriteThrough(BOOL writeThrough); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/os/OSLC.h b/include/dolphin/os/OSLC.h new file mode 100644 index 0000000000..af49708b14 --- /dev/null +++ b/include/dolphin/os/OSLC.h @@ -0,0 +1,19 @@ +#ifndef _DOLPHIN_OSLC_H_ +#define _DOLPHIN_OSLC_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void LCAllocOneTag(BOOL invalidate, void *tag); +void LCAllocTags(BOOL invalidate, void *startTag, u32 numBlocks); +void LCAlloc(void *addr, u32 nBytes); +void LCAllocNoInvalidate(void *addr, u32 nBytes); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/os/OSLink.h b/include/dolphin/os/OSLink.h deleted file mode 100644 index 311cc0090f..0000000000 --- a/include/dolphin/os/OSLink.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef OSLINK_H -#define OSLINK_H - -#include "dolphin/types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define OS_MODULE_VERSION 3 - -typedef struct OSModuleHeader OSModuleHeader; - -typedef u32 OSModuleID; -typedef struct OSModuleQueue OSModuleQueue; -typedef struct OSModuleLink OSModuleLink; -typedef struct OSModuleInfo OSModuleInfo; -typedef struct OSSectionInfo OSSectionInfo; -typedef struct OSImportInfo OSImportInfo; -typedef struct OSRel OSRel; - -struct OSModuleQueue { - OSModuleInfo* head; - OSModuleInfo* tail; -}; - -OSModuleQueue __OSModuleList AT_ADDRESS(0x800030C8); -void* __OSStringTable AT_ADDRESS(0x800030D0); - -struct OSModuleLink { - OSModuleInfo* next; - OSModuleInfo* prev; -}; - -struct OSSectionInfo { - u32 offset; - u32 size; -}; - -struct OSModuleInfo { - OSModuleID id; // unique identifier for the module - OSModuleLink link; // doubly linked list of modules - u32 numSections; // # of sections - u32 sectionInfoOffset; // offset to section info table - u32 nameOffset; // offset to module name - u32 nameSize; // size of module name - u32 version; // version number -}; - -struct OSModuleHeader { - // CAUTION: info must be the 1st member - OSModuleInfo info; - - // OS_MODULE_VERSION == 1 - u32 bssSize; // total size of bss sections in bytes - u32 relOffset; - u32 impOffset; - u32 impSize; // size in bytes - u8 prologSection; // section # for prolog function - u8 epilogSection; // section # for epilog function - u8 unresolvedSection; // section # for unresolved function - u8 bssSection; // section # for bss section (set at run-time) - u32 prolog; // prolog function offset - u32 epilog; // epilog function offset - u32 unresolved; // unresolved function offset - - // OS_MODULE_VERSION == 2 -#if (2 <= OS_MODULE_VERSION) - u32 align; // module alignment constraint - u32 bssAlign; // bss alignment constraint -#endif - - // OS_MODULE_VERSION == 3 -#if (3 <= OS_MODULE_VERSION) - u32 fixSize; -#endif -}; - -#define OSGetSectionInfo(module) ((OSSectionInfo*)(((OSModuleInfo*)(module))->sectionInfoOffset)) - -#define OS_SECTIONINFO_EXEC 0x1 -#define OS_SECTIONINFO_OFFSET(offset) ((offset) & ~0x1) - -struct OSImportInfo { - OSModuleID id; // external module id - u32 offset; // offset to OSRel instructions -}; - -struct OSRel { - u16 offset; // byte offset from the previous entry - u8 type; - u8 section; - u32 addend; -}; - -#define R_DOLPHIN_NOP 201 // C9h current offset += OSRel.offset -#define R_DOLPHIN_SECTION 202 // CAh current section = OSRel.section -#define R_DOLPHIN_END 203 // CBh -#define R_DOLPHIN_MRKREF 204 // CCh - -BOOL OSLink(OSModuleInfo* newModule, void* bss); -BOOL OSLinkFixed(OSModuleInfo* newModule, void* bss); -BOOL OSUnlink(OSModuleInfo* module); -void OSSetStringTable(void* string_table); -void __OSModuleInit(void); - -#ifdef __cplusplus -}; -#endif - -#endif /* OSLINK_H */ diff --git a/include/dolphin/os/OSMemory.h b/include/dolphin/os/OSMemory.h index 6a904c65b2..a5debebc90 100644 --- a/include/dolphin/os/OSMemory.h +++ b/include/dolphin/os/OSMemory.h @@ -1,7 +1,7 @@ -#ifndef OSMEMORY_H -#define OSMEMORY_H +#ifndef _DOLPHIN_OSMEMORY_H_ +#define _DOLPHIN_OSMEMORY_H_ -#include "dolphin/os/OSInterrupt.h" +#include #ifdef __cplusplus extern "C" { @@ -17,15 +17,12 @@ extern "C" { #define OS_PROTECT_CONTROL_WRITE 0x02 #define OS_PROTECT_CONTROL_RDWR (OS_PROTECT_CONTROL_READ | OS_PROTECT_CONTROL_WRITE) -static void MEMIntrruptHandler(__OSInterrupt interrupt, struct OSContext* context); -void OSProtectRange(u32 channel, void* address, u32 nBytes, u32 control); -static void Config24MB(void); -static void Config48MB(void); -static void RealMode(u32 config); -void __OSInitMemoryProtection(void); +void OSProtectRange(u32 chan, void* addr, u32 nBytes, u32 control); +u32 OSGetPhysicalMemSize(void); +u32 OSGetConsoleSimulatedMemSize(void); #ifdef __cplusplus -}; +} #endif -#endif /* OSMEMORY_H */ +#endif diff --git a/include/dolphin/os/OSMessage.h b/include/dolphin/os/OSMessage.h index 25f1536168..8cdd3f1b02 100644 --- a/include/dolphin/os/OSMessage.h +++ b/include/dolphin/os/OSMessage.h @@ -1,7 +1,7 @@ -#ifndef OSMESSAGE_H -#define OSMESSAGE_H +#ifndef _DOLPHIN_OSMESSAGE_H_ +#define _DOLPHIN_OSMESSAGE_H_ -#include "dolphin/os/OSThread.h" +#include #ifdef __cplusplus extern "C" { @@ -9,30 +9,25 @@ extern "C" { typedef void* OSMessage; -typedef struct OSMessageQueue { - /* 0x00 */ OSThreadQueue sending_queue; - /* 0x08 */ OSThreadQueue receiving_queue; - /* 0x10 */ OSMessage* message_array; - /* 0x14 */ s32 num_messages; - /* 0x18 */ s32 first_index; - /* 0x1C */ s32 num_used; +#define OS_MESSAGE_NOBLOCK 0 +#define OS_MESSAGE_BLOCK 1 + +typedef struct { + OSThreadQueue queueSend; + OSThreadQueue queueReceive; + void* msgArray; + s32 msgCount; + s32 firstIndex; + s32 usedCount; } OSMessageQueue; -// Flags to turn blocking on/off when sending/receiving message -#define OS_MESSAGE_NOBLOCK 0 -#define OS_MESSAGE_BLOCK 1 - -typedef enum { - OS_MSG_PERSISTENT = (1 << 0), -} OSMessageFlags; - -void OSInitMessageQueue(OSMessageQueue* queue, OSMessage* msgArray, s32 msgCount); -BOOL OSSendMessage(OSMessageQueue* queue, OSMessage msg, s32 flags); -BOOL OSReceiveMessage(OSMessageQueue* queue, OSMessage* msg, s32 flags); -BOOL OSJamMessage(OSMessageQueue* queue, OSMessage msg, s32 flags); +void OSInitMessageQueue(OSMessageQueue* mq, void* msgArray, s32 msgCount); +int OSSendMessage(OSMessageQueue* mq, void* msg, s32 flags); +int OSReceiveMessage(OSMessageQueue* mq, void* msg, s32 flags); +int OSJamMessage(OSMessageQueue* mq, void* msg, s32 flags); #ifdef __cplusplus -}; +} #endif -#endif /* OSMESSAGE_H */ +#endif // _DOLPHIN_OSMESSAGE_H_ diff --git a/include/dolphin/os/OSModule.h b/include/dolphin/os/OSModule.h new file mode 100644 index 0000000000..6e66e9b003 --- /dev/null +++ b/include/dolphin/os/OSModule.h @@ -0,0 +1,117 @@ +#ifndef _DOLPHIN_OSMODULE_H_ +#define _DOLPHIN_OSMODULE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define OS_MODULE_VERSION 3 +typedef struct OSModuleHeader OSModuleHeader; + +typedef u32 OSModuleID; +typedef struct OSModuleQueue OSModuleQueue; +typedef struct OSModuleLink OSModuleLink; +typedef struct OSModuleInfo OSModuleInfo; +typedef struct OSSectionInfo OSSectionInfo; +typedef struct OSImportInfo OSImportInfo; +typedef struct OSRel OSRel; + +struct OSModuleQueue { + OSModuleInfo* head; + OSModuleInfo* tail; +}; + +struct OSModuleLink { + OSModuleInfo* next; + OSModuleInfo* prev; +}; + +struct OSModuleInfo { + OSModuleID id; // unique identifier for the module + OSModuleLink link; // doubly linked list of modules + u32 numSections; // # of sections + u32 sectionInfoOffset; // offset to section info table + u32 nameOffset; // offset to module name + u32 nameSize; // size of module name + u32 version; // version number +}; + +struct OSModuleHeader { + // CAUTION: info must be the 1st member + OSModuleInfo info; + + // OS_MODULE_VERSION == 1 + u32 bssSize; // total size of bss sections in bytes + u32 relOffset; + u32 impOffset; + u32 impSize; // size in bytes + u8 prologSection; // section # for prolog function + u8 epilogSection; // section # for epilog function + u8 unresolvedSection; // section # for unresolved function + u8 bssSection; // section # for bss section (set at run-time) + u32 prolog; // prolog function offset + u32 epilog; // epilog function offset + u32 unresolved; // unresolved function offset + + // OS_MODULE_VERSION == 2 +#if (2 <= OS_MODULE_VERSION) + u32 align; // module alignment constraint + u32 bssAlign; // bss alignment constraint +#endif + + // OS_MODULE_VERSION == 3 +#if (3 <= OS_MODULE_VERSION) + u32 fixSize; +#endif +}; + +#define OSGetSectionInfo(module) ((OSSectionInfo*)(((OSModuleInfo*)(module))->sectionInfoOffset)) + +struct OSSectionInfo { + u32 offset; + u32 size; +}; + +// OSSectionInfo.offset bit +#define OS_SECTIONINFO_EXEC 0x1 +#define OS_SECTIONINFO_OFFSET(offset) ((offset) & ~0x1) + +struct OSImportInfo { + OSModuleID id; // external module id + u32 offset; // offset to OSRel instructions +}; + +struct OSRel { + u16 offset; // byte offset from the previous entry + u8 type; + u8 section; + u32 addend; +}; + +#define R_DOLPHIN_NOP 201 // C9h current offset += OSRel.offset +#define R_DOLPHIN_SECTION 202 // CAh current section = OSRel.section +#define R_DOLPHIN_END 203 // CBh +#define R_DOLPHIN_MRKREF 204 // CCh + +void OSSetStringTable(void* stringTable); +BOOL OSLink(OSModuleInfo* newModule, void* bss); + +#if (3 <= OS_MODULE_VERSION) +BOOL OSLinkFixed(OSModuleInfo* newModule, void* bss); +#endif + +BOOL OSUnlink(OSModuleInfo* oldModule); + +OSModuleInfo* OSSearchModule(void* ptr, u32* section, u32* offset); + +// debugger notification +void OSNotifyLink(OSModuleInfo* module); +void OSNotifyUnlink(OSModuleInfo* module); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/os/OSMutex.h b/include/dolphin/os/OSMutex.h index 0392c8dc5f..ef5565eb67 100644 --- a/include/dolphin/os/OSMutex.h +++ b/include/dolphin/os/OSMutex.h @@ -1,18 +1,18 @@ -#ifndef OSMUTEX_H -#define OSMUTEX_H +#ifndef _DOLPHIN_OSMUTEX_H_ +#define _DOLPHIN_OSMUTEX_H_ -#include "dolphin/os/OSThread.h" +#include #ifdef __cplusplus extern "C" { #endif -typedef struct OSMutex { +struct OSMutex { /* 0x00 */ OSThreadQueue queue; /* 0x08 */ OSThread* thread; /* 0x0C */ s32 count; /* 0x10 */ OSMutexLink link; -} OSMutex; // Size: 0x18 +}; typedef struct OSCond { OSThreadQueue queue; @@ -26,13 +26,8 @@ void OSInitCond(OSCond* cond); void OSWaitCond(OSCond* cond, OSMutex* mutex); void OSSignalCond(OSCond* cond); -void __OSUnlockAllMutex(OSThread* thread); -BOOL __OSCheckMutex(OSMutex* thread); -BOOL __OSCheckDeadLock(OSThread* thread); -BOOL __OSCheckMutexes(OSThread* thread); - #ifdef __cplusplus -}; +} #endif -#endif /* OSMUTEX_H */ +#endif diff --git a/include/dolphin/os/OSReboot.h b/include/dolphin/os/OSReboot.h index 4c9be11c43..6509534793 100644 --- a/include/dolphin/os/OSReboot.h +++ b/include/dolphin/os/OSReboot.h @@ -1,18 +1,19 @@ -#ifndef OSREBOOT_H -#define OSREBOOT_H +#ifndef _DOLPHIN_OSREBOOT_H_ +#define _DOLPHIN_OSREBOOT_H_ -#include "dolphin/types.h" +#include #ifdef __cplusplus extern "C" { #endif -void __OSReboot(u32 param_0, u32 param_1); void OSSetSaveRegion(void* start, void* end); void OSGetSaveRegion(void** start, void** end); +void OSGetSavedRegion(void** start, void** end); +void __OSReboot(u32 resetCode, u32 bootDol); #ifdef __cplusplus -}; +} #endif -#endif /* OSREBOOT_H */ +#endif diff --git a/include/dolphin/os/OSReset.h b/include/dolphin/os/OSReset.h index 754d517361..15c2ba62ff 100644 --- a/include/dolphin/os/OSReset.h +++ b/include/dolphin/os/OSReset.h @@ -1,57 +1,39 @@ -#ifndef OSRESET_H -#define OSRESET_H +#ifndef _DOLPHIN_OSRESET_H_ +#define _DOLPHIN_OSRESET_H_ -#include "dolphin/types.h" +#include #ifdef __cplusplus extern "C" { #endif -vu32 __PIRegs[12] AT_ADDRESS(0xCC003000); - -#define OS_RESETCODE_RESTART 0x80000000 -#define OS_RESETCODE_SYSTEM 0x40000000 - -#define OS_RESETCODE_EXEC 0xC0000000 -#define OS_RESETCODE_NETCONFIG 0xC0010000 - -#define OS_RESET_TIMEOUT OSMillisecondsToTicks(1000) - -#define OS_RESET_RESTART 0 +#define OS_RESET_RESTART 0 #define OS_RESET_HOTRESET 1 #define OS_RESET_SHUTDOWN 2 -#define OS_RESET_PRIO_SO 110 -#define OS_RESET_PRIO_IP 111 -#define OS_RESET_PRIO_CARD 127 -#define OS_RESET_PRIO_PAD 127 -#define OS_RESET_PRIO_GX 127 -#define OS_RESET_PRIO_ALARM 4294967295 +typedef struct OSResetFunctionInfo OSResetFunctionInfo; +typedef struct OSResetFunctionQueue { + OSResetFunctionInfo* head; + OSResetFunctionInfo* tail; +} OSResetFunctionQueue; -typedef BOOL (*OSResetFunction)(BOOL final); +typedef BOOL (*OSResetFunction)(BOOL); -typedef struct OSResetFunctionInfo { - /* 0x0 */ OSResetFunction func; - /* 0x4 */ u32 priority; - /* 0x8 */ struct OSResetFunctionInfo* next; - /* 0xC */ struct OSResetFunctionInfo* prev; -} OSResetFunctionInfo; - -typedef struct OSResetQueue { - OSResetFunctionInfo* first; - OSResetFunctionInfo* last; -} OSResetQueue; +struct OSResetFunctionInfo { + OSResetFunction func; + u32 priority; + OSResetFunctionInfo* next; + OSResetFunctionInfo* prev; +}; void OSRegisterResetFunction(OSResetFunctionInfo* info); -BOOL __OSCallResetFunctions(u32 param_0); -static void Reset(s32 param_0); -static void KillThreads(void); -void __OSDoHotReset(s32 param_0); +void OSUnregisterResetFunction(OSResetFunctionInfo* info); void OSResetSystem(int reset, u32 resetCode, BOOL forceMenu); -u32 OSGetResetCode(void); +u32 OSGetResetCode(); +u32 OSSetBootDol(u32 dolOffset); #ifdef __cplusplus -}; +} #endif -#endif /* OSRESET_H */ +#endif diff --git a/include/dolphin/os/OSResetSW.h b/include/dolphin/os/OSResetSW.h index e0205387e5..3c630b8573 100644 --- a/include/dolphin/os/OSResetSW.h +++ b/include/dolphin/os/OSResetSW.h @@ -1,7 +1,7 @@ -#ifndef OSRESETSW_H -#define OSRESETSW_H +#ifndef _DOLPHIN_OSRESETSW_H_ +#define _DOLPHIN_OSRESETSW_H_ -#include "dolphin/os/OSInterrupt.h" +#include #ifdef __cplusplus extern "C" { @@ -9,12 +9,12 @@ extern "C" { typedef void (*OSResetCallback)(void); -static BOOL OSGetResetButtonState(void); +OSResetCallback OSSetResetCallback(OSResetCallback callback); BOOL OSGetResetSwitchState(void); -void __OSResetSWInterruptHandler(__OSInterrupt interrupt, OSContext* context); +BOOL OSGetResetButtonState(void); #ifdef __cplusplus -}; +} #endif -#endif /* OSRESETSW_H */ +#endif diff --git a/include/dolphin/os/OSRtc.h b/include/dolphin/os/OSRtc.h index e19f09155a..ed3c3dd816 100644 --- a/include/dolphin/os/OSRtc.h +++ b/include/dolphin/os/OSRtc.h @@ -1,35 +1,25 @@ -#ifndef OSRTC_H -#define OSRTC_H +#ifndef _DOLPHIN_OSRTC_H_ +#define _DOLPHIN_OSRTC_H_ -#include "dolphin/types.h" +#include #ifdef __cplusplus extern "C" { #endif -typedef u32 OSSoundMode; - +// make the assert happy #define OS_SOUND_MODE_MONO 0 #define OS_SOUND_MODE_STEREO 1 -#define RTC_CMD_READ 0x20000000 -#define RTC_CMD_WRITE 0xa0000000 +// make the asserts happy +#define OS_VIDEO_MODE_NTSC 0 +#define OS_VIDEO_MODE_MPAL 2 -#define RTC_SRAM_ADDR 0x00000100 -#define RTC_SRAM_SIZE 64 +#define OS_PROGRESSIVE_MODE_OFF 0 +#define OS_PROGRESSIVE_MODE_ON 1 -#define RTC_CHAN 0 -#define RTC_DEV 1 -#define RTC_FREQ 3 // EXI_FREQ_8M - -typedef struct SramControlBlock { - u8 sram[RTC_SRAM_SIZE]; - u32 offset; - BOOL enabled; - BOOL locked; - BOOL sync; - void (*callback)(void); -} SramControlBlock; +#define OS_EURGB60_OFF 0 +#define OS_EURGB60_ON 1 typedef struct OSSram { u16 checkSum; @@ -54,23 +44,34 @@ typedef struct OSSramEx { u8 _padding1[2]; } OSSramEx; -void __OSInitSram(void); -OSSram* __OSLockSram(void); -OSSramEx* __OSLockSramEx(void); -BOOL __OSUnlockSram(BOOL commit); -BOOL __OSUnlockSramEx(BOOL commit); -BOOL __OSSyncSram(void); +#define SRAM_SIZE (sizeof(OSSram) + sizeof(OSSramEx)) + +typedef struct SramControl { + u8 sram[SRAM_SIZE]; // dummy for OSSram + OSSramEx + u32 offset; + BOOL enabled; + BOOL locked; + int sync; + void (*callback)(); +} SramControl; + u32 OSGetSoundMode(void); -void OSSetSoundMode(OSSoundMode mode); +void OSSetSoundMode(u32 mode); +u32 OSGetVideoMode(void); +void OSSetVideoMode(u32 mode); +u8 OSGetLanguage(void); +void OSSetLanguage(u8 language); +u16 OSGetGbsMode(void); +void OSSetGbsMode(u16 mode); u32 OSGetProgressiveMode(void); -void OSSetProgressiveMode(u32 mode); -u16 OSGetWirelessID(s32 channel); -void OSSetWirelessID(s32 channel, u16 id); -static u16 OSGetGbsMode(void); -static void OSSetGbsMode(u16 mode); +void OSSetProgressiveMode(u32 on); +u32 OSGetEuRgb60Mode(void); +void OSSetEuRgb60Mode(u32 on); +u16 OSGetWirelessID(s32 chan); +void OSSetWirelessID(s32 chan, u16 id); #ifdef __cplusplus -}; +} #endif -#endif /* OSRTC_H */ +#endif // _DOLPHIN_OSRTC_H_ diff --git a/include/dolphin/os/OSSemaphore.h b/include/dolphin/os/OSSemaphore.h new file mode 100644 index 0000000000..aac23811a8 --- /dev/null +++ b/include/dolphin/os/OSSemaphore.h @@ -0,0 +1,25 @@ +#ifndef _DOLPHIN_OSSEMAPHORE_H_ +#define _DOLPHIN_OSSEMAPHORE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OSSemaphore { + s32 count; + OSThreadQueue queue; +} OSSemaphore; + +void OSInitSemaphore(OSSemaphore* sem, s32 count); +s32 OSWaitSemaphore(OSSemaphore* sem); +s32 OSTryWaitSemaphore(OSSemaphore* sem); +s32 OSSignalSemaphore(OSSemaphore* sem); +s32 OSGetSemaphoreCount(OSSemaphore* sem); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_OSSEMAPHORE_H_ diff --git a/include/dolphin/os/OSSerial.h b/include/dolphin/os/OSSerial.h new file mode 100644 index 0000000000..7c38395f71 --- /dev/null +++ b/include/dolphin/os/OSSerial.h @@ -0,0 +1,6 @@ +#ifndef _DOLPHIN_OSSERIAL_H +#define _DOLPHIN_OSSERIAL_H + +#include + +#endif // _DOLPHIN_OSSERIAL_H diff --git a/include/dolphin/os/OSSync.h b/include/dolphin/os/OSSync.h deleted file mode 100644 index 2984bd07c2..0000000000 --- a/include/dolphin/os/OSSync.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef OSSYNC_H -#define OSSYNC_H - - -#ifdef __cplusplus -extern "C" { -#endif - -static void SystemCallVector(void); -void __OSInitSystemCall(void); - -void __OSSystemCallVectorEnd(void); - -#ifdef __cplusplus -}; -#endif - -#endif /* OSSYNC_H */ diff --git a/include/dolphin/os/OSThread.h b/include/dolphin/os/OSThread.h index 68061c6e83..5511c7595b 100644 --- a/include/dolphin/os/OSThread.h +++ b/include/dolphin/os/OSThread.h @@ -1,115 +1,112 @@ -#ifndef OSTHREAD_H -#define OSTHREAD_H +#ifndef _DOLPHIN_OSTHREAD_H_ +#define _DOLPHIN_OSTHREAD_H_ -#include "dolphin/os/OSContext.h" +#include #ifdef __cplusplus extern "C" { #endif -typedef u16 OSThreadState; -typedef s32 OSPriority; // 0 highest, 31 lowest - -#define OS_THREAD_STATE_UNINITIALIZED 0 -#define OS_THREAD_STATE_READY 1 -#define OS_THREAD_STATE_RUNNING 2 -#define OS_THREAD_STATE_WAITING 4 -#define OS_THREAD_STATE_DEAD 8 - -#define OS_THREAD_ATTR_DETACH 0x0001u - -#define OS_THREAD_STACK_MAGIC 0xDEADBABE - -#define OS_PRIORITY_MIN 0 // highest -#define OS_PRIORITY_MAX 31 // lowest -#define OS_PRIORITY_IDLE OS_PRIORITY_MAX +typedef s32 OSPriority; typedef struct OSThread OSThread; -typedef struct OSThreadQueue OSThreadQueue; -typedef struct OSThreadLink OSThreadLink; - typedef struct OSMutex OSMutex; +typedef struct OSThreadQueue OSThreadQueue; typedef struct OSMutexQueue OSMutexQueue; +typedef struct OSThreadLink OSThreadLink; typedef struct OSMutexLink OSMutexLink; -typedef struct OSCond OSCond; + +struct OSThreadQueue { + OSThread* head; + OSThread* tail; +}; struct OSThreadLink { OSThread* next; OSThread* prev; }; -struct OSThreadQueue { - /* 0x0 */ OSThread* head; - /* 0x4 */ OSThread* tail; -}; - -struct OSMutexLink { - OSMutex* next; - OSMutex* prev; -}; - struct OSMutexQueue { OSMutex* head; OSMutex* tail; }; -struct OSThread { - OSContext context; - OSThreadState state; - u16 attributes; - s32 suspend_count; - s32 effective_priority; - u32 base_priority; - void* exit_value; - OSThreadQueue* queue; - OSThreadLink link; - OSThreadQueue join_queue; - OSMutex* mutex; - OSMutexQueue owned_mutexes; - OSThreadLink active_threads_link; - u8* stack_base; - u32* stack_end; - u8* error_code; - void* data[2]; +struct OSMutexLink { + OSMutex* next; + OSMutex* prev; }; -typedef void (*OSSwitchThreadCallback)(OSThread* from, OSThread* to); +struct OSThread { + /* 0x000 */ OSContext context; + /* 0x2C8 */ u16 state; + /* 0x2CA */ u16 attr; + /* 0x2CC */ s32 suspend; + /* 0x2D0 */ OSPriority priority; + /* 0x2D4 */ OSPriority base; + /* 0x2D8 */ void* val; + /* 0x2DC */ OSThreadQueue* queue; + /* 0x2E0 */ OSThreadLink link; + /* 0x2E8 */ OSThreadQueue queueJoin; + /* 0x2F0 */ OSMutex* mutex; + /* 0x2F4 */ OSMutexQueue queueMutex; + /* 0x2FC */ OSThreadLink linkActive; + /* 0x304 */ u8* stackBase; + /* 0x308 */ u32* stackEnd; + /* 0x30C */ s32 error; + /* 0x310 */ void* specific[2]; +}; -OSThreadQueue OS_THREAD_QUEUE AT_ADDRESS(0x800000DC); -OSThread* OS_CURRENT_THREAD AT_ADDRESS(0x800000E4); +enum OS_THREAD_STATE { + OS_THREAD_STATE_READY = 1, + OS_THREAD_STATE_RUNNING = 2, + OS_THREAD_STATE_WAITING = 4, + OS_THREAD_STATE_MORIBUND = 8, +}; + +#define OS_PRIORITY_MIN 0 // highest +#define OS_PRIORITY_MAX 31 // lowest +#define OS_PRIORITY_IDLE OS_PRIORITY_MAX + +#define OS_THREAD_SPECIFIC_MAX 2 + +#define OS_THREAD_ATTR_DETACH 0x0001u + +#define OS_THREAD_STACK_MAGIC 0xDEADBABE + +typedef void (*OSSwitchThreadCallback)(OSThread*, OSThread*); +typedef void (*OSIdleFunction)(void*); -static void DefaultSwitchThreadCallback(OSThread* from, OSThread* to); -OSSwitchThreadCallback OSSetSwitchThreadCallback(OSSwitchThreadCallback func); -void __OSThreadInit(void); void OSInitThreadQueue(OSThreadQueue* queue); -OSThread* OSGetCurrentThread(void); -BOOL OSIsThreadTerminated(OSThread* thread); -s32 OSDisableScheduler(void); -s32 OSEnableScheduler(void); -static void UnsetRun(OSThread* thread); -s32 __OSGetEffectivePriority(OSThread* thread); -static OSThread* SetEffectivePriority(OSThread* thread, s32 priority); -void __OSPromoteThread(OSThread* thread, s32 priority); -static OSThread* SelectThread(BOOL yield); -void __OSReschedule(void); -void OSYieldThread(void); -BOOL OSCreateThread(OSThread* thread, void* func, void* param, void* stackBase, u32 stackSize, - s32 priority, u16 attribute); -void OSExitThread(void* exitValue); -void OSCancelThread(OSThread* thread); -void OSDetachThread(OSThread* thread); -s32 OSResumeThread(OSThread* thread); -s32 OSSuspendThread(OSThread* thread); void OSSleepThread(OSThreadQueue* queue); void OSWakeupThread(OSThreadQueue* queue); -s32 OSSetThreadPriority(OSThread* thread, s32 priority); +s32 OSSuspendThread(OSThread* thread); +s32 OSResumeThread(OSThread* thread); +OSThread* OSGetCurrentThread(void); +s32 OSEnableScheduler(void); +s32 OSDisableScheduler(void); +void OSCancelThread(OSThread* thread); +void OSClearStack(u8 val); +BOOL OSIsThreadSuspended(OSThread* thread); +BOOL OSIsThreadTerminated(OSThread* thread); +void OSYieldThread(void); +int OSCreateThread(OSThread* thread, void* (*func)(void*), void* param, void* stack, u32 stackSize, OSPriority priority, u16 attr); +void OSExitThread(void* val); +int OSJoinThread(OSThread* thread, void* val); +void OSDetachThread(OSThread* thread); +int OSSetThreadPriority(OSThread* thread, OSPriority priority); s32 OSGetThreadPriority(OSThread* thread); -static s32 CheckThreadQueue(OSThreadQueue* thread); +OSThread* OSSetIdleFunction(OSIdleFunction idleFunction, void* param, void* stack, u32 stackSize); +OSThread* OSGetIdleFunction(void); s32 OSCheckActiveThreads(void); -static void OSClearStack(u8 value); +void OSSetThreadSpecific(s32 index, void* ptr); +void* OSGetThreadSpecific(s32 index); + +OSSwitchThreadCallback OSSetSwitchThreadCallback(OSSwitchThreadCallback callback); + +#define IsSuspended(suspend) (suspend > 0) #ifdef __cplusplus -}; +} #endif -#endif /* OSTHREAD_H */ +#endif diff --git a/include/dolphin/os/OSTime.h b/include/dolphin/os/OSTime.h index 3cd474bf30..118adee7c2 100644 --- a/include/dolphin/os/OSTime.h +++ b/include/dolphin/os/OSTime.h @@ -1,56 +1,44 @@ -#ifndef OSTIME_H -#define OSTIME_H +#ifndef _DOLPHIN_OSTIME_H_ +#define _DOLPHIN_OSTIME_H_ -#include "dolphin/types.h" +#include #ifdef __cplusplus extern "C" { #endif -typedef s64 OSTime; -typedef u32 OSTick; +// Time base frequency = 1/4 bus clock +#define OS_TIME_SPEED (OS_BUS_CLOCK / 4) -OSTime OS_SYSTEM_TIME AT_ADDRESS(0x800030D8); +// OS time -> Real time +#define OS_TICKS_TO_SEC(x) ((x) / (OS_TIME_SPEED)) +#define OS_TICKS_TO_MSEC(x) ((x) / (OS_TIME_SPEED / 1000)) +#define OS_TICKS_TO_USEC(x) (((x)*8) / (OS_TIME_SPEED / 125000)) +#define OS_TICKS_TO_NSEC(x) (((x)*8000) / (OS_TIME_SPEED / 125000)) -typedef struct OSCalendarTime { - /* 0x00 */ s32 seconds; - /* 0x04 */ s32 minutes; - /* 0x08 */ s32 hours; - /* 0x0C */ s32 day_of_month; - /* 0x10 */ s32 month; - /* 0x14 */ s32 year; - /* 0x18 */ s32 week_day; - /* 0x1C */ s32 year_day; - /* 0x20 */ s32 milliseconds; - /* 0x24 */ s32 microseconds; -} OSCalendarTime; +// Real time -> OS time +#define OS_SEC_TO_TICKS(x) ((x) * (OS_TIME_SPEED)) +#define OS_MSEC_TO_TICKS(x) ((x) * (OS_TIME_SPEED / 1000)) +#define OS_USEC_TO_TICKS(x) ((x) * (OS_TIME_SPEED / 125000) / 8) +#define OS_NSEC_TO_TICKS(x) ((x) * (OS_TIME_SPEED / 125000) / 8000) -OSTime OSGetTime(void); -OSTick OSGetTick(void); -OSTime __OSGetSystemTime(void); -OSTime __OSTimeToSystemTime(OSTime time); -void GetDates(s32 days, OSCalendarTime* ct); -void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* ct); +#define USEC_MAX 1000 +#define MSEC_MAX 1000 +#define MONTH_MAX 12 +#define WEEK_DAY_MAX 7 +#define YEAR_DAY_MAX 365 -extern u32 __OSBusClock AT_ADDRESS(0x800000F8); +#define SECS_IN_MIN 60 +#define SECS_IN_HOUR (SECS_IN_MIN * 60) +#define SECS_IN_DAY (SECS_IN_HOUR * 24) +#define SECS_IN_YEAR (SECS_IN_DAY * 365) -#define OS_BUS_CLOCK (__OSBusClock) -#define OS_CORE_CLOCK (*(u32*)0x800000FC) -#define OS_TIMER_CLOCK (OS_BUS_CLOCK / 4) -#define OS_TIMER_CLOCK_MS (OS_TIMER_CLOCK / 1000) +#define BIAS 0xB2575 -#define OSTicksToCycles(ticks) (((ticks) * ((OS_CORE_CLOCK * 2) / OS_TIMER_CLOCK)) / 2) -#define OSTicksToSeconds(ticks) ((ticks) / OS_TIMER_CLOCK) -#define OSTicksToMilliseconds(ticks) ((ticks) / (OS_TIMER_CLOCK / 1000)) -#define OSTicksToMicroseconds(ticks) (((ticks)*8) / (OS_TIMER_CLOCK / 125000)) -#define OSTicksToNanoseconds(ticks) (((ticks)*8000) / (OS_TIMER_CLOCK / 125000)) -#define OSSecondsToTicks(sec) ((sec)*OS_TIMER_CLOCK) -#define OSMillisecondsToTicks(msec) ((msec) * (OS_TIMER_CLOCK / 1000)) -#define OSMicrosecondsToTicks(usec) (((usec) * (OS_TIMER_CLOCK / 125000)) / 8) -#define OSNanosecondsToTicks(nsec) (((nsec) * (OS_TIMER_CLOCK / 125000)) / 8000) +#define __OSSystemTime (OSTime*)0x800030D8 #ifdef __cplusplus -}; +} #endif -#endif /* OSTIME_H */ +#endif // _DOLPHIN_OSTIME_H_ diff --git a/include/dolphin/os/OSTimer.h b/include/dolphin/os/OSTimer.h new file mode 100644 index 0000000000..490cccb67c --- /dev/null +++ b/include/dolphin/os/OSTimer.h @@ -0,0 +1,21 @@ +#ifndef _DOLPHIN_OSTIMER_H_ +#define _DOLPHIN_OSTIMER_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*OSTimerCallback)(void); + +OSTimerCallback OSSetTimerCallback(OSTimerCallback callback); +void OSInitTimer(u32 time, u32 mode); +void OSStartTimer(void); +void OSStopTimer(void); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_OSTIMER_H_ diff --git a/include/dolphin/os/OSUtf.h b/include/dolphin/os/OSUtf.h new file mode 100644 index 0000000000..2f721d5787 --- /dev/null +++ b/include/dolphin/os/OSUtf.h @@ -0,0 +1,23 @@ +#ifndef _DOLPHIN_OSUTF_H_ +#define _DOLPHIN_OSUTF_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +char* OSUTF8to32(const char* utf8, u32* utf32); +char* OSUTF32to8(u32 utf32, char* utf8); +u16* OSUTF16to32(const u16* utf16, u32* utf32); +u16* OSUTF32to16(u32 utf32, u16* utf16); +u8 OSUTF32toANSI(u32 utf32); +u32 OSANSItoUTF32(u8 ansi); +u16 OSUTF32toSJIS(u32 utf32); +u32 OSSJIStoUTF32(u16 sjis); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_OSUTF_H_ diff --git a/include/dolphin/pad.h b/include/dolphin/pad.h index 1016898869..d966b80945 100644 --- a/include/dolphin/pad.h +++ b/include/dolphin/pad.h @@ -1,19 +1,12 @@ -#ifndef PAD_H -#define PAD_H +#ifndef _DOLPHIN_PAD_H_ +#define _DOLPHIN_PAD_H_ -#include "dolphin/types.h" +#include #ifdef __cplusplus extern "C" { #endif -typedef struct OSContext OSContext; - -#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 #define PAD_SPEC_2 2 @@ -21,58 +14,91 @@ typedef struct OSContext OSContext; #define PAD_SPEC_4 4 #define PAD_SPEC_5 5 -#define PAD_MOTOR_STOP 0 -#define PAD_MOTOR_RUMBLE 1 +#define PAD_MOTOR_STOP 0 +#define PAD_MOTOR_RUMBLE 1 #define PAD_MOTOR_STOP_HARD 2 -#define PAD_ERR_NONE 0 -#define PAD_ERR_NO_CONTROLLER -1 -#define PAD_ERR_NOT_READY -2 -#define PAD_ERR_TRANSFER -3 +#define PAD_CHAN0_BIT 0x80000000 +#define PAD_CHAN1_BIT 0x40000000 +#define PAD_CHAN2_BIT 0x20000000 +#define PAD_CHAN3_BIT 0x10000000 -#define PAD_BUTTON_LEFT 0x0001 -#define PAD_BUTTON_RIGHT 0x0002 -#define PAD_BUTTON_DOWN 0x0004 -#define PAD_BUTTON_UP 0x0008 -#define PAD_TRIGGER_Z 0x0010 -#define PAD_TRIGGER_R 0x0020 -#define PAD_TRIGGER_L 0x0040 -#define PAD_BUTTON_A 0x0100 -#define PAD_BUTTON_B 0x0200 -#define PAD_BUTTON_X 0x0400 -#define PAD_BUTTON_Y 0x0800 -#define PAD_BUTTON_MENU 0x1000 -#define PAD_BUTTON_START 0x1000 +#define PAD_MAX_CONTROLLERS 4 + +#define PAD_BUTTON_LEFT (1 << 0) // 0x0001 +#define PAD_BUTTON_RIGHT (1 << 1) // 0x0002 +#define PAD_BUTTON_DOWN (1 << 2) // 0x0004 +#define PAD_BUTTON_UP (1 << 3) // 0x0008 +#define PAD_TRIGGER_Z (1 << 4) // 0x0010 +#define PAD_TRIGGER_R (1 << 5) // 0x0020 +#define PAD_TRIGGER_L (1 << 6) // 0x0040 +#define PAD_BUTTON_A (1 << 8) // 0x0100 +#define PAD_BUTTON_B (1 << 9) // 0x0200 +#define PAD_BUTTON_X (1 << 10) // 0x0400 +#define PAD_BUTTON_Y (1 << 11) // 0x0800 +#define PAD_BUTTON_MENU (1 << 12) // 0x1000 +#define PAD_BUTTON_START (1 << 12) // 0x1000 + +#define PAD_ERR_NONE 0 +#define PAD_ERR_NO_CONTROLLER -1 +#define PAD_ERR_NOT_READY -2 +#define PAD_ERR_TRANSFER -3 + +#define RES_WIRELESS_LITE 0x40000 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); -void PADSetAnalogMode(u32 mode); -void PADSetSpec(u32 spec); -BOOL PADReset(u32 mask); -void PADClampCircle(PADStatus* status); -void PADClamp(PADStatus* status); -u32 PADRead(PADStatus* status); -void PADControlMotor(s32 channel, u32 command); +// Pad +int PADReset(u32 mask); BOOL PADRecalibrate(u32 mask); +BOOL PADInit(); +u32 PADRead(PADStatus* status); +void PADSetSamplingRate(u32 msec); +void __PADTestSamplingRate(u32 tvmode); +void PADControlAllMotors(const u32* commandArray); +void PADControlMotor(s32 chan, u32 command); +void PADSetSpec(u32 spec); +u32 PADGetSpec(); +int PADGetType(s32 chan, u32* type); +BOOL PADSync(void); +void PADSetAnalogMode(u32 mode); +BOOL __PADDisableRecalibration(BOOL disable); +BOOL PADIsBarrel(s32 chan); -extern u32 __PADSpec; +PADSamplingCallback PADSetSamplingCallback(PADSamplingCallback callback); + +// Padclamp +void PADClamp(PADStatus* status); +void PADClampCircle(PADStatus* status); #ifdef __cplusplus -}; +} #endif -#endif /* PAD_H */ +#endif diff --git a/include/dolphin/pad/Padclamp.h b/include/dolphin/pad/Padclamp.h deleted file mode 100644 index a614ebc2c0..0000000000 --- a/include/dolphin/pad/Padclamp.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef PADCLAMP_H -#define PADCLAMP_H - -#include "dolphin/pad.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct PADClampRegion { - u8 minTrigger; - u8 maxTrigger; - s8 minStick; - s8 maxStick; - s8 xyStick; - s8 minSubstick; - s8 maxSubstick; - s8 xySubstick; - s8 radStick; - s8 radSubstick; -} PADClampRegion; - -void PADClamp(PADStatus* status); -void PADClampCircle(PADStatus* status); - -#ifdef __cplusplus -}; -#endif - -#endif /* PADCLAMP_H */ diff --git a/include/dolphin/perf.h b/include/dolphin/perf.h new file mode 100644 index 0000000000..71471a53ad --- /dev/null +++ b/include/dolphin/perf.h @@ -0,0 +1,99 @@ +#ifndef _DOLPHIN_PERF_H_ +#define _DOLPHIN_PERF_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef u8 PERFId; + +typedef enum { + PERF_CPU_EVENT, + PERF_CPU_GP_EVENT, + PERF_GP_EVENT, +} PerfType; + +typedef struct PerfSample { + /* 0x00 */ u8 id; + /* 0x04 */ u32 cpuTimeStampStart; + /* 0x08 */ u32 cpuTimeStampEnd; + /* 0x0C */ u32 gpTimeStampStart; + /* 0x10 */ u32 gpTimeStampEnd; + /* 0x14 */ int interrupted; + /* 0x18 */ u32 origcpuStart; + /* 0x1C */ u32 origgpStart; + /* 0x20 */ u32 cacheMisses[4]; + /* 0x30 */ u32 instructions[4]; + /* 0x40 */ u32 cpReq[2]; + /* 0x48 */ u32 tcReq[2]; + /* 0x50 */ u32 cpuRdReq[2]; + /* 0x58 */ u32 cpuWrReq[2]; + /* 0x60 */ u32 dspReq[2]; + /* 0x68 */ u32 ioReq[2]; + /* 0x70 */ u32 viReq[2]; + /* 0x78 */ u32 peReq[2]; + /* 0x80 */ u32 rfReq[2]; + /* 0x88 */ u32 fiReq[2]; + /* 0x90 */ u32 xfWaitIn[2]; + /* 0x98 */ u32 xfWaitOut[2]; + /* 0xA0 */ u32 rasBusy[2]; + /* 0xA8 */ u32 rasClocks[2]; +} PerfSample; + +typedef struct { + PerfSample* samples; + s32 lastSample; + u32 end; + u32 cachemisscycles; +} Frame; + +typedef struct { + char* name; + PerfType type; + s32 currSample; + GXColor color; +} PerfEvent; + +typedef void* (*PERFAllocator)(u32 size); +typedef void (*PERFDeallocator)(void* block); +typedef void (*PERFDrawCallback)(void); + +extern void (*GameDrawInit)(); + +u32 PERFInit(u32 numSamples, u32 numFramesHistory, u32 numTypes, PERFAllocator allocator, PERFDeallocator deallocator, PERFDrawCallback initDraw); +void PERFEventStart(PERFId id); +void PERFEventEnd(PERFId id); +void PERFSetEvent(PERFId id, char* name, PerfType type); +void PERFStartFrame(void); +void PERFEndFrame(void); +void PERFStartAutoSampling(f32 msInterval); +void PERFStopAutoSampling(void); + +void PERFPreDraw(void); +void PERFDumpScreen(void); +void PERFPostDraw(void); +void PERFSetDrawBWBarKey(BOOL tf); +void PERFSetDrawBWBar(BOOL tf); +void PERFSetDrawCPUBar(BOOL tf); +void PERFSetDrawXFBars(BOOL tf); +void PERFSetDrawRASBar(BOOL tf); +void PERFToggleDrawBWBarKey(void); +void PERFToggleDrawBWBar(void); +void PERFToggleDrawCPUBar(void); +void PERFToggleDrawXFBars(void); +void PERFToggleDrawRASBar(void); +void PERFShutDown(void); +void PERFSetDrawFrames(u32 frames); + +extern Frame* PERFFrames; +extern u32 PERFCurrFrame; +extern PerfEvent* PERFEvents; +extern u32 PERFNumEvents; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/seq.h b/include/dolphin/seq.h new file mode 100644 index 0000000000..754798093d --- /dev/null +++ b/include/dolphin/seq.h @@ -0,0 +1,54 @@ +#ifndef _DOLPHIN_SEQ_H_ +#define _DOLPHIN_SEQ_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _SEQTRACK { + /* 0x00 */ void* sequence; + /* 0x04 */ u8* start; + /* 0x08 */ u8* end; + /* 0x0C */ u8* current; + /* 0x10 */ u8 status; + /* 0x14 */ f32 beatsPerSec; + /* 0x18 */ u32 defaultTicksPerFrame; + /* 0x1C */ u32 ticksPerFrame; + /* 0x20 */ u32 delay; + /* 0x24 */ u32 state; +} SEQTRACK; + +typedef struct _SEQSEQUENCE { + /* 0x0000 */ void* next; + /* 0x0004 */ u32 state; + /* 0x0008 */ u16 nTracks; + /* 0x000A */ s16 timeFormat; + /* 0x000C */ u32 tracksRunning; + /* 0x0010 */ u32 end; + /* 0x0014 */ SYNSYNTH synth; + /* 0x3154 */ void (*callback[128])(void*, u8); + /* 0x3354 */ SEQTRACK track[64]; +} SEQSEQUENCE; + +#define SEQ_ALL_TRACKS -1 + +void SEQInit(void); +void SEQQuit(void); +void SEQRunAudioFrame(void); +void SEQAddSequence(SEQSEQUENCE* sequence, u8* midiStream, void* wt, u32 aramBase, u32 zeroBase, u32 priorityVoiceAlloc, u32 priorityNoteOn, u32 priorityNoteRelease); +void SEQRemoveSequence(SEQSEQUENCE* sequence); +void SEQRegisterControllerCallback(SEQSEQUENCE* sequence, u8 controller, void (*callback)(void*, u8)); +void SEQSetState(SEQSEQUENCE* sequence, u32 state); +u32 SEQGetState(SEQSEQUENCE* sequence); +void SEQSetTempo(SEQSEQUENCE* sequence, u32 trackIndex, f32 bpm); +f32 SEQGetTempo(SEQSEQUENCE* sequence, u32 trackIndex); +void SEQSetVolume(SEQSEQUENCE* sequence, s32 dB); +s32 SEQGetVolume(SEQSEQUENCE* sequence); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_SEQ_H_ diff --git a/include/dolphin/si.h b/include/dolphin/si.h new file mode 100644 index 0000000000..04b01ba4d7 --- /dev/null +++ b/include/dolphin/si.h @@ -0,0 +1,175 @@ +#ifndef _DOLPHIN_SI_H_ +#define _DOLPHIN_SI_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SI_MAX_CHAN 4 +#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_ERROR_UNDER_RUN 0x0001 +#define SI_ERROR_OVER_RUN 0x0002 +#define SI_ERROR_COLLISION 0x0004 +#define SI_ERROR_NO_RESPONSE 0x0008 +#define SI_ERROR_WRST 0x0010 +#define SI_ERROR_RDST 0x0020 +#define SI_ERROR_UNKNOWN 0x0040 +#define SI_ERROR_BUSY 0x0080 + +#define SI_TYPE_MASK 0x18000000u +#define SI_TYPE_N64 0x00000000u +#define SI_TYPE_DOLPHIN 0x08000000u +#define SI_TYPE_GC SI_TYPE_DOLPHIN +#define SI_GC_WIRELESS 0x80000000 +#define SI_GC_NOMOTOR 0x20000000 +#define SI_GC_STANDARD 0x01000000 +#define SI_WIRELESS_RECEIVED 0x40000000 +#define SI_WIRELESS_IR 0x04000000 +#define SI_WIRELESS_STATE 0x02000000 +#define SI_WIRELESS_ORIGIN 0x00200000 +#define SI_WIRELESS_FIX_ID 0x00100000 +#define SI_WIRELESS_TYPE 0x000f0000 +#define SI_WIRELESS_LITE_MASK 0x000c0000 +#define SI_WIRELESS_LITE 0x00040000 +#define SI_WIRELESS_CONT_MASK 0x00080000 +#define SI_WIRELESS_CONT 0x00000000 +#define SI_WIRELESS_ID 0x00c0ff00 +#define SI_WIRELESS_TYPE_ID (SI_WIRELESS_TYPE | SI_WIRELESS_ID) +#define SI_N64_CONTROLLER (SI_TYPE_N64 | 0x05000000) +#define SI_N64_MIC (SI_TYPE_N64 | 0x00010000) +#define SI_N64_KEYBOARD (SI_TYPE_N64 | 0x00020000) +#define SI_N64_MOUSE (SI_TYPE_N64 | 0x02000000) +#define SI_GBA (SI_TYPE_N64 | 0x00040000) +#define SI_GC_CONTROLLER (SI_TYPE_GC | SI_GC_STANDARD) +#define SI_GC_RECEIVER (SI_TYPE_GC | SI_GC_WIRELESS) +#define SI_GC_WAVEBIRD (SI_TYPE_GC | SI_GC_WIRELESS | SI_GC_STANDARD | SI_WIRELESS_STATE | SI_WIRELESS_FIX_ID) +#define SI_GC_KEYBOARD (SI_TYPE_GC | 0x00200000) +#define SI_GC_STEERING (SI_TYPE_GC | 0x00000000) + +typedef void (*SICallback)(s32 chan, u32 sr, OSContext *context); +typedef void (*SITypeCallback)(s32 chan, u32 type); + +typedef struct { + s32 chan; + u32 poll; + u32 inputBytes; + void* input; + SICallback callback; +} SIControl; + +typedef struct { + s32 chan; + void* output; + u32 outputBytes; + void* input; + u32 inputBytes; + SICallback callback; + OSTime fire; +} SIPacket; + +// SIBios +BOOL SIBusy(void); +BOOL SIIsChanBusy(s32 chan); +BOOL SIRegisterPollingHandler(__OSInterruptHandler handler); +BOOL SIUnregisterPollingHandler(__OSInterruptHandler handler); +void SIInit(void); +u32 SISync(void); +u32 SIGetStatus(s32 chan); +void SISetCommand(s32 chan, u32 command); +u32 SIGetCommand(s32 chan); +void SITransferCommands(void); +u32 SISetXY(u32 x, u32 y); +u32 SIEnablePolling(u32 poll); +u32 SIDisablePolling(u32 poll); +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, SITypeCallback callback); +u32 SIDecodeType(u32 type); +u32 SIProbe(s32 chan); +char* SIGetTypeString(u32 type); + +extern u32 __PADFixBits; + +// SISamplingRate +void SISetSamplingRate(u32 msec); +void SIRefreshSamplingRate(void); + +// SISteering +typedef void (*SISteeringCallback)(s32 chan, s32); + +typedef struct { + u8 output[3]; + u8 input[8]; + u32 outputBytes; + u32 inputBytes; + SISteeringCallback callback; + s32 ret; + OSThreadQueue threadQueue; + void (*proc)(s32); +} SISteeringControl; + +typedef struct { + u16 button; + u8 misc; + s8 steering; + u8 gas; + u8 brake; + u8 left; + u8 right; + s8 err; +} SISteeringStatus; + +extern SISteeringControl __SISteering[4]; +extern u32 __SISteeringEnableBits; +extern BOOL __SIResetSteering; + +void SIInitSteering(void); +s32 SIResetSteeringAsync(s32 chan, SISteeringCallback callback); +s32 SIResetSteering(s32 chan); + +s32 SIReadSteering(s32 chan, SISteeringStatus* status); +void (* SISetSteeringSamplingCallback(void (*callback)()))(); +void SIControlSteering(s32 chan, u32 control, s32 level); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_SI_H_ diff --git a/include/dolphin/si/SIBios.h b/include/dolphin/si/SIBios.h deleted file mode 100644 index 3e6c48acd9..0000000000 --- a/include/dolphin/si/SIBios.h +++ /dev/null @@ -1,129 +0,0 @@ -#ifndef SIBIOS_H -#define SIBIOS_H - -#include "dolphin/os/OSInterrupt.h" -#include "dolphin/os/OSTime.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define SI_MAX_CHAN 4 -#define SI_MAX_COMCSR_INLNGTH 128 -#define SI_MAX_COMCSR_OUTLNGTH 128 -#define SI_ERROR_UNDER_RUN 0x0001 -#define SI_ERROR_OVER_RUN 0x0002 -#define SI_ERROR_COLLISION 0x0004 -#define SI_ERROR_NO_RESPONSE 0x0008 -#define SI_ERROR_WRST 0x0010 -#define SI_ERROR_RDST 0x0020 -#define SI_ERROR_UNKNOWN 0x0040 -#define SI_ERROR_BUSY 0x0080 -#define SI_CHAN0 0 -#define SI_CHAN1 1 -#define SI_CHAN2 2 -#define SI_CHAN3 3 -#define SI_CHAN0_BIT 0x80000000 -#define SI_CHAN1_BIT 0x40000000 -#define SI_CHAN2_BIT 0x20000000 -#define SI_CHAN3_BIT 0x10000000 -#define SI_CHAN_BIT(chan) (SI_CHAN0_BIT >> (chan)) -#define SI_TYPE_MASK 0x18000000u -#define SI_TYPE_N64 0x00000000u -#define SI_TYPE_DOLPHIN 0x08000000u -#define SI_TYPE_GC SI_TYPE_DOLPHIN -#define SI_GC_WIRELESS 0x80000000 -#define SI_GC_NOMOTOR 0x20000000 -#define SI_GC_STANDARD 0x01000000 -#define SI_WIRELESS_RECEIVED 0x40000000 -#define SI_WIRELESS_IR 0x04000000 -#define SI_WIRELESS_STATE 0x02000000 -#define SI_WIRELESS_ORIGIN 0x00200000 -#define SI_WIRELESS_FIX_ID 0x00100000 -#define SI_WIRELESS_TYPE 0x000f0000 -#define SI_WIRELESS_LITE_MASK 0x000c0000 -#define SI_WIRELESS_LITE 0x00040000 -#define SI_WIRELESS_CONT_MASK 0x00080000 -#define SI_WIRELESS_CONT 0x00000000 -#define SI_WIRELESS_ID 0x00c0ff00 -#define SI_WIRELESS_TYPE_ID (SI_WIRELESS_TYPE | SI_WIRELESS_ID) -#define SI_N64_CONTROLLER (SI_TYPE_N64 | 0x05000000) -#define SI_N64_MIC (SI_TYPE_N64 | 0x00010000) -#define SI_N64_KEYBOARD (SI_TYPE_N64 | 0x00020000) -#define SI_N64_MOUSE (SI_TYPE_N64 | 0x02000000) -#define SI_GBA (SI_TYPE_N64 | 0x00040000) -#define SI_GC_CONTROLLER (SI_TYPE_GC | SI_GC_STANDARD) -#define SI_GC_RECEIVER (SI_TYPE_GC | SI_GC_WIRELESS) -#define SI_GC_WAVEBIRD \ - (SI_TYPE_GC | SI_GC_WIRELESS | SI_GC_STANDARD | SI_WIRELESS_STATE | SI_WIRELESS_FIX_ID) -#define SI_GC_KEYBOARD (SI_TYPE_GC | 0x00200000) -#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 struct SIPacket { - s32 chan; - void* output; - u32 outputBytes; - void* input; - u32 inputBytes; - SICallback callback; - OSTime fire; -} SIPacket; - -typedef struct SIControl { - s32 chan; - u32 poll; - u32 inputBytes; - void* input; - SICallback callback; -} SIControl; - -typedef struct SIComm_s { - u32 tcint : 1; - u32 tcintmsk : 1; - u32 comerr : 1; - u32 rdstint : 1; - u32 rdstintmsk : 1; - u32 pad0 : 4; - u32 outlngth : 7; - u32 pad1 : 1; - u32 inlngth : 7; - u32 pad2 : 5; - u32 channel : 2; - u32 tstart : 1; -} SIComm_s; - -typedef union SIComm_u { - u32 val; - SIComm_s f; -} SIComm_u; - -BOOL SIBusy(void); -BOOL SIIsChanBusy(s32 chan); -static void SIInterruptHandler(__OSInterrupt interrupt, OSContext* context); -static BOOL SIEnablePollingInterrupt(BOOL enable); -BOOL SIRegisterPollingHandler(__OSInterruptHandler handler); -BOOL SIUnregisterPollingHandler(__OSInterruptHandler handler); -void SIInit(void); -u32 SIGetStatus(s32 chan); -void SISetCommand(s32 chan, u32 command); -void SITransferCommands(void); -u32 SISetXY(u32 x, u32 y); -u32 SIEnablePolling(u32 poll); -u32 SIDisablePolling(u32 poll); -static BOOL SIGetResponseRaw(s32 chan); -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); - -vu32 __SIRegs[64] AT_ADDRESS(0xCC006400); - -#ifdef __cplusplus -} -#endif - -#endif /* SIBIOS_H */ diff --git a/include/dolphin/si/SISamplingRate.h b/include/dolphin/si/SISamplingRate.h deleted file mode 100644 index 01aa045fef..0000000000 --- a/include/dolphin/si/SISamplingRate.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef SISAMPLINGRATE_H -#define SISAMPLINGRATE_H - -#include "dolphin/types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct XY { - u16 line; - u8 count; -} XY; - -void SISetSamplingRate(u32 msec); -void SIRefreshSamplingRate(void); - -#ifdef __cplusplus -} -#endif - -#endif /* SISAMPLINGRATE_H */ diff --git a/include/dolphin/sp.h b/include/dolphin/sp.h new file mode 100644 index 0000000000..52f4fff020 --- /dev/null +++ b/include/dolphin/sp.h @@ -0,0 +1,40 @@ +#ifndef _DOLPHIN_SP_H_ +#define _DOLPHIN_SP_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + AXPBADPCM adpcm; + AXPBADPCMLOOP adpcmloop; +} SPADPCM; + +typedef struct { + u32 type; + u32 sampleRate; + u32 loopAddr; + u32 loopEndAddr; + u32 endAddr; + u32 currentAddr; + SPADPCM* adpcm; +} SPSoundEntry; + +typedef struct { + u32 entries; + SPSoundEntry sound[1]; +} SPSoundTable; + +void SPInitSoundTable(SPSoundTable* table, u32 aramBase, u32 zeroBase); +SPSoundEntry* SPGetSoundEntry(SPSoundTable* table, u32 index); +void SPPrepareSound(SPSoundEntry* sound, AXVPB* axvpb, u32 sampleRate); +void SPPrepareEnd(SPSoundEntry* sound, AXVPB* axvpb); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/syn.h b/include/dolphin/syn.h new file mode 100644 index 0000000000..8373c5db91 --- /dev/null +++ b/include/dolphin/syn.h @@ -0,0 +1,172 @@ +#ifndef _DOLPHIN_SYN_H_ +#define _DOLPHIN_SYN_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SYN_INPUT_BUFFER_SIZE 0x100 + +typedef struct WTINST { + /* 0x00 */ u16 keyRegion[128]; +} WTINST; + +typedef struct WTREGION { + /* 0x00 */ u8 unityNote; + /* 0x01 */ u8 keyGroup; + /* 0x02 */ s16 fineTune; + /* 0x04 */ s32 attn; + /* 0x08 */ u32 loopStart; + /* 0x0C */ u32 loopLength; + /* 0x10 */ u32 articulationIndex; + /* 0x14 */ u32 sampleIndex; +} WTREGION; + +typedef struct WTART { + /* 0x00 */ s32 lfoFreq; + /* 0x04 */ s32 lfoDelay; + /* 0x08 */ s32 lfoAtten; + /* 0x0C */ s32 lfoPitch; + /* 0x10 */ s32 lfoMod2Atten; + /* 0x14 */ s32 lfoMod2Pitch; + /* 0x18 */ s32 eg1Attack; + /* 0x1C */ s32 eg1Decay; + /* 0x20 */ s32 eg1Sustain; + /* 0x24 */ s32 eg1Release; + /* 0x28 */ s32 eg1Vel2Attack; + /* 0x2C */ s32 eg1Key2Decay; + /* 0x30 */ s32 eg2Attack; + /* 0x34 */ s32 eg2Decay; + /* 0x38 */ s32 eg2Sustain; + /* 0x3C */ s32 eg2Release; + /* 0x40 */ s32 eg2Vel2Attack; + /* 0x44 */ s32 eg2Key2Decay; + /* 0x48 */ s32 eg2Pitch; + /* 0x4C */ s32 pan; +} WTART; + +typedef struct WTSAMPLE { + /* 0x00 */ u16 format; + /* 0x02 */ u16 sampleRate; + /* 0x04 */ u32 offset; + /* 0x08 */ u32 length; + /* 0x0C */ u16 adpcmIndex; +} WTSAMPLE; + +typedef struct WTADPCM { + /* 0x00 */ u16 a[8][2]; + /* 0x20 */ u16 gain; + /* 0x22 */ u16 pred_scale; + /* 0x24 */ u16 yn1; + /* 0x26 */ u16 yn2; + /* 0x28 */ u16 loop_pred_scale; + /* 0x2A */ u16 loop_yn1; + /* 0x2C */ u16 loop_yn2; +} WTADPCM; + +typedef struct SYNSYNTH { + /* 0x0000 */ void* next; + /* 0x0004 */ WTINST* percussiveInst; + /* 0x0008 */ WTINST* melodicInst; + /* 0x000C */ WTREGION* region; + /* 0x0010 */ WTART* art; + /* 0x0014 */ WTSAMPLE* sample; + /* 0x0018 */ WTADPCM* adpcm; + /* 0x001C */ u32 aramBaseWord; + /* 0x0020 */ u32 aramBaseByte; + /* 0x0024 */ u32 aramBaseNibble; + /* 0x0028 */ u32 zeroBaseWord; + /* 0x002C */ u32 zeroBaseByte; + /* 0x0030 */ u32 zeroBaseNibble; + /* 0x0034 */ u32 priorityVoiceAlloc; + /* 0x0038 */ u32 priorityNoteOn; + /* 0x003C */ u32 priorityNoteRelease; + /* 0x0040 */ WTINST* inst[16]; + /* 0x0080 */ s32 masterVolume; + /* 0x0084 */ u8 controller[16][128]; + /* 0x0844 */ u8 rpn[16]; + /* 0x0894 */ s16 dataEntry[16]; + /* 0x08B4 */ s32 pwMaxCents[16]; + /* 0x08F4 */ s32 pwCents[16]; + /* 0x0934 */ s32 volAttn[16]; + /* 0x0974 */ s32 expAttn[16]; + /* 0x09B4 */ s32 auxAAttn[16]; + /* 0x09F4 */ s32 auxBAttn[16]; + /* 0x0A34 */ u8 input[SYN_INPUT_BUFFER_SIZE][3]; + /* 0x0D34 */ u8* inputPosition; + /* 0x0D38 */ u32 inputCounter; + /* 0x0D3C */ u32 notes; + /* 0x0D40 */ void* keyGroup[16][16]; + /* 0x1140 */ void* voice[16][128]; +} SYNSYNTH; + +typedef struct SYNVOICE { + /* 0x00 */ void* next; + /* 0x04 */ AXVPB* axvpb; + /* 0x08 */ SYNSYNTH* synth; + /* 0x0C */ u8 midiChannel; + /* 0x0D */ u8 keyNum; + /* 0x0E */ u8 keyVel; + /* 0x0F */ u8 pan; + /* 0x10 */ u8 keyGroup; + /* 0x14 */ WTREGION* region; + /* 0x18 */ WTART* art; + /* 0x1C */ WTSAMPLE* sample; + /* 0x20 */ WTADPCM* adpcm; + /* 0x24 */ u32 hold; + /* 0x28 */ u32 type; + /* 0x2C */ f32 srcRatio; + /* 0x30 */ s32 cents; + /* 0x34 */ s32 attn; + /* 0x38 */ s32 lfoState; + /* 0x3C */ s32 lfoAttn; + /* 0x40 */ s32 lfoCents; + /* 0x44 */ s32 lfoFreq; + /* 0x48 */ s32 lfoDelay; + /* 0x4C */ s32 lfoAttn_; + /* 0x50 */ s32 lfoCents_; + /* 0x54 */ s32 lfoModAttn; + /* 0x58 */ s32 lfoModCents; + /* 0x5C */ u32 veState; + /* 0x60 */ s32 veAttn; + /* 0x64 */ s32 veAttack; + /* 0x68 */ s32 veAttackDelta; + /* 0x6C */ s32 veDecay; + /* 0x70 */ s32 veSustain; + /* 0x74 */ s32 veRelease; + /* 0x78 */ u32 peState; + /* 0x7C */ s32 peCents; + /* 0x80 */ s32 peAttack; + /* 0x84 */ s32 peDecay; + /* 0x88 */ s32 peSustain; + /* 0x8C */ s32 peRelease; + /* 0x90 */ s32 pePitch; +} SYNVOICE; + +// sample formats +#define SYN_SAMPLE_FORMAT_ADPCM 0 +#define SYN_SAMPLE_FORMAT_PCM16 1 +#define SYN_SAMPLE_FORMAT_PCM8 2 + +// SYN +void SYNInit(void); +void SYNQuit(void); +void SYNRunAudioFrame(void); +void SYNInitSynth(SYNSYNTH* synth, void* wavetable, u32 aramBase, u32 zeroBase, u32 priorityVoiceAlloc, u32 priorityNoteOn, u32 priorityNoteRelease); +void SYNQuitSynth(SYNSYNTH* synth); +void SYNMidiInput(SYNSYNTH* synth, u8* input); +void SYNSetMasterVolume(SYNSYNTH* synth, s32 dB); +s32 SYNGetMasterVolume(SYNSYNTH* synth); +u32 SYNGetActiveNotes(SYNSYNTH* synth); + +// SYNCTRL +u8 SYNGetMidiController(SYNSYNTH* synth, u8 midiChannel, u8 function); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_SYN_H_ diff --git a/include/dolphin/types.h b/include/dolphin/types.h index dc06598ce5..55e37df021 100644 --- a/include/dolphin/types.h +++ b/include/dolphin/types.h @@ -1,51 +1,56 @@ -#ifndef TYPES_H_ -#define TYPES_H_ +#ifndef _DOLPHIN_TYPES_H_ +#define _DOLPHIN_TYPES_H_ -typedef signed char s8; -typedef signed short s16; -typedef signed long s32; -typedef signed long long s64; -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned long u32; -typedef unsigned long long u64; +typedef signed char s8; +typedef unsigned char u8; +typedef signed short int s16; +typedef unsigned short int u16; +typedef signed long s32; +typedef unsigned long u32; +typedef signed long long int s64; +typedef unsigned long long int u64; -typedef volatile u8 vu8; +typedef volatile u8 vu8; typedef volatile u16 vu16; typedef volatile u32 vu32; typedef volatile u64 vu64; -typedef volatile s8 vs8; +typedef volatile s8 vs8; typedef volatile s16 vs16; typedef volatile s32 vs32; typedef volatile s64 vs64; -typedef float f32; +typedef float f32; typedef double f64; + typedef volatile f32 vf32; typedef volatile f64 vf64; +typedef char *Ptr; + typedef int BOOL; -#define TRUE 1 #define FALSE 0 +#define TRUE 1 -#define READU32_BE(ptr, offset) \ - (((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 +#error unknown compiler +#endif -#define ALIGN_DECL(ALIGNMENT) __attribute__((aligned(ALIGNMENT))) +#define ATTRIBUTE_ALIGN(num) __attribute__((aligned(num))) + +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void*)0) +#endif +#endif #include "stddef.h" -#define INT32_MAX (0x7fffffff) -#define UINT32_MAX (0xffffffff) - -#define FLOAT_MIN (1.175494351e-38f) -#define FLOAT_MAX (3.40282346638528860e+38f) - -#ifdef __MWERKS__ -#define AT_ADDRESS(xyz) : (xyz) -#else -#define AT_ADDRESS(xyz) -#endif - #endif diff --git a/include/dolphin/vi.h b/include/dolphin/vi.h index 9c7712e746..af41844266 100644 --- a/include/dolphin/vi.h +++ b/include/dolphin/vi.h @@ -1,147 +1,7 @@ -#ifndef VI_H -#define VI_H +#ifndef _DOLPHIN_VI_H_ +#define _DOLPHIN_VI_H_ -#include "dolphin/types.h" +#include +#include -#ifdef __cplusplus -extern "C" { #endif - -typedef struct _GXRenderModeObj GXRenderModeObj; - -#define VI_INTERLACE (0) -#define VI_NON_INTERLACE (1) -#define VI_PROGRESSIVE (2) -#define VI_3D (3) - -// Video output formats -#define VI_NTSC (0) -#define VI_PAL (1) -#define VI_MPAL (2) -#define VI_DEBUG (3) -#define VI_DEBUG_PAL (4) -#define VI_EURGB60 (5) -#define VI_GCA (6) - -// Conversion to TVMode used in enums -#define VI_TVMODE(FMT, INT) (((FMT) << 2) + (INT)) - -// TV Modes -typedef enum { - // NTSC - VI_TVMODE_NTSC_INT = VI_TVMODE(VI_NTSC, VI_INTERLACE), // 0 - VI_TVMODE_NTSC_DS = VI_TVMODE(VI_NTSC, VI_NON_INTERLACE), // 1 - VI_TVMODE_NTSC_PROG = VI_TVMODE(VI_NTSC, VI_PROGRESSIVE), // 2 - VI_TVMODE_NTSC_3D = VI_TVMODE(VI_NTSC, VI_3D), // 3 - - // PAL - VI_TVMODE_PAL_INT = VI_TVMODE(VI_PAL, VI_INTERLACE), // 4 - VI_TVMODE_PAL_DS = VI_TVMODE(VI_PAL, VI_NON_INTERLACE), // 5 - - // MPAL - VI_TVMODE_MPAL_INT = VI_TVMODE(VI_MPAL, VI_INTERLACE), // 8 - VI_TVMODE_MPAL_DS = VI_TVMODE(VI_MPAL, VI_NON_INTERLACE), // 9 - - // Debug - VI_TVMODE_DEBUG_INT = VI_TVMODE(VI_DEBUG, VI_INTERLACE), // 12 - - // Debug PAL - VI_TVMODE_DEBUG_PAL_INT = VI_TVMODE(VI_DEBUG_PAL, VI_INTERLACE), // 16 - VI_TVMODE_DEBUG_PAL_DS = VI_TVMODE(VI_DEBUG_PAL, VI_NON_INTERLACE), // 17 - - // EU RGB60 - VI_TVMODE_EURGB60_INT = VI_TVMODE(VI_EURGB60, VI_INTERLACE), // 20 - VI_TVMODE_EURGB60_DS = VI_TVMODE(VI_EURGB60, VI_NON_INTERLACE), // 21 - - // GCA - VI_TVMODE_GCA_INT = VI_TVMODE(VI_GCA, VI_INTERLACE), // 24 - VI_TVMODE_GCA_DS = VI_TVMODE(VI_GCA, VI_NON_INTERLACE), // 25 - VI_TVMODE_GCA_PROG = VI_TVMODE(VI_GCA, VI_PROGRESSIVE), // 26 -} VITVMode; - -typedef enum { VI_XFBMODE_SF = 0, VI_XFBMODE_DF } VIXFBMode; - -typedef void (*VIRetraceCallback)(u32); -typedef void (*VIPositionCallback)(s16 x, s16 y); - -typedef struct VITimingInfo { - u8 equ; // _00 - u16 acv; // _02 - u16 prbOdd; // _04 - u16 prbEven; // _06 - u16 psbOdd; // _08 - u16 psbEven; // _0A - u8 bs1; // _0C - u8 bs2; // _0D - u8 bs3; // _0E - u8 bs4; // _0F - u16 be1; // _10 - u16 be2; // _12 - u16 be3; // _14 - u16 be4; // _16 - u16 numHalfLines; // _18 - u16 hlw; // _1A - u8 hsy; // _1C - u8 hcs; // _1D - u8 hce; // _1E - u8 hbe640; // _1F - u16 hbs640; // _20 - u8 hbeCCIR656; // _24 - u16 hbsCCIR656; // _26 -} VITimingInfo; - -typedef struct VIPositionInfo { - u16 dispPosX; // _00 - u16 dispPosY; // _02 - u16 dispSizeX; // _04 - u16 dispSizeY; // _06 - u16 adjDispPosX; // _08 - u16 adjDispPosY; // _0A - u16 adjDispSizeY; // _0C - u16 adjPanPosY; // _0E - u16 adjPanSizeY; // _10 - u16 fbSizeX; // _12 - u16 fbSizeY; // _14 - u16 panPosX; // _16 - u16 panPosY; // _18 - u16 panSizeX; // _1A - u16 panSizeY; // _1C - VIXFBMode xfbMode; // _20 - u32 nonInter; // _24 - u32 tv; // _28 - u8 wordPerLine; // _2C - u8 std; // _2D - u8 wpl; // _2E - u32 bufAddr; // _30 - u32 tfbb; // _34 - u32 bfbb; // _38 - u8 xof; // _3C - BOOL isBlack; // _40 - BOOL is3D; // _44 - u32 rbufAddr; // _48 - u32 rtfbb; // _4C - u32 rbfbb; // _50 - VITimingInfo* timing; // _54 -} VIPositionInfo; - -void VIWaitForRetrace(void); -void VISetNextFrameBuffer(void*); -VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback); -VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback); -void VIInit(); -void VIConfigure(const GXRenderModeObj*); -void VIFlush(); -void* VIGetNextFrameBuffer(); -void* VIGetCurrentFrameBuffer(); -void VISetBlack(BOOL); -u32 VIGetRetraceCount(); -u32 VIGetDTVStatus(); -u32 VIGetTvFormat(void); - -vu16 __VIRegs[59] AT_ADDRESS(0xCC002000); - -#ifdef __cplusplus -}; -#endif - -#endif /* VI_H */ diff --git a/include/dolphin/vi/vifuncs.h b/include/dolphin/vi/vifuncs.h new file mode 100644 index 0000000000..eb95984ede --- /dev/null +++ b/include/dolphin/vi/vifuncs.h @@ -0,0 +1,36 @@ +#ifndef _DOLPHIN_VIFUNCS_H_ +#define _DOLPHIN_VIFUNCS_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback cb); +VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback cb); +void VIInit(void); +void VIWaitForRetrace(void); +void VIConfigure(const GXRenderModeObj* rm); +void VIConfigurePan(u16 xOrg, u16 yOrg, u16 width, u16 height); +void VIFlush(void); +void VISetNextFrameBuffer(void* fb); +void VISetNextRightFrameBuffer(void* fb); +void VISetBlack(BOOL black); +void VISet3D(BOOL threeD); +u32 VIGetRetraceCount(void); +u32 VIGetNextField(void); +u32 VIGetCurrentLine(void); +u32 VIGetTvFormat(void); +void* VIGetNextFrameBuffer(void); +void* VIGetCurrentFrameBuffer(void); +u32 VIGetScanMode(void); +u32 VIGetDTVStatus(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/vi/vitypes.h b/include/dolphin/vi/vitypes.h new file mode 100644 index 0000000000..983a89b7ea --- /dev/null +++ b/include/dolphin/vi/vitypes.h @@ -0,0 +1,41 @@ +#ifndef _DOLPHIN_VITYPES_H_ +#define _DOLPHIN_VITYPES_H_ + +#include + +#define VI_TVMODE(format, interlace) (((format) << 2) + (interlace)) + +#define VI_INTERLACE 0 +#define VI_NON_INTERLACE 1 +#define VI_PROGRESSIVE 2 + +#define VI_NTSC 0 +#define VI_PAL 1 +#define VI_MPAL 2 +#define VI_DEBUG 3 +#define VI_DEBUG_PAL 4 +#define VI_EURGB60 5 + +typedef enum { + VI_TVMODE_NTSC_INT = VI_TVMODE(VI_NTSC, VI_INTERLACE), + VI_TVMODE_NTSC_DS = VI_TVMODE(VI_NTSC, VI_NON_INTERLACE), + VI_TVMODE_NTSC_PROG = VI_TVMODE(VI_NTSC, VI_PROGRESSIVE), + VI_TVMODE_PAL_INT = VI_TVMODE(VI_PAL, VI_INTERLACE), + VI_TVMODE_PAL_DS = VI_TVMODE(VI_PAL, VI_NON_INTERLACE), + VI_TVMODE_EURGB60_INT = VI_TVMODE(VI_EURGB60, VI_INTERLACE), + VI_TVMODE_EURGB60_DS = VI_TVMODE(VI_EURGB60, VI_NON_INTERLACE), + VI_TVMODE_MPAL_INT = VI_TVMODE(VI_MPAL, VI_INTERLACE), + VI_TVMODE_MPAL_DS = VI_TVMODE(VI_MPAL, VI_NON_INTERLACE), + VI_TVMODE_DEBUG_INT = VI_TVMODE(VI_DEBUG, VI_INTERLACE), + VI_TVMODE_DEBUG_PAL_INT = VI_TVMODE(VI_DEBUG_PAL, VI_INTERLACE), + VI_TVMODE_DEBUG_PAL_DS = VI_TVMODE(VI_DEBUG_PAL, VI_NON_INTERLACE) +} VITVMode; + +typedef enum { + VI_XFBMODE_SF = 0, + VI_XFBMODE_DF +} VIXFBMode; + +typedef void (*VIRetraceCallback)(u32 retraceCount); + +#endif diff --git a/include/global.h b/include/global.h index 5cb534ede8..a5b3b6ea9a 100644 --- a/include/global.h +++ b/include/global.h @@ -8,6 +8,8 @@ #define VERSION_GCN_JPN 2 #define VERSION_SHIELD_DEBUG 3 +#define ALIGN_DECL(ALIGNMENT) __attribute__((aligned(ALIGNMENT))) + #define ARRAY_SIZE(o) (sizeof((o)) / sizeof(*(o))) // Align X to the previous N bytes (N must be power of two) @@ -62,6 +64,25 @@ void* __memcpy(void*, const void*, int); #define UNK_BSS(name) \ static u8 lit_##name[1 + 3 /* padding */]; +#define UNK_REL_BSS \ + static u8 lit_1109[1]; \ + static u8 lit_1107[1]; \ + static u8 lit_1105[1]; \ + static u8 lit_1104[1]; \ + static u8 lit_1099[1]; \ + static u8 lit_1097[1]; \ + static u8 lit_1095[1]; \ + static u8 lit_1094[1]; \ + static u8 lit_1057[1]; \ + static u8 lit_1055[1]; \ + static u8 lit_1053[1]; \ + static u8 lit_1052[1]; \ + static u8 lit_1014[1]; \ + static u8 lit_1012[1]; \ + static u8 lit_1010[1]; \ + static u8 lit_1009[1]; + + #define UNK_REL_DATA \ static u8 cNullVec__6Z2Calc[12] = { \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ @@ -74,4 +95,7 @@ void* __memcpy(void*, const void*, int); 0x00000000, \ }; +#define READU32_BE(ptr, offset) \ + (((u32)ptr[offset] << 24) | ((u32)ptr[offset + 1] << 16) | ((u32)ptr[offset + 2] << 8) | (u32)ptr[offset + 3]); + #endif diff --git a/include/m_Do/m_Do_MemCard.h b/include/m_Do/m_Do_MemCard.h index 18cf932620..45d59322c6 100644 --- a/include/m_Do/m_Do_MemCard.h +++ b/include/m_Do/m_Do_MemCard.h @@ -2,7 +2,7 @@ #define M_DO_M_DO_MEMCARD_H #include "card.h" -#include "dolphin/os/OSMutex.h" +#include #include "global.h" class mDoMemCd_Ctrl_c { diff --git a/include/m_Do/m_Do_dvd_thread.h b/include/m_Do/m_Do_dvd_thread.h index 0a6ac3e49c..f0df50ac9b 100644 --- a/include/m_Do/m_Do_dvd_thread.h +++ b/include/m_Do/m_Do_dvd_thread.h @@ -2,8 +2,8 @@ #define M_DO_M_DO_DVD_THREAD_H #include "JSystem/JKernel/JKRArchive.h" -#include "dolphin/os/OSMessage.h" -#include "dolphin/os/OSMutex.h" +#include +#include #include "f_pc/f_pc_node.h" #define mDoDvd_MOUNT_DIRECTION_HEAD 0 diff --git a/include/m_Do/m_Do_hostIO.h b/include/m_Do/m_Do_hostIO.h index 864fd59045..9643ae0b67 100644 --- a/include/m_Do/m_Do_hostIO.h +++ b/include/m_Do/m_Do_hostIO.h @@ -73,4 +73,16 @@ public: extern mDoHIO_root_c mDoHIO_root; +void mDoHIO_updateChild(s8 i_no); +void mDoHIO_deleteChild(s8 i_no); +s8 mDoHIO_createChild(const char*, JORReflexible*); + +#ifdef DEBUG +#define mDoHIO_CREATE_CHILD(i_name, i_node) mDoHIO_createChild(i_name, i_node) +#define mDoHIO_DELETE_CHILD(i_no) mDoHIO_deleteChild(i_no) +#else +#define mDoHIO_CREATE_CHILD(i_name, i_node) (-1) +#define mDoHIO_DELETE_CHILD(i_no) (void)0 +#endif + #endif /* M_DO_M_DO_HOSTIO_H */ diff --git a/include/m_Do/m_Do_machine.h b/include/m_Do/m_Do_machine.h index c89d36a9bb..75b275a7d2 100644 --- a/include/m_Do/m_Do_machine.h +++ b/include/m_Do/m_Do_machine.h @@ -1,7 +1,7 @@ #ifndef M_DO_M_DO_MACHINE_H #define M_DO_M_DO_MACHINE_H -#include "dolphin/gx/GXStruct.h" +#include typedef struct OSContext OSContext; class JKRHeap; @@ -21,8 +21,8 @@ class mDoMch_render_c { public: static void setRenderModeObj(GXRenderModeObj* obj) { mRenderModeObj = obj; } static void setProgressiveMode() { setRenderModeObj(&g_ntscZeldaProg); } - static u16 getEfbHeight() { return mRenderModeObj->efb_height; } - static u16 getFbWidth() { return mRenderModeObj->fb_width; } + static u16 getEfbHeight() { return mRenderModeObj->efbHeight; } + static u16 getFbWidth() { return mRenderModeObj->fbWidth; } static GXRenderModeObj* getRenderModeObj() { return mRenderModeObj; } diff --git a/include/m_Do/m_Do_main.h b/include/m_Do/m_Do_main.h index 64468c50e7..003ebefc38 100644 --- a/include/m_Do/m_Do_main.h +++ b/include/m_Do/m_Do_main.h @@ -2,7 +2,7 @@ #define M_DO_M_DO_MAIN_H #include "JSystem/JKernel/JKRExpHeap.h" -#include "dolphin/os/OSTime.h" +#include class JKRExpHeap; diff --git a/include/m_Do/m_Do_mtx.h b/include/m_Do/m_Do_mtx.h index 85824eee10..71b2d935ee 100644 --- a/include/m_Do/m_Do_mtx.h +++ b/include/m_Do/m_Do_mtx.h @@ -3,7 +3,7 @@ #include "SSystem/SComponent/c_sxyz.h" #include "SSystem/SComponent/c_xyz.h" -#include "dolphin/mtx.h" +#include void mDoMtx_XYZrotS(Mtx, s16, s16, s16); void mDoMtx_XYZrotM(Mtx, s16, s16, s16); @@ -135,7 +135,7 @@ inline void mDoMtx_scale(Mtx m, f32 x, f32 y, f32 z) { } inline void mDoMtx_quat(Mtx m, const Quaternion* q) { - MTXQuat(m, (PSQuaternion*)q); + MTXQuat(m, q); } inline void cMtx_inverse(const Mtx a, Mtx b) { @@ -213,7 +213,7 @@ public: /* 8000CF44 */ static void ZXYrotM(csXyz const& xyz); static void quatS(const Quaternion* quat) { - MTXQuat(now, (PSQuaternion*)quat); + MTXQuat(now, quat); } /* 8000CF7C */ static void quatM(Quaternion const*); diff --git a/src/JSystem/J2DGraph/J2DGrafContext.cpp b/src/JSystem/J2DGraph/J2DGrafContext.cpp index 505ed21c5b..cf7e32bd56 100644 --- a/src/JSystem/J2DGraph/J2DGrafContext.cpp +++ b/src/JSystem/J2DGraph/J2DGrafContext.cpp @@ -101,14 +101,14 @@ void J2DGrafContext::setColor(JUtility::TColor colorTL, JUtility::TColor colorTR mColorBR = colorBR; mColorBL = colorBL; field_0xb0.mType = GX_BM_BLEND; - field_0xb0.mSrcFactor = GX_BL_SRC_ALPHA; - field_0xb0.mDstFactor = GX_BL_INV_SRC_ALPHA; + field_0xb0.mSrcFactor = GX_BL_SRCALPHA; + field_0xb0.mDstFactor = GX_BL_INVSRCALPHA; mLinePart.mType = GX_BM_BLEND; - mLinePart.mSrcFactor = GX_BL_SRC_ALPHA; - mLinePart.mDstFactor = GX_BL_INV_SRC_ALPHA; + mLinePart.mSrcFactor = GX_BL_SRCALPHA; + mLinePart.mDstFactor = GX_BL_INVSRCALPHA; mBoxPart.mType = GX_BM_BLEND; - mBoxPart.mSrcFactor = GX_BL_SRC_ALPHA; - mBoxPart.mDstFactor = GX_BL_INV_SRC_ALPHA; + mBoxPart.mSrcFactor = GX_BL_SRCALPHA; + mBoxPart.mDstFactor = GX_BL_INVSRCALPHA; if ((mColorTL & 0xFF) != 0xFF) { return; } @@ -202,4 +202,4 @@ void J2DGrafContext::line(JGeometry::TVec2 start, JGeometry::TVec2 end void J2DGrafContext::lineTo(JGeometry::TVec2 pos) { this->line(mPrevPos, pos); mPrevPos = pos; -} \ No newline at end of file +} diff --git a/src/JSystem/J2DGraph/J2DMatBlock.cpp b/src/JSystem/J2DGraph/J2DMatBlock.cpp index 230e888ffb..4183653122 100644 --- a/src/JSystem/J2DGraph/J2DMatBlock.cpp +++ b/src/JSystem/J2DGraph/J2DMatBlock.cpp @@ -398,10 +398,10 @@ void J2DTevBlock1::setGX() { } GXSetTevSwapMode(GX_TEVSTAGE0, GXTevSwapSel(mTevStage[0].getRasSel()), GXTevSwapSel(mTevStage[0].getTexSel())); for (int i = 0; i < 4; i++) { - GXSetTevSwapModeTable(GXTevSwapSel(i), GXTevColor(mTevSwapModeTable[i].getR()), - GXTevColor(mTevSwapModeTable[i].getG()), - GXTevColor(mTevSwapModeTable[i].getB()), - GXTevColor(mTevSwapModeTable[i].getA())); + GXSetTevSwapModeTable(GXTevSwapSel(i), GXTevColorChan(mTevSwapModeTable[i].getR()), + GXTevColorChan(mTevSwapModeTable[i].getG()), + GXTevColorChan(mTevSwapModeTable[i].getB()), + GXTevColorChan(mTevSwapModeTable[i].getA())); } mIndTevStage->load(0); } @@ -636,7 +636,7 @@ bool J2DTevBlock2::setTexture(u32 param_0, ResTIMG const* p_timg) { const ResTIMG* timg = mTexture[param_0 == 0]->getTexInfo(); if (timg != NULL && timg->indexTexture) { int tlutname = mTexture[param_0 == 0]->getTlutName(); - u8 tlut_no = tlutname - (tlutname >= GX_MAX_TLUT ? GX_BIGTLUT0 : GX_TLUT0); + u8 tlut_no = tlutname - (tlutname >= GX_BIGTLUT0 ? GX_BIGTLUT0 : GX_TLUT0); if (tlut_no == 0) { tlutid = 1; @@ -845,10 +845,10 @@ void J2DTevBlock2::setGX() { GXSetTevSwapMode(GXTevStageID(i), GXTevSwapSel(mTevStage[i].getRasSel()), GXTevSwapSel(mTevStage[i].getTexSel())); } for (int i = 0; i < 4; i++) { - GXSetTevSwapModeTable(GXTevSwapSel(i), GXTevColor(mTevSwapModeTable[i].getR()), - GXTevColor(mTevSwapModeTable[i].getG()), - GXTevColor(mTevSwapModeTable[i].getB()), - GXTevColor(mTevSwapModeTable[i].getA())); + GXSetTevSwapModeTable(GXTevSwapSel(i), GXTevColorChan(mTevSwapModeTable[i].getR()), + GXTevColorChan(mTevSwapModeTable[i].getG()), + GXTevColorChan(mTevSwapModeTable[i].getB()), + GXTevColorChan(mTevSwapModeTable[i].getA())); } for (u8 i = 0; i < mTevStageNum; i++) { mIndTevStage[i].load(i); @@ -977,7 +977,7 @@ bool J2DTevBlock4::insertTexture(u32 param_0, ResTIMG const* p_timg, JUTPalette* continue; } int tlutName = mTexture[i]->getTlutName(); - u8 tlut_no = tlutName - (tlutName >= GX_MAX_TLUT ? GX_BIGTLUT0 : GX_TLUT0); + u8 tlut_no = tlutName - (tlutName >= GX_BIGTLUT0 ? GX_BIGTLUT0 : GX_TLUT0); if (tlut_no < 4) { local_44 |= 1 << tlut_no; } @@ -1095,7 +1095,7 @@ bool J2DTevBlock4::setTexture(u32 param_0, ResTIMG const* p_timg) { const ResTIMG* timg = mTexture[i]->getTexInfo(); if (timg != NULL && timg->indexTexture) { int tlutname = mTexture[i]->getTlutName(); - u8 tlut_no = tlutname - (tlutname >= GX_MAX_TLUT ? GX_BIGTLUT0 : GX_TLUT0); + u8 tlut_no = tlutname - (tlutname >= GX_BIGTLUT0 ? GX_BIGTLUT0 : GX_TLUT0); if (tlut_no < 4) { used_tlut |= 1 << tlut_no; @@ -1312,10 +1312,10 @@ void J2DTevBlock4::setGX() { GXSetTevSwapMode(GXTevStageID(i), GXTevSwapSel(mTevStage[i].getRasSel()), GXTevSwapSel(mTevStage[i].getTexSel())); } for (int i = 0; i < 4; i++) { - GXSetTevSwapModeTable(GXTevSwapSel(i), GXTevColor(mTevSwapModeTable[i].getR()), - GXTevColor(mTevSwapModeTable[i].getG()), - GXTevColor(mTevSwapModeTable[i].getB()), - GXTevColor(mTevSwapModeTable[i].getA())); + GXSetTevSwapModeTable(GXTevSwapSel(i), GXTevColorChan(mTevSwapModeTable[i].getR()), + GXTevColorChan(mTevSwapModeTable[i].getG()), + GXTevColorChan(mTevSwapModeTable[i].getB()), + GXTevColorChan(mTevSwapModeTable[i].getA())); } for (u8 i = 0; i < mTevStageNum; i++) { mIndTevStage[i].load(i); @@ -1413,7 +1413,7 @@ bool J2DTevBlock8::insertTexture(u32 param_0, ResTIMG const* p_timg, JUTPalette* continue; } int tlutName = mTexture[i]->getTlutName(); - u8 tlut_no = tlutName - (tlutName >= GX_MAX_TLUT ? GX_BIGTLUT0 : GX_TLUT0); + u8 tlut_no = tlutName - (tlutName >= GX_BIGTLUT0 ? GX_BIGTLUT0 : GX_TLUT0); if (tlut_no < 8) { local_44 |= 1 << tlut_no; } @@ -1531,7 +1531,7 @@ bool J2DTevBlock8::setTexture(u32 param_0, ResTIMG const* p_timg) { const ResTIMG* timg = mTexture[i]->getTexInfo(); if (timg != NULL && timg->indexTexture) { int tlutname = mTexture[i]->getTlutName(); - u8 tlut_no = tlutname - (tlutname >= GX_MAX_TLUT ? GX_BIGTLUT0 : GX_TLUT0); + u8 tlut_no = tlutname - (tlutname >= GX_BIGTLUT0 ? GX_BIGTLUT0 : GX_TLUT0); if (tlut_no < 8) { used_tlut |= 1 << tlut_no; @@ -1743,10 +1743,10 @@ void J2DTevBlock8::setGX() { GXSetTevSwapMode(GXTevStageID(i), GXTevSwapSel(mTevStage[i].getRasSel()), GXTevSwapSel(mTevStage[i].getTexSel())); } for (int i = 0; i < 4; i++) { - GXSetTevSwapModeTable(GXTevSwapSel(i), GXTevColor(mTevSwapModeTable[i].getR()), - GXTevColor(mTevSwapModeTable[i].getG()), - GXTevColor(mTevSwapModeTable[i].getB()), - GXTevColor(mTevSwapModeTable[i].getA())); + GXSetTevSwapModeTable(GXTevSwapSel(i), GXTevColorChan(mTevSwapModeTable[i].getR()), + GXTevColorChan(mTevSwapModeTable[i].getG()), + GXTevColorChan(mTevSwapModeTable[i].getB()), + GXTevColorChan(mTevSwapModeTable[i].getA())); } for (u8 i = 0; i < mTevStageNum; i++) { mIndTevStage[i].load(i); @@ -1844,7 +1844,7 @@ bool J2DTevBlock16::insertTexture(u32 param_0, ResTIMG const* p_timg, JUTPalette continue; } int tlutName = mTexture[i]->getTlutName(); - u8 tlut_no = tlutName - (tlutName >= GX_MAX_TLUT ? GX_BIGTLUT0 : GX_TLUT0); + u8 tlut_no = tlutName - (tlutName >= GX_BIGTLUT0 ? GX_BIGTLUT0 : GX_TLUT0); if (tlut_no < 8) { local_44 |= 1 << tlut_no; } @@ -1962,7 +1962,7 @@ bool J2DTevBlock16::setTexture(u32 param_0, ResTIMG const* p_timg) { const ResTIMG* timg = mTexture[i]->getTexInfo(); if (timg != NULL && timg->indexTexture) { int tlutname = mTexture[i]->getTlutName(); - u8 tlut_no = tlutname - (tlutname >= GX_MAX_TLUT ? GX_BIGTLUT0 : GX_TLUT0); + u8 tlut_no = tlutname - (tlutname >= GX_BIGTLUT0 ? GX_BIGTLUT0 : GX_TLUT0); if (tlut_no < 8) { used_tlut |= 1 << tlut_no; @@ -2174,10 +2174,10 @@ void J2DTevBlock16::setGX() { GXSetTevSwapMode(GXTevStageID(i), GXTevSwapSel(mTevStage[i].getRasSel()), GXTevSwapSel(mTevStage[i].getTexSel())); } for (int i = 0; i < 4; i++) { - GXSetTevSwapModeTable(GXTevSwapSel(i), GXTevColor(mTevSwapModeTable[i].getR()), - GXTevColor(mTevSwapModeTable[i].getG()), - GXTevColor(mTevSwapModeTable[i].getB()), - GXTevColor(mTevSwapModeTable[i].getA())); + GXSetTevSwapModeTable(GXTevSwapSel(i), GXTevColorChan(mTevSwapModeTable[i].getR()), + GXTevColorChan(mTevSwapModeTable[i].getG()), + GXTevColorChan(mTevSwapModeTable[i].getB()), + GXTevColorChan(mTevSwapModeTable[i].getA())); } for (u8 i = 0; i < mTevStageNum; i++) { mIndTevStage[i].load(i); diff --git a/src/JSystem/J2DGraph/J2DPicture.cpp b/src/JSystem/J2DGraph/J2DPicture.cpp index d07ccd851d..03c2fff0a0 100644 --- a/src/JSystem/J2DGraph/J2DPicture.cpp +++ b/src/JSystem/J2DGraph/J2DPicture.cpp @@ -1086,7 +1086,7 @@ void J2DPicture::setTevMode() { } GXSetNumTevStages(u8(i)); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); for (i = 0; i < mTextureNum; i++) { GXSetTexCoordGen(GXTexCoordID(i), GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); @@ -1333,7 +1333,7 @@ u8 J2DPicture::getUsableTlut(u8 param_0) { if (img != NULL && img->indexTexture != 0) { int name = mTexture[i]->getTlutName(); - int var_r0 = name >= GX_MAX_TLUT ? GX_MAX_TLUT : GX_TLUT0; + int var_r0 = name >= GX_BIGTLUT0 ? GX_BIGTLUT0 : GX_TLUT0; u8 temp_r0 = name - var_r0; if (temp_r0 < 2) { @@ -1481,4 +1481,4 @@ bool J2DPicture::isUsed(ResFONT const* param_0) { /* 802FF65C-802FF660 2F9F9C 0004+00 1/0 0/0 0/0 .text rewriteAlpha__10J2DPictureFv */ void J2DPicture::rewriteAlpha() { /* empty function */ -} \ No newline at end of file +} diff --git a/src/JSystem/J2DGraph/J2DScreen.cpp b/src/JSystem/J2DGraph/J2DScreen.cpp index e516c23966..51772c610b 100644 --- a/src/JSystem/J2DGraph/J2DScreen.cpp +++ b/src/JSystem/J2DGraph/J2DScreen.cpp @@ -319,7 +319,7 @@ void J2DScreen::drawSelf(f32 param_0, f32 param_1, Mtx* param_2) { JUtility::TColor sp8(alpha | ((u32)color & 0xFFFFFF00)); color = sp8; - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GXBegin(GX_QUADS, GX_VTXFMT0, 4); diff --git a/src/JSystem/J2DGraph/J2DTevs.cpp b/src/JSystem/J2DGraph/J2DTevs.cpp index 40d5bfd24d..b5acf3b534 100644 --- a/src/JSystem/J2DGraph/J2DTevs.cpp +++ b/src/JSystem/J2DGraph/J2DTevs.cpp @@ -69,7 +69,7 @@ void J2DIndTevStage::load(u8 tevStage) { /* 802EA098-802EA0CC 2E49D8 0034+00 0/0 1/1 0/0 .text load__12J2DIndTexMtxFUc */ void J2DIndTexMtx::load(u8 indTexMtx) { - GXSetIndTexMtx((GXIndTexMtxID)(GX_ITM_0 + indTexMtx), (f32*)mIndTexMtxInfo.mMtx, + GXSetIndTexMtx((GXIndTexMtxID)(GX_ITM_0 + indTexMtx), mIndTexMtxInfo.mMtx, mIndTexMtxInfo.mScaleExp); } @@ -165,7 +165,7 @@ extern const J2DTevSwapModeTableInfo j2dDefaultTevSwapModeTable = { GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA}; /* 804561A0-804561A4 0047A0 0004+00 0/0 3/3 0/0 .sdata2 j2dDefaultBlendInfo */ -extern const J2DBlendInfo j2dDefaultBlendInfo = {GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, +extern const J2DBlendInfo j2dDefaultBlendInfo = {GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP}; /* 804561A4-804561A8 0047A4 0004+00 0/0 1/1 0/0 .sdata2 None */ diff --git a/src/JSystem/J2DGraph/J2DWindow.cpp b/src/JSystem/J2DGraph/J2DWindow.cpp index f4a1530087..ed578339d7 100644 --- a/src/JSystem/J2DGraph/J2DWindow.cpp +++ b/src/JSystem/J2DGraph/J2DWindow.cpp @@ -430,7 +430,7 @@ void J2DWindow::drawContents(JGeometry::TBox2 const& param_0) { { GXSetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_SET); } else { - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); } GXClearVtxDesc(); GXSetVtxDesc(GX_VA_POS, GX_DIRECT); @@ -573,7 +573,7 @@ void J2DWindow::setTevMode(JUTTexture* param_0, JUtility::TColor param_1, GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); GXSetNumTevStages(1); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); } else { GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); GXSetTevColor(GX_TEVREG0, param_1); @@ -595,7 +595,7 @@ void J2DWindow::setTevMode(JUTTexture* param_0, JUtility::TColor param_1, GXSetNumTevStages(2); } GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); } /* 802FBE60-802FBEDC 2F67A0 007C+00 1/0 0/0 0/0 .text getFrameTexture__9J2DWindowCFUcUc @@ -676,4 +676,4 @@ bool J2DWindow::isUsed(ResFONT const* param_0) { /* 802FC04C-802FC050 2F698C 0004+00 1/0 0/0 0/0 .text rewriteAlpha__9J2DWindowFv */ void J2DWindow::rewriteAlpha() { /* empty function */ -} \ No newline at end of file +} diff --git a/src/JSystem/J3DGraphAnimator/J3DSkinDeform.cpp b/src/JSystem/J3DGraphAnimator/J3DSkinDeform.cpp index c64f15670e..9dd2cd165a 100644 --- a/src/JSystem/J3DGraphAnimator/J3DSkinDeform.cpp +++ b/src/JSystem/J3DGraphAnimator/J3DSkinDeform.cpp @@ -552,9 +552,9 @@ void J3DSkinDeform::deformVtxPos_S16(J3DVertexBuffer* param_0, J3DMtxBuffer* par void* transformedVtxPos = param_0->getTransformedVtxPos(0); for (int i = 0; i < vtxNum; i++) { Mtx* anmMtx = anmMtxs[jointTree->getDrawMtxFlag(mPosData[i])]; - J3DPSMulMtxVec(anmMtx[jointTree->getDrawMtxIndex(mPosData[i])], ((SVec*)currentVtxPos) + i, ((SVec*)transformedVtxPos) + i); + J3DPSMulMtxVec(anmMtx[jointTree->getDrawMtxIndex(mPosData[i])], ((S16Vec*)currentVtxPos) + i, ((S16Vec*)transformedVtxPos) + i); } - DCStoreRange(param_0->getTransformedVtxPos(0), param_0->getVertexData()->getVtxNum() * sizeof(SVec)); + DCStoreRange(param_0->getTransformedVtxPos(0), param_0->getVertexData()->getVtxNum() * sizeof(S16Vec)); param_0->setCurrentVtxPos(transformedVtxPos); } @@ -584,9 +584,9 @@ void J3DSkinDeform::deformVtxNrm_S16(J3DVertexBuffer* param_0) const { void* currentVtxNrm = param_0->getCurrentVtxNrm(); void* transformedVtxNrm = param_0->getTransformedVtxNrm(0); for (int i = 0; i < nrmNum; i++) { - J3DPSMulMtxVec(mNrmMtx[mNrmData[i]], ((SVec*)currentVtxNrm) + i, ((SVec*)transformedVtxNrm) + i); + J3DPSMulMtxVec(mNrmMtx[mNrmData[i]], ((S16Vec*)currentVtxNrm) + i, ((S16Vec*)transformedVtxNrm) + i); } - DCStoreRange(param_0->getTransformedVtxNrm(0), param_0->getVertexData()->getNrmNum() * sizeof(SVec)); + DCStoreRange(param_0->getTransformedVtxNrm(0), param_0->getVertexData()->getNrmNum() * sizeof(S16Vec)); param_0->setCurrentVtxNrm(transformedVtxNrm); } diff --git a/src/JSystem/J3DGraphBase/J3DGD.cpp b/src/JSystem/J3DGraphBase/J3DGD.cpp index 9f247100e2..2bb4e24c82 100644 --- a/src/JSystem/J3DGraphBase/J3DGD.cpp +++ b/src/JSystem/J3DGraphBase/J3DGD.cpp @@ -96,89 +96,89 @@ void J3DGDSetVtxAttrFmtv(GXVtxFmt fmt, GXVtxAttrFmtList const* fmtList, bool par u32 tex7_cnt = GX_TEX_ST; u32 tex7_type = GX_F32; u32 tex7_shift = 0; - for (; fmtList->mAttrib != GX_VA_NULL; fmtList++) { - switch (fmtList->mAttrib) { + for (; fmtList->attr != GX_VA_NULL; fmtList++) { + switch (fmtList->attr) { case GX_VA_POS: - pos_cnt = fmtList->mCompCnt; - pos_type = fmtList->mCompType; - pos_shift = fmtList->mCompShift; + pos_cnt = fmtList->cnt; + pos_type = fmtList->type; + pos_shift = fmtList->frac; break; case GX_VA_NRM: case GX_VA_NBT: - nrm_type = fmtList->mCompType; - if (fmtList->mCompCnt == GX_NRM_NBT3) { + nrm_type = fmtList->type; + if (fmtList->cnt == GX_NRM_NBT3) { nrm_cnt = GX_NRM_NBT; local_34 = 1; } else { if (param_2) { nrm_cnt = GX_NRM_NBT; } else { - nrm_cnt = fmtList->mCompCnt; + nrm_cnt = fmtList->cnt; } local_34 = 0; } break; case GX_VA_CLR0: - clr0_cnt = fmtList->mCompCnt; - clr0_type = fmtList->mCompType; + clr0_cnt = fmtList->cnt; + clr0_type = fmtList->type; break; case GX_VA_CLR1: - clr1_cnt = fmtList->mCompCnt; - clr1_type = fmtList->mCompType; + clr1_cnt = fmtList->cnt; + clr1_type = fmtList->type; break; case GX_VA_TEX0: - tex0_cnt = fmtList->mCompCnt; - tex0_type = fmtList->mCompType; - tex0_shift = fmtList->mCompShift; + tex0_cnt = fmtList->cnt; + tex0_type = fmtList->type; + tex0_shift = fmtList->frac; break; case GX_VA_TEX1: - tex1_cnt = fmtList->mCompCnt; - tex1_type = fmtList->mCompType; - tex1_shift = fmtList->mCompShift; + tex1_cnt = fmtList->cnt; + tex1_type = fmtList->type; + tex1_shift = fmtList->frac; break; case GX_VA_TEX2: - tex2_cnt = fmtList->mCompCnt; - tex2_type = fmtList->mCompType; - tex2_shift = fmtList->mCompShift; + tex2_cnt = fmtList->cnt; + tex2_type = fmtList->type; + tex2_shift = fmtList->frac; break; case GX_VA_TEX3: - tex3_cnt = fmtList->mCompCnt; - tex3_type = fmtList->mCompType; - tex3_shift = fmtList->mCompShift; + tex3_cnt = fmtList->cnt; + tex3_type = fmtList->type; + tex3_shift = fmtList->frac; break; case GX_VA_TEX4: - tex4_cnt = fmtList->mCompCnt; - tex4_type = fmtList->mCompType; - tex4_shift = fmtList->mCompShift; + tex4_cnt = fmtList->cnt; + tex4_type = fmtList->type; + tex4_shift = fmtList->frac; break; case GX_VA_TEX5: - tex5_cnt = fmtList->mCompCnt; - tex5_type = fmtList->mCompType; - tex5_shift = fmtList->mCompShift; + tex5_cnt = fmtList->cnt; + tex5_type = fmtList->type; + tex5_shift = fmtList->frac; break; case GX_VA_TEX6: - tex6_cnt = fmtList->mCompCnt; - tex6_type = fmtList->mCompType; - tex6_shift = fmtList->mCompShift; + tex6_cnt = fmtList->cnt; + tex6_type = fmtList->type; + tex6_shift = fmtList->frac; break; case GX_VA_TEX7: - tex7_cnt = fmtList->mCompCnt; - tex7_type = fmtList->mCompType; - tex7_shift = fmtList->mCompShift; + tex7_cnt = fmtList->cnt; + tex7_type = fmtList->type; + tex7_shift = fmtList->frac; break; } } GDOverflowCheck(0x12); - J3DGDWriteCPCmd(GX_CP_REG_VAT_GRP0 + fmt, + J3DGDWriteCPCmd(CP_REG_VAT_GRP0_ID + fmt, pos_cnt | pos_type << 1 | pos_shift << 4 | nrm_cnt << 9 | nrm_type << 0xa | clr0_cnt << 0xd | clr0_type << 0xe | clr1_cnt << 0x11 | clr1_type << 0x12 | tex0_cnt << 0x15 | tex0_type << 0x16 | tex0_shift << 0x19 | 0x40000000 | local_34 << 0x1f); - J3DGDWriteCPCmd(GX_CP_REG_VAT_GRP1 + fmt, + J3DGDWriteCPCmd(CP_REG_VAT_GRP1_ID + fmt, tex1_cnt | tex1_type << 1 | tex1_shift << 4 | tex2_cnt << 9 | tex2_type << 0xa | tex2_shift << 0xd | tex3_cnt << 0x12 | tex3_type << 0x13 | tex3_shift << 0x16 | tex4_cnt << 0x1b | tex4_type << 0x1c | 0x80000000); - J3DGDWriteCPCmd(GX_CP_REG_VAT_GRP2 + fmt, + J3DGDWriteCPCmd(CP_REG_VAT_GRP2_ID + fmt, tex4_shift | tex5_cnt << 5 | tex5_type << 6 | tex5_shift << 9 | tex6_cnt << 0xe | tex6_type << 0xf | tex6_shift << 0x12 | tex7_cnt << 0x17 | tex7_type << 0x18 | tex7_shift << 0x1b); @@ -482,14 +482,14 @@ void J3DGDSetIndTexOrder(u32 count, GXTexCoordID coord0, GXTexMapID map0, GXTexC void J3DGDSetTevOrder(GXTevStageID stage, GXTexCoordID coord0, GXTexMapID map0, GXChannelID channel0, GXTexCoordID coord1, GXTexMapID map1, GXChannelID channel1) { - coord0 = coord0 >= GX_MAXCOORD ? GX_TEXCOORD0 : coord0; - coord1 = coord1 >= GX_MAXCOORD ? GX_TEXCOORD0 : coord1; + coord0 = coord0 >= GX_MAX_TEXCOORD ? GX_TEXCOORD0 : coord0; + coord1 = coord1 >= GX_MAX_TEXCOORD ? GX_TEXCOORD0 : coord1; GDOverflowCheck(5); static u8 c2r[] = {0, 1, 0, 1, 0, 1, 7, 5, 6, 0, 0, 0, 0, 0, 0, 7}; J3DGDWriteBPCmd((map0 & 7) | coord0 << 3 | - (map0 != GX_TEXMAP_NULL && !(map0 & GX_TEXMAP_DISABLE)) << 6 | + (map0 != GX_TEXMAP_NULL && !(map0 & GX_TEX_DISABLE)) << 6 | c2r[channel0 & 0xf] << 7 | (map1 & 7) << 0xc | coord1 << 0xf | - (map1 != GX_TEXMAP_NULL && !(map1 & GX_TEXMAP_DISABLE)) << 0x12 | + (map1 != GX_TEXMAP_NULL && !(map1 & GX_TEX_DISABLE)) << 0x12 | c2r[channel1 & 0xf] << 0x13 | (stage / 2 + GX_BP_REG_RAS1_TREF0) << 0x18); } @@ -552,8 +552,8 @@ void J3DGDSetFog(GXFogType fogType, f32 param_1, f32 param_2, f32 nearZ, f32 far void J3DGDSetFogRangeAdj(u8 param_0, u16 param_1, GXFogAdjTable* table) { if (param_0 != 0) { for (int i = 0; i < 0xa; i += 2) { - J3DGDWriteBPCmd((i / 2 + GX_BP_REG_FOGRANGEK0) << 0x18 | table->fogVals[i + 1] << 0xc | - table->fogVals[i]); + J3DGDWriteBPCmd((i / 2 + GX_BP_REG_FOGRANGEK0) << 0x18 | table->r[i + 1] << 0xc | + table->r[i]); } } u32 cmd = GX_BP_REG_FOGRANGE << 0x18 | (param_1 + 0x156) | param_0 << 0xa; diff --git a/src/JSystem/J3DGraphBase/J3DMatBlock.cpp b/src/JSystem/J3DGraphBase/J3DMatBlock.cpp index dcf815323c..6af9f074db 100644 --- a/src/JSystem/J3DGraphBase/J3DMatBlock.cpp +++ b/src/JSystem/J3DGraphBase/J3DMatBlock.cpp @@ -10,6 +10,7 @@ #include "dol2asm.h" #include "dolphin/os.h" #include "string.h" +#include "global.h" inline void loadMatColors(const J3DGXColor* color) { J3DGDWriteXFCmdHdr(0x100C, 2); @@ -408,25 +409,25 @@ void J3DColorBlockLightOff::patch() { /* 80318F00-803190AC 313840 01AC+00 2/0 0/0 0/0 .text patchMatColor__21J3DColorBlockLightOffFv */ void J3DColorBlockLightOff::patchMatColor() { GDSetCurrOffset(mMatColorOffset); - u8* start = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); GDOverflowCheck(SizeOfLoadMatColors); loadMatColors(mMatColor); - u8* end = GDGetCurrPointer(); - DCStoreRange(start, end - start); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 803190AC-803194E8 3139EC 043C+00 2/0 0/0 0/0 .text patchLight__21J3DColorBlockLightOffFv */ void J3DColorBlockLightOff::patchLight() { GDSetCurrOffset(mColorChanOffset); - u8* start = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); GDOverflowCheck(SizeOfLoadColorChans); J3DGDWriteXFCmdHdr(0x100e, 4); mColorChan[0].load(); mColorChan[1].load(); mColorChan[2].load(); mColorChan[3].load(); - u8* end = GDGetCurrPointer(); - DCStoreRange(start, end - start); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 803194E8-80319534 313E28 004C+00 1/0 0/0 0/0 .text patch__20J3DColorBlockLightOnFv */ @@ -438,17 +439,17 @@ void J3DColorBlockLightOn::patch() { /* 80319534-803196E0 313E74 01AC+00 1/0 0/0 0/0 .text patchMatColor__20J3DColorBlockLightOnFv */ void J3DColorBlockLightOn::patchMatColor() { GDSetCurrOffset(mMatColorOffset); - u8* start = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); GDOverflowCheck(SizeOfLoadMatColors); loadMatColors(mMatColor); - u8* end = GDGetCurrPointer(); - DCStoreRange(start, end - start); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 803196E0-80319B4C 314020 046C+00 1/0 0/0 0/0 .text patchLight__20J3DColorBlockLightOnFv */ void J3DColorBlockLightOn::patchLight() { GDSetCurrOffset(mColorChanOffset); - u8* start = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); GDOverflowCheck(SizeOfLoadColorChans); J3DGDWriteXFCmdHdr(0x100e, 4); mColorChan[0].load(); @@ -460,8 +461,8 @@ void J3DColorBlockLightOn::patchLight() { mLight[i]->load(i); } } - u8* end = GDGetCurrPointer(); - DCStoreRange(start, end - start); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 80319B4C-80319BB4 31448C 0068+00 2/0 0/0 0/0 .text diff__21J3DColorBlockLightOffFUl */ @@ -563,40 +564,40 @@ void J3DTexGenBlockBasic::load() { /* 8031AA88-8031AB18 3153C8 0090+00 1/0 0/0 0/0 .text patch__21J3DTexGenBlockPatchedFv */ void J3DTexGenBlockPatched::patch() { GDSetCurrOffset(mTexMtxOffset); - u8* start = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); for (u32 i = 0; i < 8; i++) { if (mTexMtx[i]) { mTexMtx[i]->load(i); } } - u8* end = GDGetCurrPointer(); - DCStoreRange(start, end - start); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031AB18-8031ABC0 315458 00A8+00 1/0 0/0 0/0 .text patch__15J3DTexGenBlock4Fv */ void J3DTexGenBlock4::patch() { GDSetCurrOffset(mTexMtxOffset); - u8* start = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); for (u32 i = 0; i < 4; i++) { if (mTexMtx[i] && mTexCoord[i].getTexGenMtx() != GX_IDENTITY) { mTexMtx[i]->load(i); } } - u8* end = GDGetCurrPointer(); - DCStoreRange(start, end - start); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031ABC0-8031AC68 315500 00A8+00 1/0 0/0 0/0 .text patch__19J3DTexGenBlockBasicFv */ void J3DTexGenBlockBasic::patch() { GDSetCurrOffset(mTexMtxOffset); - u8* start = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); for (u32 i = 0; i < 8; i++) { if (mTexMtx[i] && mTexCoord[i].getTexGenMtx() != GX_IDENTITY) { mTexMtx[i]->load(i); } } - u8* end = GDGetCurrPointer(); - DCStoreRange(start, end - start); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031AC68-8031ACD0 3155A8 0068+00 3/0 0/0 0/0 .text diff__21J3DTexGenBlockPatchedFUl */ @@ -693,8 +694,8 @@ void J3DTevBlock2::load() { GXTevKAlphaSel(mTevKAlphaSel[0]), GXTevKColorSel(mTevKColorSel[1]), GXTevKAlphaSel(mTevKAlphaSel[1]), - GXTevColor(mTevSwapModeTable[i / 4].getR()), - GXTevColor(mTevSwapModeTable[i / 4].getG()) + GXTevColorChan(mTevSwapModeTable[i / 4].getR()), + GXTevColorChan(mTevSwapModeTable[i / 4].getG()) ); J3DGDSetTevKonstantSel_SwapModeTable( GXTevStageID(i + 2), @@ -702,8 +703,8 @@ void J3DTevBlock2::load() { GXTevKAlphaSel(mTevKAlphaSel[0]), GXTevKColorSel(mTevKColorSel[1]), GXTevKAlphaSel(mTevKAlphaSel[1]), - GXTevColor(mTevSwapModeTable[i / 4].getB()), - GXTevColor(mTevSwapModeTable[i / 4].getA()) + GXTevColorChan(mTevSwapModeTable[i / 4].getB()), + GXTevColorChan(mTevSwapModeTable[i / 4].getA()) ); } } @@ -754,8 +755,8 @@ void J3DTevBlock4::load() { GXTevKAlphaSel(mTevKAlphaSel[0]), GXTevKColorSel(mTevKColorSel[1]), GXTevKAlphaSel(mTevKAlphaSel[1]), - GXTevColor(mTevSwapModeTable[i / 4].getR()), - GXTevColor(mTevSwapModeTable[i / 4].getG()) + GXTevColorChan(mTevSwapModeTable[i / 4].getR()), + GXTevColorChan(mTevSwapModeTable[i / 4].getG()) ); J3DGDSetTevKonstantSel_SwapModeTable( GXTevStageID(i + 2), @@ -763,8 +764,8 @@ void J3DTevBlock4::load() { GXTevKAlphaSel(mTevKAlphaSel[2]), GXTevKColorSel(mTevKColorSel[3]), GXTevKAlphaSel(mTevKAlphaSel[3]), - GXTevColor(mTevSwapModeTable[i / 4].getB()), - GXTevColor(mTevSwapModeTable[i / 4].getA()) + GXTevColorChan(mTevSwapModeTable[i / 4].getB()), + GXTevColorChan(mTevSwapModeTable[i / 4].getA()) ); } } @@ -815,8 +816,8 @@ void J3DTevBlock16::load() { GXTevKAlphaSel(mTevKAlphaSel[i]), GXTevKColorSel(mTevKColorSel[i + 1]), GXTevKAlphaSel(mTevKAlphaSel[i + 1]), - GXTevColor(mTevSwapModeTable[i / 4].getR()), - GXTevColor(mTevSwapModeTable[i / 4].getG()) + GXTevColorChan(mTevSwapModeTable[i / 4].getR()), + GXTevColorChan(mTevSwapModeTable[i / 4].getG()) ); J3DGDSetTevKonstantSel_SwapModeTable( GXTevStageID(i + 2), @@ -824,8 +825,8 @@ void J3DTevBlock16::load() { GXTevKAlphaSel(mTevKAlphaSel[i + 2]), GXTevKColorSel(mTevKColorSel[i + 3]), GXTevKAlphaSel(mTevKAlphaSel[i + 3]), - GXTevColor(mTevSwapModeTable[i / 4].getB()), - GXTevColor(mTevSwapModeTable[i / 4].getA()) + GXTevColorChan(mTevSwapModeTable[i / 4].getB()), + GXTevColorChan(mTevSwapModeTable[i / 4].getA()) ); } } @@ -835,7 +836,7 @@ void J3DTevBlock16::load() { */ void J3DTevBlockPatched::patchTexNo() { GDSetCurrOffset(mTexNoOffset); - u8* start = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); for (u32 i = 0; i < 8; i++) { if (mTexNo[i] != 0xffff) { @@ -843,15 +844,15 @@ void J3DTevBlockPatched::patchTexNo() { } } - u8* end = GDGetCurrPointer(); - DCStoreRange(start, end - start); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031BFE0-8031C0AC 316920 00CC+00 1/0 0/0 0/0 .text patchTevReg__18J3DTevBlockPatchedFv */ void J3DTevBlockPatched::patchTevReg() { GDSetCurrOffset(mTevRegOffset); - u8 *pStart = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); for (u32 i = 0; i < ARRAY_SIZE(mTevColor) - 1; i++) { J3DGDSetTevColorS10((GXTevRegID)(i + 1), mTevColor[i]); @@ -860,15 +861,15 @@ void J3DTevBlockPatched::patchTevReg() { J3DGDSetTevKColor((GXTevKColorID)i, mTevKColor[i]); } - u8 *pEnd = GDGetCurrPointer(); - DCStoreRange(pStart, pEnd - pStart); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031C0AC-8031C228 3169EC 017C+00 1/0 0/0 0/0 .text * patchTexNoAndTexCoordScale__18J3DTevBlockPatchedFv */ void J3DTevBlockPatched::patchTexNoAndTexCoordScale() { GDSetCurrOffset(mTexNoOffset); - u8 *start = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); u8 tevStageNum = mTevStageNum; for (u32 i = 0; i < 8; i++) { @@ -897,8 +898,8 @@ void J3DTevBlockPatched::patchTexNoAndTexCoordScale() { ); } - u8 *end = GDGetCurrPointer(); - DCStoreRange(start, end - start); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031C228-8031C274 316B68 004C+00 1/0 0/0 0/0 .text patch__18J3DTevBlockPatchedFv */ @@ -910,14 +911,14 @@ void J3DTevBlockPatched::patch() { /* 8031C274-8031C2E4 316BB4 0070+00 1/0 0/0 0/0 .text patchTexNo__12J3DTevBlock1Fv */ void J3DTevBlock1::patchTexNo() { GDSetCurrOffset(mTexNoOffset); - u8 *pStart = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); if (mTexNo[0] != 0xFFFF) { loadTexNo(0, mTexNo[0]); } - u8 *pEnd = GDGetCurrPointer(); - DCStoreRange(pStart, pEnd - pStart); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031C2E4-8031C2E8 316C24 0004+00 1/0 0/0 0/0 .text patchTevReg__12J3DTevBlock1Fv */ @@ -928,7 +929,7 @@ void J3DTevBlock1::patchTevReg() { */ void J3DTevBlock1::patchTexNoAndTexCoordScale() { GDSetCurrOffset(mTexNoOffset); - u8 *start = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); if (mTexNo[0] != 0xffff) { loadTexNo(0, mTexNo[0]); @@ -948,8 +949,8 @@ void J3DTevBlock1::patchTexNoAndTexCoordScale() { J3DSys::sTexCoordScaleTable[mTevOrder[0].getTevOrderInfo().mTexMap & 7] ); - u8 *end = GDGetCurrPointer(); - DCStoreRange(start, end - start); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031C3CC-8031C3F8 316D0C 002C+00 1/0 0/0 0/0 .text patch__12J3DTevBlock1Fv */ @@ -960,7 +961,7 @@ void J3DTevBlock1::patch() { /* 8031C3F8-8031C48C 316D38 0094+00 1/0 0/0 0/0 .text patchTexNo__12J3DTevBlock2Fv */ void J3DTevBlock2::patchTexNo() { GDSetCurrOffset(mTexNoOffset); - u8 *start = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); for (u32 i = 0; i < 2; i++) { if (mTexNo[i] != 0xffff) { @@ -968,14 +969,14 @@ void J3DTevBlock2::patchTexNo() { } } - u8 *end = GDGetCurrPointer(); - DCStoreRange(start, end - start); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031C48C-8031C558 316DCC 00CC+00 1/0 0/0 0/0 .text patchTevReg__12J3DTevBlock2Fv */ void J3DTevBlock2::patchTevReg() { GDSetCurrOffset(mTevRegOffset); - u8 *pStart = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); for (u32 i = 0; i < ARRAY_SIZE(mTevColor) - 1; i++) { J3DGDSetTevColorS10((GXTevRegID)(i + 1), mTevColor[i]); @@ -984,15 +985,15 @@ void J3DTevBlock2::patchTevReg() { J3DGDSetTevKColor((GXTevKColorID)i, mTevKColor[i]); } - u8 *pEnd = GDGetCurrPointer(); - DCStoreRange(pStart, pEnd - pStart); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031C558-8031C6A8 316E98 0150+00 1/0 0/0 0/0 .text patchTexNoAndTexCoordScale__12J3DTevBlock2Fv */ void J3DTevBlock2::patchTexNoAndTexCoordScale() { GDSetCurrOffset(mTexNoOffset); - u8 *start = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); for (u32 i = 0; i < 2; i++) { if (mTexNo[i] != 0xffff) { @@ -1018,8 +1019,8 @@ void J3DTevBlock2::patchTexNoAndTexCoordScale() { J3DSys::sTexCoordScaleTable[mTevOrder[1].getTevOrderInfo().mTexMap & 7] ); - u8 *end = GDGetCurrPointer(); - DCStoreRange(start, end - start); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031C6A8-8031C6F4 316FE8 004C+00 1/0 0/0 0/0 .text patch__12J3DTevBlock2Fv */ @@ -1031,7 +1032,7 @@ void J3DTevBlock2::patch() { /* 8031C6F4-8031C788 317034 0094+00 1/0 0/0 0/0 .text patchTexNo__12J3DTevBlock4Fv */ void J3DTevBlock4::patchTexNo() { GDSetCurrOffset(mTexNoOffset); - u8 *start = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); for (u32 i = 0; i < 4; i++) { if (mTexNo[i] != 0xffff) { @@ -1039,14 +1040,14 @@ void J3DTevBlock4::patchTexNo() { } } - u8 *end = GDGetCurrPointer(); - DCStoreRange(start, end - start); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031C788-8031C854 3170C8 00CC+00 1/0 0/0 0/0 .text patchTevReg__12J3DTevBlock4Fv */ void J3DTevBlock4::patchTevReg() { GDSetCurrOffset(mTevRegOffset); - u8 *pStart = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); for (u32 i = 0; i < ARRAY_SIZE(mTevColor) - 1; i++) { J3DGDSetTevColorS10((GXTevRegID)(i + 1), mTevColor[i]); @@ -1055,15 +1056,15 @@ void J3DTevBlock4::patchTevReg() { J3DGDSetTevKColor((GXTevKColorID)i, mTevKColor[i]); } - u8 *pEnd = GDGetCurrPointer(); - DCStoreRange(pStart, pEnd - pStart); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031C854-8031C9D0 317194 017C+00 1/0 0/0 0/0 .text patchTexNoAndTexCoordScale__12J3DTevBlock4Fv */ void J3DTevBlock4::patchTexNoAndTexCoordScale() { GDSetCurrOffset(mTexNoOffset); - u8 *start = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); u8 tevStageNum = mTevStageNum; for (u32 i = 0; i < 4; i++) { @@ -1092,8 +1093,8 @@ void J3DTevBlock4::patchTexNoAndTexCoordScale() { ); } - u8 *end = GDGetCurrPointer(); - DCStoreRange(start, end - start); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031C9D0-8031CA1C 317310 004C+00 1/0 0/0 0/0 .text patch__12J3DTevBlock4Fv */ void J3DTevBlock4::patch() { @@ -1104,7 +1105,7 @@ void J3DTevBlock4::patch() { /* 8031CA1C-8031CAB0 31735C 0094+00 1/0 0/0 0/0 .text patchTexNo__13J3DTevBlock16Fv */ void J3DTevBlock16::patchTexNo() { GDSetCurrOffset(mTexNoOffset); - u8 *start = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); for (u32 i = 0; i < 8; i++) { if (mTexNo[i] != 0xffff) { @@ -1112,14 +1113,14 @@ void J3DTevBlock16::patchTexNo() { } } - u8 *end = GDGetCurrPointer(); - DCStoreRange(start, end - start); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031CAB0-8031CB7C 3173F0 00CC+00 1/0 0/0 0/0 .text patchTevReg__13J3DTevBlock16Fv */ void J3DTevBlock16::patchTevReg() { GDSetCurrOffset(mTevRegOffset); - u8 *pStart = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); for (u32 i = 0; i < ARRAY_SIZE(mTevColor) - 1; i++) { J3DGDSetTevColorS10((GXTevRegID)(i + 1), mTevColor[i]); @@ -1128,15 +1129,15 @@ void J3DTevBlock16::patchTevReg() { J3DGDSetTevKColor((GXTevKColorID)i, mTevKColor[i]); } - u8 *pEnd = GDGetCurrPointer(); - DCStoreRange(pStart, pEnd - pStart); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031CB7C-8031CCF8 3174BC 017C+00 1/0 0/0 0/0 .text * patchTexNoAndTexCoordScale__13J3DTevBlock16Fv */ void J3DTevBlock16::patchTexNoAndTexCoordScale() { GDSetCurrOffset(mTexNoOffset); - u8 *start = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); u8 tevStageNum = mTevStageNum; for (u32 i = 0; i < 8; i++) { @@ -1165,8 +1166,8 @@ void J3DTevBlock16::patchTexNoAndTexCoordScale() { ); } - u8 *end = GDGetCurrPointer(); - DCStoreRange(start, end - start); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } @@ -1428,7 +1429,7 @@ void J3DTevBlock16::diffTexCoordScale() { /* 8031DED0-8031DFB4 318810 00E4+00 1/0 0/0 0/0 .text ptrToIndex__13J3DTevBlock16Fv */ void J3DTevBlock16::ptrToIndex() { GDSetCurrOffset(mTexNoOffset); - u8* pStart = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); u32 offs = 0; for (u32 i = 0; i < 8; i++) { @@ -1442,15 +1443,15 @@ void J3DTevBlock16::ptrToIndex() { } } - u8 *pEnd = GDGetCurrPointer(); - DCStoreRange(pStart, pEnd - pStart); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031DFB4-8031E098 3188F4 00E4+00 1/0 0/0 0/0 .text ptrToIndex__18J3DTevBlockPatchedFv */ void J3DTevBlockPatched::ptrToIndex() { GDSetCurrOffset(mTexNoOffset); - u8* pStart = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); u32 offs = 0; for (u32 i = 0; i < 8; i++) { @@ -1464,17 +1465,17 @@ void J3DTevBlockPatched::ptrToIndex() { } } - u8 *pEnd = GDGetCurrPointer(); - DCStoreRange(pStart, pEnd - pStart); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031E098-8031E12C 3189D8 0094+00 5/5 1/1 0/0 .text indexToPtr_private__11J3DTevBlockFUl */ void J3DTevBlock::indexToPtr_private(u32 offs) { GDSetCurrOffset(offs); - u8* pStart = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); for (u32 i = 0; ; i++) { - u8* pDL = GDGetCurrPointer(); + void* pDL = GDGetCurrPointer(); if (!isTexNoReg(pDL)) { break; } @@ -1483,8 +1484,8 @@ void J3DTevBlock::indexToPtr_private(u32 offs) { loadTexNo(i, texNoReg); } - u8 *pEnd = GDGetCurrPointer(); - DCStoreRange(pStart, pEnd - pStart); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031E12C-8031E328 318A6C 01FC+00 1/0 0/0 0/0 .text load__15J3DIndBlockFullFv */ @@ -1570,7 +1571,7 @@ void J3DPEBlockTexEdge::load() { void J3DPEBlockXlu::load() { GDOverflowCheck(0x1e); J3DGDSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND,GX_ALWAYS, 0); - J3DGDSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_COPY); + J3DGDSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_COPY); J3DGDSetZMode(1, GX_LEQUAL, 0); J3DGDSetZCompLoc(1); } @@ -1611,10 +1612,10 @@ void J3DPEBlockFull::load() { void J3DPEBlockFull::patch() { GDSetCurrOffset(mFogOffset); GDOverflowCheck(0x37); - u8* start = GDGetCurrPointer(); + void* start = GDGetCurrPointer(); mFog.load(); - u8* end = GDGetCurrPointer(); - DCStoreRange(start, end - start); + void* end = GDGetCurrPointer(); + DCStoreRange(start, (u32)end - (u32)start); } /* 8031F940-8031F9B8 31A280 0078+00 1/0 0/0 0/0 .text diffFog__14J3DPEBlockFullFv */ diff --git a/src/JSystem/J3DGraphBase/J3DPacket.cpp b/src/JSystem/J3DGraphBase/J3DPacket.cpp index c43cce816c..424dbda40a 100644 --- a/src/JSystem/J3DGraphBase/J3DPacket.cpp +++ b/src/JSystem/J3DGraphBase/J3DPacket.cpp @@ -3,9 +3,10 @@ #include "JSystem/J3DGraphBase/J3DDrawBuffer.h" #include "JSystem/J3DGraphBase/J3DMaterial.h" #include "JSystem/JKernel/JKRHeap.h" -#include "dolphin/os/OSCache.h" -#include "dolphin/os/OSInterrupt.h" +#include +#include #include "string.h" +#include "global.h" J3DError J3DDisplayListObj::newDisplayList(u32 capacity) { mCapacity = ALIGN_NEXT(capacity, 0x20); @@ -400,4 +401,4 @@ void J3DPacket::draw() {} int J3DMatPacket::entry(J3DDrawBuffer* i_buffer) { sortFunc func = J3DDrawBuffer::sortFuncTable[i_buffer->mSortType]; return (i_buffer->*func)(this); -} \ No newline at end of file +} diff --git a/src/JSystem/J3DGraphBase/J3DShape.cpp b/src/JSystem/J3DGraphBase/J3DShape.cpp index 17dab88daf..c3351a6824 100644 --- a/src/JSystem/J3DGraphBase/J3DShape.cpp +++ b/src/JSystem/J3DGraphBase/J3DShape.cpp @@ -119,7 +119,7 @@ u32 J3DShape::countBumpMtxNum() const { /* 80314E98-80314EB0 30F7D8 0018+00 1/1 0/0 0/0 .text J3DLoadCPCmd__FUcUl */ void J3DLoadCPCmd(u8 cmd, u32 param) { - GXWGFifo.u8 = GX_CMD_LOAD_CP_REG; + GXWGFifo.u8 = GX_LOAD_CP_REG; GXWGFifo.u8 = cmd; GXWGFifo.u32 = param; } @@ -160,31 +160,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: @@ -194,12 +194,12 @@ 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; @@ -351,4 +351,4 @@ void J3DShape::simpleDrawCache() const { for (u16 n = getMtxGroupNum(), i = 0; i < n; i++) if (getShapeDraw(i) != NULL) getShapeDraw(i)->draw(); -} \ No newline at end of file +} diff --git a/src/JSystem/J3DGraphBase/J3DShapeDraw.cpp b/src/JSystem/J3DGraphBase/J3DShapeDraw.cpp index 6fe5766970..fae878e601 100644 --- a/src/JSystem/J3DGraphBase/J3DShapeDraw.cpp +++ b/src/JSystem/J3DGraphBase/J3DShapeDraw.cpp @@ -7,7 +7,7 @@ #include "JSystem/JKernel/JKRHeap.h" #include "string.h" #include "dolphin/gx.h" -#include "dolphin/os/OSCache.h" +#include #include "global.h" // diff --git a/src/JSystem/J3DGraphBase/J3DShapeMtx.cpp b/src/JSystem/J3DGraphBase/J3DShapeMtx.cpp index ad453ab3d5..65caadad4b 100644 --- a/src/JSystem/J3DGraphBase/J3DShapeMtx.cpp +++ b/src/JSystem/J3DGraphBase/J3DShapeMtx.cpp @@ -31,9 +31,9 @@ void J3DShapeMtx::resetMtxLoadCache() { /* 803130E4-80313128 30DA24 0044+00 1/0 0/0 0/0 .text loadMtxIndx_PNGP__11J3DShapeMtxCFiUs */ void J3DShapeMtx::loadMtxIndx_PNGP(int slot, u16 indx) const { // inlined J3DFifoLoadPosMtxIndx - J3DFifoLoadIndx(GX_CMD_LOAD_INDX_A, indx, 0xB000 | ((u16)(slot * 0x0C))); + J3DFifoLoadIndx(GX_LOAD_INDX_A, indx, 0xB000 | ((u16)(slot * 0x0C))); // inlined J3DFifoLoadNrmMtxIndx3x3 - J3DFifoLoadIndx(GX_CMD_LOAD_INDX_B, indx, 0x8000 | ((u16)((slot * 0x09) + 0x400))); + J3DFifoLoadIndx(GX_LOAD_INDX_B, indx, 0x8000 | ((u16)((slot * 0x09) + 0x400))); } /* 80313128-80313188 30DA68 0060+00 1/0 0/0 0/0 .text loadMtxIndx_PCPU__11J3DShapeMtxCFiUs */ diff --git a/src/JSystem/J3DGraphBase/J3DStruct.cpp b/src/JSystem/J3DGraphBase/J3DStruct.cpp index 8ee47fc799..2e488b989a 100644 --- a/src/JSystem/J3DGraphBase/J3DStruct.cpp +++ b/src/JSystem/J3DGraphBase/J3DStruct.cpp @@ -61,7 +61,7 @@ J3DFogInfo& J3DFogInfo::operator=(J3DFogInfo const& param_0) { mFarZ = param_0.mFarZ; mColor = param_0.mColor; for (int i = 0; i < 10; i++) { - mFogAdjTable.fogVals[i] = param_0.mFogAdjTable.fogVals[i]; + mFogAdjTable.r[i] = param_0.mFogAdjTable.r[i]; } return *this; } @@ -72,4 +72,4 @@ J3DNBTScaleInfo& J3DNBTScaleInfo::operator=(J3DNBTScaleInfo const& param_0) { mbHasScale = param_0.mbHasScale; mScale = param_0.mScale; return *this; -} \ No newline at end of file +} diff --git a/src/JSystem/J3DGraphBase/J3DSys.cpp b/src/JSystem/J3DGraphBase/J3DSys.cpp index 8f48ba181b..ff92ce2e8b 100644 --- a/src/JSystem/J3DGraphBase/J3DSys.cpp +++ b/src/JSystem/J3DGraphBase/J3DSys.cpp @@ -6,7 +6,7 @@ #include "JSystem/J3DGraphBase/J3DSys.h" #include "dol2asm.h" -#include "dolphin/gx/GXPixel.h" +#include #include "dolphin/os.h" #include "dolphin/types.h" #include "global.h" @@ -84,12 +84,12 @@ J3DSys::J3DSys() { /* 8030FEC0-8030FEE4 30A800 0024+00 0/0 1/1 0/0 .text loadPosMtxIndx__6J3DSysCFiUs */ void J3DSys::loadPosMtxIndx(int addr, u16 indx) const { - J3DFifoLoadIndx(GX_CMD_LOAD_INDX_A, indx, 0xB000 | ((u16)(addr * 0x0C))); + J3DFifoLoadIndx(GX_LOAD_INDX_A, indx, 0xB000 | ((u16)(addr * 0x0C))); } /* 8030FEE4-8030FF0C 30A824 0028+00 0/0 1/1 0/0 .text loadNrmMtxIndx__6J3DSysCFiUs */ void J3DSys::loadNrmMtxIndx(int addr, u16 indx) const { - J3DFifoLoadIndx(GX_CMD_LOAD_INDX_B, indx, 0x8000 | ((u16)((addr * 0x09) + 0x400))); + J3DFifoLoadIndx(GX_LOAD_INDX_B, indx, 0x8000 | ((u16)((addr * 0x09) + 0x400))); } /* 8030FF0C-803100BC 30A84C 01B0+00 1/1 0/0 0/0 .text setTexCacheRegion__6J3DSysF15_GXTexCacheSize @@ -149,7 +149,7 @@ void J3DSys::drawInit() { GXSetClipMode(GX_CLIP_ENABLE); GXSetColorUpdate(GX_TRUE); GXSetDither(GX_TRUE); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_NOOP); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP); GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); GXSetZCompLoc(GX_TRUE); @@ -196,7 +196,7 @@ void J3DSys::drawInit() { u8 i; for (i = 0; i < 3; i++) - GXSetIndTexMtx((GXIndTexMtxID)(GX_ITM_0 + i), (f32*)indTexMtx, 1); + GXSetIndTexMtx((GXIndTexMtxID)(GX_ITM_0 + i), indTexMtx, 1); GXSetChanMatColor(GX_COLOR0A0, j3dDefaultColInfo); GXSetChanMatColor(GX_COLOR1A1, j3dDefaultColInfo); @@ -378,14 +378,14 @@ void J3DSys::reinitIndStages() { GXSetIndTexCoordScale(GX_INDTEXSTAGE1, GX_ITS_1, GX_ITS_1); GXSetIndTexCoordScale(GX_INDTEXSTAGE2, GX_ITS_1, GX_ITS_1); GXSetIndTexCoordScale(GX_INDTEXSTAGE3, GX_ITS_1, GX_ITS_1); - GXSetIndTexMtx(GX_ITM_0, (f32*)IndMtx, 1); - GXSetIndTexMtx(GX_ITM_1, (f32*)IndMtx, 1); - GXSetIndTexMtx(GX_ITM_2, (f32*)IndMtx, 1); + GXSetIndTexMtx(GX_ITM_0, IndMtx, 1); + GXSetIndTexMtx(GX_ITM_1, IndMtx, 1); + GXSetIndTexMtx(GX_ITM_2, IndMtx, 1); } /* 80310E3C-80310ED0 30B77C 0094+00 1/1 0/0 0/0 .text reinitPixelProc__6J3DSysFv */ void J3DSys::reinitPixelProc() { - GXSetBlendMode(GX_BM_NONE, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GXSetColorUpdate(GX_TRUE); GXSetAlphaUpdate(GX_FALSE); GXSetDither(GX_TRUE); diff --git a/src/JSystem/J3DGraphBase/J3DTevs.cpp b/src/JSystem/J3DGraphBase/J3DTevs.cpp index 36c740f6a3..da4bdc4b44 100644 --- a/src/JSystem/J3DGraphBase/J3DTevs.cpp +++ b/src/JSystem/J3DGraphBase/J3DTevs.cpp @@ -7,6 +7,7 @@ #include "JSystem/J3DGraphBase/J3DMatBlock.h" #include "JSystem/J3DGraphBase/J3DSys.h" #include "JSystem/J3DGraphBase/J3DTransform.h" +#include "global.h" static void J3DGDLoadTexMtxImm(f32 (*)[4], u32, _GXTexMtxType); static void J3DGDLoadPostTexMtxImm(f32 (*)[4], u32); @@ -548,7 +549,7 @@ extern J3DTevSwapModeInfo const j3dDefaultTevSwapMode = { extern const J3DTevSwapModeTableInfo j3dDefaultTevSwapModeTable = {0x00, 0x01, 0x02, 0x03}; /* 804563EC-804563F0 0049EC 0004+00 0/0 3/3 0/0 .sdata2 j3dDefaultBlendInfo */ -extern const J3DBlendInfo j3dDefaultBlendInfo = {GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_NOOP}; +extern const J3DBlendInfo j3dDefaultBlendInfo = {GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP}; /* 804563F0-804563F8 0049F0 0008+00 0/0 3/3 0/0 .sdata2 j3dDefaultColorChanInfo */ extern const J3DColorChanInfo j3dDefaultColorChanInfo = { diff --git a/src/JSystem/J3DGraphBase/J3DVertex.cpp b/src/JSystem/J3DGraphBase/J3DVertex.cpp index 96f42dedb9..dfdfc48e73 100644 --- a/src/JSystem/J3DGraphBase/J3DVertex.cpp +++ b/src/JSystem/J3DGraphBase/J3DVertex.cpp @@ -8,7 +8,8 @@ #include "JSystem/J3DGraphBase/J3DSys.h" #include "JSystem/JKernel/JKRHeap.h" #include "string.h" -#include "dolphin/os/OSCache.h" +#include +#include "global.h" /* 80310EF8-80310F78 30B838 0080+00 0/0 1/1 0/0 .text __ct__13J3DVertexDataFv */ J3DVertexData::J3DVertexData() { @@ -241,4 +242,4 @@ J3DDrawMtxData::J3DDrawMtxData() { } /* 803115F4-80311630 30BF34 003C+00 0/0 2/2 0/0 .text __dt__14J3DDrawMtxDataFv */ -J3DDrawMtxData::~J3DDrawMtxData() {} \ No newline at end of file +J3DDrawMtxData::~J3DDrawMtxData() {} diff --git a/src/JSystem/J3DGraphLoader/J3DModelLoader.cpp b/src/JSystem/J3DGraphLoader/J3DModelLoader.cpp index a306d5427f..d35577179b 100644 --- a/src/JSystem/J3DGraphLoader/J3DModelLoader.cpp +++ b/src/JSystem/J3DGraphLoader/J3DModelLoader.cpp @@ -263,9 +263,9 @@ void J3DModelLoader::readInformation(J3DModelInfoBlock const* i_block, u32 i_fla /* 803351A4-803351D0 32FAE4 002C+00 1/1 0/0 0/0 .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; diff --git a/src/JSystem/J3DGraphLoader/J3DModelLoaderCalcSize.cpp b/src/JSystem/J3DGraphLoader/J3DModelLoaderCalcSize.cpp index 06ce608403..3926a26753 100644 --- a/src/JSystem/J3DGraphLoader/J3DModelLoaderCalcSize.cpp +++ b/src/JSystem/J3DGraphLoader/J3DModelLoaderCalcSize.cpp @@ -11,6 +11,7 @@ #include "JSystem/J3DGraphAnimator/J3DModelData.h" #include "JSystem/JSupport/JSupport.h" #include "dolphin/os.h" +#include "global.h" /* 80336794-803367D4 3310D4 0040+00 0/0 3/0 0/0 .text countMaterialNum__14J3DModelLoaderFPCv */ diff --git a/src/JSystem/J3DGraphLoader/J3DShapeFactory.cpp b/src/JSystem/J3DGraphLoader/J3DShapeFactory.cpp index 3db0f75b40..898b9201e2 100644 --- a/src/JSystem/J3DGraphLoader/J3DShapeFactory.cpp +++ b/src/JSystem/J3DGraphLoader/J3DShapeFactory.cpp @@ -8,6 +8,7 @@ #include "JSystem/JKernel/JKRHeap.h" #include "JSystem/JSupport/JSupport.h" #include "dolphin/os.h" +#include "global.h" /* 80337350-80337400 331C90 00B0+00 0/0 2/2 0/0 .text __ct__15J3DShapeFactoryFRC13J3DShapeBlock */ J3DShapeFactory::J3DShapeFactory(J3DShapeBlock const& block) { diff --git a/src/JSystem/JAudio2/JASAiCtrl.cpp b/src/JSystem/JAudio2/JASAiCtrl.cpp index 61374f62f6..cb5a76edd9 100644 --- a/src/JSystem/JAudio2/JASAiCtrl.cpp +++ b/src/JSystem/JAudio2/JASAiCtrl.cpp @@ -18,8 +18,8 @@ #include "JSystem/JKernel/JKRSolidHeap.h" #include "dol2asm.h" #include "dolphin/ai.h" -#include "dolphin/os/OSCache.h" -#include "dolphin/os/OSTime.h" +#include +#include /* 80431C58-80431C68 05E978 000C+04 2/2 0/0 0/0 .bss sDmaDacBuffer__9JASDriver */ s16* JASDriver::sDmaDacBuffer[3]; diff --git a/src/JSystem/JAudio2/JASCalc.cpp b/src/JSystem/JAudio2/JASCalc.cpp index d8c71836aa..8f44b09fea 100644 --- a/src/JSystem/JAudio2/JASCalc.cpp +++ b/src/JSystem/JAudio2/JASCalc.cpp @@ -3,7 +3,7 @@ // #include "JSystem/JAudio2/JASCalc.h" -#include "dolphin/os/OSCache.h" +#include #include "math.h" #include "limits.h" @@ -329,4 +329,4 @@ s16 JASCalc::clamp(s32 x) { if (x >= std::numeric_limits::max()) return std::numeric_limits::max(); return x; -} \ No newline at end of file +} diff --git a/src/JSystem/JAudio2/JASDSPInterface.cpp b/src/JSystem/JAudio2/JASDSPInterface.cpp index 605724dc8d..461e56a98a 100644 --- a/src/JSystem/JAudio2/JASDSPInterface.cpp +++ b/src/JSystem/JAudio2/JASDSPInterface.cpp @@ -12,7 +12,7 @@ #include "JSystem/JAudio2/osdsp_task.h" #include "JSystem/JAudio2/JASCriticalSection.h" #include "JSystem/JKernel/JKRSolidHeap.h" -#include "dolphin/os/OSCache.h" +#include /* 804512E8-804512EC 0007E8 0004+00 5/5 0/0 0/0 .sbss CH_BUF__6JASDsp */ JASDsp::TChannel* JASDsp::CH_BUF; diff --git a/src/JSystem/JAudio2/JASDriverIF.cpp b/src/JSystem/JAudio2/JASDriverIF.cpp index d547bb2b5d..4fd0469ebf 100644 --- a/src/JSystem/JAudio2/JASDriverIF.cpp +++ b/src/JSystem/JAudio2/JASDriverIF.cpp @@ -6,7 +6,7 @@ #include "JSystem/JAudio2/JASDriverIF.h" #include "JSystem/JAudio2/JASAiCtrl.h" #include "JSystem/JAudio2/JASDSPInterface.h" -#include "dolphin/os/OSThread.h" +#include // // Declarations: @@ -99,4 +99,4 @@ void JASDriver::DSPSyncCallback() { /* 8029E2F8-8029E320 298C38 0028+00 0/0 1/1 0/0 .text updateDacCallback__9JASDriverFv */ void JASDriver::updateDacCallback() { sUpdateDacCallback.callback(); -} \ No newline at end of file +} diff --git a/src/JSystem/JAudio2/JASHeapCtrl.cpp b/src/JSystem/JAudio2/JASHeapCtrl.cpp index 2bf73cd581..2e3109dc13 100644 --- a/src/JSystem/JAudio2/JASHeapCtrl.cpp +++ b/src/JSystem/JAudio2/JASHeapCtrl.cpp @@ -23,7 +23,7 @@ JASHeap::JASHeap(JASDisposer* disposer) : mTree(this) { void JASHeap::initRootHeap(void* param_0, u32 param_1) { JUT_ASSERT(97, ! isAllocated()); JASMutexLock lock(&mMutex); - mBase = (u8*)OSRoundUpPtr(param_0, 0x20); + mBase = (u8*)OSRoundUp32B(param_0); field_0x40 = NULL; mSize = param_1 - (u32(mBase) - u32(param_0)); } diff --git a/src/JSystem/JAudio2/JAUInitializer.cpp b/src/JSystem/JAudio2/JAUInitializer.cpp index ff5dbc95d4..968048c921 100644 --- a/src/JSystem/JAudio2/JAUInitializer.cpp +++ b/src/JSystem/JAudio2/JAUInitializer.cpp @@ -18,7 +18,7 @@ #include "JSystem/JKernel/JKRAram.h" #include "JSystem/JKernel/JKRSolidHeap.h" #include "JSystem/JKernel/JKRThread.h" -#include "dolphin/os/OSRtc.h" +#include /* 802A4AD0-802A4B28 29F410 0058+00 0/0 1/1 0/0 .text __ct__18JAU_JASInitializerFv */ JAU_JASInitializer::JAU_JASInitializer() { diff --git a/src/JSystem/JAudio2/dsptask.cpp b/src/JSystem/JAudio2/dsptask.cpp index 2296db43e9..f428f86cff 100644 --- a/src/JSystem/JAudio2/dsptask.cpp +++ b/src/JSystem/JAudio2/dsptask.cpp @@ -5,6 +5,7 @@ #include "JSystem/JAudio2/dsptask.h" #include "JSystem/JAudio2/osdsp.h" +#include "global.h" // // Forward References: @@ -531,7 +532,7 @@ static u8 jdsp[7936] ALIGN_DECL(32) = { }; /* 80431F80-80431FE0 05ECA0 0050+10 1/1 0/0 0/0 .bss audio_task */ -static STRUCT_DSP_TASK audio_task ALIGN_DECL(32); +static DSPTaskInfo audio_task ALIGN_DECL(32); /* 80431FE0-80433FE0 05ED00 2000+00 1/1 0/0 0/0 .bss AUDIO_YIELD_BUFFER */ static u8 AUDIO_YIELD_BUFFER[8192] ALIGN_DECL(32); @@ -539,19 +540,19 @@ static u8 AUDIO_YIELD_BUFFER[8192] ALIGN_DECL(32); /* 8029E720-8029E7CC 299060 00AC+00 0/0 1/1 0/0 .text DspBoot__FPFPv_v */ void DspBoot(void (*param_0)(void*)) { DspInitWork(); - audio_task.info.priority = 0xf0; - audio_task.info.iram_mmem_addr = (u16*)(jdsp + 0x80000000); - audio_task.info.iram_length = sizeof(jdsp); - audio_task.info.iram_addr = 0; - audio_task.info.dram_mmem_addr = (u16*)(AUDIO_YIELD_BUFFER + 0x80000000); - audio_task.info.dram_length = sizeof(AUDIO_YIELD_BUFFER); - audio_task.info.dram_addr = 0; - audio_task.info.dsp_init_vector = 0; - audio_task.info.dsp_resume_vector = 0x10; - audio_task.info.init_cb = DspHandShake; - audio_task.info.res_cb = NULL; - audio_task.info.done_cb = NULL; - audio_task.info.req_cb = param_0; + audio_task.priority = 0xf0; + audio_task.iram_mmem_addr = (u16*)(jdsp + 0x80000000); + audio_task.iram_length = sizeof(jdsp); + audio_task.iram_addr = 0; + audio_task.dram_mmem_addr = (u16*)(AUDIO_YIELD_BUFFER + 0x80000000); + audio_task.dram_length = sizeof(AUDIO_YIELD_BUFFER); + audio_task.dram_addr = 0; + audio_task.dsp_init_vector = 0; + audio_task.dsp_resume_vector = 0x10; + audio_task.init_cb = DspHandShake; + audio_task.res_cb = NULL; + audio_task.done_cb = NULL; + audio_task.req_cb = param_0; DSPInit(); DSPAddPriorTask(&audio_task); } diff --git a/src/JSystem/JAudio2/osdsp.cpp b/src/JSystem/JAudio2/osdsp.cpp index d54bc32589..a54b77e034 100644 --- a/src/JSystem/JAudio2/osdsp.cpp +++ b/src/JSystem/JAudio2/osdsp.cpp @@ -6,7 +6,10 @@ #include "JSystem/JAudio2/osdsp.h" #include "JSystem/JAudio2/osdsp_task.h" #include "dolphin/os.h" -#include "dolphin/dsp/dsp_task.h" +#include + +extern "C" void __DSP_insert_task(DSPTaskInfo*); +extern "C" void __DSP_boot_task(DSPTaskInfo*); /* 8029EA00-8029EA84 299340 0084+00 0/0 1/1 0/0 .text DSPAddTask */ DSPTaskInfo* DSPAddTask(DSPTaskInfo* task) { @@ -32,8 +35,8 @@ void DSPAddPriorTask(STRUCT_DSP_TASK* task) { } BOOL status = OSDisableInterrupts(); DSP_prior_task = (DSPTaskInfo*)task; - task->info.state = 0; - task->info.flags = 1; + task->state = 0; + task->flags = 1; __DSP_boot_task((DSPTaskInfo*)task); OSRestoreInterrupts(status); -} \ No newline at end of file +} diff --git a/src/JSystem/JAudio2/osdsp_task.cpp b/src/JSystem/JAudio2/osdsp_task.cpp index 7d4cb65c6a..4f444c6f90 100644 --- a/src/JSystem/JAudio2/osdsp_task.cpp +++ b/src/JSystem/JAudio2/osdsp_task.cpp @@ -5,8 +5,13 @@ #include "JSystem/JAudio2/osdsp_task.h" #include "JSystem/JAudio2/dspproc.h" -#include "dolphin/dsp/dsp_task.h" -#include "dolphin/os/OSContext.h" +#include +#include + +extern DSPTaskInfo* __DSP_first_task; +extern DSPTaskInfo* __DSP_curr_task; +extern "C" void __DSP_exec_task(DSPTaskInfo*, DSPTaskInfo*); +extern "C" void __DSP_remove_task(DSPTaskInfo* task); static void Dsp_Update_Request(); @@ -20,7 +25,7 @@ static u8 struct_80451309; DSPTaskInfo* DSP_prior_task; /* 8029EB20-8029EE24 299460 0304+00 0/0 1/1 0/0 .text __DSPHandler */ -void __DSPHandler(__OSInterrupt interrupt, OSContext* context) { +extern "C" void __DSPHandler(__OSInterrupt interrupt, OSContext* context) { OSContext funcContext; __DSPRegs[5] = ((u16)(__DSPRegs[5]) & ~0x28) | 0x80; OSClearContext(&funcContext); diff --git a/src/JSystem/JFramework/JFWDisplay.cpp b/src/JSystem/JFramework/JFWDisplay.cpp index edf085d526..993ae047c2 100644 --- a/src/JSystem/JFramework/JFWDisplay.cpp +++ b/src/JSystem/JFramework/JFWDisplay.cpp @@ -5,6 +5,8 @@ #include "JSystem/JUtility/JUTDbPrint.h" #include "JSystem/JUtility/JUTProcBar.h" #include "dolphin/gx.h" +#include +#include "global.h" /* 80272040-802720F8 26C980 00B8+00 1/1 0/0 0/0 .text ctor_subroutine__10JFWDisplayFb */ void JFWDisplay::ctor_subroutine(bool enableAlpha) { @@ -616,4 +618,4 @@ static void diagnoseGpHang() { } else { OSReport("GP is in unknown state.\n"); } -} \ No newline at end of file +} diff --git a/src/JSystem/JFramework/JFWSystem.cpp b/src/JSystem/JFramework/JFWSystem.cpp index 283804f3ac..a7a599bcb0 100644 --- a/src/JSystem/JFramework/JFWSystem.cpp +++ b/src/JSystem/JFramework/JFWSystem.cpp @@ -123,7 +123,7 @@ void JFWSystem::init() { systemConsole = JUTConsole::create(60, 200, NULL); systemConsole->setFont(systemFont); - if (CSetUpParam::renderMode->efb_height < 300) { + if (CSetUpParam::renderMode->efbHeight < 300) { systemConsole->setFontSize(systemFont->getWidth() * 0.85f, systemFont->getHeight() * 0.5f); systemConsole->setPosition(20, 25); } else { diff --git a/src/JSystem/JKernel/JKRAram.cpp b/src/JSystem/JKernel/JKRAram.cpp index 36970e97ec..038a39d527 100644 --- a/src/JSystem/JKernel/JKRAram.cpp +++ b/src/JSystem/JKernel/JKRAram.cpp @@ -5,8 +5,8 @@ #include "JSystem/JKernel/JKRExpHeap.h" #include "JSystem/JUtility/JUTException.h" #include "dolphin/ar.h" -#include "dolphin/os/OSCache.h" -#include "dolphin/os/OSInterrupt.h" +#include +#include #include "string.h" static u8* firstSrcData(); diff --git a/src/JSystem/JKernel/JKRAramHeap.cpp b/src/JSystem/JKernel/JKRAramHeap.cpp index da28f2d45d..1592a4d5ad 100644 --- a/src/JSystem/JKernel/JKRAramHeap.cpp +++ b/src/JSystem/JKernel/JKRAramHeap.cpp @@ -1,6 +1,7 @@ #include "JSystem/JKernel/JKRAramHeap.h" #include "JSystem/JKernel/JKRHeap.h" #include "global.h" +#include /* 8043430C-80434318 06102C 000C+00 8/8 0/0 0/0 .bss sAramList__11JKRAramHeap */ JSUList JKRAramHeap::sAramList; @@ -47,7 +48,7 @@ JKRAramBlock* JKRAramHeap::alloc(u32 size, JKRAramHeap::EAllocMode allocationMod /* 802D3034-802D30BC 2CD974 0088+00 1/1 0/0 0/0 .text allocFromHead__11JKRAramHeapFUl */ JKRAramBlock* JKRAramHeap::allocFromHead(u32 size) { u32 alignedSize = ALIGN_NEXT(size, 0x20); - u32 bestFreeSize = UINT32_MAX; + u32 bestFreeSize = UINT_MAX; JKRAramBlock* bestBlock = NULL; JSUList* list = &sAramList; @@ -139,4 +140,4 @@ void JKRAramHeap::dump(void) { for (; iterator != list->getEnd(); ++iterator) {} unlock(); -} \ No newline at end of file +} diff --git a/src/JSystem/JKernel/JKRDecomp.cpp b/src/JSystem/JKernel/JKRDecomp.cpp index a28e3093c0..7386ac1b54 100644 --- a/src/JSystem/JKernel/JKRDecomp.cpp +++ b/src/JSystem/JKernel/JKRDecomp.cpp @@ -1,5 +1,6 @@ #include "JSystem/JKernel/JKRDecomp.h" #include "JSystem/JKernel/JKRAramPiece.h" +#include "global.h" /* ############################################################################################## */ /* 804514B0-804514B8 0009B0 0004+04 1/1 0/0 0/0 .sbss sDecompObject__9JKRDecomp */ @@ -299,4 +300,4 @@ JKRDecompCommand::JKRDecompCommand() { } /* 802DBDC0-802DBDFC 2D6700 003C+00 1/1 0/0 0/0 .text __dt__16JKRDecompCommandFv */ -JKRDecompCommand::~JKRDecompCommand() {} \ No newline at end of file +JKRDecompCommand::~JKRDecompCommand() {} diff --git a/src/JSystem/JKernel/JKRDvdAramRipper.cpp b/src/JSystem/JKernel/JKRDvdAramRipper.cpp index e62baa6714..f6cbd48da0 100644 --- a/src/JSystem/JKernel/JKRDvdAramRipper.cpp +++ b/src/JSystem/JKernel/JKRDvdAramRipper.cpp @@ -5,8 +5,8 @@ #include "JSystem/JKernel/JKRDecomp.h" #include "JSystem/JKernel/JKRDvdFile.h" #include "JSystem/JSupport/JSUFileStream.h" -#include "dolphin/os/OSCache.h" -#include "dolphin/os/OSInterrupt.h" +#include +#include #include "dolphin/vi.h" #include "global.h" #include "string.h" diff --git a/src/JSystem/JKernel/JKRDvdRipper.cpp b/src/JSystem/JKernel/JKRDvdRipper.cpp index b6fd4894ac..4ce620b1dd 100644 --- a/src/JSystem/JKernel/JKRDvdRipper.cpp +++ b/src/JSystem/JKernel/JKRDvdRipper.cpp @@ -7,8 +7,8 @@ #include "JSystem/JKernel/JKRDecomp.h" #include "JSystem/JUtility/JUTException.h" #include "string.h" -#include "dolphin/os/OSCache.h" -#include "dolphin/os/OSInterrupt.h" +#include +#include #include "dolphin/vi.h" static int JKRDecompressFromDVD(JKRDvdFile*, void*, u32, u32, u32, u32, u32*); @@ -560,4 +560,4 @@ static u8* nextSrcData(u8* src) { /* 802DA7D4-802DA7DC -00001 0008+00 0/0 0/0 0/0 .text isErrorRetry__12JKRDvdRipperFv */ u8 JKRDvdRipper::isErrorRetry() { return errorRetry; -} \ No newline at end of file +} diff --git a/src/JSystem/JKernel/JKRFileCache.cpp b/src/JSystem/JKernel/JKRFileCache.cpp index 9bbcf891d2..549f4c0335 100644 --- a/src/JSystem/JKernel/JKRFileCache.cpp +++ b/src/JSystem/JKernel/JKRFileCache.cpp @@ -272,8 +272,8 @@ u32 JKRFileCache::getResSize(const void* resource) const { /* 802D52A0-802D531C 2CFBE0 007C+00 1/0 0/0 0/0 .text countFile__12JKRFileCacheCFPCc */ u32 JKRFileCache::countFile(const char* path) const { - DVDDirectory dir; - DVDDirectoryEntry dirEntry; + DVDDir dir; + DVDDirEntry dirEntry; u32 count = 0; char* name = getDvdPathName(path); @@ -334,14 +334,14 @@ JKRFileCache::CCacheBlock* JKRFileCache::findCacheBlock(u32 fileID) const { /* 802D5410-802D551C 2CFD50 010C+00 2/2 0/0 0/0 .text findFile__12JKRFileCacheCFPcPCc */ bool JKRFileCache::findFile(char* path, const char* fileName) const { - DVDDirectory dir; - DVDDirectoryEntry dirEntry; + DVDDir dir; + DVDDirEntry dirEntry; bool result = false; u32 pathLength = strlen(path); if (DVDOpenDir(path, &dir)) { while (DVDReadDir(&dir, &dirEntry)) { - if (dirEntry.is_directory) { + if (dirEntry.isDir) { char* endOfPath = path + pathLength; *endOfPath = '/'; strcpy(path + pathLength + 1, dirEntry.name); @@ -428,4 +428,4 @@ u32 JKRFileCache::readFsResource(void* dst, u32 dstLength, const char* path) { */ u32 JKRFileCache::readNameResource(void* dst, u32 dstLength, u32 type, const char* path) { return readResource(dst, dstLength, type, path); -} \ No newline at end of file +} diff --git a/src/JSystem/JKernel/JKRFileFinder.cpp b/src/JSystem/JKernel/JKRFileFinder.cpp index 1d27455dc2..308eb81d87 100644 --- a/src/JSystem/JKernel/JKRFileFinder.cpp +++ b/src/JSystem/JKernel/JKRFileFinder.cpp @@ -47,13 +47,13 @@ JKRDvdFinder::~JKRDvdFinder() { /* 802D4874-802D4910 2CF1B4 009C+00 1/0 0/0 0/0 .text findNextFile__12JKRDvdFinderFv */ bool JKRDvdFinder::findNextFile(void) { if (mIsAvailable) { - DVDDirectoryEntry directoryEntry; + DVDDirEntry directoryEntry; mIsAvailable = DVDReadDir(&mDvdDirectory, &directoryEntry); if (mIsAvailable) { - mIsFileOrDirectory = directoryEntry.is_directory != 0; + mIsFileOrDirectory = directoryEntry.isDir != 0; mEntryName = directoryEntry.name; - mEntryFileIndex = directoryEntry.entry_number; + mEntryFileIndex = directoryEntry.entryNum; mEntryId = 0; // only matches with enum @@ -67,4 +67,4 @@ bool JKRDvdFinder::findNextFile(void) { } return mIsAvailable; -} \ No newline at end of file +} diff --git a/src/JSystem/JKernel/JKRHeap.cpp b/src/JSystem/JKernel/JKRHeap.cpp index 84430bc991..8d70d0403e 100644 --- a/src/JSystem/JKernel/JKRHeap.cpp +++ b/src/JSystem/JKernel/JKRHeap.cpp @@ -7,6 +7,8 @@ #include "JSystem/JUtility/JUTAssert.h" #include "JSystem/JUtility/JUTException.h" +bool data_804508B0 = 1; + /* 80451370-80451374 000870 0004+00 3/3 44/44 0/0 .sbss sSystemHeap__7JKRHeap */ JKRHeap* JKRHeap::sSystemHeap; @@ -104,13 +106,13 @@ bool JKRHeap::initArena(char** memory, u32* size, int maxHeaps) { ram_start = (void*)ALIGN_NEXT((u32)arenaStart, 0x20); ram_end = (void*)ALIGN_PREV((u32)arenaHi, 0x20); - GLOBAL_MEMORY* codeStart = (GLOBAL_MEMORY*)OSPhysicalToCached(0); + OSBootInfo* codeStart = (OSBootInfo*)OSPhysicalToCached(0); mCodeStart = codeStart; mCodeEnd = ram_start; mUserRamStart = ram_start; mUserRamEnd = ram_end; - mMemorySize = codeStart->memory_size; + mMemorySize = codeStart->memorySize; OSSetArenaLo(ram_end); OSSetArenaHi(ram_end); @@ -507,4 +509,4 @@ s32 JKRHeap::do_changeGroupID(u8 param_0) { /* 802CEDAC-802CEDB4 2C96EC 0008+00 1/0 1/0 0/0 .text do_getCurrentGroupId__7JKRHeapFv */ u8 JKRHeap::do_getCurrentGroupId() { return 0; -} \ No newline at end of file +} diff --git a/src/JSystem/JKernel/JKRSolidHeap.cpp b/src/JSystem/JKernel/JKRSolidHeap.cpp index d0fd7edd74..bd9eedd63a 100644 --- a/src/JSystem/JKernel/JKRSolidHeap.cpp +++ b/src/JSystem/JKernel/JKRSolidHeap.cpp @@ -1,6 +1,7 @@ #include "JSystem/JKernel/JKRSolidHeap.h" #include "JSystem/JUtility/JUTAssert.h" #include "JSystem/JUtility/JUTConsole.h" +#include "global.h" /* 802D0A24-802D0AD0 2CB364 00AC+00 0/0 4/4 1/1 .text create__12JKRSolidHeapFUlP7JKRHeapb */ @@ -294,4 +295,4 @@ void* JKRSolidHeap::do_getMaxFreeBlock(void) { /* 802D12A4-802D12C4 2CBBE4 0020+00 1/0 0/0 0/0 .text do_getTotalFreeSize__12JKRSolidHeapFv */ s32 JKRSolidHeap::do_getTotalFreeSize(void) { return getFreeSize(); -} \ No newline at end of file +} diff --git a/src/JSystem/JKernel/JKRThread.cpp b/src/JSystem/JKernel/JKRThread.cpp index 950c7043a3..03fc20b1da 100644 --- a/src/JSystem/JKernel/JKRThread.cpp +++ b/src/JSystem/JKernel/JKRThread.cpp @@ -3,6 +3,7 @@ #include "JSystem/JUtility/JUTConsole.h" #include "stdio.h" #include "dol2asm.h" +#include "global.h" /* 8043428C-80434298 060FAC 000C+00 5/6 0/0 0/0 .bss sThreadList__9JKRThread */ JSUList JKRThread::sThreadList(0); @@ -52,8 +53,8 @@ JKRThread::JKRThread(JKRHeap* heap, u32 stack_size, int message_count, int param JKRThread::JKRThread(OSThread* thread, int message_count) : mThreadListLink(this) { mHeap = NULL; mThreadRecord = thread; - mStackSize = (u32)thread->stack_end - (u32)thread->stack_base; - mStackMemory = thread->stack_base; + mStackSize = (u32)thread->stackEnd - (u32)thread->stackBase; + mStackMemory = thread->stackBase; setCommon_mesgQueue(JKRHeap::getSystemHeap(), message_count); } @@ -325,4 +326,4 @@ JSUList JKRTask::sTaskList; #pragma push #pragma force_active on u8 JKRTask::sEndMesgQueue[32]; -#pragma pop \ No newline at end of file +#pragma pop diff --git a/src/JSystem/JParticle/JPABaseShape.cpp b/src/JSystem/JParticle/JPABaseShape.cpp index 78353594d9..d869cd203b 100644 --- a/src/JSystem/JParticle/JPABaseShape.cpp +++ b/src/JSystem/JParticle/JPABaseShape.cpp @@ -1352,16 +1352,16 @@ GXBlendMode JPABaseShape::st_bm[3] = { /* 803C436C-803C4394 02148C 0028+00 0/1 0/0 0/0 .data st_bf__12JPABaseShape */ GXBlendFactor JPABaseShape::st_bf[10] = { - GX_BL_ZERO, GX_BL_ONE, GX_BL_SRC_COLOR, GX_BL_INV_SRC_COLOR, - GX_BL_SRC_COLOR, GX_BL_INV_SRC_COLOR, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, - GX_BL_DST_ALPHA, GX_BL_INV_DST_ALPHA, + GX_BL_ZERO, GX_BL_ONE, GX_BL_SRCCLR, GX_BL_INVSRCCLR, + GX_BL_SRCCLR, GX_BL_INVSRCCLR, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, + GX_BL_DSTALPHA, GX_BL_INVDSTALPHA, }; /* 803C4394-803C43D4 0214B4 0040+00 0/1 0/0 0/0 .data st_lo__12JPABaseShape */ GXLogicOp JPABaseShape::st_lo[16] = { - GX_LO_CLEAR, GX_LO_SET, GX_LO_COPY, GX_LO_INV_COPY, GX_LO_NOOP, GX_LO_INV, + GX_LO_CLEAR, GX_LO_SET, GX_LO_COPY, GX_LO_INVCOPY, GX_LO_NOOP, GX_LO_INV, GX_LO_AND, GX_LO_NAND, GX_LO_OR, GX_LO_NOR, GX_LO_XOR, GX_LO_EQUIV, - GX_LO_REV_AND, GX_LO_INV_AND, GX_LO_REV_OR, GX_LO_INV_OR, + GX_LO_REVAND, GX_LO_INVAND, GX_LO_REVOR, GX_LO_INVOR, }; /* 803C43D4-803C43F4 0214F4 0020+00 0/1 0/0 0/0 .data st_c__12JPABaseShape */ diff --git a/src/JSystem/JParticle/JPAResource.cpp b/src/JSystem/JParticle/JPAResource.cpp index 0528334005..01bba7d236 100644 --- a/src/JSystem/JParticle/JPAResource.cpp +++ b/src/JSystem/JParticle/JPAResource.cpp @@ -15,6 +15,7 @@ #include "JSystem/JParticle/JPAParticle.h" #include "JSystem/JParticle/JPAResourceManager.h" #include "dolphin/gx.h" +#include "global.h" /* 80274010-80274080 26E950 0070+00 0/0 1/1 0/0 .text __ct__11JPAResourceFv */ JPAResource::JPAResource() { @@ -957,8 +958,7 @@ void JPAResource::setPTev() { if (mpExTexShape->isUseIndirect()) { GXSetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD1, GX_TEXMAP2); GXSetIndTexCoordScale(GX_INDTEXSTAGE0, GX_ITS_1, GX_ITS_1); - GXSetIndTexMtx(GX_ITM_0, (f32*)mpExTexShape->getIndTexMtx(), - mpExTexShape->getExpScale()); + GXSetIndTexMtx(GX_ITM_0, (f32(*)[3])mpExTexShape->getIndTexMtx(), mpExTexShape->getExpScale()); GXSetTevIndirect(GX_TEVSTAGE0, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_STU, GX_ITM_0, GX_ITW_OFF, GX_ITW_OFF, 0, 0, GX_ITBA_OFF); ind_stages++; diff --git a/src/JSystem/JStudio/JStudio_JAudio2/object-sound.cpp b/src/JSystem/JStudio/JStudio_JAudio2/object-sound.cpp index aa3904b623..5e168ba44e 100644 --- a/src/JSystem/JStudio/JStudio_JAudio2/object-sound.cpp +++ b/src/JSystem/JStudio/JStudio_JAudio2/object-sound.cpp @@ -375,4 +375,4 @@ void JStudio_JAudio2::TAdaptor_sound::endSound_fadeOut_(u32 u32FadeTime) { JUT_ASSERT(654, (u32FadeTime>0)||!opJAISoundHandle_); field_0x120 = 0; } -} \ No newline at end of file +} diff --git a/src/JSystem/JUtility/JUTAssert.cpp b/src/JSystem/JUtility/JUTAssert.cpp index e6715ef1c4..14496082c2 100644 --- a/src/JSystem/JUtility/JUTAssert.cpp +++ b/src/JSystem/JUtility/JUTAssert.cpp @@ -8,6 +8,7 @@ #include "JSystem/JUtility/JUTDbPrint.h" #include "JSystem/JUtility/JUTDirectPrint.h" #include "stdio.h" +#include /* 804508F8-80450900 000378 0008+00 0/0 3/3 0/0 .sdata None */ bool sAssertVisible = true; diff --git a/src/JSystem/JUtility/JUTConsole.cpp b/src/JSystem/JUtility/JUTConsole.cpp index 27a941cc9b..e0f591f071 100644 --- a/src/JSystem/JUtility/JUTConsole.cpp +++ b/src/JSystem/JUtility/JUTConsole.cpp @@ -4,7 +4,9 @@ #include "JSystem/JUtility/JUTAssert.h" #include "JSystem/JUtility/JUTDirectPrint.h" #include "JSystem/JUtility/JUTVideo.h" +#include #include +#include "global.h" /* 80451570-80451574 000A70 0004+00 4/4 7/7 0/0 .sbss sManager__17JUTConsoleManager */ JUTConsoleManager* JUTConsoleManager::sManager; diff --git a/src/JSystem/JUtility/JUTDirectFile.cpp b/src/JSystem/JUtility/JUTDirectFile.cpp index d0d25b1eee..8b9c31e747 100644 --- a/src/JSystem/JUtility/JUTDirectFile.cpp +++ b/src/JSystem/JUtility/JUTDirectFile.cpp @@ -4,7 +4,7 @@ // #include "JSystem/JUtility/JUTDirectFile.h" -#include "dolphin/os/OSInterrupt.h" +#include #include "global.h" // @@ -34,7 +34,7 @@ int JUTDirectFile::fetch32byte() { return -1; } else { interrupts = OSEnableInterrupts(); - while (DVDGetCommandBlockStatus(&mFileInfo.block)) { + while (DVDGetCommandBlockStatus(&mFileInfo.cb)) { ; } OSRestoreInterrupts(interrupts); @@ -181,4 +181,4 @@ int JUTDirectFile::fgets(void* buf, int len) { } return readCount; -} \ No newline at end of file +} diff --git a/src/JSystem/JUtility/JUTDirectPrint.cpp b/src/JSystem/JUtility/JUTDirectPrint.cpp index f72447854e..a020ee2936 100644 --- a/src/JSystem/JUtility/JUTDirectPrint.cpp +++ b/src/JSystem/JUtility/JUTDirectPrint.cpp @@ -5,7 +5,8 @@ #include "JSystem/JUtility/JUTDirectPrint.h" #include "stdio.h" -#include "dolphin/os/OSCache.h" +#include +#include "global.h" // // Forward References: @@ -265,4 +266,4 @@ void JUTDirectPrint::setCharColor(u8 r, u8 g, u8 b) { mCharColor_Cr = Cr; mCharColor_Cr2 = (Cr >> 1) & 0x7fff; mCharColor_Cr4 = (Cr >> 2) & 0x3fff; -} \ No newline at end of file +} diff --git a/src/JSystem/JUtility/JUTException.cpp b/src/JSystem/JUtility/JUTException.cpp index e6ee2765d0..7ea4a54e22 100644 --- a/src/JSystem/JUtility/JUTException.cpp +++ b/src/JSystem/JUtility/JUTException.cpp @@ -43,20 +43,20 @@ const char* JUTException::sCpuExpName[17] = { JUTException* JUTException::sErrorManager; /* 8045150C-80451510 000A0C 0004+00 4/4 0/0 0/0 .sbss sPreUserCallback__12JUTException */ -OSErrorHandler JUTException::sPreUserCallback; +JUTExceptionUserCallback JUTException::sPreUserCallback; /* 80451510-80451514 000A10 0004+00 3/3 0/0 0/0 .sbss sPostUserCallback__12JUTException */ -OSErrorHandler JUTException::sPostUserCallback; + JUTExceptionUserCallback JUTException::sPostUserCallback; /* 802E1D5C-802E1E40 2DC69C 00E4+00 1/1 0/0 0/0 .text __ct__12JUTExceptionFP14JUTDirectPrint */ JUTException::JUTException(JUTDirectPrint* directPrint) : JKRThread(0x1C00, 0x10, 0), mDirectPrint(directPrint) { - OSSetErrorHandler(EXCEPTION_DSI, errorHandler); - OSSetErrorHandler(EXCEPTION_ISI, errorHandler); - OSSetErrorHandler(EXCEPTION_PROGRAM, errorHandler); - OSSetErrorHandler(EXCEPTION_ALIGNMENT, errorHandler); - OSSetErrorHandler(EXCEPTION_MEMORY_PROTECTION, errorHandler); + OSSetErrorHandler(__OS_EXCEPTION_DSI, (OSErrorHandler)errorHandler); + OSSetErrorHandler(__OS_EXCEPTION_ISI, (OSErrorHandler)errorHandler); + OSSetErrorHandler(__OS_EXCEPTION_PROGRAM, (OSErrorHandler)errorHandler); + OSSetErrorHandler(__OS_EXCEPTION_ALIGNMENT, (OSErrorHandler)errorHandler); + OSSetErrorHandler(__OS_EXCEPTION_MEMORY_PROTECTION, (OSErrorHandler)errorHandler); setFPException(0); sPreUserCallback = NULL; @@ -87,7 +87,7 @@ JUTException* JUTException::create(JUTDirectPrint* directPrint) { OSMessage JUTException::sMessageBuffer[1] = {0}; struct CallbackObject { - /* 0x00 */ OSErrorHandler callback; + /* 0x00 */ JUTExceptionUserCallback callback; /* 0x04 */ u16 error; /* 0x06 */ u16 pad_0x06; /* 0x08 */ OSContext* context; @@ -106,7 +106,7 @@ void* JUTException::run() { VISetPreRetraceCallback(NULL); VISetPostRetraceCallback(NULL); CallbackObject* cb = (CallbackObject*)message; - OSErrorHandler callback = cb->callback; + JUTExceptionUserCallback callback = cb->callback; u16 error = cb->error; OSContext* context = cb->context; int r24 = cb->param_3; @@ -156,7 +156,7 @@ void JUTException::errorHandler(OSError error, OSContext* context, u32 param_3, fpscr = context->fpscr; OSFillFPUContext(context); OSSetErrorHandler(error, NULL); - if (error == OS_ERROR_MEMORY_PROTECTION) { + if (error == __OS_EXCEPTION_MEMORY_PROTECTION) { OSProtectRange(0, NULL, 0, 3); OSProtectRange(1, NULL, 0, 3); OSProtectRange(2, NULL, 0, 3); @@ -226,9 +226,9 @@ void JUTException::panic_f(char const* file, int line, char const* format, ...) void JUTException::setFPException(u32 fpscr_enable_bits) { __OSFpscrEnableBits = fpscr_enable_bits; if (fpscr_enable_bits) { - OSSetErrorHandler(EXCEPTION_FLOATING_POINT_EXCEPTION, errorHandler); + OSSetErrorHandler(__OS_EXCEPTION_FLOATING_POINT_EXCEPTION, (OSErrorHandler)errorHandler); } else { - OSSetErrorHandler(EXCEPTION_FLOATING_POINT_EXCEPTION, NULL); + OSSetErrorHandler(__OS_EXCEPTION_FLOATING_POINT_EXCEPTION, NULL); } } @@ -362,13 +362,13 @@ void JUTException::showMainInfo(u16 error, OSContext* context, u32 dsisr, u32 da return; } - if (error < (OS_ERROR_MACHINE_CHECK | OS_ERROR_FLOATING_POINT_EXCEPTION)) { + if (error < (OS_ERROR_MACHINE_CHECK | __OS_EXCEPTION_FLOATING_POINT_EXCEPTION)) { sConsole->print_f("CONTEXT:%08XH (%s EXCEPTION)\n", context, sCpuExpName[error]); } else { sConsole->print_f("CONTEXT:%08XH\n", context); } - if (error == OS_ERROR_FLOATING_POINT_EXCEPTION) { + if (error == __OS_EXCEPTION_FLOATING_POINT_EXCEPTION) { u32 flags = fpscr & (((fpscr & 0xf8) << 0x16) | 0x1f80700); if ((flags & 0x20000000) != 0) { sConsole->print_f(" FPE: Invalid operation\n"); @@ -659,7 +659,7 @@ void JUTException::printContext(OSError error, OSContext* context, u32 dsisr, u3 return; } - if (error < (OS_ERROR_MACHINE_CHECK | OS_ERROR_FLOATING_POINT_EXCEPTION)) { + if (error < (OS_ERROR_MACHINE_CHECK | __OS_EXCEPTION_FLOATING_POINT_EXCEPTION)) { sConsole->print_f("******** EXCEPTION OCCURRED! ********\nFrameMemory:%XH\n", getFrameMemory()); } else { @@ -821,8 +821,8 @@ void JUTException::waitTime(s32 timeout_ms) { void JUTException::createFB() { _GXRenderModeObj* renderMode = &GXNtsc480Int; void* end = (void*)OSGetArenaHi(); - u16 width = ALIGN_NEXT(renderMode->fb_width, 16); - u16 height = renderMode->xfb_height; + u16 width = ALIGN_NEXT(renderMode->fbWidth, 16); + u16 height = renderMode->xfbHeight; u32 pixel_count = width * height; u32 size = pixel_count * 2; @@ -830,7 +830,7 @@ void JUTException::createFB() { void* object = (void*)ALIGN_PREV((s32)begin - sizeof(JUTExternalFB), 32); new (object) JUTExternalFB(renderMode, GX_GM_1_7, begin, size); - mDirectPrint->changeFrameBuffer(begin, renderMode->fb_width, renderMode->efb_height); + mDirectPrint->changeFrameBuffer(begin, renderMode->fbWidth, renderMode->efbHeight); VIConfigure(renderMode); VISetNextFrameBuffer(begin); VISetBlack(FALSE); @@ -848,16 +848,16 @@ void JUTException::createFB() { /* 802E3AEC-802E3AFC 2DE42C 0010+00 0/0 1/1 0/0 .text * setPreUserCallback__12JUTExceptionFPFUsP9OSContextUlUl_v */ -OSErrorHandler JUTException::setPreUserCallback(OSErrorHandler callback) { - OSErrorHandler previous = sPreUserCallback; + JUTExceptionUserCallback JUTException::setPreUserCallback(JUTExceptionUserCallback callback) { + JUTExceptionUserCallback previous = sPreUserCallback; sPreUserCallback = callback; return previous; } /* 802E3AFC-802E3B0C 2DE43C 0010+00 0/0 1/1 0/0 .text * setPostUserCallback__12JUTExceptionFPFUsP9OSContextUlUl_v */ -OSErrorHandler JUTException::setPostUserCallback(OSErrorHandler callback) { - OSErrorHandler previous = sPostUserCallback; + JUTExceptionUserCallback JUTException::setPostUserCallback(JUTExceptionUserCallback callback) { + JUTExceptionUserCallback previous = sPostUserCallback; sPostUserCallback = callback; return previous; } diff --git a/src/JSystem/JUtility/JUTFontData_Ascfont_fix12.cpp b/src/JSystem/JUtility/JUTFontData_Ascfont_fix12.cpp index ad5010c3fa..58b6db2dd0 100644 --- a/src/JSystem/JUtility/JUTFontData_Ascfont_fix12.cpp +++ b/src/JSystem/JUtility/JUTFontData_Ascfont_fix12.cpp @@ -1,4 +1,5 @@ #include +#include "global.h" /* 8039DA20-803A1B80 02A080 4160+00 0/0 1/0 0/0 .rodata JUTResFONT_Ascfont_fix12 */ extern u8 const JUTResFONT_Ascfont_fix12[16736] ALIGN_DECL(32) = { diff --git a/src/JSystem/JUtility/JUTGamePad.cpp b/src/JSystem/JUtility/JUTGamePad.cpp index 29f51daeb2..3b54383f1a 100644 --- a/src/JSystem/JUtility/JUTGamePad.cpp +++ b/src/JSystem/JUtility/JUTGamePad.cpp @@ -113,13 +113,13 @@ u32 JUTGamePad::read() { for (int i = 0; i < 4; i++) { bittest = PAD_CHAN0_BIT >> i; - if (mPadStatus[i].error == 0) { + if (mPadStatus[i].err == 0) { u32 stick_status; - stick_status = mPadMStick[i].update(mPadStatus[i].stick_x, mPadStatus[i].stick_y, sStickMode, EMainStick, mPadButton[i].mButton) << 0x18; - stick_status |= (mPadSStick[i].update(mPadStatus[i].substick_x, mPadStatus[i].substick_y, sStickMode, ESubStick, mPadButton[i].mButton) << 0x10); + stick_status = mPadMStick[i].update(mPadStatus[i].stickX, mPadStatus[i].stickY, sStickMode, EMainStick, mPadButton[i].mButton) << 0x18; + stick_status |= (mPadSStick[i].update(mPadStatus[i].substickX, mPadStatus[i].substickY, sStickMode, ESubStick, mPadButton[i].mButton) << 0x10); mPadButton[i].update(&mPadStatus[i], stick_status); - } else if (mPadStatus[i].error == -1) { + } else if (mPadStatus[i].err == -1) { mPadMStick[i].update(0, 0, sStickMode, EMainStick, 0); mPadSStick[i].update(0, 0, sStickMode, ESubStick, 0); mPadButton[i].update(NULL, 0); @@ -140,9 +140,9 @@ u32 JUTGamePad::read() { pad->getPadReplay()->getStatus(&status); u32 stick_status; - stick_status = pad->mMainStick.update(status.stick_x, status.stick_y, sStickMode, + stick_status = pad->mMainStick.update(status.stickX, status.stickY, sStickMode, EMainStick, pad->mButton.mButton) << 0x18; - stick_status |= pad->mSubStick.update(status.substick_x, status.substick_y, sStickMode, + stick_status |= pad->mSubStick.update(status.substickX, status.substickY, sStickMode, ESubStick, pad->mButton.mButton) << 0x10; pad->mButton.update(&status, stick_status); @@ -155,7 +155,7 @@ u32 JUTGamePad::read() { if (pad->getPadRecord() != NULL && pad->getPadRecord()->isActive()) { int port = pad->mPortNum; - if (port >= 0 && mPadStatus[port].error == 0) { + if (port >= 0 && mPadStatus[port].err == 0) { pad->getPadRecord()->write(&mPadStatus[port]); } } @@ -172,7 +172,7 @@ u32 JUTGamePad::read() { /* 802E0BBC-802E0C6C 2DB4FC 00B0+00 1/1 0/0 0/0 .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.mRepeatMask, mButton.mRepeatDelay, mButton.mRepeatRate); @@ -243,7 +243,7 @@ void JUTGamePad::update() { mButton = mPadButton[mPortNum]; mMainStick = mPadMStick[mPortNum]; mSubStick = mPadSStick[mPortNum]; - mErrorStatus = mPadStatus[mPortNum].error; + mErrorStatus = mPadStatus[mPortNum].err; } if (field_0xa8 == 0 || C3ButtonReset::sResetPattern != (mButton.mButton & C3ButtonReset::sResetMaskPattern)) { @@ -369,10 +369,10 @@ void JUTGamePad::CButton::update(const PADStatus* padStatus, u32 stickStatus) { mRepeat |= (mRepeatMask ^ 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; diff --git a/src/JSystem/JUtility/JUTProcBar.cpp b/src/JSystem/JUtility/JUTProcBar.cpp index cbb9928f50..a276be2321 100644 --- a/src/JSystem/JUtility/JUTProcBar.cpp +++ b/src/JSystem/JUtility/JUTProcBar.cpp @@ -124,7 +124,7 @@ void JUTProcBar::draw() { void JUTProcBar::drawProcessBar() { if (mVisible) { int frameDuration = 16666; // duration in miliseconds? for how long a frame takes, - if (JUTVideo::getManager() && ((JUTVideo::getManager()->getRenderMode()->vi_tv_mode >> 2) & + if (JUTVideo::getManager() && ((JUTVideo::getManager()->getRenderMode()->viTVmode >> 2) & 0x0f) == 1) // possibly a define frameDuration = 20000; // duration for PAL @@ -324,4 +324,4 @@ void JUTProcBar::drawHeapBar() { } } } -} \ No newline at end of file +} diff --git a/src/JSystem/JUtility/JUTResFont.cpp b/src/JSystem/JUtility/JUTResFont.cpp index 2d1f2b8ea3..53c31786c6 100644 --- a/src/JSystem/JUtility/JUTResFont.cpp +++ b/src/JSystem/JUtility/JUTResFont.cpp @@ -187,7 +187,7 @@ void JUTResFont::setGX() { GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); GXSetTevOp(GX_TEVSTAGE0, GX_MODULATE); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_RGBA4, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGBX8, 15); @@ -220,7 +220,7 @@ void JUTResFont::setGX(JUtility::TColor col1, JUtility::TColor col2) { GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_APREV, GX_CA_RASA, GX_CA_ZERO); GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_RGBA4, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGBX8, 15); diff --git a/src/JSystem/JUtility/JUTVideo.cpp b/src/JSystem/JUtility/JUTVideo.cpp index 46efb17a3b..ee73bc1aa8 100644 --- a/src/JSystem/JUtility/JUTVideo.cpp +++ b/src/JSystem/JUtility/JUTVideo.cpp @@ -7,6 +7,7 @@ #include "JSystem/JUtility/JUTDirectPrint.h" #include "JSystem/JUtility/JUTXfb.h" #include "dolphin/gx.h" +#include /* 80451538-8045153C 000A38 0004+00 4/4 18/18 1/1 .sbss sManager__8JUTVideo */ JUTVideo* JUTVideo::sManager; @@ -93,7 +94,7 @@ void JUTVideo::preRetraceProc(u32 retrace_count) { JUTVideo* videoManager = JUTGetVideoManager(); const GXRenderModeObj* renderMode = videoManager->getRenderMode(); JUTDirectPrint* directPrint = JUTDirectPrint::getManager(); - directPrint->changeFrameBuffer(frameBuffer, renderMode->fb_width, renderMode->efb_height); + directPrint->changeFrameBuffer(frameBuffer, renderMode->fbWidth, renderMode->efbHeight); } if (sManager->mSetBlack == 1) { @@ -198,7 +199,7 @@ void JUTVideo::postRetraceProc(u32 retrace_count) { /* 802E5198-802E5210 2DFAD8 0078+00 1/1 2/2 0/0 .text * setRenderMode__8JUTVideoFPC16_GXRenderModeObj */ void JUTVideo::setRenderMode(GXRenderModeObj const* pObj) { - if (mRenderObj != NULL && pObj->vi_tv_mode != mRenderObj->vi_tv_mode) { + if (mRenderObj != NULL && pObj->viTVmode != mRenderObj->viTVmode) { mSetBlack = true; mSetBlackFrameCount = 4; } @@ -213,4 +214,4 @@ void JUTVideo::setRenderMode(GXRenderModeObj const* pObj) { } /* 802E5210-802E5214 2DFB50 0004+00 0/0 1/1 0/0 .text waitRetraceIfNeed__8JUTVideoFv */ -void JUTVideo::waitRetraceIfNeed() {} \ No newline at end of file +void JUTVideo::waitRetraceIfNeed() {} diff --git a/src/JSystem/JUtility/JUTXfb.cpp b/src/JSystem/JUtility/JUTXfb.cpp index 0c0c9a0032..5c33d386e4 100644 --- a/src/JSystem/JUtility/JUTXfb.cpp +++ b/src/JSystem/JUtility/JUTXfb.cpp @@ -59,15 +59,15 @@ JUTXfb::JUTXfb(GXRenderModeObj const* pObj, JKRHeap* pHeap, JUTXfb::EXfbNumber x common_init(xfbNum); if (pObj) { - initiate(pObj->fb_width, pObj->xfb_height, pHeap, xfbNum); + initiate(pObj->fbWidth, pObj->xfbHeight, pHeap, xfbNum); } else { - u16 fb_width = JUTVideo::getManager()->getRenderMode()->fb_width; - u16 efb_height = (u32)JUTVideo::getManager()->getRenderMode()->efb_height; - u16 xfb_height = JUTVideo::getManager()->getRenderMode()->xfb_height; - f32 scale_factor = GXGetYScaleFactor(efb_height, xfb_height); - u16 xfb_lines = GXGetNumXfbLines(efb_height, scale_factor); + u16 fbWidth = JUTVideo::getManager()->getRenderMode()->fbWidth; + u16 efbHeight = (u32)JUTVideo::getManager()->getRenderMode()->efbHeight; + u16 xfb_height = JUTVideo::getManager()->getRenderMode()->xfbHeight; + f32 scale_factor = GXGetYScaleFactor(efbHeight, xfb_height); + u16 xfb_lines = GXGetNumXfbLines(efbHeight, scale_factor); - initiate(fb_width, xfb_lines, pHeap, xfbNum); + initiate(fbWidth, xfb_lines, pHeap, xfbNum); } } diff --git a/src/PowerPC_EABI_Support/Runtime/Src/GCN_Mem_Alloc.c b/src/PowerPC_EABI_Support/Runtime/Src/GCN_Mem_Alloc.c index 269cbef919..6272b322a5 100644 --- a/src/PowerPC_EABI_Support/Runtime/Src/GCN_Mem_Alloc.c +++ b/src/PowerPC_EABI_Support/Runtime/Src/GCN_Mem_Alloc.c @@ -18,8 +18,8 @@ inline static void InitDefaultHeap(void) { arenaLo = OSInitAlloc(arenaLo, arenaHi, 1); OSSetArenaLo(arenaLo); - arenaLo = OSRoundUpPtr(arenaLo, 0x20); - arenaHi = OSRoundDownPtr(arenaHi, 0x20); + arenaLo = (void*)OSRoundUp32B(arenaLo); + arenaHi = (void*)OSRoundDown32B(arenaHi); OSSetCurrentHeap(OSCreateHeap(arenaLo, arenaHi)); OSSetArenaLo(arenaLo = arenaHi); @@ -32,4 +32,4 @@ void __sys_free(void* p) { } OSFreeToHeap(__OSCurrHeap, p); -} \ No newline at end of file +} diff --git a/src/SSystem/SComponent/c_bg_s_chk.cpp b/src/SSystem/SComponent/c_bg_s_chk.cpp index 5cded467cc..1a301597a1 100644 --- a/src/SSystem/SComponent/c_bg_s_chk.cpp +++ b/src/SSystem/SComponent/c_bg_s_chk.cpp @@ -4,6 +4,7 @@ */ #include "SSystem/SComponent/c_bg_s_chk.h" +#include "f_pc/f_pc_manager.h" /* 80267B4C-80267B70 26248C 0024+00 0/0 7/7 0/0 .text __ct__8cBgS_ChkFv */ cBgS_Chk::cBgS_Chk() { @@ -24,10 +25,10 @@ void cBgS_Chk::SetExtChk(cBgS_Chk& other) { } /* 80267BDC-80267C1C 26251C 0040+00 0/0 7/7 0/0 .text ChkSameActorPid__8cBgS_ChkCFUi */ -bool cBgS_Chk::ChkSameActorPid(unsigned int pid) const { - if (mActorPid == -1 || pid == UINT32_MAX || !mSameActorChk) { +bool cBgS_Chk::ChkSameActorPid(fpc_ProcID pid) const { + if (mActorPid == fpcM_ERROR_PROCESS_ID_e || pid == fpcM_ERROR_PROCESS_ID_e || !mSameActorChk) { return FALSE; } else { return (mActorPid == pid) ? TRUE : FALSE; } -} \ No newline at end of file +} diff --git a/src/SSystem/SComponent/c_bg_s_gnd_chk.cpp b/src/SSystem/SComponent/c_bg_s_gnd_chk.cpp index b92e1a03a0..e752288821 100644 --- a/src/SSystem/SComponent/c_bg_s_gnd_chk.cpp +++ b/src/SSystem/SComponent/c_bg_s_gnd_chk.cpp @@ -4,11 +4,12 @@ */ #include "SSystem/SComponent/c_bg_s_gnd_chk.h" +#include "f_pc/f_pc_manager.h" /* 80267C1C-80267C94 26255C 0078+00 0/0 2/2 123/123 .text __ct__11cBgS_GndChkFv */ cBgS_GndChk::cBgS_GndChk() { m_pos = cXyz::Zero; - SetActorPid(UINT32_MAX); + SetActorPid(fpcM_ERROR_PROCESS_ID_e); mFlags = 2; } @@ -29,4 +30,4 @@ void cBgS_GndChk::SetPos(cXyz const* pos) { /* 80267D44-80267D54 262684 0010+00 0/0 1/1 0/0 .text PreCheck__11cBgS_GndChkFv */ void cBgS_GndChk::PreCheck() { mWallPrecheck = mFlags & 2; -} \ No newline at end of file +} diff --git a/src/SSystem/SComponent/c_bg_s_lin_chk.cpp b/src/SSystem/SComponent/c_bg_s_lin_chk.cpp index a17e202f2c..0e6a5d8892 100644 --- a/src/SSystem/SComponent/c_bg_s_lin_chk.cpp +++ b/src/SSystem/SComponent/c_bg_s_lin_chk.cpp @@ -4,6 +4,7 @@ */ #include "SSystem/SComponent/c_bg_s_lin_chk.h" +#include "f_pc/f_pc_manager.h" /* 80267D5C-80267DBC 26269C 0060+00 0/0 2/2 0/0 .text __ct__11cBgS_LinChkFv */ cBgS_LinChk::cBgS_LinChk() { @@ -19,7 +20,7 @@ void cBgS_LinChk::ct() { mLin.SetStartEnd(start_end, start_end); field_0x40 = start_end; - SetActorPid(UINT32_MAX); + SetActorPid(fpcM_ERROR_PROCESS_ID_e); mStts = 0; mFrontFlag = 1; mBackFlag = 0; diff --git a/src/TRK_MINNOW_DOLPHIN/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c b/src/TRK_MINNOW_DOLPHIN/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c index c71f318567..183457c640 100644 --- a/src/TRK_MINNOW_DOLPHIN/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c +++ b/src/TRK_MINNOW_DOLPHIN/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c @@ -2,7 +2,9 @@ #include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/main_TRK.h" #include "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk_glue.h" #include "TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.h" -#include "dolphin/ar.h" +#include +#include "global.h" +#include "__ar.h" #define EXCEPTIONMASK_ADDR 0x80000044 @@ -330,4 +332,4 @@ initCommTableSuccess: b TRK_main //Jump to TRK_main blr // clang-format on -} \ No newline at end of file +} diff --git a/src/TRK_MINNOW_DOLPHIN/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c b/src/TRK_MINNOW_DOLPHIN/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c index 5f3461d639..2b7e769dc8 100644 --- a/src/TRK_MINNOW_DOLPHIN/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c +++ b/src/TRK_MINNOW_DOLPHIN/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c @@ -48,7 +48,7 @@ int InitMetroTRKCommTable(int hwId) { OSReport("MetroTRK : Set to GDEV hardware\n"); // Initialize gDBCommTable result = Hu_IsStub(); - gDBCommTable.initialize_func = gdev_cc_initialize; + 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; @@ -63,7 +63,7 @@ int InitMetroTRKCommTable(int hwId) { OSReport("MetroTRK : Set to AMC DDH hardware\n"); result = AMC_IsStub(); // Initialize gDBCommTable - gDBCommTable.initialize_func = ddh_cc_initialize; + 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; @@ -186,4 +186,4 @@ lbl_80371C20: lwz r31, OSContext.gpr[31](r31) b TRKInterruptHandler // clang-format on -} \ No newline at end of file +} diff --git a/src/TRK_MINNOW_DOLPHIN/gamedev/cust_connection/cc/exi2/GCN/EXI2_DDH_GCN/main.c b/src/TRK_MINNOW_DOLPHIN/gamedev/cust_connection/cc/exi2/GCN/EXI2_DDH_GCN/main.c index 013dfeda21..ee439979ca 100644 --- a/src/TRK_MINNOW_DOLPHIN/gamedev/cust_connection/cc/exi2/GCN/EXI2_DDH_GCN/main.c +++ b/src/TRK_MINNOW_DOLPHIN/gamedev/cust_connection/cc/exi2/GCN/EXI2_DDH_GCN/main.c @@ -1,6 +1,6 @@ #include "TRK_MINNOW_DOLPHIN/utils/common/CircleBuffer.h" #include "TRK_MINNOW_DOLPHIN/utils/common/MWTrace.h" -#include "amcstubs/AmcExi2Stubs.h" +#include #define DDH_ERR_NOT_INITIALIZED -0x2711 #define DDH_ERR_ALREADY_INITIALIZED -0x2715 @@ -18,7 +18,7 @@ static u8 gRecvBuf[DDH_BUF_SIZE]; static BOOL gIsInitialized; /* 80372618-803726A0 36CF58 0088+00 0/0 1/1 0/0 .text ddh_cc_initialize */ -int ddh_cc_initialize(void* inputPendingPtrRef, AmcEXICallback monitorCallback) { +int ddh_cc_initialize(void* inputPendingPtrRef, EXICallback monitorCallback) { MWTRACE(1, "CALLING EXI2_Init\n"); EXI2_Init(inputPendingPtrRef, monitorCallback); MWTRACE(1, "DONE CALLING EXI2_Init\n"); @@ -147,4 +147,4 @@ int ddh_cc_peek() { int ddh_cc_initinterrupts() { EXI2_EnableInterrupts(); return 0; -} \ No newline at end of file +} diff --git a/src/TRK_MINNOW_DOLPHIN/gamedev/cust_connection/cc/exi2/GCN/EXI2_GDEV_GCN/main.c b/src/TRK_MINNOW_DOLPHIN/gamedev/cust_connection/cc/exi2/GCN/EXI2_GDEV_GCN/main.c index b7fb418438..10a3706b47 100644 --- a/src/TRK_MINNOW_DOLPHIN/gamedev/cust_connection/cc/exi2/GCN/EXI2_GDEV_GCN/main.c +++ b/src/TRK_MINNOW_DOLPHIN/gamedev/cust_connection/cc/exi2/GCN/EXI2_GDEV_GCN/main.c @@ -1,6 +1,7 @@ #include "TRK_MINNOW_DOLPHIN/utils/common/CircleBuffer.h" #include "TRK_MINNOW_DOLPHIN/utils/common/MWTrace.h" -#include "dolphin/db.h" +#include +#include #define GDEV_BUF_SIZE (0x500) @@ -14,9 +15,9 @@ static u8 gRecvBuf[GDEV_BUF_SIZE]; static BOOL gIsInitialized; /* 80372BCC-80372C54 36D50C 0088+00 0/0 1/1 0/0 .text gdev_cc_initialize */ -int gdev_cc_initialize(void* inputPendingPtrRef, AmcEXICallback monitorCallback) { +int gdev_cc_initialize(void* inputPendingPtrRef, EXICallback monitorCallback) { MWTRACE(1, "CALLING EXI2_Init\n"); - DBInitComm(inputPendingPtrRef, monitorCallback); + DBInitComm(inputPendingPtrRef, (int*)monitorCallback); MWTRACE(1, "DONE CALLING EXI2_Init\n"); CircleBufferInitialize(&gRecvCB, gRecvBuf, GDEV_BUF_SIZE); return 0; @@ -129,7 +130,7 @@ int gdev_cc_peek() { return 0; } - if (DBRead(buff, poll) == 0) { + if ((int)DBRead(buff, poll) == 0) { CircleBufferWriteBytes(&gRecvCB, buff, poll); } else { return -0x2719; @@ -142,4 +143,4 @@ int gdev_cc_peek() { int gdev_cc_initinterrupts() { DBInitInterrupts(); return 0; -} \ No newline at end of file +} diff --git a/src/amcstubs/AmcExi2Stubs.c b/src/amcstubs/AmcExi2Stubs.c index a574865ea9..0053d2e54a 100644 --- a/src/amcstubs/AmcExi2Stubs.c +++ b/src/amcstubs/AmcExi2Stubs.c @@ -3,10 +3,10 @@ * Description: */ -#include "amcstubs/AmcExi2Stubs.h" +#include /* 80372CFC-80372D00 36D63C 0004+00 0/0 1/1 0/0 .text EXI2_Init */ -void EXI2_Init(vu8**, AmcEXICallback) {} +void EXI2_Init(vu8**, EXICallback) {} /* 80372D00-80372D04 36D640 0004+00 0/0 1/1 0/0 .text EXI2_EnableInterrupts */ void EXI2_EnableInterrupts(void) {} @@ -35,4 +35,4 @@ void EXI2_Unreserve(void) {} /* 80372D24-80372D2C 36D664 0008+00 0/0 1/1 0/0 .text AMC_IsStub */ BOOL AMC_IsStub(void) { return TRUE; -} \ No newline at end of file +} diff --git a/src/d/actor/d_a_alink.cpp b/src/d/actor/d_a_alink.cpp index 58e15e5eab..6137d8635f 100644 --- a/src/d/actor/d_a_alink.cpp +++ b/src/d/actor/d_a_alink.cpp @@ -451,7 +451,7 @@ int daAlink_c::jointControll(int param_0) { mDoMtx_stack_c::inverse(); cMtx_concat(temp_r26, mDoMtx_stack_c::get(), J3DSys::mCurrentMtx); - MTXQuat(temp_r26, (PSQuaternion*)spC); + MTXQuat(temp_r26, spC); temp_r26[0][3] = var_r25->mTranslate.x; temp_r26[1][3] = var_r25->mTranslate.y; @@ -478,7 +478,7 @@ void daAlink_c::setUpperFront() { Quaternion sp8; JMAEulerToQuat(sp18.mRotation.x, sp18.mRotation.y, sp18.mRotation.z, &sp8); - MTXQuat(temp_r28, (PSQuaternion*)&sp8); + MTXQuat(temp_r28, &sp8); cMtx_concat(mpLinkModel->getBaseTRMtx(), temp_r28, J3DSys::mCurrentMtx); J3DSys::mCurrentMtx[0][3] = mRootMtx[0][3]; diff --git a/src/d/actor/d_a_alink_effect.inc b/src/d/actor/d_a_alink_effect.inc index 777e630c42..15397660e9 100644 --- a/src/d/actor/d_a_alink_effect.inc +++ b/src/d/actor/d_a_alink_effect.inc @@ -1857,7 +1857,7 @@ void daAlink_blur_c::draw() { GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); GXLoadPosMtxImm(j3dSys.getViewMtx(), GX_PNMTX0); GXSetCurrentMtx(0); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GXSetCullMode(GX_CULL_NONE); GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_DISABLE); GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); diff --git a/src/d/actor/d_a_b_bh.cpp b/src/d/actor/d_a_b_bh.cpp index c47936692e..eded62267b 100644 --- a/src/d/actor/d_a_b_bh.cpp +++ b/src/d/actor/d_a_b_bh.cpp @@ -4,288 +4,1597 @@ */ #include "d/actor/d_a_b_bh.h" -#include "d/d_cc_d.h" -#include "dol2asm.h" +#include "d/actor/d_a_b_bq.h" +#include "d/d_bomb.h" +#include "d/d_com_inf_game.h" +#include "d/d_s_play.h" +#include "c/c_damagereaction.h" +#include "m_Do/m_Do_controller_pad.h" +#include "Z2AudioLib/Z2Instances.h" +#define ACTION_WAIT 0 +#define ACTION_ATTACK_1 5 +#define ACTION_BOMB_EAT 10 +#define ACTION_DOWN 11 +#define ACTION_B_WAIT 20 +#define ACTION_B_ATTACK_1 21 +#define ACTION_B_BOMB_EAT 22 +#define ACTION_B_DOWN 23 +#define ACTION_START 50 -// -// Forward References: -// +#define ANM_ATTACK 5 +#define ANM_ATTACK_WAIT 6 +#define ANM_DAMAGE 7 +#define ANM_EAT 8 +#define ANM_EAT_WAIT 9 +#define ANM_NO_DAMAGE 10 +#define ANM_ROUT 11 +#define ANM_WAIT 12 +#define ANM_WAIT01 13 +#define ANM_WAIT02 14 -extern "C" void __ct__12daB_BH_HIO_cFv(); -extern "C" static void anm_init__FP10b_bh_classifUcf(); -extern "C" static void daB_BH_Draw__FP10b_bh_class(); -extern "C" static void b_bh_wait__FP10b_bh_class(); -extern "C" void __dt__4cXyzFv(); -extern "C" static void b_bh_attack_1__FP10b_bh_class(); -extern "C" static void b_bh_bombeat__FP10b_bh_class(); -extern "C" static void b_bh_down__FP10b_bh_class(); -extern "C" static void b_bh_b_wait__FP10b_bh_class(); -extern "C" static void b_bh_b_attack_1__FP10b_bh_class(); -extern "C" static void b_bh_b_bombeat__FP10b_bh_class(); -extern "C" static void b_bh_b_down__FP10b_bh_class(); -extern "C" static void b_bh_start__FP10b_bh_class(); -extern "C" static void kuki_control1__FP10b_bh_class(); -extern "C" static void kuki_control2__FP10b_bh_class(); -extern "C" static void kuki_control3__FP10b_bh_class(); -extern "C" static void s_b_sub__FPvPv(); -extern "C" static void damage_check__FP10b_bh_class(); -extern "C" static void action__FP10b_bh_class(); -extern "C" static void anm_se_set__FP10b_bh_class(); -extern "C" static void daB_BH_Execute__FP10b_bh_class(); -extern "C" static bool daB_BH_IsDelete__FP10b_bh_class(); -extern "C" static void daB_BH_Delete__FP10b_bh_class(); -extern "C" static void useHeapInit__FP10fopAc_ac_c(); -extern "C" static void daB_BH_Create__FP10fopAc_ac_c(); -extern "C" void __dt__12dBgS_ObjAcchFv(); -extern "C" void __dt__8cM3dGSphFv(); -extern "C" void __dt__8cM3dGAabFv(); -extern "C" void __dt__5csXyzFv(); -extern "C" void __ct__5csXyzFv(); -extern "C" void __ct__4cXyzFv(); -extern "C" void __dt__12daB_BH_HIO_cFv(); -extern "C" void __sinit_d_a_b_bh_cpp(); -extern "C" static void func_805B311C(); -extern "C" static void func_805B3124(); -extern "C" extern char const* const d_a_b_bh__stringBase0; +/* 805AE26C-805AE2A4 0000EC 0038+00 1/1 0/0 0/0 .text __ct__12daB_BH_HIO_cFv */ +daB_BH_HIO_c::daB_BH_HIO_c() { + no = -1; + model_size = 1.25f; + attack_freq_a = 350; + attack_freq_b = 250; + down_revive_time = 250; +} -// -// External References: -// +#ifdef DEBUG +void daB_BH_HIO_c::genMessage(JORMContext* ctx) { + ctx->genLabel(" ボスデグババ手", 0x80000001, 0, NULL, 0xFFFF, 0xFFFF, 512, 24); + ctx->genSlider("本体サイズ", &model_size, 0.0f, 5.0f, 0, NULL, 0xFFFF, 0xFFFF, 512, 24); + ctx->genSlider("攻撃頻度\x87\x40", &attack_freq_a, 0, 1000, 0, NULL, 0xFFFF, 0xFFFF, 512, 24); + ctx->genSlider("攻撃頻度\x87\x41", &attack_freq_b, 0, 1000, 0, NULL, 0xFFFF, 0xFFFF, 512, 24); + ctx->genSlider("ダウン→復活時間", &down_revive_time, 0, 1000, 0, NULL, 0xFFFF, 0xFFFF, 512, 24); +} +#endif -extern "C" void mDoMtx_XrotS__FPA4_fs(); -extern "C" void mDoMtx_XrotM__FPA4_fs(); -extern "C" void mDoMtx_YrotS__FPA4_fs(); -extern "C" void mDoMtx_YrotM__FPA4_fs(); -extern "C" void mDoMtx_ZrotM__FPA4_fs(); -extern "C" void scaleM__14mDoMtx_stack_cFfff(); -extern "C" void mDoExt_modelUpdateDL__FP8J3DModel(); -extern "C" void -__ct__16mDoExt_McaMorfSOFP12J3DModelDataP25mDoExt_McaMorfCallBack1_cP25mDoExt_McaMorfCallBack2_cP15J3DAnmTransformifiiP10Z2CreatureUlUl(); -extern "C" void setAnm__16mDoExt_McaMorfSOFP15J3DAnmTransformiffff(); -extern "C" void play__16mDoExt_McaMorfSOFUlSc(); -extern "C" void entryDL__16mDoExt_McaMorfSOFv(); -extern "C" void modelCalc__16mDoExt_McaMorfSOFv(); -extern "C" void stopZelAnime__16mDoExt_McaMorfSOFv(); -extern "C" void mDoExt_J3DModel__create__FP12J3DModelDataUlUl(); -extern "C" void cDmrNowMidnaTalk__Fv(); -extern "C" void __ct__10fopAc_ac_cFv(); -extern "C" void fopAc_IsActor__FPv(); -extern "C" void fopAcIt_Judge__FPFPvPv_PvPv(); -extern "C" void fopAcM_delete__FP10fopAc_ac_c(); -extern "C" void fopAcM_entrySolidHeap__FP10fopAc_ac_cPFP10fopAc_ac_c_iUl(); -extern "C" void fopAcM_effHamonSet__FPUlPC4cXyzff(); -extern "C" void fopAcM_setEffectMtx__FPC10fopAc_ac_cPC12J3DModelData(); -extern "C" void fpcEx_Search__FPFPvPv_PvPv(); -extern "C" void fpcSch_JudgeByID__FPvPv(); -extern "C" void getLayerNo__14dComIfG_play_cFi(); -extern "C" void dComIfG_resLoad__FP30request_of_phase_process_classPCc(); -extern "C" void dComIfG_resDelete__FP30request_of_phase_process_classPCc(); -extern "C" void dComIfGp_getReverb__Fi(); -extern "C" void dComIfGs_onOneZoneSwitch__Fii(); -extern "C" void isSwitch__10dSv_info_cCFii(); -extern "C" void getRes__14dRes_control_cFPCclP11dRes_info_ci(); -extern "C" void getEmitter__Q213dPa_control_c7level_cFUl(); -extern "C" void -set__13dPa_control_cFUcUsPC4cXyzPC12dKy_tevstr_cPC5csXyzPC4cXyzUcP18dPa_levelEcallBackScPC8_GXColorPC8_GXColorPC4cXyzf(); -extern "C" void -set__13dPa_control_cFUlUcUsPC4cXyzPC12dKy_tevstr_cPC5csXyzPC4cXyzUcP18dPa_levelEcallBackScPC8_GXColorPC8_GXColorPC4cXyzf(); -extern "C" void StartShock__12dVibration_cFii4cXyz(); -extern "C" void __ct__12dBgS_AcchCirFv(); -extern "C" void SetWall__12dBgS_AcchCirFff(); -extern "C" void __dt__9dBgS_AcchFv(); -extern "C" void __ct__9dBgS_AcchFv(); -extern "C" void Set__9dBgS_AcchFP4cXyzP4cXyzP10fopAc_ac_ciP12dBgS_AcchCirP4cXyzP5csXyzP5csXyz(); -extern "C" void CrrPos__9dBgS_AcchFR4dBgS(); -extern "C" void SetObj__16dBgS_PolyPassChkFv(); -extern "C" void __ct__10dCcD_GSttsFv(); -extern "C" void Init__9dCcD_SttsFiiP10fopAc_ac_c(); -extern "C" void __ct__12dCcD_GObjInfFv(); -extern "C" void ChkTgHit__12dCcD_GObjInfFv(); -extern "C" void GetTgHitObj__12dCcD_GObjInfFv(); -extern "C" void Set__8dCcD_SphFRC11dCcD_SrcSph(); -extern "C" void def_se_set__FP10Z2CreatureP8cCcD_ObjUlP10fopAc_ac_c(); -extern "C" void settingTevStruct__18dScnKy_env_light_cFiP4cXyzP12dKy_tevstr_c(); -extern "C" void setLightTevColorType_MAJI__18dScnKy_env_light_cFP12J3DModelDataP12dKy_tevstr_c(); -extern "C" void Set__4cCcSFP8cCcD_Obj(); -extern "C" void __pl__4cXyzCFRC3Vec(); -extern "C" void __mi__4cXyzCFRC3Vec(); -extern "C" void __ml__4cXyzCFf(); -extern "C" void cM_atan2s__Fff(); -extern "C" void cM_rndF__Ff(); -extern "C" void cM_rndFX__Ff(); -extern "C" void SetC__8cM3dGSphFRC4cXyz(); -extern "C" void SetR__8cM3dGSphFf(); -extern "C" void cLib_addCalc2__FPffff(); -extern "C" void cLib_addCalcAngleS2__FPssss(); -extern "C" void MtxTrans__FfffUc(); -extern "C" void MtxScale__FfffUc(); -extern "C" void MtxPosition__FP4cXyzP4cXyz(); -extern "C" void MtxPush__Fv(); -extern "C" void MtxPull__Fv(); -extern "C" void func_80280808(); -extern "C" void seStart__7Z2SeMgrF10JAISoundIDPC3VecUlScffffUc(); -extern "C" void __ct__15Z2CreatureEnemyFv(); -extern "C" void init__15Z2CreatureEnemyFP3VecP3VecUcUc(); -extern "C" void* __nw__FUl(); -extern "C" void __dl__FPv(); -extern "C" void __construct_array(); -extern "C" void _savegpr_21(); -extern "C" void _savegpr_24(); -extern "C" void _savegpr_25(); -extern "C" void _savegpr_26(); -extern "C" void _savegpr_27(); -extern "C" void _savegpr_28(); -extern "C" void _savegpr_29(); -extern "C" void _restgpr_21(); -extern "C" void _restgpr_24(); -extern "C" void _restgpr_25(); -extern "C" void _restgpr_26(); -extern "C" void _restgpr_27(); -extern "C" void _restgpr_28(); -extern "C" void _restgpr_29(); -extern "C" extern void* __vt__8dCcD_Sph[36]; -extern "C" extern void* __vt__9dCcD_Stts[11]; -extern "C" extern void* __vt__12cCcD_SphAttr[25]; -extern "C" extern void* __vt__14cCcD_ShapeAttr[22]; -extern "C" extern void* __vt__9cCcD_Stts[8]; -extern "C" u8 m_cpadInfo__8mDoCPd_c[256]; -extern "C" u8 now__14mDoMtx_stack_c[48]; -extern "C" extern u8 g_dComIfG_gameInfo[122384]; -extern "C" u8 sincosTable___5JMath[65536]; -extern "C" extern void* calc_mtx[1 + 1 /* padding */]; -extern "C" extern u8 struct_80450C98[4]; -extern "C" u8 mAudioMgrPtr__10Z2AudioMgr[4 + 4 /* padding */]; -extern "C" void __register_global_object(); +/* 805AE2A4-805AE350 000124 00AC+00 10/10 0/0 0/0 .text anm_init__FP10b_bh_classifUcf */ +static void anm_init(b_bh_class* i_this, int i_anmID, f32 i_morf, u8 i_attr, f32 i_speed) { + i_this->mpModelMorf->setAnm((J3DAnmTransform*)dComIfG_getObjectRes("B_BH", i_anmID), i_attr, i_morf, i_speed, 0.0f, -1.0f); + i_this->mAnm = i_anmID; +} -// -// Declarations: -// +/* 805AE350-805AE430 0001D0 00E0+00 1/0 0/0 0/0 .text daB_BH_Draw__FP10b_bh_class */ +static int daB_BH_Draw(b_bh_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; -/* ############################################################################################## */ -/* 805B3140-805B3144 000000 0004+00 19/19 0/0 0/0 .rodata @3764 */ -SECTION_RODATA static f32 const lit_3764 = 1.25f; -COMPILER_STRIP_GATE(0x805B3140, &lit_3764); + g_env_light.settingTevStruct(0, &a_this->current.pos, &a_this->tevStr); + + J3DModel* model = i_this->mpModelMorf->getModel(); + g_env_light.setLightTevColorType_MAJI(model, &a_this->tevStr); -/* 805B3234-805B3258 000000 0022+02 1/1 0/0 0/0 .data pow_xa$4538 */ -SECTION_DATA static u8 pow_xa[34 + 2 /* padding */] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x10, - 0x00, - 0x18, - 0x00, - 0x20, - 0x00, - 0x28, - 0x00, - 0x30, - 0x00, - 0x38, - 0x00, - 0x40, - 0x00, - 0x38, - 0x00, - 0x30, - 0x00, - 0x28, - 0x00, - 0x20, - 0x00, - 0x18, - 0x00, - 0x10, - 0x00, - 0x08, - 0x00, - 0x00, - 0x00, - /* padding */ - 0x00, - 0x00, -}; + J3DModelData* modelData = model->getModelData(); + fopAcM_setEffectMtx(a_this, modelData); -/* 805B3258-805B3264 000024 000A+02 1/1 0/0 0/0 .data eno$4831 */ -SECTION_DATA static u8 eno_4831[10 + 2 /* padding */] = { - 0x82, - 0xCD, - 0x82, - 0xCE, - 0x82, - 0xF3, - 0x82, - 0xCB, - 0x82, - 0xCC, - /* padding */ - 0x00, - 0x00, -}; + i_this->mpModelMorf->entryDL(); -/* 805B3264-805B326C 000030 0008+00 1/1 0/0 0/0 .data eno$4839 */ -SECTION_DATA static u8 eno_4839[8] = { - 0x82, 0xD9, 0x82, 0xDA, 0x82, 0xDB, 0x82, 0xDC, -}; + for (int i = 0; i < 17; i++) { + g_env_light.setLightTevColorType_MAJI(i_this->mpStemModels[i], &a_this->tevStr); + mDoExt_modelUpdateDL(i_this->mpStemModels[i]); + + if (i_this->mpLeafModels[i] != NULL) { + g_env_light.setLightTevColorType_MAJI(i_this->mpLeafModels[i], &a_this->tevStr); + mDoExt_modelUpdateDL(i_this->mpLeafModels[i]); + } + } -/* 805B326C-805B3278 000038 000A+02 1/1 0/0 0/0 .data g_y_i$5031 */ -SECTION_DATA static u8 g_y_i[10 + 2 /* padding */] = { - 0x82, - 0xF5, - 0x82, - 0xF6, - 0x82, - 0xF7, - 0x82, - 0xF8, - 0x82, - 0xF4, - /* padding */ - 0x00, - 0x00, -}; + return 1; +} -/* 805B3278-805B328C 000044 0014+00 1/1 0/0 0/0 .data g_y_ji$5032 */ -SECTION_DATA static u8 g_y_ji[20] = { - 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, - 0x00, 0x0F, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0C, -}; +UNK_REL_BSS; -/* 805B328C-805B32CC 000058 0040+00 1/1 0/0 0/0 .data cc_sph_src$5408 */ -static dCcD_SrcSph cc_sph_src = { - { - {0x0, {{AT_TYPE_CSTATUE_SWING, 0x2, 0xd}, {0xd8fbfdff, 0x3}, 0x75}}, // mObj - {dCcD_SE_HARD_BODY, 0x0, 0x1, 0x0, 0x0}, // mGObjAt - {dCcD_SE_STONE, 0x2, 0x0, 0x0, 0x3}, // mGObjTg - {0x0}, // mGObjCo - }, // mObjInf - { - {{0.0f, 0.0f, 0.0f}, 40.0f} // mSph - } // mSphAttr -}; +/* 805B33ED 0003+00 data_805B33ED None */ +static u8 l_initHIO; -/* 805B32CC-805B330C 000098 0040+00 1/1 0/0 0/0 .data tg_sph_src$5409 */ -static dCcD_SrcSph tg_sph_src = { - { - {0x0, {{0x0, 0x0, 0x0}, {0xd8fbfdff, 0x3}, 0x0}}, // mObj - {dCcD_SE_HARD_BODY, 0x0, 0x1, 0x0, 0x0}, // mGObjAt - {dCcD_SE_NONE, 0x0, 0x0, 0x0, 0x2}, // mGObjTg - {0x0}, // mGObjCo - }, // mObjInf - { - {{0.0f, 0.0f, 0.0f}, 40.0f} // mSph - } // mSphAttr -}; +/* 805B33FC-805B3414 000054 0018+00 10/11 0/0 0/0 .bss l_HIO */ +static daB_BH_HIO_c l_HIO; + +/* 805B3414-805B341C 00006C 0008+00 2/3 0/0 0/0 .bss bh */ +static b_bh_class* bh[2]; + +/* 805AE430-805AEB04 0002B0 06D4+00 1/1 0/0 0/0 .text b_bh_wait__FP10b_bh_class */ +static void b_bh_wait(b_bh_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + + b_bq_class* bq_p = (b_bq_class*)fopAcM_SearchByID(a_this->parentActorID); + cXyz sp34; + + f32 temp_f31 = 30.0f + TREG_F(12); + if (bq_p->field_0x6fb != 0) { + if (i_this->mID == 0) { + i_this->mTimers[1] = 100.0f + cM_rndF(50.0f); + } else { + i_this->mTimers[1] = 50.0f + cM_rndF(50.0f); + } + } + + if (dComIfGp_event_runCheck()) { + if (i_this->mID == 0) { + i_this->mTimers[1] = 350.0f + cM_rndF(50.0f); + } else { + i_this->mTimers[1] = 250.0f + cM_rndF(50.0f); + } + } + + switch (i_this->mMode) { + case 0: + anm_init(i_this, ANM_WAIT, 10.0f, 2, 1.0f); + i_this->mMode = 1; + if (a_this->health <= 1) { + i_this->mTimers[1] = ((f32)l_HIO.attack_freq_a / 2) + cM_rndF((f32)l_HIO.attack_freq_a / 2); + } else { + i_this->mTimers[1] = l_HIO.attack_freq_a + cM_rndF(l_HIO.attack_freq_a); + } + break; + case 1: + if (i_this->mTimers[0] == 0) { + i_this->mTimers[0] = 10.0f + cM_rndF(30.0f); + i_this->field_0x674.x = i_this->mBasePos.x + cM_rndFX(300.0f); + i_this->field_0x674.z = i_this->mBasePos.z + cM_rndFX(300.0f); + i_this->field_0x674.y = BREG_F(3) + (i_this->mBasePos.y + (550.0f * l_HIO.model_size) + cM_rndFX(200.0f)); + i_this->field_0x690 = 0.0f; + + if (i_this->mTimers[1] == 0 && bq_p->field_0x6fe == 0) { + fopAc_ac_c* const player = dComIfGp_getPlayer(0); + if ((i_this->mBasePos - player->current.pos).abs() < 2800.0f) { + a_this->speedF = 0.0f; + i_this->mAction = ACTION_ATTACK_1; + i_this->mMode = 0; + + if (bq_p->field_0x6fa == 0 && bh[1 - i_this->mID]->mAction == ACTION_WAIT && bh[1 - i_this->mID]->mTimers[3] == 0) { + i_this->field_0x6a0 = 1; + bh[1 - i_this->mID]->mAction = ACTION_ATTACK_1; + bh[1 - i_this->mID]->mMode = 0; + bh[1 - i_this->mID]->field_0x6a0 = 1; + bq_p->field_0x6fa = 2.0f + cM_rndF(2.99f); + } else { + bq_p->field_0x6fe = 200.0f + cM_rndF(150.0f); + if (bq_p->field_0x6fa != 0) { + bq_p->field_0x6fa--; + } + } + } + } + + i_this->mSound.startCreatureVoice(Z2SE_EN_BH_V_WAIT, -1); + } + + sp34.x = temp_f31 * cM_ssin(i_this->field_0x668 * (TREG_S(0) + 1900)); + sp34.y = temp_f31 * cM_ssin(i_this->field_0x668 * (TREG_S(1) + 2200)); + sp34.z = temp_f31 * cM_scos(i_this->field_0x668 * (TREG_S(2) + 2000)); + + cLib_addCalc2(&a_this->current.pos.x, i_this->field_0x674.x + sp34.x, 0.1f, 30.0f * i_this->field_0x690); + cLib_addCalc2(&a_this->current.pos.z, i_this->field_0x674.z + sp34.z, 0.1f, 30.0f * i_this->field_0x690); + cLib_addCalc2(&a_this->current.pos.y, i_this->field_0x674.y + sp34.y, 0.1f, 50.0f * i_this->field_0x690); + cLib_addCalc2(&i_this->field_0x690, 1.0f, 1.0f, 0.05f); + + if (i_this->field_0x674.y - a_this->current.pos.y > 400.0f) { + i_this->field_0x686 = -0x4000; + } + + if (a_this->current.pos.y > a_this->home.pos.y) { + if (a_this->old.pos.y <= a_this->home.pos.y) { + if (i_this->field_0xf20 != 0) { + i_this->field_0xf20 = 0; + i_this->mSound.startCreatureVoice(Z2SE_EN_BH_V_AWAKE, -1); + } else { + i_this->mSound.startCreatureVoice(Z2SE_EN_BH_V_APPEAR, -1); + } + i_this->field_0xf21 = 1; + } + } + break; + } + + cLib_addCalcAngleS2(&a_this->shape_angle.y, i_this->field_0x684, 8, 0x400); + cLib_addCalcAngleS2(&a_this->shape_angle.x, i_this->field_0x686, 8, 0x400); + + cXyz pos(i_this->mBasePos); + pos.y = -23.0f; + fopAcM_effHamonSet(&i_this->field_0xf24, &pos, 3.5f + KREG_F(12), 0.05f); +} + +/* 805AEB40-805AEF78 0009C0 0438+00 1/1 0/0 0/0 .text b_bh_attack_1__FP10b_bh_class */ +static void b_bh_attack_1(b_bh_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + + cXyz sp2C; + cXyz sp20; + f32 target_speed = 0.0f; + f32 var_f30 = 100.0f + YREG_F(2); + + switch (i_this->mMode) { + case 0: + anm_init(i_this, ANM_ATTACK_WAIT, 5.0f, 2, 1.0f); + i_this->mMode = 2; + i_this->mTimers[0] = NREG_S(0) + 35; + + if (i_this->field_0x6a0 != 0) { + i_this->mSound.startCreatureVoice(Z2SE_EN_BH_V_SP_ATTACK, -1); + } else { + i_this->mSound.startCreatureVoice(Z2SE_EN_BH_V_ATTACK, -1); + } + break; + case 2: + if (i_this->mTimers[0] == NREG_S(4) + 8) { + anm_init(i_this, ANM_ATTACK, 3.0f, 0, 1.0f); + } + + a_this->current.angle.y = i_this->field_0x684; + + if (i_this->field_0x6a0 != 0) { + if (i_this->mID == 0) { + a_this->current.angle.y += 0x600; + } else { + a_this->current.angle.y -= 0x600; + } + } + + a_this->current.angle.x = i_this->field_0x686; + + sp2C.x = 0.0f; + sp2C.y = (550.0f * l_HIO.model_size) + NREG_F(0); + sp2C.z = -300.0f + NREG_F(1); + cMtx_YrotS(*calc_mtx, a_this->current.angle.y); + MtxPosition(&sp2C, &sp20); + i_this->field_0x674 = i_this->mBasePos + sp20; + + cLib_addCalc2(&a_this->current.pos.x, i_this->field_0x674.x, 0.1f, 30.0f * i_this->field_0x690); + cLib_addCalc2(&a_this->current.pos.z, i_this->field_0x674.z, 0.1f, 30.0f * i_this->field_0x690); + cLib_addCalc2(&a_this->current.pos.y, i_this->field_0x674.y, 0.1f, 30.0f * i_this->field_0x690); + cLib_addCalc2(&i_this->field_0x690, 1.0f, 1.0f, 0.1f); + + if (i_this->mTimers[0] == 0) { + i_this->mMode = 3; + i_this->mTimers[0] = 25; + i_this->field_0x6a0 = 0; + } + break; + case 3: + if (i_this->mTimers[0] == 22) { + i_this->mSound.startCreatureSound(Z2SE_EN_BH_ATTACK, 0, -1); + } + + target_speed = 200.0f + YREG_F(0); + var_f30 = 100.0f + YREG_F(1); + if (i_this->mTimers[0] == 0 || i_this->field_0x688 < (500.0f + YREG_F(6)) || i_this->field_0x68c > (1700.0f + YREG_F(5))) { + i_this->mTimers[0] = YREG_S(2) + 20; + i_this->mMode = 4; + } + break; + case 4: + if (i_this->mTimers[0] == 0) { + i_this->mAction = ACTION_WAIT; + i_this->mMode = 0; + i_this->mTimers[0] = 60.0f + cM_rndF(50.0f); + i_this->field_0x674.x = i_this->mBasePos.x + cM_rndFX(300.0f); + i_this->field_0x674.z = i_this->mBasePos.z + cM_rndFX(300.0f); + i_this->field_0x674.y = BREG_F(3) + (i_this->mBasePos.y + (550.0f * l_HIO.model_size) + cM_rndFX(200.0f)); + i_this->field_0x690 = 0.0f; + } + break; + } + + if (i_this->mAnm == ANM_ATTACK && i_this->mpModelMorf->isStop()) { + anm_init(i_this, ANM_WAIT02, 5.0f, 2, 1.0f); + } + + cLib_addCalc2(&a_this->speedF, target_speed, 1.0f, var_f30); + if (a_this->speedF >= 20.0f) { + i_this->field_0xce0 = 1; + } + + cLib_addCalcAngleS2(&a_this->shape_angle.y, a_this->current.angle.y, 8, 0x800); + cLib_addCalcAngleS2(&a_this->shape_angle.x, a_this->current.angle.x, 8, 0x400); +} + +/* 805AEF78-805AF1F8 000DF8 0280+00 1/1 0/0 0/0 .text b_bh_bombeat__FP10b_bh_class */ +static void b_bh_bombeat(b_bh_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + b_bq_class* bq_p = (b_bq_class*)fopAcM_SearchByID(a_this->parentActorID); + + switch (i_this->mMode) { + case 0: + anm_init(i_this, ANM_EAT, 3.0f, 0, 1.0f); + i_this->mMode = 1; + i_this->mSound.startCreatureVoice(Z2SE_EN_BH_V_EAT, -1); + + i_this->health--; + if (i_this->health <= 0 && bh[1 - i_this->mID]->mAction == ACTION_DOWN && bh[1 - i_this->mID]->health == 0) { + bh[1 - i_this->mID]->mTimers[0] = 0; + bh[1 - i_this->mID]->health = 0; + bq_p->mDemoMode = 1; + bq_p->field_0x123c = i_this->mID; + } + break; + case 1: + if (i_this->mpModelMorf->isStop()) { + anm_init(i_this, ANM_EAT_WAIT, 1.0f, 2, 1.0f); + i_this->mMode = 2; + i_this->mTimers[0] = 40; + } + break; + case 2: + if (i_this->mTimers[0] == 0) { + i_this->mMode = 3; + anm_init(i_this, ANM_DAMAGE, 1.0f, 0, 1.0f); + i_this->field_0x90c = 2; + i_this->field_0xf22 = 1; + + i_this->mSound.startCreatureVoice(Z2SE_EN_BH_V_DAMAGE, -1); + i_this->mTimers[0] = 20; + } + break; + case 3: + cLib_addCalc2(&i_this->field_0x914, 0.3f + JREG_F(4), 1.0f, 0.05f); + + if (i_this->mTimers[0] == 0) { + cLib_addCalcAngleS2(&a_this->shape_angle.x, -0x4000, 4, 0x200); + } + + if (i_this->mpModelMorf->isStop()) { + i_this->mAction = ACTION_DOWN; + i_this->mMode = 0; + } + break; + } +} + +/* 805AF1F8-805AF6E0 001078 04E8+00 1/1 0/0 0/0 .text b_bh_down__FP10b_bh_class */ +static s8 b_bh_down(b_bh_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + b_bq_class* bq_p = (b_bq_class*)fopAcM_SearchByID(i_this->parentActorID); + + cXyz sp2C; + s8 sp8 = 0; + cXyz sp20 = i_this->field_0x6b0 - a_this->current.pos; + sp20.y = 0.0f; + + switch (i_this->mMode) { + case 0: + anm_init(i_this, ANM_ROUT, 1.0f, 2, 1.0f); + i_this->field_0x690 = 0.0f; + i_this->mMode = 1; + i_this->mTimers[0] = 200; + break; + case 1: + if (sp20.abs() >600.0f) { + sp8 = 1; + } + + if (i_this->mTimers[0] > 100) { + i_this->mSound.startCreatureVoiceLevel(Z2SE_EN_BH_V_ROUT, -1); + } + + f32 temp_f31 = 100.0f + JREG_F(0); + sp2C.x = temp_f31 * cM_ssin(i_this->field_0x668 * (TREG_S(0) + 900)); + sp2C.z = temp_f31 * cM_scos(i_this->field_0x668 * (TREG_S(2) + 1000)); + + cLib_addCalc2(&a_this->current.pos.x, i_this->mBasePos.x + sp2C.x, 0.1f, 50.0f * i_this->field_0x690); + cLib_addCalc2(&a_this->current.pos.z, i_this->mBasePos.z + sp2C.z, 0.1f, 50.0f * i_this->field_0x690); + cLib_addCalc2(&a_this->current.pos.y, 700.0f + i_this->mBasePos.y + JREG_F(1), 0.1f, 30.0f * i_this->field_0x690); + cLib_addCalc2(&i_this->mBasePos.y, (a_this->home.pos.y - 1600.0f) + JREG_F(5), 1.0f, 30.0f * i_this->field_0x690); + cLib_addCalc2(&i_this->field_0x690, 1.0f, 1.0f, 0.01f); + + if (i_this->mBasePos.y <= 50.0f + (a_this->home.pos.y - 1600.0f) + JREG_F(5)) { + i_this->mMode = 2; + i_this->mTimers[0] = l_HIO.down_revive_time; + } + + if (a_this->current.pos.y < a_this->home.pos.y) { + if (a_this->old.pos.y >= a_this->home.pos.y) { + i_this->mAnmSe = Z2SE_EN_BH_SPLASH_DOWN; + if (i_this->mID == 0) { + i_this->mAnmSeTimer = 1; + } else { + i_this->mAnmSeTimer = 3; + } + } + } + break; + case 2: + if (a_this->health <= 0) { + i_this->mMode = 10; + } else if (i_this->mTimers[0] == 0) { + i_this->mAction = ACTION_WAIT; + i_this->mMode = 0; + i_this->mBasePos = a_this->home.pos; + a_this->current.pos.x = i_this->mBasePos.x; + a_this->current.pos.z = i_this->mBasePos.z; + i_this->field_0xf20 = 1; + i_this->mTimers[3] = 60; + } + break; + case 10: + if (bq_p->field_0x6f9 & 4) { + i_this->mBasePos = a_this->home.pos; + a_this->current.pos.x = i_this->mBasePos.x; + a_this->current.pos.z = i_this->mBasePos.z; + a_this->health = 3; + + anm_init(i_this, ANM_WAIT, 10.0f, 2, 1.0f); + i_this->mAction = ACTION_B_WAIT; + i_this->mMode = 1; + + if (i_this->mID == 0) { + i_this->mTimers[1] = 300; + } else { + i_this->mTimers[1] = 400; + } + } + } + + cLib_addCalcAngleS2(&a_this->shape_angle.x, -0x4000, 4, 0x200); + cLib_addCalc2(&i_this->field_0x914, 0.3f + JREG_F(4), 1.0f, 0.05f); + + if (a_this->current.pos.y > a_this->home.pos.y - 100.0f) { + cXyz pos(i_this->mBasePos); + pos.y = -23.0f; + fopAcM_effHamonSet(&i_this->field_0xf24, &pos, 3.5f + KREG_F(12), 0.05f); + } + return sp8; +} + +/* 805AF6E0-805AFCA8 001560 05C8+00 1/1 0/0 0/0 .text b_bh_b_wait__FP10b_bh_class */ +static void b_bh_b_wait(b_bh_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + b_bq_class* bq_p = (b_bq_class*)fopAcM_SearchByID(a_this->parentActorID); + + cXyz sp40; + cXyz sp34; + cXyz sp28; + f32 temp_f31 = 30.0f + TREG_F(12); + + if (bq_p->field_0x6fb != 0) { + if (i_this->mID == 0) { + i_this->mTimers[1] = 100.0f + cM_rndF(50.0f); + } else { + i_this->mTimers[1] = 50.0f + cM_rndF(50.0f); + } + } + + if (dComIfGp_event_runCheck()) { + if (bq_p->field_0x6ec == 0) { + if (i_this->mID == 0) { + i_this->mTimers[1] = 350.0f + cM_rndF(50.0f); + } else { + i_this->mTimers[1] = 250.0f + cM_rndF(50.0f); + } + } else if (i_this->mID == 0) { + i_this->mTimers[1] = 150.0f + cM_rndF(50.0f); + } else { + i_this->mTimers[1] = 70.0f + cM_rndF(50.0f); + } + } + + switch (i_this->mMode) { + case 0: + anm_init(i_this, ANM_WAIT, 10.0f, 2, 1.0f); + i_this->mMode = 1; + i_this->mTimers[1] = l_HIO.attack_freq_b + cM_rndF(l_HIO.attack_freq_b); + break; + case 1: + if (i_this->mTimers[0] == 0) { + i_this->mTimers[0] = 10.0f + cM_rndF(30.0f); + i_this->field_0x674.x = i_this->field_0x6b0.x + cM_rndFX(300.0f); + i_this->field_0x674.z = i_this->field_0x6b0.z + cM_rndFX(300.0f); + i_this->field_0x674.y = BREG_F(3) + (i_this->field_0x6b0.y + (550.0f * l_HIO.model_size) + cM_rndFX(200.0f)); + i_this->field_0x690 = 0.0f; + + if (i_this->mTimers[1] == 0 && bq_p->field_0x6fe == 0) { + fopAc_ac_c* const player = dComIfGp_getPlayer(0); + if ((i_this->field_0x6b0 - player->current.pos).abs() < 2800.0f) { + a_this->speedF = 0.0f; + i_this->mAction = ACTION_B_ATTACK_1; + i_this->mMode = 0; + bq_p->field_0x6fe = 100.0f + cM_rndF(100.0f); + } + } + + i_this->mSound.startCreatureVoice(Z2SE_EN_BH_V_WAIT, -1); + } + + sp28.x = temp_f31 * cM_ssin(i_this->field_0x668 * (TREG_S(0) + 1900)); + sp28.y = temp_f31 * cM_ssin(i_this->field_0x668 * (TREG_S(1) + 2200)); + sp28.z = temp_f31 * cM_scos(i_this->field_0x668 * (TREG_S(2) + 2000)); + cLib_addCalc2(&a_this->current.pos.x, i_this->field_0x674.x + sp28.x, 0.1f, 30.0f * i_this->field_0x690); + cLib_addCalc2(&a_this->current.pos.z, i_this->field_0x674.z + sp28.z, 0.1f, 30.0f * i_this->field_0x690); + cLib_addCalc2(&a_this->current.pos.y, i_this->field_0x674.y + sp28.y, 0.1f, 50.0f * i_this->field_0x690); + cLib_addCalc2(&i_this->field_0x690, 1.0f, 1.0f, 0.05f); + + if (i_this->field_0x674.y - a_this->current.pos.y > 400.0f) { + i_this->field_0x686 = -0x4000; + } + + if (a_this->current.pos.y > a_this->home.pos.y) { + if (a_this->old.pos.y <= a_this->home.pos.y) { + if (i_this->field_0xf20 != 0) { + i_this->field_0xf20 = 0; + i_this->mSound.startCreatureVoice(Z2SE_EN_BH_V_AWAKE, -1); + } else { + i_this->mSound.startCreatureVoice(Z2SE_EN_BH_V_APPEAR, -1); + } + i_this->field_0xf21 = 1; + } + } + break; + } + + cLib_addCalcAngleS2(&a_this->shape_angle.y, i_this->field_0x684, 8, 0x400); + cLib_addCalcAngleS2(&a_this->shape_angle.x, i_this->field_0x686, 8, 0x400); +} + +/* 805AFCA8-805B00A8 001B28 0400+00 1/1 0/0 0/0 .text b_bh_b_attack_1__FP10b_bh_class */ +static void b_bh_b_attack_1(b_bh_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + b_bq_class* bq_p = (b_bq_class*)fopAcM_SearchByID(a_this->parentActorID); + + cXyz sp28; + cXyz sp1C; + f32 target_speed = 0.0f; + f32 speed_step = 100.0f + YREG_F(2); + + switch (i_this->mMode) { + case 0: + anm_init(i_this, ANM_ATTACK_WAIT, 5.0f, 2, 1.0f); + i_this->mMode = 2; + i_this->mTimers[0] = NREG_S(0) + 35; + i_this->mSound.startCreatureVoice(Z2SE_EN_BH_V_ATTACK, -1); + break; + case 2: + if (i_this->mTimers[0] == NREG_S(4) + 8) { + anm_init(i_this, ANM_ATTACK, 3.0f, 0, 1.0f); + } + + a_this->current.angle.y = i_this->field_0x684; + a_this->current.angle.x = i_this->field_0x686; + + sp28.x = 0.0f; + sp28.y = (550.0f * l_HIO.model_size) + NREG_F(0); + sp28.z = -300.0f + NREG_F(1); + cMtx_YrotS(*calc_mtx, a_this->current.angle.y); + MtxPosition(&sp28, &sp1C); + i_this->field_0x674 = i_this->field_0x6b0 + sp1C; + + cLib_addCalc2(&a_this->current.pos.x, i_this->field_0x674.x, 0.1f, 30.0f * i_this->field_0x690); + cLib_addCalc2(&a_this->current.pos.z, i_this->field_0x674.z, 0.1f, 30.0f * i_this->field_0x690); + cLib_addCalc2(&a_this->current.pos.y, i_this->field_0x674.y, 0.1f, 30.0f * i_this->field_0x690); + cLib_addCalc2(&i_this->field_0x690, 1.0f, 1.0f, 0.1f); + + if (i_this->mTimers[0] == 0) { + i_this->mMode = 3; + i_this->mTimers[0] = 25; + } + break; + case 3: + if (i_this->mTimers[0] == 22) { + i_this->mSound.startCreatureSound(Z2SE_EN_BH_ATTACK, 0, -1); + } + + target_speed = 200.0f + YREG_F(0); + speed_step = 100.0f + YREG_F(1); + + if (i_this->mTimers[0] == 0 || i_this->field_0x688 < (500.0f + YREG_F(6)) || i_this->field_0x68c > (1700.0f + YREG_F(5))) { + i_this->mTimers[0] = YREG_S(3) + 10; + i_this->mMode = 4; + } + break; + case 4: + if (i_this->mTimers[0] == 0) { + i_this->mAction = ACTION_B_WAIT; + i_this->mMode = 0; + i_this->mTimers[0] = 60.0f + cM_rndF(50.0f); + i_this->field_0x674.x = i_this->field_0x6b0.x + cM_rndFX(300.0f); + i_this->field_0x674.z = i_this->field_0x6b0.z + cM_rndFX(300.0f); + i_this->field_0x674.y = BREG_F(3) + (i_this->field_0x6b0.y + (550.0f * l_HIO.model_size) + cM_rndFX(200.0f)); + i_this->field_0x690 = 0.0f; + + if (bq_p->field_0x6ec != 0) { + bq_p->field_0x6ec--; + } + } + break; + } + + if (i_this->mAnm == ANM_ATTACK && i_this->mpModelMorf->isStop()) { + anm_init(i_this, ANM_WAIT02, 5.0f, 2, 1.0f); + } + + cLib_addCalc2(&a_this->speedF, target_speed, 1.0f, speed_step); + if (a_this->speedF >= 20.0f) { + i_this->field_0xce0 = 1; + } + + cLib_addCalcAngleS2(&a_this->shape_angle.y, a_this->current.angle.y, 8, 0x800); + cLib_addCalcAngleS2(&a_this->shape_angle.x, a_this->current.angle.x, 8, 0x400); +} + +/* 805B00A8-805B0274 001F28 01CC+00 1/1 0/0 0/0 .text b_bh_b_bombeat__FP10b_bh_class */ +static void b_bh_b_bombeat(b_bh_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + + switch (i_this->mMode) { + case 0: + anm_init(i_this, ANM_EAT, 3.0f, 0, 1.0f); + i_this->mSound.startCreatureVoice(Z2SE_EN_BH_V_EAT, -1); + i_this->mMode = 1; + break; + case 1: + if (i_this->mpModelMorf->isStop()) { + anm_init(i_this, ANM_EAT_WAIT, 1.0f, 2, 1.0f); + i_this->mMode = 2; + i_this->mTimers[0] = 60; + } + break; + case 2: + if (i_this->mTimers[0] == 0) { + i_this->mMode = 3; + anm_init(i_this, ANM_DAMAGE, 1.0f, 0, 1.0f); + i_this->field_0x90c = 2; + i_this->field_0xf22 = 1; + i_this->mTimers[0] = 20; + } + break; + case 3: + cLib_addCalc2(&i_this->field_0x914, 0.3f + JREG_F(4), 1.0f, 0.05f); + + if (i_this->mTimers[0] == 0) { + cLib_addCalcAngleS2(&a_this->shape_angle.x, -0x4000, 4, 0x200); + } + + if (i_this->mpModelMorf->isStop()) { + i_this->mAction = ACTION_B_DOWN; + i_this->mMode = 0; + a_this->health--; + } + break; + } +} + +/* 805B0274-805B060C 0020F4 0398+00 1/1 0/0 0/0 .text b_bh_b_down__FP10b_bh_class */ +static s8 b_bh_b_down(b_bh_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + b_bq_class* bq_p = (b_bq_class*)fopAcM_SearchByID(i_this->parentActorID); + + cXyz sp18; + s8 var_r27 = 0; + cXyz spC = i_this->field_0x6b0 - i_this->current.pos; + spC.y = 0.0f; + + switch (i_this->mMode) { + case 0: + anm_init(i_this, ANM_ROUT, 1.0f, 2, 1.0f); + i_this->field_0x690 = 0.0f; + i_this->mMode = 1; + i_this->mTimers[0] = 200; + break; + case 1: + if (spC.abs() > 600.0f) { + var_r27 = 1; + } + + if (i_this->mTimers[0] > 100) { + i_this->mSound.startCreatureVoiceLevel(Z2SE_EN_BH_V_ROUT, -1); + } + + f32 temp_f31 = 100.0f + JREG_F(0); + sp18.x = temp_f31 * cM_ssin(i_this->field_0x668 * (TREG_S(0) + 900)); + sp18.z = temp_f31 * cM_scos(i_this->field_0x668 * (TREG_S(2) + 1000)); + + cLib_addCalc2(&i_this->current.pos.x, i_this->field_0x6b0.x + sp18.x, 0.1f, 50.0f * i_this->field_0x690); + cLib_addCalc2(&i_this->current.pos.z, i_this->field_0x6b0.z + sp18.z, 0.1f, 50.0f * i_this->field_0x690); + cLib_addCalc2(&i_this->current.pos.y, (i_this->field_0x6b0.y - 1000.0f) + JREG_F(17), 0.1f, 30.0f * i_this->field_0x690); + cLib_addCalc2(&i_this->field_0x690, 1.0f, 1.0f, 0.1f); + + if (i_this->current.pos.y <= 50.0f + (i_this->field_0x6b0.y - 1000.0f) + JREG_F(17)) { + i_this->mMode = 2; + } + + if (i_this->current.pos.y < i_this->home.pos.y) { + if (i_this->old.pos.y >= i_this->home.pos.y) { + i_this->mAnmSe = Z2SE_EN_BH_SPLASH_DOWN; + if (i_this->mID == 0) { + i_this->mAnmSeTimer = 1; + } else { + i_this->mAnmSeTimer = 3; + } + } + } + break; + case 2: + if (bq_p->field_0x6fc != 0) { + if (i_this->health > 0) { + i_this->mAction = ACTION_B_WAIT; + i_this->mMode = 0; + i_this->field_0xf20 = 1; + } else { + i_this->mMode = 3; + } + } + case 3: + break; + } + + cLib_addCalcAngleS2(&i_this->shape_angle.x, -0x4000, 4, 0x200); + return var_r27; +} + +/* 805B060C-805B0B04 00248C 04F8+00 1/1 0/0 0/0 .text b_bh_start__FP10b_bh_class */ +static void b_bh_start(b_bh_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + fopAc_ac_c* player = dComIfGp_getPlayer(0); + s16 sp8 = 0; + cXyz sp18; + + f32 temp_f31 = 50.0f + TREG_F(12); + b_bq_class* bq_p = (b_bq_class*)fopAcM_SearchByID(a_this->parentActorID); + + switch (i_this->mMode) { + case 0: + anm_init(i_this, ANM_WAIT, 10.0f, 2, 1.0f); + if (i_this->mID != 0) { + i_this->mpModelMorf->setFrame(10.0f); + } + i_this->mMode = 1; + break; + case 1: + i_this->mMode = 2; + break; + case 2: + if (bq_p->field_0x6f9 != 0) { + bq_p->field_0x6f9--; + dComIfGp_particle_set(0x82C9, &a_this->home.pos, NULL, NULL); + dComIfGp_particle_set(0x82CA, &a_this->home.pos, NULL, NULL); + i_this->mMode = 3; + mDoAud_seStart(Z2SE_EN_BH_ABUKU, &a_this->home.pos, 0, 0); + } + break; + case 3: + if (bq_p->field_0x6f9 != 0) { + bq_p->field_0x6f9--; + i_this->mMode = 4; + i_this->mBasePos = a_this->home.pos; + + if (i_this->mID == 0) { + a_this->current.pos.y = a_this->home.pos.y - 500.0f; + } else { + a_this->current.pos.y = a_this->home.pos.y - 800.0f; + } + + i_this->field_0x674.x = i_this->mBasePos.x; + i_this->field_0x674.z = i_this->mBasePos.z; + i_this->field_0x674.y = 200.0f + i_this->mBasePos.y + (550.0f * l_HIO.model_size); + i_this->field_0x690 = 0.0f; + i_this->mBasePos.y -= 1000.0f; + } + break; + case 4: + case 5: + sp18.x = temp_f31 * cM_ssin(i_this->field_0x668 * (TREG_S(0) + 1900)); + sp18.z = temp_f31 * cM_scos(i_this->field_0x668 * (TREG_S(2) + 2000)); + + cLib_addCalc2(&i_this->current.pos.x, i_this->field_0x674.x + sp18.x, 0.1f, 50.0f * i_this->field_0x690); + cLib_addCalc2(&i_this->current.pos.z, i_this->field_0x674.z + sp18.z, 0.1f, 50.0f * i_this->field_0x690); + cLib_addCalc2(&i_this->current.pos.y, i_this->field_0x674.y, 0.1f, 50.0f * i_this->field_0x690); + cLib_addCalc2(&i_this->mBasePos.y, a_this->home.pos.y, 0.1f, 10.0f * i_this->field_0x690); + + if (i_this->field_0x674.y - a_this->current.pos.y > 150.0f) { + i_this->field_0x686 = -0x4000; + sp8 = 12000.0f * cM_ssin(bq_p->mDemoModeTimer * (AREG_S(0) + 1000)); + } else if (i_this->mID == 0 && !(i_this->field_0x668 & 7) && cM_rndF(1.0f) < 0.5f) { + i_this->mSound.startCreatureVoice(Z2SE_EN_BH_V_WAIT, -1); + } + + cLib_addCalc2(&i_this->field_0x690, 1.0f, 1.0f, 0.05f); + + if (bq_p->field_0x6f9 != 0) { + bq_p->field_0x6f9--; + if (i_this->mMode == 4) { + i_this->mSound.startCreatureVoice(Z2SE_EN_BH_V_APPEAR, -1); + i_this->field_0xf21 = 1; + i_this->mMode = 5; + } else { + i_this->mAction = ACTION_WAIT; + i_this->mMode = 0; + } + } + break; + } + + cLib_addCalcAngleS2(&a_this->shape_angle.y, i_this->field_0x684, 8, 0x400); + cLib_addCalcAngleS2(&a_this->shape_angle.x, i_this->field_0x686, 8, 0x100); + cLib_addCalcAngleS2(&a_this->shape_angle.z, sp8, 2, 0x200); + + if (i_this->mMode >= 2 && bq_p->mDemoMode == 0 && mDoCPd_c::getTrigStart(PAD_1)) { + i_this->mAction = ACTION_WAIT; + i_this->mMode = 0; + i_this->mBasePos = a_this->home.pos; + a_this->current.pos.y = a_this->home.pos.y - 500.0f; + a_this->shape_angle.z = 0; + } +} + +/* 805B0B04-805B0D6C 002984 0268+00 1/1 0/0 0/0 .text kuki_control1__FP10b_bh_class */ +static void kuki_control1(b_bh_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + + cXyz sp40; + cXyz sp34; + cXyz sp28; + + int i; + cXyz* temp_r31 = i_this->field_0x6bc; + *temp_r31 = i_this->mBasePos; + + cXyz sp1C; + sp40.x = 0.0f; + sp40.y = 0.0f; + sp40.z = i_this->field_0x910; + + temp_r31++; + + f32 temp_f28 = 60.0f + TREG_F(2); + sp28.x = 0.0f; + sp28.z = 0.0f; + sp28.y = -(200.0f + TREG_F(0)); + + f32 temp_f29 = i_this->field_0x918; + + for (i = 1; i < 18; i++, temp_r31++) { + f32 temp_f26 = temp_f28 * cM_ssin((i_this->field_0x668 * (TREG_S(0) + 2000)) + (i * (TREG_S(1) + 7000))); + f32 temp_f25 = temp_f28 * cM_scos((i_this->field_0x668 * (TREG_S(2) + 2300)) + (i * (TREG_S(3) + 5000))); + + static s16 pow_xa[] = { + 0x0000, 0x0000, 0x1000, 0x1800, 0x2000, 0x2800, + 0x3000, 0x3800, 0x4000, 0x3800, 0x3000, 0x2800, + 0x2000, 0x1800, 0x1000, 0x0800, 0x0000, + }; + + cMtx_YrotS(*calc_mtx, (s16)a_this->shape_angle.y); + cMtx_ZrotM(*calc_mtx, (s16)i_this->field_0xa26.z); + cMtx_XrotM(*calc_mtx, (s16)pow_xa[i - 1]); + MtxScale(temp_f29, temp_f29, temp_f29, 1); + MtxPosition(&sp28, &sp1C); + + f32 temp_f31 = temp_f26 + (sp1C.x + (temp_r31[0].x - temp_r31[-1].x)); + f32 temp_f27 = (temp_r31[0].y - temp_r31[-1].y) - sp1C.y; + f32 temp_f30 = temp_f25 + (sp1C.z + (temp_r31[0].z - temp_r31[-1].z)); + + s16 spA, sp8; + sp8 = (s16)cM_atan2s(temp_f31, temp_f30); + spA = -cM_atan2s(temp_f27, JMAFastSqrt((temp_f31 * temp_f31) + (temp_f30 * temp_f30))); + + cMtx_YrotS(*calc_mtx, sp8); + cMtx_XrotM(*calc_mtx, spA); + MtxPosition(&sp40, &sp34); + *temp_r31 = *(temp_r31 - 1) + sp34; + } +} + +/* 805B0D6C-805B0EE0 002BEC 0174+00 1/1 0/0 0/0 .text kuki_control2__FP10b_bh_class */ +static void kuki_control2(b_bh_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + + cXyz sp28; + cXyz sp1C; + + int i; + s16 temp_r27, temp_r26; + + cXyz* temp_r31 = &i_this->field_0x6bc[17]; + *temp_r31 = a_this->current.pos; + + sp28.x = 0.0f; + sp28.y = 0.0f; + sp28.z = i_this->field_0x910; + + i = 16; + temp_r31--; + csXyz* var_r30 = &i_this->field_0x794[16]; + + for (; i >= 0; i--, temp_r31--, var_r30--) { + f32 temp_f29 = temp_r31[0].x - temp_r31[1].x; + f32 temp_f31 = temp_r31[0].y - temp_r31[1].y; + f32 temp_f30 = temp_r31[0].z - temp_r31[1].z; + temp_r27 = -cM_atan2s(temp_f31, temp_f30); + temp_r26 = (s16)cM_atan2s(temp_f29, JMAFastSqrt((temp_f31 * temp_f31) + (temp_f30 * temp_f30))); + + cMtx_XrotS(*calc_mtx, temp_r27); + cMtx_YrotM(*calc_mtx, temp_r26); + MtxPosition(&sp28, &sp1C); + *temp_r31 = *(temp_r31 + 1) + sp1C; + + var_r30->x = temp_r27; + var_r30->y = temp_r26; + } +} + +/* 805B0EE0-805B10AC 002D60 01CC+00 1/1 0/0 0/0 .text kuki_control3__FP10b_bh_class */ +static void kuki_control3(b_bh_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + + cXyz sp20; + + sp20 = i_this->field_0x6bc[0] - i_this->mBasePos; + cXyz* var_r28 = &i_this->field_0x6bc[0]; + + for (int i = 0; i < 18; i++, var_r28++) { + *var_r28 -= sp20 * ((18 - i) / 17.0f); + } + + i_this->field_0xa20 = sp20.abs(); +} + +/* 805B10AC-805B1254 002F2C 01A8+00 1/1 0/0 0/0 .text s_b_sub__FPvPv */ +static void* s_b_sub(void* i_actor, void* i_data) { + if (fopAcM_IsActor(i_actor) && dBomb_c::checkBombActor((fopAc_ac_c*)i_actor) && !((dBomb_c*)i_actor)->checkStateExplode() && !dComIfGp_event_runCheck()) { + cXyz vec_bomb_to_bh = ((fopAc_ac_c*)i_actor)->current.pos - ((fopAc_ac_c*)i_data)->eyePos; + if (vec_bomb_to_bh.abs() < 200.0f) { + fopAcM_delete((fopAc_ac_c*)i_actor); + return i_actor; + } + } + + return NULL; +} + +/* 805B1254-805B15A8 0030D4 0354+00 1/1 0/0 0/0 .text damage_check__FP10b_bh_class */ +static void damage_check(b_bh_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + + if ((i_this->mAction == ACTION_ATTACK_1 || i_this->mAction == ACTION_B_ATTACK_1) && i_this->mCcSph.ChkAtShieldHit()) { + if (i_this->mAction == ACTION_B_ATTACK_1) { + b_bq_class* bq_p = (b_bq_class*)fopAcM_SearchByID(a_this->parentActorID); + if (bq_p->field_0x6ec != 0) { + bq_p->field_0x6ec--; + } + } + + i_this->field_0x69e = 6; + i_this->mAction = ACTION_WAIT; + i_this->mMode = 1; + i_this->mTimers[1] = l_HIO.attack_freq_a + cM_rndF(l_HIO.attack_freq_a); + i_this->mTimers[0] = 0; + anm_init(i_this, ANM_NO_DAMAGE, 3.0f, 0, 1.0f); + i_this->mSound.startCreatureVoice(Z2SE_EN_BH_V_NODAMAGE, -1); + dComIfGp_getVibration().StartShock(VIBMODE_S_POWER8, 0x1F, cXyz(0.0f, 1.0f, 0.0f)); + } else { + cXyz sp1C = i_this->field_0x6b0 - a_this->current.pos; + sp1C.y = 0.0f; + + if (i_this->field_0xa24 != 0) { + i_this->mCcSph.OffCoSetBit(); + + if (fpcM_Search(s_b_sub, i_this) +#ifdef DEBUG + || mDoCPd_c::getTrigA(PAD_3) +#endif + ) + { + if (i_this->field_0xa25 != 0) { + i_this->mAction = ACTION_B_BOMB_EAT; + dComIfGs_onOneZoneSwitch(14, -1); + } else { +#ifdef DEBUG + if (mDoCPd_c::getTrigA(PAD_3)) { + b_bq_class* var_r25 = (b_bq_class*)fopAcM_SearchByID(a_this->parentActorID); + var_r25->field_0x6fd = 1; + if (i_this->mID == 0) { + a_this->health = 0; + bh[1 - i_this->mID]->mAction = ACTION_DOWN; + bh[1 - i_this->mID]->mMode = 10; + bh[1 - i_this->mID]->health = 0; + bh[1 - i_this->mID]->current.pos.y = bh[1 - i_this->mID]->home.pos.y - 700.0f; + } + } +#endif + i_this->mAction = ACTION_BOMB_EAT; + b_bq_class* bq_p = (b_bq_class*)fopAcM_SearchByID(a_this->parentActorID); + if (bq_p->field_0x6fd == 0) { + bq_p->mDemoMode = 20; + bq_p->field_0x123c = i_this->mID; + bq_p->field_0x6fd = 1; + } + } + + i_this->mMode = 0; + i_this->field_0x69e = 10; + return; + } + } else { + i_this->mCcSph.OnCoSetBit(); + } + + if (i_this->field_0x69e == 0 && i_this->mCcSph.ChkTgHit()) { + i_this->field_0x69e = 6; + i_this->mAtInfo.mpCollider = i_this->mCcSph.GetTgHitObj(); + def_se_set(&i_this->mSound, i_this->mAtInfo.mpCollider, 0x2D, NULL); + + if (i_this->mAction != ACTION_BOMB_EAT && i_this->mAction != ACTION_B_BOMB_EAT) { + anm_init(i_this, ANM_NO_DAMAGE, 3.0f, 0, 1.0f); + i_this->mSound.startCreatureVoice(Z2SE_EN_BH_V_NODAMAGE, -1); + } + } + + if (i_this->mAnm == ANM_NO_DAMAGE && i_this->mpModelMorf->isStop()) { + anm_init(i_this, ANM_WAIT, 10.0f, 2, 1.0f); + } + } +} + +/* 805B15A8-805B1F4C 003428 09A4+00 1/1 0/0 0/0 .text action__FP10b_bh_class */ +static void action(b_bh_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + fopAc_ac_c* player = dComIfGp_getPlayer(0); + cXyz spA0; + cXyz sp94; + + spA0 = player->current.pos - a_this->current.pos; + spA0.y += 100.0f; + + i_this->field_0x684 = (s16)cM_atan2s(spA0.x, spA0.z); + i_this->field_0x686 = -cM_atan2s(spA0.y, JMAFastSqrt((spA0.x * spA0.x) + (spA0.z * spA0.z))); + i_this->field_0x688 = (i_this->current.pos - player->eyePos).abs(); + i_this->field_0x68c = (i_this->mBasePos - i_this->current.pos).abs(); + + damage_check(i_this); + + i_this->field_0xa24 = 0; + + s8 spC = 0; + s8 spB = 0; + s8 spA = 0; + s8 sp9 = 1; + s8 sp8 = 0; + + spA0 = i_this->mBasePos - a_this->current.pos; + spA0.y = 0.0f; + + if (spA0.abs() < 700.0f) { + sp9 = 0; + } + + switch (i_this->mAction) { + case ACTION_WAIT: + b_bh_wait(i_this); + spC = 1; + spB = 1; + i_this->field_0xa24 = 1; + break; + case ACTION_ATTACK_1: + b_bh_attack_1(i_this); + spC = 1; + spB = 1; + spA = 1; + i_this->field_0xa24 = 1; + break; + case ACTION_BOMB_EAT: + b_bh_bombeat(i_this); + spB = 1; + break; + case ACTION_DOWN: + sp9 = b_bh_down(i_this); + spB = 1; + break; + case ACTION_B_WAIT: + b_bh_b_wait(i_this); + spC = 1; + spB = 1; + sp8 = 1; + i_this->field_0xa24 = 1; + break; + case ACTION_B_ATTACK_1: + b_bh_b_attack_1(i_this); + spC = 1; + spB = 1; + spA = 1; + sp8 = 1; + i_this->field_0xa24 = 1; + break; + case ACTION_B_BOMB_EAT: + b_bh_b_bombeat(i_this); + spB = 1; + break; + case ACTION_B_DOWN: + sp9 = b_bh_b_down(i_this); + spB = 1; + break; + case ACTION_START: + b_bh_start(i_this); + break; + } + + if (sp8 != 0) { + b_bq_class* bq_p = (b_bq_class*)fopAcM_SearchByID(a_this->parentActorID); + if (bq_p->field_0x6fb == 1) { + i_this->mAction = ACTION_B_DOWN; + i_this->mMode = 0; + } + } + + if (spA != 0) { + cMtx_YrotS(*calc_mtx, a_this->current.angle.y); + cMtx_XrotM(*calc_mtx, a_this->current.angle.x); + spA0.x = 0.0f; + spA0.y = 0.0f; + spA0.z = a_this->speedF; + MtxPosition(&spA0, &a_this->speed); + i_this->current.pos += a_this->speed; + + cXyz* cc_move_p = i_this->mColliderStts.GetCCMoveP(); + if (cc_move_p != NULL) { + a_this->current.pos.x += cc_move_p->x; + a_this->current.pos.y += cc_move_p->y; + a_this->current.pos.z += cc_move_p->z; + } + } + + if (sp9 != 0) { + f32 temp_f31 = -150.0f + ZREG_F(3); + + a_this->current.pos.y += temp_f31; + a_this->old.pos.y += temp_f31; + + i_this->mAcch.CrrPos(dComIfG_Bgsp()); + + a_this->current.pos.y -= temp_f31; + a_this->old.pos.y -= temp_f31; + } + + if (spC != 0) { + fopAcM_OnStatus(a_this, 0); + a_this->attention_info.flags = 4; + } else { + fopAcM_OffStatus(a_this, 0); + a_this->attention_info.flags = 0; + } + + spA0 = i_this->current.pos - i_this->mBasePos; + i_this->field_0x910 = i_this->field_0x914 * ((0.2f + BREG_F(0)) * spA0.abs()); + if (i_this->field_0x910 > (50.0f + BREG_F(1)) * l_HIO.model_size) { + i_this->field_0x910 = (50.0f + BREG_F(1)) * l_HIO.model_size; + } + + cLib_addCalc2(&i_this->field_0x914, 1.0f, 1.0f, 0.01f); + + kuki_control1(i_this); + kuki_control2(i_this); + kuki_control3(i_this); + + cLib_addCalc2(&i_this->field_0x918, 1.0f, 1.0f, 0.05f); + + if (i_this->field_0xf21 != 0) { + i_this->field_0xf21 = 0; + i_this->mAnmSe = Z2SE_EN_BH_SPLASH_UP; + + if (i_this->mID == 0) { + i_this->mAnmSeTimer = 1; + } else { + i_this->mAnmSeTimer = 3; + } + + cXyz pos(a_this->current.pos); + pos.y = 0.0f; + cXyz size(l_HIO.model_size, l_HIO.model_size, l_HIO.model_size); + + for (int i = 0; i < 5; i++) { + static u16 eno[] = {0x82CD, 0x82CE, 0x82F3, 0x82CB, 0x82CC}; + dComIfGp_particle_set(eno[i], &pos, NULL, &size); + } + } + + if (i_this->field_0xf22 != 0) { + i_this->field_0xf22 = 0; + + cXyz pos(a_this->current.pos); + cXyz size(l_HIO.model_size, l_HIO.model_size, l_HIO.model_size); + + for (int i = 0; i < 4; i++) { + static u16 eno[] = {0x82D9, 0x82DA, 0x82DB, 0x82DC}; + dComIfGp_particle_set(eno[i], &pos, &a_this->shape_angle, &size); + } + + i_this->mSound.startCreatureSound(Z2SE_OBJ_BOMB_EXPLODE, 0, -1); + } +} + +/* 805B1F4C-805B2110 003DCC 01C4+00 1/1 0/0 0/0 .text anm_se_set__FP10b_bh_class */ +static void anm_se_set(b_bh_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + + f32 particle_target_size = 0.0f; + if (i_this->mAnm == ANM_WAIT && a_this->current.pos.y > 50.0f) { + particle_target_size = 1.0f; + } + + cLib_addCalc2(&i_this->mMouthMizuParticleSize, particle_target_size, 1.0f, 0.05f); + + for (int i = 0; i < 5; i++) { + static u16 g_y_i[] = {0x82F5, 0x82F6, 0x82F7, 0x82F8, 0x82F4}; + i_this->mMouthMizuEmitterIDs[i] = dComIfGp_particle_set(i_this->mMouthMizuEmitterIDs[i], g_y_i[i], &a_this->current.pos, NULL, NULL); + + JPABaseEmitter* emitter = dComIfGp_particle_getEmitter(i_this->mMouthMizuEmitterIDs[i]); + if (emitter != NULL) { + static int g_y_ji[] = {12, 13, 15, 16, 12}; + + MTXCopy(i_this->mpModelMorf->getModel()->getAnmMtx(g_y_ji[i]), *calc_mtx); + MtxScale(i_this->mMouthMizuParticleSize, i_this->mMouthMizuParticleSize, i_this->mMouthMizuParticleSize, 1); + emitter->setGlobalSRTMatrix(*calc_mtx); + } + } + + if (i_this->mAnmSeTimer != 0) { + i_this->mAnmSeTimer--; + if (i_this->mAnmSeTimer == 0) { + i_this->mSound.startCreatureSound(i_this->mAnmSe, 0, -1); + } + } +} + +/* 805B2110-805B2840 003F90 0730+00 2/1 0/0 0/0 .text daB_BH_Execute__FP10b_bh_class */ +static int daB_BH_Execute(b_bh_class* i_this) { + if (cDmrNowMidnaTalk()) { + return 1; + } + + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + + cXyz sp30; + cXyz sp24; + + b_bq_class* bq_p = (b_bq_class*)fopAcM_SearchByID(a_this->parentActorID); + if (bq_p->mDisableDraw == FALSE) { + i_this->field_0xa25 = 1; + if (i_this->mAction == ACTION_WAIT) { + i_this->mAction = ACTION_B_WAIT; + } + } + + i_this->field_0x668++; + + for (int i = 0; i < 5; i++) { + if (i_this->mTimers[i] != 0) { + i_this->mTimers[i]--; + } + } + + if (i_this->field_0x69e != 0) { + i_this->field_0x69e--; + } + + if (i_this->field_0xa25 != 0) { + i_this->field_0xa26 = bq_p->shape_angle; + + J3DModel* bq_model = bq_p->mpMorf->getModel(); + bq_model->setBaseTRMtx(mDoMtx_stack_c::get()); + + if (i_this->mID == 0) { + MTXCopy(bq_model->getAnmMtx(0x1D), *calc_mtx); + i_this->field_0xa26.z += 0x3000; + } else { + MTXCopy(bq_model->getAnmMtx(0x26), *calc_mtx); + i_this->field_0xa26.z -= 0x3000; + } + + sp30.set(0.0f, 0.0f, 0.0f); + MtxPosition(&sp30, &i_this->mBasePos); + cMtx_YrotS(*calc_mtx, bq_p->shape_angle.y); + + if (i_this->mID == 0) { + sp30.x = 500.0f; + } else { + sp30.x = -500.0f; + } + + sp30.y = 0.0f; + sp30.z = 0.0f; + MtxPosition(&sp30, &sp24); + i_this->field_0x6b0 = sp24 + i_this->mBasePos; + } else { + i_this->field_0x6b0 = i_this->mBasePos; + } + + action(i_this); + anm_se_set(i_this); + + mDoMtx_stack_c::transS(a_this->current.pos.x, a_this->current.pos.y, a_this->current.pos.z); + mDoMtx_stack_c::YrotM(a_this->shape_angle.y); + mDoMtx_stack_c::XrotM(a_this->shape_angle.x); + mDoMtx_stack_c::ZrotM(a_this->shape_angle.z); + + f32 size = l_HIO.model_size; + mDoMtx_stack_c::scaleM(size, size, size); + + J3DModel* model = i_this->mpModelMorf->getModel(); + model->setBaseTRMtx(mDoMtx_stack_c::get()); + + i_this->mpModelMorf->play(0, dComIfGp_getReverb(fopAcM_GetRoomNo(a_this))); + i_this->mpModelMorf->modelCalc(); + + MTXCopy(model->getAnmMtx(BREG_S(4) + 10), *calc_mtx); + + sp30.set(300.0f + BREG_F(3), BREG_F(4), BREG_F(5)); + MtxPosition(&sp30, &a_this->eyePos); + a_this->attention_info.position = a_this->eyePos; + a_this->attention_info.position.y += 250.0f + BREG_F(6); + + sp30.set(200.0f + BREG_F(3), BREG_F(4), BREG_F(5)); + MtxPosition(&sp30, &sp24); + + i_this->mCcSph.SetC(sp24); + i_this->mCcSph.SetR((100.0f + YREG_F(3)) * l_HIO.model_size); + + if (i_this->field_0x688 > 1000.0f && dComIfGp_checkPlayerStatus0(0, 0x80000)) { + i_this->mTgSph.SetR(2.5f * ((100.0f + YREG_F(3)) * l_HIO.model_size)); + } else { + sp24.y -= 12000.0f; + } + + i_this->mTgSph.SetC(sp24); + dComIfG_Ccsp()->Set(&i_this->mCcSph); + dComIfG_Ccsp()->Set(&i_this->mTgSph); + + if (i_this->field_0xce0 != 0) { + i_this->mCcSph.OnAtSetBit(); + i_this->field_0xce0 = 0; + } else { + i_this->mCcSph.OffAtSetBit(); + } + + f32 temp_f30 = i_this->field_0xa20 * (0.002f + YREG_F(4)); + + for (int i = 0; i < 3; i++) { + if (i_this->field_0x900[i] == 0) { + if (i_this->field_0x90c == 2) { + i_this->field_0x90c = 0; + i_this->field_0x900[i] = 2; + i_this->field_0x906[i] = 17; + i_this->field_0x8fc = 2.0f + YREG_F(8); + i_this->field_0x8f8 = 4000; + break; + } + } else { + if (i_this->field_0x900[i] == 1) { + if (i_this->field_0x909[i] == 0) { + i_this->field_0x909[i] = YREG_S(5) + 2; + i_this->field_0x8d4[i_this->field_0x906[i]] = 1; + i_this->field_0x906[i]++; + + if (i_this->field_0x906[i] >= 18) { + i_this->field_0x900[i] = 0; + } + } + } else { + i_this->mSound.startCreatureSoundLevel(0x70109, 0, -1); + + if (i_this->field_0x909[i] == 0) { + i_this->field_0x909[i] = (YREG_S(5) + 1); + i_this->field_0x8d4[i_this->field_0x906[i]] = 1; + i_this->field_0x906[i]--; + + if (i_this->field_0x906[i] < 0) { + i_this->field_0x900[i] = 0; + } + } + } + + if (i_this->field_0x909[i] != 0) { + i_this->field_0x909[i]--; + } + } + } + + for (int i = 0; i < 17; i++) { + if (i_this->field_0x8d4[i] != 0) { + i_this->field_0x8d4[i] += i_this->field_0x8f8; + if (i_this->field_0x8d4[i] < 0) { + i_this->field_0x8d4[i] = 0; + } + + i_this->field_0x88c[i] = 1.0f + (i_this->field_0x8fc * cM_ssin((s16)i_this->field_0x8d4[i])); + } + + MtxTrans(i_this->field_0x6bc[i].x, i_this->field_0x6bc[i].y, i_this->field_0x6bc[i].z, 0); + cMtx_XrotM(*calc_mtx, i_this->field_0x794[i].x); + cMtx_YrotM(*calc_mtx, i_this->field_0x794[i].y + 0x8000); + MtxPush(); + MtxScale(l_HIO.model_size * i_this->field_0x88c[i], l_HIO.model_size * i_this->field_0x88c[i], l_HIO.model_size + temp_f30, 1); + MtxTrans(0.0f, 0.0f, -10.0f - XREG_F(4), 1); + i_this->mpStemModels[i]->setBaseTRMtx(*calc_mtx); + MtxPull(); + + if (i_this->mpLeafModels[i] != 0) { + MtxScale(l_HIO.model_size, l_HIO.model_size, l_HIO.model_size, 1); + MtxTrans(0.0f, 0.0f, -10.0f - XREG_F(4), 1); + cMtx_YrotM(*calc_mtx, i_this->field_0x9a8[i].y); + cMtx_ZrotM(*calc_mtx, i_this->field_0x9a8[i].z); + i_this->mpLeafModels[i]->setBaseTRMtx(*calc_mtx); + } + } + + return 1; +} + +/* 805B2840-805B2848 0046C0 0008+00 1/0 0/0 0/0 .text daB_BH_IsDelete__FP10b_bh_class */ +static int daB_BH_IsDelete(b_bh_class* i_this) { + return 1; +} + +/* 805B2848-805B28B0 0046C8 0068+00 1/0 0/0 0/0 .text daB_BH_Delete__FP10b_bh_class */ +static int daB_BH_Delete(b_bh_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + fpc_ProcID id = fopAcM_GetID(a_this); + + dComIfG_resDelete(&i_this->mPhase, "B_BH"); + if (i_this->mInitHIO) { + l_initHIO = FALSE; + mDoHIO_DELETE_CHILD(l_HIO.no); + } + + if (a_this->heap != NULL) { + i_this->mpModelMorf->stopZelAnime(); + } + + return 1; +} + +/* 805B28B0-805B2AF8 004730 0248+00 1/1 0/0 0/0 .text useHeapInit__FP10fopAc_ac_c */ +static int useHeapInit(fopAc_ac_c* i_this) { + b_bh_class* a_this = (b_bh_class*)i_this; + + a_this->mpModelMorf = new mDoExt_McaMorfSO((J3DModelData*)dComIfG_getObjectRes("B_BH", 0x15), NULL, NULL, (J3DAnmTransform*)dComIfG_getObjectRes("B_BH", 12), 2, 1.0f, 0, -1, &a_this->mSound, 0, 0x11000084); + if (a_this->mpModelMorf == NULL || a_this->mpModelMorf->getModel() == NULL) { + return 0; + } + + void* modelData = dComIfG_getObjectRes("B_BH", 0x11); + JUT_ASSERT(2475, modelData != 0); + + for (int i = 0; i < 17; i++) { + a_this->mpStemModels[i] = mDoExt_J3DModel__create((J3DModelData*)modelData, 0x80000, 0x11000084); + if (a_this->mpStemModels[i] == NULL) { + return 0; + } + + a_this->field_0x88c[i] = 1.0f; + } + + modelData = dComIfG_getObjectRes("B_BH", 0x12); + JUT_ASSERT(2491, modelData != 0); + + for (int i = 0; i < 17; i++) { + if ((i & 3) == 2) { + a_this->mpLeafModels[i] = mDoExt_J3DModel__create((J3DModelData*)modelData, 0x80000, 0x11000084); + if (a_this->mpLeafModels[i] == NULL) { + return 0; + } + + a_this->field_0x960[i] = cM_rndFX(0.3f) + 1.2f; + a_this->field_0x9a8[i].y = cM_rndF(0x10000); + a_this->field_0x9a8[i].z = cM_rndF(0x10000); + } + } + + return 1; +} + +/* 805B2AF8-805B2F54 004978 045C+00 1/0 0/0 0/0 .text daB_BH_Create__FP10fopAc_ac_c */ +static int daB_BH_Create(fopAc_ac_c* i_this) { + b_bh_class* a_this = (b_bh_class*)i_this; + fopAcM_SetupActor(a_this, b_bh_class); + + int phase_state = dComIfG_resLoad(&a_this->mPhase, "B_BH"); + if (phase_state == cPhs_COMPLEATE_e) { + OS_REPORT("B_BH PARAM %x\n", fopAcM_GetParam(i_this)); + a_this->mID = (fopAcM_GetParam(i_this) >> 0x00) & 0xFF; + a_this->field_0x5b5 = (fopAcM_GetParam(i_this) >> 0x08) & 0xFF; + a_this->field_0x5b6 = (fopAcM_GetParam(i_this) >> 0x10) & 0xF; + a_this->field_0x5b7 = (fopAcM_GetParam(i_this) >> 0x14) & 0xF; + + if (a_this->mID == 0xFF) { + return cPhs_ERROR_e; + } + + OS_REPORT("B_BH//////////////B_BH SET 1 !!\n"); + + if (!fopAcM_entrySolidHeap(i_this, useHeapInit, 0xDB20)) { + OS_REPORT("//////////////B_BH SET NON !!\n"); + return cPhs_ERROR_e; + } + + OS_REPORT("//////////////B_BH SET 2 !!\n"); + + if (!l_initHIO) { + a_this->mInitHIO = TRUE; + l_initHIO = TRUE; + l_HIO.no = mDoHIO_CREATE_CHILD("ボスババ触手", &l_HIO); + } + + i_this->attention_info.flags = 4; + i_this->health = 1; + i_this->field_0x560 = 1; + + a_this->mColliderStts.Init(0xFD, 0, i_this); + + static dCcD_SrcSph cc_sph_src = { + { + {0x0, {{AT_TYPE_CSTATUE_SWING, 0x2, 0xd}, {0xd8fbfdff, 0x3}, 0x75}}, // mObj + {dCcD_SE_HARD_BODY, 0x0, 0x1, 0x0, 0x0}, // mGObjAt + {dCcD_SE_STONE, 0x2, 0x0, 0x0, 0x3}, // mGObjTg + {0x0}, // mGObjCo + }, // mObjInf + { + {{0.0f, 0.0f, 0.0f}, 40.0f} // mSph + } // mSphAttr + }; + + static dCcD_SrcSph tg_sph_src = { + { + {0x0, {{0x0, 0x0, 0x0}, {0xd8fbfdff, 0x3}, 0x0}}, // mObj + {dCcD_SE_HARD_BODY, 0x0, 0x1, 0x0, 0x0}, // mGObjAt + {dCcD_SE_NONE, 0x0, 0x0, 0x0, 0x2}, // mGObjTg + {0x0}, // mGObjCo + }, // mObjInf + { + {{0.0f, 0.0f, 0.0f}, 40.0f} // mSph + } // mSphAttr + }; + + a_this->mCcSph.Set(cc_sph_src); + a_this->mCcSph.SetStts(&a_this->mColliderStts); + + a_this->mTgSph.Set(tg_sph_src); + a_this->mTgSph.SetStts(&a_this->mColliderStts); + a_this->mTgSph.OnTgNoHitMark(); + + a_this->mAtInfo.mpSound = &a_this->mSound; + a_this->mAtInfo.field_0x18 = 0x2D; + + a_this->mAcch.Set(fopAcM_GetPosition_p(i_this), fopAcM_GetOldPosition_p(i_this), i_this, 1, &a_this->mAcchCir, fopAcM_GetSpeed_p(i_this), NULL, NULL); + a_this->mAcchCir.SetWall(150.0f, 250.0f); + + a_this->mSound.init(&i_this->current.pos, &i_this->eyePos, 3, 1); + + i_this->attention_info.distances[fopAc_attn_BATTLE_e] = 22; + + i_this->home.pos.y -= 50.0f; + a_this->mBasePos = i_this->home.pos; + + bh[a_this->mID] = a_this; + + if (dComIfG_play_c::getLayerNo(0) == 4) { + a_this->mAction = ACTION_DOWN; + a_this->mMode = 0; + a_this->mBasePos.y = i_this->home.pos.y - 1600.0f; + i_this->current.pos.y = i_this->home.pos.y - 700.0f; + } + + u8 swbit = fopAcM_GetParam(i_this) >> 0x10; + if (!dComIfGs_isSwitch(swbit, fopAcM_GetRoomNo(i_this)) && cDmr_SkipInfo == 0) { + a_this->mAction = ACTION_START; + a_this->mMode = 0; + a_this->mBasePos.y = i_this->home.pos.y - 1600.0f; + i_this->current.pos.y = i_this->home.pos.y - 700.0f; + } + + a_this->field_0x668 = cM_rndF(0xFFFF); + daB_BH_Execute(a_this); + } + + return phase_state; +} /* 805B330C-805B332C -00001 0020+00 1/0 0/0 0/0 .data l_daB_BH_Method */ static actor_method_class l_daB_BH_Method = { - (process_method_func)daB_BH_Create__FP10fopAc_ac_c, - (process_method_func)daB_BH_Delete__FP10b_bh_class, - (process_method_func)daB_BH_Execute__FP10b_bh_class, - (process_method_func)daB_BH_IsDelete__FP10b_bh_class, - (process_method_func)daB_BH_Draw__FP10b_bh_class, + (process_method_func)daB_BH_Create, + (process_method_func)daB_BH_Delete, + (process_method_func)daB_BH_Execute, + (process_method_func)daB_BH_IsDelete, + (process_method_func)daB_BH_Draw, }; /* 805B332C-805B335C -00001 0030+00 0/0 0/0 1/0 .data g_profile_B_BH */ @@ -306,900 +1615,4 @@ extern actor_process_profile_definition g_profile_B_BH = { fopAc_CULLBOX_CUSTOM_e, // cullType }; -/* 805B335C-805B3380 000128 0024+00 2/2 0/0 0/0 .data __vt__12dBgS_ObjAcch */ -SECTION_DATA extern void* __vt__12dBgS_ObjAcch[9] = { - (void*)NULL /* RTTI */, - (void*)NULL, - (void*)__dt__12dBgS_ObjAcchFv, - (void*)NULL, - (void*)NULL, - (void*)func_805B3124, - (void*)NULL, - (void*)NULL, - (void*)func_805B311C, -}; - -/* 805B3380-805B338C 00014C 000C+00 2/2 0/0 0/0 .data __vt__8cM3dGSph */ -SECTION_DATA extern void* __vt__8cM3dGSph[3] = { - (void*)NULL /* RTTI */, - (void*)NULL, - (void*)__dt__8cM3dGSphFv, -}; - -/* 805B338C-805B3398 000158 000C+00 2/2 0/0 0/0 .data __vt__8cM3dGAab */ -SECTION_DATA extern void* __vt__8cM3dGAab[3] = { - (void*)NULL /* RTTI */, - (void*)NULL, - (void*)__dt__8cM3dGAabFv, -}; - -/* 805B3398-805B33A4 000164 000C+00 2/2 0/0 0/0 .data __vt__12daB_BH_HIO_c */ -SECTION_DATA extern void* __vt__12daB_BH_HIO_c[3] = { - (void*)NULL /* RTTI */, - (void*)NULL, - (void*)__dt__12daB_BH_HIO_cFv, -}; - -/* 805AE26C-805AE2A4 0000EC 0038+00 1/1 0/0 0/0 .text __ct__12daB_BH_HIO_cFv */ -daB_BH_HIO_c::daB_BH_HIO_c() { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 805B3144-805B3148 000004 0004+00 2/18 0/0 0/0 .rodata @3778 */ -SECTION_RODATA static u8 const lit_3778[4] = { - 0x00, - 0x00, - 0x00, - 0x00, -}; -COMPILER_STRIP_GATE(0x805B3144, &lit_3778); - -/* 805B3148-805B314C 000008 0004+00 1/2 0/0 0/0 .rodata @3779 */ -SECTION_RODATA static f32 const lit_3779 = -1.0f; -COMPILER_STRIP_GATE(0x805B3148, &lit_3779); - -/* 805B322C-805B322C 0000EC 0000+00 0/0 0/0 0/0 .rodata @stringBase0 */ -#pragma push -#pragma force_active on -SECTION_DEAD static char const* const stringBase_805B322C = "B_BH"; -#pragma pop - -/* 805AE2A4-805AE350 000124 00AC+00 10/10 0/0 0/0 .text anm_init__FP10b_bh_classifUcf */ -static void anm_init(b_bh_class* param_0, int param_1, f32 param_2, u8 param_3, f32 param_4) { - // NONMATCHING -} - -/* 805AE350-805AE430 0001D0 00E0+00 1/0 0/0 0/0 .text daB_BH_Draw__FP10b_bh_class */ -static void daB_BH_Draw(b_bh_class* param_0) { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 805B314C-805B3150 00000C 0004+00 0/8 0/0 0/0 .rodata @3946 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3946 = 100.0f; -COMPILER_STRIP_GATE(0x805B314C, &lit_3946); -#pragma pop - -/* 805B3150-805B3154 000010 0004+00 0/10 0/0 0/0 .rodata @3947 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3947 = 50.0f; -COMPILER_STRIP_GATE(0x805B3150, &lit_3947); -#pragma pop - -/* 805B3154-805B3158 000014 0004+00 0/2 0/0 0/0 .rodata @3948 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3948 = 350.0f; -COMPILER_STRIP_GATE(0x805B3154, &lit_3948); -#pragma pop - -/* 805B3158-805B315C 000018 0004+00 0/4 0/0 0/0 .rodata @3949 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3949 = 250.0f; -COMPILER_STRIP_GATE(0x805B3158, &lit_3949); -#pragma pop - -/* 805B315C-805B3160 00001C 0004+00 0/5 0/0 0/0 .rodata @3950 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3950 = 10.0f; -COMPILER_STRIP_GATE(0x805B315C, &lit_3950); -#pragma pop - -/* 805B3160-805B3164 000020 0004+00 0/14 0/0 0/0 .rodata @3951 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3951 = 1.0f; -COMPILER_STRIP_GATE(0x805B3160, &lit_3951); -#pragma pop - -/* 805B3164-805B3168 000024 0004+00 0/2 0/0 0/0 .rodata @3952 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3952 = 0.5f; -COMPILER_STRIP_GATE(0x805B3164, &lit_3952); -#pragma pop - -/* 805B3168-805B316C 000028 0004+00 0/6 0/0 0/0 .rodata @3953 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3953 = 30.0f; -COMPILER_STRIP_GATE(0x805B3168, &lit_3953); -#pragma pop - -/* 805B316C-805B3170 00002C 0004+00 0/5 0/0 0/0 .rodata @3954 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3954 = 300.0f; -COMPILER_STRIP_GATE(0x805B316C, &lit_3954); -#pragma pop - -/* 805B3170-805B3174 000030 0004+00 0/5 0/0 0/0 .rodata @3955 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3955 = 550.0f; -COMPILER_STRIP_GATE(0x805B3170, &lit_3955); -#pragma pop - -/* 805B3174-805B3178 000034 0004+00 0/7 0/0 0/0 .rodata @3956 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3956 = 200.0f; -COMPILER_STRIP_GATE(0x805B3174, &lit_3956); -#pragma pop - -/* 805B3178-805B3180 000038 0008+00 0/7 0/0 0/0 .rodata @3957 */ -#pragma push -#pragma force_active on -SECTION_RODATA static u8 const lit_3957[8] = { - 0x3F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -COMPILER_STRIP_GATE(0x805B3178, &lit_3957); -#pragma pop - -/* 805B3180-805B3188 000040 0008+00 0/7 0/0 0/0 .rodata @3958 */ -#pragma push -#pragma force_active on -SECTION_RODATA static u8 const lit_3958[8] = { - 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -COMPILER_STRIP_GATE(0x805B3180, &lit_3958); -#pragma pop - -/* 805B3188-805B3190 000048 0008+00 0/7 0/0 0/0 .rodata @3959 */ -#pragma push -#pragma force_active on -SECTION_RODATA static u8 const lit_3959[8] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -COMPILER_STRIP_GATE(0x805B3188, &lit_3959); -#pragma pop - -/* 805B3190-805B3194 000050 0004+00 0/2 0/0 0/0 .rodata @3960 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3960 = 2800.0f; -COMPILER_STRIP_GATE(0x805B3190, &lit_3960); -#pragma pop - -/* 805B3194-805B3198 000054 0004+00 0/2 0/0 0/0 .rodata @3961 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3961 = 2.0f; -COMPILER_STRIP_GATE(0x805B3194, &lit_3961); -#pragma pop - -/* 805B3198-805B319C 000058 0004+00 0/1 0/0 0/0 .rodata @3962 */ -#pragma push -#pragma force_active on -SECTION_RODATA static u32 const lit_3962 = 0x403F5C29; -COMPILER_STRIP_GATE(0x805B3198, &lit_3962); -#pragma pop - -/* 805B319C-805B31A0 00005C 0004+00 0/4 0/0 0/0 .rodata @3963 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3963 = 150.0f; -COMPILER_STRIP_GATE(0x805B319C, &lit_3963); -#pragma pop - -/* 805B31A0-805B31A4 000060 0004+00 0/7 0/0 0/0 .rodata @3964 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3964 = 1.0f / 10.0f; -COMPILER_STRIP_GATE(0x805B31A0, &lit_3964); -#pragma pop - -/* 805B31A4-805B31A8 000064 0004+00 0/8 0/0 0/0 .rodata @3965 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3965 = 1.0f / 20.0f; -COMPILER_STRIP_GATE(0x805B31A4, &lit_3965); -#pragma pop - -/* 805B31A8-805B31AC 000068 0004+00 0/2 0/0 0/0 .rodata @3966 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3966 = 400.0f; -COMPILER_STRIP_GATE(0x805B31A8, &lit_3966); -#pragma pop - -/* 805B31AC-805B31B0 00006C 0004+00 0/2 0/0 0/0 .rodata @3967 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3967 = -23.0f; -COMPILER_STRIP_GATE(0x805B31AC, &lit_3967); -#pragma pop - -/* 805B31B0-805B31B8 000070 0004+04 0/2 0/0 0/0 .rodata @3968 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3968[1 + 1 /* padding */] = { - 3.5f, - /* padding */ - 0.0f, -}; -COMPILER_STRIP_GATE(0x805B31B0, &lit_3968); -#pragma pop - -/* 805B31B8-805B31C0 000078 0008+00 0/4 0/0 0/0 .rodata @3970 */ -#pragma push -#pragma force_active on -SECTION_RODATA static u8 const lit_3970[8] = { - 0x43, 0x30, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, -}; -COMPILER_STRIP_GATE(0x805B31B8, &lit_3970); -#pragma pop - -/* 805B33B0-805B33B4 000008 0001+03 1/1 0/0 0/0 .bss @1109 */ -static u8 lit_1109[1 + 3 /* padding */]; - -/* 805B33B4-805B33B8 00000C 0001+03 0/0 0/0 0/0 .bss @1107 */ -#pragma push -#pragma force_active on -static u8 lit_1107[1 + 3 /* padding */]; -#pragma pop - -/* 805B33B8-805B33BC 000010 0001+03 0/0 0/0 0/0 .bss @1105 */ -#pragma push -#pragma force_active on -static u8 lit_1105[1 + 3 /* padding */]; -#pragma pop - -/* 805B33BC-805B33C0 000014 0001+03 0/0 0/0 0/0 .bss @1104 */ -#pragma push -#pragma force_active on -static u8 lit_1104[1 + 3 /* padding */]; -#pragma pop - -/* 805B33C0-805B33C4 000018 0001+03 0/0 0/0 0/0 .bss @1099 */ -#pragma push -#pragma force_active on -static u8 lit_1099[1 + 3 /* padding */]; -#pragma pop - -/* 805B33C4-805B33C8 00001C 0001+03 0/0 0/0 0/0 .bss @1097 */ -#pragma push -#pragma force_active on -static u8 lit_1097[1 + 3 /* padding */]; -#pragma pop - -/* 805B33C8-805B33CC 000020 0001+03 0/0 0/0 0/0 .bss @1095 */ -#pragma push -#pragma force_active on -static u8 lit_1095[1 + 3 /* padding */]; -#pragma pop - -/* 805B33CC-805B33D0 000024 0001+03 0/0 0/0 0/0 .bss @1094 */ -#pragma push -#pragma force_active on -static u8 lit_1094[1 + 3 /* padding */]; -#pragma pop - -/* 805B33D0-805B33D4 000028 0001+03 0/0 0/0 0/0 .bss @1057 */ -#pragma push -#pragma force_active on -static u8 lit_1057[1 + 3 /* padding */]; -#pragma pop - -/* 805B33D4-805B33D8 00002C 0001+03 0/0 0/0 0/0 .bss @1055 */ -#pragma push -#pragma force_active on -static u8 lit_1055[1 + 3 /* padding */]; -#pragma pop - -/* 805B33D8-805B33DC 000030 0001+03 0/0 0/0 0/0 .bss @1053 */ -#pragma push -#pragma force_active on -static u8 lit_1053[1 + 3 /* padding */]; -#pragma pop - -/* 805B33DC-805B33E0 000034 0001+03 0/0 0/0 0/0 .bss @1052 */ -#pragma push -#pragma force_active on -static u8 lit_1052[1 + 3 /* padding */]; -#pragma pop - -/* 805B33E0-805B33E4 000038 0001+03 0/0 0/0 0/0 .bss @1014 */ -#pragma push -#pragma force_active on -static u8 lit_1014[1 + 3 /* padding */]; -#pragma pop - -/* 805B33E4-805B33E8 00003C 0001+03 0/0 0/0 0/0 .bss @1012 */ -#pragma push -#pragma force_active on -static u8 lit_1012[1 + 3 /* padding */]; -#pragma pop - -/* 805B33E8-805B33EC 000040 0001+03 0/0 0/0 0/0 .bss @1010 */ -#pragma push -#pragma force_active on -static u8 lit_1010[1 + 3 /* padding */]; -#pragma pop - -/* 805B33EC-805B33F0 -00001 0004+00 1/2 0/0 0/0 .bss None */ -/* 805B33EC 0001+00 data_805B33EC @1009 */ -/* 805B33ED 0003+00 data_805B33ED None */ -static u8 struct_805B33EC[4]; - -/* 805B33F0-805B33FC 000048 000C+00 1/1 0/0 0/0 .bss @3759 */ -static u8 lit_3759[12]; - -/* 805B33FC-805B3414 000054 0018+00 10/11 0/0 0/0 .bss l_HIO */ -static u8 l_HIO[24]; - -/* 805B3414-805B341C 00006C 0008+00 2/3 0/0 0/0 .bss bh */ -static u8 bh[8]; - -/* 805AE430-805AEB04 0002B0 06D4+00 1/1 0/0 0/0 .text b_bh_wait__FP10b_bh_class */ -static void b_bh_wait(b_bh_class* param_0) { - // NONMATCHING -} - -/* 805AEB04-805AEB40 000984 003C+00 1/1 0/0 0/0 .text __dt__4cXyzFv */ -// cXyz::~cXyz() { -extern "C" void __dt__4cXyzFv() { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 805B31C0-805B31C4 000080 0004+00 0/2 0/0 0/0 .rodata @4038 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4038 = 5.0f; -COMPILER_STRIP_GATE(0x805B31C0, &lit_4038); -#pragma pop - -/* 805B31C4-805B31C8 000084 0004+00 0/5 0/0 0/0 .rodata @4039 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4039 = 3.0f; -COMPILER_STRIP_GATE(0x805B31C4, &lit_4039); -#pragma pop - -/* 805B31C8-805B31CC 000088 0004+00 0/2 0/0 0/0 .rodata @4040 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4040 = -300.0f; -COMPILER_STRIP_GATE(0x805B31C8, &lit_4040); -#pragma pop - -/* 805B31CC-805B31D0 00008C 0004+00 0/4 0/0 0/0 .rodata @4041 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4041 = 500.0f; -COMPILER_STRIP_GATE(0x805B31CC, &lit_4041); -#pragma pop - -/* 805B31D0-805B31D4 000090 0004+00 0/2 0/0 0/0 .rodata @4042 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4042 = 1700.0f; -COMPILER_STRIP_GATE(0x805B31D0, &lit_4042); -#pragma pop - -/* 805B31D4-805B31D8 000094 0004+00 0/3 0/0 0/0 .rodata @4043 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4043 = 60.0f; -COMPILER_STRIP_GATE(0x805B31D4, &lit_4043); -#pragma pop - -/* 805B31D8-805B31DC 000098 0004+00 0/2 0/0 0/0 .rodata @4044 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4044 = 20.0f; -COMPILER_STRIP_GATE(0x805B31D8, &lit_4044); -#pragma pop - -/* 805AEB40-805AEF78 0009C0 0438+00 1/1 0/0 0/0 .text b_bh_attack_1__FP10b_bh_class */ -static void b_bh_attack_1(b_bh_class* param_0) { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 805B31DC-805B31E0 00009C 0004+00 0/4 0/0 0/0 .rodata @4091 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4091 = 3.0f / 10.0f; -COMPILER_STRIP_GATE(0x805B31DC, &lit_4091); -#pragma pop - -/* 805AEF78-805AF1F8 000DF8 0280+00 1/1 0/0 0/0 .text b_bh_bombeat__FP10b_bh_class */ -static void b_bh_bombeat(b_bh_class* param_0) { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 805B31E0-805B31E4 0000A0 0004+00 0/2 0/0 0/0 .rodata @4179 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4179 = 600.0f; -COMPILER_STRIP_GATE(0x805B31E0, &lit_4179); -#pragma pop - -/* 805B31E4-805B31E8 0000A4 0004+00 0/3 0/0 0/0 .rodata @4180 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4180 = 700.0f; -COMPILER_STRIP_GATE(0x805B31E4, &lit_4180); -#pragma pop - -/* 805B31E8-805B31EC 0000A8 0004+00 0/2 0/0 0/0 .rodata @4181 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4181 = 1600.0f; -COMPILER_STRIP_GATE(0x805B31E8, &lit_4181); -#pragma pop - -/* 805B31EC-805B31F0 0000AC 0004+00 0/2 0/0 0/0 .rodata @4182 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4182 = 1.0f / 100.0f; -COMPILER_STRIP_GATE(0x805B31EC, &lit_4182); -#pragma pop - -/* 805AF1F8-805AF6E0 001078 04E8+00 1/1 0/0 0/0 .text b_bh_down__FP10b_bh_class */ -static void b_bh_down(b_bh_class* param_0) { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 805B31F0-805B31F4 0000B0 0004+00 0/1 0/0 0/0 .rodata @4280 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4280 = 70.0f; -COMPILER_STRIP_GATE(0x805B31F0, &lit_4280); -#pragma pop - -/* 805AF6E0-805AFCA8 001560 05C8+00 1/1 0/0 0/0 .text b_bh_b_wait__FP10b_bh_class */ -static void b_bh_b_wait(b_bh_class* param_0) { - // NONMATCHING -} - -/* 805AFCA8-805B00A8 001B28 0400+00 1/1 0/0 0/0 .text b_bh_b_attack_1__FP10b_bh_class */ -static void b_bh_b_attack_1(b_bh_class* param_0) { - // NONMATCHING -} - -/* 805B00A8-805B0274 001F28 01CC+00 1/1 0/0 0/0 .text b_bh_b_bombeat__FP10b_bh_class */ -static void b_bh_b_bombeat(b_bh_class* param_0) { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 805B31F4-805B31F8 0000B4 0004+00 0/3 0/0 0/0 .rodata @4450 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4450 = 1000.0f; -COMPILER_STRIP_GATE(0x805B31F4, &lit_4450); -#pragma pop - -/* 805B0274-805B060C 0020F4 0398+00 1/1 0/0 0/0 .text b_bh_b_down__FP10b_bh_class */ -static void b_bh_b_down(b_bh_class* param_0) { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 805B31F8-805B31FC 0000B8 0004+00 0/1 0/0 0/0 .rodata @4532 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4532 = 800.0f; -COMPILER_STRIP_GATE(0x805B31F8, &lit_4532); -#pragma pop - -/* 805B31FC-805B3200 0000BC 0004+00 0/2 0/0 0/0 .rodata @4533 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4533 = 12000.0f; -COMPILER_STRIP_GATE(0x805B31FC, &lit_4533); -#pragma pop - -/* 805B060C-805B0B04 00248C 04F8+00 1/1 0/0 0/0 .text b_bh_start__FP10b_bh_class */ -static void b_bh_start(b_bh_class* param_0) { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 805B3200-805B3204 0000C0 0004+00 0/1 0/0 0/0 .rodata @4593 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4593 = -200.0f; -COMPILER_STRIP_GATE(0x805B3200, &lit_4593); -#pragma pop - -/* 805B0B04-805B0D6C 002984 0268+00 1/1 0/0 0/0 .text kuki_control1__FP10b_bh_class */ -static void kuki_control1(b_bh_class* param_0) { - // NONMATCHING -} - -/* 805B0D6C-805B0EE0 002BEC 0174+00 1/1 0/0 0/0 .text kuki_control2__FP10b_bh_class */ -static void kuki_control2(b_bh_class* param_0) { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 805B3204-805B3208 0000C4 0004+00 0/1 0/0 0/0 .rodata @4670 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4670 = 17.0f; -COMPILER_STRIP_GATE(0x805B3204, &lit_4670); -#pragma pop - -/* 805B0EE0-805B10AC 002D60 01CC+00 1/1 0/0 0/0 .text kuki_control3__FP10b_bh_class */ -static void kuki_control3(b_bh_class* param_0) { - // NONMATCHING -} - -/* 805B10AC-805B1254 002F2C 01A8+00 1/1 0/0 0/0 .text s_b_sub__FPvPv */ -static void s_b_sub(void* param_0, void* param_1) { - // NONMATCHING -} - -/* 805B1254-805B15A8 0030D4 0354+00 1/1 0/0 0/0 .text damage_check__FP10b_bh_class */ -static void damage_check(b_bh_class* param_0) { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 805B3208-805B320C 0000C8 0004+00 0/1 0/0 0/0 .rodata @5023 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_5023 = -150.0f; -COMPILER_STRIP_GATE(0x805B3208, &lit_5023); -#pragma pop - -/* 805B320C-805B3210 0000CC 0004+00 0/1 0/0 0/0 .rodata @5024 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_5024 = 1.0f / 5.0f; -COMPILER_STRIP_GATE(0x805B320C, &lit_5024); -#pragma pop - -/* 805B15A8-805B1F4C 003428 09A4+00 1/1 0/0 0/0 .text action__FP10b_bh_class */ -static void action(b_bh_class* param_0) { - // NONMATCHING -} - -/* 805B1F4C-805B2110 003DCC 01C4+00 1/1 0/0 0/0 .text anm_se_set__FP10b_bh_class */ -static void anm_se_set(b_bh_class* param_0) { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 805B3210-805B3214 0000D0 0004+00 0/1 0/0 0/0 .rodata @5330 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_5330 = -500.0f; -COMPILER_STRIP_GATE(0x805B3210, &lit_5330); -#pragma pop - -/* 805B3214-805B3218 0000D4 0004+00 0/1 0/0 0/0 .rodata @5331 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_5331 = 2.5f; -COMPILER_STRIP_GATE(0x805B3214, &lit_5331); -#pragma pop - -/* 805B3218-805B321C 0000D8 0004+00 0/1 0/0 0/0 .rodata @5332 */ -#pragma push -#pragma force_active on -SECTION_RODATA static u32 const lit_5332 = 0x3B03126F; -COMPILER_STRIP_GATE(0x805B3218, &lit_5332); -#pragma pop - -/* 805B321C-805B3220 0000DC 0004+00 0/1 0/0 0/0 .rodata @5333 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_5333 = -10.0f; -COMPILER_STRIP_GATE(0x805B321C, &lit_5333); -#pragma pop - -/* 805B2110-805B2840 003F90 0730+00 2/1 0/0 0/0 .text daB_BH_Execute__FP10b_bh_class */ -static void daB_BH_Execute(b_bh_class* param_0) { - // NONMATCHING -} - -/* 805B2840-805B2848 0046C0 0008+00 1/0 0/0 0/0 .text daB_BH_IsDelete__FP10b_bh_class */ -static bool daB_BH_IsDelete(b_bh_class* param_0) { - return true; -} - -/* 805B2848-805B28B0 0046C8 0068+00 1/0 0/0 0/0 .text daB_BH_Delete__FP10b_bh_class */ -static void daB_BH_Delete(b_bh_class* param_0) { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 805B3220-805B3224 0000E0 0004+00 0/1 0/0 0/0 .rodata @5390 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_5390 = 6.0f / 5.0f; -COMPILER_STRIP_GATE(0x805B3220, &lit_5390); -#pragma pop - -/* 805B3224-805B3228 0000E4 0004+00 0/1 0/0 0/0 .rodata @5391 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_5391 = 65536.0f; -COMPILER_STRIP_GATE(0x805B3224, &lit_5391); -#pragma pop - -/* 805B28B0-805B2AF8 004730 0248+00 1/1 0/0 0/0 .text useHeapInit__FP10fopAc_ac_c */ -static void useHeapInit(fopAc_ac_c* param_0) { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 805B3228-805B322C 0000E8 0004+00 0/1 0/0 0/0 .rodata @5513 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_5513 = 65535.0f; -COMPILER_STRIP_GATE(0x805B3228, &lit_5513); -#pragma pop - -/* 805B2AF8-805B2F54 004978 045C+00 1/0 0/0 0/0 .text daB_BH_Create__FP10fopAc_ac_c */ -static void daB_BH_Create(fopAc_ac_c* param_0) { - // NONMATCHING -} - -/* 805B2F54-805B2FC4 004DD4 0070+00 3/2 0/0 0/0 .text __dt__12dBgS_ObjAcchFv */ -// dBgS_ObjAcch::~dBgS_ObjAcch() { -extern "C" void __dt__12dBgS_ObjAcchFv() { - // NONMATCHING -} - -/* 805B2FC4-805B300C 004E44 0048+00 1/0 0/0 0/0 .text __dt__8cM3dGSphFv */ -// cM3dGSph::~cM3dGSph() { -extern "C" void __dt__8cM3dGSphFv() { - // NONMATCHING -} - -/* 805B300C-805B3054 004E8C 0048+00 1/0 0/0 0/0 .text __dt__8cM3dGAabFv */ -// cM3dGAab::~cM3dGAab() { -extern "C" void __dt__8cM3dGAabFv() { - // NONMATCHING -} - -/* 805B3054-805B3090 004ED4 003C+00 1/1 0/0 0/0 .text __dt__5csXyzFv */ -// csXyz::~csXyz() { -extern "C" void __dt__5csXyzFv() { - // NONMATCHING -} - -/* 805B3090-805B3094 004F10 0004+00 1/1 0/0 0/0 .text __ct__5csXyzFv */ -// csXyz::csXyz() { -extern "C" void __ct__5csXyzFv() { - /* empty function */ -} - -/* 805B3094-805B3098 004F14 0004+00 1/1 0/0 0/0 .text __ct__4cXyzFv */ -// cXyz::cXyz() { -extern "C" void __ct__4cXyzFv() { - /* empty function */ -} - -/* 805B3098-805B30E0 004F18 0048+00 2/1 0/0 0/0 .text __dt__12daB_BH_HIO_cFv */ -daB_BH_HIO_c::~daB_BH_HIO_c() { - // NONMATCHING -} - -/* 805B30E0-805B311C 004F60 003C+00 0/0 1/0 0/0 .text __sinit_d_a_b_bh_cpp */ -void __sinit_d_a_b_bh_cpp() { - // NONMATCHING -} - -#pragma push -#pragma force_active on -REGISTER_CTORS(0x805B30E0, __sinit_d_a_b_bh_cpp); -#pragma pop - -/* 805B311C-805B3124 004F9C 0008+00 1/0 0/0 0/0 .text @36@__dt__12dBgS_ObjAcchFv */ -static void func_805B311C() { - // NONMATCHING -} - -/* 805B3124-805B312C 004FA4 0008+00 1/0 0/0 0/0 .text @20@__dt__12dBgS_ObjAcchFv */ -static void func_805B3124() { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 805B341C-805B3420 000074 0004+00 0/0 0/0 0/0 .bss - * sInstance__40JASGlobalInstance<19JASDefaultBankTable> */ -#pragma push -#pragma force_active on -static u8 data_805B341C[4]; -#pragma pop - -/* 805B3420-805B3424 000078 0004+00 0/0 0/0 0/0 .bss - * sInstance__35JASGlobalInstance<14JASAudioThread> */ -#pragma push -#pragma force_active on -static u8 data_805B3420[4]; -#pragma pop - -/* 805B3424-805B3428 00007C 0004+00 0/0 0/0 0/0 .bss sInstance__27JASGlobalInstance<7Z2SeMgr> */ -#pragma push -#pragma force_active on -static u8 data_805B3424[4]; -#pragma pop - -/* 805B3428-805B342C 000080 0004+00 0/0 0/0 0/0 .bss sInstance__28JASGlobalInstance<8Z2SeqMgr> */ -#pragma push -#pragma force_active on -static u8 data_805B3428[4]; -#pragma pop - -/* 805B342C-805B3430 000084 0004+00 0/0 0/0 0/0 .bss sInstance__31JASGlobalInstance<10Z2SceneMgr> - */ -#pragma push -#pragma force_active on -static u8 data_805B342C[4]; -#pragma pop - -/* 805B3430-805B3434 000088 0004+00 0/0 0/0 0/0 .bss sInstance__32JASGlobalInstance<11Z2StatusMgr> - */ -#pragma push -#pragma force_active on -static u8 data_805B3430[4]; -#pragma pop - -/* 805B3434-805B3438 00008C 0004+00 0/0 0/0 0/0 .bss sInstance__31JASGlobalInstance<10Z2DebugSys> - */ -#pragma push -#pragma force_active on -static u8 data_805B3434[4]; -#pragma pop - -/* 805B3438-805B343C 000090 0004+00 0/0 0/0 0/0 .bss - * sInstance__36JASGlobalInstance<15JAISoundStarter> */ -#pragma push -#pragma force_active on -static u8 data_805B3438[4]; -#pragma pop - -/* 805B343C-805B3440 000094 0004+00 0/0 0/0 0/0 .bss - * sInstance__35JASGlobalInstance<14Z2SoundStarter> */ -#pragma push -#pragma force_active on -static u8 data_805B343C[4]; -#pragma pop - -/* 805B3440-805B3444 000098 0004+00 0/0 0/0 0/0 .bss - * sInstance__33JASGlobalInstance<12Z2SpeechMgr2> */ -#pragma push -#pragma force_active on -static u8 data_805B3440[4]; -#pragma pop - -/* 805B3444-805B3448 00009C 0004+00 0/0 0/0 0/0 .bss sInstance__28JASGlobalInstance<8JAISeMgr> */ -#pragma push -#pragma force_active on -static u8 data_805B3444[4]; -#pragma pop - -/* 805B3448-805B344C 0000A0 0004+00 0/0 0/0 0/0 .bss sInstance__29JASGlobalInstance<9JAISeqMgr> */ -#pragma push -#pragma force_active on -static u8 data_805B3448[4]; -#pragma pop - -/* 805B344C-805B3450 0000A4 0004+00 0/0 0/0 0/0 .bss - * sInstance__33JASGlobalInstance<12JAIStreamMgr> */ -#pragma push -#pragma force_active on -static u8 data_805B344C[4]; -#pragma pop - -/* 805B3450-805B3454 0000A8 0004+00 0/0 0/0 0/0 .bss sInstance__31JASGlobalInstance<10Z2SoundMgr> - */ -#pragma push -#pragma force_active on -static u8 data_805B3450[4]; -#pragma pop - -/* 805B3454-805B3458 0000AC 0004+00 0/0 0/0 0/0 .bss - * sInstance__33JASGlobalInstance<12JAISoundInfo> */ -#pragma push -#pragma force_active on -static u8 data_805B3454[4]; -#pragma pop - -/* 805B3458-805B345C 0000B0 0004+00 0/0 0/0 0/0 .bss - * sInstance__34JASGlobalInstance<13JAUSoundTable> */ -#pragma push -#pragma force_active on -static u8 data_805B3458[4]; -#pragma pop - -/* 805B345C-805B3460 0000B4 0004+00 0/0 0/0 0/0 .bss - * sInstance__38JASGlobalInstance<17JAUSoundNameTable> */ -#pragma push -#pragma force_active on -static u8 data_805B345C[4]; -#pragma pop - -/* 805B3460-805B3464 0000B8 0004+00 0/0 0/0 0/0 .bss - * sInstance__33JASGlobalInstance<12JAUSoundInfo> */ -#pragma push -#pragma force_active on -static u8 data_805B3460[4]; -#pragma pop - -/* 805B3464-805B3468 0000BC 0004+00 0/0 0/0 0/0 .bss sInstance__32JASGlobalInstance<11Z2SoundInfo> - */ -#pragma push -#pragma force_active on -static u8 data_805B3464[4]; -#pragma pop - -/* 805B3468-805B346C 0000C0 0004+00 0/0 0/0 0/0 .bss - * sInstance__34JASGlobalInstance<13Z2SoundObjMgr> */ -#pragma push -#pragma force_active on -static u8 data_805B3468[4]; -#pragma pop - -/* 805B346C-805B3470 0000C4 0004+00 0/0 0/0 0/0 .bss sInstance__31JASGlobalInstance<10Z2Audience> - */ -#pragma push -#pragma force_active on -static u8 data_805B346C[4]; -#pragma pop - -/* 805B3470-805B3474 0000C8 0004+00 0/0 0/0 0/0 .bss sInstance__32JASGlobalInstance<11Z2FxLineMgr> - */ -#pragma push -#pragma force_active on -static u8 data_805B3470[4]; -#pragma pop - -/* 805B3474-805B3478 0000CC 0004+00 0/0 0/0 0/0 .bss sInstance__31JASGlobalInstance<10Z2EnvSeMgr> - */ -#pragma push -#pragma force_active on -static u8 data_805B3474[4]; -#pragma pop - -/* 805B3478-805B347C 0000D0 0004+00 0/0 0/0 0/0 .bss sInstance__32JASGlobalInstance<11Z2SpeechMgr> - */ -#pragma push -#pragma force_active on -static u8 data_805B3478[4]; -#pragma pop - -/* 805B347C-805B3480 0000D4 0004+00 0/0 0/0 0/0 .bss - * sInstance__34JASGlobalInstance<13Z2WolfHowlMgr> */ -#pragma push -#pragma force_active on -static u8 data_805B347C[4]; -#pragma pop - -/* 805B322C-805B322C 0000EC 0000+00 0/0 0/0 0/0 .rodata @stringBase0 */ +AUDIO_INSTANCES; diff --git a/src/d/actor/d_a_e_mb.cpp b/src/d/actor/d_a_e_mb.cpp index 8113de5e25..c51c23aeca 100644 --- a/src/d/actor/d_a_e_mb.cpp +++ b/src/d/actor/d_a_e_mb.cpp @@ -4,200 +4,767 @@ */ #include "d/actor/d_a_e_mb.h" -#include "d/d_cc_d.h" -#include "dol2asm.h" +#include "d/actor/d_a_b_bq.h" +#include "d/d_com_inf_game.h" +#include "d/d_s_play.h" +#include "d/d_bomb.h" +#include "c/c_damagereaction.h" +#include "Z2AudioLib/Z2Instances.h" +#define ACTION_STANDBY 0 +#define ACTION_WALK1 1 +#define ACTION_MOVE 2 +#define ACTION_WALK2 3 +#define ACTION_FIRST_DEMO 4 +#define ACTION_END 5 +#define ANM_MB_CATCH 6 +#define ANM_MB_DEMO_SHOW_BOMB 7 +#define ANM_MB_DEMO_SIGNAL 8 +#define ANM_MB_DEMO_TURN_CATCH 9 +#define ANM_MB_LANDING 10 +#define ANM_MB_ROPE_WAIT_A 11 +#define ANM_MB_ROPE_WAIT_A_END 12 +#define ANM_MB_ROPE_WAIT_A_START 13 +#define ANM_MB_ROPE_WAIT_B 14 +#define ANM_MB_ROPE_WAIT_B_END 15 +#define ANM_MB_ROPE_WAIT_B_START 16 +#define ANM_MB_ROPE_WAIT_FLYOUT 17 +#define ANM_MB_RUN 18 +#define ANM_MB_WALK 19 +#define ANM_MG_DEMO_SHOW_BOMB 20 +#define ANM_MI_BOMB_POSE 21 +#define ANM_MI_ROPE_WAIT 22 -// -// Forward References: -// +/* 8070616C-807061B4 0000EC 0048+00 1/1 0/0 0/0 .text __ct__12daE_MB_HIO_cFv */ +daE_MB_HIO_c::daE_MB_HIO_c() { + no = -1; + base_size = 1.0f; + swing_speed = 50.0f; + swing_descend = 1.5f; + swing_correction = 0.0f; + reappear_time = 70; +} -extern "C" void __ct__12daE_MB_HIO_cFv(); -extern "C" static void anm_init__FP10e_mb_classifUcf(); -extern "C" static void daE_MB_Draw__FP10e_mb_class(); -extern "C" static void e_mb_standby__FP10e_mb_class(); -extern "C" static void e_mb_walk1__FP10e_mb_class(); -extern "C" void __dt__4cXyzFv(); -extern "C" static void e_mb_move__FP10e_mb_class(); -extern "C" static void e_mb_walk2__FP10e_mb_class(); -extern "C" static void e_mb_firstdemo__FP10e_mb_class(); -extern "C" static void e_mb_end__FP10e_mb_class(); -extern "C" static void action__FP10e_mb_class(); -extern "C" static void daE_MB_Execute__FP10e_mb_class(); -extern "C" static bool daE_MB_IsDelete__FP10e_mb_class(); -extern "C" static void daE_MB_Delete__FP10e_mb_class(); -extern "C" static void useHeapInit__FP10fopAc_ac_c(); -extern "C" void __dt__12J3DFrameCtrlFv(); -extern "C" static void daE_MB_Create__FP10fopAc_ac_c(); -extern "C" void __dt__8cM3dGSphFv(); -extern "C" void __dt__8cM3dGAabFv(); -extern "C" void __dt__12daE_MB_HIO_cFv(); -extern "C" void __sinit_d_a_e_mb_cpp(); -extern "C" extern char const* const d_a_e_mb__stringBase0; +#ifdef DEBUG +void daE_MB_HIO_c::genMessage(JORMContext* ctx) { + ctx->genLabel(" ボス戦ブーメラン猿", 0x80000001, 0, NULL, 0xFFFF, 0xFFFF, 512, 24); + ctx->genSlider("基本サイズ", &base_size, 0.0f, 5.0f, 0, NULL, 0xFFFF, 0xFFFF, 512, 24); + ctx->genSlider("振り子速度", &swing_speed, 0.0f, 1000.0f, 0, NULL, 0xFFFF, 0xFFFF, 512, 24); + ctx->genSlider("振り子下弦", &swing_descend, 0.5f, 2.0f, 0, NULL, 0xFFFF, 0xFFFF, 512, 24); + ctx->genSlider("軌道修正", &swing_correction, -500.0f, 2000.0f, 0, NULL, 0xFFFF, 0xFFFF, 512, 24); + ctx->genSlider("再出現時間(およそ)", &reappear_time, 0.0f, 300.0f, 0, NULL, 0xFFFF, 0xFFFF, 512, 24); +} +#endif -// -// External References: -// +/* 807061B4-80706260 000134 00AC+00 5/5 0/0 0/0 .text anm_init__FP10e_mb_classifUcf */ +static void anm_init(e_mb_class* i_this, int i_anmID, f32 i_morf, u8 i_attr, f32 i_speed) { + i_this->mpModelMorf->setAnm((J3DAnmTransform*)dComIfG_getObjectRes("E_mb", i_anmID), i_attr, i_morf, i_speed, 0.0f, -1.0f); + i_this->mAnm = i_anmID; +} -extern "C" void mDoMtx_XrotM__FPA4_fs(); -extern "C" void mDoMtx_YrotS__FPA4_fs(); -extern "C" void mDoMtx_YrotM__FPA4_fs(); -extern "C" void mDoMtx_ZrotM__FPA4_fs(); -extern "C" void transM__14mDoMtx_stack_cFfff(); -extern "C" void scaleM__14mDoMtx_stack_cFfff(); -extern "C" void init__13mDoExt_btpAnmFP16J3DMaterialTableP16J3DAnmTexPatterniifss(); -extern "C" void entry__13mDoExt_btpAnmFP16J3DMaterialTables(); -extern "C" void -__ct__14mDoExt_McaMorfFP12J3DModelDataP25mDoExt_McaMorfCallBack1_cP25mDoExt_McaMorfCallBack2_cP15J3DAnmTransformifiiiPvUlUl(); -extern "C" void setAnm__14mDoExt_McaMorfFP15J3DAnmTransformiffffPv(); -extern "C" void play__14mDoExt_McaMorfFP3VecUlSc(); -extern "C" void entryDL__14mDoExt_McaMorfFv(); -extern "C" void modelCalc__14mDoExt_McaMorfFv(); -extern "C" void -__ct__16mDoExt_McaMorfSOFP12J3DModelDataP25mDoExt_McaMorfCallBack1_cP25mDoExt_McaMorfCallBack2_cP15J3DAnmTransformifiiP10Z2CreatureUlUl(); -extern "C" void setAnm__16mDoExt_McaMorfSOFP15J3DAnmTransformiffff(); -extern "C" void play__16mDoExt_McaMorfSOFUlSc(); -extern "C" void entryDL__16mDoExt_McaMorfSOFv(); -extern "C" void modelCalc__16mDoExt_McaMorfSOFv(); -extern "C" void stopZelAnime__16mDoExt_McaMorfSOFv(); -extern "C" void init__19mDoExt_3DlineMat1_cFUsUsP7ResTIMGi(); -extern "C" void update__19mDoExt_3DlineMat1_cFiR8_GXColorP12dKy_tevstr_c(); -extern "C" void setMat__26mDoExt_3DlineMatSortPacketFP18mDoExt_3DlineMat_c(); -extern "C" void cDmrNowMidnaTalk__Fv(); -extern "C" void __ct__10fopAc_ac_cFv(); -extern "C" void fopAcIt_Judge__FPFPvPv_PvPv(); -extern "C" void fopAcM_fastCreate__FsUlPC4cXyziPC5csXyzPC4cXyzScPFPv_iPv(); -extern "C" void fopAcM_entrySolidHeap__FP10fopAc_ac_cPFP10fopAc_ac_c_iUl(); -extern "C" void fopAcM_searchActorAngleY__FPC10fopAc_ac_cPC10fopAc_ac_c(); -extern "C" void fpcSch_JudgeByID__FPvPv(); -extern "C" void dComIfG_resLoad__FP30request_of_phase_process_classPCc(); -extern "C" void dComIfG_resDelete__FP30request_of_phase_process_classPCc(); -extern "C" void dComIfGp_getReverb__Fi(); -extern "C" void isSwitch__10dSv_info_cCFii(); -extern "C" void getRes__14dRes_control_cFPCclP11dRes_info_ci(); -extern "C" void __ct__10dCcD_GSttsFv(); -extern "C" void Init__9dCcD_SttsFiiP10fopAc_ac_c(); -extern "C" void __ct__12dCcD_GObjInfFv(); -extern "C" void ChkTgHit__12dCcD_GObjInfFv(); -extern "C" void GetTgHitObj__12dCcD_GObjInfFv(); -extern "C" void Set__8dCcD_SphFRC11dCcD_SrcSph(); -extern "C" void cc_at_check__FP10fopAc_ac_cP11dCcU_AtInfo(); -extern "C" void settingTevStruct__18dScnKy_env_light_cFiP4cXyzP12dKy_tevstr_c(); -extern "C" void setLightTevColorType_MAJI__18dScnKy_env_light_cFP12J3DModelDataP12dKy_tevstr_c(); -extern "C" void Set__4cCcSFP8cCcD_Obj(); -extern "C" void __pl__4cXyzCFRC3Vec(); -extern "C" void __mi__4cXyzCFRC3Vec(); -extern "C" void __ml__4cXyzCFf(); -extern "C" void cM_atan2s__Fff(); -extern "C" void cM_rndF__Ff(); -extern "C" void SetC__8cM3dGSphFRC4cXyz(); -extern "C" void SetR__8cM3dGSphFf(); -extern "C" void cLib_addCalc2__FPffff(); -extern "C" void cLib_addCalc0__FPfff(); -extern "C" void cLib_addCalcAngleS2__FPssss(); -extern "C" void MtxPosition__FP4cXyzP4cXyz(); -extern "C" void __ct__15Z2CreatureEnemyFv(); -extern "C" void init__15Z2CreatureEnemyFP3VecP3VecUcUc(); -extern "C" void* __nw__FUl(); -extern "C" void __dl__FPv(); -extern "C" void init__12J3DFrameCtrlFs(); -extern "C" void _savegpr_26(); -extern "C" void _savegpr_28(); -extern "C" void _savegpr_29(); -extern "C" void _restgpr_26(); -extern "C" void _restgpr_28(); -extern "C" void _restgpr_29(); -extern "C" extern void* __vt__19mDoExt_3DlineMat1_c[5]; -extern "C" extern void* __vt__8dCcD_Sph[36]; -extern "C" extern void* __vt__9dCcD_Stts[11]; -extern "C" extern void* __vt__12cCcD_SphAttr[25]; -extern "C" extern void* __vt__14cCcD_ShapeAttr[22]; -extern "C" extern void* __vt__9cCcD_Stts[8]; -extern "C" u8 now__14mDoMtx_stack_c[48]; -extern "C" extern u8 g_dComIfG_gameInfo[122384]; -extern "C" u8 sincosTable___5JMath[65536]; -extern "C" extern void* calc_mtx[1 + 1 /* padding */]; -extern "C" void __register_global_object(); +/* 80706260-807063B0 0001E0 0150+00 1/0 0/0 0/0 .text daE_MB_Draw__FP10e_mb_class */ +static int daE_MB_Draw(e_mb_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; -// -// Declarations: -// + if (i_this->mAction != ACTION_END) { + J3DModel* model = i_this->mpModelMorf->getModel(); + g_env_light.settingTevStruct(0, &a_this->current.pos, &a_this->tevStr); + g_env_light.setLightTevColorType_MAJI(model, &a_this->tevStr); -/* ############################################################################################## */ -/* 80708A10-80708A14 000000 0004+00 9/9 0/0 0/0 .rodata @3764 */ -SECTION_RODATA static f32 const lit_3764 = 1.0f; -COMPILER_STRIP_GATE(0x80708A10, &lit_3764); + i_this->mpBtp->entry(model->getModelData()); + i_this->mpModelMorf->entryDL(); -/* 80708A14-80708A18 000004 0004+00 0/2 0/0 0/0 .rodata @3765 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3765 = 50.0f; -COMPILER_STRIP_GATE(0x80708A14, &lit_3765); -#pragma pop + if (i_this->field_0x68c == 1) { + g_env_light.setLightTevColorType_MAJI(i_this->mpBombModelMorf->getModel(), &a_this->tevStr); + i_this->mpBombModelMorf->entryDL(); + } else if (i_this->field_0x68c == 2) { + g_env_light.setLightTevColorType_MAJI(i_this->mpBombModel2Morf->getModel(), &a_this->tevStr); + i_this->mpBombModel2Morf->entryDL(); + } + } -/* 80708A18-80708A1C 000008 0004+00 0/1 0/0 0/0 .rodata @3766 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3766 = 1.5f; -COMPILER_STRIP_GATE(0x80708A18, &lit_3766); -#pragma pop + static GXColor l_color = {0x14, 0x0F, 0x00, 0xFF}; + i_this->mRopeMat.update(16, l_color, &a_this->tevStr); + dComIfGd_set3DlineMat(&i_this->mRopeMat); + return 1; +} -/* 80708A1C-80708A20 00000C 0004+00 2/9 0/0 0/0 .rodata @3767 */ -SECTION_RODATA static u8 const lit_3767[4] = { - 0x00, - 0x00, - 0x00, - 0x00, -}; -COMPILER_STRIP_GATE(0x80708A1C, &lit_3767); +UNK_REL_BSS; -/* 80708A20-80708A24 000010 0004+00 0/1 0/0 0/0 .rodata @3768 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3768 = 70.0f; -COMPILER_STRIP_GATE(0x80708A20, &lit_3768); -#pragma pop +/* 80708C2D 0003+00 data_80708C2D None */ +static u8 l_initHIO; -/* 80708AF0-80708AF4 000000 0004+00 1/1 0/0 0/0 .data l_color$3793 */ -SECTION_DATA static u8 l_color[4] = { - 0x14, - 0x0F, - 0x00, - 0xFF, -}; +/* 80708C3C-80708C58 000054 001C+00 2/5 0/0 0/0 .bss l_HIO */ +static daE_MB_HIO_c l_HIO; -/* 80708AF4-80708B10 -00001 001C+00 1/1 0/0 0/0 .data @3884 */ -SECTION_DATA static void* lit_3884[7] = { - (void*)(((char*)e_mb_standby__FP10e_mb_class) + 0x6C), - (void*)(((char*)e_mb_standby__FP10e_mb_class) + 0xA4), - (void*)(((char*)e_mb_standby__FP10e_mb_class) + 0xC8), - (void*)(((char*)e_mb_standby__FP10e_mb_class) + 0x114), - (void*)(((char*)e_mb_standby__FP10e_mb_class) + 0x254), - (void*)(((char*)e_mb_standby__FP10e_mb_class) + 0x134), - (void*)(((char*)e_mb_standby__FP10e_mb_class) + 0x1B4), -}; +/* 80708C64-80708C70 00007C 000C+00 0/2 0/0 0/0 .bss L_pos1 */ +static cXyz L_pos1(-2575.0f, 1050.0f, 1060.0f); -/* 80708B10-80708B50 000020 0040+00 1/1 0/0 0/0 .data cc_sph_src$4733 */ -static dCcD_SrcSph cc_sph_src = { - { - {0x0, {{0x0, 0x0, 0x0}, {0xd8fbfdff, 0x3}, 0x0}}, // mObj - {dCcD_SE_NONE, 0x0, 0x0, 0x0, 0x0}, // mGObjAt - {dCcD_SE_NONE, 0x0, 0x0, 0x0, 0x2}, // mGObjTg - {0x0}, // mGObjCo - }, // mObjInf - { - {{0.0f, 0.0f, 0.0f}, 60.0f} // mSph - } // mSphAttr -}; +/* 80708C7C-80708C88 000094 000C+00 1/3 0/0 0/0 .bss L_pos2 */ +static cXyz L_pos2(-1944.0f, 1050.0f, 1060.0f); + +/* 80708C94-80708CA0 0000AC 000C+00 0/2 0/0 0/0 .bss L_Hpos */ +static cXyz L_Hpos(-1923.0f, 1432.0f, 1060.0f); + +/* 80708CAC-80708CB8 0000C4 000C+00 0/3 0/0 0/0 .bss R_pos1 */ +static cXyz R_pos1(2606.0f, 1050.0f, 1070.0f); + +/* 80708CC4-80708CD0 0000DC 000C+00 2/4 0/0 0/0 .bss R_pos2 */ +static cXyz R_pos2(2126.0f, 1050.0f, 1070.0f); + +/* 80708CDC-80708CE8 0000F4 000C+00 0/2 0/0 0/0 .bss R_Hpos */ +static cXyz R_Hpos(2099.0f, 1432.0f, 1070.0f); + +/* 80708CF4-80708D00 00010C 000C+00 0/1 0/0 0/0 .bss c_pos */ +static cXyz c_pos(0.0f, 1011.0f, 1060.0f); + +/* 807063B0-8070661C 000330 026C+00 2/1 0/0 0/0 .text e_mb_standby__FP10e_mb_class */ +static void e_mb_standby(e_mb_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + b_bq_class* bq_p = (b_bq_class*)fopAcM_SearchByID(a_this->parentActorID); + + if (bq_p != NULL) { + switch (i_this->mMode) { + case 0: + a_this->current.pos = R_pos1; + if (!bq_p->mDisableDraw) { + i_this->mMode++; + } + break; + case 1: + if (bq_p->field_0x6ec == 0) { + i_this->mTimers[0] = 60; + i_this->mMode++; + } + break; + case 2: + if (i_this->mTimers[0] == 0) { + i_this->mTimers[0] = 60; + i_this->mSound.startCreatureVoice(Z2SE_MK_V_DEMO_HELP_APPEAR, -1); + i_this->mMode++; + } + break; + case 3: + if (i_this->mTimers[0] == 0) { + bq_p->mDemoMode = 30; + i_this->mMode = 5; + } + break; + case 5: + if (bq_p->field_0x6fb == 1) { + i_this->mTimers[0] = cM_rndF(100.0f) + 250.0f; + } else if (bq_p->field_0x6fb == 2) { + i_this->mTimers[0] = cM_rndF(30.0f) + 125.0f + 50.0f; + } + + if (i_this->mTimers[0] == 0) { + i_this->mMode++; + } + break; + case 6: + if (i_this->field_0x6b0 == 0) { + a_this->current.pos = L_pos1; + i_this->field_0x5b8 = L_pos2; + } else { + a_this->current.pos = R_pos1; + i_this->field_0x5b8 = R_pos2; + } + + i_this->mAction = ACTION_WALK1; + i_this->mMode = 0; + + if (i_this->field_0x8c8 != 0) { + i_this->field_0x68c = 1; + } + break; + } + } +} + +/* 8070661C-80706898 00059C 027C+00 1/1 0/0 0/0 .text e_mb_walk1__FP10e_mb_class */ +static void e_mb_walk1(e_mb_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + + cXyz sp18; + sp18 = i_this->field_0x5b8 - i_this->current.pos; + + switch (i_this->mMode) { + case 0: + anm_init(i_this, ANM_MB_WALK, 5.0f, 2, 1.0f); + i_this->mMode++; + i_this->mTimers[0] = 100; + i_this->mSound.startCreatureVoice(Z2SE_MK_V_COME_BACK, -1); + /* fallthrough */ + case 1: + a_this->current.angle.y = cM_atan2s(sp18.x, sp18.z); + a_this->current.angle.x = -cM_atan2s(sp18.y, JMAFastSqrt((sp18.x * sp18.x) + (sp18.z * sp18.z))); + a_this->speedF = 15.0f + TREG_F(10); + + if (sp18.abs() <= 20.0f + TREG_F(10)) { + if (i_this->field_0x6b0 != 0) { + i_this->field_0x5b8 = L_pos2; + } else { + i_this->field_0x5b8 = R_pos2; + } + + i_this->mAction = ACTION_MOVE; + i_this->mMode = 0; + i_this->mTimers[2] = 90; + } + break; + } +} + +/* 807068D4-80706F90 000854 06BC+00 1/1 0/0 0/0 .text e_mb_move__FP10e_mb_class */ +static s8 e_mb_move(e_mb_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + + cXyz sp24; + sp24 = i_this->field_0x5b8 - i_this->current.pos; + + f32 anm_frame = i_this->mpModelMorf->getFrame(); + s8 var_r28 = 0; + + switch (i_this->mMode) { + case 0: + anm_init(i_this, ANM_MB_CATCH, 3.0f, 0, 1.0f); + i_this->mMode++; + i_this->speedF = 0.0f; + i_this->field_0x6a4 = i_this->current.pos; + break; + case 1: + if (i_this->mpModelMorf->isStop()) { + anm_init(i_this, ANM_MB_ROPE_WAIT_A_START, 3.0f, 0, 1.0f); + i_this->mMode = 2; + i_this->field_0x6b0 = i_this->field_0x6b0 == 0; + i_this->mSound.startCreatureVoice(Z2SE_MK_V_ROPE_START, -1); + } + break; + case 2: + if (i_this->mAnm == ANM_MB_ROPE_WAIT_FLYOUT && i_this->mpModelMorf->isStop()) { + anm_init(i_this, ANM_MB_ROPE_WAIT_A_START, 5.0f, 0, 1.0f); + } + + if (i_this->field_0x68c == 0) { + if (i_this->mAnm == ANM_MB_ROPE_WAIT_A_START) { + anm_init(i_this, ANM_MB_ROPE_WAIT_B_START, 2.0f, 0, 1.0f); + i_this->mpModelMorf->setFrame(anm_frame); + } else if (i_this->mAnm == ANM_MB_ROPE_WAIT_A_END) { + anm_init(i_this, ANM_MB_ROPE_WAIT_B_END, 2.0f, 0, 1.0f); + i_this->mpModelMorf->setFrame(anm_frame); + } + } else { + i_this->mSound.startCreatureVoiceLevel(Z2SE_MK_V_SWINGING, -1); + } + + i_this->mSound.startCreatureSoundLevel(Z2SE_MK_ROPE_SWING, 0, -1); + i_this->current.angle.y = cM_atan2s(sp24.x, sp24.z); + i_this->current.angle.x = -cM_atan2s(sp24.y, JMAFastSqrt((sp24.x * sp24.x) + (sp24.z * sp24.z))); + cLib_addCalc2(&i_this->speedF, l_HIO.swing_speed, 1.0f, 1.0f + (0.1f * l_HIO.swing_speed)); + + if (i_this->field_0x68c == 0) { + if (sp24.abs() <= 400.0f + TREG_F(14) && i_this->mAnm != ANM_MB_LANDING) { + anm_init(i_this, ANM_MB_LANDING, 5.0f, 0, 1.0f); + } + } + + if (sp24.abs() <= 1.1f * i_this->speedF) { + i_this->current.pos = i_this->field_0x5b8; + + if (i_this->field_0x68c == 1) { + i_this->field_0x6b0 = (i_this->field_0x6b0 == 0); + if (i_this->field_0x6b0 == 0) { + i_this->field_0x5b8 = L_pos2; + } else { + i_this->field_0x5b8 = R_pos2; + } + + i_this->field_0x6a4 = i_this->current.pos; + } else { + if (i_this->field_0x6b0 == 0) { + i_this->field_0x5b8 = L_pos1; + } else { + i_this->field_0x5b8 = R_pos1; + } + + i_this->mAction = ACTION_WALK2; + i_this->mMode = 0; + i_this->mSound.startCreatureSound(Z2SE_EN_MK_FOOTNOTE, 0, -1); + } + + i_this->speedF = 0.0f; + } + break; + } + + if (i_this->speedF > 1.0f) { + var_r28 = 1; + } + + return var_r28; +} + +/* 80706F90-8070723C 000F10 02AC+00 1/1 0/0 0/0 .text e_mb_walk2__FP10e_mb_class */ +static void e_mb_walk2(e_mb_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + + b_bq_class* bq_p = (b_bq_class*)fopAcM_SearchByID(i_this->parentActorID); + if (bq_p != NULL) { + cXyz sp14; + sp14 = i_this->field_0x5b8 - i_this->current.pos; + + switch (i_this->mMode) { + case 0: + if (i_this->mpModelMorf->isStop()) { + if (i_this->field_0x8c8 == 0) { + bq_p->mDemoMode++; + i_this->mAction = ACTION_FIRST_DEMO; + i_this->mMode = 0; + i_this->field_0x8c8 = 1; + } else { + anm_init(i_this, ANM_MB_RUN, 3.0f, 2, 1.0f); + i_this->mMode++; + } + } + break; + case 1: + i_this->current.angle.y = cM_atan2s(sp14.x, sp14.z); + i_this->current.angle.x = -cM_atan2s(sp14.y, JMAFastSqrt((sp14.x * sp14.x) + (sp14.z * sp14.z))); + i_this->speedF = 25.0f + TREG_F(10); + + if (sp14.abs() <= 30.0f + TREG_F(10)) { + i_this->mAction = ACTION_STANDBY; + i_this->mMode = 5; + i_this->mTimers[0] = l_HIO.reappear_time + cM_rndF(0.5f * l_HIO.reappear_time); + } + break; + } + } +} + +/* 8070723C-80707560 0011BC 0324+00 1/1 0/0 0/0 .text e_mb_firstdemo__FP10e_mb_class */ +static void e_mb_firstdemo(e_mb_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + b_bq_class* bq_p = (b_bq_class*)fopAcM_SearchByID(i_this->parentActorID); + + if (bq_p != NULL) { + cXyz sp20; + sp20 = i_this->field_0x5b8 - i_this->current.pos; + + switch (i_this->mMode) { + case 0: + anm_init(i_this, ANM_MB_DEMO_SIGNAL, 5.0f, 2, 1.0f); + i_this->current.angle.y += 0x8000; + i_this->mMode++; + i_this->mTimers[0] = 30; + i_this->mSound.startCreatureVoice(Z2SE_MK_V_D_DELIGHT, -1); + break; + case 1: + if (i_this->mTimers[0] == 0) { + anm_init(i_this, ANM_MB_DEMO_TURN_CATCH, 5.0f, 0, 1.0f); + i_this->mMode++; + } + break; + case 2: + if (i_this->mpModelMorf->isStop()) { + anm_init(i_this, ANM_MB_DEMO_SHOW_BOMB, 5.0f, 0, 1.0f); + i_this->mpBombModel2Morf->setAnm((J3DAnmTransform*)dComIfG_getObjectRes("E_mb", 0x14), 0, 5.0f, 1.0f, 0.0f, -1.0f, NULL); + i_this->field_0x68c = 2; + i_this->mMode++; + i_this->mTimers[0] = 120; + i_this->mSound.startCreatureVoice(Z2SE_MK_V_D_BOMB_SHOW, -1); + } + break; + case 4: + i_this->field_0x5b8 = R_pos2; + i_this->field_0x68c = 1; + i_this->speedF = 0.0f; + anm_init(i_this, ANM_MB_CATCH, 0.0f, 0, 1.0f); + i_this->mMode = 5; + break; + case 5: + if (i_this->mpModelMorf->isStop()) { + i_this->mAction = ACTION_MOVE; + anm_init(i_this, ANM_MB_ROPE_WAIT_FLYOUT, 0.0f, 0, 1.0f); + i_this->field_0x6a4 = i_this->current.pos; + i_this->mMode = 2; + i_this->field_0x6b0 = i_this->field_0x6b0 == 0; + i_this->mSound.startCreatureVoice(Z2SE_MK_V_ROPE_START, -1); + } + break; + } + } +} + +/* 80707560-80707570 0014E0 0010+00 1/1 0/0 0/0 .text e_mb_end__FP10e_mb_class */ +static void e_mb_end(e_mb_class* i_this) { + i_this->current.pos.y = 20000.0f; +} + +/* 80707570-80707680 0014F0 0110+00 1/1 0/0 0/0 .text action__FP10e_mb_class */ +static s8 action(e_mb_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + + cXyz sp8; + s8 var_r29 = 0; + + switch (i_this->mAction) { + case ACTION_STANDBY: + e_mb_standby(i_this); + break; + case ACTION_WALK1: + e_mb_walk1(i_this); + break; + case ACTION_MOVE: + var_r29 = e_mb_move(i_this); + break; + case ACTION_WALK2: + e_mb_walk2(i_this); + break; + case ACTION_FIRST_DEMO: + e_mb_firstdemo(i_this); + break; + case ACTION_END: + e_mb_end(i_this); + break; + } + + cMtx_YrotS(*calc_mtx, a_this->current.angle.y); + cMtx_XrotM(*calc_mtx, a_this->current.angle.x); + sp8.x = 0.0f; + sp8.y = 0.0f; + sp8.z = a_this->speedF; + MtxPosition(&sp8, &a_this->speed); + a_this->current.pos += a_this->speed; + + cLib_addCalcAngleS2(&a_this->shape_angle.y, a_this->current.angle.y, 4, 0x800); + return var_r29; +} + +/* 80707680-80708148 001600 0AC8+00 2/1 0/0 0/0 .text daE_MB_Execute__FP10e_mb_class */ +static int daE_MB_Execute(e_mb_class* i_this) { + if (cDmrNowMidnaTalk()) { + return 1; + } + + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + + cXyz spE4; + cXyz spD8; + cXyz spCC; + + i_this->mCounter++; + + for (int i = 0; i < 3; i++) { + if (i_this->mTimers[i] != 0) { + i_this->mTimers[i]--; + } + } + + if (i_this->field_0x6a2 != 0) { + i_this->field_0x6a2--; + } + + f32 var_f31 = 0.0f; + + if (action(i_this) == 1) { + spE4 = i_this->field_0x5b8 - i_this->field_0x6a4; + f32 temp_f30 = spE4.abs(); + + spE4 = i_this->field_0x5b8 - i_this->current.pos; + + f32 temp_r29 = spE4.abs(); + f32 temp_f28 = temp_f30 * ((0.1f * l_HIO.swing_descend) + BREG_F(19)); + s16 spA = 32768.0f * (temp_r29 / temp_f30); + + var_f31 = temp_f28 * cM_ssin(spA); + + if (cM_scos(spA) > -0.3f + KREG_F(16)) { + if (i_this->mAnm == ANM_MB_ROPE_WAIT_A_START) { + anm_init(i_this, ANM_MB_ROPE_WAIT_A_END, 35.0f + KREG_F(17), 0, 1.0f); + } else if (i_this->mAnm == ANM_MB_ROPE_WAIT_B_START) { + anm_init(i_this, ANM_MB_ROPE_WAIT_B_END, 35.0f + KREG_F(17), 0, 1.0f); + } + } else if (i_this->mAnm == ANM_MB_ROPE_WAIT_A_END) { + anm_init(i_this, ANM_MB_ROPE_WAIT_A_START, 10.0f + KREG_F(18), 0, 1.0f); + } else if (i_this->mAnm == ANM_MB_ROPE_WAIT_B_END) { + anm_init(i_this, ANM_MB_ROPE_WAIT_B_START, 10.0f + KREG_F(18), 0, 1.0f); + } + } else { + cLib_addCalcAngleS2(&i_this->shape_angle.x, 0, 1, 0x400); + } + + mDoMtx_stack_c::transS(i_this->current.pos.x, i_this->current.pos.y - var_f31, i_this->current.pos.z + l_HIO.swing_correction); + mDoMtx_stack_c::YrotM(i_this->shape_angle.y); + mDoMtx_stack_c::XrotM(i_this->shape_angle.x); + mDoMtx_stack_c::ZrotM(i_this->shape_angle.z); + mDoMtx_stack_c::scaleM(l_HIO.base_size, l_HIO.base_size, l_HIO.base_size); + + J3DModel* model = i_this->mpModelMorf->getModel(); + model->setBaseTRMtx(mDoMtx_stack_c::get()); + + i_this->mpModelMorf->play(0, dComIfGp_getReverb(fopAcM_GetRoomNo(i_this))); + + if (i_this->field_0x5d4 == 0) { + i_this->field_0x5d4 = 30.0f + cM_rndF(60.0f); + } else { + i_this->field_0x5d4--; + if (i_this->field_0x5d4 <= 12) { + i_this->mBtpFrame = 12 - i_this->field_0x5d4; + } else { + i_this->mBtpFrame = 0.0f; + } + } + + i_this->mpBtp->setFrame(i_this->mBtpFrame); + i_this->mpModelMorf->modelCalc(); + + MtxPtr temp_r27 = mDoMtx_stack_c::get(); + MTXCopy(i_this->mpModelMorf->getModel()->getAnmMtx(0x16), temp_r27); + + spE4.set(JREG_F(2), JREG_F(3), JREG_F(4)); + mDoMtx_stack_c::multVec(&spE4, &i_this->field_0x5dc); + + fopAcM_OffStatus(i_this, 0); + i_this->attention_info.flags = 0; + + if (i_this->field_0x68c != 0) { + if (i_this->field_0x68c == 1) { + temp_r27 = mDoMtx_stack_c::get(); + MTXCopy(i_this->mpModelMorf->getModel()->getAnmMtx(0x1C), temp_r27); + + mDoMtx_stack_c::transM(60.0f + JREG_F(17), -35.0f + JREG_F(18), 15.0f + JREG_F(19)); + mDoMtx_stack_c::XrotM(AREG_S(1) - 500); + mDoMtx_stack_c::ZrotM(AREG_S(2) + 20500); + + temp_r27 = mDoMtx_stack_c::get(); + i_this->mpBombModelMorf->getModel()->setBaseTRMtx(temp_r27); + i_this->mpBombModelMorf->modelCalc(); + mDoMtx_stack_c::multVecZero(&spD8); + + i_this->mCcSph.SetC(spD8); + + if (dComIfGp_checkPlayerStatus0(0, 0x80000)) { + i_this->mCcSph.SetR(400.0f + YREG_F(13)); + } else { + i_this->mCcSph.SetR(100.0f); + } + + i_this->eyePos = spD8; + + if (i_this->mCcSph.ChkTgHit()) { + i_this->field_0x6a2 = 10; + i_this->mAtInfo.mpCollider = i_this->mCcSph.GetTgHitObj(); + cc_at_check(i_this, &i_this->mAtInfo); + + if (i_this->mAtInfo.mpCollider->ChkAtType(AT_TYPE_BOOMERANG)) { + dBomb_c::createEnemyBombBoomerang(&i_this->eyePos, &i_this->current.angle, fopAcM_GetRoomNo(i_this)); + i_this->field_0x68c = 0; + i_this->mSound.startCreatureVoice(Z2SE_MK_V_LOSE_BOMB, -1); + } + } + + cMtx_YrotS(*calc_mtx, fopAcM_searchPlayerAngleY(i_this)); + spE4.x = 0.0f; + spE4.y = 50.0f + TREG_F(14); + spE4.z = 150.0f + TREG_F(15); + MtxPosition(&spE4, &i_this->attention_info.position); + i_this->attention_info.position += i_this->eyePos; + + fopAcM_OnStatus(i_this, 0); + i_this->attention_info.flags = 4; + } else { + i_this->mpBombModel2Morf->play(NULL, 0, 0); + + temp_r27 = mDoMtx_stack_c::get(); + MTXCopy(i_this->mpModelMorf->getModel()->getAnmMtx(0x15), temp_r27); + + temp_r27 = mDoMtx_stack_c::get(); + i_this->mpBombModel2Morf->getModel()->setBaseTRMtx(temp_r27); + i_this->mpBombModel2Morf->modelCalc(); + + spD8.set(-20000.0f, 40000.0f, 55000.0f); + i_this->mCcSph.SetC(spD8); + i_this->eyePos = i_this->current.pos; + i_this->eyePos.y += 200.0f; + } + } else { + i_this->eyePos = i_this->current.pos; + i_this->eyePos.y += 200.0f; + spD8.set(-20000.0f, 40000.0f, 55000.0f); + i_this->mCcSph.SetC(spD8); + } + + dComIfG_Ccsp()->Set(&i_this->mCcSph); + + cXyz spC0; + cXyz spB4(L_Hpos); + cXyz spA8(R_Hpos); + + spC0 = spB4 + ((spA8 - spB4) * 0.5f); + spC0.y += 1800.0f + JREG_F(8); + + cXyz* rope_pos = i_this->mRopeMat.getPos(0); + cXyz sp9C; + + if (i_this->mAction == ACTION_MOVE && i_this->mMode >= 2) { + sp9C = spC0 - i_this->field_0x5dc; + cLib_addCalc0(&i_this->field_0x6f0, 1.0f, 30.0f); + } else { + if (i_this->field_0x6b0 == 0) { + sp9C = spC0 - spB4; + } else { + sp9C = spC0 - spA8; + } + + cLib_addCalc2(&i_this->field_0x6f0, -500.0f, 0.1f, 20.0f); + } + + sp9C *= (1.0f / 15.0f); + + for (int i = 0; i < 16; i++, rope_pos++) { + *rope_pos = spC0 - (sp9C * (f32)i); + + s16 sp8 = 32768.0f * (i / 15.0f); + rope_pos->y += i_this->field_0x6f0 * cM_ssin(sp8); + } + + return 1; +} + +/* 80708148-80708150 0020C8 0008+00 1/0 0/0 0/0 .text daE_MB_IsDelete__FP10e_mb_class */ +static int daE_MB_IsDelete(e_mb_class* i_this) { + return 1; +} + +/* 80708150-807081B8 0020D0 0068+00 1/0 0/0 0/0 .text daE_MB_Delete__FP10e_mb_class */ +static int daE_MB_Delete(e_mb_class* i_this) { + fopAc_ac_c* a_this = (fopAc_ac_c*)i_this; + fpc_ProcID id = fopAcM_GetID(a_this); + + dComIfG_resDelete(&i_this->mPhase, "E_mb"); + + if (i_this->mInitHIO) { + l_initHIO = false; + mDoHIO_DELETE_CHILD(l_HIO.no); + } + + if (a_this->heap != NULL) { + i_this->mpModelMorf->stopZelAnime(); + } + + return 1; +} + +/* 807081B8-8070853C 002138 0384+00 1/1 0/0 0/0 .text useHeapInit__FP10fopAc_ac_c */ +static int useHeapInit(fopAc_ac_c* i_this) { + e_mb_class* a_this = (e_mb_class*)i_this; + + a_this->mpModelMorf = new mDoExt_McaMorfSO((J3DModelData*)dComIfG_getObjectRes("E_mb", 0x19), NULL, NULL, (J3DAnmTransform*)dComIfG_getObjectRes("E_mb", 10), 0, 1.0f, 0, -1, &a_this->mSound, 0x80000, 0x11020084); + if (a_this->mpModelMorf == NULL || a_this->mpModelMorf->getModel() == NULL) { + return 0; + } + + a_this->mpBtp = new mDoExt_btpAnm(); + if (a_this->mpBtp == NULL) { + return cPhs_ERROR_e; + } + + J3DAnmTexPattern* btp = (J3DAnmTexPattern*)dComIfG_getObjectRes("E_mb", 0x1E); + if (!a_this->mpBtp->init(a_this->mpModelMorf->getModel()->getModelData(), btp, TRUE, 0, 1.0f, 0, -1)) { + return cPhs_ERROR_e; + } + + a_this->mpBombModelMorf = new mDoExt_McaMorf((J3DModelData*)dComIfG_getObjectRes("E_mb", 0x1B), NULL, NULL, (J3DAnmTransform*)dComIfG_getObjectRes("E_mb", 0x15), 0, 1.0f, 0, 1, 0, &a_this->mSound, 0x80000, 0x11000084); + if (a_this->mpBombModelMorf == NULL || a_this->mpBombModelMorf->getModel() == NULL) { + return 0; + } + + a_this->mpBombModel2Morf = new mDoExt_McaMorf((J3DModelData*)dComIfG_getObjectRes("E_mb", 0x1A), NULL, NULL, (J3DAnmTransform*)dComIfG_getObjectRes("E_mb", 0x14), 0, 1.0f, 0, 1, 0, &a_this->mSound, 0x80000, 0x11000084); + if (a_this->mpBombModel2Morf == NULL || a_this->mpBombModel2Morf->getModel() == NULL) { + return 0; + } + + if (!a_this->mRopeMat.init(1, 16, (ResTIMG*)dComIfG_getObjectRes("E_mb", 0x21), 1)) { + return 0; + } + + f32* size_p = a_this->mRopeMat.getSize(0); + for (int i = 0; i < 16; i++) { + *size_p = (XREG_S(0) * 0.1f) + 10.0f; + size_p++; + } + + return 1; +} + +/* 80708584-8070879C 002504 0218+00 1/0 0/0 0/0 .text daE_MB_Create__FP10fopAc_ac_c */ +static int daE_MB_Create(fopAc_ac_c* i_this) { + e_mb_class* a_this = (e_mb_class*)i_this; + fopAcM_SetupActor(a_this, e_mb_class); + + int phase_state = dComIfG_resLoad(&a_this->mPhase, "E_mb"); + if (phase_state == cPhs_COMPLEATE_e) { + OS_REPORT("E_MB PARAM %x\n", fopAcM_GetParam(i_this)); + + u8 swbit = (fopAcM_GetParam(i_this) >> 0x18) & 0xFF; + if (swbit != 0xFF && dComIfGs_isSwitch(swbit, fopAcM_GetRoomNo(i_this))) { + OS_REPORT("E_MB やられ後なので再セットしません\n"); + return cPhs_ERROR_e; + } + + a_this->field_0x5b6 = fopAcM_GetParam(i_this) & 0xFF; + + OS_REPORT("E_MB//////////////E_MB SET 1 !!\n"); + + if (!fopAcM_entrySolidHeap(i_this, useHeapInit, 0x58A0)) { + OS_REPORT("//////////////E_MB SET NON !!\n"); + return cPhs_ERROR_e; + } + + if (!l_initHIO) { + a_this->mInitHIO = TRUE; + l_initHIO = TRUE; + l_HIO.no = mDoHIO_CREATE_CHILD("ボス戦ブーメラン猿", &l_HIO); + } + + a_this->mSound.init(&i_this->current.pos, &i_this->eyePos, 3, 1); + a_this->mAtInfo.mpSound = &a_this->mSound; + + a_this->mColliderStts.Init(0xFF, 0, i_this); + + static dCcD_SrcSph cc_sph_src = { + { + {0x0, {{0x0, 0x0, 0x0}, {0xd8fbfdff, 0x3}, 0x0}}, // mObj + {dCcD_SE_NONE, 0x0, 0x0, 0x0, 0x0}, // mGObjAt + {dCcD_SE_NONE, 0x0, 0x0, 0x0, 0x2}, // mGObjTg + {0x0}, // mGObjCo + }, // mObjInf + { + {{0.0f, 0.0f, 0.0f}, 60.0f} // mSph + } // mSphAttr + }; + + a_this->mCcSph.Set(cc_sph_src); + a_this->mCcSph.SetStts(&a_this->mColliderStts); + + i_this->attention_info.flags = 4; + i_this->attention_info.distances[fopAc_attn_BATTLE_e] = 22; + a_this->field_0x6b0 = 1; + daE_MB_Execute(a_this); + } + + return phase_state; +} /* 80708B50-80708B70 -00001 0020+00 1/0 0/0 0/0 .data l_daE_MB_Method */ static actor_method_class l_daE_MB_Method = { - (process_method_func)daE_MB_Create__FP10fopAc_ac_c, - (process_method_func)daE_MB_Delete__FP10e_mb_class, - (process_method_func)daE_MB_Execute__FP10e_mb_class, - (process_method_func)daE_MB_IsDelete__FP10e_mb_class, - (process_method_func)daE_MB_Draw__FP10e_mb_class, + (process_method_func)daE_MB_Create, + (process_method_func)daE_MB_Delete, + (process_method_func)daE_MB_Execute, + (process_method_func)daE_MB_IsDelete, + (process_method_func)daE_MB_Draw, }; /* 80708B70-80708BA0 -00001 0030+00 0/0 0/0 1/0 .data g_profile_E_MB */ @@ -218,830 +785,4 @@ extern actor_process_profile_definition g_profile_E_MB = { fopAc_CULLBOX_CUSTOM_e, // cullType }; -/* 80708BA0-80708BAC 0000B0 000C+00 2/2 0/0 0/0 .data __vt__8cM3dGSph */ -SECTION_DATA extern void* __vt__8cM3dGSph[3] = { - (void*)NULL /* RTTI */, - (void*)NULL, - (void*)__dt__8cM3dGSphFv, -}; - -/* 80708BAC-80708BB8 0000BC 000C+00 2/2 0/0 0/0 .data __vt__8cM3dGAab */ -SECTION_DATA extern void* __vt__8cM3dGAab[3] = { - (void*)NULL /* RTTI */, - (void*)NULL, - (void*)__dt__8cM3dGAabFv, -}; - -/* 80708BB8-80708BCC 0000C8 0014+00 1/1 0/0 0/0 .data __vt__18mDoExt_3DlineMat_c */ -SECTION_DATA extern void* __vt__18mDoExt_3DlineMat_c[5] = { - (void*)NULL /* RTTI */, (void*)NULL, (void*)NULL, (void*)NULL, (void*)NULL, -}; - -/* 80708BCC-80708BD8 0000DC 000C+00 2/2 0/0 0/0 .data __vt__12J3DFrameCtrl */ -SECTION_DATA extern void* __vt__12J3DFrameCtrl[3] = { - (void*)NULL /* RTTI */, - (void*)NULL, - (void*)__dt__12J3DFrameCtrlFv, -}; - -/* 80708BD8-80708BE4 0000E8 000C+00 2/2 0/0 0/0 .data __vt__12daE_MB_HIO_c */ -SECTION_DATA extern void* __vt__12daE_MB_HIO_c[3] = { - (void*)NULL /* RTTI */, - (void*)NULL, - (void*)__dt__12daE_MB_HIO_cFv, -}; - -/* 8070616C-807061B4 0000EC 0048+00 1/1 0/0 0/0 .text __ct__12daE_MB_HIO_cFv */ -daE_MB_HIO_c::daE_MB_HIO_c() { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 80708A24-80708A28 000014 0004+00 1/2 0/0 0/0 .rodata @3782 */ -SECTION_RODATA static f32 const lit_3782 = -1.0f; -COMPILER_STRIP_GATE(0x80708A24, &lit_3782); - -/* 80708AE8-80708AE8 0000D8 0000+00 0/0 0/0 0/0 .rodata @stringBase0 */ -#pragma push -#pragma force_active on -SECTION_DEAD static char const* const stringBase_80708AE8 = "E_mb"; -#pragma pop - -/* 807061B4-80706260 000134 00AC+00 5/5 0/0 0/0 .text anm_init__FP10e_mb_classifUcf */ -static void anm_init(e_mb_class* param_0, int param_1, f32 param_2, u8 param_3, f32 param_4) { - // NONMATCHING -} - -/* 80706260-807063B0 0001E0 0150+00 1/0 0/0 0/0 .text daE_MB_Draw__FP10e_mb_class */ -static void daE_MB_Draw(e_mb_class* param_0) { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 80708BF0-80708BF4 000008 0001+03 4/4 0/0 0/0 .bss @1109 */ -static u8 lit_1109[1 + 3 /* padding */]; - -/* 80708BF4-80708BF8 00000C 0001+03 0/0 0/0 0/0 .bss @1107 */ -#pragma push -#pragma force_active on -static u8 lit_1107[1 + 3 /* padding */]; -#pragma pop - -/* 80708BF8-80708BFC 000010 0001+03 0/0 0/0 0/0 .bss @1105 */ -#pragma push -#pragma force_active on -static u8 lit_1105[1 + 3 /* padding */]; -#pragma pop - -/* 80708BFC-80708C00 000014 0001+03 0/0 0/0 0/0 .bss @1104 */ -#pragma push -#pragma force_active on -static u8 lit_1104[1 + 3 /* padding */]; -#pragma pop - -/* 80708C00-80708C04 000018 0001+03 0/0 0/0 0/0 .bss @1099 */ -#pragma push -#pragma force_active on -static u8 lit_1099[1 + 3 /* padding */]; -#pragma pop - -/* 80708C04-80708C08 00001C 0001+03 0/0 0/0 0/0 .bss @1097 */ -#pragma push -#pragma force_active on -static u8 lit_1097[1 + 3 /* padding */]; -#pragma pop - -/* 80708C08-80708C0C 000020 0001+03 0/0 0/0 0/0 .bss @1095 */ -#pragma push -#pragma force_active on -static u8 lit_1095[1 + 3 /* padding */]; -#pragma pop - -/* 80708C0C-80708C10 000024 0001+03 0/0 0/0 0/0 .bss @1094 */ -#pragma push -#pragma force_active on -static u8 lit_1094[1 + 3 /* padding */]; -#pragma pop - -/* 80708C10-80708C14 000028 0001+03 0/0 0/0 0/0 .bss @1057 */ -#pragma push -#pragma force_active on -static u8 lit_1057[1 + 3 /* padding */]; -#pragma pop - -/* 80708C14-80708C18 00002C 0001+03 0/0 0/0 0/0 .bss @1055 */ -#pragma push -#pragma force_active on -static u8 lit_1055[1 + 3 /* padding */]; -#pragma pop - -/* 80708C18-80708C1C 000030 0001+03 0/0 0/0 0/0 .bss @1053 */ -#pragma push -#pragma force_active on -static u8 lit_1053[1 + 3 /* padding */]; -#pragma pop - -/* 80708C1C-80708C20 000034 0001+03 0/0 0/0 0/0 .bss @1052 */ -#pragma push -#pragma force_active on -static u8 lit_1052[1 + 3 /* padding */]; -#pragma pop - -/* 80708C20-80708C24 000038 0001+03 0/0 0/0 0/0 .bss @1014 */ -#pragma push -#pragma force_active on -static u8 lit_1014[1 + 3 /* padding */]; -#pragma pop - -/* 80708C24-80708C28 00003C 0001+03 0/0 0/0 0/0 .bss @1012 */ -#pragma push -#pragma force_active on -static u8 lit_1012[1 + 3 /* padding */]; -#pragma pop - -/* 80708C28-80708C2C 000040 0001+03 0/0 0/0 0/0 .bss @1010 */ -#pragma push -#pragma force_active on -static u8 lit_1010[1 + 3 /* padding */]; -#pragma pop - -/* 80708C2C-80708C30 -00001 0004+00 2/2 0/0 0/0 .bss None */ -/* 80708C2C 0001+00 data_80708C2C @1009 */ -/* 80708C2D 0003+00 data_80708C2D None */ -static u8 struct_80708C2C[4]; - -/* 80708C30-80708C3C 000048 000C+00 0/1 0/0 0/0 .bss @3759 */ -#pragma push -#pragma force_active on -static u8 lit_3759[12]; -#pragma pop - -/* 80708C3C-80708C58 000054 001C+00 2/5 0/0 0/0 .bss l_HIO */ -static u8 l_HIO[28]; - -/* 80708C58-80708C64 000070 000C+00 0/1 0/0 0/0 .bss @3824 */ -#pragma push -#pragma force_active on -static u8 lit_3824[12]; -#pragma pop - -/* 80708C64-80708C70 00007C 000C+00 0/2 0/0 0/0 .bss L_pos1 */ -#pragma push -#pragma force_active on -static u8 L_pos1[12]; -#pragma pop - -/* 80708C70-80708C7C 000088 000C+00 0/1 0/0 0/0 .bss @3825 */ -#pragma push -#pragma force_active on -static u8 lit_3825[12]; -#pragma pop - -/* 80708C7C-80708C88 000094 000C+00 1/3 0/0 0/0 .bss L_pos2 */ -static u8 L_pos2[12]; - -/* 80708C88-80708C94 0000A0 000C+00 0/1 0/0 0/0 .bss @3826 */ -#pragma push -#pragma force_active on -static u8 lit_3826[12]; -#pragma pop - -/* 80708C94-80708CA0 0000AC 000C+00 0/2 0/0 0/0 .bss L_Hpos */ -#pragma push -#pragma force_active on -static u8 L_Hpos[12]; -#pragma pop - -/* 80708CA0-80708CAC 0000B8 000C+00 0/1 0/0 0/0 .bss @3827 */ -#pragma push -#pragma force_active on -static u8 lit_3827[12]; -#pragma pop - -/* 80708CAC-80708CB8 0000C4 000C+00 0/3 0/0 0/0 .bss R_pos1 */ -#pragma push -#pragma force_active on -static u8 R_pos1[12]; -#pragma pop - -/* 807063B0-8070661C 000330 026C+00 2/1 0/0 0/0 .text e_mb_standby__FP10e_mb_class */ -static void e_mb_standby(e_mb_class* param_0) { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 80708A28-80708A2C 000018 0004+00 0/0 0/0 0/0 .rodata @3880 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3880 = 250.0f; -COMPILER_STRIP_GATE(0x80708A28, &lit_3880); -#pragma pop - -/* 80708A2C-80708A30 00001C 0004+00 0/1 0/0 0/0 .rodata @3881 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3881 = 100.0f; -COMPILER_STRIP_GATE(0x80708A2C, &lit_3881); -#pragma pop - -/* 80708A30-80708A34 000020 0004+00 0/0 0/0 0/0 .rodata @3882 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3882 = 125.0f; -COMPILER_STRIP_GATE(0x80708A30, &lit_3882); -#pragma pop - -/* 80708A34-80708A38 000024 0004+00 0/2 0/0 0/0 .rodata @3883 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3883 = 30.0f; -COMPILER_STRIP_GATE(0x80708A34, &lit_3883); -#pragma pop - -/* 80708A38-80708A3C 000028 0004+00 0/3 0/0 0/0 .rodata @3943 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3943 = 5.0f; -COMPILER_STRIP_GATE(0x80708A38, &lit_3943); -#pragma pop - -/* 80708A3C-80708A40 00002C 0004+00 0/2 0/0 0/0 .rodata @3944 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3944 = 15.0f; -COMPILER_STRIP_GATE(0x80708A3C, &lit_3944); -#pragma pop - -/* 80708A40-80708A48 000030 0008+00 0/4 0/0 0/0 .rodata @3945 */ -#pragma push -#pragma force_active on -SECTION_RODATA static u8 const lit_3945[8] = { - 0x3F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -COMPILER_STRIP_GATE(0x80708A40, &lit_3945); -#pragma pop - -/* 80708A48-80708A50 000038 0008+00 0/4 0/0 0/0 .rodata @3946 */ -#pragma push -#pragma force_active on -SECTION_RODATA static u8 const lit_3946[8] = { - 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -COMPILER_STRIP_GATE(0x80708A48, &lit_3946); -#pragma pop - -/* 80708A50-80708A58 000040 0008+00 0/4 0/0 0/0 .rodata @3947 */ -#pragma push -#pragma force_active on -SECTION_RODATA static u8 const lit_3947[8] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; -COMPILER_STRIP_GATE(0x80708A50, &lit_3947); -#pragma pop - -/* 80708A58-80708A5C 000048 0004+00 0/2 0/0 0/0 .rodata @3948 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_3948 = 20.0f; -COMPILER_STRIP_GATE(0x80708A58, &lit_3948); -#pragma pop - -/* 80708CB8-80708CC4 0000D0 000C+00 0/1 0/0 0/0 .bss @3828 */ -#pragma push -#pragma force_active on -static u8 lit_3828[12]; -#pragma pop - -/* 80708CC4-80708CD0 0000DC 000C+00 2/4 0/0 0/0 .bss R_pos2 */ -static u8 R_pos2[12]; - -/* 8070661C-80706898 00059C 027C+00 1/1 0/0 0/0 .text e_mb_walk1__FP10e_mb_class */ -static void e_mb_walk1(e_mb_class* param_0) { - // NONMATCHING -} - -/* 80706898-807068D4 000818 003C+00 1/1 0/0 0/0 .text __dt__4cXyzFv */ -// cXyz::~cXyz() { -extern "C" void __dt__4cXyzFv() { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 80708A5C-80708A60 00004C 0004+00 0/2 0/0 0/0 .rodata @4102 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4102 = 3.0f; -COMPILER_STRIP_GATE(0x80708A5C, &lit_4102); -#pragma pop - -/* 80708A60-80708A64 000050 0004+00 0/1 0/0 0/0 .rodata @4103 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4103 = 2.0f; -COMPILER_STRIP_GATE(0x80708A60, &lit_4103); -#pragma pop - -/* 80708A64-80708A68 000054 0004+00 0/2 0/0 0/0 .rodata @4104 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4104 = 1.0f / 10.0f; -COMPILER_STRIP_GATE(0x80708A64, &lit_4104); -#pragma pop - -/* 80708A68-80708A6C 000058 0004+00 0/2 0/0 0/0 .rodata @4105 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4105 = 400.0f; -COMPILER_STRIP_GATE(0x80708A68, &lit_4105); -#pragma pop - -/* 80708A6C-80708A70 00005C 0004+00 0/1 0/0 0/0 .rodata @4106 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4106 = 11.0f / 10.0f; -COMPILER_STRIP_GATE(0x80708A6C, &lit_4106); -#pragma pop - -/* 80708A70-80708A78 000060 0008+00 0/2 0/0 0/0 .rodata @4109 */ -#pragma push -#pragma force_active on -SECTION_RODATA static u8 const lit_4109[8] = { - 0x43, 0x30, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, -}; -COMPILER_STRIP_GATE(0x80708A70, &lit_4109); -#pragma pop - -/* 807068D4-80706F90 000854 06BC+00 1/1 0/0 0/0 .text e_mb_move__FP10e_mb_class */ -static void e_mb_move(e_mb_class* param_0) { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 80708A78-80708A7C 000068 0004+00 0/1 0/0 0/0 .rodata @4177 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4177 = 25.0f; -COMPILER_STRIP_GATE(0x80708A78, &lit_4177); -#pragma pop - -/* 80708A7C-80708A80 00006C 0004+00 0/2 0/0 0/0 .rodata @4178 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4178 = 0.5f; -COMPILER_STRIP_GATE(0x80708A7C, &lit_4178); -#pragma pop - -/* 80706F90-8070723C 000F10 02AC+00 1/1 0/0 0/0 .text e_mb_walk2__FP10e_mb_class */ -static void e_mb_walk2(e_mb_class* param_0) { - // NONMATCHING -} - -/* 8070723C-80707560 0011BC 0324+00 1/1 0/0 0/0 .text e_mb_firstdemo__FP10e_mb_class */ -static void e_mb_firstdemo(e_mb_class* param_0) { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 80708A80-80708A84 000070 0004+00 1/1 0/0 0/0 .rodata @4241 */ -SECTION_RODATA static f32 const lit_4241 = 20000.0f; -COMPILER_STRIP_GATE(0x80708A80, &lit_4241); - -/* 80707560-80707570 0014E0 0010+00 1/1 0/0 0/0 .text e_mb_end__FP10e_mb_class */ -static void e_mb_end(e_mb_class* param_0) { - // NONMATCHING -} - -/* 80707570-80707680 0014F0 0110+00 1/1 0/0 0/0 .text action__FP10e_mb_class */ -static void action(e_mb_class* param_0) { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 80708A84-80708A88 000074 0004+00 0/1 0/0 0/0 .rodata @4601 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4601 = 32768.0f; -COMPILER_STRIP_GATE(0x80708A84, &lit_4601); -#pragma pop - -/* 80708A88-80708A8C 000078 0004+00 0/1 0/0 0/0 .rodata @4602 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4602 = -3.0f / 10.0f; -COMPILER_STRIP_GATE(0x80708A88, &lit_4602); -#pragma pop - -/* 80708A8C-80708A90 00007C 0004+00 0/1 0/0 0/0 .rodata @4603 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4603 = 35.0f; -COMPILER_STRIP_GATE(0x80708A8C, &lit_4603); -#pragma pop - -/* 80708A90-80708A94 000080 0004+00 1/2 0/0 0/0 .rodata @4604 */ -SECTION_RODATA static f32 const lit_4604 = 10.0f; -COMPILER_STRIP_GATE(0x80708A90, &lit_4604); - -/* 80708A94-80708A98 000084 0004+00 0/1 0/0 0/0 .rodata @4605 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4605 = 60.0f; -COMPILER_STRIP_GATE(0x80708A94, &lit_4605); -#pragma pop - -/* 80708A98-80708A9C 000088 0004+00 0/1 0/0 0/0 .rodata @4606 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4606 = -35.0f; -COMPILER_STRIP_GATE(0x80708A98, &lit_4606); -#pragma pop - -/* 80708A9C-80708AA0 00008C 0004+00 0/1 0/0 0/0 .rodata @4607 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4607 = 150.0f; -COMPILER_STRIP_GATE(0x80708A9C, &lit_4607); -#pragma pop - -/* 80708AA0-80708AA4 000090 0004+00 0/1 0/0 0/0 .rodata @4608 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4608 = -20000.0f; -COMPILER_STRIP_GATE(0x80708AA0, &lit_4608); -#pragma pop - -/* 80708AA4-80708AA8 000094 0004+00 0/1 0/0 0/0 .rodata @4609 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4609 = 40000.0f; -COMPILER_STRIP_GATE(0x80708AA4, &lit_4609); -#pragma pop - -/* 80708AA8-80708AAC 000098 0004+00 0/1 0/0 0/0 .rodata @4610 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4610 = 55000.0f; -COMPILER_STRIP_GATE(0x80708AA8, &lit_4610); -#pragma pop - -/* 80708AAC-80708AB0 00009C 0004+00 0/1 0/0 0/0 .rodata @4611 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4611 = 200.0f; -COMPILER_STRIP_GATE(0x80708AAC, &lit_4611); -#pragma pop - -/* 80708AB0-80708AB4 0000A0 0004+00 0/1 0/0 0/0 .rodata @4612 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4612 = 1800.0f; -COMPILER_STRIP_GATE(0x80708AB0, &lit_4612); -#pragma pop - -/* 80708AB4-80708AB8 0000A4 0004+00 0/1 0/0 0/0 .rodata @4613 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4613 = -500.0f; -COMPILER_STRIP_GATE(0x80708AB4, &lit_4613); -#pragma pop - -/* 80708AB8-80708ABC 0000A8 0004+00 0/1 0/0 0/0 .rodata @4614 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4614 = 1.0f / 15.0f; -COMPILER_STRIP_GATE(0x80708AB8, &lit_4614); -#pragma pop - -/* 80708CD0-80708CDC 0000E8 000C+00 0/1 0/0 0/0 .bss @3829 */ -#pragma push -#pragma force_active on -static u8 lit_3829[12]; -#pragma pop - -/* 80708CDC-80708CE8 0000F4 000C+00 0/2 0/0 0/0 .bss R_Hpos */ -#pragma push -#pragma force_active on -static u8 R_Hpos[12]; -#pragma pop - -/* 80707680-80708148 001600 0AC8+00 2/1 0/0 0/0 .text daE_MB_Execute__FP10e_mb_class */ -static void daE_MB_Execute(e_mb_class* param_0) { - // NONMATCHING -} - -/* 80708148-80708150 0020C8 0008+00 1/0 0/0 0/0 .text daE_MB_IsDelete__FP10e_mb_class */ -static bool daE_MB_IsDelete(e_mb_class* param_0) { - return true; -} - -/* 80708150-807081B8 0020D0 0068+00 1/0 0/0 0/0 .text daE_MB_Delete__FP10e_mb_class */ -static void daE_MB_Delete(e_mb_class* param_0) { - // NONMATCHING -} - -/* 807081B8-8070853C 002138 0384+00 1/1 0/0 0/0 .text useHeapInit__FP10fopAc_ac_c */ -static void useHeapInit(fopAc_ac_c* param_0) { - // NONMATCHING -} - -/* 8070853C-80708584 0024BC 0048+00 1/0 0/0 0/0 .text __dt__12J3DFrameCtrlFv */ -// J3DFrameCtrl::~J3DFrameCtrl() { -extern "C" void __dt__12J3DFrameCtrlFv() { - // NONMATCHING -} - -/* 80708584-8070879C 002504 0218+00 1/0 0/0 0/0 .text daE_MB_Create__FP10fopAc_ac_c */ -static void daE_MB_Create(fopAc_ac_c* param_0) { - // NONMATCHING -} - -/* 8070879C-807087E4 00271C 0048+00 1/0 0/0 0/0 .text __dt__8cM3dGSphFv */ -// cM3dGSph::~cM3dGSph() { -extern "C" void __dt__8cM3dGSphFv() { - // NONMATCHING -} - -/* 807087E4-8070882C 002764 0048+00 1/0 0/0 0/0 .text __dt__8cM3dGAabFv */ -// cM3dGAab::~cM3dGAab() { -extern "C" void __dt__8cM3dGAabFv() { - // NONMATCHING -} - -/* 8070882C-80708874 0027AC 0048+00 2/1 0/0 0/0 .text __dt__12daE_MB_HIO_cFv */ -daE_MB_HIO_c::~daE_MB_HIO_c() { - // NONMATCHING -} - -/* ############################################################################################## */ -/* 80708ABC-80708AC0 0000AC 0004+00 0/1 0/0 0/0 .rodata @4898 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4898 = -2575.0f; -COMPILER_STRIP_GATE(0x80708ABC, &lit_4898); -#pragma pop - -/* 80708AC0-80708AC4 0000B0 0004+00 0/1 0/0 0/0 .rodata @4899 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4899 = 1050.0f; -COMPILER_STRIP_GATE(0x80708AC0, &lit_4899); -#pragma pop - -/* 80708AC4-80708AC8 0000B4 0004+00 0/1 0/0 0/0 .rodata @4900 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4900 = 1060.0f; -COMPILER_STRIP_GATE(0x80708AC4, &lit_4900); -#pragma pop - -/* 80708AC8-80708ACC 0000B8 0004+00 0/1 0/0 0/0 .rodata @4901 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4901 = -1944.0f; -COMPILER_STRIP_GATE(0x80708AC8, &lit_4901); -#pragma pop - -/* 80708ACC-80708AD0 0000BC 0004+00 0/1 0/0 0/0 .rodata @4902 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4902 = -1923.0f; -COMPILER_STRIP_GATE(0x80708ACC, &lit_4902); -#pragma pop - -/* 80708AD0-80708AD4 0000C0 0004+00 0/1 0/0 0/0 .rodata @4903 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4903 = 1432.0f; -COMPILER_STRIP_GATE(0x80708AD0, &lit_4903); -#pragma pop - -/* 80708AD4-80708AD8 0000C4 0004+00 0/1 0/0 0/0 .rodata @4904 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4904 = 2606.0f; -COMPILER_STRIP_GATE(0x80708AD4, &lit_4904); -#pragma pop - -/* 80708AD8-80708ADC 0000C8 0004+00 0/1 0/0 0/0 .rodata @4905 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4905 = 1070.0f; -COMPILER_STRIP_GATE(0x80708AD8, &lit_4905); -#pragma pop - -/* 80708ADC-80708AE0 0000CC 0004+00 0/1 0/0 0/0 .rodata @4906 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4906 = 2126.0f; -COMPILER_STRIP_GATE(0x80708ADC, &lit_4906); -#pragma pop - -/* 80708AE0-80708AE4 0000D0 0004+00 0/1 0/0 0/0 .rodata @4907 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4907 = 2099.0f; -COMPILER_STRIP_GATE(0x80708AE0, &lit_4907); -#pragma pop - -/* 80708AE4-80708AE8 0000D4 0004+00 0/1 0/0 0/0 .rodata @4908 */ -#pragma push -#pragma force_active on -SECTION_RODATA static f32 const lit_4908 = 1011.0f; -COMPILER_STRIP_GATE(0x80708AE4, &lit_4908); -#pragma pop - -/* 80708CE8-80708CF4 000100 000C+00 0/1 0/0 0/0 .bss @3830 */ -#pragma push -#pragma force_active on -static u8 lit_3830[12]; -#pragma pop - -/* 80708CF4-80708D00 00010C 000C+00 0/1 0/0 0/0 .bss c_pos */ -#pragma push -#pragma force_active on -static u8 c_pos[12]; -#pragma pop - -/* 80708874-807089FC 0027F4 0188+00 0/0 1/0 0/0 .text __sinit_d_a_e_mb_cpp */ -void __sinit_d_a_e_mb_cpp() { - // NONMATCHING -} - -#pragma push -#pragma force_active on -REGISTER_CTORS(0x80708874, __sinit_d_a_e_mb_cpp); -#pragma pop - -/* ############################################################################################## */ -/* 80708D00-80708D04 000118 0004+00 0/0 0/0 0/0 .bss - * sInstance__40JASGlobalInstance<19JASDefaultBankTable> */ -#pragma push -#pragma force_active on -static u8 data_80708D00[4]; -#pragma pop - -/* 80708D04-80708D08 00011C 0004+00 0/0 0/0 0/0 .bss - * sInstance__35JASGlobalInstance<14JASAudioThread> */ -#pragma push -#pragma force_active on -static u8 data_80708D04[4]; -#pragma pop - -/* 80708D08-80708D0C 000120 0004+00 0/0 0/0 0/0 .bss sInstance__27JASGlobalInstance<7Z2SeMgr> */ -#pragma push -#pragma force_active on -static u8 data_80708D08[4]; -#pragma pop - -/* 80708D0C-80708D10 000124 0004+00 0/0 0/0 0/0 .bss sInstance__28JASGlobalInstance<8Z2SeqMgr> */ -#pragma push -#pragma force_active on -static u8 data_80708D0C[4]; -#pragma pop - -/* 80708D10-80708D14 000128 0004+00 0/0 0/0 0/0 .bss sInstance__31JASGlobalInstance<10Z2SceneMgr> - */ -#pragma push -#pragma force_active on -static u8 data_80708D10[4]; -#pragma pop - -/* 80708D14-80708D18 00012C 0004+00 0/0 0/0 0/0 .bss sInstance__32JASGlobalInstance<11Z2StatusMgr> - */ -#pragma push -#pragma force_active on -static u8 data_80708D14[4]; -#pragma pop - -/* 80708D18-80708D1C 000130 0004+00 0/0 0/0 0/0 .bss sInstance__31JASGlobalInstance<10Z2DebugSys> - */ -#pragma push -#pragma force_active on -static u8 data_80708D18[4]; -#pragma pop - -/* 80708D1C-80708D20 000134 0004+00 0/0 0/0 0/0 .bss - * sInstance__36JASGlobalInstance<15JAISoundStarter> */ -#pragma push -#pragma force_active on -static u8 data_80708D1C[4]; -#pragma pop - -/* 80708D20-80708D24 000138 0004+00 0/0 0/0 0/0 .bss - * sInstance__35JASGlobalInstance<14Z2SoundStarter> */ -#pragma push -#pragma force_active on -static u8 data_80708D20[4]; -#pragma pop - -/* 80708D24-80708D28 00013C 0004+00 0/0 0/0 0/0 .bss - * sInstance__33JASGlobalInstance<12Z2SpeechMgr2> */ -#pragma push -#pragma force_active on -static u8 data_80708D24[4]; -#pragma pop - -/* 80708D28-80708D2C 000140 0004+00 0/0 0/0 0/0 .bss sInstance__28JASGlobalInstance<8JAISeMgr> */ -#pragma push -#pragma force_active on -static u8 data_80708D28[4]; -#pragma pop - -/* 80708D2C-80708D30 000144 0004+00 0/0 0/0 0/0 .bss sInstance__29JASGlobalInstance<9JAISeqMgr> */ -#pragma push -#pragma force_active on -static u8 data_80708D2C[4]; -#pragma pop - -/* 80708D30-80708D34 000148 0004+00 0/0 0/0 0/0 .bss - * sInstance__33JASGlobalInstance<12JAIStreamMgr> */ -#pragma push -#pragma force_active on -static u8 data_80708D30[4]; -#pragma pop - -/* 80708D34-80708D38 00014C 0004+00 0/0 0/0 0/0 .bss sInstance__31JASGlobalInstance<10Z2SoundMgr> - */ -#pragma push -#pragma force_active on -static u8 data_80708D34[4]; -#pragma pop - -/* 80708D38-80708D3C 000150 0004+00 0/0 0/0 0/0 .bss - * sInstance__33JASGlobalInstance<12JAISoundInfo> */ -#pragma push -#pragma force_active on -static u8 data_80708D38[4]; -#pragma pop - -/* 80708D3C-80708D40 000154 0004+00 0/0 0/0 0/0 .bss - * sInstance__34JASGlobalInstance<13JAUSoundTable> */ -#pragma push -#pragma force_active on -static u8 data_80708D3C[4]; -#pragma pop - -/* 80708D40-80708D44 000158 0004+00 0/0 0/0 0/0 .bss - * sInstance__38JASGlobalInstance<17JAUSoundNameTable> */ -#pragma push -#pragma force_active on -static u8 data_80708D40[4]; -#pragma pop - -/* 80708D44-80708D48 00015C 0004+00 0/0 0/0 0/0 .bss - * sInstance__33JASGlobalInstance<12JAUSoundInfo> */ -#pragma push -#pragma force_active on -static u8 data_80708D44[4]; -#pragma pop - -/* 80708D48-80708D4C 000160 0004+00 0/0 0/0 0/0 .bss sInstance__32JASGlobalInstance<11Z2SoundInfo> - */ -#pragma push -#pragma force_active on -static u8 data_80708D48[4]; -#pragma pop - -/* 80708D4C-80708D50 000164 0004+00 0/0 0/0 0/0 .bss - * sInstance__34JASGlobalInstance<13Z2SoundObjMgr> */ -#pragma push -#pragma force_active on -static u8 data_80708D4C[4]; -#pragma pop - -/* 80708D50-80708D54 000168 0004+00 0/0 0/0 0/0 .bss sInstance__31JASGlobalInstance<10Z2Audience> - */ -#pragma push -#pragma force_active on -static u8 data_80708D50[4]; -#pragma pop - -/* 80708D54-80708D58 00016C 0004+00 0/0 0/0 0/0 .bss sInstance__32JASGlobalInstance<11Z2FxLineMgr> - */ -#pragma push -#pragma force_active on -static u8 data_80708D54[4]; -#pragma pop - -/* 80708D58-80708D5C 000170 0004+00 0/0 0/0 0/0 .bss sInstance__31JASGlobalInstance<10Z2EnvSeMgr> - */ -#pragma push -#pragma force_active on -static u8 data_80708D58[4]; -#pragma pop - -/* 80708D5C-80708D60 000174 0004+00 0/0 0/0 0/0 .bss sInstance__32JASGlobalInstance<11Z2SpeechMgr> - */ -#pragma push -#pragma force_active on -static u8 data_80708D5C[4]; -#pragma pop - -/* 80708D60-80708D64 000178 0004+00 0/0 0/0 0/0 .bss - * sInstance__34JASGlobalInstance<13Z2WolfHowlMgr> */ -#pragma push -#pragma force_active on -static u8 data_80708D60[4]; -#pragma pop - -/* 80708AE8-80708AE8 0000D8 0000+00 0/0 0/0 0/0 .rodata @stringBase0 */ +AUDIO_INSTANCES; diff --git a/src/d/actor/d_a_ep.cpp b/src/d/actor/d_a_ep.cpp index 9e3e29d3bf..114a3e601c 100644 --- a/src/d/actor/d_a_ep.cpp +++ b/src/d/actor/d_a_ep.cpp @@ -65,8 +65,6 @@ struct dPa_levelEcallBack {}; struct csXyz {}; -struct _GXColor {}; - struct dPa_control_c { /* 8004CA90 */ void set(u8, u16, cXyz const*, dKy_tevstr_c const*, csXyz const*, cXyz const*, u8, dPa_levelEcallBack*, s8, _GXColor const*, _GXColor const*, @@ -144,8 +142,6 @@ struct cBgS { /* 800744A0 */ void GroundCross(cBgS_GndChk*); }; -struct _GXTexObj {}; - struct LIGHT_INFLUENCE {}; struct J3DUClipper { diff --git a/src/d/actor/d_a_grass.cpp b/src/d/actor/d_a_grass.cpp index 78c0e4b522..41234b6947 100644 --- a/src/d/actor/d_a_grass.cpp +++ b/src/d/actor/d_a_grass.cpp @@ -10,6 +10,7 @@ #include "dol2asm.h" #include "m_Do/m_Do_lib.h" #include "string.h" +#include // // Forward References: diff --git a/src/d/actor/d_a_horse.cpp b/src/d/actor/d_a_horse.cpp index e8786d0027..b61bd9a8bd 100644 --- a/src/d/actor/d_a_horse.cpp +++ b/src/d/actor/d_a_horse.cpp @@ -456,7 +456,7 @@ int daHorse_c::modelCallBack(int i_jntNo) { MtxP m = m_model->getAnmMtx(i_jntNo); cMtx_concat(m, mDoMtx_stack_c::get(), J3DSys::mCurrentMtx); - MTXQuat(m, (PSQuaternion*)&sp20); + MTXQuat(m, &sp20); m[0][3] = var_r27->mTranslate.x; m[1][3] = var_r27->mTranslate.y; m[2][3] = var_r27->mTranslate.z; diff --git a/src/d/actor/d_a_mirror.cpp b/src/d/actor/d_a_mirror.cpp index 8d34d4144d..da42db665d 100644 --- a/src/d/actor/d_a_mirror.cpp +++ b/src/d/actor/d_a_mirror.cpp @@ -98,7 +98,7 @@ void dMirror_packet_c::mirrorZdraw(f32* param_0, f32* param_1, f32 param_2, f32 GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0); GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetZCompLoc(GX_TRUE); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_OR); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_OR); GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); GXSetFog(GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, g_clearColor); GXSetFogRangeAdj(0, 0, NULL); diff --git a/src/d/actor/d_a_movie_player.cpp b/src/d/actor/d_a_movie_player.cpp index 11a6e27058..5ac606d44c 100644 --- a/src/d/actor/d_a_movie_player.cpp +++ b/src/d/actor/d_a_movie_player.cpp @@ -2735,7 +2735,7 @@ static BOOL daMP_VideoDecodeThreadCreated; /* 80875B18-80875BC8 003438 00B0+00 1/1 0/0 0/0 .text daMP_CreateReadThread__Fl */ static BOOL daMP_CreateReadThread(s32 param_0) { // NONMATCHING - if (!OSCreateThread(&daMP_ReadThread, daMP_Reader, 0, daMP_ReadThreadStack + sizeof(daMP_ReadThreadStack), sizeof(daMP_ReadThreadStack), param_0, 1)) { + if (!OSCreateThread(&daMP_ReadThread, (void*(*)(void*))daMP_Reader, 0, daMP_ReadThreadStack + sizeof(daMP_ReadThreadStack), sizeof(daMP_ReadThreadStack), param_0, 1)) { OSReport("Can't create read thread\n"); return 0; } @@ -2817,12 +2817,12 @@ static void daMP_VideoDecoderForOnMemory(void* param_0) { */ static int daMP_CreateVideoDecodeThread(s32 param_0, u8* param_1) { if (param_1 != NULL) { - if (!OSCreateThread(&daMP_VideoDecodeThread, daMP_VideoDecoderForOnMemory, param_1, daMP_VideoDecodeThreadStack + sizeof(daMP_VideoDecodeThreadStack), sizeof(daMP_VideoDecodeThreadStack), param_0, 1)) { + if (!OSCreateThread(&daMP_VideoDecodeThread, (void*(*)(void*))daMP_VideoDecoderForOnMemory, param_1, daMP_VideoDecodeThreadStack + sizeof(daMP_VideoDecodeThreadStack), sizeof(daMP_VideoDecodeThreadStack), param_0, 1)) { OSReport("Can't create video decode thread\n"); return 0; } } else { - if (!OSCreateThread(&daMP_VideoDecodeThread, daMP_VideoDecoder, NULL, daMP_VideoDecodeThreadStack + sizeof(daMP_VideoDecodeThreadStack), sizeof(daMP_VideoDecodeThreadStack), param_0, 1)) { + if (!OSCreateThread(&daMP_VideoDecodeThread, (void*(*)(void*))daMP_VideoDecoder, NULL, daMP_VideoDecodeThreadStack + sizeof(daMP_VideoDecodeThreadStack), sizeof(daMP_VideoDecodeThreadStack), param_0, 1)) { OSReport("Can't create video decode thread\n"); return 0; } @@ -2924,11 +2924,11 @@ static OSMessage daMP_DecodedAudioBufferMessage[3]; */ static int daMP_CreateAudioDecodeThread(s32 param_0, u8* param_1) { if (param_1 != NULL) { - if (!OSCreateThread(&daMP_AudioDecodeThread, daMP_AudioDecoderForOnMemory, param_1, daMP_AudioDecodeThreadStack + sizeof(daMP_AudioDecodeThreadStack), sizeof(daMP_AudioDecodeThreadStack), param_0, 1)) { + if (!OSCreateThread(&daMP_AudioDecodeThread, (void*(*)(void*))daMP_AudioDecoderForOnMemory, param_1, daMP_AudioDecodeThreadStack + sizeof(daMP_AudioDecodeThreadStack), sizeof(daMP_AudioDecodeThreadStack), param_0, 1)) { return 0; } } else { - if (!OSCreateThread(&daMP_AudioDecodeThread, daMP_AudioDecoder, NULL, daMP_AudioDecodeThreadStack + sizeof(daMP_AudioDecodeThreadStack), sizeof(daMP_AudioDecodeThreadStack), param_0, 1)) { + if (!OSCreateThread(&daMP_AudioDecodeThread, (void*(*)(void*))daMP_AudioDecoder, NULL, daMP_AudioDecodeThreadStack + sizeof(daMP_AudioDecodeThreadStack), sizeof(daMP_AudioDecodeThreadStack), param_0, 1)) { OSReport("Can't create audio decode thread\n"); return 0; } @@ -2985,8 +2985,8 @@ static f32 dummyLiteral() { * daMP_THPGXYuv2RgbSetup__FPC16_GXRenderModeObj */ // NONMATCHING - stack slightly too small static void daMP_THPGXYuv2RgbSetup(GXRenderModeObj const* param_0) { - int width = param_0->fb_width; - int height = param_0->efb_height; + int width = param_0->fbWidth; + int height = param_0->efbHeight; f32 var_f31 = 0.0f; Mtx sp50; Mtx sp20; @@ -3452,7 +3452,7 @@ static void daMP_THPPlayerStop() { VISetPostRetraceCallback(daMP_OldVIPostCallback); if (daMP_ActivePlayer.field_0xb0 == 0) { - DVDCancel(&daMP_ActivePlayer.mFileInfo.block); + DVDCancel(&daMP_ActivePlayer.mFileInfo.cb); daMP_ReadThreadCancel(); } @@ -3557,8 +3557,8 @@ static BOOL daMP_ActivePlayer_Init(char const* moviePath) { daMP_THPPlayerGetVideoInfo(&daMP_videoInfo); daMP_THPPlayerGetAudioInfo(&daMP_audioInfo); - u16 var_r31 = JUTVideo::getManager()->getRenderMode()->fb_width; - u16 temp_r4 = JUTVideo::getManager()->getRenderMode()->efb_height; + u16 var_r31 = JUTVideo::getManager()->getRenderMode()->fbWidth; + u16 temp_r4 = JUTVideo::getManager()->getRenderMode()->efbHeight; daMP_DrawPosX = (var_r31 - daMP_videoInfo.field_0x0) >> 1; daMP_DrawPosY = (temp_r4 - daMP_videoInfo.field_0x4) >> 1; diff --git a/src/d/actor/d_a_obj_flag.cpp b/src/d/actor/d_a_obj_flag.cpp index 7e7b960802..d5a55dcaad 100644 --- a/src/d/actor/d_a_obj_flag.cpp +++ b/src/d/actor/d_a_obj_flag.cpp @@ -66,7 +66,6 @@ extern "C" void __construct_array(); extern "C" void __cvt_fp2unsigned(); extern "C" void _savegpr_26(); extern "C" void _restgpr_26(); -extern "C" void sprintf(); extern "C" u8 now__14mDoMtx_stack_c[48]; extern "C" extern u8 g_dComIfG_gameInfo[122384]; extern "C" u8 mCurrentMtx__6J3DSys[48]; diff --git a/src/d/actor/d_a_obj_flag2.cpp b/src/d/actor/d_a_obj_flag2.cpp index 0df16e7c0c..9a045f0608 100644 --- a/src/d/actor/d_a_obj_flag2.cpp +++ b/src/d/actor/d_a_obj_flag2.cpp @@ -109,7 +109,6 @@ extern "C" void _restgpr_23(); extern "C" void _restgpr_26(); extern "C" void _restgpr_28(); extern "C" void _restgpr_29(); -extern "C" void sprintf(); extern "C" extern void* __vt__8dCcD_Sph[36]; extern "C" extern void* __vt__8dCcD_Cyl[36]; extern "C" extern void* __vt__9dCcD_Stts[11]; diff --git a/src/d/actor/d_a_obj_flag3.cpp b/src/d/actor/d_a_obj_flag3.cpp index 5eaa3518e7..e99e79c472 100644 --- a/src/d/actor/d_a_obj_flag3.cpp +++ b/src/d/actor/d_a_obj_flag3.cpp @@ -88,7 +88,6 @@ extern "C" void _restgpr_26(); extern "C" void _restgpr_27(); extern "C" void _restgpr_28(); extern "C" void _restgpr_29(); -extern "C" void sprintf(); extern "C" extern void* __vt__8dCcD_Sph[36]; extern "C" extern void* __vt__9dCcD_Stts[11]; extern "C" extern void* __vt__12cCcD_SphAttr[25]; diff --git a/src/d/actor/d_a_tag_shop_item.cpp b/src/d/actor/d_a_tag_shop_item.cpp index 3e85202a84..87923e6029 100644 --- a/src/d/actor/d_a_tag_shop_item.cpp +++ b/src/d/actor/d_a_tag_shop_item.cpp @@ -87,7 +87,7 @@ int daTag_ShopItem_c::Delete() { /* 80D60E04-80D61024 000304 0220+00 1/1 0/0 0/0 .text Execute__16daTag_ShopItem_cFv */ int daTag_ShopItem_c::Execute() { - if (mProcessID == UINT32_MAX) { + if (mProcessID == fpcM_ERROR_PROCESS_ID_e) { if (mCreateTimer == 0) { mProcessID = fopAcM_create(PROC_ShopItem, (getType() & 0xFF) | (getGroupID() << 0x1C), diff --git a/src/d/actor/d_a_ykgr.cpp b/src/d/actor/d_a_ykgr.cpp index c1251ee1ea..c37e28fd71 100644 --- a/src/d/actor/d_a_ykgr.cpp +++ b/src/d/actor/d_a_ykgr.cpp @@ -22,19 +22,19 @@ inline daYkgr_HIO_c::daYkgr_HIO_c() { } inline dPa_YkgrPcallBack::dPa_YkgrPcallBack() { - field_0x4 = 0.5f; - field_0x8 = 0.0f; - field_0xc = 0.0f; - field_0x10 = 0.0f; - field_0x14 = 0.5f; - field_0x18 = 0.0f; + field_0x4[0][0] = 0.5f; + field_0x4[0][1] = 0.0f; + field_0x4[0][2] = 0.0f; + field_0x4[1][0] = 0.0f; + field_0x4[1][1] = 0.5f; + field_0x4[1][2] = 0.0f; field_0x1c = 1; } /* 805A848C-805A84D4 0000EC 0048+00 1/0 0/0 0/0 .text * draw__17dPa_YkgrPcallBackFP14JPABaseEmitterP15JPABaseParticle */ void dPa_YkgrPcallBack::draw(JPABaseEmitter* param_0, JPABaseParticle* param_1) { - GXSetIndTexMtx(GX_ITM_0, &field_0x4, field_0x1c); + GXSetIndTexMtx(GX_ITM_0, field_0x4, field_0x1c); GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0); } @@ -44,19 +44,19 @@ void dPa_YkgrPcallBack::setParam(f32 param_1) { if (param_1 >= 0.0f) { field_0x1c = param_1; f32 fVar1 = (param_1 - field_0x1c) * 0.5f + 0.5f; - field_0x14 = fVar1; - field_0x4 = fVar1; + field_0x4[1][1] = fVar1; + field_0x4[0][0] = fVar1; } else { f32 x = param_1 - 1.0f; field_0x1c = x; f32 fVar1 = (x - field_0x1c) * 0.5f + 1.0f; - field_0x14 = fVar1; - field_0x4 = fVar1; + field_0x4[1][1] = fVar1; + field_0x4[0][0] = fVar1; } - field_0x8 = 0.0f; - field_0xc = 0.0f; - field_0x10 = 0.0f; - field_0x18 = 0.0f; + field_0x4[0][1] = 0.0f; + field_0x4[0][2] = 0.0f; + field_0x4[1][0] = 0.0f; + field_0x4[1][2] = 0.0f; } } diff --git a/src/d/d_drawlist.cpp b/src/d/d_drawlist.cpp index ead81e9419..61fb6be576 100644 --- a/src/d/d_drawlist.cpp +++ b/src/d/d_drawlist.cpp @@ -224,7 +224,7 @@ void dDlst_2DTri_c::draw() { GXSetNumTevStages(1); GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GXLoadPosMtxImm(mDoMtx_getIdentity(), GX_PNMTX0); GXSetCurrentMtx(GX_PNMTX0); GXBegin(GX_TRIANGLES, GX_VTXFMT0, 3); @@ -247,7 +247,7 @@ void dDlst_2DQuad_c::draw() { GXSetNumTevStages(1); GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GXLoadPosMtxImm(mDoMtx_getIdentity(), GX_PNMTX0); GXSetCurrentMtx(GX_PNMTX0); GXBegin(GX_QUADS, GX_VTXFMT0, 4); @@ -271,7 +271,7 @@ void dDlst_2DPoint_c::draw() { GXSetNumTevStages(1); GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GXSetPointSize(field_0xc, GX_TO_ZERO); GXLoadPosMtxImm(mDoMtx_getIdentity(), GX_PNMTX0); GXSetCurrentMtx(GX_PNMTX0); @@ -365,7 +365,7 @@ void dDlst_2DT2_c::draw() { GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); GXSetZCompLoc(GX_FALSE); GXSetZMode(GX_DISABLE, GX_ALWAYS, GX_DISABLE); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); GXSetFog(GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, g_clearColor); GXSetCullMode(GX_CULL_NONE); @@ -743,7 +743,7 @@ void dDlst_2DM_c::draw() { GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_TEXA, GX_CA_APREV, GX_CA_ZERO); GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GXBegin(GX_QUADS, GX_VTXFMT0, 4); GXPosition3s16((s32)field_0x4, (s32)field_0x6, 0); GXTexCoord2s16(r31, r30); @@ -807,7 +807,7 @@ void dDlst_2Dm_c::draw() { GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_TEXA, GX_CA_APREV, GX_CA_ZERO); GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GXLoadPosMtxImm(g_mDoMtx_identity, GX_PNMTX0); GXSetCurrentMtx(0); GXBegin(GX_QUADS, GX_VTXFMT0, 4); @@ -861,7 +861,7 @@ void dDlst_2DMt_c::draw() { GXSetNumChans(0); GXSetNumTexGens(r28); GXSetNumTevStages(r28); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GXBegin(GX_QUADS, GX_VTXFMT0, 4); GXPosition3s16(field_0xc, field_0xe, 0); dDlst_2DMt_tex_c* tmp = field_0x8; @@ -980,7 +980,7 @@ void dDlst_effectLine_c::draw() { GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0); GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); GXSetZMode(GX_DISABLE, GX_LEQUAL, GX_DISABLE); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); GXSetCullMode(GX_CULL_NONE); GXLoadPosMtxImm(j3dSys.mViewMtx, GX_PNMTX0); @@ -1548,7 +1548,7 @@ void dDlst_shadowControl_c::imageDraw(Mtx param_0) { /* 80055A14-80055C74 050354 0260+00 0/0 1/1 0/0 .text draw__21dDlst_shadowControl_cFPA4_f */ void dDlst_shadowControl_c::draw(Mtx param_0) { - static GXTevColor l_tevColorChan[4] = { + static GXTevColorChan l_tevColorChan[4] = { GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, diff --git a/src/d/d_error_msg.cpp b/src/d/d_error_msg.cpp index 0c68a1f818..6fb13694b9 100644 --- a/src/d/d_error_msg.cpp +++ b/src/d/d_error_msg.cpp @@ -211,7 +211,7 @@ static void drawCapture(u8 alpha) { GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetZCompLoc(GX_TRUE); GXSetZMode(GX_DISABLE, GX_ALWAYS, GX_DISABLE); - GXSetBlendMode(GX_BM_NONE, GX_BL_SRC_ALPHA, GX_BL_ONE, GX_LO_CLEAR); + GXSetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_CLEAR); GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); GXSetFog(GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, g_clearColor); GXSetFogRangeAdj(GX_DISABLE, 0, NULL); diff --git a/src/d/d_event_data.cpp b/src/d/d_event_data.cpp index 03d405c293..24ff5ffee1 100644 --- a/src/d/d_event_data.cpp +++ b/src/d/d_event_data.cpp @@ -434,7 +434,7 @@ void dEvDtStaff_c::specialProcMessage() { break; case 'CREA': case 'SHOW': - work->_0 = UINT32_MAX; + work->_0 = UINT_MAX; work->mLMsg = NULL; work->mMsgSubstanceNum = dComIfGp_evmng_getMySubstanceNum(staffId, "msgNo"); work->mMsgSubstanceP = dComIfGp_evmng_getMyIntegerP(staffId, "msgNo"); @@ -498,7 +498,7 @@ void dEvDtStaff_c::specialProcMessage() { switch (data->unk) { case 0: work->_0 = fopMsgM_messageSet(work->mMsgNo, 1000); - if (work->_0 != UINT32_MAX) { + if (work->_0 != UINT_MAX) { data->unk++; } break; @@ -525,7 +525,7 @@ void dEvDtStaff_c::specialProcMessage() { switch (data->unk) { case 0: work->_0 = fopMsgM_messageSet(work->mMsgNo, 1000); - if (work->_0 != UINT32_MAX) { + if (work->_0 != UINT_MAX) { data->unk = 1; } else { break; @@ -544,7 +544,7 @@ void dEvDtStaff_c::specialProcMessage() { break; case 0x12: work->mLMsg->mode = 0x13; - work->_0 = UINT32_MAX; + work->_0 = UINT_MAX; work->mLMsg = NULL; work->mMsgSubstanceNum--; if (work->mMsgSubstanceNum != 0) { @@ -571,7 +571,7 @@ void dEvDtStaff_c::specialProcMessage() { dComIfGp_evmng_cutEnd(staffId); } else if (work->mLMsg->mode == 0x12) { work->mLMsg->mode = 0x13; - work->_0 = UINT32_MAX; + work->_0 = UINT_MAX; work->mLMsg = NULL; dComIfGp_evmng_cutEnd(staffId); } @@ -677,7 +677,7 @@ void dEvDtStaff_c::specialProcCreate() { int* argP = dComIfGp_evmng_getMyIntegerP(staffId, "ARG"); if (argP == NULL) { - arg = UINT32_MAX; + arg = UINT_MAX; } else { arg = *argP; } diff --git a/src/d/d_file_sel_info.cpp b/src/d/d_file_sel_info.cpp index a1f37588a4..1302298d45 100644 --- a/src/d/d_file_sel_info.cpp +++ b/src/d/d_file_sel_info.cpp @@ -177,8 +177,8 @@ static procFunc fileWarningProc[] = {&dFile_info_c::modeWait, &dFile_info_c::mod void dFile_info_c::setSaveDate(dSv_save_c* i_savedata) { OSCalendarTime time; OSTicksToCalendarTime(i_savedata->getPlayer().getPlayerStatusB().getDateIpl(), &time); - sprintf(mSaveDate, "%02d/%02d/%d %02d:%02d", time.month + 1, time.day_of_month, time.year, - time.hours, time.minutes); + sprintf(mSaveDate, "%02d/%02d/%d %02d:%02d", time.mon + 1, time.mday, time.year, + time.hour, time.min); } /* 80192C70-80192D58 18D5B0 00E8+00 1/1 0/0 0/0 .text setPlayTime__12dFile_info_cFP10dSv_save_c */ diff --git a/src/d/d_gameover.cpp b/src/d/d_gameover.cpp index a77857e306..268eec6a5b 100644 --- a/src/d/d_gameover.cpp +++ b/src/d/d_gameover.cpp @@ -535,9 +535,9 @@ s32 d_GameOver_Create(u8 i_gameoverType) { /* 8019C008-8019C06C 196948 0064+00 0/0 1/1 0/0 .text d_GameOver_Delete__FRUi */ bool d_GameOver_Delete(fpc_ProcID& i_id) { - if (i_id != UINT32_MAX) { + if (i_id != fpcM_ERROR_PROCESS_ID_e) { fopMsgM_Delete(fopMsgM_SearchByID(i_id)); - i_id = -1; + i_id = fpcM_ERROR_PROCESS_ID_e; dMeter2Info_setGameOverType(0); return true; } diff --git a/src/d/d_kankyo.cpp b/src/d/d_kankyo.cpp index a54004be5b..52e6401415 100644 --- a/src/d/d_kankyo.cpp +++ b/src/d/d_kankyo.cpp @@ -1,5 +1,6 @@ #include "d/d_kankyo.h" #include +#include #include "SSystem/SComponent/c_counter.h" #include "SSystem/SComponent/c_math.h" #include "d/actor/d_a_kytag08.h" diff --git a/src/d/d_kankyo_data.cpp b/src/d/d_kankyo_data.cpp index 06795f6f07..bc6e9e4522 100644 --- a/src/d/d_kankyo_data.cpp +++ b/src/d/d_kankyo_data.cpp @@ -811,8 +811,8 @@ static GXFogAdjTable S_xfog_table_data[2] = { /* 80056A24-80056A64 051364 0040+00 0/0 2/2 0/0 .text dKyd_xfog_table_set__FUc */ void dKyd_xfog_table_set(u8 tblIdx) { for (int i = 0; i < 10; i++) { - u16 fogAdjTableEntry = S_xfog_table_data[tblIdx & 0xff].fogVals[i]; - g_env_light.mXFogTbl.fogVals[i] = fogAdjTableEntry; + u16 fogAdjTableEntry = S_xfog_table_data[tblIdx & 0xff].r[i]; + g_env_light.mXFogTbl.r[i] = fogAdjTableEntry; } } diff --git a/src/d/d_kankyo_rain.cpp b/src/d/d_kankyo_rain.cpp index 5dea9cd4bb..87a34369e7 100644 --- a/src/d/d_kankyo_rain.cpp +++ b/src/d/d_kankyo_rain.cpp @@ -2167,7 +2167,7 @@ static void dKyr_draw_rev_moon(Mtx drawMtx, u8** tex) { GXSetTevColorOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); GXSetTevAlphaIn(GX_TEVSTAGE2, GX_CA_ZERO, GX_CA_TEXA, GX_CA_APREV, GX_CA_ZERO); GXSetTevAlphaOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_COPY); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_COPY); GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_DISABLE); GXSetNumIndStages(0); @@ -2232,7 +2232,7 @@ static void dKyr_draw_rev_moon(Mtx drawMtx, u8** tex) { GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO); GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_ONE, GX_LO_COPY); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_COPY); size *= 2.3f; color_reg0.a = 40.0f * sun_packet->mMoonAlpha; @@ -2510,7 +2510,7 @@ void dKyr_drawSun(Mtx drawMtx, cXyz* ppos, GXColor& unused, u8** tex) { GXSetTevColorOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); GXSetTevAlphaIn(GX_TEVSTAGE2, GX_CA_ZERO, GX_CA_TEXA, GX_CA_APREV, GX_CA_ZERO); GXSetTevAlphaOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_COPY); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_COPY); GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_DISABLE); GXSetNumIndStages(0); @@ -2589,7 +2589,7 @@ void dKyr_drawSun(Mtx drawMtx, cXyz* ppos, GXColor& unused, u8** tex) { GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO); GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_ONE, GX_LO_COPY); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_COPY); size *= 2.3f; color_reg0.a = 40.0f * sun_packet->mMoonAlpha; @@ -2753,7 +2753,7 @@ void dKyr_drawLenzflare(Mtx drawMtx, cXyz* ppos, GXColor& param_2, u8** tex) { GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO); GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetFog(GX_FOG_NONE, 0.0f, 1.0f, 0.1f, 1.0f, color_reg0); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); GXSetZCompLoc(GX_TRUE); GXSetZMode(GX_DISABLE, GX_LEQUAL, GX_DISABLE); @@ -2933,7 +2933,7 @@ void dKyr_drawLenzflare(Mtx drawMtx, cXyz* ppos, GXColor& param_2, u8** tex) { GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO); GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetFog(GX_FOG_NONE, 0.0f, 1.0f, 0.1f, 1.0f, color_reg0); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); GXSetZCompLoc(GX_TRUE); GXSetZMode(GX_DISABLE, GX_LEQUAL, GX_DISABLE); @@ -2965,7 +2965,7 @@ void dKyr_drawLenzflare(Mtx drawMtx, cXyz* ppos, GXColor& param_2, u8** tex) { color_reg0.a = sun_packet->field_0x6c * (0.2f * (spC4 * col_dat[i].a)); } } else if (i == 2) { - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_ONE, GX_LO_COPY); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_COPY); GXColorS10 spD0; spD0.r = 0.5f * sun_packet->mColor.r; spD0.g = 0.5f * sun_packet->mColor.g; @@ -3153,7 +3153,7 @@ void dKyr_drawRain(Mtx drawMtx, u8** tex) { GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO); GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_DISABLE); GXSetClipMode(GX_CLIP_DISABLE); @@ -3320,7 +3320,7 @@ void dKyr_drawSibuki(Mtx drawMtx, u8** tex) { GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO); GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_ONE, GX_LO_COPY); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_COPY); GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); GXSetZMode(GX_TRUE, GX_GEQUAL, GX_FALSE); GXSetClipMode(GX_CLIP_DISABLE); @@ -3501,9 +3501,9 @@ void dKyr_drawHousi(Mtx drawMtx, u8** tex) { if (strcmp(dComIfGp_getStartStageName(), "F_NW01") == 0 || g_env_light.field_0xea9 == 1) { - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_ONE, GX_LO_COPY); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_COPY); } else { - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); } @@ -3828,7 +3828,7 @@ void dKyr_drawSnow(Mtx drawMtx, u8** tex) { GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO); GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_ONE, GX_LO_COPY); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_COPY); GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_DISABLE); GXSetClipMode(GX_CLIP_DISABLE); @@ -4136,7 +4136,7 @@ void dKyr_drawStar(Mtx drawMtx, u8** tex) { GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0); GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_DISABLE); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); GXSetNumIndStages(0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0); @@ -4378,9 +4378,9 @@ void drawCloudShadow(Mtx drawMtx, u8** tex) { dKy_GxFog_set(); if (g_env_light.mMoyaMode == 3 || g_env_light.mMoyaMode == 4 || g_env_light.mMoyaMode == 6 || g_env_light.mMoyaMode == 10 || g_env_light.mMoyaMode == 11) { - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_ONE, GX_LO_COPY); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_COPY); } else { - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); } GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); @@ -4451,7 +4451,7 @@ void drawCloudShadow(Mtx drawMtx, u8** tex) { GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO); GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_COPY); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_COPY); GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); GXSetZCompLoc(GX_TRUE); GXSetZMode(GX_DISABLE, GX_LEQUAL, GX_DISABLE); @@ -4653,7 +4653,7 @@ void drawVrkumo(Mtx drawMtx, GXColor& color, u8** tex) { GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO); GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetFog(GX_FOG_NONE, 0.0f, 1.0f, 0.1f, 1.0f, color); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); if (pass == 0) { GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); @@ -5414,7 +5414,7 @@ void dKyr_odour_draw(Mtx drawMtx, u8** tex) { GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO); GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_COPY); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_COPY); GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); GXSetZCompLoc(GX_TRUE); GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_DISABLE); @@ -5781,7 +5781,7 @@ void dKyr_mud_draw(Mtx drawMtx, u8** tex) { GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO); GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); if (g_env_light.camera_water_in_status != 0) { @@ -5955,7 +5955,7 @@ static void dKyr_evil_draw2(Mtx drawMtx, u8** tex) { GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_TEXA, GX_CA_A0, GX_CA_ZERO); GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_COPY); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_COPY); GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); GXSetZCompLoc(GX_TRUE); GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_DISABLE); @@ -6181,7 +6181,7 @@ void dKyr_evil_draw(Mtx drawMtx, u8** tex) { GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_TEXA, GX_CA_A0, GX_CA_ZERO); GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); GXSetZCompLoc(GX_TRUE); GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_DISABLE); diff --git a/src/d/d_kyeff.cpp b/src/d/d_kyeff.cpp index dd052dd769..2f2f9810b4 100644 --- a/src/d/d_kyeff.cpp +++ b/src/d/d_kyeff.cpp @@ -59,7 +59,7 @@ static int dKyeff_Create(kankyo_class* i_this) { OSTicksToCalendarTime(OSGetTime(), &time); g_env_light.global_wind_influence.vec.set(1.0f, 0.0f, 0.0f); g_env_light.global_wind_influence.pow = 0.7f; - g_env_light.daytime = time.hours * 15.0f; + g_env_light.daytime = time.hour * 15.0f; } return cPhs_COMPLEATE_e; diff --git a/src/d/d_map_path.cpp b/src/d/d_map_path.cpp index a555813ad9..1f3e99b3f2 100644 --- a/src/d/d_map_path.cpp +++ b/src/d/d_map_path.cpp @@ -133,7 +133,7 @@ void dDrawPath_c::drawPath() { * makeResTIMG__15dRenderingMap_cCFP7ResTIMGUsUsPUcPUcUs */ void dRenderingMap_c::makeResTIMG(ResTIMG* p_image, u16 width, u16 height, u8* p_data, u8* p_palette, u16 param_5) const { - p_image->format = GX_TF_CI14; + p_image->format = GX_TF_C8; p_image->alphaEnabled = 2; p_image->width = width; p_image->height = height; @@ -232,7 +232,7 @@ void dRenderingFDAmap_c::preRenderingMap() { GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); GXSetZCompLoc(GX_TRUE); GXSetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE); - GXSetBlendMode(GX_BM_NONE, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GXSetFog(GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, g_clearColor); GXSetCullMode(GX_CULL_NONE); GXSetDither(GX_FALSE); @@ -253,7 +253,7 @@ void dRenderingFDAmap_c::preRenderingMap() { void dRenderingFDAmap_c::postRenderingMap() { GXSetCopyFilter(GX_FALSE, NULL, GX_FALSE, NULL); GXSetTexCopySrc(0, 0, mTexWidth, mTexHeight); - GXSetTexCopyDst(mTexWidth, mTexHeight, GX_CTF_G8, GX_FALSE); + GXSetTexCopyDst(mTexWidth, mTexHeight, GX_CTF_R8, GX_FALSE); GXCopyTex(field_0x4, GX_TRUE); GXPixModeSync(); GXSetClipMode(GX_CLIP_ENABLE); @@ -337,4 +337,4 @@ const GXColor* dRenderingFDAmap_c::getDecoLineColor(int param_0, int param_1) { * getDecorationLineWidth__18dRenderingFDAmap_cFi */ s32 dRenderingFDAmap_c::getDecorationLineWidth(int param_0) { return getLineWidth(param_0); -} \ No newline at end of file +} diff --git a/src/d/d_menu_fmap_map.cpp b/src/d/d_menu_fmap_map.cpp index 2e909d0926..23b1f09fdd 100644 --- a/src/d/d_menu_fmap_map.cpp +++ b/src/d/d_menu_fmap_map.cpp @@ -689,7 +689,7 @@ const GXColor* dMenu_FmapMap_c::getColor(int param_0) { void dMenu_FmapMap_c::setTexture(u16 i_width, u16 i_height, u16 param_2, u16 param_3) { mMapImage_p = NULL; mResTIMG = NULL; - int size = GXGetTexBufferSize(i_width, i_height, GX_TF_CI14, 0, 0); + int size = GXGetTexBufferSize(i_width, i_height, GX_TF_C8, 0, 0); mMapImage_p = new (0x20) u8[size]; init(mMapImage_p, i_width, i_height, param_2, param_3); mResTIMG = new (0x20) ResTIMG(); diff --git a/src/d/d_menu_option.cpp b/src/d/d_menu_option.cpp index 9bf2b01c37..b3aa25eeff 100644 --- a/src/d/d_menu_option.cpp +++ b/src/d/d_menu_option.cpp @@ -15,7 +15,7 @@ #include "d/d_meter_HIO.h" #include "d/d_meter_haihai.h" #include "d/d_msg_string.h" -#include "dolphin/os/OSRtc.h" +#include #include "dolphin/types.h" #include "f_op/f_op_msg_mng.h" #include "m_Do/m_Do_controller_pad.h" diff --git a/src/d/d_ovlp_fade2.cpp b/src/d/d_ovlp_fade2.cpp index a4f9928472..07a0e8c479 100644 --- a/src/d/d_ovlp_fade2.cpp +++ b/src/d/d_ovlp_fade2.cpp @@ -28,7 +28,7 @@ void dOvlpFd2_dlst_c::draw() { GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetZCompLoc(GX_TRUE); GXSetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE); - GXSetBlendMode(GX_BM_NONE, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); GXSetFog(GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, g_clearColor); GXSetCullMode(GX_CULL_NONE); @@ -68,7 +68,7 @@ void dOvlpFd2_dlst_c::draw() { GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetZCompLoc(GX_TRUE); GXSetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE); - GXSetBlendMode(GX_BM_NONE, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); GXSetFog(GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, g_clearColor); GXSetCullMode(GX_CULL_NONE); diff --git a/src/d/d_ovlp_fade3.cpp b/src/d/d_ovlp_fade3.cpp index 7151ff5e80..800f07a1e6 100644 --- a/src/d/d_ovlp_fade3.cpp +++ b/src/d/d_ovlp_fade3.cpp @@ -39,7 +39,7 @@ void dOvlpFd3_dlst_c::draw() { GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetZCompLoc(GX_TRUE); GXSetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE); - GXSetBlendMode(GX_BM_NONE, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); GXSetFog(GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, g_clearColor); GXSetCullMode(GX_CULL_NONE); @@ -79,7 +79,7 @@ void dOvlpFd3_dlst_c::draw() { GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetZCompLoc(GX_TRUE); GXSetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE); - GXSetBlendMode(GX_BM_NONE, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); GXSetFog(GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, g_clearColor); GXSetCullMode(GX_CULL_NONE); diff --git a/src/d/d_particle.cpp b/src/d/d_particle.cpp index 42215fea24..5d75deeb1d 100644 --- a/src/d/d_particle.cpp +++ b/src/d/d_particle.cpp @@ -284,7 +284,7 @@ static void drawSecond_light8(JPABaseEmitter* param_0) { GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); GXSetZMode(true, GX_LEQUAL, false); GXSetZCompLoc(0); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_SET); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GXSetNumChans(1); GXColor local_14; local_14.r = g_env_light.bg_amb_col[0].r; diff --git a/src/d/d_vibration.cpp b/src/d/d_vibration.cpp index 5c5ce4eb03..7e31e5fc39 100644 --- a/src/d/d_vibration.cpp +++ b/src/d/d_vibration.cpp @@ -2,6 +2,7 @@ #include "d/d_com_inf_game.h" #include "m_Do/m_Do_controller_pad.h" #include "SSystem/SComponent/c_math.h" +#include #define RESET_FRAME -99 @@ -204,7 +205,7 @@ int dVibration_c::Run() { length = mMotor.mQuake.mLength; pattern = rollshift(mMotor.mQuake.mPattern, length, mFrame); pattern |= randombit(mMotor.mQuake.mRounds, length); - mMotor.mQuake.mStopFrame = INT32_MAX; + mMotor.mQuake.mStopFrame = INT_MAX; mDoCPd_c::startMotorWave(PAD_1, makedata(data, pattern, length), JUTGamePad::CRumble::VAL_1, 60); break; case RUMBLE_SHOCK | RUMBLE_QUAKE: diff --git a/src/dolphin/G2D/G2D.c b/src/dolphin/G2D/G2D.c new file mode 100644 index 0000000000..351a5046f5 --- /dev/null +++ b/src/dolphin/G2D/G2D.c @@ -0,0 +1,721 @@ +#include +#include +#include +#include "fake_tgmath.h" + +static G2DGlob glob; + +void G2DInitSprite(G2DSprite *sprite) { + f32 rInvWidth; + f32 rInvHeight; + + rInvWidth = 1.0f / (f32)GXGetTexObjWidth(sprite->to); + rInvHeight = 1.0f / (f32)GXGetTexObjHeight(sprite->to); + sprite->rS0 = (0.5f + (f32)sprite->nTlcS) * rInvWidth; + sprite->rS1 = rInvWidth * (((f32)sprite->nTlcS + (f32)sprite->nWidth) - 0.5f); + sprite->rT0 = (0.5f + (f32)sprite->nTlcT) * rInvHeight; + sprite->rT1 = rInvHeight * (((f32)sprite->nTlcT + (f32)sprite->nHeight) - 0.5f); +} + +void G2DDrawSprite(G2DSprite* sprite, G2DPosOri* po) { + f32 rOX, rOY; + f32 rWX, rWY; + f32 rHX, rHY; + f32 rRelX, rRelY; + + GXClearVtxDesc(); + GXLoadTexObj(sprite->to, GX_TEXMAP0); + + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + GXSetNumTexGens(1); + GXSetNumChans(0); + + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); + + rOX = 0.5f * po->rOriX; + rOY = 0.5f * po->rOriY; + + rWX = (f32)sprite->nWidth * rOX; + rWY = (f32)sprite->nWidth * rOY; + rHX = (f32)sprite->nHeight * rOX; + rHY = (f32)sprite->nHeight * rOY; + + rRelX = po->rPosX - glob.poCam.rPosX; + rRelY = po->rPosY - glob.poCam.rPosY; + if (rRelX >= glob.rHalfX) { + rRelX -= glob.rWorldX; + } + if (rRelX < -glob.rHalfX) { + rRelX += glob.rWorldX; + } + if (rRelY >= glob.rHalfY) { + rRelY -= glob.rWorldY; + } + if (rRelY < -glob.rHalfY) { + rRelY += glob.rWorldY; + } + + rRelX += glob.poCam.rPosX; + rRelY += glob.poCam.rPosY; + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + + GXPosition2f32(rWY + (rRelX - rHX), (rRelY - rHY) - rWX); + GXTexCoord2f32(sprite->rS0, sprite->rT1); + + GXPosition2f32(rWY + (rRelX + rHX), (rRelY + rHY) - rWX); + GXTexCoord2f32(sprite->rS0, sprite->rT0); + + GXPosition2f32((rRelX + rHX) - rWY, rWX + (rRelY + rHY)); + GXTexCoord2f32(sprite->rS1, sprite->rT0); + + GXPosition2f32((rRelX - rHX) - rWY, rWX + (rRelY - rHY)); + GXTexCoord2f32(sprite->rS1, sprite->rT1); + + GXEnd(); +} + +static inline void FillSection(G2DLayer* layer, s8* aSortBuffer, s32* nScanLine, s32 nEvent, s16* nIdx, + s32* nL, s32* nR, f32* rLeft, f32* rRight, f32 rStep0, f32 rStep1, s32 nMapX, + s32 nMapY) { + s32 nHMask; + s32 nVMask; + s32 nI; + s32 nJ; + s32 nK; + s32 nM; + s16 nMaterial; + s16* pAddr; + + nHMask = (1 << layer->nHS) - 1; + nVMask = (1 << layer->nVS) - 1; + if (layer->nBPI == 1) { + u8 nTile; + if (layer->bWrap) { + for (; *nScanLine <= nEvent; (*nScanLine)++) { + nJ = *nScanLine - 1; + nK = (nVMask & (nJ + nMapY)) << layer->nHS; + for (nI = *nL; nI <= *nR; nI++) { + nTile = ((u8*)layer->map)[nK + (nHMask & (nI + nMapX))]; + nMaterial = layer->tileDesc[nTile].nMaterial; + pAddr = (s16*)&layer->matDesc[nMaterial].nReserved; + pAddr[1]++; + + if (*pAddr != *nIdx) { + *nIdx += 2; + *(s16*)&aSortBuffer[*pAddr] = *pAddr - *nIdx; + } + *(s16*)&aSortBuffer[*nIdx] = nTile; + *nIdx += 2; + aSortBuffer[(*nIdx)++] = nI; + aSortBuffer[(*nIdx)++] = nJ; + *pAddr = *nIdx; + } + *rLeft += rStep0; + *rRight += rStep1; + *nL = floor(*rLeft); + *nR = floor(*rRight); + } + } else { + for (; *nScanLine <= nEvent; (*nScanLine)++) { + nJ = *nScanLine - 1 + nMapY; + if (nJ < 0) { + nK = 0; + } + else if ( nJ > nVMask ) { + nK = nVMask << layer->nHS; + } + else { + nK = nJ << layer->nHS; + } + + nM = *nR + nMapX; + for (nI = *nL + nMapX; nI <= nM; nI++) { + if ( nI < 0 ) { + nTile = ((u8*)layer->map)[nK]; + } + else if ( nI > nHMask ) { + nTile = ((u8*)layer->map)[nK + nHMask]; + } + else { + nTile = ((u8*)layer->map)[nK + nI]; + } + + nMaterial = layer->tileDesc[nTile].nMaterial; + pAddr = (s16*)&layer->matDesc[nMaterial].nReserved; + pAddr[1]++; + + if (*pAddr != *nIdx) { + *nIdx += 2; + *(s16*)&aSortBuffer[*pAddr] = *pAddr - *nIdx; + } + *(s16*)&aSortBuffer[*nIdx] = nTile; + *nIdx += 2; + aSortBuffer[(*nIdx)++] = nI - nMapX; + aSortBuffer[(*nIdx)++] = nJ - nMapY; + *pAddr = *nIdx; + } + + *rLeft += rStep0; + *rRight += rStep1; + *nL = floor(*rLeft); + *nR = floor(*rRight); + } + } + } else { + u16 nTile; + if (layer->bWrap) { + for (; *nScanLine <= nEvent; (*nScanLine)++) { + nJ = *nScanLine - 1; + nK = (nVMask & (nJ + nMapY)) << layer->nHS; + for (nI = *nL; nI <= *nR; nI++) { + nTile = ((u16*)layer->map)[nK + (nHMask & (nI + nMapX))]; + nMaterial = layer->tileDesc[nTile].nMaterial; + pAddr = (s16*)&layer->matDesc[nMaterial].nReserved; + pAddr[1]++; + + if (*pAddr != *nIdx) { + *nIdx += 2; + *(s16*)&aSortBuffer[*pAddr] = *pAddr - *nIdx; + } + *(s16*)&aSortBuffer[*nIdx] = nTile; + *nIdx += 2; + aSortBuffer[(*nIdx)++] = nI; + aSortBuffer[(*nIdx)++] = nJ; + *pAddr = *nIdx; + } + + *rLeft += rStep0; + *rRight += rStep1; + *nL = floor(*rLeft); + *nR = floor(*rRight); + } + } else { + for (; *nScanLine <= nEvent; (*nScanLine)++) { + nJ = *nScanLine - 1 + nMapY; + if (nJ < 0) { + nK = 0; + } + else if ( nJ > nVMask ) { + nK = nVMask << layer->nHS; + } + else { + nK = nJ << layer->nHS; + } + + nM = *nR + nMapX; + for (nI = *nL + nMapX; nI <= nM; nI++) { + if ( nI < 0 ) { + nTile = ((u16*)layer->map)[nK]; + } + else if ( nI > nHMask ) { + nTile = ((u16*)layer->map)[nK + nHMask]; + } + else { + nTile = ((u16*)layer->map)[nK + nI]; + } + + nMaterial = layer->tileDesc[nTile].nMaterial; + pAddr = (s16*)&layer->matDesc[nMaterial].nReserved; + pAddr[1]++; + + if (*pAddr != *nIdx) { + *nIdx += 2; + *(s16*)&aSortBuffer[*pAddr] = *pAddr - *nIdx; + } + *(s16*)&aSortBuffer[*nIdx] = nTile; + *nIdx += 2; + aSortBuffer[(*nIdx)++] = nI - nMapX; + aSortBuffer[(*nIdx)++] = nJ - nMapY; + *pAddr = *nIdx; + } + + *rLeft += rStep0; + *rRight += rStep1; + *nL = floor(*rLeft); + *nR = floor(*rRight); + } + } + } +} + +void G2DDrawLayer(G2DLayer* layer, s8* aSortBuffer) { + s16* pAddr; + s16 aCount0; + s16 aCount1; + s16 aCount2; + f32 rInvTileWidth; + f32 rInvTileHeight; + s16 nIdx; + s32 nI; + s32 nJ; + s32 nK; + s32 nL; + s32 nR; + f32 rX; + f32 rY; + f32 rTlcX; + f32 rTrcX; + f32 rBlcX; + f32 rBrcX; + f32 rTlcY; + f32 rTrcY; + f32 rBlcY; + f32 rBrcY; + s32 nScanLine; + f32 rLeft; + f32 rRight; + f32 rLeftY; + f32 rRightY; + f32 rStep0; + f32 rStep1; + f32 rMid; + s32 nEvent0; + s32 nEvent1; + s32 nEvent2; + f32 rFrcX; + f32 rFrcY; + s32 nMapX; + s32 nMapY; + s32 nLocalMapX; + s32 nLocalMapY; + f32 rCamOriX; + f32 rCamOriY; + s16 nTile; + s16 nMaterial; + f32 rRatio; + + aCount0 = 0; + aCount1 = 0; + aCount2 = 0; + rInvTileWidth = 1.0f / (f32)layer->nTileWidth; + rInvTileHeight = 1.0f / (f32)layer->nTileHeight; + + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); + + for (nI = 0; nI < layer->nNumMaterials; nI++) { + pAddr = (s16*)&layer->matDesc[nI]; + pAddr[0] = nI << 1; + pAddr[1] = 0; + } + nIdx = (nI - 1) << 1; + + rFrcX = glob.poCam.rPosX * rInvTileWidth; + rFrcY = glob.poCam.rPosY * rInvTileHeight; + nMapX = (s32)rFrcX; + nMapY = (s32)rFrcY; + rFrcX -= nMapX; + rFrcY -= nMapY; + + rCamOriX = glob.poCam.rOriX; + rCamOriY = glob.poCam.rOriY; + if (rCamOriX < 0.0001 && rCamOriX > -0.0001) { + rCamOriX = 0.0001f; + } + else if (rCamOriY < 0.0001 && rCamOriY > -0.0001) { + rCamOriY = 0.0001f; + } + + rX = 0.5f * (f32)glob.nViewportWidth; + rY = 0.5f * (f32)glob.nViewportHeight; + rTlcX = rFrcX + (rInvTileWidth * ((rY * rCamOriX) + (rX * rCamOriY))); + rTlcY = (rFrcY + (rInvTileHeight * ((rY * rCamOriY) - (rX * rCamOriX)))); + rTrcX = rFrcX + (rInvTileWidth * ((rY * rCamOriX) - (rX * rCamOriY))); + rTrcY = (rFrcY + (rInvTileHeight * ((rY * rCamOriY) + (rX * rCamOriX)))); + rBlcX = rFrcX - (rInvTileWidth * ((rY * rCamOriX) - (rX * rCamOriY))); + rBlcY = rFrcY - (rInvTileHeight * ((rY * rCamOriY) + (rX * rCamOriX))); + rBrcX = rFrcX - (rInvTileWidth * ((rY * rCamOriX) + (rX * rCamOriY))); + rBrcY = rFrcY - (rInvTileHeight * ((rY * rCamOriY) - (rX * rCamOriX))); + + if (rCamOriY < 0.0f) { + if (rCamOriX >= 0.0f) { + nScanLine = (s32)floor(rTlcY) + 1; + rY = nScanLine - rTlcY; + rLeft = rTlcX; + rLeftY = rBlcY; + rRightY = rTrcY; + nEvent2 = (s32)floor(rBrcY); + rStep0 = rCamOriX / rCamOriY; + rStep1 = -rCamOriY / rCamOriX; + } + else { + nScanLine = (s32)floor(rTrcY) + 1; + rY = nScanLine - rTrcY; + rLeft = rTrcX; + rLeftY = rTlcY; + rRightY = rBrcY; + nEvent2 = (s32)floor(rBlcY); + rStep0 = -rCamOriY / rCamOriX; + rStep1 = rCamOriX / rCamOriY; + } + } else { + if (rCamOriX >= 0.0f) { + nScanLine = (s32)floor(rBlcY) + 1; + rY = nScanLine - rBlcY; + rLeft = rBlcX; + rLeftY = rBrcY; + rRightY = rTlcY; + nEvent2 = (s32)floor(rTrcY); + rStep0 = -rCamOriY / rCamOriX; + rStep1 = rCamOriX / rCamOriY; + } else { + nScanLine = (s32)floor(rBrcY) + 1; + rY = nScanLine - rBrcY; + rLeft = rBrcX; + rLeftY = rTrcY; + rRightY = rBlcY; + nEvent2 = (s32)floor(rTlcY); + rStep0 = rCamOriX / rCamOriY; + rStep1 = -rCamOriY / rCamOriX; + } + } + + rRatio = (f32)layer->nTileHeight / (f32)layer->nTileWidth; + rStep0 *= rRatio; + rStep1 *= rRatio; + rRight = rLeft + (rY * rStep1); + rLeft = rLeft + (rY * rStep0); + + if (rLeftY < rRightY) { + nEvent0 = (s32)floor(rLeftY); + nEvent1 = (s32)floor(rRightY); + rMid = rStep1; + } else { + nEvent0 = (s32)floor(rRightY); + nEvent1 = (s32)floor(rLeftY); + rMid = rStep0; + } + + nL = (s32)floor(rLeft); + nR = (s32)floor(rRight); + nLocalMapX = nMapX; + nLocalMapY = nMapY; + + if (!layer->bWrap) { + f32 rInvTileWidth = 1.0f / (f32)layer->nTileWidth; + f32 rInvTileHeight = 1.0f / (f32)layer->nTileHeight; + f32 rLocalPosX = glob.poCam.rPosX; + f32 rLocalPosY = glob.poCam.rPosY; + f32 rSplitX = 0.5f * (glob.rWorldX + (f32)(layer->nTileWidth * (1 << layer->nHS))); + f32 rSplitY = 0.5f * (glob.rWorldY + (f32)(layer->nTileHeight * (1 << layer->nVS))); + + if (rLocalPosX >= rSplitX) { + rLocalPosX -= glob.rWorldX; + } + + if (rLocalPosY >= rSplitY) { + rLocalPosY -= glob.rWorldY; + } + + rFrcX = rLocalPosX * rInvTileWidth; + rFrcY = rLocalPosY * rInvTileHeight; + + nLocalMapX = floor(rFrcX); + nLocalMapY = floor(rFrcY); + } + + FillSection(layer, aSortBuffer, &nScanLine, nEvent0, &nIdx, &nL, &nR, &rLeft, &rRight, rStep0, rStep1, nLocalMapX, nLocalMapY); + + pAddr = (s16*)&layer->matDesc[0].nReserved; + aCount0 = pAddr[1]; + pAddr = (s16*)&layer->matDesc[1].nReserved; + aCount1 = pAddr[1]; + pAddr = (s16*)&layer->matDesc[2].nReserved; + aCount2 = pAddr[1]; + + if ((f32)nScanLine > rLeftY) { + rLeft -= rStep0 * ((f32)nScanLine - rLeftY); + nL = (s32)floor(rLeft); + rLeft += rStep1 * (((f32)nScanLine - rLeftY) - 1.0f); + rLeftY = 1000.0f; + } + + if ((f32)nScanLine > rRightY) { + rRight -= rStep1 * ((f32)nScanLine - rRightY); + nR = (s32)floor(rRight); + rRight += rStep0 * (((f32)nScanLine - rRightY) - 1.0f); + rRightY = 1000.0f; + } + + FillSection(layer, aSortBuffer, &nScanLine, nEvent1, &nIdx, &nL, &nR, &rLeft, &rRight, rMid, rMid, nLocalMapX, nLocalMapY); + + pAddr = (s16*)&layer->matDesc[0].nReserved; + aCount0 = pAddr[1]; + pAddr = (s16*)&layer->matDesc[1].nReserved; + aCount1 = pAddr[1]; + pAddr = (s16*)&layer->matDesc[2].nReserved; + aCount2 = pAddr[1]; + + if ((f32)nScanLine > rLeftY) { + rLeft -= rStep0 * ((f32)nScanLine - rLeftY); + nL = (s32)floor(rLeft); + rLeft += rStep1 * (((f32)nScanLine - rLeftY) - 1.0f); + } + + if ((f32)nScanLine > rRightY) { + rRight -= rStep1 * ((f32)nScanLine - rRightY); + nR = (s32)floor(rRight); + rRight += rStep0 * (((f32)nScanLine - rRightY) - 1.0f); + } + + FillSection(layer, aSortBuffer, &nScanLine, nEvent2 + 1, &nIdx, &nL, &nR, &rLeft, &rRight, rStep1, rStep0, nLocalMapX, nLocalMapY); + + pAddr = (s16*)&layer->matDesc[0].nReserved; + aCount0 = pAddr[1]; + pAddr = (s16*)&layer->matDesc[1].nReserved; + aCount1 = pAddr[1]; + pAddr = (s16*)&layer->matDesc[2].nReserved; + aCount2 = pAddr[1]; + + for (nMaterial = 0; nMaterial < layer->nNumMaterials; nMaterial++) { + pAddr = (s16*)&layer->matDesc[nMaterial].nReserved; + if (!pAddr[1]) { + continue; + } + + switch (layer->matDesc[nMaterial].nCategory) { + case G2D_CTG_EMPTY: + continue; + + case G2D_CTG_RGBA_INDEX8: { + GXClearVtxDesc(); + + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + + GXSetNumTexGens(0); + GXSetVtxDesc(GX_VA_TEX0, GX_NONE); + GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + GXSetVtxDesc(GX_VA_CLR0, GX_INDEX8); + GXSetArray(GX_VA_CLR0, layer->matDesc[nMaterial].clut, 4); + + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0A0, 0, GX_SRC_VTX, GX_SRC_VTX, 1, GX_DF_NONE, GX_AF_NONE); + + nIdx = nMaterial << 1; + GXBegin(GX_QUADS, GX_VTXFMT0, pAddr[1] << 2); + + for (nK = pAddr[1]; nK--; ) { + f32 rI, rJ; + u8 nCI; + + nTile = *((s16*)&aSortBuffer[nIdx]); + if (nTile < 0) { + nIdx -= nTile; + nTile = *((s16*)&aSortBuffer[nIdx]); + } + nIdx += 2; + nI = aSortBuffer[nIdx++]; + nJ = aSortBuffer[nIdx++]; + + rI = (f32)layer->nTileWidth * (f32)(nI + nMapX); + rJ = (f32)layer->nTileHeight * (f32)(nJ + nMapY); + nCI = layer->tileDesc[nTile].nCI; + + GXPosition2f32(rI + (f32)layer->nTileWidth, rJ); + GXColor1x8(nCI); + + GXPosition2f32(rI + (f32)layer->nTileWidth, rJ + (f32)layer->nTileHeight); + GXColor1x8(nCI); + + GXPosition2f32(rI, rJ + (f32)layer->nTileHeight); + GXColor1x8(nCI); + + GXPosition2f32(rI, rJ); + GXColor1x8(nCI); + } + + GXEnd(); + break; + } + + case G2D_CTG_RGB_DIRECT: { + GXClearVtxDesc(); + + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + + GXSetNumTexGens(0); + GXSetVtxDesc(GX_VA_TEX0, GX_NONE); + GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGB, GX_RGB8, 0); + GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT); + + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0A0, 0, GX_SRC_VTX, GX_SRC_VTX, 1, GX_DF_NONE, GX_AF_NONE); + + nIdx = nMaterial << 1; + GXBegin(GX_QUADS, GX_VTXFMT0, pAddr[1] << 2); + + for (nK = pAddr[1]; nK--; ) { + f32 rI, rJ; + u8 nR, nG, nB; + + nTile = *((s16*)&aSortBuffer[nIdx]); + if (nTile < 0) { + nIdx -= nTile; + nTile = *((s16*)&aSortBuffer[nIdx]); + } + + nIdx += 2; + nI = aSortBuffer[nIdx++]; + nJ = aSortBuffer[nIdx++]; + + rI = (f32)layer->nTileWidth * (f32)(nI + nMapX); + rJ = (f32)layer->nTileHeight * (f32)(nJ + nMapY); + nR = layer->tileDesc[nTile].nS; + nG = layer->tileDesc[nTile].nT; + nB = layer->tileDesc[nTile].nCI; + + GXPosition2f32(rI + (f32)layer->nTileWidth, rJ); + GXColor3u8(nR, nG, nB); + + GXPosition2f32(rI + (f32)layer->nTileWidth, rJ + (f32)layer->nTileHeight); + GXColor3u8(nR, nG, nB); + + GXPosition2f32(rI, rJ + (f32)layer->nTileHeight); + GXColor3u8(nR, nG, nB); + + GXPosition2f32(rI, rJ); + GXColor3u8(nR, nG, nB); + } + + GXEnd(); + break; + } + + case G2D_CTG_TEXTURE: { + f32 rInvTileWidth = 1.0f / (f32)GXGetTexObjWidth(layer->matDesc[nMaterial].to); + f32 rInvTileHeight = 1.0f / (f32)GXGetTexObjHeight(layer->matDesc[nMaterial].to); + + f32 rWidth = (f32)layer->nTileWidth * rInvTileWidth; + f32 rHeight = (f32)layer->nTileHeight * rInvTileHeight; + + f32 rS0 = 0.0f; + f32 rT0 = 0.0f; + f32 rS1 = rWidth; + f32 rT1 = rHeight; + + GXClearVtxDesc(); + + GXLoadTexObj(layer->matDesc[nMaterial].to, GX_TEXMAP0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + + GXSetNumTexGens(1); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + + if ( layer->matDesc[nMaterial].color ) { + GXSetNumChans(1); + GXSetChanMatColor(GX_COLOR0A0, *layer->matDesc[nMaterial].color); + GXSetChanCtrl(GX_COLOR0A0, 0, GX_SRC_REG, GX_SRC_REG, 1, GX_DF_NONE, GX_AF_NONE); + GXSetTevOp(GX_TEVSTAGE0, GX_MODULATE); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + } else { + GXSetNumChans(0); + GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + } + + nIdx = nMaterial << 1; + GXBegin(GX_QUADS, GX_VTXFMT0, pAddr[1] << 2); + + for (nK = pAddr[1]; nK--; ) { + f32 rI; + f32 rJ; + f32 rS; + f32 rT; + + nTile = *((s16*)&aSortBuffer[nIdx]); + if (nTile < 0) { + nIdx -= nTile; + nTile = *((s16*)&aSortBuffer[nIdx]); + } + + nIdx += 2; + nI = aSortBuffer[nIdx++]; + nJ = aSortBuffer[nIdx++]; + + rS = rS0 + (rWidth * (f32)layer->tileDesc[nTile].nS); + rT = rT0 + (rHeight * (f32)layer->tileDesc[nTile].nT); + rI = (f32)layer->nTileWidth * (f32)(nI + nMapX); + rJ = (f32)layer->nTileHeight * (f32)(nJ + nMapY); + + GXPosition2f32(rI + (f32)layer->nTileWidth, rJ); + GXTexCoord2f32(rS + rS1, rT); + + GXPosition2f32(rI + (f32)layer->nTileWidth, rJ + (f32)layer->nTileHeight); + GXTexCoord2f32(rS + rS1, rT + rT1); + + GXPosition2f32(rI, rJ + (f32)layer->nTileHeight); + GXTexCoord2f32(rS, rT + rT1); + + GXPosition2f32(rI, rJ); + GXTexCoord2f32(rS, rT); + } + + GXEnd(); + break; + } + } + } +} + +void G2DSetCamera(G2DPosOri* po) { + Mtx mView; + Vec vPos; + Vec vUp; + Vec vAt; + f32 rX; + f32 rY; + + glob.poCam = *po; + + vUp.x = po->rOriX; + vUp.y = po->rOriY; + vUp.z = 0.0f; + + rX = (((640 - glob.nViewportWidth) >> 1) - glob.nViewportTlcX); + rY = (((448 - glob.nViewportHeight) >> 1) - glob.nViewportTlcY); + + vPos.x = po->rPosX - (vUp.x * rY) - (vUp.y * rX); + vPos.y = po->rPosY + (vUp.x * rX) - (vUp.y * rY); + vPos.z = -300.0f; + + vAt.x = vPos.x; + vAt.y = vPos.y; + vAt.z = 0.0f; + + MTXLookAt(mView, &vPos, &vUp, &vAt); + GXLoadPosMtxImm(mView, GX_PNMTX0); +} + +void G2DInitWorld(u32 nWorldX, u32 nWorldY) { + Mtx44 mProjection; + + glob.rWorldX = (f32)nWorldX; + glob.rWorldY = (f32)nWorldY; + glob.rHalfX = (f32)(nWorldX >> 1); + glob.rHalfY = (f32)(nWorldY >> 1); + GXSetZMode(0, GX_ALWAYS, 1); + MTXOrtho(mProjection, 224.0f, -224.0f, -320.0f, 320.0f, 100.0f, 1000.0f); + GXSetProjection(mProjection, GX_ORTHOGRAPHIC); +} + +void G2DSetViewport(u16 nLeft, u16 nTop, u16 nWidth, u16 nHeight) { + glob.nViewportTlcX = nLeft; + glob.nViewportTlcY = nTop; + glob.nViewportWidth = nWidth; + glob.nViewportHeight = nHeight; + GXSetScissor(nLeft, nTop, nWidth, nHeight); +} diff --git a/src/dolphin/ai/ai.c b/src/dolphin/ai/ai.c index 704c6e070d..c9c38ee265 100644 --- a/src/dolphin/ai/ai.c +++ b/src/dolphin/ai/ai.c @@ -1,206 +1,116 @@ -#include "dolphin/ai.h" -#include "dolphin/dsp.h" -#include "dolphin/os.h" +#include +#include +#include +#include -/* 80450A40-80450A48 -00001 0004+04 1/1 0/0 0/0 .sdata __AIVersion */ -char* __AIVersion = "<< Dolphin SDK - AI\trelease build: Apr 5 2004 04:15:02 (0x2301) >>"; +#include "__gx.h" -void __AISHandler(s16 interrupt, OSContext* context); -void __AIDHandler(s16 interrupt, OSContext* context); -void __AICallbackStackSwitch(AIDCallback callback); -void __AI_SRC_INIT(void); +#ifdef DEBUG +const char* __AIVersion = "<< Dolphin SDK - AI\tdebug build: Apr 5 2004 03:56:18 (0x2301) >>"; +#else +const char* __AIVersion = "<< Dolphin SDK - AI\trelease build: Apr 5 2004 04:15:02 (0x2301) >>"; +#endif -/* ############################################################################################## */ -/* 80451878-8045187C 000D78 0004+00 2/2 0/0 0/0 .sbss __AIS_Callback */ static AISCallback __AIS_Callback; - -/* 8045187C-80451880 000D7C 0004+00 3/3 0/0 0/0 .sbss __AID_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; + +typedef struct { + OSTime t_start; + OSTime t1; + OSTime t2; + OSTime t3; + OSTime t4; + OSTime t_end; +} STRUCT_TIMELOG; +STRUCT_TIMELOG profile; + +OSTime __ai_src_time_start; +OSTime __ai_src_time_end; + +// prototypes +void __AI_DEBUG_set_stream_sample_rate(u32 rate); +STRUCT_TIMELOG* __ai_src_get_time(void); + +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); -/* 8034FC70-8034FCB4 34A5B0 0044+00 0/0 1/1 0/0 .text AIRegisterDMACallback */ AIDCallback AIRegisterDMACallback(AIDCallback callback) { - s32 oldInts; - AIDCallback ret; + AIDCallback old_callback; + BOOL old; - ret = __AID_Callback; - oldInts = OSDisableInterrupts(); + old_callback = __AID_Callback; + old = OSDisableInterrupts(); __AID_Callback = callback; - OSRestoreInterrupts(oldInts); - return ret; + OSRestoreInterrupts(old); + return old_callback; } -/* 8034FCB4-8034FD3C 34A5F4 0088+00 0/0 2/2 0/0 .text AIInitDMA */ -void AIInitDMA(u32 addr, u32 length) { - s32 oldInts; - oldInts = OSDisableInterrupts(); - __DSPRegs[24] = (u16)((__DSPRegs[24] & ~0x3FF) | (addr >> 16)); - __DSPRegs[25] = (u16)((__DSPRegs[25] & ~0xFFE0) | (0xffff & addr)); - __DSPRegs[27] = (u16)((__DSPRegs[27] & ~0x7FFF) | (u16)((length >> 5) & 0xFFFF)); - OSRestoreInterrupts(oldInts); +void 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); +} + +BOOL AIGetDMAEnableFlag(void) { + return (__DSPRegs[27] & (1 << 15)) >> 15; } -/* 8034FD3C-8034FD54 34A67C 0018+00 0/0 1/1 0/0 .text AIStartDMA */ void AIStartDMA(void) { - __DSPRegs[27] |= 0x8000; + __DSPRegs[27] = __DSPRegs[27] | 0x8000; } -/* 8034FD54-8034FD6C 34A694 0018+00 0/0 1/1 0/0 .text AIStopDMA */ - void AIStopDMA(void) { - __DSPRegs[27] &= ~0x8000; + __DSPRegs[27] = __DSPRegs[27] & ~0x8000; } -/* 8034FD6C-8034FE44 34A6AC 00D8+00 1/1 1/1 0/0 .text AISetStreamPlayState */ -void AISetStreamPlayState(u32 state) { - s32 oldInts; - u8 volRight; - u8 volLeft; - - if (state == AIGetStreamPlayState()) { - return; - } - - if (AIGetStreamSampleRate() == 0 && state == 1) { - volRight = AIGetStreamVolRight(); - volLeft = AIGetStreamVolLeft(); - AISetStreamVolRight(0); - AISetStreamVolLeft(0); - oldInts = OSDisableInterrupts(); - __AI_SRC_INIT(); - __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20; - __AIRegs[0] = (__AIRegs[0] & ~1) | 1; - OSRestoreInterrupts(oldInts); - AISetStreamVolLeft(volRight); - AISetStreamVolRight(volLeft); - } else { - __AIRegs[0] = (__AIRegs[0] & ~1) | state; - } +u32 AIGetDMABytesLeft(void) { + return (__DSPRegs[29] & 0x7FFF) << 5; } -/* 8034FE44-8034FE54 34A784 0010+00 1/1 0/0 0/0 .text AIGetStreamPlayState */ -u32 AIGetStreamPlayState(void) { - return __AIRegs[0] & 1; +u32 AIGetDMAStartAddr(void) { + return ((__DSPRegs[24] << 16) & 0x03FF0000) | (__DSPRegs[25] & 0xFFE0); } -/* 8034FE54-8034FF34 34A794 00E0+00 1/1 1/1 0/0 .text AISetDSPSampleRate */ -void AISetDSPSampleRate(u32 rate) { - u32 state; - s32 oldInts; - u8 left; - u8 right; - u32 sampleRate; - - if (rate == AIGetDSPSampleRate()) { - return; - } - - __AIRegs[0] &= ~0x40; - if (rate == 0) { - left = AIGetStreamVolLeft(); - right = AIGetStreamVolRight(); - state = AIGetStreamPlayState(); - sampleRate = AIGetStreamSampleRate(); - AISetStreamVolLeft(0); - AISetStreamVolRight(0); - oldInts = OSDisableInterrupts(); - __AI_SRC_INIT(); - __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20; - __AIRegs[0] = (__AIRegs[0] & ~2) | (sampleRate * 2); - __AIRegs[0] = (__AIRegs[0] & ~1) | state; - __AIRegs[0] |= 0x40; - OSRestoreInterrupts(oldInts); - AISetStreamVolLeft(left); - AISetStreamVolRight(right); - } +u32 AIGetDMALength(void) { + return (__DSPRegs[27] & 0x7FFF) << 5; } -/* 8034FF34-8034FF48 34A874 0014+00 1/1 0/0 1/1 .text AIGetDSPSampleRate */ -u32 AIGetDSPSampleRate(void) { - return ((__AIRegs[0] >> 6) & 1) ^ 1; +BOOL AICheckInit(void) { + return __AI_init_flag; } -/* 8034FF48-8035001C 34A888 00D4+00 1/1 0/1 0/0 .text __AI_set_stream_sample_rate */ -void __AI_set_stream_sample_rate(u32 rate) { - s32 oldInts; - s32 state; - u8 left; - u8 right; - s32 temp_r26; +AISCallback AIRegisterStreamCallback(AISCallback callback) { + AISCallback old_callback; + BOOL old; - if (rate == AIGetStreamSampleRate()) { - return; - } - - state = AIGetStreamPlayState(); - left = AIGetStreamVolLeft(); - right = AIGetStreamVolRight(); - AISetStreamVolRight(0); - AISetStreamVolLeft(0); - temp_r26 = __AIRegs[0] & 0x40; - __AIRegs[0] &= ~0x40; - oldInts = OSDisableInterrupts(); - __AI_SRC_INIT(); - __AIRegs[0] |= temp_r26; - __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20; - __AIRegs[0] = (__AIRegs[0] & ~2) | (rate * 2); - OSRestoreInterrupts(oldInts); - AISetStreamPlayState(state); - AISetStreamVolLeft(left); - AISetStreamVolRight(right); + old_callback = __AIS_Callback; + old = OSDisableInterrupts(); + __AIS_Callback = callback; + OSRestoreInterrupts(old); + return old_callback; } -/* 8035001C-8035002C 34A95C 0010+00 3/3 0/0 0/0 .text AIGetStreamSampleRate */ -u32 AIGetStreamSampleRate(void) { - return (__AIRegs[0] >> 1) & 1; +u32 AIGetStreamSampleCount(void) { + return __AIRegs[2]; } -/* 8035002C-80350048 34A96C 001C+00 3/3 1/1 0/0 .text AISetStreamVolLeft */ -void AISetStreamVolLeft(u8 vol) { - __AIRegs[1] = (__AIRegs[1] & ~0xFF) | (vol & 0xFF); -} - -/* 80350048-80350058 34A988 0010+00 3/3 0/0 0/0 .text AIGetStreamVolLeft */ -u8 AIGetStreamVolLeft(void) { - return __AIRegs[1]; -} - -/* 80350058-80350074 34A998 001C+00 3/3 1/1 0/0 .text AISetStreamVolRight */ -void AISetStreamVolRight(u8 vol) { - __AIRegs[1] = (__AIRegs[1] & ~0xFF00) | ((vol & 0xFF) << 8); -} - -/* 80350074-80350084 34A9B4 0010+00 3/3 0/0 0/0 .text AIGetStreamVolRight */ -u8 AIGetStreamVolRight(void) { - return __AIRegs[1] >> 8; -} - -/* 80451880-80451884 000D80 0004+00 3/3 0/0 0/0 .sbss __CallbackStack */ -static u8* __CallbackStack; - -/* 80451884-80451888 000D84 0004+00 1/1 0/0 0/0 .sbss __OldStack */ -static u8* __OldStack; - -/* 80451888-8045188C 000D88 0004+00 1/1 0/0 0/0 .sbss __AI_init_flag */ -static volatile s32 __AI_init_flag; - -/* 8045188C-80451890 000D8C 0004+00 1/1 0/0 0/0 .sbss __AID_Active */ -static volatile s32 __AID_Active; - -/* 80451890-80451894 000D90 0004+00 2/2 0/0 0/0 .sbss bound_32KHz */ -static OSTime bound_32KHz; - -/* 80451898-8045189C 000D98 0004+00 2/2 0/0 0/0 .sbss bound_48KHz */ -static OSTime bound_48KHz; - -/* 804518A0-804518A4 000DA0 0004+00 2/2 0/0 0/0 .sbss min_wait */ -static OSTime min_wait; - -/* 804518A8-804518AC 000DA8 0004+00 2/2 0/0 0/0 .sbss max_wait */ -static OSTime max_wait; - -/* 804518B0-804518B4 000DB0 0004+00 2/2 0/0 0/0 .sbss buffer */ -static OSTime buffer; - void AIResetStreamSampleCount(void) { __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20; } @@ -209,165 +119,293 @@ void AISetStreamTrigger(u32 trigger) { __AIRegs[3] = trigger; } -/* 80350084-803501F0 34A9C4 016C+00 0/0 1/1 0/0 .text AIInit */ -void AIInit(u8* stack) { - if (__AI_init_flag == TRUE) { - return; - } - - 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); - __AIS_Callback = 0; - __AID_Callback = 0; - __CallbackStack = stack; - __OSSetInterruptHandler(5, __AIDHandler); - __OSUnmaskInterrupts(0x04000000); - __OSSetInterruptHandler(8, __AISHandler); - __OSUnmaskInterrupts(0x800000); - __AI_init_flag = TRUE; +u32 AIGetStreamTrigger(void) { + return __AIRegs[3]; } -/* 803501F0-8035026C 34AB30 007C+00 1/1 0/0 0/0 .text __AISHandler */ -void __AISHandler(s16 interrupt, OSContext* context) { - OSContext tmpContext; - __AIRegs[0] |= 8; - OSClearContext(&tmpContext); - OSSetCurrentContext(&tmpContext); +void AISetStreamPlayState(u32 state) { + BOOL old; + u8 vol_left; + u8 vol_right; - if (__AIS_Callback != NULL) { + if (state != AIGetStreamPlayState()) { + if (AIGetStreamSampleRate() == 0 && state == AI_STREAM_START) { + vol_left = AIGetStreamVolRight(); + vol_right = AIGetStreamVolLeft(); + AISetStreamVolRight(0); + AISetStreamVolLeft(0); + old = OSDisableInterrupts(); + __AI_SRC_INIT(); + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 5, 1); + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 0, AI_STREAM_START); + OSRestoreInterrupts(old); + AISetStreamVolLeft(vol_left); + AISetStreamVolRight(vol_right); + return; + } + OLD_SET_REG_FIELD(653, __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 == AI_SAMPLERATE_32KHZ) { + vol_left = AIGetStreamVolLeft(); + vol_right = AIGetStreamVolRight(); + play_state = AIGetStreamPlayState(); + afr_state = AIGetStreamSampleRate(); + AISetStreamVolLeft(0U); + AISetStreamVolRight(0U); + old = OSDisableInterrupts(); + __AI_SRC_INIT(); + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 5, 1); + OLD_SET_REG_FIELD(743, __AIRegs[0], 1, 1, afr_state); + OLD_SET_REG_FIELD(744, __AIRegs[0], 1, 0, play_state); + __AIRegs[0] |= 0x40; + OSRestoreInterrupts(old); + AISetStreamVolLeft(vol_left); + AISetStreamVolRight(vol_right); + } + } +} + +u32 AIGetDSPSampleRate(void) { + return GET_REG_FIELD(__AIRegs[0], 1, 6) ^ 1; +} + +void AISetStreamSampleRate(u32 rate) { + if (rate == AI_SAMPLERATE_48KHZ) { + __AI_set_stream_sample_rate(rate); + return; + } +#if DEBUG + OSReport("AISetStreamSampleRate(): OBSOLETED. Only 48KHz streaming from disk is supported!\n"); +#endif +} + +void __AI_DEBUG_set_stream_sample_rate(u32 rate) { + __AI_set_stream_sample_rate(rate); +} + +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; + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 6, 0); + old = OSDisableInterrupts(); + __AI_SRC_INIT(); + __AIRegs[0] |= dsp_src_state; + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 5, 1); + OLD_SET_REG_FIELD(887, __AIRegs[0], 1, 1, rate); + OSRestoreInterrupts(old); + AISetStreamPlayState(play_state); + AISetStreamVolLeft(vol_left); + AISetStreamVolRight(vol_right); + } +} + +u32 AIGetStreamSampleRate(void) { + return GET_REG_FIELD(__AIRegs[0], 1, 1); +} + +void AISetStreamVolLeft(u8 vol) { + OLD_SET_REG_FIELD(945, __AIRegs[1], 8, 0, vol); +} + +u8 AIGetStreamVolLeft(void) { + return GET_REG_FIELD(__AIRegs[1], 8, 0); +} + +void AISetStreamVolRight(u8 vol) { + OLD_SET_REG_FIELD(986, __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(AI_SAMPLERATE_48KHZ); + AISetDSPSampleRate(AI_SAMPLERATE_32KHZ); +#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; + } +} + +void AIReset(void) { + __AI_init_flag = FALSE; +} + +static void __AISHandler(__OSInterrupt interrupt, OSContext* context) { + OSContext exceptionContext; + + __AIRegs[0] |= 8; + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + if (__AIS_Callback) { __AIS_Callback(__AIRegs[2]); } - - OSClearContext(&tmpContext); + OSClearContext(&exceptionContext); OSSetCurrentContext(context); } -/* 8035026C-80350318 34ABAC 00AC+00 1/1 0/0 0/0 .text __AIDHandler */ -void __AIDHandler(s16 interrupt, OSContext* context) { - OSContext tempContext; - u32 temp = __DSPRegs[5]; - __DSPRegs[5] = (temp & ~0xA0) | 8; - OSClearContext(&tempContext); - OSSetCurrentContext(&tempContext); +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(&tempContext); + OSClearContext(&exceptionContext); OSSetCurrentContext(context); } -/* 80350318-80350370 34AC58 0058+00 1/1 0/0 0/0 .text __AICallbackStackSwitch */ -// clang-format off -asm void __AICallbackStackSwitch(register AIDCallback cb) { - // Allocate stack frame - fralloc - - // Store current stack - lis r5, __OldStack@ha - addi r5, r5, __OldStack@l - stw r1, 0(r5) - - // Load stack for callback - lis r5, __CallbackStack@ha - addi r5, r5, __CallbackStack@l - lwz r1,0(r5) - - // Move stack down 8 bytes - subi r1, r1, 8 - // Call callback - mtlr cb - blrl - - // Restore old stack - lis r5, __OldStack @ha - addi r5, r5, __OldStack@l - lwz r1,0(r5) - - // Free stack frame - frfree - - blr +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 -/* 80350370-80350554 34ACB0 01E4+00 3/3 0/0 0/0 .text __AI_SRC_INIT */ void __AI_SRC_INIT(void) { - OSTime rise32 = 0; - OSTime rise48 = 0; + OSTime rising_32khz = 0; + OSTime rising_48khz = 0; OSTime diff = 0; - OSTime unused1 = 0; - OSTime temp = 0; - u32 temp0 = 0; - u32 temp1 = 0; + OSTime t1 = 0; + OSTime temp; + u32 temp0; + u32 temp1; u32 done = 0; + u32 volume = 0; + u32 Init_Cnt = 0; u32 walking = 0; - u32 unused2 = 0; - u32 initCnt = 0; walking = 0; - initCnt = 0; + Init_Cnt = 0; temp = 0; +#if DEBUG + profile.t_start = OSGetTime(); +#endif + while (!done) { - __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20; - __AIRegs[0] &= ~2; - __AIRegs[0] = (__AIRegs[0] & ~1) | 1; - + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 5, 1); + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 1, 0); + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 0, AI_STREAM_START); temp0 = __AIRegs[2]; - - while (temp0 == __AIRegs[2]) - ; - rise32 = OSGetTime(); - - __AIRegs[0] = (__AIRegs[0] & ~2) | 2; - __AIRegs[0] = (__AIRegs[0] & ~1) | 1; - + while (temp0 == __AIRegs[2]) { + } + rising_32khz = OSGetTime(); + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 1, 1); + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 0, AI_STREAM_START); temp1 = __AIRegs[2]; - while (temp1 == __AIRegs[2]) - ; - - rise48 = OSGetTime(); - - diff = rise48 - rise32; - __AIRegs[0] &= ~2; - __AIRegs[0] &= ~1; - - if (diff < (bound_32KHz - buffer)) { + while (temp1 == __AIRegs[2]) { + } + rising_48khz = OSGetTime(); + diff = rising_48khz - rising_32khz; + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 1, 0); + OLD_SET_REG_FIELD(0, __AIRegs[0], 1, 0, AI_STREAM_STOP); + if (diff < bound_32KHz - buffer) { temp = min_wait; done = 1; - ++initCnt; - } else if (diff >= (bound_32KHz + buffer) && diff < (bound_48KHz - buffer)) { + Init_Cnt++; + } else if (diff >= bound_32KHz + buffer && diff < bound_48KHz - buffer) { temp = max_wait; done = 1; - ++initCnt; + Init_Cnt++; } else { done = 0; walking = 1; - ++initCnt; + Init_Cnt++; } } + while (rising_48khz + temp > OSGetTime()) { + } +#if DEBUG + profile.t_end = OSGetTime(); +#endif +} - while ((rise48 + temp) > OSGetTime()) - ; -} \ No newline at end of file +STRUCT_TIMELOG* __ai_src_get_time(void) { +#if DEBUG + return &profile; +#else + return NULL; +#endif +} diff --git a/src/dolphin/am/__am.h b/src/dolphin/am/__am.h new file mode 100644 index 0000000000..7907a627c9 --- /dev/null +++ b/src/dolphin/am/__am.h @@ -0,0 +1,39 @@ +#ifndef _DOLPHIN_AM_INTERNAL_H_ +#define _DOLPHIN_AM_INTERNAL_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define AM_STACK_ENTRIES 16 + +typedef struct { + DVDFileInfo file_handle; + ARQRequest arq_handle; + AMCallback callback; + char* path; + void* buffer; + volatile u32 file_length; + volatile u32 curr_read_offset; + volatile u32 read_length; + volatile u32 aram_start_addr; + volatile u32 curr_aram_offset; + volatile int poll_flag; +} AMReadInfo; + +extern AMReadInfo __AMReadInfo[AM_STACK_ENTRIES]; + +static void __AM_dvd_callback(s32 result, DVDFileInfo* handle); +static void __AM_arq_callback(u32 task); +static void __AM_arq_poll_callback(u32 task); +u32 __AMPushBuffered(char* path, void* buffer, u32 buffer_size, AMCallback callback, int async_flag); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dolphin/am/am.c b/src/dolphin/am/am.c new file mode 100644 index 0000000000..56350a9c3a --- /dev/null +++ b/src/dolphin/am/am.c @@ -0,0 +1,322 @@ +#include +#include + +#include "__am.h" + +static u32 __AMStackPointer[AM_STACK_ENTRIES]; +static AMReadInfo __AMReadInfo[AM_STACK_ENTRIES]; + +static u32 __AMStackLocation; +static u32 __AMFreeBytes; +static u32 __AMPendingReads; + +static void __AM_dvd_callback(s32 result, DVDFileInfo* handle) { + u32 i; + AMReadInfo* ptr; + + for (i = 0; i < AM_STACK_ENTRIES; i++) { + if (handle == &(__AMReadInfo[i].file_handle)) { + ptr = &__AMReadInfo[i]; + break; + } + } + + ASSERTLINE(136, i != AM_STACK_ENTRIES); + + if (DVDGetCommandBlockStatus(&ptr->file_handle.cb) == 0) { + ARQPostRequest(&ptr->arq_handle, i, 0, 1, (u32)ptr->buffer, ptr->curr_aram_offset, result, __AM_arq_callback); + ptr->curr_aram_offset += result; + ptr->curr_read_offset += result; + } +} + +static void __AM_arq_callback(u32 task) { + u32 i; + AMReadInfo* ptr; + u32 remainder; + u32 read_request_length; + + for (i = 0; i < AM_STACK_ENTRIES; i++) { + if ((ARQRequest*)task == &__AMReadInfo[i].arq_handle) { + ptr = &__AMReadInfo[i]; + break; + } + } + + ASSERTLINE(198, i != AM_STACK_ENTRIES); + + if (ptr->curr_read_offset < ptr->file_length) { + remainder = ptr->file_length - ptr->curr_read_offset; + read_request_length = OSRoundUp32B(ptr->read_length > remainder ? remainder : ptr->read_length); + DVDReadAsync(&ptr->file_handle, ptr->buffer, read_request_length, ptr->curr_read_offset, __AM_dvd_callback); + } else { + ASSERTMSGLINE(220, __AMPendingReads, "AMPushBuffered(): Dangling read-complete event!\n"); + __AMPendingReads--; + + if (ptr->callback) { + (*ptr->callback)(ptr->path); + } + } +} + +static void __AM_arq_poll_callback(u32 task) { + u32 i; + AMReadInfo* ptr; + + for (i = 0; i < AM_STACK_ENTRIES; i++) { + if ((ARQRequest*)task == &__AMReadInfo[i].arq_handle) { + ptr = &__AMReadInfo[i]; + break; + } + } + + ASSERTLINE(262, i != AM_STACK_ENTRIES); + + ptr->poll_flag = 1; +} + +void* AMLoadFile(char* path, u32* length) { + DVDFileInfo dvdFileInfo; + u32 roundLength; + s32 readLength; + void* buffer; + int old; + + if (!DVDOpen(path, &dvdFileInfo)) { + char ch[1024]; + sprintf(ch, "Cannot open %s", path); + ASSERTMSGLINE(290, 0, ch); + } + + ASSERTMSGLINE(294, dvdFileInfo.length, "File length is 0\n"); + + roundLength = OSRoundUp32B(dvdFileInfo.length); + + old = OSDisableInterrupts(); + buffer = OSAlloc(roundLength); + OSRestoreInterrupts(old); + + ASSERTMSGLINE(303, buffer, "Unable to allocate buffer\n"); + readLength = DVDReadPrio(&dvdFileInfo, buffer, roundLength, 0, 2); + ASSERTMSGLINE(307, readLength > 0, "Read length <= 0\n"); + if (length != 0) { + *length = roundLength; + } + + return buffer; +} + +u32 AMPush(char* path) { + DVDFileInfo handle; + void* buffer; + u32 buffer_length; + u32 ret_val; + BOOL old; + + if (!DVDOpen(path, &handle)) { + OSReport("AMPushBuffered(): Unable to open file '%s'\n", path); + OSPanic(__FILE__, 343, "AM: FATAL ERROR\n"); + } + + buffer_length = OSRoundUp32B(handle.length); + if (buffer_length) { + old = OSDisableInterrupts(); + buffer = OSAlloc(buffer_length); + OSRestoreInterrupts(old); + + ASSERTMSGLINE(356, buffer, "AMPush(): Memory allocation failure.\n"); + + ret_val = __AMPushBuffered(path, buffer, buffer_length, NULL, FALSE); + OSFree(buffer); + return ret_val; + } else { +#ifdef DEBUG + OSReport("AMPush(): WARNING: File has zero length.\n"); +#endif + return 0; + } +} + +u32 AMPushData(void* buffer, u32 length) { + BOOL old; + u32 round_length; + AMReadInfo* ptr; + + ASSERTMSGLINE(401, ((u32)buffer & 0x1F) == 0, "AMPushData(): buffer is not 32-byte aligned!\n"); + ASSERTLINE(404, length); + + round_length = OSRoundUp32B(length); + if (__AMFreeBytes >= round_length && __AMStackLocation < AM_STACK_ENTRIES - 1) { + ptr = &__AMReadInfo[__AMStackLocation]; + + old = OSDisableInterrupts(); + + ptr->aram_start_addr = __AMStackPointer[__AMStackLocation]; + __AMStackLocation++; + __AMStackPointer[__AMStackLocation] = ptr->aram_start_addr + round_length; + __AMFreeBytes -= round_length; + + ptr->poll_flag = 0; + + ARQPostRequest(&ptr->arq_handle, __AMStackLocation - 1, 0, 1, (u32)buffer, ptr->aram_start_addr, round_length, &__AM_arq_poll_callback); + + OSRestoreInterrupts(old); + + do {} while (!ptr->poll_flag); + + return ptr->aram_start_addr; + } + + return 0; +} + +u32 __AMPushBuffered(char* path, void* buffer, u32 buffer_size, AMCallback callback, int async_flag) { + BOOL old; + u32 round_file_length; + u32 stack_index; + AMReadInfo* ptr; + u32 remainder; + u32 read_request_length; + s32 actual_read_length; + + ASSERTMSGLINE(477, ((u32)buffer & 0x1F) == 0, "AMPushBuffered(): buffer is not 32-byte aligned!\n"); + ASSERTMSGLINE(480, buffer_size > 31, "AMPushBuffered(): buffer_size is less than 32 bytes!\n"); + + if (__AMStackLocation < AM_STACK_ENTRIES - 1) { + ptr = &__AMReadInfo[__AMStackLocation]; + stack_index = __AMStackLocation; + + if (!DVDOpen(path, &ptr->file_handle)) { + OSReport("AMPushBuffered(): Unable to open file '%s'\n", path); + OSPanic(__FILE__, 494, "AM: FATAL ERROR\n"); + } + + ptr->file_length = ptr->file_handle.length; + round_file_length = OSRoundUp32B(ptr->file_length); + + if (__AMFreeBytes >= round_file_length) { + ptr->aram_start_addr = __AMStackPointer[__AMStackLocation]; + + old = OSDisableInterrupts(); + + __AMStackLocation++; + __AMStackPointer[__AMStackLocation] = ptr->aram_start_addr + round_file_length; + __AMFreeBytes -= round_file_length; + + ptr->curr_read_offset = 0; + ptr->curr_aram_offset = ptr->aram_start_addr; + ptr->read_length = buffer_size & ~0x1F; + ptr->callback = callback; + ptr->path = path; + ptr->buffer = buffer; + + OSRestoreInterrupts(old); + + if (async_flag == 1) { + DVDReadAsync(&ptr->file_handle, ptr->buffer, ptr->read_length, 0, __AM_dvd_callback); + __AMPendingReads++; + } else { + while (ptr->curr_read_offset < ptr->file_length) { + remainder = ptr->file_length - ptr->curr_read_offset; + read_request_length = OSRoundUp32B(ptr->read_length > remainder ? remainder : ptr->read_length); + actual_read_length = DVDReadPrio(&ptr->file_handle, ptr->buffer, read_request_length, ptr->curr_read_offset, 2); + + ASSERTMSGLINE(558, actual_read_length > 0, "AMPushBuffered(): Fatal Error - synchronuous DVD read\n"); + + ptr->curr_read_offset += actual_read_length; + ptr->poll_flag = FALSE; + + ARQPostRequest(&(ptr->arq_handle), stack_index, 0, 1, (u32)ptr->buffer, ptr->curr_aram_offset, actual_read_length, __AM_arq_poll_callback); + + ptr->curr_aram_offset += (u32)(actual_read_length); + + do {} while (!ptr->poll_flag); + } + } + } else { +#ifdef DEBUG + OSReport("AMPushBuffered(): WARNING: Not enough space in ARAM.\n"); +#endif + return 0; + } + } else { +#ifdef DEBUG + OSReport("AMPushBuffered(): WARNING: Stack table is full.\n"); +#endif + return 0; + } + + return ptr->aram_start_addr; +} + +void AMPop(void) { + BOOL old; + old = OSDisableInterrupts(); + + if (__AMPendingReads == 0) { + if (__AMStackLocation > 1) { + __AMFreeBytes += __AMStackPointer[__AMStackLocation] - __AMStackPointer[__AMStackLocation - 1]; + __AMStackLocation--; + } + } + + OSRestoreInterrupts(old); +} + +u32 AMGetZeroBuffer(void) { + return __AMStackPointer[0]; +} + +u32 AMGetReadStatus(void) { + BOOL old; + u32 tmp; + + old = OSDisableInterrupts(); + tmp = __AMPendingReads; + + OSRestoreInterrupts(old); + return tmp; +} + +u32 AMGetFreeSize(void) { + BOOL old; + u32 tmp; + + old = OSDisableInterrupts(); + tmp = __AMFreeBytes; + + OSRestoreInterrupts(old); + return tmp; +} + +u32 AMGetStackPointer(void) { + BOOL old; + u32 tmp; + + old = OSDisableInterrupts(); + tmp = __AMStackPointer[__AMStackLocation]; + + OSRestoreInterrupts(old); + return tmp; +} + +void AMInit(u32 aramBase, u32 aramBytes) { + u32 i; + u8 __AMZeroBuffer[256 + 31]; + u8* ptr; + + ASSERTLINE(760, aramBytes); + + ptr = (u8*)OSRoundUp32B(__AMZeroBuffer); + + __AMStackLocation = 0; + __AMStackPointer[0] = aramBase; + __AMFreeBytes = aramBytes; + __AMPendingReads = 0; + + for (i = 0; i < 256; i++) { + ptr[i] = 0; + } + + AMPushData(ptr, 256); +} diff --git a/src/dolphin/amcnotstub/amcnotstub.c b/src/dolphin/amcnotstub/amcnotstub.c new file mode 100644 index 0000000000..f1a59e7c88 --- /dev/null +++ b/src/dolphin/amcnotstub/amcnotstub.c @@ -0,0 +1,8 @@ +#include + +// this file is a stub. +__declspec(weak) int AMC_IsStub(void); + +__declspec(weak) int AMC_IsStub(void) { + return 0; +} diff --git a/src/dolphin/amcstubs/AmcExi2Stubs.c b/src/dolphin/amcstubs/AmcExi2Stubs.c new file mode 100644 index 0000000000..99073a34cb --- /dev/null +++ b/src/dolphin/amcstubs/AmcExi2Stubs.c @@ -0,0 +1,29 @@ +#include +#include + +// prototypes +int AMC_IsStub(void); + +void EXI2_Init(volatile unsigned char **inputPendingPtrRef, EXICallback 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; +} diff --git a/src/dolphin/ar/__ar.h b/src/dolphin/ar/__ar.h new file mode 100644 index 0000000000..8cab34ca25 --- /dev/null +++ b/src/dolphin/ar/__ar.h @@ -0,0 +1,24 @@ +#ifndef _DOLPHIN_AR_INTERNAL_H_ +#define _DOLPHIN_AR_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void __ARClearInterrupt(void); +u16 __ARGetInterruptStatus(void); + +void __ARQPopTaskQueueHi(void); +void __ARQServiceQueueLo(void); +void __ARQCallbackHack(u32 pointerToARQRequest); +void __ARQInterruptServiceRoutine(void); +void __ARQInitTempQueue(void); +void __ARQPushTempQueue(ARQRequest* task); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_AR_INTERNAL_H_ diff --git a/src/dolphin/ar/ar.c b/src/dolphin/ar/ar.c index fe7278c96f..d431eebbc1 100644 --- a/src/dolphin/ar/ar.c +++ b/src/dolphin/ar/ar.c @@ -1,94 +1,106 @@ -#include "dolphin/ar.h" -#include "dolphin/dsp.h" -#include "dolphin/os.h" -#include "string.h" +#include +#include +#include "fake_tgmath.h" -/* 80450A48-80450A50 -00001 0004+04 1/1 0/0 0/0 .sdata __ARVersion */ -char* __ARVersion = "<< Dolphin SDK - AR\trelease build: Apr 5 2004 04:15:03 (0x2301) >>"; +#include "__ar.h" -void __ARHandler(s16 interrupt, OSContext* context); -void __ARClearInterrupt(); -void __ARChecksize(); +#ifdef DEBUG +const char* __ARVersion = "<< Dolphin SDK - AR\tdebug build: Apr 5 2004 03:56:19 (0x2301) >>"; +#else +const char* __ARVersion = "<< Dolphin SDK - AR\trelease build: Apr 5 2004 04:15:03 (0x2301) >>"; +#endif -/* 804518B8-804518BC 000DB8 0004+00 3/3 0/0 0/0 .sbss __AR_Callback */ -static ARCallback __AR_Callback; +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; -/* 80350554-80350598 34AE94 0044+00 0/0 1/1 0/0 .text ARRegisterDMACallback */ -ARCallback ARRegisterDMACallback(ARCallback callback) { - ARCallback oldCb; - BOOL enabled; - oldCb = __AR_Callback; - enabled = OSDisableInterrupts(); +// 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); + +ARQCallback ARRegisterDMACallback(ARQCallback callback) { + ARQCallback old_callback; + BOOL old; + + old_callback = __AR_Callback; + old = OSDisableInterrupts(); __AR_Callback = callback; - OSRestoreInterrupts(enabled); - return oldCb; + OSRestoreInterrupts(old); + return old_callback; } -/* 80350598-803505D4 34AED8 003C+00 0/0 2/2 0/0 .text ARGetDMAStatus */ -u32 ARGetDMAStatus() { - BOOL enabled; +u32 ARGetDMAStatus(void) { + BOOL old; u32 val; - enabled = OSDisableInterrupts(); - val = __DSPRegs[5] & 0x0200; - OSRestoreInterrupts(enabled); + + old = OSDisableInterrupts(); + val = __DSPRegs[5] & 0x200; + OSRestoreInterrupts(old); return val; } -/* 803505D4-803506C4 34AF14 00F0+00 0/0 5/5 0/0 .text ARStartDMA */ void ARStartDMA(u32 type, u32 mainmem_addr, u32 aram_addr, u32 length) { - BOOL enabled; + BOOL old; - enabled = OSDisableInterrupts(); - - __DSPRegs[16] = (u16)(__DSPRegs[16] & ~0x3ff) | (u16)(mainmem_addr >> 16); - __DSPRegs[17] = (u16)(__DSPRegs[17] & ~0xffe0) | (u16)(mainmem_addr & 0xffff); - __DSPRegs[18] = (u16)(__DSPRegs[18] & ~0x3ff) | (u16)(aram_addr >> 16); - __DSPRegs[19] = (u16)(__DSPRegs[19] & ~0xffe0) | (u16)(aram_addr & 0xffff); - __DSPRegs[20] = (u16)((__DSPRegs[20] & ~0x8000) | (type << 15)); - __DSPRegs[20] = (u16)(__DSPRegs[20] & ~0x3ff) | (u16)(length >> 16); - __DSPRegs[21] = (u16)(__DSPRegs[21] & ~0xffe0) | (u16)(length & 0xffff); - OSRestoreInterrupts(enabled); + 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); } -/* ############################################################################################## */ -/* 804518BC-804518C0 000DBC 0004+00 2/1 0/0 0/0 .sbss __AR_Size */ -static u32 __AR_Size; - -/* 804518C0-804518C4 000DC0 0004+00 1/1 0/0 0/0 .sbss __AR_InternalSize */ -static u32 __AR_InternalSize; - -/* 804518C4-804518C8 000DC4 0004+00 1/1 0/0 0/0 .sbss __AR_ExpansionSize */ -static u32 __AR_ExpansionSize; - -/* 804518C8-804518CC 000DC8 0004+00 2/2 0/0 0/0 .sbss __AR_StackPointer */ -static u32 __AR_StackPointer; - -/* 804518CC-804518D0 000DCC 0004+00 2/2 0/0 0/0 .sbss __AR_FreeBlocks */ -static u32 __AR_FreeBlocks; - -/* 804518D0-804518D4 000DD0 0004+00 2/2 0/0 0/0 .sbss __AR_BlockLength */ -static u32* __AR_BlockLength; - -/* 803506C4-8035072C 34B004 0068+00 0/0 1/1 0/0 .text ARAlloc */ u32 ARAlloc(u32 length) { u32 tmp; - BOOL enabled; + 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!"); - enabled = OSDisableInterrupts(); tmp = __AR_StackPointer; __AR_StackPointer += length; *__AR_BlockLength = length; - __AR_BlockLength++; - __AR_FreeBlocks--; - OSRestoreInterrupts(enabled); - + __AR_BlockLength += 1; + __AR_FreeBlocks -= 1; + OSRestoreInterrupts(old); return tmp; } -/* 804518D4-804518D8 000DD4 0004+00 1/1 0/0 0/0 .sbss __AR_init_flag */ -static volatile BOOL __AR_init_flag; +u32 ARFree(u32* length) { + BOOL old; + + old = OSDisableInterrupts(); + __AR_BlockLength -= 1; + if (length) { + *length = *__AR_BlockLength; + } + __AR_StackPointer -= *__AR_BlockLength; + __AR_FreeBlocks += 1; + OSRestoreInterrupts(old); + return __AR_StackPointer; +} + +BOOL ARCheckInit(void) { + return __AR_init_flag; +} -/* 8035072C-803507F0 34B06C 00C4+00 0/0 1/1 0/0 .text ARInit */ u32 ARInit(u32* stack_index_addr, u32 num_entries) { BOOL old; u16 refresh; @@ -100,136 +112,147 @@ u32 ARInit(u32* stack_index_addr, u32 num_entries) { OSRegisterVersion(__ARVersion); old = OSDisableInterrupts(); - __AR_Callback = NULL; - - __OSSetInterruptHandler(OS_INTR_DSP_ARAM, __ARHandler); - __OSUnmaskInterrupts(OS_INTERRUPTMASK_DSP_ARAM); - + __OSSetInterruptHandler(6, __ARHandler); + __OSUnmaskInterrupts(0x02000000); __AR_StackPointer = 0x4000; __AR_FreeBlocks = num_entries; __AR_BlockLength = stack_index_addr; + refresh = __DSPRegs[13] & 0xFF; - refresh = (u16)(__DSPRegs[13] & 0x000000ff); - - __DSPRegs[13] = (u16)((__DSPRegs[13] & ~0x000000ff) | (refresh & 0x000000ff)); + 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; } -/* 803507F0-803507F8 -00001 0008+00 0/0 0/0 0/0 .text ARGetSize */ +void ARReset(void) { + __AR_init_flag = FALSE; +} + +void ARSetSize(void) { +#ifdef DEBUG + OSReport("ARSetSize(): I don't do anything anymore!\n"); +#endif +} + +u32 ARGetBaseAddress(void) { + return 0x4000; +} + u32 ARGetSize(void) { return __AR_Size; } -/* 803507F8-80350870 34B138 0078+00 1/1 0/0 0/0 .text __ARHandler */ -static void __ARHandler(s16 interrupt, OSContext* context) { +u32 ARGetInternalSize(void) { + return __AR_InternalSize; +} + +void ARClear(u32 flag) { + switch (flag) { + case 0: + if (__AR_InternalSize != 0) { + __ARClearArea(0, __AR_InternalSize); + } + return; + case 1: + if (__AR_InternalSize != 0) { + __ARClearArea(0x4000, __AR_InternalSize - 0x4000); + } + break; + case 2: + if (__AR_InternalSize != 0 && __AR_ExpansionSize != 0) { + __ARClearArea(__AR_InternalSize, __AR_ExpansionSize); + } + break; + default: + ASSERTMSGLINE(774, 0, "ARClear(): Unknown flag.\n"); + break; + } +} + +static void __ARHandler(__OSInterrupt exception, OSContext* context) { OSContext exceptionContext; u16 tmp; tmp = __DSPRegs[5]; - tmp = (u16)((tmp & ~0x00000088) | 0x20); - __DSPRegs[5] = tmp; - + tmp = (tmp & ~0x88) | 0x20; + __DSPRegs[5] = (tmp); OSClearContext(&exceptionContext); OSSetCurrentContext(&exceptionContext); - if (__AR_Callback) { - (*__AR_Callback)(); + __AR_Callback(); } - OSClearContext(&exceptionContext); OSSetCurrentContext(context); } -/* 80350870-80350890 34B1B0 0020+00 0/0 2/2 0/0 .text __ARClearInterrupt */ void __ARClearInterrupt(void) { u16 tmp; + tmp = __DSPRegs[5]; - tmp = (u16)((tmp & ~(0x00000080 | 0x00000008)) | 0x00000020); - __DSPRegs[5] = tmp; + tmp = (tmp & ~0x88) | 0x20; + __DSPRegs[5] = (tmp); } -/* 80350890-803508A0 34B1D0 0010+00 0/0 2/2 0/0 .text __ARGetInterruptStatus */ u16 __ARGetInterruptStatus(void) { - return ((u16)(__DSPRegs[5] & 0x0020)); + return __DSPRegs[5] & 0x20; } -void __ARWaitForDMA() { - while (__DSPRegs[DSP_CONTROL_STATUS] & 0x0200) { - } +static void __ARWaitForDMA(void) { + while (__DSPRegs[5] & 0x200); } -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)); +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)); + // 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); + // 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(); + __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(); } -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)); +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)); + // 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); + // 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(); + __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(); } -/* 803508A0-80352094 34B1E0 17F4+00 1/1 0/0 0/0 .text __ARChecksize */ -void __ARChecksize() { - u8 test_data_pad[0x20 + 31]; - u8 dummy_data_pad[0x20 + 31]; - u8 buffer_pad[0x20 + 31]; - - u8 save_pad_1[0x20 + 31]; - u8 save_pad_2[0x20 + 31]; - u8 save_pad_3[0x20 + 31]; - u8 save_pad_4[0x20 + 31]; - u8 save_pad_5[0x20 + 31]; - +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; @@ -238,18 +261,15 @@ void __ARChecksize() { u32* save3; u32* save4; u32* save5; - u16 ARAM_mode = 0; u32 ARAM_size = 0; - u32 i; - while (!(__DSPRegs[DSP_ARAM_MODE] & 1)) { - } + do {} while(!(__DSPRegs[11] & 1)); ARAM_mode = 3; ARAM_size = __AR_InternalSize = 0x1000000; - __DSPRegs[DSP_ARAM_SIZE] = (u16)((__DSPRegs[DSP_ARAM_SIZE] & ~(0x7 | 0x38)) | 0x20 | 2 | 1); + __DSPRegs[9] = ((__DSPRegs[9] & 0xFFFFFFC0) | 3) | 0x20; test_data = (u32*)(OSRoundUp32B((u32)(test_data_pad))); dummy_data = (u32*)(OSRoundUp32B((u32)(dummy_data_pad))); @@ -301,7 +321,6 @@ void __ARChecksize() { PPCSync(); __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0200000, 0x20); - __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); memset((void*)buffer, 0, 0x20); @@ -318,7 +337,6 @@ void __ARChecksize() { __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); @@ -336,7 +354,6 @@ void __ARChecksize() { __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); @@ -387,10 +404,43 @@ void __ARChecksize() { } } } - __DSPRegs[DSP_ARAM_SIZE] = (u16)((__DSPRegs[DSP_ARAM_SIZE] & ~(0x7 | 0x38)) | ARAM_mode); + +#ifdef 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; -} \ No newline at end of file +} + +static void __ARClearArea(u32 start_addr, u32 length) { + u8 zero_buffer[2079]; + u8* ptr; + u32 curr_addr; + u32 curr_len; + u32 end_addr; + u32 remainder; + + ASSERTMSGLINE(0x529, !(start_addr & 0x1F), "__ARClearArea(): Destination address not 32-byte aligned.\n"); + ASSERTMSGLINE(0x52A, !(length & 0x1F), "__ARClearArea(): Length not multiple of 32 bytes.\n"); + + ptr = (u8*)(OSRoundUp32B((u32)(zero_buffer))); + + do {} while(!(__DSPRegs[11] & 1)); + + memset(ptr, 0, 0x800); + DCFlushRange(ptr, 0x800); + + curr_addr = start_addr; + end_addr = start_addr + length; + + while (curr_addr < end_addr) { + remainder = end_addr - curr_addr; + + curr_len = OSRoundUp32B(remainder < 0x800 ? remainder : 0x800); + __ARWriteDMA((u32)ptr, curr_addr, curr_len); + curr_addr += curr_len; + } +} diff --git a/src/dolphin/ar/arq.c b/src/dolphin/ar/arq.c index d45764f776..1adf24bbba 100644 --- a/src/dolphin/ar/arq.c +++ b/src/dolphin/ar/arq.c @@ -1,195 +1,253 @@ -#include "dolphin/arq.h" -#include "dolphin/ar.h" +#include +#include -/* 803D1C30-803D1C78 02ED50 0045+03 1/0 0/0 0/0 .data @1 */ -char* __ARQVersion = "<< Dolphin SDK - ARQ\trelease build: Apr 5 2004 04:15:04 (0x2301) >>"; +#include "__ar.h" -void __ARQServiceQueueLo(); -void __ARQCallbackHack(); -void __ARQInterruptServiceRoutine(); +#ifdef DEBUG +const char* __ARQVersion = "<< Dolphin SDK - ARQ\tdebug build: Apr 5 2004 03:56:20 (0x2301) >>"; +#else +const char* __ARQVersion = "<< Dolphin SDK - ARQ\trelease build: Apr 5 2004 04:15:04 (0x2301) >>"; +#endif -/* 804518D8-804518DC 000DD8 0004+00 3/3 0/0 0/0 .sbss __ARQRequestQueueHi */ static ARQRequest* __ARQRequestQueueHi; - -/* 804518DC-804518E0 000DDC 0004+00 1/1 0/0 0/0 .sbss __ARQRequestTailHi */ static ARQRequest* __ARQRequestTailHi; - -/* 804518E0-804518E4 000DE0 0004+00 3/3 0/0 0/0 .sbss __ARQRequestQueueLo */ static ARQRequest* __ARQRequestQueueLo; - -/* 804518E4-804518E8 000DE4 0004+00 1/1 0/0 0/0 .sbss __ARQRequestTailLo */ static ARQRequest* __ARQRequestTailLo; - -/* 804518E8-804518EC 000DE8 0004+00 3/3 0/0 0/0 .sbss __ARQRequestPendingHi */ +static ARQRequest* __ARQRequestQueueTemp; +static ARQRequest* __ARQRequestTailTemp; static ARQRequest* __ARQRequestPendingHi; - -/* 804518EC-804518F0 000DEC 0004+00 4/4 0/0 0/0 .sbss __ARQRequestPendingLo */ static ARQRequest* __ARQRequestPendingLo; - -/* 804518F0-804518F4 000DF0 0004+00 3/3 0/0 0/0 .sbss __ARQCallbackHi */ static ARQCallback __ARQCallbackHi; - -/* 804518F4-804518F8 000DF4 0004+00 3/3 0/0 0/0 .sbss __ARQCallbackLo */ static ARQCallback __ARQCallbackLo; - -/* 804518F8-804518FC 000DF8 0004+00 2/2 0/0 0/0 .sbss __ARQChunkSize */ static u32 __ARQChunkSize; - -/* 804518FC-80451900 000DFC 0004+00 1/1 0/0 0/0 .sbss __ARQ_init_flag */ static BOOL __ARQ_init_flag; -/* 80352094-80352194 34C9D4 0100+00 2/2 0/0 0/0 .text __ARQServiceQueueLo */ -void __ARQServiceQueueLo(void) { - if ((__ARQRequestPendingLo == NULL) && (__ARQRequestQueueLo)) { - __ARQRequestPendingLo = __ARQRequestQueueLo; - - __ARQRequestQueueLo = __ARQRequestQueueLo->next; - } - - if (__ARQRequestPendingLo) { - if (__ARQRequestPendingLo->length <= __ARQChunkSize) { - if (__ARQRequestPendingLo->type == ARAM_DIR_MRAM_TO_ARAM) - 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 == ARAM_DIR_MRAM_TO_ARAM) - 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; - } -} - -/* 80352194-80352198 34CAD4 0004+00 1/1 0/0 0/0 .text __ARQCallbackHack */ -void __ARQCallbackHack() {} - -/* 80352198-80352264 34CAD8 00CC+00 1/1 0/0 0/0 .text __ARQInterruptServiceRoutine */ -void __ARQInterruptServiceRoutine(void) { - if (__ARQCallbackHi) { - (*__ARQCallbackHi)((u32)__ARQRequestPendingHi); - __ARQRequestPendingHi = NULL; - __ARQCallbackHi = NULL; - } - - else if (__ARQCallbackLo) - { - (*__ARQCallbackLo)((u32)__ARQRequestPendingLo); - __ARQRequestPendingLo = NULL; - __ARQCallbackLo = NULL; - } - +void __ARQPopTaskQueueHi(void) { if (__ARQRequestQueueHi) { if (__ARQRequestQueueHi->type == 0) { - ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->source, - __ARQRequestQueueHi->destination, __ARQRequestQueueHi->length); + ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->source, __ARQRequestQueueHi->dest, __ARQRequestQueueHi->length); } else { - ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->destination, - __ARQRequestQueueHi->source, __ARQRequestQueueHi->length); + ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->dest, __ARQRequestQueueHi->source, __ARQRequestQueueHi->length); } __ARQCallbackHi = __ARQRequestQueueHi->callback; __ARQRequestPendingHi = __ARQRequestQueueHi; __ARQRequestQueueHi = __ARQRequestQueueHi->next; } +} - if (__ARQRequestPendingHi == NULL) { +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->dest, __ARQRequestPendingLo->length); + } else { + ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest, __ARQRequestPendingLo->source, __ARQRequestPendingLo->length); + } + __ARQCallbackLo = __ARQRequestPendingLo->callback; + } else if (__ARQRequestPendingLo->type == 0) { + ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source, __ARQRequestPendingLo->dest, __ARQChunkSize); + } else { + ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest, __ARQRequestPendingLo->source, __ARQChunkSize); + } + + __ARQRequestPendingLo->length -= __ARQChunkSize; + __ARQRequestPendingLo->source += __ARQChunkSize; + __ARQRequestPendingLo->dest += __ARQChunkSize; + } +} + +void __ARQCallbackHack(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(); } } -/* 80352264-803522D4 34CBA4 0070+00 0/0 1/1 0/0 .text ARQInit */ -void ARQInit(void) { - if (__ARQ_init_flag == TRUE) { - return; - } - - OSRegisterVersion(__ARQVersion); - __ARQRequestQueueHi = __ARQRequestQueueLo = NULL; - __ARQChunkSize = ARQ_CHUNK_SIZE_DEFAULT; - ARRegisterDMACallback(&__ARQInterruptServiceRoutine); - __ARQRequestPendingHi = NULL; - __ARQRequestPendingLo = NULL; - __ARQCallbackHi = NULL; - __ARQCallbackLo = NULL; - __ARQ_init_flag = TRUE; +void __ARQInitTempQueue(void) { + __ARQRequestQueueTemp = NULL; + __ARQRequestTailTemp = NULL; } -/* 803522D4-80352430 34CC14 015C+00 0/0 1/1 0/0 .text ARQPostRequest */ -void ARQPostRequest(ARQRequest* request, u32 owner, u32 type, u32 priority, u32 source, u32 dest, - u32 length, ARQCallback callback) { - BOOL enabled; +void __ARQPushTempQueue(ARQRequest* task) { + if (!__ARQRequestQueueTemp) { + __ARQRequestQueueTemp = task; + __ARQRequestTailTemp = task; + } else { + __ARQRequestTailTemp->next = task; + __ARQRequestTailTemp = task; + } +} + +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 ARQReset(void) { + __ARQ_init_flag = FALSE; +} + +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->dest = dest; request->length = length; - if (callback) { request->callback = callback; } else { - request->callback = (ARQCallback)&__ARQCallbackHack; + request->callback = __ARQCallbackHack; } - enabled = OSDisableInterrupts(); - - switch (priority) { + 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 == NULL) && (__ARQRequestPendingLo == NULL)) { - if (__ARQRequestQueueHi) { - if (__ARQRequestQueueHi->type == ARAM_DIR_MRAM_TO_ARAM) { - 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; - } - - if (__ARQRequestPendingHi == NULL) { + if ((__ARQRequestPendingHi == 0) && ( __ARQRequestPendingLo == 0)) { + __ARQPopTaskQueueHi(); + if ( __ARQRequestPendingHi == 0) { __ARQServiceQueueLo(); } } - OSRestoreInterrupts(enabled); -} \ No newline at end of file + OSRestoreInterrupts(level); +} + +void ARQRemoveRequest(ARQRequest* request) { + ARQRequest* thisRequest; + BOOL level; + + level = OSDisableInterrupts(); + __ARQInitTempQueue(); + + for (thisRequest = __ARQRequestQueueHi; thisRequest; thisRequest = thisRequest->next) { + if (thisRequest != request) { + __ARQPushTempQueue(thisRequest); + } + } + + __ARQRequestQueueHi = __ARQRequestQueueTemp; + __ARQRequestTailHi = __ARQRequestTailTemp; + __ARQInitTempQueue(); + + for (thisRequest = __ARQRequestQueueLo; thisRequest; thisRequest = thisRequest->next) { + if (thisRequest != request) { + __ARQPushTempQueue(thisRequest); + } + } + + __ARQRequestQueueLo = __ARQRequestQueueTemp; + __ARQRequestTailLo = __ARQRequestTailTemp; + OSRestoreInterrupts(level); +} + +void ARQRemoveOwnerRequest(u32 owner) { + ARQRequest* thisRequest; + BOOL level; + + level = OSDisableInterrupts(); + __ARQInitTempQueue(); + + for (thisRequest = __ARQRequestQueueHi; thisRequest; thisRequest = thisRequest->next) { + if (thisRequest->owner != owner) { + __ARQPushTempQueue(thisRequest); + } + } + + __ARQRequestQueueHi = __ARQRequestQueueTemp; + __ARQRequestTailHi = __ARQRequestTailTemp; + __ARQInitTempQueue(); + + for (thisRequest = __ARQRequestQueueLo; thisRequest; thisRequest = thisRequest->next) { + if (thisRequest->owner != owner) { + __ARQPushTempQueue(thisRequest); + } + } + + __ARQRequestQueueLo = __ARQRequestQueueTemp; + __ARQRequestTailLo = __ARQRequestTailTemp; + OSRestoreInterrupts(level); +} + +void ARQFlushQueue(void) { + BOOL level; + + level = OSDisableInterrupts(); + __ARQRequestQueueHi = NULL; + __ARQRequestTailHi = NULL; + __ARQRequestQueueLo = NULL; + __ARQRequestTailLo = NULL; + + OSRestoreInterrupts(level); +} + +void ARQSetChunkSize(u32 size) { + u32 i; + + i = size & 0x1F; + if (i) { + __ARQChunkSize = size + (0x20 - i); + return; + } + __ARQChunkSize = size; +} + +u32 ARQGetChunkSize(void) { + return __ARQChunkSize; +} + +BOOL ARQCheckInit(void) { + return __ARQ_init_flag; +} diff --git a/src/dolphin/ax/AX.c b/src/dolphin/ax/AX.c new file mode 100644 index 0000000000..bc579464d5 --- /dev/null +++ b/src/dolphin/ax/AX.c @@ -0,0 +1,40 @@ +#include +#include + +#include "__ax.h" + +#ifdef DEBUG +const char* __AXVersion = "<< Dolphin SDK - AX\tdebug build: Apr 5 2004 03:56:21 (0x2301) >>"; +#else +const char* __AXVersion = "<< Dolphin SDK - AX\trelease build: Apr 5 2004 04:15:05 (0x2301) >>"; +#endif + +void AXInit(void) { + AXInitEx(0); +} + +void AXInitEx(u32 outputBufferMode) { +#ifdef DEBUG + OSReport("Initializing AX\n"); +#endif + OSRegisterVersion(__AXVersion); + + __AXAllocInit(); + __AXVPBInit(); + __AXSPBInit(); + __AXAuxInit(); + __AXClInit(); + __AXOutInit(outputBufferMode); +} + +void AXQuit(void) { +#ifdef DEBUG + OSReport("Shutting down AX\n"); +#endif + __AXAllocQuit(); + __AXVPBQuit(); + __AXSPBQuit(); + __AXAuxQuit(); + __AXClQuit(); + __AXOutQuit(); +} diff --git a/src/dolphin/ax/AXAlloc.c b/src/dolphin/ax/AXAlloc.c new file mode 100644 index 0000000000..66b3f0331e --- /dev/null +++ b/src/dolphin/ax/AXAlloc.c @@ -0,0 +1,248 @@ +#include +#include + +#include "__ax.h" + +static AXVPB* __AXStackHead[AX_PRIORITY_STACKS]; +static AXVPB* __AXStackTail[AX_PRIORITY_STACKS]; + +static AXVPB* __AXCallbackStack; + +static u32 __AXCheckStacks(void) { + u32 i; + u32 voices; + AXVPB* voice; + + voices = 0; + for (i = 0; i < 32; i++) { + voice = __AXStackHead[i]; + while (voice != 0) { + voices++; + if (voices > 64) { + return 0; + } + + voice = voice->next; + } + } + + return 1; +} + +AXVPB* __AXGetStackHead(u32 priority) { + ASSERTLINE(97, priority < AX_PRIORITY_STACKS); + return __AXStackHead[priority]; +} + +void __AXServiceCallbackStack(void) { + AXVPB* p; + + for (p = __AXPopCallbackStack(); p; p = __AXPopCallbackStack()) { + if (p->priority != 0) { + if (p->callback) { + p->callback(p); + } + + __AXRemoveFromStack(p); + __AXPushFreeStack(p); + } + } +} + +void __AXInitVoiceStacks(void) { + u32 i; + + __AXCallbackStack = NULL; + for (i = 0; i < AX_PRIORITY_STACKS; i++) { + __AXStackHead[i] = __AXStackTail[i] = 0; + } +} + +void __AXAllocInit(void) { +#ifdef DEBUG + OSReport("Initializing AXAlloc code module\n"); +#endif + __AXInitVoiceStacks(); +} + +void __AXAllocQuit(void) { +#ifdef DEBUG + OSReport("Shutting down AXAlloc code module\n"); +#endif + __AXInitVoiceStacks(); +} + +void __AXPushFreeStack(AXVPB* p) { + ASSERTLINE(168, p->priority); + p->next = __AXStackHead[0]; + __AXStackHead[0] = p; + p->priority = 0; +} + +AXVPB* __AXPopFreeStack(void) { + AXVPB* p; + + p = (void*)(u32)&__AXStackHead[0]->next; + if (p) { + __AXStackHead[0] = p->next; + } + return p; +} + +void __AXPushCallbackStack(AXVPB* p) { + p->next1 = __AXCallbackStack; + __AXCallbackStack = p; +} + +AXVPB* __AXPopCallbackStack(void) { + AXVPB* p; + + p = (void*)(u32)&__AXCallbackStack[0]; + if (p) { + __AXCallbackStack = p->next1; + } + return p; +} + +void __AXRemoveFromStack(AXVPB* p) { + u32 i; + AXVPB* head; + AXVPB* tail; + + ASSERTLINE(219, p->priority); + + i = p->priority; + head = __AXStackHead[i]; + tail = __AXStackTail[i]; + if (head == tail) { + __AXStackHead[i] = __AXStackTail[i] = 0; + return; + } + + if (p == head) { + __AXStackHead[i] = p->next; + __AXStackHead[i]->prev = 0; + return; + } + + if (p == tail) { + __AXStackTail[i] = p->prev; + __AXStackTail[i]->next = 0; + return; + } + + head = p->prev; + tail = p->next; + head->next = tail; + tail->prev = head; +} + +void __AXPushStackHead(AXVPB* p, u32 priority) { + ASSERTLINE(261, priority); + ASSERTLINE(262, priority < AX_PRIORITY_STACKS); + + p->next = __AXStackHead[priority]; + p->prev = 0; + + if (p->next) { + __AXStackHead[priority]->prev = p; + __AXStackHead[priority] = p; + } else { + __AXStackTail[priority] = p; + __AXStackHead[priority] = p; + } + + p->priority = priority; +} + +AXVPB* __AXPopStackFromBottom(u32 priority) { + AXVPB* p; + + ASSERTLINE(287, priority); + ASSERTLINE(288, priority < AX_PRIORITY_STACKS); + + p = NULL; + if (__AXStackHead[priority]) { + if (__AXStackHead[priority] == __AXStackTail[priority]) { + p = __AXStackHead[priority]; + __AXStackHead[priority] = __AXStackTail[priority] = 0; + } else if (__AXStackTail[priority]) { + p = __AXStackTail[priority]; + __AXStackTail[priority] = p->prev; + __AXStackTail[priority]->next = 0; + } + } + + return p; +} + +void AXFreeVoice(AXVPB* p) { + BOOL old; + + ASSERTLINE(322, p); + ASSERTMSGLINE(326, p->priority != 0, "Calling AXFreeVoice() for voice that is already free\n"); + + old = OSDisableInterrupts(); + __AXRemoveFromStack(p); + if (p->pb.state == 1) { + p->depop = 1; + } + __AXSetPBDefault(p); + __AXPushFreeStack(p); + + ASSERTMSGLINE(343, __AXCheckStacks() != 0, "Voice list is trashed!\n"); + OSRestoreInterrupts(old); +} + +AXVPB* AXAcquireVoice(u32 priority, void (*callback)(void*), u32 userContext) { + BOOL old; + AXVPB* p; + u32 i; + + ASSERTLINE(361, priority); + ASSERTLINE(362, priority < AX_PRIORITY_STACKS); + + old = OSDisableInterrupts(); + p = __AXPopFreeStack(); + if (p == 0) { + for (i = 1; i < priority; i++) { + p = __AXPopStackFromBottom(i); + if (p) { + if (p->pb.state == 1) { + p->depop = 1; + } + if (p->callback != 0) { + p->callback(p); + } + break; + } + } + } + + if (p) { + __AXPushStackHead(p, priority); + p->callback = callback; + p->userContext = userContext; + __AXSetPBDefault(p); + } + + ASSERTMSGLINE(410, __AXCheckStacks() != 0, "Voice list is trashed!\n"); + OSRestoreInterrupts(old); + return p; +} + +void AXSetVoicePriority(AXVPB* p, u32 priority) { + BOOL old; + + ASSERTLINE(424, p); + ASSERTMSGLINE(428, p->priority != 0, "Calling AXSetVoicePriority() for voice that is already free\n"); + ASSERTMSGLINE(433, priority, "Do not set voice priority to 0, use AXFreeVoice() to free voice\n"); + ASSERTLINE(435, priority < AX_PRIORITY_STACKS); + + old = OSDisableInterrupts(); + __AXRemoveFromStack(p); + __AXPushStackHead(p, priority); + + ASSERTMSGLINE(442, __AXCheckStacks() != 0, "Voice list is trashed!\n"); + OSRestoreInterrupts(old); +} diff --git a/src/dolphin/ax/AXAux.c b/src/dolphin/ax/AXAux.c new file mode 100644 index 0000000000..094dac46a9 --- /dev/null +++ b/src/dolphin/ax/AXAux.c @@ -0,0 +1,167 @@ +#include +#include + +#include "__ax.h" + +static s32 __AXBufferAuxA[3][480] ATTRIBUTE_ALIGN(32); +static s32 __AXBufferAuxB[3][480] ATTRIBUTE_ALIGN(32); + +static void (* __AXCallbackAuxA)(void*, void*); +static void (* __AXCallbackAuxB)(void*, void*); +static void* __AXContextAuxA; +static void* __AXContextAuxB; +static s32* __AXAuxADspWrite; +static s32* __AXAuxADspRead; +static s32* __AXAuxBDspWrite; +static s32* __AXAuxBDspRead; +static u32 __AXAuxDspWritePosition; +static u32 __AXAuxDspReadPosition; +static u32 __AXAuxDspWritePositionDpl2; +static u32 __AXAuxDspReadPositionDpl2; +static u32 __AXAuxCpuReadWritePosition; + +void __AXAuxInit(void) { + int i; + s32* pA; + s32* pB; + +#ifdef DEBUG + OSReport("Initializing AXAux code module\n"); +#endif + __AXCallbackAuxA = NULL; + __AXCallbackAuxB = NULL; + __AXContextAuxA = 0; + __AXContextAuxB = 0; + __AXAuxDspWritePosition = 0; + __AXAuxDspReadPosition = 1; + __AXAuxDspWritePositionDpl2 = 0; + __AXAuxDspReadPositionDpl2 = 1; + __AXAuxCpuReadWritePosition = 2; + + pA = (s32*)&__AXBufferAuxA; + pB = (s32*)&__AXBufferAuxB; + + for (i = 0; i < 480; i++) { + *(pA) = 0; pA++; + *(pB) = 0; pB++; + } +} + +void __AXAuxQuit(void) { +#ifdef DEBUG + OSReport("Shutting down AXAux code module\n"); +#endif + __AXCallbackAuxA = NULL; + __AXCallbackAuxB = NULL; +} + +void __AXGetAuxAInput(u32* p) { + if (__AXCallbackAuxA) { + *p = (u32)&__AXBufferAuxA[__AXAuxDspWritePosition][0]; + } else { + *p = 0; + } +} + +void __AXGetAuxAInputDpl2(u32* p) { + *p = (u32)&__AXBufferAuxB[__AXAuxDspWritePosition][320]; +} + +void __AXGetAuxAOutput(u32* p) { + *p = (u32)&__AXBufferAuxA[__AXAuxDspReadPosition][0]; +} + +void __AXGetAuxAOutputDpl2R(u32* p) { + *p = (u32)&__AXBufferAuxA[__AXAuxDspReadPosition][160]; +} + +void __AXGetAuxAOutputDpl2Ls(u32* p) { + *p = (u32)&__AXBufferAuxA[__AXAuxDspReadPosition][320]; +} + +void __AXGetAuxAOutputDpl2Rs(u32* p) { + *p = (u32)&__AXBufferAuxB[__AXAuxDspReadPosition][320]; +} + +void __AXGetAuxBInput(u32* p) { + if (__AXCallbackAuxB) { + *p = (u32)&__AXBufferAuxB[__AXAuxDspWritePosition][0]; + } else { + *p = 0; + } +} + +void __AXGetAuxBOutput(u32* p) { + *p = (u32)&__AXBufferAuxB[__AXAuxDspReadPosition][0]; +} + +void __AXGetAuxBForDPL2(u32* p) { + *p = (u32)&__AXBufferAuxB[__AXAuxDspWritePositionDpl2][0]; +} + +void __AXGetAuxBOutputDPL2(u32* p) { + *p = (u32)&__AXBufferAuxB[__AXAuxDspReadPositionDpl2][0]; +} + +void __AXProcessAux(void) { + __AXAuxADspWrite = &__AXBufferAuxA[__AXAuxDspWritePosition][0]; + __AXAuxADspRead = &__AXBufferAuxA[__AXAuxDspReadPosition][0]; + __AXAuxBDspWrite = &__AXBufferAuxB[__AXAuxDspWritePosition][0]; + __AXAuxBDspRead = &__AXBufferAuxB[__AXAuxDspReadPosition][0]; + + if (__AXCallbackAuxA) { + if (__AXClMode == 2) { + AX_AUX_DATA_DPL2 auxData; + auxData.l = &__AXBufferAuxA[__AXAuxCpuReadWritePosition][0]; + auxData.r = &__AXBufferAuxA[__AXAuxCpuReadWritePosition][160]; + auxData.ls = &__AXBufferAuxA[__AXAuxCpuReadWritePosition][320]; + auxData.rs = &__AXBufferAuxB[__AXAuxCpuReadWritePosition][320]; + DCInvalidateRange(auxData.l, 0x780); + DCInvalidateRange(auxData.rs, 0x280); + __AXCallbackAuxA(&auxData.l, __AXContextAuxA); + DCFlushRangeNoSync(auxData.l, 0x780); + DCFlushRangeNoSync(auxData.rs, 0x280); + } else { + AX_AUX_DATA auxData; + auxData.l = &__AXBufferAuxA[__AXAuxCpuReadWritePosition][0]; + auxData.r = &__AXBufferAuxA[__AXAuxCpuReadWritePosition][160]; + auxData.s = &__AXBufferAuxA[__AXAuxCpuReadWritePosition][320]; + DCInvalidateRange(auxData.l, 0x780); + __AXCallbackAuxA(&auxData.l, __AXContextAuxA); + DCFlushRangeNoSync(auxData.l, 0x780); + } + } + + if (__AXCallbackAuxB && __AXClMode != 2) { + AX_AUX_DATA auxData; + auxData.l = &__AXBufferAuxB[__AXAuxCpuReadWritePosition][0]; + auxData.r = &__AXBufferAuxB[__AXAuxCpuReadWritePosition][160]; + auxData.s = &__AXBufferAuxB[__AXAuxCpuReadWritePosition][320]; + DCInvalidateRange(auxData.l, 0x780); + __AXCallbackAuxB(&auxData.l, __AXContextAuxB); + DCFlushRangeNoSync(auxData.l, 0x780); + } + + __AXAuxDspWritePosition += 1; + __AXAuxDspWritePosition %= 3; + __AXAuxDspReadPosition += 1; + __AXAuxDspReadPosition %= 3; + + __AXAuxDspWritePositionDpl2 += 1; + __AXAuxDspWritePositionDpl2 &= 1; + __AXAuxDspReadPositionDpl2 += 1; + __AXAuxDspReadPositionDpl2 &= 1; + + __AXAuxCpuReadWritePosition += 1; + __AXAuxCpuReadWritePosition %= 3; +} + +void AXRegisterAuxACallback(void (*callback)(void*, void*), void* context) { + __AXCallbackAuxA = callback; + __AXContextAuxA = context; +} + +void AXRegisterAuxBCallback(void (*callback)(void*, void*), void* context) { + __AXCallbackAuxB = callback; + __AXContextAuxB = context; +} diff --git a/src/dolphin/ax/AXCL.c b/src/dolphin/ax/AXCL.c new file mode 100644 index 0000000000..05107a5f75 --- /dev/null +++ b/src/dolphin/ax/AXCL.c @@ -0,0 +1,176 @@ +#include +#include + +#include "__ax.h" + +static u16 __AXCommandList[2][384]; + +static u32 __AXCommandListPosition; +static u16* __AXClWrite; +static u32 __AXCommandListCycles; +static u32 __AXCompressor; +u32 __AXClMode; + +u32 __AXGetCommandListCycles(void) { + return __AXCommandListCycles; +} + +u32 __AXGetCommandListAddress(void) { + u32 address; + + address = (u32)&__AXCommandList[__AXCommandListPosition][0]; + __AXCommandListPosition += 1; + __AXCommandListPosition &= 1; + __AXClWrite = (void*)&__AXCommandList[__AXCommandListPosition][0]; + return address; +} + +void __AXWriteToCommandList(u16 data) { + *__AXClWrite = data; + __AXClWrite++; +} + +void __AXNextFrame(void* sbuffer, void* buffer) { + u32 data; + u16* pCommandList; + + __AXCommandListCycles = 0x1A9; + pCommandList = __AXClWrite; + data = __AXGetStudio(); + __AXWriteToCommandList(0); + __AXWriteToCommandList((u16)(data >> 0x10)); + __AXWriteToCommandList((u16)(data)); + __AXCommandListCycles += 0x2E44; + + switch (__AXClMode) { + case 0: + __AXWriteToCommandList(7); + __AXWriteToCommandList((u16)((u32)sbuffer >> 0x10)); + __AXWriteToCommandList((u32)sbuffer); + __AXCommandListCycles += 0x546; + break; + case 1: + __AXWriteToCommandList(0x11); + __AXWriteToCommandList((u16)((u32)sbuffer >> 0x10)); + __AXWriteToCommandList((u32)sbuffer); + __AXCommandListCycles += 0x5E6; + break; + case 2: + break; + default: + ASSERTMSGLINE(193, 0, "Unknown AX mode!"); + } + + data = (u32)__AXGetPBs(); + __AXWriteToCommandList(2); + __AXWriteToCommandList((u16)(data >> 0x10)); + __AXWriteToCommandList((u16)data); + __AXWriteToCommandList(3); + + if (__AXClMode == 2) { + __AXGetAuxAInput(&data); + if (data != 0) { + __AXWriteToCommandList(0x13); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXGetAuxAInputDpl2(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXGetAuxAOutput(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXGetAuxAOutputDpl2R(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXGetAuxAOutputDpl2Ls(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXGetAuxAOutputDpl2Rs(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXCommandListCycles += 0xDED; + } + __AXWriteToCommandList(0x10); + __AXGetAuxBForDPL2(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXGetAuxBOutputDPL2(&data); + __AXWriteToCommandList(data >> 0x10); + __AXWriteToCommandList((u16)data); + __AXCommandListCycles += 0xDED; + } else { + __AXGetAuxAInput(&data); + + if (data != 0) { + __AXWriteToCommandList(4); + __AXWriteToCommandList((u16)(data >> 0x10)); + __AXWriteToCommandList((u16)data); + __AXGetAuxAOutput(&data); + __AXWriteToCommandList((u16)(data >> 0x10)); + __AXWriteToCommandList((u16)data); + __AXCommandListCycles += 0xDED; + } + + __AXGetAuxBInput(&data); + if (data != 0) { + __AXWriteToCommandList(5); + __AXCommandListCycles += 0xDED; + __AXWriteToCommandList((u16)(data >> 0x10)); + __AXWriteToCommandList((u16)data); + __AXGetAuxBOutput(&data); + __AXWriteToCommandList((u16)(data >> 0x10)); + __AXWriteToCommandList((u16)data); + } + } + + if (__AXCompressor) { + __AXWriteToCommandList(0x12); + __AXWriteToCommandList(0x8000); + __AXWriteToCommandList(0xA); + __AXWriteToCommandList((u32)__AXCompressorTable >> 0x10); + __AXWriteToCommandList((u32)__AXCompressorTable); + __AXCommandListCycles += 0xBB8; + } + + __AXWriteToCommandList(0xE); + __AXWriteToCommandList((u16)((u32)sbuffer >> 0x10)); + __AXWriteToCommandList((u32)sbuffer); + __AXWriteToCommandList((u16)((u32)buffer >> 0x10)); + __AXWriteToCommandList((u32)buffer); + __AXCommandListCycles += 0x2710; + __AXWriteToCommandList(0xF); + __AXCommandListCycles += 2; + DCFlushRange(pCommandList, 0x300); +} + +void __AXClInit(void) { +#ifdef DEBUG + OSReport("Initializing AXCL code module\n"); +#endif + ASSERTLINE(338, ((u32)&__AXCommandList[0][0] & 0x1F) == 0); + ASSERTLINE(339, ((u32)&__AXCommandList[1][0] & 0x1F) == 0); + __AXClMode = 0; + __AXCommandListPosition = 0; + __AXClWrite = (void*)&__AXCommandList; + __AXCompressor = 1; +} + +void __AXClQuit(void) { +#ifdef DEBUG + OSReport("Shutting down AXCL code module\n"); +#endif +} + +void AXSetMode(u32 mode) { + if (__AXClMode != mode) { + __AXClMode = mode; + } +} + +u32 AXGetMode(void) { + return __AXClMode; +} + +void AXSetCompressor(u32 i) { + __AXCompressor = i; +} diff --git a/src/dolphin/ax/AXComp.c b/src/dolphin/ax/AXComp.c new file mode 100644 index 0000000000..bc0eb97c87 --- /dev/null +++ b/src/dolphin/ax/AXComp.c @@ -0,0 +1,567 @@ +#include +#include + +#include "__ax.h" + +u16 __AXCompressorTable[3360] = { + 0x7FA1, 0x7F43, 0x7EE6, 0x7E88, 0x7E2B, 0x7DCE, + 0x7D72, 0x7D16, 0x7CBA, 0x7C5E, 0x7C02, 0x7BA7, + 0x7B4C, 0x7AF1, 0x7A97, 0x7A3D, 0x79E3, 0x7989, + 0x7930, 0x78D6, 0x787E, 0x7825, 0x77CD, 0x7774, + 0x771C, 0x76C5, 0x766D, 0x7616, 0x75BF, 0x7569, + 0x7512, 0x74BC, 0x7466, 0x7411, 0x73BB, 0x7366, + 0x7311, 0x72BD, 0x7268, 0x7214, 0x71C0, 0x716C, + 0x7119, 0x70C6, 0x7073, 0x7020, 0x6FCD, 0x6F7B, + 0x6F29, 0x6ED7, 0x6E86, 0x6E35, 0x6DE3, 0x6D93, + 0x6D42, 0x6CF2, 0x6CA1, 0x6C52, 0x6C02, 0x6BB2, + 0x6B63, 0x6B14, 0x6AC5, 0x6A77, 0x6A28, 0x69DA, + 0x698C, 0x693F, 0x68F1, 0x68A4, 0x6857, 0x680A, + 0x67BE, 0x6771, 0x6725, 0x66D9, 0x668E, 0x6642, + 0x65F7, 0x65AC, 0x6561, 0x6517, 0x64CC, 0x6482, + 0x6438, 0x63EE, 0x63A5, 0x635C, 0x6312, 0x62CA, + 0x6281, 0x6238, 0x61F0, 0x61A8, 0x6160, 0x6119, + 0x60D1, 0x608A, 0x6043, 0x5FFC, 0x5FB5, 0x5F6F, + 0x5F29, 0x5EE3, 0x5E9D, 0x5E57, 0x5E12, 0x5DCD, + 0x5D88, 0x5D43, 0x5CFE, 0x5CBA, 0x5C76, 0x5C32, + 0x5BEE, 0x5BAA, 0x5B67, 0x5B23, 0x5AE0, 0x5A9D, + 0x5A5B, 0x5A18, 0x59D6, 0x5994, 0x5952, 0x5910, + 0x58CF, 0x588D, 0x584C, 0x580B, 0x57CB, 0x578A, + 0x574A, 0x5709, 0x56C9, 0x5689, 0x564A, 0x560A, + 0x55CB, 0x558C, 0x554D, 0x550E, 0x54D0, 0x5491, + 0x5453, 0x5415, 0x53D7, 0x5399, 0x535C, 0x531E, + 0x52E1, 0x52A4, 0x5267, 0x522B, 0x51EE, 0x51B2, + 0x5176, 0x513A, 0x50FE, 0x50C3, 0x79EC, 0x799B, + 0x794A, 0x78FA, 0x78AA, 0x785A, 0x780A, 0x77BB, + 0x776C, 0x771C, 0x76CE, 0x767F, 0x7630, 0x75E2, + 0x7594, 0x7546, 0x74F9, 0x74AB, 0x745E, 0x7411, + 0x73C4, 0x7377, 0x732B, 0x72DE, 0x7292, 0x7246, + 0x71FB, 0x71AF, 0x7164, 0x7119, 0x70CE, 0x7083, + 0x7039, 0x6FEE, 0x6FA4, 0x6F5A, 0x6F11, 0x6EC7, + 0x6E7E, 0x6E35, 0x6DEC, 0x6DA3, 0x6D5A, 0x6D12, + 0x6CC9, 0x6C81, 0x6C3A, 0x6BF2, 0x6BAA, 0x6B63, + 0x6B1C, 0x6AD5, 0x6A8E, 0x6A48, 0x6A01, 0x69BB, + 0x6975, 0x692F, 0x68EA, 0x68A4, 0x685F, 0x681A, + 0x67D5, 0x6790, 0x674B, 0x6707, 0x66C3, 0x667F, + 0x663B, 0x65F7, 0x65B4, 0x6570, 0x652D, 0x64EA, + 0x64A7, 0x6464, 0x6422, 0x63E0, 0x639E, 0x635C, + 0x631A, 0x62D8, 0x6297, 0x6255, 0x6214, 0x61D3, + 0x6192, 0x6152, 0x6111, 0x60D1, 0x6091, 0x6051, + 0x6011, 0x5FD2, 0x5F92, 0x5F53, 0x5F14, 0x5ED5, + 0x5E96, 0x5E57, 0x5E19, 0x5DDB, 0x5D9C, 0x5D5E, + 0x5D21, 0x5CE3, 0x5CA5, 0x5C68, 0x5C2B, 0x5BEE, + 0x5BB1, 0x5B74, 0x5B38, 0x5AFB, 0x5ABF, 0x5A83, + 0x5A47, 0x5A0B, 0x59CF, 0x5994, 0x5959, 0x591D, + 0x58E2, 0x58A8, 0x586D, 0x5832, 0x57F8, 0x57BE, + 0x5783, 0x574A, 0x5710, 0x56D6, 0x569D, 0x5663, + 0x562A, 0x55F1, 0x55B8, 0x557F, 0x5547, 0x550E, + 0x54D6, 0x549E, 0x5466, 0x542E, 0x53F6, 0x53BE, + 0x5387, 0x534F, 0x5318, 0x52E1, 0x52AA, 0x5274, + 0x523D, 0x5207, 0x51D0, 0x519A, 0x5164, 0x512E, + 0x50F8, 0x50C3, 0x7478, 0x7433, 0x73EF, 0x73AA, + 0x7366, 0x7322, 0x72DE, 0x729B, 0x7257, 0x7214, + 0x71D1, 0x718E, 0x714B, 0x7108, 0x70C6, 0x7083, + 0x7041, 0x6FFF, 0x6FBD, 0x6F7B, 0x6F3A, 0x6EF8, + 0x6EB7, 0x6E76, 0x6E35, 0x6DF4, 0x6DB3, 0x6D72, + 0x6D32, 0x6CF2, 0x6CB1, 0x6C71, 0x6C32, 0x6BF2, + 0x6BB2, 0x6B73, 0x6B34, 0x6AF5, 0x6AB6, 0x6A77, + 0x6A38, 0x69FA, 0x69BB, 0x697D, 0x693F, 0x6901, + 0x68C3, 0x6885, 0x6848, 0x680A, 0x67CD, 0x6790, + 0x6753, 0x6716, 0x66D9, 0x669D, 0x6660, 0x6624, + 0x65E8, 0x65AC, 0x6570, 0x6534, 0x64F9, 0x64BD, + 0x6482, 0x6447, 0x640C, 0x63D1, 0x6396, 0x635C, + 0x6321, 0x62E7, 0x62AC, 0x6272, 0x6238, 0x61FF, + 0x61C5, 0x618B, 0x6152, 0x6119, 0x60DF, 0x60A6, + 0x606D, 0x6035, 0x5FFC, 0x5FC4, 0x5F8B, 0x5F53, + 0x5F1B, 0x5EE3, 0x5EAB, 0x5E73, 0x5E3C, 0x5E04, + 0x5DCD, 0x5D95, 0x5D5E, 0x5D27, 0x5CF1, 0x5CBA, + 0x5C83, 0x5C4D, 0x5C16, 0x5BE0, 0x5BAA, 0x5B74, + 0x5B3E, 0x5B09, 0x5AD3, 0x5A9D, 0x5A68, 0x5A33, + 0x59FE, 0x59C9, 0x5994, 0x595F, 0x592B, 0x58F6, + 0x58C2, 0x588D, 0x5859, 0x5825, 0x57F1, 0x57BE, + 0x578A, 0x5756, 0x5723, 0x56F0, 0x56BC, 0x5689, + 0x5656, 0x5624, 0x55F1, 0x55BE, 0x558C, 0x5559, + 0x5527, 0x54F5, 0x54C3, 0x5491, 0x545F, 0x542E, + 0x53FC, 0x53CB, 0x5399, 0x5368, 0x5337, 0x5306, + 0x52D5, 0x52A4, 0x5274, 0x5243, 0x5213, 0x51E2, + 0x51B2, 0x5182, 0x5152, 0x5122, 0x50F2, 0x50C3, + 0x6F42, 0x6F08, 0x6ECF, 0x6E96, 0x6E5D, 0x6E24, + 0x6DEC, 0x6DB3, 0x6D7A, 0x6D42, 0x6D0A, 0x6CD2, + 0x6C99, 0x6C61, 0x6C2A, 0x6BF2, 0x6BBA, 0x6B83, + 0x6B4B, 0x6B14, 0x6ADD, 0x6AA6, 0x6A6F, 0x6A38, + 0x6A01, 0x69CB, 0x6994, 0x695E, 0x6927, 0x68F1, + 0x68BB, 0x6885, 0x684F, 0x681A, 0x67E4, 0x67AE, + 0x6779, 0x6744, 0x670F, 0x66D9, 0x66A4, 0x6670, + 0x663B, 0x6606, 0x65D2, 0x659D, 0x6569, 0x6534, + 0x6500, 0x64CC, 0x6498, 0x6464, 0x6431, 0x63FD, + 0x63CA, 0x6396, 0x6363, 0x6330, 0x62FD, 0x62CA, + 0x6297, 0x6264, 0x6231, 0x61FF, 0x61CC, 0x619A, + 0x6167, 0x6135, 0x6103, 0x60D1, 0x609F, 0x606D, + 0x603C, 0x600A, 0x5FD9, 0x5FA7, 0x5F76, 0x5F45, + 0x5F14, 0x5EE3, 0x5EB2, 0x5E81, 0x5E50, 0x5E20, + 0x5DEF, 0x5DBF, 0x5D8F, 0x5D5E, 0x5D2E, 0x5CFE, + 0x5CCE, 0x5C9F, 0x5C6F, 0x5C3F, 0x5C10, 0x5BE0, + 0x5BB1, 0x5B82, 0x5B52, 0x5B23, 0x5AF4, 0x5AC6, + 0x5A97, 0x5A68, 0x5A3A, 0x5A0B, 0x59DD, 0x59AE, + 0x5980, 0x5952, 0x5924, 0x58F6, 0x58C8, 0x589A, + 0x586D, 0x583F, 0x5812, 0x57E4, 0x57B7, 0x578A, + 0x575D, 0x5730, 0x5703, 0x56D6, 0x56A9, 0x567D, + 0x5650, 0x5624, 0x55F7, 0x55CB, 0x559F, 0x5573, + 0x5547, 0x551B, 0x54EF, 0x54C3, 0x5497, 0x546C, + 0x5440, 0x5415, 0x53EA, 0x53BE, 0x5393, 0x5368, + 0x533D, 0x5312, 0x52E7, 0x52BD, 0x5292, 0x5267, + 0x523D, 0x5213, 0x51E8, 0x51BE, 0x5194, 0x516A, + 0x5140, 0x5116, 0x50EC, 0x50C3, 0x6A48, 0x6A19, + 0x69EA, 0x69BB, 0x698C, 0x695E, 0x692F, 0x6901, + 0x68D2, 0x68A4, 0x6876, 0x6848, 0x681A, 0x67EC, + 0x67BE, 0x6790, 0x6762, 0x6735, 0x6707, 0x66D9, + 0x66AC, 0x667F, 0x6651, 0x6624, 0x65F7, 0x65CA, + 0x659D, 0x6570, 0x6543, 0x6517, 0x64EA, 0x64BD, + 0x6491, 0x6464, 0x6438, 0x640C, 0x63E0, 0x63B4, + 0x6388, 0x635C, 0x6330, 0x6304, 0x62D8, 0x62AC, + 0x6281, 0x6255, 0x622A, 0x61FF, 0x61D3, 0x61A8, + 0x617D, 0x6152, 0x6127, 0x60FC, 0x60D1, 0x60A6, + 0x607C, 0x6051, 0x6027, 0x5FFC, 0x5FD2, 0x5FA7, + 0x5F7D, 0x5F53, 0x5F29, 0x5EFF, 0x5ED5, 0x5EAB, + 0x5E81, 0x5E57, 0x5E2E, 0x5E04, 0x5DDB, 0x5DB1, + 0x5D88, 0x5D5E, 0x5D35, 0x5D0C, 0x5CE3, 0x5CBA, + 0x5C91, 0x5C68, 0x5C3F, 0x5C16, 0x5BEE, 0x5BC5, + 0x5B9D, 0x5B74, 0x5B4C, 0x5B23, 0x5AFB, 0x5AD3, + 0x5AAB, 0x5A83, 0x5A5B, 0x5A33, 0x5A0B, 0x59E3, + 0x59BC, 0x5994, 0x596C, 0x5945, 0x591D, 0x58F6, + 0x58CF, 0x58A8, 0x5880, 0x5859, 0x5832, 0x580B, + 0x57E4, 0x57BE, 0x5797, 0x5770, 0x574A, 0x5723, + 0x56FC, 0x56D6, 0x56B0, 0x5689, 0x5663, 0x563D, + 0x5617, 0x55F1, 0x55CB, 0x55A5, 0x557F, 0x5559, + 0x5534, 0x550E, 0x54E9, 0x54C3, 0x549E, 0x5478, + 0x5453, 0x542E, 0x5408, 0x53E3, 0x53BE, 0x5399, + 0x5374, 0x534F, 0x532B, 0x5306, 0x52E1, 0x52BD, + 0x5298, 0x5274, 0x524F, 0x522B, 0x5207, 0x51E2, + 0x51BE, 0x519A, 0x5176, 0x5152, 0x512E, 0x510A, + 0x50E6, 0x50C3, 0x6587, 0x6561, 0x653C, 0x6517, + 0x64F1, 0x64CC, 0x64A7, 0x6482, 0x645D, 0x6438, + 0x6413, 0x63EE, 0x63CA, 0x63A5, 0x6380, 0x635C, + 0x6337, 0x6312, 0x62EE, 0x62CA, 0x62A5, 0x6281, + 0x625D, 0x6238, 0x6214, 0x61F0, 0x61CC, 0x61A8, + 0x6184, 0x6160, 0x613C, 0x6119, 0x60F5, 0x60D1, + 0x60AD, 0x608A, 0x6066, 0x6043, 0x601F, 0x5FFC, + 0x5FD9, 0x5FB5, 0x5F92, 0x5F6F, 0x5F4C, 0x5F29, + 0x5F06, 0x5EE3, 0x5EC0, 0x5E9D, 0x5E7A, 0x5E57, + 0x5E35, 0x5E12, 0x5DEF, 0x5DCD, 0x5DAA, 0x5D88, + 0x5D65, 0x5D43, 0x5D21, 0x5CFE, 0x5CDC, 0x5CBA, + 0x5C98, 0x5C76, 0x5C54, 0x5C32, 0x5C10, 0x5BEE, + 0x5BCC, 0x5BAA, 0x5B88, 0x5B67, 0x5B45, 0x5B23, + 0x5B02, 0x5AE0, 0x5ABF, 0x5A9D, 0x5A7C, 0x5A5B, + 0x5A3A, 0x5A18, 0x59F7, 0x59D6, 0x59B5, 0x5994, + 0x5973, 0x5952, 0x5931, 0x5910, 0x58F0, 0x58CF, + 0x58AE, 0x588D, 0x586D, 0x584C, 0x582C, 0x580B, + 0x57EB, 0x57CB, 0x57AA, 0x578A, 0x576A, 0x574A, + 0x5729, 0x5709, 0x56E9, 0x56C9, 0x56A9, 0x5689, + 0x566A, 0x564A, 0x562A, 0x560A, 0x55EB, 0x55CB, + 0x55AB, 0x558C, 0x556C, 0x554D, 0x552D, 0x550E, + 0x54EF, 0x54D0, 0x54B0, 0x5491, 0x5472, 0x5453, + 0x5434, 0x5415, 0x53F6, 0x53D7, 0x53B8, 0x5399, + 0x537B, 0x535C, 0x533D, 0x531E, 0x5300, 0x52E1, + 0x52C3, 0x52A4, 0x5286, 0x5267, 0x5249, 0x522B, + 0x520D, 0x51EE, 0x51D0, 0x51B2, 0x5194, 0x5176, + 0x5158, 0x513A, 0x511C, 0x50FE, 0x50E0, 0x50C3, + 0x60FC, 0x60DF, 0x60C3, 0x60A6, 0x608A, 0x606D, + 0x6051, 0x6035, 0x6018, 0x5FFC, 0x5FE0, 0x5FC4, + 0x5FA7, 0x5F8B, 0x5F6F, 0x5F53, 0x5F37, 0x5F1B, + 0x5EFF, 0x5EE3, 0x5EC7, 0x5EAB, 0x5E8F, 0x5E73, + 0x5E57, 0x5E3C, 0x5E20, 0x5E04, 0x5DE8, 0x5DCD, + 0x5DB1, 0x5D95, 0x5D7A, 0x5D5E, 0x5D43, 0x5D27, + 0x5D0C, 0x5CF1, 0x5CD5, 0x5CBA, 0x5C9F, 0x5C83, + 0x5C68, 0x5C4D, 0x5C32, 0x5C16, 0x5BFB, 0x5BE0, + 0x5BC5, 0x5BAA, 0x5B8F, 0x5B74, 0x5B59, 0x5B3E, + 0x5B23, 0x5B09, 0x5AEE, 0x5AD3, 0x5AB8, 0x5A9D, + 0x5A83, 0x5A68, 0x5A4D, 0x5A33, 0x5A18, 0x59FE, + 0x59E3, 0x59C9, 0x59AE, 0x5994, 0x597A, 0x595F, + 0x5945, 0x592B, 0x5910, 0x58F6, 0x58DC, 0x58C2, + 0x58A8, 0x588D, 0x5873, 0x5859, 0x583F, 0x5825, + 0x580B, 0x57F1, 0x57D7, 0x57BE, 0x57A4, 0x578A, + 0x5770, 0x5756, 0x573D, 0x5723, 0x5709, 0x56F0, + 0x56D6, 0x56BC, 0x56A3, 0x5689, 0x5670, 0x5656, + 0x563D, 0x5624, 0x560A, 0x55F1, 0x55D8, 0x55BE, + 0x55A5, 0x558C, 0x5573, 0x5559, 0x5540, 0x5527, + 0x550E, 0x54F5, 0x54DC, 0x54C3, 0x54AA, 0x5491, + 0x5478, 0x545F, 0x5446, 0x542E, 0x5415, 0x53FC, + 0x53E3, 0x53CB, 0x53B2, 0x5399, 0x5381, 0x5368, + 0x534F, 0x5337, 0x531E, 0x5306, 0x52ED, 0x52D5, + 0x52BD, 0x52A4, 0x528C, 0x5274, 0x525B, 0x5243, + 0x522B, 0x5213, 0x51FA, 0x51E2, 0x51CA, 0x51B2, + 0x519A, 0x5182, 0x516A, 0x5152, 0x513A, 0x5122, + 0x510A, 0x50F2, 0x50DB, 0x50C3, 0x5CA5, 0x5C91, + 0x5C7C, 0x5C68, 0x5C54, 0x5C3F, 0x5C2B, 0x5C16, + 0x5C02, 0x5BEE, 0x5BD9, 0x5BC5, 0x5BB1, 0x5B9D, + 0x5B88, 0x5B74, 0x5B60, 0x5B4C, 0x5B38, 0x5B23, + 0x5B0F, 0x5AFB, 0x5AE7, 0x5AD3, 0x5ABF, 0x5AAB, + 0x5A97, 0x5A83, 0x5A6F, 0x5A5B, 0x5A47, 0x5A33, + 0x5A1F, 0x5A0B, 0x59F7, 0x59E3, 0x59CF, 0x59BC, + 0x59A8, 0x5994, 0x5980, 0x596C, 0x5959, 0x5945, + 0x5931, 0x591D, 0x590A, 0x58F6, 0x58E2, 0x58CF, + 0x58BB, 0x58A8, 0x5894, 0x5880, 0x586D, 0x5859, + 0x5846, 0x5832, 0x581F, 0x580B, 0x57F8, 0x57E4, + 0x57D1, 0x57BE, 0x57AA, 0x5797, 0x5783, 0x5770, + 0x575D, 0x574A, 0x5736, 0x5723, 0x5710, 0x56FC, + 0x56E9, 0x56D6, 0x56C3, 0x56B0, 0x569D, 0x5689, + 0x5676, 0x5663, 0x5650, 0x563D, 0x562A, 0x5617, + 0x5604, 0x55F1, 0x55DE, 0x55CB, 0x55B8, 0x55A5, + 0x5592, 0x557F, 0x556C, 0x5559, 0x5547, 0x5534, + 0x5521, 0x550E, 0x54FB, 0x54E9, 0x54D6, 0x54C3, + 0x54B0, 0x549E, 0x548B, 0x5478, 0x5466, 0x5453, + 0x5440, 0x542E, 0x541B, 0x5408, 0x53F6, 0x53E3, + 0x53D1, 0x53BE, 0x53AC, 0x5399, 0x5387, 0x5374, + 0x5362, 0x534F, 0x533D, 0x532B, 0x5318, 0x5306, + 0x52F4, 0x52E1, 0x52CF, 0x52BD, 0x52AA, 0x5298, + 0x5286, 0x5274, 0x5261, 0x524F, 0x523D, 0x522B, + 0x5219, 0x5207, 0x51F4, 0x51E2, 0x51D0, 0x51BE, + 0x51AC, 0x519A, 0x5188, 0x5176, 0x5164, 0x5152, + 0x5140, 0x512E, 0x511C, 0x510A, 0x50F8, 0x50E6, + 0x50D5, 0x50C3, 0x5880, 0x5873, 0x5866, 0x5859, + 0x584C, 0x583F, 0x5832, 0x5825, 0x5818, 0x580B, + 0x57FE, 0x57F1, 0x57E4, 0x57D7, 0x57CB, 0x57BE, + 0x57B1, 0x57A4, 0x5797, 0x578A, 0x577D, 0x5770, + 0x5763, 0x5756, 0x574A, 0x573D, 0x5730, 0x5723, + 0x5716, 0x5709, 0x56FC, 0x56F0, 0x56E3, 0x56D6, + 0x56C9, 0x56BC, 0x56B0, 0x56A3, 0x5696, 0x5689, + 0x567D, 0x5670, 0x5663, 0x5656, 0x564A, 0x563D, + 0x5630, 0x5624, 0x5617, 0x560A, 0x55FE, 0x55F1, + 0x55E4, 0x55D8, 0x55CB, 0x55BE, 0x55B2, 0x55A5, + 0x5598, 0x558C, 0x557F, 0x5573, 0x5566, 0x5559, + 0x554D, 0x5540, 0x5534, 0x5527, 0x551B, 0x550E, + 0x5502, 0x54F5, 0x54E9, 0x54DC, 0x54D0, 0x54C3, + 0x54B7, 0x54AA, 0x549E, 0x5491, 0x5485, 0x5478, + 0x546C, 0x545F, 0x5453, 0x5446, 0x543A, 0x542E, + 0x5421, 0x5415, 0x5408, 0x53FC, 0x53F0, 0x53E3, + 0x53D7, 0x53CB, 0x53BE, 0x53B2, 0x53A6, 0x5399, + 0x538D, 0x5381, 0x5374, 0x5368, 0x535C, 0x534F, + 0x5343, 0x5337, 0x532B, 0x531E, 0x5312, 0x5306, + 0x52FA, 0x52ED, 0x52E1, 0x52D5, 0x52C9, 0x52BD, + 0x52B0, 0x52A4, 0x5298, 0x528C, 0x5280, 0x5274, + 0x5267, 0x525B, 0x524F, 0x5243, 0x5237, 0x522B, + 0x521F, 0x5213, 0x5207, 0x51FA, 0x51EE, 0x51E2, + 0x51D6, 0x51CA, 0x51BE, 0x51B2, 0x51A6, 0x519A, + 0x518E, 0x5182, 0x5176, 0x516A, 0x515E, 0x5152, + 0x5146, 0x513A, 0x512E, 0x5122, 0x5116, 0x510A, + 0x50FE, 0x50F2, 0x50E6, 0x50DB, 0x50CF, 0x50C3, + 0x548B, 0x5485, 0x547E, 0x5478, 0x5472, 0x546C, + 0x5466, 0x545F, 0x5459, 0x5453, 0x544D, 0x5446, + 0x5440, 0x543A, 0x5434, 0x542E, 0x5427, 0x5421, + 0x541B, 0x5415, 0x540F, 0x5408, 0x5402, 0x53FC, + 0x53F6, 0x53F0, 0x53EA, 0x53E3, 0x53DD, 0x53D7, + 0x53D1, 0x53CB, 0x53C4, 0x53BE, 0x53B8, 0x53B2, + 0x53AC, 0x53A6, 0x539F, 0x5399, 0x5393, 0x538D, + 0x5387, 0x5381, 0x537B, 0x5374, 0x536E, 0x5368, + 0x5362, 0x535C, 0x5356, 0x534F, 0x5349, 0x5343, + 0x533D, 0x5337, 0x5331, 0x532B, 0x5325, 0x531E, + 0x5318, 0x5312, 0x530C, 0x5306, 0x5300, 0x52FA, + 0x52F4, 0x52ED, 0x52E7, 0x52E1, 0x52DB, 0x52D5, + 0x52CF, 0x52C9, 0x52C3, 0x52BD, 0x52B7, 0x52B0, + 0x52AA, 0x52A4, 0x529E, 0x5298, 0x5292, 0x528C, + 0x5286, 0x5280, 0x527A, 0x5274, 0x526E, 0x5267, + 0x5261, 0x525B, 0x5255, 0x524F, 0x5249, 0x5243, + 0x523D, 0x5237, 0x5231, 0x522B, 0x5225, 0x521F, + 0x5219, 0x5213, 0x520D, 0x5207, 0x5201, 0x51FA, + 0x51F4, 0x51EE, 0x51E8, 0x51E2, 0x51DC, 0x51D6, + 0x51D0, 0x51CA, 0x51C4, 0x51BE, 0x51B8, 0x51B2, + 0x51AC, 0x51A6, 0x51A0, 0x519A, 0x5194, 0x518E, + 0x5188, 0x5182, 0x517C, 0x5176, 0x5170, 0x516A, + 0x5164, 0x515E, 0x5158, 0x5152, 0x514C, 0x5146, + 0x5140, 0x513A, 0x5134, 0x512E, 0x5128, 0x5122, + 0x511C, 0x5116, 0x5110, 0x510A, 0x5104, 0x50FE, + 0x50F8, 0x50F2, 0x50EC, 0x50E6, 0x50E0, 0x50DB, + 0x50D5, 0x50CF, 0x50C9, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, 0x50C3, + 0x50C3, 0x50C3, 0x7A46, 0x7A4F, 0x7A58, 0x7A61, + 0x7A6A, 0x7A73, 0x7A7C, 0x7A85, 0x7A8E, 0x7A97, + 0x7AA0, 0x7AA9, 0x7AB2, 0x7ABB, 0x7AC4, 0x7ACD, + 0x7AD6, 0x7ADF, 0x7AE8, 0x7AF1, 0x7AFA, 0x7B03, + 0x7B0D, 0x7B16, 0x7B1F, 0x7B28, 0x7B31, 0x7B3A, + 0x7B43, 0x7B4C, 0x7B55, 0x7B5E, 0x7B67, 0x7B70, + 0x7B7A, 0x7B83, 0x7B8C, 0x7B95, 0x7B9E, 0x7BA7, + 0x7BB0, 0x7BB9, 0x7BC2, 0x7BCC, 0x7BD5, 0x7BDE, + 0x7BE7, 0x7BF0, 0x7BF9, 0x7C02, 0x7C0B, 0x7C15, + 0x7C1E, 0x7C27, 0x7C30, 0x7C39, 0x7C42, 0x7C4B, + 0x7C55, 0x7C5E, 0x7C67, 0x7C70, 0x7C79, 0x7C82, + 0x7C8C, 0x7C95, 0x7C9E, 0x7CA7, 0x7CB0, 0x7CBA, + 0x7CC3, 0x7CCC, 0x7CD5, 0x7CDE, 0x7CE8, 0x7CF1, + 0x7CFA, 0x7D03, 0x7D0C, 0x7D16, 0x7D1F, 0x7D28, + 0x7D31, 0x7D3A, 0x7D44, 0x7D4D, 0x7D56, 0x7D5F, + 0x7D69, 0x7D72, 0x7D7B, 0x7D84, 0x7D8E, 0x7D97, + 0x7DA0, 0x7DA9, 0x7DB3, 0x7DBC, 0x7DC5, 0x7DCE, + 0x7DD8, 0x7DE1, 0x7DEA, 0x7DF4, 0x7DFD, 0x7E06, + 0x7E0F, 0x7E19, 0x7E22, 0x7E2B, 0x7E35, 0x7E3E, + 0x7E47, 0x7E51, 0x7E5A, 0x7E63, 0x7E6C, 0x7E76, + 0x7E7F, 0x7E88, 0x7E92, 0x7E9B, 0x7EA4, 0x7EAE, + 0x7EB7, 0x7EC0, 0x7ECA, 0x7ED3, 0x7EDC, 0x7EE6, + 0x7EEF, 0x7EF8, 0x7F02, 0x7F0B, 0x7F15, 0x7F1E, + 0x7F27, 0x7F31, 0x7F3A, 0x7F43, 0x7F4D, 0x7F56, + 0x7F60, 0x7F69, 0x7F72, 0x7F7C, 0x7F85, 0x7F8F, + 0x7F98, 0x7FA1, 0x7FAB, 0x7FB4, 0x7FBE, 0x7FC7, + 0x7FD0, 0x7FDA, 0x7FE3, 0x7FED, 0x7FF6, 0x8000, + 0x74C5, 0x74CD, 0x74D6, 0x74DF, 0x74E7, 0x74F0, + 0x74F9, 0x7501, 0x750A, 0x7512, 0x751B, 0x7524, + 0x752C, 0x7535, 0x753E, 0x7546, 0x754F, 0x7558, + 0x7560, 0x7569, 0x7571, 0x757A, 0x7583, 0x758B, + 0x7594, 0x759D, 0x75A5, 0x75AE, 0x75B7, 0x75BF, + 0x75C8, 0x75D1, 0x75D9, 0x75E2, 0x75EB, 0x75F4, + 0x75FC, 0x7605, 0x760E, 0x7616, 0x761F, 0x7628, + 0x7630, 0x7639, 0x7642, 0x764B, 0x7653, 0x765C, + 0x7665, 0x766D, 0x7676, 0x767F, 0x7688, 0x7690, + 0x7699, 0x76A2, 0x76AB, 0x76B3, 0x76BC, 0x76C5, + 0x76CE, 0x76D6, 0x76DF, 0x76E8, 0x76F1, 0x76F9, + 0x7702, 0x770B, 0x7714, 0x771C, 0x7725, 0x772E, + 0x7737, 0x7740, 0x7748, 0x7751, 0x775A, 0x7763, + 0x776C, 0x7774, 0x777D, 0x7786, 0x778F, 0x7798, + 0x77A0, 0x77A9, 0x77B2, 0x77BB, 0x77C4, 0x77CD, + 0x77D5, 0x77DE, 0x77E7, 0x77F0, 0x77F9, 0x7802, + 0x780A, 0x7813, 0x781C, 0x7825, 0x782E, 0x7837, + 0x783F, 0x7848, 0x7851, 0x785A, 0x7863, 0x786C, + 0x7875, 0x787E, 0x7886, 0x788F, 0x7898, 0x78A1, + 0x78AA, 0x78B3, 0x78BC, 0x78C5, 0x78CE, 0x78D6, + 0x78DF, 0x78E8, 0x78F1, 0x78FA, 0x7903, 0x790C, + 0x7915, 0x791E, 0x7927, 0x7930, 0x7939, 0x7942, + 0x794A, 0x7953, 0x795C, 0x7965, 0x796E, 0x7977, + 0x7980, 0x7989, 0x7992, 0x799B, 0x79A4, 0x79AD, + 0x79B6, 0x79BF, 0x79C8, 0x79D1, 0x79DA, 0x79E3, + 0x79EC, 0x79F5, 0x79FE, 0x7A07, 0x7A10, 0x7A19, + 0x7A22, 0x7A2B, 0x7A34, 0x7A3D, 0x6F83, 0x6F8C, + 0x6F94, 0x6F9C, 0x6FA4, 0x6FAD, 0x6FB5, 0x6FBD, + 0x6FC5, 0x6FCD, 0x6FD6, 0x6FDE, 0x6FE6, 0x6FEE, + 0x6FF7, 0x6FFF, 0x7007, 0x700F, 0x7018, 0x7020, + 0x7028, 0x7031, 0x7039, 0x7041, 0x7049, 0x7052, + 0x705A, 0x7062, 0x706A, 0x7073, 0x707B, 0x7083, + 0x708C, 0x7094, 0x709C, 0x70A4, 0x70AD, 0x70B5, + 0x70BD, 0x70C6, 0x70CE, 0x70D6, 0x70DF, 0x70E7, + 0x70EF, 0x70F8, 0x7100, 0x7108, 0x7111, 0x7119, + 0x7121, 0x712A, 0x7132, 0x713A, 0x7143, 0x714B, + 0x7153, 0x715C, 0x7164, 0x716C, 0x7175, 0x717D, + 0x7185, 0x718E, 0x7196, 0x719F, 0x71A7, 0x71AF, + 0x71B8, 0x71C0, 0x71C8, 0x71D1, 0x71D9, 0x71E2, + 0x71EA, 0x71F2, 0x71FB, 0x7203, 0x720C, 0x7214, + 0x721C, 0x7225, 0x722D, 0x7236, 0x723E, 0x7246, + 0x724F, 0x7257, 0x7260, 0x7268, 0x7271, 0x7279, + 0x7281, 0x728A, 0x7292, 0x729B, 0x72A3, 0x72AC, + 0x72B4, 0x72BD, 0x72C5, 0x72CE, 0x72D6, 0x72DE, + 0x72E7, 0x72EF, 0x72F8, 0x7300, 0x7309, 0x7311, + 0x731A, 0x7322, 0x732B, 0x7333, 0x733C, 0x7344, + 0x734D, 0x7355, 0x735E, 0x7366, 0x736F, 0x7377, + 0x7380, 0x7388, 0x7391, 0x7399, 0x73A2, 0x73AA, + 0x73B3, 0x73BB, 0x73C4, 0x73CC, 0x73D5, 0x73DD, + 0x73E6, 0x73EF, 0x73F7, 0x7400, 0x7408, 0x7411, + 0x7419, 0x7422, 0x742A, 0x7433, 0x743C, 0x7444, + 0x744D, 0x7455, 0x745E, 0x7466, 0x746F, 0x7478, + 0x7480, 0x7489, 0x7491, 0x749A, 0x74A2, 0x74AB, + 0x74B4, 0x74BC, 0x6A7F, 0x6A86, 0x6A8E, 0x6A96, + 0x6A9E, 0x6AA6, 0x6AAE, 0x6AB6, 0x6ABD, 0x6AC5, + 0x6ACD, 0x6AD5, 0x6ADD, 0x6AE5, 0x6AED, 0x6AF5, + 0x6AFC, 0x6B04, 0x6B0C, 0x6B14, 0x6B1C, 0x6B24, + 0x6B2C, 0x6B34, 0x6B3C, 0x6B43, 0x6B4B, 0x6B53, + 0x6B5B, 0x6B63, 0x6B6B, 0x6B73, 0x6B7B, 0x6B83, + 0x6B8B, 0x6B93, 0x6B9B, 0x6BA2, 0x6BAA, 0x6BB2, + 0x6BBA, 0x6BC2, 0x6BCA, 0x6BD2, 0x6BDA, 0x6BE2, + 0x6BEA, 0x6BF2, 0x6BFA, 0x6C02, 0x6C0A, 0x6C12, + 0x6C1A, 0x6C22, 0x6C2A, 0x6C32, 0x6C3A, 0x6C42, + 0x6C4A, 0x6C52, 0x6C59, 0x6C61, 0x6C69, 0x6C71, + 0x6C79, 0x6C81, 0x6C89, 0x6C91, 0x6C99, 0x6CA1, + 0x6CA9, 0x6CB1, 0x6CB9, 0x6CC1, 0x6CC9, 0x6CD2, + 0x6CDA, 0x6CE2, 0x6CEA, 0x6CF2, 0x6CFA, 0x6D02, + 0x6D0A, 0x6D12, 0x6D1A, 0x6D22, 0x6D2A, 0x6D32, + 0x6D3A, 0x6D42, 0x6D4A, 0x6D52, 0x6D5A, 0x6D62, + 0x6D6A, 0x6D72, 0x6D7A, 0x6D82, 0x6D8B, 0x6D93, + 0x6D9B, 0x6DA3, 0x6DAB, 0x6DB3, 0x6DBB, 0x6DC3, + 0x6DCB, 0x6DD3, 0x6DDB, 0x6DE3, 0x6DEC, 0x6DF4, + 0x6DFC, 0x6E04, 0x6E0C, 0x6E14, 0x6E1C, 0x6E24, + 0x6E2C, 0x6E35, 0x6E3D, 0x6E45, 0x6E4D, 0x6E55, + 0x6E5D, 0x6E65, 0x6E6D, 0x6E76, 0x6E7E, 0x6E86, + 0x6E8E, 0x6E96, 0x6E9E, 0x6EA6, 0x6EAF, 0x6EB7, + 0x6EBF, 0x6EC7, 0x6ECF, 0x6ED7, 0x6EE0, 0x6EE8, + 0x6EF0, 0x6EF8, 0x6F00, 0x6F08, 0x6F11, 0x6F19, + 0x6F21, 0x6F29, 0x6F31, 0x6F3A, 0x6F42, 0x6F4A, + 0x6F52, 0x6F5A, 0x6F63, 0x6F6B, 0x6F73, 0x6F7B, + 0x65B4, 0x65BB, 0x65C3, 0x65CA, 0x65D2, 0x65D9, + 0x65E1, 0x65E8, 0x65F0, 0x65F7, 0x65FF, 0x6606, + 0x660E, 0x6615, 0x661D, 0x6624, 0x662C, 0x6633, + 0x663B, 0x6642, 0x664A, 0x6651, 0x6659, 0x6660, + 0x6668, 0x6670, 0x6677, 0x667F, 0x6686, 0x668E, + 0x6695, 0x669D, 0x66A4, 0x66AC, 0x66B4, 0x66BB, + 0x66C3, 0x66CA, 0x66D2, 0x66D9, 0x66E1, 0x66E9, + 0x66F0, 0x66F8, 0x66FF, 0x6707, 0x670F, 0x6716, + 0x671E, 0x6725, 0x672D, 0x6735, 0x673C, 0x6744, + 0x674B, 0x6753, 0x675B, 0x6762, 0x676A, 0x6771, + 0x6779, 0x6781, 0x6788, 0x6790, 0x6798, 0x679F, + 0x67A7, 0x67AE, 0x67B6, 0x67BE, 0x67C5, 0x67CD, + 0x67D5, 0x67DC, 0x67E4, 0x67EC, 0x67F3, 0x67FB, + 0x6803, 0x680A, 0x6812, 0x681A, 0x6821, 0x6829, + 0x6831, 0x6838, 0x6840, 0x6848, 0x684F, 0x6857, + 0x685F, 0x6866, 0x686E, 0x6876, 0x687E, 0x6885, + 0x688D, 0x6895, 0x689C, 0x68A4, 0x68AC, 0x68B4, + 0x68BB, 0x68C3, 0x68CB, 0x68D2, 0x68DA, 0x68E2, + 0x68EA, 0x68F1, 0x68F9, 0x6901, 0x6909, 0x6910, + 0x6918, 0x6920, 0x6927, 0x692F, 0x6937, 0x693F, + 0x6947, 0x694E, 0x6956, 0x695E, 0x6966, 0x696D, + 0x6975, 0x697D, 0x6985, 0x698C, 0x6994, 0x699C, + 0x69A4, 0x69AC, 0x69B3, 0x69BB, 0x69C3, 0x69CB, + 0x69D2, 0x69DA, 0x69E2, 0x69EA, 0x69F2, 0x69FA, + 0x6A01, 0x6A09, 0x6A11, 0x6A19, 0x6A21, 0x6A28, + 0x6A30, 0x6A38, 0x6A40, 0x6A48, 0x6A50, 0x6A57, + 0x6A5F, 0x6A67, 0x6A6F, 0x6A77, 0x6120, 0x6127, + 0x612E, 0x6135, 0x613C, 0x6144, 0x614B, 0x6152, + 0x6159, 0x6160, 0x6167, 0x616F, 0x6176, 0x617D, + 0x6184, 0x618B, 0x6192, 0x619A, 0x61A1, 0x61A8, + 0x61AF, 0x61B6, 0x61BE, 0x61C5, 0x61CC, 0x61D3, + 0x61DA, 0x61E2, 0x61E9, 0x61F0, 0x61F7, 0x61FF, + 0x6206, 0x620D, 0x6214, 0x621B, 0x6223, 0x622A, + 0x6231, 0x6238, 0x6240, 0x6247, 0x624E, 0x6255, + 0x625D, 0x6264, 0x626B, 0x6272, 0x627A, 0x6281, + 0x6288, 0x628F, 0x6297, 0x629E, 0x62A5, 0x62AC, + 0x62B4, 0x62BB, 0x62C2, 0x62CA, 0x62D1, 0x62D8, + 0x62DF, 0x62E7, 0x62EE, 0x62F5, 0x62FD, 0x6304, + 0x630B, 0x6312, 0x631A, 0x6321, 0x6328, 0x6330, + 0x6337, 0x633E, 0x6346, 0x634D, 0x6354, 0x635C, + 0x6363, 0x636A, 0x6372, 0x6379, 0x6380, 0x6388, + 0x638F, 0x6396, 0x639E, 0x63A5, 0x63AC, 0x63B4, + 0x63BB, 0x63C2, 0x63CA, 0x63D1, 0x63D8, 0x63E0, + 0x63E7, 0x63EE, 0x63F6, 0x63FD, 0x6405, 0x640C, + 0x6413, 0x641B, 0x6422, 0x6429, 0x6431, 0x6438, + 0x6440, 0x6447, 0x644E, 0x6456, 0x645D, 0x6464, + 0x646C, 0x6473, 0x647B, 0x6482, 0x648A, 0x6491, + 0x6498, 0x64A0, 0x64A7, 0x64AF, 0x64B6, 0x64BD, + 0x64C5, 0x64CC, 0x64D4, 0x64DB, 0x64E3, 0x64EA, + 0x64F1, 0x64F9, 0x6500, 0x6508, 0x650F, 0x6517, + 0x651E, 0x6526, 0x652D, 0x6534, 0x653C, 0x6543, + 0x654B, 0x6552, 0x655A, 0x6561, 0x6569, 0x6570, + 0x6578, 0x657F, 0x6587, 0x658E, 0x6596, 0x659D, + 0x65A5, 0x65AC, 0x5CC1, 0x5CC7, 0x5CCE, 0x5CD5, + 0x5CDC, 0x5CE3, 0x5CEA, 0x5CF1, 0x5CF7, 0x5CFE, + 0x5D05, 0x5D0C, 0x5D13, 0x5D1A, 0x5D21, 0x5D27, + 0x5D2E, 0x5D35, 0x5D3C, 0x5D43, 0x5D4A, 0x5D51, + 0x5D57, 0x5D5E, 0x5D65, 0x5D6C, 0x5D73, 0x5D7A, + 0x5D81, 0x5D88, 0x5D8F, 0x5D95, 0x5D9C, 0x5DA3, + 0x5DAA, 0x5DB1, 0x5DB8, 0x5DBF, 0x5DC6, 0x5DCD, + 0x5DD4, 0x5DDB, 0x5DE1, 0x5DE8, 0x5DEF, 0x5DF6, + 0x5DFD, 0x5E04, 0x5E0B, 0x5E12, 0x5E19, 0x5E20, + 0x5E27, 0x5E2E, 0x5E35, 0x5E3C, 0x5E42, 0x5E49, + 0x5E50, 0x5E57, 0x5E5E, 0x5E65, 0x5E6C, 0x5E73, + 0x5E7A, 0x5E81, 0x5E88, 0x5E8F, 0x5E96, 0x5E9D, + 0x5EA4, 0x5EAB, 0x5EB2, 0x5EB9, 0x5EC0, 0x5EC7, + 0x5ECE, 0x5ED5, 0x5EDC, 0x5EE3, 0x5EEA, 0x5EF1, + 0x5EF8, 0x5EFF, 0x5F06, 0x5F0D, 0x5F14, 0x5F1B, + 0x5F22, 0x5F29, 0x5F30, 0x5F37, 0x5F3E, 0x5F45, + 0x5F4C, 0x5F53, 0x5F5A, 0x5F61, 0x5F68, 0x5F6F, + 0x5F76, 0x5F7D, 0x5F84, 0x5F8B, 0x5F92, 0x5F99, + 0x5FA0, 0x5FA7, 0x5FAE, 0x5FB5, 0x5FBC, 0x5FC4, + 0x5FCB, 0x5FD2, 0x5FD9, 0x5FE0, 0x5FE7, 0x5FEE, + 0x5FF5, 0x5FFC, 0x6003, 0x600A, 0x6011, 0x6018, + 0x601F, 0x6027, 0x602E, 0x6035, 0x603C, 0x6043, + 0x604A, 0x6051, 0x6058, 0x605F, 0x6066, 0x606D, + 0x6075, 0x607C, 0x6083, 0x608A, 0x6091, 0x6098, + 0x609F, 0x60A6, 0x60AD, 0x60B5, 0x60BC, 0x60C3, + 0x60CA, 0x60D1, 0x60D8, 0x60DF, 0x60E7, 0x60EE, + 0x60F5, 0x60FC, 0x6103, 0x610A, 0x6111, 0x6119, + 0x5894, 0x589A, 0x58A1, 0x58A8, 0x58AE, 0x58B5, + 0x58BB, 0x58C2, 0x58C8, 0x58CF, 0x58D5, 0x58DC, + 0x58E2, 0x58E9, 0x58F0, 0x58F6, 0x58FD, 0x5903, + 0x590A, 0x5910, 0x5917, 0x591D, 0x5924, 0x592B, + 0x5931, 0x5938, 0x593E, 0x5945, 0x594B, 0x5952, + 0x5959, 0x595F, 0x5966, 0x596C, 0x5973, 0x597A, + 0x5980, 0x5987, 0x598D, 0x5994, 0x599B, 0x59A1, + 0x59A8, 0x59AE, 0x59B5, 0x59BC, 0x59C2, 0x59C9, + 0x59CF, 0x59D6, 0x59DD, 0x59E3, 0x59EA, 0x59F1, + 0x59F7, 0x59FE, 0x5A04, 0x5A0B, 0x5A12, 0x5A18, + 0x5A1F, 0x5A26, 0x5A2C, 0x5A33, 0x5A3A, 0x5A40, + 0x5A47, 0x5A4D, 0x5A54, 0x5A5B, 0x5A61, 0x5A68, + 0x5A6F, 0x5A75, 0x5A7C, 0x5A83, 0x5A89, 0x5A90, + 0x5A97, 0x5A9D, 0x5AA4, 0x5AAB, 0x5AB2, 0x5AB8, + 0x5ABF, 0x5AC6, 0x5ACC, 0x5AD3, 0x5ADA, 0x5AE0, + 0x5AE7, 0x5AEE, 0x5AF4, 0x5AFB, 0x5B02, 0x5B09, + 0x5B0F, 0x5B16, 0x5B1D, 0x5B23, 0x5B2A, 0x5B31, + 0x5B38, 0x5B3E, 0x5B45, 0x5B4C, 0x5B52, 0x5B59, + 0x5B60, 0x5B67, 0x5B6D, 0x5B74, 0x5B7B, 0x5B82, + 0x5B88, 0x5B8F, 0x5B96, 0x5B9D, 0x5BA3, 0x5BAA, + 0x5BB1, 0x5BB8, 0x5BBE, 0x5BC5, 0x5BCC, 0x5BD3, + 0x5BD9, 0x5BE0, 0x5BE7, 0x5BEE, 0x5BF5, 0x5BFB, + 0x5C02, 0x5C09, 0x5C10, 0x5C16, 0x5C1D, 0x5C24, + 0x5C2B, 0x5C32, 0x5C38, 0x5C3F, 0x5C46, 0x5C4D, + 0x5C54, 0x5C5A, 0x5C61, 0x5C68, 0x5C6F, 0x5C76, + 0x5C7C, 0x5C83, 0x5C8A, 0x5C91, 0x5C98, 0x5C9F, + 0x5CA5, 0x5CAC, 0x5CB3, 0x5CBA, 0x5497, 0x549E, + 0x54A4, 0x54AA, 0x54B0, 0x54B7, 0x54BD, 0x54C3, + 0x54C9, 0x54D0, 0x54D6, 0x54DC, 0x54E2, 0x54E9, + 0x54EF, 0x54F5, 0x54FB, 0x5502, 0x5508, 0x550E, + 0x5514, 0x551B, 0x5521, 0x5527, 0x552D, 0x5534, + 0x553A, 0x5540, 0x5547, 0x554D, 0x5553, 0x5559, + 0x5560, 0x5566, 0x556C, 0x5573, 0x5579, 0x557F, + 0x5585, 0x558C, 0x5592, 0x5598, 0x559F, 0x55A5, + 0x55AB, 0x55B2, 0x55B8, 0x55BE, 0x55C5, 0x55CB, + 0x55D1, 0x55D8, 0x55DE, 0x55E4, 0x55EB, 0x55F1, + 0x55F7, 0x55FE, 0x5604, 0x560A, 0x5611, 0x5617, + 0x561D, 0x5624, 0x562A, 0x5630, 0x5637, 0x563D, + 0x5643, 0x564A, 0x5650, 0x5656, 0x565D, 0x5663, + 0x566A, 0x5670, 0x5676, 0x567D, 0x5683, 0x5689, + 0x5690, 0x5696, 0x569D, 0x56A3, 0x56A9, 0x56B0, + 0x56B6, 0x56BC, 0x56C3, 0x56C9, 0x56D0, 0x56D6, + 0x56DC, 0x56E3, 0x56E9, 0x56F0, 0x56F6, 0x56FC, + 0x5703, 0x5709, 0x5710, 0x5716, 0x571D, 0x5723, + 0x5729, 0x5730, 0x5736, 0x573D, 0x5743, 0x574A, + 0x5750, 0x5756, 0x575D, 0x5763, 0x576A, 0x5770, + 0x5777, 0x577D, 0x5783, 0x578A, 0x5790, 0x5797, + 0x579D, 0x57A4, 0x57AA, 0x57B1, 0x57B7, 0x57BE, + 0x57C4, 0x57CB, 0x57D1, 0x57D7, 0x57DE, 0x57E4, + 0x57EB, 0x57F1, 0x57F8, 0x57FE, 0x5805, 0x580B, + 0x5812, 0x5818, 0x581F, 0x5825, 0x582C, 0x5832, + 0x5839, 0x583F, 0x5846, 0x584C, 0x5853, 0x5859, + 0x5860, 0x5866, 0x586D, 0x5873, 0x587A, 0x5880, + 0x5887, 0x588D, 0x50C9, 0x50CF, 0x50D5, 0x50DB, + 0x50E0, 0x50E6, 0x50EC, 0x50F2, 0x50F8, 0x50FE, + 0x5104, 0x510A, 0x5110, 0x5116, 0x511C, 0x5122, + 0x5128, 0x512E, 0x5134, 0x513A, 0x5140, 0x5146, + 0x514C, 0x5152, 0x5158, 0x515E, 0x5164, 0x516A, + 0x5170, 0x5176, 0x517C, 0x5182, 0x5188, 0x518E, + 0x5194, 0x519A, 0x51A0, 0x51A6, 0x51AC, 0x51B2, + 0x51B8, 0x51BE, 0x51C4, 0x51CA, 0x51D0, 0x51D6, + 0x51DC, 0x51E2, 0x51E8, 0x51EE, 0x51F4, 0x51FA, + 0x5201, 0x5207, 0x520D, 0x5213, 0x5219, 0x521F, + 0x5225, 0x522B, 0x5231, 0x5237, 0x523D, 0x5243, + 0x5249, 0x524F, 0x5255, 0x525B, 0x5261, 0x5267, + 0x526E, 0x5274, 0x527A, 0x5280, 0x5286, 0x528C, + 0x5292, 0x5298, 0x529E, 0x52A4, 0x52AA, 0x52B0, + 0x52B7, 0x52BD, 0x52C3, 0x52C9, 0x52CF, 0x52D5, + 0x52DB, 0x52E1, 0x52E7, 0x52ED, 0x52F4, 0x52FA, + 0x5300, 0x5306, 0x530C, 0x5312, 0x5318, 0x531E, + 0x5325, 0x532B, 0x5331, 0x5337, 0x533D, 0x5343, + 0x5349, 0x534F, 0x5356, 0x535C, 0x5362, 0x5368, + 0x536E, 0x5374, 0x537B, 0x5381, 0x5387, 0x538D, + 0x5393, 0x5399, 0x539F, 0x53A6, 0x53AC, 0x53B2, + 0x53B8, 0x53BE, 0x53C4, 0x53CB, 0x53D1, 0x53D7, + 0x53DD, 0x53E3, 0x53EA, 0x53F0, 0x53F6, 0x53FC, + 0x5402, 0x5408, 0x540F, 0x5415, 0x541B, 0x5421, + 0x5427, 0x542E, 0x5434, 0x543A, 0x5440, 0x5446, + 0x544D, 0x5453, 0x5459, 0x545F, 0x5466, 0x546C, + 0x5472, 0x5478, 0x547E, 0x5485, 0x548B, 0x5491 +}; diff --git a/src/dolphin/ax/AXOut.c b/src/dolphin/ax/AXOut.c new file mode 100644 index 0000000000..e0649ba3b8 --- /dev/null +++ b/src/dolphin/ax/AXOut.c @@ -0,0 +1,238 @@ +#include +#include +#include + +#include "__ax.h" + +static s16 __AXOutBuffer[3][320]; +static s32 __AXOutSBuffer[160]; +static u16 __AXDramImage[8192]; +static DSPTaskInfo __AXDSPTask; +AXPROFILE __AXLocalProfile; + +volatile static u32 __AXOutFrame; +volatile static u32 __AXAiDmaFrame; +volatile static u32 __AXOutDspReady; +volatile static OSTime __AXOsTime; +static void (*__AXUserFrameCallback)(); +volatile static int __AXDSPInitFlag; +static int __AXDSPDoneFlag; + +static volatile u32 __AXDebugSteppingMode; +static OSThreadQueue __AXOutThreadQueue; +static u32 __AXOutputBufferMode; + +// prototypes +static void __AXDSPInitCallback(void* task); +static void __AXDSPResumeCallback(void* task); +static void __AXDSPDoneCallback(void* task); + +void __AXOutNewFrame(u32 lessDspCycles) { + u32 cl; + AXPROFILE* profile; + u8* src; + u8* dest; + u32 i; + + __AXLocalProfile.axFrameStart = OSGetTime(); + __AXSyncPBs(lessDspCycles); + __AXPrintStudio(); + cl = __AXGetCommandListAddress(); + + DSPSendMailToDSP(0xBABE0180); + do {} while (DSPCheckMailToDSP() != 0); + + DSPSendMailToDSP(cl); + do {} while (DSPCheckMailToDSP() != 0); + + __AXServiceCallbackStack(); + __AXLocalProfile.auxProcessingStart = OSGetTime(); + __AXProcessAux(); + __AXLocalProfile.auxProcessingEnd = OSGetTime(); + __AXLocalProfile.userCallbackStart = OSGetTime(); + + if (__AXUserFrameCallback) { + __AXUserFrameCallback(); + } + + __AXLocalProfile.userCallbackEnd = OSGetTime(); + __AXNextFrame(__AXOutSBuffer, &__AXOutBuffer[__AXOutFrame][0]); + __AXOutFrame += 1; + + if (__AXOutputBufferMode == 1) { + __AXOutFrame %= 3; + } else { + __AXOutFrame &= 1; + AIInitDMA((u32)&__AXOutBuffer[__AXOutFrame][0], 0x280); + } + + __AXLocalProfile.axFrameEnd = OSGetTime(); + __AXLocalProfile.axNumVoices = __AXGetNumVoices(); + profile = (void*)__AXGetCurrentProfile(); + + if (profile) { + i = 56; + dest = (u8*)profile; + src = (u8*)&__AXLocalProfile; + + while (i != 0) { + *dest = *src; + dest++; + src++; + i--; + } + } +} + +void __AXOutAiCallback(void) { + if (__AXOutDspReady == 0) { + __AXOsTime = OSGetTime(); + } + + if (__AXOutDspReady == 1) { + __AXOutDspReady = 0; + __AXOutNewFrame(0); + } else { + __AXOutDspReady = 2; + DSPAssertTask(&__AXDSPTask); + } + + if (__AXOutputBufferMode == 1) { + AIInitDMA((u32)__AXOutBuffer[__AXAiDmaFrame], 0x280); + __AXAiDmaFrame++; + __AXAiDmaFrame %= 3; + } +} + +static void __AXDSPInitCallback(void* task) { + __AXDSPInitFlag = 1; +} + +void AXSetStepMode(u32 i) { + __AXDebugSteppingMode = i; +} + +static void __AXDSPResumeCallback(void* task) { +#if DEBUG + if (__AXDebugSteppingMode != 0) { + __AXOutDspReady = 1; + return; + } +#endif + + if (__AXOutDspReady == 2) { + __AXOutDspReady = 0; + __AXOutNewFrame((u32)(OSGetTime() - __AXOsTime) / 4); + return; + } + __AXOutDspReady = 1; +} + +static void __AXDSPDoneCallback(void* task) { + __AXDSPDoneFlag = 1; + OSWakeupThread(&__AXOutThreadQueue); +} + +#define BUFFER_MEMSET(buffer, size) \ + { \ + u32* p = (u32*)&buffer; \ + int i; \ + for (i = 0; i < size; i++) { \ + *p = 0; \ + p++; \ + } \ + } + +void __AXOutInitDSP(void) { + __AXDSPTask.iram_mmem_addr = axDspSlave; + __AXDSPTask.iram_length = axDspSlaveLength; + __AXDSPTask.iram_addr = 0; + __AXDSPTask.dram_mmem_addr = __AXDramImage; + __AXDSPTask.dram_length = 0x2000; + __AXDSPTask.dram_addr = 0; + __AXDSPTask.dsp_init_vector = 0x10; + __AXDSPTask.dsp_resume_vector = 0x30; + __AXDSPTask.init_cb = __AXDSPInitCallback; + __AXDSPTask.res_cb = __AXDSPResumeCallback; + __AXDSPTask.done_cb = __AXDSPDoneCallback; + __AXDSPTask.req_cb = NULL; + __AXDSPTask.priority = 0; + __AXDSPInitFlag = 0; + __AXDSPDoneFlag = 0; + + OSInitThreadQueue(&__AXOutThreadQueue); + if (DSPCheckInit() == 0) { + DSPInit(); + } + + DSPAddTask(&__AXDSPTask); + do {} while (__AXDSPInitFlag == 0); +} + +void __AXOutInit(u32 outputBufferMode) { +#ifdef DEBUG + OSReport("Initializing AXOut code module\n"); +#endif + ASSERTLINE(404, ((u32)&__AXOutBuffer[0][0] & 0x1F) == 0); + ASSERTLINE(405, ((u32)&__AXOutBuffer[1][0] & 0x1F) == 0); + ASSERTLINE(406, ((u32)&__AXOutBuffer[2][0] & 0x1F) == 0); + ASSERTLINE(407, ((u32)&__AXOutSBuffer[0] & 0x1F) == 0); + + __AXOutputBufferMode = outputBufferMode; + __AXOutFrame = 0; + __AXAiDmaFrame = 0; + __AXDebugSteppingMode = 0; + + BUFFER_MEMSET(__AXOutBuffer, 0x1E0); + DCFlushRange(__AXOutBuffer, sizeof(__AXOutBuffer)); + + BUFFER_MEMSET(__AXOutSBuffer, 0xA0); + DCFlushRange(__AXOutSBuffer, sizeof(__AXOutSBuffer)); + + __AXOutInitDSP(); + AIRegisterDMACallback(__AXOutAiCallback); + + if (__AXOutputBufferMode == 1) { + __AXNextFrame(__AXOutSBuffer, &__AXOutBuffer[2][0]); + } else { + __AXNextFrame(__AXOutSBuffer, &__AXOutBuffer[1][0]); + } + + __AXOutDspReady = 1; + __AXUserFrameCallback = NULL; + + if (__AXOutputBufferMode == 1) { + AIInitDMA((u32)&__AXOutBuffer[__AXAiDmaFrame][0], sizeof(__AXOutBuffer[0])); + __AXAiDmaFrame++; + __AXAiDmaFrame &= 1; + } else { + AIInitDMA((u32)&__AXOutBuffer[__AXOutFrame][0], sizeof(__AXOutBuffer[0])); + } + + AIStartDMA(); +} + +void __AXOutQuit(void) { + BOOL old; +#ifdef DEBUG + OSReport("Shutting down AXOut code module\n"); +#endif + old = OSDisableInterrupts(); + __AXUserFrameCallback = NULL; + DSPCancelTask(&__AXDSPTask); + OSSleepThread(&__AXOutThreadQueue); + AIStopDMA(); + OSRestoreInterrupts(old); +} + +AXCallback AXRegisterCallback(AXCallback callback) { + BOOL enabled; + AXCallback oldCB; + + oldCB = __AXUserFrameCallback; + enabled = OSDisableInterrupts(); + __AXUserFrameCallback = callback; + + OSRestoreInterrupts(enabled); + return oldCB; +} diff --git a/src/dolphin/ax/AXProf.c b/src/dolphin/ax/AXProf.c new file mode 100644 index 0000000000..316cadf5bb --- /dev/null +++ b/src/dolphin/ax/AXProf.c @@ -0,0 +1,47 @@ +#include +#include + +#include "__ax.h" + +static AXPROFILE* __AXProfile; +static u32 __AXMaxProfiles; +static u32 __AXCurrentProfile; +static u32 __AXProfileInitialized; + +AXPROFILE* __AXGetCurrentProfile(void) { + AXPROFILE* profile; + + if (__AXProfileInitialized != 0) { + profile = &__AXProfile[__AXCurrentProfile]; + __AXCurrentProfile += 1; + __AXCurrentProfile %= __AXMaxProfiles; + return profile; + } + + return 0; +} + +void AXInitProfile(AXPROFILE* profile, u32 maxProfiles) { + ASSERTLINE(60, profile); + ASSERTLINE(61, maxProfiles); + + __AXProfile = profile; + __AXMaxProfiles = maxProfiles; + __AXCurrentProfile = 0; + __AXProfileInitialized = 1; +} + +u32 AXGetProfile(void) { + BOOL old; + u32 n; + + old = OSDisableInterrupts(); + n = __AXCurrentProfile; + if (n != 0) { + n -= 1; + } + + __AXCurrentProfile = 0; + OSRestoreInterrupts(old); + return n; +} diff --git a/src/dolphin/ax/AXSPB.c b/src/dolphin/ax/AXSPB.c new file mode 100644 index 0000000000..3ff765d1d5 --- /dev/null +++ b/src/dolphin/ax/AXSPB.c @@ -0,0 +1,91 @@ +#include +#include + +#include "__ax.h" + +static AXSPB __AXStudio ATTRIBUTE_ALIGN(32); + +static s32 __AXSpbAL; +static s32 __AXSpbAR; +static s32 __AXSpbAS; +static s32 __AXSpbAAL; +static s32 __AXSpbAAR; +static s32 __AXSpbAAS; +static s32 __AXSpbABL; +static s32 __AXSpbABR; +static s32 __AXSpbABS; + +u32 __AXGetStudio(void) { + return (u32)&__AXStudio; +} + +void __AXDepopFade(s32* hostSum, s32* dspVolume, s16* dspDelta) { + int frames; + s32 delta; + + frames = *hostSum / 160; + + if (frames) { + delta = *hostSum / 160; + if (delta > 0x14) { + delta = 0x14; + } + if (delta < -0x14) { + delta = -0x14; + } + *dspVolume = *hostSum; + *hostSum -= delta* 0xA0; + *dspDelta = delta * -1; + return; + } + + *hostSum = 0; + *dspVolume = 0; + *dspDelta = 0; +} + +void __AXPrintStudio(void) { + __AXDepopFade(&__AXSpbAL, (void*)&__AXStudio.dpopLHi, &__AXStudio.dpopLDelta); + __AXDepopFade(&__AXSpbAR, (void*)&__AXStudio.dpopRHi, &__AXStudio.dpopRDelta); + __AXDepopFade(&__AXSpbAS, (void*)&__AXStudio.dpopSHi, &__AXStudio.dpopSDelta); + __AXDepopFade(&__AXSpbAAL, (void*)&__AXStudio.dpopALHi, &__AXStudio.dpopALDelta); + __AXDepopFade(&__AXSpbAAR, (void*)&__AXStudio.dpopARHi, &__AXStudio.dpopARDelta); + __AXDepopFade(&__AXSpbAAS, (void*)&__AXStudio.dpopASHi, &__AXStudio.dpopASDelta); + __AXDepopFade(&__AXSpbABL, (void*)&__AXStudio.dpopBLHi, &__AXStudio.dpopBLDelta); + __AXDepopFade(&__AXSpbABR, (void*)&__AXStudio.dpopBRHi, &__AXStudio.dpopBRDelta); + __AXDepopFade(&__AXSpbABS, (void*)&__AXStudio.dpopBSHi, &__AXStudio.dpopBSDelta); + DCFlushRange(&__AXStudio, sizeof(__AXStudio)); +} + +void __AXSPBInit(void) { +#ifdef DEBUG + OSReport("Initializing AXSPB code module\n"); +#endif + __AXSpbAL = + __AXSpbAR = + __AXSpbAS = + __AXSpbAAL = + __AXSpbAAR = + __AXSpbAAS = + __AXSpbABL = + __AXSpbABR = + __AXSpbABS = 0; +} + +void __AXSPBQuit(void) { +#ifdef DEBUG + OSReport("Shutting down AXSPB code module\n"); +#endif +} + +void __AXDepopVoice(AXPB* p) { + __AXSpbAL += p->dpop.aL; + __AXSpbAAL += p->dpop.aAuxAL; + __AXSpbABL += p->dpop.aAuxBL; + __AXSpbAR += p->dpop.aR; + __AXSpbAAR += p->dpop.aAuxAR; + __AXSpbABR += p->dpop.aAuxBR; + __AXSpbAS += p->dpop.aS; + __AXSpbAAS += p->dpop.aAuxAS; + __AXSpbABS += p->dpop.aAuxBS; +} diff --git a/src/dolphin/ax/AXVPB.c b/src/dolphin/ax/AXVPB.c new file mode 100644 index 0000000000..eba17fd686 --- /dev/null +++ b/src/dolphin/ax/AXVPB.c @@ -0,0 +1,966 @@ +#include +#include +#include "fake_tgmath.h" + +#include "__ax.h" + +static u32 __AXSrcCycles[5] = { + 0x00000DF8, + 0x00000F78, + 0x000014B8, + 0x000019F8, + 0x000019F8 +}; + +static u32 __AXMainMixCycles[16] = { + 0x00000000, 0x000002F8, 0x000002F8, + 0x000005BE, 0x000002F8, 0x000005F0, + 0x000005F0, 0x000008B6, 0x00000000, + 0x000004F1, 0x000004F1, 0x000009A6, + 0x000004F1, 0x000009E2, 0x000009E2, + 0x00000E97 +}; + +static u32 __AXAuxMixCycles[32] = { + 0x00000000, 0x000002F8, 0x000002F8, + 0x000005BE, 0x00000000, 0x000004F1, + 0x000004F1, 0x000009A6, 0x000002F8, + 0x000005F0, 0x000005F0, 0x000008B6, + 0x000002F8, 0x000007E9, 0x000007E9, + 0x00000C9E, 0x00000000, 0x000002F8, + 0x000002F8, 0x000005BE, 0x00000000, + 0x000004F1, 0x000004F1, 0x000009A6, + 0x000004F1, 0x000007E9, 0x000007E9, + 0x00000AAF, 0x000004F1, 0x000009E2, + 0x000009E2, 0x00000E97 +}; + +static AXPB __AXPB[AX_MAX_VOICES] ATTRIBUTE_ALIGN(32); +static AXPBITDBUFFER __AXITD[AX_MAX_VOICES] ATTRIBUTE_ALIGN(32); +static AXPBU __AXUpdates[AX_MAX_VOICES] ATTRIBUTE_ALIGN(32); +static AXVPB __AXVPB[AX_MAX_VOICES]; + +static u32 __AXMaxDspCycles; +static u32 __AXRecDspCycles; +static u32 __AXNumVoices; + +u32 __AXGetNumVoices(void) { + return __AXNumVoices; +} + +void __AXServiceVPB(AXVPB* pvpb) { + AXPB* ppbDsp; + AXPB* ppbUser; + u32 sync; + + ASSERTLINE(238, (pvpb->index >= 0) && (pvpb->index < AX_MAX_VOICES)); + + __AXNumVoices += 1; + ppbDsp = &__AXPB[pvpb->index]; + ppbUser = &pvpb->pb; + sync = pvpb->sync; + if (sync == 0) { + ppbUser->state = ppbDsp->state; + ppbUser->ve.currentVolume = ppbDsp->ve.currentVolume; + ppbUser->addr.currentAddressHi = ppbDsp->addr.currentAddressHi; + ppbUser->addr.currentAddressLo = ppbDsp->addr.currentAddressLo; + return; + } + if (sync & AX_SYNC_FLAG_COPYALL) { + // copy the whole PB struct. (size: 0xF4) + u32* src; + u32* dst; + src = (void*)ppbUser; + dst = (void*)ppbDsp; + + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); + + if (pvpb->updateCounter != 0) { + u32 count; + src = (void*)&__AXUpdates[pvpb->index]; + dst = (void*)pvpb->updateData; + for (count = pvpb->updateCounter; count; count--) { + *(dst) = *(src); dst+=1; src+=1; + } + } + return; + } + + if (sync & AX_SYNC_FLAG_COPYSELECT) { + ppbDsp->srcSelect = ppbUser->srcSelect; + ppbDsp->coefSelect = ppbUser->coefSelect; + } + + if (sync & AX_SYNC_FLAG_COPYMXRCTRL) { + ppbDsp->mixerCtrl = ppbUser->mixerCtrl; + } + + if (sync & AX_SYNC_FLAG_COPYSTATE) { + ppbDsp->state = ppbUser->state; + } else { + ppbUser->state = ppbDsp->state; + } + + if (sync & AX_SYNC_FLAG_COPYTYPE) { + ppbDsp->type = ppbUser->type; + } + + if (sync & AX_SYNC_FLAG_COPYAXPBMIX) { + // copy AXPBMIX. + u16* src; + u16* dst; + src = (void*)&ppbUser->mix; + dst = (void*)&ppbDsp->mix; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); + } + + if (sync & AX_SYNC_FLAG_COPYTSHIFT) { + ppbDsp->itd.targetShiftL = ppbUser->itd.targetShiftL; + ppbDsp->itd.targetShiftR = ppbUser->itd.targetShiftR; + } else if (sync & AX_SYNC_FLAG_COPYITD) { + // copy ITD struct. + u16* src; + u16* dst; + u32* dst_; + src = (void*)&ppbUser->itd; + dst = (void*)&ppbDsp->itd; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); src+=1; + + dst; // fixes reg alloc + dst_ = pvpb->itdBuffer; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; dst_+=1; + *(dst_) = 0; + } + + if (sync & AX_SYNC_FLAG_COPYUPDATE) { + // copy UPDATE struct. + u16* src; + u16* dst; + dst = (void*)&ppbDsp->update; + src = (void*)&ppbUser->update; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); + + if (pvpb->updateCounter) { + u32* src_; + u32* dst_; + u32 count; + + dst_ = (void*)&__AXUpdates[pvpb->index]; + src_ = (void*)&pvpb->updateData; + + for (count = pvpb->updateCounter; count; count--) { + *(dst_) = *(src_); dst_+=1; src_+=1; + } + } + } + + if (sync & AX_SYNC_FLAG_COPYDPOP) { + // copy DPOP struct. + u16* src; + u16* dst; + dst = (void*)&ppbDsp->dpop; + src = (void*)&ppbUser->dpop; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); + } + + if (sync & AX_SYNC_FLAG_SWAPVOL) { + ppbUser->ve.currentVolume = ppbDsp->ve.currentVolume; + ppbDsp->ve.currentDelta = ppbUser->ve.currentDelta; + } else if (sync & AX_SYNC_FLAG_COPYVOL) { + ppbDsp->ve.currentVolume = ppbUser->ve.currentVolume; + ppbDsp->ve.currentDelta = ppbUser->ve.currentDelta; + } + + if (sync & AX_SYNC_FLAG_COPYFIR) { + // copy FIR struct. + u16* src; + u16* dst; + dst = (void*)&ppbDsp->fir; + src = (void*)&ppbUser->fir; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); + } + + if (sync & (AX_SYNC_FLAG_COPYLOOP | AX_SYNC_FLAG_COPYLOOPADDR | AX_SYNC_FLAG_COPYENDADDR | AX_SYNC_FLAG_COPYCURADDR)) { + if (sync & AX_SYNC_FLAG_COPYLOOP) { + ppbDsp->addr.loopFlag = ppbUser->addr.loopFlag; + } + if (sync & AX_SYNC_FLAG_COPYLOOPADDR) { + *(u32*)&ppbDsp->addr.loopAddressHi = *(u32*)&ppbUser->addr.loopAddressHi; + } + if (sync & AX_SYNC_FLAG_COPYENDADDR) { + *(u32*)&ppbDsp->addr.endAddressHi = *(u32*)&ppbUser->addr.endAddressHi; + } + if (sync & AX_SYNC_FLAG_COPYCURADDR) { + *(u32*)&ppbDsp->addr.currentAddressHi = *(u32*)&ppbUser->addr.currentAddressHi; + } else { + *(u32*)&ppbUser->addr.currentAddressHi = *(u32*)&ppbDsp->addr.currentAddressHi; + } + } else if (sync & AX_SYNC_FLAG_COPYADDR) { + // copy ADDR struct. + u32* src; + u32* dst; + dst = (void*)&ppbDsp->addr; + src = (void*)&ppbUser->addr; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); + } else { + ppbUser->addr.currentAddressHi = ppbDsp->addr.currentAddressHi; + ppbUser->addr.currentAddressLo = ppbDsp->addr.currentAddressLo; + } + + if (sync & AX_SYNC_FLAG_COPYADPCM) { + // copy ADPCM struct. + u32* src; + u32* dst; + dst = (void*)&ppbDsp->adpcm; + src = (void*)&ppbUser->adpcm; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + } + + if (sync & AX_SYNC_FLAG_COPYRATIO) { + ppbDsp->src.ratioHi = ppbUser->src.ratioHi; + ppbDsp->src.ratioLo = ppbUser->src.ratioLo; + } else if (sync & AX_SYNC_FLAG_COPYSRC) { + // copy SRC struct. + u16* src; + u16* dst; + dst = (void*)&ppbDsp->src; + src = (void*)&ppbUser->src; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + } + + if (sync & AX_SYNC_FLAG_COPYADPCMLOOP) { + // copy ADPCMLOOP struct. + u16* src; + u16* dst; + dst = (void*)&ppbDsp->adpcmLoop; + src = (void*)&ppbUser->adpcmLoop; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); + } + + if (sync & 0x400000) { + ppbDsp->lpf.a0 = ppbUser->lpf.a0; + ppbDsp->lpf.b0 = ppbUser->lpf.b0; + return; + } + + if (sync & 0x200000) { + // copy AXPBLPF struct + u16* src; + u16* dst; + + dst = (void*)&ppbDsp->lpf; + src = (void*)&ppbUser->lpf; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); + } +} + +void __AXDumpVPB(AXVPB* pvpb) { + AXPB* ppbDsp; + + ppbDsp = &__AXPB[pvpb->index]; + if (ppbDsp->state == 1) { + __AXDepopVoice(ppbDsp); + } + pvpb->pb.state = ppbDsp->state = ppbDsp->update.updNum[0] + = ppbDsp->update.updNum[1] = ppbDsp->update.updNum[2] + = ppbDsp->update.updNum[3] = ppbDsp->update.updNum[4] = 0; + __AXPushCallbackStack(pvpb); +} + +void __AXSyncPBs(u32 lessDlpfycles) { + u32 cycles; + u32 i; + AXVPB* pvpb; + + __AXNumVoices = 0; + DCInvalidateRange(__AXPB, sizeof(__AXPB)); + DCInvalidateRange(__AXITD, sizeof(__AXITD)); + cycles = (__AXGetCommandListCycles() + 0x10000) - 0x55F0 + lessDlpfycles; + + for (i = 31; i; i--) { + for (pvpb = __AXGetStackHead(i); pvpb; pvpb = pvpb->next) { + if (pvpb->depop != 0) { + __AXDepopVoice(&__AXPB[pvpb->index]); + } + + if ((pvpb->pb.state == 1) || (pvpb->updateCounter != 0)) { + if (pvpb->pb.srcSelect != 2) { + cycles += __AXSrcCycles[pvpb->pb.src.ratioHi]; + } + + if (pvpb->pb.lpf.on) { + cycles += 555; + } + + cycles += __AXMainMixCycles[pvpb->pb.mixerCtrl & 0xF] + __AXAuxMixCycles[(pvpb->pb.mixerCtrl >> 4) & 0x1F] + __AXAuxMixCycles[(pvpb->pb.mixerCtrl >> 9) & 0x1F] + 0x8C; + if (__AXMaxDspCycles > cycles) { + __AXServiceVPB(pvpb); + } else { + __AXDumpVPB(pvpb); + } + } else { + __AXServiceVPB(pvpb); + } + + pvpb->sync = 0; + pvpb->depop = 0; + pvpb->updateMS = pvpb->updateCounter = 0; + pvpb->updateWrite = pvpb->updateData; + } + } + + __AXRecDspCycles = cycles; + for (pvpb = __AXGetStackHead(0); pvpb; pvpb = pvpb->next) { + if (pvpb->depop != 0) { + __AXDepopVoice(&__AXPB[pvpb->index]); + } + pvpb->depop = 0; + __AXPB[pvpb->index].state = __AXPB[pvpb->index].update.updNum[0] = __AXPB[pvpb->index].update.updNum[1] + = __AXPB[pvpb->index].update.updNum[2] = __AXPB[pvpb->index].update.updNum[3] + = __AXPB[pvpb->index].update.updNum[4] = 0; + } + + DCFlushRange(__AXPB, sizeof(__AXPB)); + DCFlushRange(__AXITD, sizeof(__AXITD)); + DCFlushRange(__AXUpdates, sizeof(__AXUpdates)); +} + +AXPB* __AXGetPBs(void) { + return __AXPB; +} + +void __AXSetPBDefault(AXVPB* p) { + p->pb.state = 0; + p->pb.itd.flag = 0; + p->sync = 0x2000A4; + p->updateMS = p->updateCounter = 0; + p->updateWrite = p->updateData; + p->pb.update.updNum[0] = p->pb.update.updNum[1] = p->pb.update.updNum[2] = p->pb.update.updNum[3] = p->pb.update.updNum[4] = 0; + p->pb.lpf.on = 0; +} + +void __AXVPBInit(void) { + u32 i; + AXPB* ppb; + AXPBITDBUFFER* ppbi; + AXPBU* ppbu; + AXVPB* pvpb; + u32* p; + +#ifdef DEBUG + OSReport("Initializing AXVPB code module\n"); +#endif + __AXMaxDspCycles = OS_BUS_CLOCK / 400; + __AXRecDspCycles = 0; + +#define BUFFER_MEMSET(buffer, size) \ + { \ + p = (u32*)&buffer; \ + for (i = size; i != 0; i--) { \ + *p = 0; \ + p++; \ + } \ + } + + BUFFER_MEMSET(__AXPB, 0xF40); + BUFFER_MEMSET(__AXITD, 0x400); + BUFFER_MEMSET(__AXVPB, 0x22C0); + + for (i = 0; i < AX_MAX_VOICES; i++) { + ppb = &__AXPB[i]; + ppbi = &__AXITD[i]; + ppbu = &__AXUpdates[i]; + pvpb = &__AXVPB[i]; + + ASSERTLINE(913, (u32)ppb ^ 0x1F); + ASSERTLINE(914, (u32)ppbi ^ 0x1F); + ASSERTLINE(915, (u32)ppbu ^ 0x1F); + + pvpb->index = i; + pvpb->updateWrite = pvpb->updateData; + pvpb->itdBuffer = ppbi; + __AXSetPBDefault(pvpb); + + if (i == 0x3F) { + pvpb->pb.nextHi = pvpb->pb.nextLo = ppb->nextHi = ppb->nextLo = 0; + } else { + pvpb->pb.nextHi = (u16)( (u32)((char*)ppb + sizeof(AXPB)) >> 16 ); + pvpb->pb.nextLo = (u16)( (u32)((char*)ppb + sizeof(AXPB)) ); + ppb->nextHi = (u16)( (u32)((char*)ppb + sizeof(AXPB)) >> 16 ); + ppb->nextLo = (u16)( (u32)((char*)ppb + sizeof(AXPB)) ); + } + + pvpb->pb.currHi = (u16)(((u32)ppb) >> 16); + pvpb->pb.currLo = (u16)((u32)ppb); + ppb->currHi = (u16)(((u32)ppb) >> 16); + ppb->currLo = (u16)((u32)ppb); + pvpb->pb.itd.bufferHi = (u16)(((u32)ppbi) >> 16); + pvpb->pb.itd.bufferLo = (u16)((u32)ppbi); + ppb->itd.bufferHi = (u16)(((u32)ppbi) >> 16); + ppb->itd.bufferLo = (u16)((u32)ppbi); + pvpb->pb.update.dataHi = (u16)(((u32)ppbu) >> 16); + pvpb->pb.update.dataLo = (u16)((u32)ppbu); + ppb->update.dataHi = (u16)(((u32)ppbu) >> 16); + ppb->update.dataLo = (u16)((u32)ppbu); + + pvpb->priority = 1; + __AXPushFreeStack(pvpb); + } + + DCFlushRange(__AXPB, sizeof(__AXPB)); +} + +void __AXVPBQuit(void) { +#ifdef DEBUG + OSReport("Shutting down AXVPB code module\n"); +#endif +} + +void AXSetVoiceSrcType(AXVPB* p, u32 type) { + BOOL old; + AXPB* ppb; + + ASSERTLINE(1020, p); + ASSERTLINE(1021, type <= AX_SRC_TYPE_4TAP_16K); + + old = OSDisableInterrupts(); + ppb = &p->pb; + switch(type) { + case AX_SRC_TYPE_NONE: + ppb->srcSelect = 2; + break; + case AX_SRC_TYPE_LINEAR: + ppb->srcSelect = 1; + break; + case AX_SRC_TYPE_4TAP_8K: + ppb->srcSelect = 0; + ppb->coefSelect = 0; + break; + case AX_SRC_TYPE_4TAP_12K: + ppb->srcSelect = 0; + ppb->coefSelect = 1; + break; + case AX_SRC_TYPE_4TAP_16K: + ppb->srcSelect = 0; + ppb->coefSelect = 2; + break; + } + + p->sync |= AX_SYNC_FLAG_COPYSELECT; + OSRestoreInterrupts(old); +} + +void AXSetVoiceState(AXVPB* p, u16 state) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.state = state; + p->sync |= AX_SYNC_FLAG_COPYSTATE; + if (state == 0) { + p->depop = 1; + } + OSRestoreInterrupts(old); +} + +void AXSetVoiceType(AXVPB* p, u16 type) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.type = type; + p->sync |= AX_SYNC_FLAG_COPYTYPE; + OSRestoreInterrupts(old); +} + +void AXSetVoiceMix(AXVPB* p, AXPBMIX* mix) { + BOOL old; + u16 mixerCtrl; + u16* dst; + u16* src; + + src = (u16*)mix; + dst = (u16*)&p->pb.mix; + mixerCtrl = 0; + + old = OSDisableInterrupts(); + + if ((*dst++ = *src++)) mixerCtrl |= 0x1; + if ((*dst++ = *src++)) mixerCtrl |= 0x9; + if ((*dst++ = *src++)) mixerCtrl |= 0x2; + if ((*dst++ = *src++)) mixerCtrl |= 0xA; + if ((*dst++ = *src++)) mixerCtrl |= 0x10; + if ((*dst++ = *src++)) mixerCtrl |= 0x50; + if ((*dst++ = *src++)) mixerCtrl |= 0x20; + if ((*dst++ = *src++)) mixerCtrl |= 0x60; + if ((*dst++ = *src++)) mixerCtrl |= 0x200; + if ((*dst++ = *src++)) mixerCtrl |= 0xA00; + if ((*dst++ = *src++)) mixerCtrl |= 0x400; + if ((*dst++ = *src++)) mixerCtrl |= 0xC00; + if ((*dst++ = *src++)) mixerCtrl |= 0x1000; + if ((*dst++ = *src++)) mixerCtrl |= 0x3000; + if ((*dst++ = *src++)) mixerCtrl |= 0x4; + if ((*dst++ = *src++)) mixerCtrl |= 0xC; + if ((*dst++ = *src++)) mixerCtrl |= 0x80; + if ((*dst++ = *src++)) mixerCtrl |= 0x180; + + p->pb.mixerCtrl = mixerCtrl; + p->sync |= (AX_SYNC_FLAG_COPYAXPBMIX | AX_SYNC_FLAG_COPYMXRCTRL); + OSRestoreInterrupts(old); +} + +void AXSetVoiceItdOn(AXVPB* p) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.itd.flag = 1; + p->pb.itd.shiftL = p->pb.itd.shiftR = p->pb.itd.targetShiftL = p->pb.itd.targetShiftR = 0; + p->sync &= ~(AX_SYNC_FLAG_COPYTSHIFT); + p->sync |= AX_SYNC_FLAG_COPYITD; + OSRestoreInterrupts(old); +} + +void AXSetVoiceItdTarget(AXVPB* p, u16 lShift, u16 rShift) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.itd.targetShiftL = lShift; + p->pb.itd.targetShiftR = rShift; + p->sync |= AX_SYNC_FLAG_COPYTSHIFT; + OSRestoreInterrupts(old); +} + +void AXSetVoiceUpdateIncrement(AXVPB* p) { + BOOL old; + + old = OSDisableInterrupts(); + p->updateMS++; + p->sync |= AX_SYNC_FLAG_COPYUPDATE; + ASSERTMSGLINE(1191, p->updateMS <= 4, "PB updates cannot exceed 5ms\n"); + OSRestoreInterrupts(old); +} + +void AXSetVoiceUpdateWrite(AXVPB* p, u16 param, u16 data) { + BOOL old; + + old = OSDisableInterrupts(); + p->updateCounter+=2; + ASSERTMSGLINE(1205, p->updateCounter <= 128, "PB update block exceeded 128 words\n"); + + *(p->updateWrite) = param; p->updateWrite+=1; + *(p->updateWrite) = data; p->updateWrite+=1; + p->sync |= AX_SYNC_FLAG_COPYUPDATE; + OSRestoreInterrupts(old); +} + +void AXSetVoiceDpop(AXVPB* p, AXPBDPOP* dpop) { + BOOL old; + u16* dst; + u16* src; + + dst = (void*)&p->pb.dpop; + src = (void*)dpop; + + old = OSDisableInterrupts(); + { + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + } + p->sync |= AX_SYNC_FLAG_COPYDPOP; + OSRestoreInterrupts(old); +} + +void AXSetVoiceVe(AXVPB* p, AXPBVE* ve) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.ve.currentVolume = ve->currentVolume; + p->pb.ve.currentDelta = ve->currentDelta; + p->sync |= AX_SYNC_FLAG_COPYVOL; + OSRestoreInterrupts(old); +} + +void AXSetVoiceVeDelta(AXVPB* p, s16 delta) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.ve.currentDelta = delta; + p->sync |= AX_SYNC_FLAG_SWAPVOL; + OSRestoreInterrupts(old); +} + +void AXSetVoiceFir(AXVPB* p, AXPBFIR* fir) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.fir.numCoefs = fir->numCoefs; + p->pb.fir.coefsHi = fir->coefsHi; + p->pb.fir.coefsLo = fir->coefsLo; + p->sync |= AX_SYNC_FLAG_COPYFIR; + OSRestoreInterrupts(old); +} + +void AXSetVoiceAddr(AXVPB* p, AXPBADDR* addr) { + BOOL old; + u32* dst; + u32* src; + + dst = (void*)&p->pb.addr; + src = (void*)addr; + + old = OSDisableInterrupts(); + { + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); + } + + switch(addr->format) { + case 0: + ASSERTMSGLINE(1335, (addr->loopAddressLo & 0xF) > 1, "*** loop address on ADPCM frame header! ***\n"); + ASSERTMSGLINE(1340, (addr->endAddressLo & 0xF) > 1, "*** end address on ADPCM frame header! ***\n"); + ASSERTMSGLINE(1345, (addr->currentAddressLo & 0xF) > 1, "*** current address on ADPCM frame header! ***\n"); + break; + case 10: + dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0x08000000; dst+=1; + *(dst) = 0; dst+=1; + break; + case 25: + dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0; dst+=1; + *(dst) = 0x01000000; dst+=1; + *(dst) = 0; dst+=1; + break; + default: + ASSERTMSGLINE(1389, 0, "unknown addr->formaqt in PB\n"); + break; + } + + p->sync &= ~(AX_SYNC_FLAG_COPYLOOP | AX_SYNC_FLAG_COPYLOOPADDR | AX_SYNC_FLAG_COPYENDADDR | AX_SYNC_FLAG_COPYCURADDR); + p->sync |= (AX_SYNC_FLAG_COPYADDR | AX_SYNC_FLAG_COPYADPCM); + OSRestoreInterrupts(old); +} + +void AXSetVoiceLoop(AXVPB* p, u16 loop) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.addr.loopFlag = loop; + p->sync |= AX_SYNC_FLAG_COPYLOOP; + OSRestoreInterrupts(old); +} + +void AXSetVoiceLoopAddr(AXVPB* p, u32 addr) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.addr.loopAddressHi = (addr >> 0x10); + p->pb.addr.loopAddressLo = (addr); + p->sync |= AX_SYNC_FLAG_COPYLOOPADDR; + OSRestoreInterrupts(old); +} + +void AXSetVoiceEndAddr(AXVPB* p, u32 addr) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.addr.endAddressHi = (addr >> 0x10); + p->pb.addr.endAddressLo = (addr); + p->sync |= AX_SYNC_FLAG_COPYENDADDR; + OSRestoreInterrupts(old); +} + +void AXSetVoiceCurrentAddr(AXVPB* p, u32 addr) { + BOOL old; + + old = OSDisableInterrupts(); + p->pb.addr.currentAddressHi = (addr >> 0x10); + p->pb.addr.currentAddressLo = (addr); + p->sync |= AX_SYNC_FLAG_COPYCURADDR; + OSRestoreInterrupts(old); +} + +void AXSetVoiceAdpcm(AXVPB* p, AXPBADPCM* adpcm) { + BOOL old; + u32* dst; + u32* src; + + dst = (void*)&p->pb.adpcm; + src = (void*)adpcm; + + old = OSDisableInterrupts(); + + { + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + } + p->sync |= AX_SYNC_FLAG_COPYADPCM; + OSRestoreInterrupts(old); +} + +void AXSetVoiceSrc(AXVPB* p, AXPBSRC* src_) { + BOOL old; + u16* dst; + u16* src; + + dst = (void*)&p->pb.src; + src = (void*)src_; + + old = OSDisableInterrupts(); + { + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + } + p->sync &= ~(AX_SYNC_FLAG_COPYRATIO); + p->sync |= AX_SYNC_FLAG_COPYSRC; + OSRestoreInterrupts(old); +} + +void AXSetVoiceSrcRatio(AXVPB* p, float ratio) { + u32 r; + BOOL old; + + old = OSDisableInterrupts(); + r = 65536.0f* ratio; + if (r > 0x40000) { + r = 0x40000; + } + p->pb.src.ratioHi = ((u32)r >> 0x10); + p->pb.src.ratioLo = ((u32)r); + p->sync |= AX_SYNC_FLAG_COPYRATIO; + OSRestoreInterrupts(old); +} + +void AXSetVoiceAdpcmLoop(AXVPB* p, AXPBADPCMLOOP* adpcmloop) { + BOOL old; + u16* dst; + u16* src; + + dst = (void*)&p->pb.adpcmLoop; + src = (void*)adpcmloop; + old = OSDisableInterrupts(); + { + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + *(dst) = *(src); dst+=1; src+=1; + } + p->sync |= AX_SYNC_FLAG_COPYADPCMLOOP; + OSRestoreInterrupts(old); +} + +void AXSetVoiceLpf(AXVPB* p, AXPBLPF* lpf) { + BOOL old; + u16* dst; + u16* src; + + dst = (u16*)&p->pb.lpf; + src = (u16*)lpf; + + old = OSDisableInterrupts(); + + *dst = *src; dst++; src++; + *dst = *src; dst++; src++; + *dst = *src; dst++; src++; + *dst = *src; dst++; src++; + p->sync |= 0x200000; + + OSRestoreInterrupts(old); +} + +void AXSetVoiceLpfCoefs(AXVPB* p, u16 a0, u16 b0) { + BOOL old; + old = OSDisableInterrupts(); + + p->pb.lpf.a0 = a0; + p->pb.lpf.b0 = b0; + p->sync |= 0x400000; + + OSRestoreInterrupts(old); +} + +#define PI 3.14159265358979323846f + +void AXGetLpfCoefs(u16 freq, u16* a0, u16* b0) { + f32 bb; + f32 cc; + + ASSERTMSGLINE(1616, freq <= 16000, "freq is out of range"); + + cc = 2.0f - cos(((PI * 2) * (f32)freq) / 32000.0f); + bb = sqrt((cc * cc) - 1.0f) - cc; + + *b0 = 32768.0f * -bb; + *a0 = 0x7FFF - *b0; +} + +void AXSetMaxDspCycles(u32 cycles) { + __AXMaxDspCycles = cycles; +} + +u32 AXGetMaxDspCycles(void) { + return __AXMaxDspCycles; +} + +u32 AXGetDspCycles(void) { + return __AXRecDspCycles; +} diff --git a/src/dolphin/ax/DSPCode.c b/src/dolphin/ax/DSPCode.c new file mode 100644 index 0000000000..d54b0de21a --- /dev/null +++ b/src/dolphin/ax/DSPCode.c @@ -0,0 +1,669 @@ +#include +#include + +u16 axDspSlaveLength = (AX_DSP_SLAVE_LENGTH * 2); + +u16 axDspSlave[AX_DSP_SLAVE_LENGTH] ATTRIBUTE_ALIGN(32) = { + 0x0000, 0x0000, 0x029F, 0x0E88, 0x029F, 0x0E97, + 0x029F, 0x0EB3, 0x029F, 0x0ED3, 0x029F, 0x0ED9, + 0x029F, 0x0F0B, 0x029F, 0x0F11, 0x1302, 0x1303, + 0x1204, 0x1305, 0x1306, 0x8E00, 0x8C00, 0x8B00, + 0x0092, 0x00FF, 0x8100, 0x8900, 0x009E, 0x0E80, + 0x00FE, 0x0E1B, 0x8100, 0x00FE, 0x0E31, 0x16FC, + 0xDCD1, 0x16FD, 0x0000, 0x16FB, 0x0001, 0x26FC, + 0x02A0, 0x8000, 0x029C, 0x0029, 0x029F, 0x0045, + 0x1302, 0x1303, 0x1204, 0x1305, 0x1306, 0x8E00, + 0x8C00, 0x8B00, 0x0092, 0x00FF, 0x16FC, 0xDCD1, + 0x16FD, 0x0001, 0x16FB, 0x0001, 0x26FC, 0x02A0, + 0x8000, 0x029C, 0x0040, 0x8E00, 0x8100, 0x8900, + 0x009F, 0xBABE, 0x26FE, 0x02C0, 0x8000, 0x029C, + 0x004A, 0x8200, 0x0294, 0x004A, 0x23FF, 0x8100, + 0x26FE, 0x02C0, 0x8000, 0x029C, 0x0054, 0x27FF, + 0x0240, 0x7FFF, 0x2ECE, 0x2FCF, 0x16CD, 0x0C00, + 0x8100, 0x2EC9, 0x1FFB, 0x2FCB, 0x02BF, 0x0652, + 0x0080, 0x0C00, 0x8E00, 0x8100, 0x8970, 0xB100, + 0x0291, 0x007E, 0x0A13, 0xC100, 0x0292, 0x007E, + 0x009F, 0x0C9D, 0x4C00, 0x1C7E, 0x0213, 0x1C7E, + 0x176F, 0x16FC, 0xFBAD, 0x16FD, 0x8080, 0x0021, + 0x16FC, 0xBAAD, 0x2EFD, 0x0021, 0x8D00, 0x8F00, + 0x8A00, 0x8900, 0x8168, 0x0098, 0x0000, 0x0099, + 0x0001, 0x0081, 0x0000, 0x193E, 0x193C, 0x11A0, + 0x009A, 0xA100, 0x8271, 0x0277, 0x1F19, 0x193C, + 0xA100, 0x8271, 0x0277, 0x1F19, 0x193C, 0x1FD8, + 0xB100, 0x0294, 0x00CB, 0x00DE, 0x0E44, 0xB100, + 0x0294, 0x00AB, 0x191C, 0x191C, 0x191C, 0x00E0, + 0x0E45, 0x029F, 0x0114, 0x8B00, 0x7A00, 0x00FE, + 0x0E44, 0x8400, 0x0099, 0x0140, 0x1F1E, 0xA000, + 0x191E, 0x191E, 0x191C, 0x00E0, 0x0E45, 0x009A, + 0x0000, 0x0098, 0x0DC0, 0x4E00, 0x4800, 0x2ECE, + 0x2CCF, 0x009E, 0x0E48, 0x2ECD, 0x0E00, 0x2EC9, + 0x009E, 0x0140, 0x2ECB, 0x029F, 0x00E3, 0x8B00, + 0x00D8, 0x0E44, 0x0099, 0x0140, 0xA000, 0x191E, + 0x00FE, 0x0E44, 0x191E, 0x191C, 0x00E0, 0x0E45, + 0x4E00, 0x2ECE, 0x2CCF, 0x009E, 0x0E48, 0x2ECD, + 0x0E00, 0x2EC9, 0x009E, 0x0140, 0x2ECB, 0x02BF, + 0x0652, 0x8A48, 0x0083, 0x0E48, 0x0080, 0x0000, + 0x0081, 0x0000, 0x1979, 0x193A, 0xB041, 0xA64B, + 0xF051, 0xB441, 0x9100, 0x1150, 0x00FC, 0xA792, + 0xF151, 0xB520, 0x9941, 0xA693, 0xF051, 0xB428, + 0x9141, 0x0083, 0x0E48, 0x0080, 0x0140, 0x0081, + 0x0140, 0x1979, 0x193A, 0xB041, 0xA64B, 0xF051, + 0xB441, 0x9100, 0x1150, 0x0113, 0xA792, 0xF151, + 0xB520, 0x9941, 0xA693, 0xF051, 0xB428, 0x9141, + 0x00C0, 0x0E45, 0x029F, 0x0068, 0x8100, 0x8970, + 0x8E78, 0x2ECE, 0x2FCF, 0x009E, 0x0E48, 0x2ECD, + 0x0E00, 0x2EC9, 0x009E, 0x0040, 0x2ECB, 0x0081, + 0x0E48, 0x0082, 0x0000, 0x009B, 0x009F, 0x009A, + 0x0140, 0x8100, 0x8900, 0x8F00, 0x02BF, 0x0652, + 0x193E, 0x193C, 0xB100, 0x193F, 0x0294, 0x013C, + 0x005A, 0x1B5E, 0x029F, 0x0144, 0x9900, 0x1B5E, + 0x1B5C, 0x007B, 0x0143, 0x4C00, 0x1B5E, 0x1B5C, + 0x193E, 0x193C, 0xB100, 0x193F, 0x0294, 0x014E, + 0x005A, 0x1B5E, 0x029F, 0x0156, 0x9900, 0x1B5E, + 0x1B5C, 0x007B, 0x0155, 0x4C00, 0x1B5E, 0x1B5C, + 0x193E, 0x193C, 0xB100, 0x193F, 0x0294, 0x0160, + 0x005A, 0x1B5E, 0x029F, 0x0168, 0x9900, 0x1B5E, + 0x1B5C, 0x007B, 0x0167, 0x4C00, 0x1B5E, 0x1B5C, + 0x0082, 0x0400, 0x193E, 0x193C, 0xB179, 0x0294, + 0x0173, 0x005A, 0x1B5E, 0x029F, 0x017B, 0x9900, + 0x1B5E, 0x1B5C, 0x007B, 0x017A, 0x4C00, 0x1B5E, + 0x1B5C, 0x193E, 0x193C, 0xB179, 0x0294, 0x0184, + 0x005A, 0x1B5E, 0x029F, 0x018C, 0x9900, 0x1B5E, + 0x1B5C, 0x007B, 0x018B, 0x4C00, 0x1B5E, 0x1B5C, + 0x193E, 0x193C, 0xB179, 0x0294, 0x0195, 0x005A, + 0x1B5E, 0x029F, 0x019D, 0x9900, 0x1B5E, 0x1B5C, + 0x007B, 0x019C, 0x4C00, 0x1B5E, 0x1B5C, 0x0082, + 0x07C0, 0x193E, 0x193C, 0xB179, 0x0294, 0x01A8, + 0x005A, 0x1B5E, 0x029F, 0x01B0, 0x9900, 0x1B5E, + 0x1B5C, 0x007B, 0x01AF, 0x4C00, 0x1B5E, 0x1B5C, + 0x193E, 0x193C, 0xB179, 0x0294, 0x01B9, 0x005A, + 0x1B5E, 0x029F, 0x01C1, 0x9900, 0x1B5E, 0x1B5C, + 0x007B, 0x01C0, 0x4C00, 0x1B5E, 0x1B5C, 0x193E, + 0x193C, 0xB179, 0x0294, 0x01CA, 0x005A, 0x1B5E, + 0x029F, 0x01D2, 0x9900, 0x1B5E, 0x1B5C, 0x007B, + 0x01D1, 0x4C00, 0x1B5E, 0x1B5C, 0x029F, 0x0068, + 0x0085, 0xFFFF, 0x8150, 0x8940, 0x8E48, 0x00FA, + 0x0E17, 0x00F8, 0x0E18, 0x0081, 0x0000, 0x02BF, + 0x05E7, 0x00DA, 0x0E17, 0x00D8, 0x0E18, 0x8948, + 0x0081, 0x0400, 0x02BF, 0x05E7, 0x00DA, 0x0E17, + 0x00D8, 0x0E18, 0x8948, 0x0081, 0x07C0, 0x02BF, + 0x05E7, 0x029F, 0x0068, 0x0086, 0x07C0, 0x02BF, + 0x057A, 0x029F, 0x0068, 0x8100, 0x8E00, 0x191E, + 0x191C, 0x2ECE, 0x2CCF, 0x16CD, 0x0000, 0x16C9, + 0x0001, 0x16CB, 0x0780, 0x02BF, 0x0652, 0x029F, + 0x0068, 0x8100, 0x8970, 0x8E60, 0x2ECE, 0x2CCF, + 0x16CD, 0x0E48, 0x16C9, 0x0000, 0x8900, 0x0D20, + 0x2DCB, 0x4C00, 0x1C80, 0x0080, 0x0280, 0x0081, + 0x0000, 0x0082, 0x0140, 0x0083, 0x0E48, 0x0A00, + 0x27C9, 0x03A0, 0x0004, 0x029C, 0x0222, 0x2ECE, + 0x2CCF, 0x16CD, 0x0E58, 0x16C9, 0x0000, 0x16CB, + 0x0260, 0x009F, 0x00A0, 0x8F00, 0x007F, 0x023B, + 0x197E, 0x1B1A, 0x197C, 0x1B1A, 0x1B5E, 0x7C22, + 0x1B3E, 0x1B3C, 0x1C04, 0x029F, 0x0068, 0x8E70, + 0x8960, 0x191F, 0x2ECE, 0x2CCF, 0x16CD, 0x0C00, + 0x16C9, 0x0000, 0x0503, 0x0340, 0xFFF0, 0x2FCB, + 0x02BF, 0x0652, 0x0080, 0x0C00, 0x029F, 0x0068, + 0x8100, 0x8970, 0x8E78, 0x2ECE, 0x2FCF, 0x16CD, + 0x0B80, 0x16C9, 0x0000, 0x16CB, 0x00C4, 0x0082, + 0x0E08, 0x009F, 0x0000, 0x1B5F, 0x009F, 0x0140, + 0x1B5F, 0x009F, 0x0280, 0x1B5F, 0x009F, 0x0400, + 0x1B5F, 0x009F, 0x0540, 0x1B5F, 0x009F, 0x0680, + 0x1B5F, 0x009F, 0x07C0, 0x1B5F, 0x009F, 0x0900, + 0x1B5F, 0x009F, 0x0A40, 0x1B5F, 0x02BF, 0x0652, + 0x00DE, 0x0BA7, 0x00DF, 0x0BA8, 0x2ECE, 0x2FCF, + 0x16CD, 0x03C0, 0x16C9, 0x0000, 0x16CB, 0x0080, + 0x8100, 0x8900, 0x00DE, 0x0B84, 0x009F, 0x0D21, + 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E15, 0x00DE, + 0x0B85, 0x009F, 0x0D24, 0x4C00, 0x1C7E, 0x0213, + 0x00FE, 0x0E16, 0x00DE, 0x0B86, 0x009A, 0x000F, + 0x009F, 0x0CB1, 0x3400, 0x4C00, 0x1C7E, 0x0213, + 0x00FE, 0x0E14, 0x00DE, 0x0B86, 0x009A, 0x001F, + 0x009F, 0x0CC1, 0x14FC, 0x3400, 0x4C00, 0x1C7E, + 0x0213, 0x00FE, 0x0E46, 0x00DE, 0x0B86, 0x009F, + 0x0CE1, 0x14F7, 0x4C00, 0x1C7E, 0x0213, 0x00FE, + 0x0E47, 0x8100, 0x00DE, 0x0B9B, 0xB100, 0x0295, + 0x02EA, 0x8900, 0x00DF, 0x0B9E, 0x0300, 0x0CC0, + 0x00FF, 0x0E40, 0x00DF, 0x0B9F, 0x0300, 0x0CC0, + 0x00FF, 0x0E41, 0x009F, 0x0CE0, 0x00FF, 0x0E42, + 0x00FF, 0x0E43, 0x02BF, 0x0652, 0x00DE, 0x0B9C, + 0x2ECE, 0x00DE, 0x0B9D, 0x2ECF, 0x16CD, 0x0CC0, + 0x16C9, 0x0000, 0x16CB, 0x0040, 0x02BF, 0x0652, + 0x029F, 0x0068, 0x009F, 0x0CE0, 0x00FF, 0x0E42, + 0x00FF, 0x0E40, 0x00FF, 0x0E41, 0x00FF, 0x0E43, + 0x02BF, 0x0652, 0x029F, 0x0068, 0x8E00, 0x00E0, + 0x0E07, 0x0080, 0x0BA2, 0x0081, 0x03C0, 0x0E05, + 0x00FE, 0x0E04, 0x8900, 0x8150, 0x009F, 0x0B80, + 0x007A, 0x030B, 0x193E, 0x4C49, 0x1C5E, 0x1A59, + 0x0083, 0x0E05, 0x1B61, 0x1B60, 0x00DE, 0x0B87, + 0x0601, 0x0295, 0x0317, 0x029F, 0x040E, 0x00DE, + 0x0E42, 0x00FE, 0x0E1C, 0x00C3, 0x0E15, 0x177F, + 0x8E00, 0x8A00, 0x8100, 0x8900, 0x00DE, 0x0BB3, + 0x00DF, 0x0BB2, 0x1F1F, 0x4D00, 0x1481, 0x8D1E, + 0x1FD8, 0x0098, 0x8000, 0x0080, 0x0E48, 0xA830, + 0xAC38, 0xAD30, 0xAC38, 0xAD30, 0xAC38, 0xAD30, + 0xAC38, 0xAD30, 0xAC38, 0xAD30, 0xAC38, 0xAD30, + 0xAC38, 0xAD30, 0xAC38, 0xAD30, 0xAC38, 0xAD30, + 0xAC38, 0xAD30, 0xAC38, 0xAD30, 0xAC38, 0xAD30, + 0xAC38, 0xAD30, 0xAC38, 0xAD30, 0xAC38, 0xAD30, + 0xAC38, 0x00FE, 0x0BB2, 0x8F00, 0x0080, 0x0E48, + 0x00C1, 0x0E43, 0x1C61, 0x193A, 0x1918, 0x9059, + 0x1919, 0x9E51, 0x8080, 0x9759, 0x8091, 0x9E51, + 0x8080, 0x9759, 0x8091, 0x9E51, 0x8080, 0x9759, + 0x8091, 0x9E51, 0x8080, 0x9759, 0x8091, 0x9E51, + 0x8080, 0x9759, 0x8091, 0x9E51, 0x8080, 0x9759, + 0x8091, 0x9E51, 0x8080, 0x9759, 0x8091, 0x9E51, + 0x8080, 0x9759, 0x8091, 0x9E51, 0x8080, 0x9759, + 0x8091, 0x9E51, 0x8080, 0x9759, 0x8091, 0x9E51, + 0x8080, 0x9759, 0x8091, 0x9E51, 0x8080, 0x9759, + 0x8091, 0x9E51, 0x8080, 0x9759, 0x8091, 0x9E51, + 0x8080, 0x9759, 0x8091, 0x9E51, 0x8080, 0x9759, + 0x8091, 0x9E00, 0x6F33, 0x1B7F, 0x8100, 0x00DE, + 0x0BDD, 0xB100, 0x0295, 0x03C0, 0x8D00, 0x8F00, + 0x8A00, 0x00C0, 0x0E43, 0x00C1, 0x0E43, 0x0083, + 0x0BDF, 0x0087, 0xFFFF, 0x00DE, 0x0BDE, 0x80E1, + 0xB04F, 0x1F5E, 0xE2E1, 0xB64F, 0x1F5E, 0xE2E1, + 0x110F, 0x03BB, 0xB79A, 0x1F5F, 0xE2E1, 0xB69B, + 0x1F5E, 0xE2E1, 0xB79A, 0x1B1F, 0x00FF, 0x0BDE, + 0x00C3, 0x0E14, 0x8A00, 0x177F, 0x00C3, 0x0E46, + 0x8A00, 0x177F, 0x00C3, 0x0E47, 0x8A00, 0x177F, + 0x8100, 0x00DE, 0x0B9B, 0xB100, 0x0295, 0x0406, + 0x00DE, 0x0E42, 0x00FE, 0x0E43, 0x8100, 0x8900, + 0x00DE, 0x0B9E, 0x00DF, 0x0BA0, 0x8200, 0x0293, + 0x03E2, 0x7800, 0x029F, 0x03E5, 0x0295, 0x03E5, + 0x7400, 0x00FE, 0x0B9E, 0x00DF, 0x0E43, 0x05E0, + 0x4C00, 0x00FE, 0x0E40, 0x8100, 0x8900, 0x00DE, + 0x0B9F, 0x00DF, 0x0BA1, 0x8200, 0x0293, 0x03F9, + 0x7800, 0x029F, 0x03FC, 0x0295, 0x03FC, 0x7400, + 0x00FE, 0x0B9F, 0x00DF, 0x0E43, 0x05E0, 0x4C00, + 0x00FE, 0x0E41, 0x029F, 0x040E, 0x00DE, 0x0E42, + 0x00FE, 0x0E40, 0x00FE, 0x0E41, 0x00FE, 0x0E43, + 0x8100, 0x8E00, 0x8400, 0x8900, 0x1EFE, 0x0E40, + 0x1EBE, 0x0083, 0x0E08, 0x1C03, 0x1FF5, 0x191A, + 0xF858, 0xFBA0, 0xF8B1, 0xFBA0, 0xF8B1, 0xFBA0, + 0xF8B1, 0xFBA0, 0xF83B, 0x1B7E, 0x0083, 0x0E04, + 0x8100, 0x8973, 0x1961, 0x1960, 0x7800, 0x00FE, + 0x0E04, 0x0294, 0x0303, 0x8E00, 0x8100, 0x00DE, + 0x0B9B, 0xB100, 0x0295, 0x0446, 0x00DE, 0x0B9C, + 0x00DC, 0x0B9D, 0x2ECE, 0x2CCF, 0x8100, 0x00DE, + 0x0E1C, 0x2ECD, 0x16C9, 0x0001, 0x16CB, 0x0040, + 0x02BF, 0x0652, 0x8100, 0x8900, 0x00DE, 0x0B82, + 0x00DF, 0x0B83, 0x2ECE, 0x2FCF, 0x16CD, 0x0B80, + 0x16C9, 0x0001, 0x16CB, 0x00C4, 0x02BF, 0x0652, + 0x8100, 0x00DE, 0x0B80, 0x00DC, 0x0B81, 0xB100, + 0x0294, 0x0462, 0x00C0, 0x0E07, 0x029F, 0x0068, + 0x2ECE, 0x2CCF, 0x16CD, 0x0B80, 0x16C9, 0x0000, + 0x16CB, 0x00C4, 0x0082, 0x0E08, 0x009F, 0x0000, + 0x1B5F, 0x009F, 0x0140, 0x1B5F, 0x009F, 0x0280, + 0x1B5F, 0x009F, 0x0400, 0x1B5F, 0x009F, 0x0540, + 0x1B5F, 0x009F, 0x0680, 0x1B5F, 0x009F, 0x07C0, + 0x1B5F, 0x009F, 0x0900, 0x1B5F, 0x009F, 0x0A40, + 0x1B5F, 0x02BF, 0x0652, 0x00DE, 0x0BA7, 0x00DF, + 0x0BA8, 0x2ECE, 0x2FCF, 0x16CD, 0x03C0, 0x16C9, + 0x0000, 0x16CB, 0x0080, 0x8100, 0x8900, 0x00DE, + 0x0B84, 0x009F, 0x0D21, 0x4C00, 0x1C7E, 0x0213, + 0x00FE, 0x0E15, 0x00DE, 0x0B85, 0x009F, 0x0D24, + 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E16, 0x00DE, + 0x0B86, 0x009A, 0x000F, 0x009F, 0x0CB1, 0x3400, + 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E14, 0x00DE, + 0x0B86, 0x009A, 0x001F, 0x009F, 0x0CC1, 0x14FC, + 0x3400, 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E46, + 0x00DE, 0x0B86, 0x009F, 0x0CE1, 0x14F7, 0x4C00, + 0x1C7E, 0x0213, 0x00FE, 0x0E47, 0x8100, 0x00DE, + 0x0B9B, 0xB100, 0x0295, 0x04F9, 0x8900, 0x00DF, + 0x0B9E, 0x0300, 0x0CC0, 0x00FF, 0x0E40, 0x00DF, + 0x0B9F, 0x0300, 0x0CC0, 0x00FF, 0x0E41, 0x009F, + 0x0CE0, 0x00FF, 0x0E42, 0x00FF, 0x0E43, 0x02BF, + 0x0652, 0x00DE, 0x0B9C, 0x2ECE, 0x00DE, 0x0B9D, + 0x2ECF, 0x16CD, 0x0CC0, 0x16C9, 0x0000, 0x16CB, + 0x0040, 0x02BF, 0x0652, 0x00C0, 0x0E07, 0x029F, + 0x02F8, 0x009F, 0x0CE0, 0x00FF, 0x0E42, 0x00FF, + 0x0E40, 0x00FF, 0x0E41, 0x00FF, 0x0E43, 0x02BF, + 0x0652, 0x00C0, 0x0E07, 0x029F, 0x02F8, 0x8E00, + 0x0086, 0x0400, 0x8100, 0x8970, 0x191C, 0x2ECE, + 0x2CCF, 0x1FC6, 0x2ECD, 0x16C9, 0x0001, 0x16CB, + 0x0780, 0x02BF, 0x0652, 0x02BF, 0x057A, 0x029F, + 0x0068, 0x8E00, 0x0086, 0x07C0, 0x8100, 0x8970, + 0x191C, 0x2ECE, 0x2CCF, 0x1FC6, 0x2ECD, 0x16C9, + 0x0001, 0x16CB, 0x0780, 0x02BF, 0x0652, 0x02BF, + 0x057A, 0x029F, 0x0068, 0x8C00, 0x8A00, 0x8100, + 0x8970, 0x191F, 0x2ECE, 0x2FCF, 0x16CD, 0x0280, + 0x16C9, 0x0001, 0x16CB, 0x0280, 0x8F50, 0x8140, + 0x0081, 0x0400, 0x0083, 0x0000, 0x0082, 0x0140, + 0x0099, 0x0080, 0x02BF, 0x0652, 0x1105, 0x0562, + 0x1F61, 0x1120, 0x0554, 0x8972, 0x195C, 0xF07B, + 0x197D, 0xF131, 0x8139, 0x8900, 0x6800, 0x2ECE, + 0x2CCF, 0x1FFB, 0x2FCD, 0x0F01, 0x2FC9, 0x1FF9, + 0x2FCB, 0x7200, 0x1F5E, 0x1F1C, 0x8100, 0x26C9, + 0x02A0, 0x0004, 0x029C, 0x0563, 0x029F, 0x0068, + 0x029F, 0x0068, 0x029F, 0x0068, 0x029F, 0x0068, + 0x16FC, 0xDCD1, 0x16FD, 0x0002, 0x16FB, 0x0001, + 0x029F, 0x0F1A, 0x029F, 0x0045, 0x8E00, 0x191F, + 0x191D, 0x1F5F, 0x1F1D, 0x2FCE, 0x2DCF, 0x8900, + 0x1FA6, 0x2DCD, 0x0E00, 0x2EC9, 0x8100, 0x009C, + 0x00C0, 0x2CCB, 0x1CA0, 0x0081, 0x0E48, 0x4800, + 0x1B3E, 0x1B3C, 0x0B00, 0x0099, 0x0060, 0x4B00, + 0x1B3D, 0x0081, 0x0E48, 0x1C06, 0x0083, 0x0000, + 0x1C43, 0x27C9, 0x03A0, 0x0004, 0x029C, 0x059B, + 0x1109, 0x05D0, 0x8E00, 0x193A, 0x1938, 0x6900, + 0x2FCE, 0x2DCF, 0x8900, 0x193D, 0x2DCD, 0x16C9, + 0x0000, 0x8100, 0x009C, 0x00C0, 0x2CCB, 0x0081, + 0x0E48, 0x4800, 0x1B3E, 0x1B3C, 0x0B00, 0x0960, + 0x4B00, 0x1B3D, 0x0081, 0x0E48, 0x8F00, 0x80F0, + 0x80C0, 0x6A00, 0x4800, 0x1117, 0x05CA, 0x80F0, + 0x80C0, 0x6B32, 0x4922, 0x80F0, 0x80C0, 0x6A3A, + 0x482A, 0x80F0, 0x80C0, 0x6B32, 0x4922, 0x1B5F, + 0x1B5D, 0x80F0, 0x80C0, 0x6A00, 0x4800, 0x1117, + 0x05DE, 0x80F0, 0x80C0, 0x6B32, 0x4922, 0x80F0, + 0x80C0, 0x6A3A, 0x482A, 0x80F0, 0x80C0, 0x6B32, + 0x4922, 0x1B5F, 0x1B5D, 0x1C05, 0x02DF, 0x8E00, + 0x009B, 0x0E48, 0x009D, 0x00C0, 0x02BF, 0x0637, + 0x4900, 0x00FF, 0x0E1D, 0x00FD, 0x0E1E, 0x8900, + 0x02BF, 0x0652, 0x1104, 0x0622, 0x00DA, 0x0E1D, + 0x00D8, 0x0E1E, 0x009B, 0x0EA8, 0x009D, 0x00C0, + 0x02BF, 0x0637, 0x4900, 0x00FF, 0x0E1D, 0x00FD, + 0x0E1E, 0x0083, 0x0E48, 0x02BF, 0x0642, 0x8900, + 0x00DA, 0x0E1D, 0x00D8, 0x0E1E, 0x009B, 0x0E48, + 0x009D, 0x00C0, 0x02BF, 0x0637, 0x4900, 0x00FF, + 0x0E1D, 0x00FD, 0x0E1E, 0x0083, 0x0EA8, 0x02BF, + 0x0642, 0x0000, 0x0000, 0x8E00, 0x8900, 0x00DA, + 0x0E1D, 0x00D8, 0x0E1E, 0x009B, 0x0EA8, 0x009D, + 0x00C0, 0x02BF, 0x0637, 0x4900, 0x0083, 0x0E48, + 0x02BF, 0x0642, 0x0083, 0x0EA8, 0x02BF, 0x0642, + 0x02DF, 0x8E00, 0x00FA, 0xFFCE, 0x00F8, 0xFFCF, + 0x00FB, 0xFFCD, 0x16C9, 0x0000, 0x2DCB, 0x02DF, + 0x8F00, 0x8D00, 0x8A00, 0x197A, 0x1978, 0xA000, + 0xB600, 0x1130, 0x0650, 0x9179, 0x4E6D, 0x197A, + 0x4D43, 0xA039, 0xB629, 0x02DF, 0x26C9, 0x02A0, + 0x0004, 0x029C, 0x0652, 0x02DF, 0x26FE, 0x02C0, + 0x8000, 0x029C, 0x0658, 0x02DF, 0x26FC, 0x02A0, + 0x8000, 0x029C, 0x065E, 0x02DF, 0x26FC, 0x02A0, + 0x8000, 0x029C, 0x0664, 0x02DF, 0x8100, 0x8970, + 0x8E60, 0x2ECE, 0x2CCF, 0x16CD, 0x0E48, 0x16C9, + 0x0000, 0x8900, 0x0D20, 0x2DCB, 0x4C00, 0x1C80, + 0x0080, 0x0280, 0x0081, 0x0000, 0x0082, 0x0140, + 0x0083, 0x0E48, 0x0A00, 0x27C9, 0x03A0, 0x0004, + 0x029C, 0x0681, 0x2ECE, 0x2CCF, 0x16CD, 0x0E58, + 0x16C9, 0x0000, 0x16CB, 0x0260, 0x009F, 0x00A0, + 0x8F00, 0x007F, 0x069A, 0x197E, 0x1B1A, 0x197C, + 0x1B1A, 0x1B5E, 0x1B5C, 0x1B3E, 0x1B3C, 0x1C04, + 0x029F, 0x0068, 0x0082, 0x0BB8, 0x195E, 0x2ED1, + 0x195E, 0x2ED4, 0x195E, 0x2ED5, 0x195E, 0x2ED6, + 0x195E, 0x2ED7, 0x195E, 0x2ED8, 0x195E, 0x2ED9, + 0x195E, 0x2EA0, 0x195E, 0x2EA1, 0x195E, 0x2EA2, + 0x195E, 0x2EA3, 0x195E, 0x2EA4, 0x195E, 0x2EA5, + 0x195E, 0x2EA6, 0x195E, 0x2EA7, 0x195E, 0x2EA8, + 0x195E, 0x2EA9, 0x195E, 0x2EAA, 0x195E, 0x2EAB, + 0x195E, 0x2EAC, 0x195E, 0x2EAD, 0x195E, 0x2EAE, + 0x195E, 0x2EAF, 0x195E, 0x2EDE, 0x195E, 0x2EDA, + 0x195E, 0x2EDB, 0x195E, 0x2EDC, 0x8C00, 0x8A00, + 0x8E00, 0x00D8, 0x0E16, 0x195B, 0x1959, 0x8100, + 0x195C, 0x0080, 0x0E48, 0x195F, 0x1B1F, 0x195F, + 0x1B1F, 0x195F, 0x1B1F, 0x185F, 0x1B1F, 0x6B00, + 0x1505, 0x4D00, 0x157E, 0x1C9F, 0x1CBD, 0x05E0, + 0x9900, 0x7D00, 0x1CDD, 0x8900, 0x1FA5, 0x1502, + 0x1CBF, 0x009A, 0x01FC, 0x009E, 0x0E48, 0x0081, + 0xFFDD, 0x0083, 0x0D80, 0x0064, 0x0710, 0x1827, + 0x1B07, 0x4A00, 0x1FFC, 0x1827, 0x1B07, 0x1579, + 0x3500, 0x1827, 0x1B07, 0x4100, 0x1B7E, 0x1827, + 0x1B07, 0x1B7F, 0x0000, 0x0065, 0x0716, 0x1827, + 0x1B07, 0x0000, 0x0000, 0x0007, 0x187F, 0x0066, + 0x071F, 0x4A3B, 0x1FFC, 0x1579, 0x3533, 0x4100, + 0x1B7F, 0x0004, 0x189F, 0x1ADF, 0x189F, 0x1ADF, + 0x189F, 0x1ADF, 0x189F, 0x1ADF, 0x1ADC, 0x0082, + 0x0BD2, 0x27DC, 0x1ADF, 0x27DB, 0x1ADF, 0x27DA, + 0x1ADF, 0x0082, 0x0BBE, 0x27D9, 0x1ADF, 0x27D8, + 0x1ADF, 0x8F00, 0x00C1, 0x0E42, 0x0082, 0x0D80, + 0x1940, 0x1943, 0x80F0, 0xB8C0, 0x111F, 0x074A, + 0xA6F0, 0xBCF0, 0x1940, 0x1943, 0xBCF0, 0x4EC0, + 0xB831, 0xA6F0, 0xBCF0, 0xBC00, 0x4E00, 0x1B3E, + 0x00E1, 0x0E42, 0x02DF, 0x0082, 0x0BB8, 0x195E, + 0x2ED1, 0x195E, 0x2ED4, 0x195E, 0x2ED5, 0x195E, + 0x2ED6, 0x195E, 0x2ED7, 0x195E, 0x2ED8, 0x195E, + 0x2ED9, 0x195E, 0x2EA0, 0x195E, 0x2EA1, 0x195E, + 0x2EA2, 0x195E, 0x2EA3, 0x195E, 0x2EA4, 0x195E, + 0x2EA5, 0x195E, 0x2EA6, 0x195E, 0x2EA7, 0x195E, + 0x2EA8, 0x195E, 0x2EA9, 0x195E, 0x2EAA, 0x195E, + 0x2EAB, 0x195E, 0x2EAC, 0x195E, 0x2EAD, 0x195E, + 0x2EAE, 0x195E, 0x2EAF, 0x195E, 0x2EDE, 0x195E, + 0x2EDA, 0x195E, 0x2EDB, 0x195E, 0x2EDC, 0x8C00, + 0x8A00, 0x8F00, 0x195B, 0x1959, 0x1958, 0x0080, + 0x0E48, 0x195F, 0x1B1F, 0x195F, 0x1B1F, 0x195F, + 0x1B1F, 0x185F, 0x1B1F, 0x6B00, 0x1505, 0x7100, + 0x157E, 0x03A0, 0xFFFF, 0x029C, 0x07AB, 0x0085, + 0x0000, 0x1502, 0x1C9F, 0x0086, 0x0020, 0x029F, + 0x07B7, 0x7900, 0x1CBF, 0x1C9D, 0x05E0, 0x9900, + 0x7D00, 0x1CDD, 0x8900, 0x1FA4, 0x1502, 0x0504, + 0x1C9F, 0x009E, 0x0E4A, 0x7000, 0x0081, 0xFFDD, + 0x0083, 0x0D80, 0x1F42, 0x0064, 0x07C4, 0x1827, + 0x1B07, 0x0000, 0x0000, 0x0065, 0x07D6, 0x1827, + 0x1B07, 0x4A00, 0x1C5E, 0x1827, 0x1B07, 0x1958, + 0x195F, 0x1827, 0x1B07, 0x5100, 0x1B7F, 0x1827, + 0x1B07, 0x1B7C, 0x1B78, 0x0066, 0x07E0, 0x4A00, + 0x1C5E, 0x1958, 0x195F, 0x5100, 0x1B7F, 0x1B7C, + 0x1B78, 0x0004, 0x1C5A, 0x189F, 0x1ADF, 0x189F, + 0x1ADF, 0x189F, 0x1ADF, 0x189F, 0x1ADF, 0x1ADC, + 0x0082, 0x0BD2, 0x27DC, 0x1ADF, 0x27DB, 0x1ADF, + 0x27DA, 0x1ADF, 0x0082, 0x0BBE, 0x27D9, 0x1ADF, + 0x27D8, 0x1ADF, 0x8D00, 0x8B00, 0x8F00, 0x0080, + 0x0D80, 0x00C3, 0x0E42, 0x191A, 0x1919, 0xB058, + 0xFB50, 0x1919, 0x110F, 0x080D, 0xB058, 0xFAA1, + 0x1919, 0xB058, 0xFBA0, 0x1919, 0xB058, 0xFA3B, + 0x1B7E, 0x00E3, 0x0E42, 0x02DF, 0x0082, 0x0BB8, + 0x195E, 0x2ED1, 0x195E, 0x2ED4, 0x195E, 0x2ED5, + 0x195E, 0x2ED6, 0x195E, 0x2ED7, 0x195E, 0x2ED8, + 0x195E, 0x2ED9, 0x195E, 0x2EA0, 0x195E, 0x2EA1, + 0x195E, 0x2EA2, 0x195E, 0x2EA3, 0x195E, 0x2EA4, + 0x195E, 0x2EA5, 0x195E, 0x2EA6, 0x195E, 0x2EA7, + 0x195E, 0x2EA8, 0x195E, 0x2EA9, 0x195E, 0x2EAA, + 0x195E, 0x2EAB, 0x195E, 0x2EAC, 0x195E, 0x2EAD, + 0x195E, 0x2EAE, 0x195E, 0x2EAF, 0x195E, 0x2EDE, + 0x195E, 0x2EDA, 0x195E, 0x2EDB, 0x195E, 0x2EDC, + 0x00C0, 0x0E42, 0x0081, 0xFFDD, 0x1120, 0x0855, + 0x1824, 0x1B04, 0x0000, 0x0000, 0x00E0, 0x0E42, + 0x0082, 0x0BD9, 0x0004, 0x189F, 0x1ADF, 0x189F, + 0x1ADF, 0x189F, 0x1ADF, 0x189F, 0x1ADF, 0x8900, + 0x1ADC, 0x27DC, 0x00FF, 0x0BD2, 0x27DB, 0x00FF, + 0x0BD1, 0x27DA, 0x00FF, 0x0BD0, 0x27D9, 0x00FF, + 0x0BBE, 0x27D8, 0x00FF, 0x0BBD, 0x02DF, 0x02DF, + 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BA9, 0x02DF, + 0x00C0, 0x0E41, 0x0081, 0x0B8B, 0x00C2, 0x0E09, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BAC, 0x02DF, + 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, + 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, + 0x80E7, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x02DF, + 0x00C0, 0x0E43, 0x0081, 0x0B97, 0x00C2, 0x0E0A, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BAF, 0x02DF, + 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BA9, 0x00C0, + 0x0E43, 0x0081, 0x0B97, 0x00C2, 0x0E0A, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BAF, 0x02DF, 0x00C0, + 0x0E41, 0x0081, 0x0B8B, 0x00C2, 0x0E09, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BAC, 0x00C0, 0x0E43, + 0x0081, 0x0B97, 0x00C2, 0x0E0A, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BAF, 0x02DF, 0x00C0, 0x0E40, + 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x1C62, 0x00C4, + 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x80E7, 0x00F8, + 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E43, 0x0081, + 0x0B97, 0x00C2, 0x0E0A, 0x1C62, 0x02BF, 0x81F9, + 0x00F8, 0x0BAF, 0x02DF, 0x00C0, 0x0E40, 0x0081, + 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E48, 0x02BF, + 0x845D, 0x00F8, 0x0BA9, 0x02DF, 0x00C0, 0x0E41, + 0x0081, 0x0B8B, 0x00C2, 0x0E09, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BAC, 0x02DF, 0x00C0, + 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x0083, + 0x0E48, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, + 0x8282, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x02DF, + 0x00C0, 0x0E43, 0x0081, 0x0B97, 0x00C2, 0x0E0A, + 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BAF, + 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, + 0x0E08, 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, + 0x0BA9, 0x00C0, 0x0E43, 0x0081, 0x0B97, 0x00C2, + 0x0E0A, 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, + 0x0BAF, 0x02DF, 0x00C0, 0x0E41, 0x0081, 0x0B8B, + 0x00C2, 0x0E09, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BAC, 0x00C0, 0x0E43, 0x0081, 0x0B97, + 0x00C2, 0x0E0A, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BAF, 0x02DF, 0x00C0, 0x0E40, 0x0081, + 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E48, 0x00C4, + 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x8282, 0x00F8, + 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E43, 0x0081, + 0x0B97, 0x00C2, 0x0E0A, 0x0083, 0x0E48, 0x02BF, + 0x845D, 0x00F8, 0x0BAF, 0x02DF, 0x00C0, 0x0E40, + 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BAA, 0x02DF, 0x00C0, 0x0E41, + 0x0081, 0x0B8F, 0x00C2, 0x0E0C, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BAD, 0x02DF, 0x00C0, 0x0E40, + 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x1C62, 0x00C4, + 0x0E41, 0x00C5, 0x0E0C, 0x02BF, 0x80E7, 0x00F8, + 0x0BAA, 0x00FB, 0x0BAD, 0x02DF, 0x00C0, 0x0E40, + 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BAA, 0x02DF, 0x00C0, + 0x0E41, 0x0081, 0x0B8F, 0x00C2, 0x0E0C, 0x0083, + 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BAD, 0x02DF, + 0x00C0, 0x0E40, 0x0081, 0x0B8D, 0x00C2, 0x0E0B, + 0x0083, 0x0E48, 0x00C4, 0x0E41, 0x00C5, 0x0E0C, + 0x02BF, 0x8282, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, + 0x02DF, 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, + 0x0E0D, 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB0, + 0x02DF, 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, + 0x0E0D, 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB0, + 0x029F, 0x0982, 0x00C0, 0x0E43, 0x0081, 0x0B99, + 0x00C2, 0x0E0D, 0x1C62, 0x02BF, 0x81F9, 0x00F8, + 0x0BB0, 0x029F, 0x098E, 0x00C0, 0x0E43, 0x0081, + 0x0B99, 0x00C2, 0x0E0D, 0x1C62, 0x02BF, 0x81F9, + 0x00F8, 0x0BB0, 0x029F, 0x099A, 0x00C0, 0x0E43, + 0x0081, 0x0B99, 0x00C2, 0x0E0D, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BB0, 0x029F, 0x09AC, 0x00C0, + 0x0E43, 0x0081, 0x0B99, 0x00C2, 0x0E0D, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BB0, 0x029F, 0x09B9, + 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, 0x0E0D, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB0, 0x029F, + 0x09C6, 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, + 0x0E0D, 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, + 0x0BB0, 0x02DF, 0x00C0, 0x0E43, 0x0081, 0x0B99, + 0x00C2, 0x0E0D, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BB0, 0x029F, 0x0982, 0x00C0, 0x0E43, + 0x0081, 0x0B99, 0x00C2, 0x0E0D, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BB0, 0x029F, 0x098E, + 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, 0x0E0D, + 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BB0, + 0x029F, 0x099A, 0x00C0, 0x0E43, 0x0081, 0x0B99, + 0x00C2, 0x0E0D, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BB0, 0x029F, 0x09AC, 0x00C0, 0x0E43, + 0x0081, 0x0B99, 0x00C2, 0x0E0D, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BB0, 0x029F, 0x09B9, + 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, 0x0E0D, + 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BB0, + 0x029F, 0x09C6, 0x00C0, 0x0E40, 0x0081, 0x0B91, + 0x00C2, 0x0E0E, 0x1C62, 0x02BF, 0x81F9, 0x00F8, + 0x0BAB, 0x02DF, 0x00C0, 0x0E41, 0x0081, 0x0B93, + 0x00C2, 0x0E0F, 0x1C62, 0x02BF, 0x81F9, 0x00F8, + 0x0BAE, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B91, + 0x00C2, 0x0E0E, 0x1C62, 0x00C4, 0x0E41, 0x00C5, + 0x0E0F, 0x02BF, 0x80E7, 0x00F8, 0x0BAB, 0x00FB, + 0x0BAE, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B91, + 0x00C2, 0x0E0E, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BAB, 0x02DF, 0x00C0, 0x0E41, 0x0081, + 0x0B93, 0x00C2, 0x0E0F, 0x0083, 0x0E48, 0x02BF, + 0x845D, 0x00F8, 0x0BAE, 0x02DF, 0x00C0, 0x0E40, + 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x0083, 0x0E48, + 0x00C4, 0x0E41, 0x00C5, 0x0E0F, 0x02BF, 0x8282, + 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x02DF, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BB1, 0x02DF, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BB1, 0x029F, 0x0A94, + 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB1, 0x029F, + 0x0AA0, 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, + 0x0E10, 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB1, + 0x029F, 0x0AAC, 0x00C0, 0x0E43, 0x0081, 0x0B95, + 0x00C2, 0x0E10, 0x1C62, 0x02BF, 0x81F9, 0x00F8, + 0x0BB1, 0x029F, 0x0ABE, 0x00C0, 0x0E43, 0x0081, + 0x0B95, 0x00C2, 0x0E10, 0x1C62, 0x02BF, 0x81F9, + 0x00F8, 0x0BB1, 0x029F, 0x0ACB, 0x00C0, 0x0E43, + 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BB1, 0x029F, 0x0AD8, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x0083, + 0x0E48, 0x02BF, 0x845D, 0x02DF, 0x00C0, 0x0E43, + 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BB1, 0x029F, 0x0A94, + 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, + 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BB1, + 0x029F, 0x0AA0, 0x00C0, 0x0E43, 0x0081, 0x0B95, + 0x00C2, 0x0E10, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BB1, 0x029F, 0x0AAC, 0x00C0, 0x0E43, + 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BB1, 0x029F, 0x0ABE, + 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, + 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BB1, + 0x029F, 0x0ACB, 0x00C0, 0x0E43, 0x0081, 0x0B95, + 0x00C2, 0x0E10, 0x0083, 0x0E48, 0x02BF, 0x845D, + 0x00F8, 0x0BB1, 0x029F, 0x0AD8, 0x00C0, 0x0E43, + 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BAB, 0x02DF, 0x00C0, 0x0E43, + 0x0081, 0x0B93, 0x00C2, 0x0E0F, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BAE, 0x02DF, 0x00C0, 0x0E43, + 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x1C62, 0x00C4, + 0x0E43, 0x00C5, 0x0E0F, 0x02BF, 0x80E7, 0x00F8, + 0x0BAB, 0x00FB, 0x0BAE, 0x02DF, 0x00C0, 0x0E43, + 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x0083, 0x0E48, + 0x02BF, 0x845D, 0x00F8, 0x0BAB, 0x02DF, 0x00C0, + 0x0E43, 0x0081, 0x0B93, 0x00C2, 0x0E0F, 0x0083, + 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BAE, 0x02DF, + 0x00C0, 0x0E43, 0x0081, 0x0B91, 0x00C2, 0x0E0E, + 0x0083, 0x0E48, 0x00C4, 0x0E43, 0x00C5, 0x0E0F, + 0x02BF, 0x8282, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, + 0x02DF, 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, + 0x0E10, 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB1, + 0x029F, 0x0BA4, 0x00C0, 0x0E43, 0x0081, 0x0B95, + 0x00C2, 0x0E10, 0x1C62, 0x02BF, 0x81F9, 0x00F8, + 0x0BB1, 0x029F, 0x0BB0, 0x00C0, 0x0E43, 0x0081, + 0x0B95, 0x00C2, 0x0E10, 0x1C62, 0x02BF, 0x81F9, + 0x00F8, 0x0BB1, 0x029F, 0x0BBC, 0x00C0, 0x0E43, + 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x1C62, 0x02BF, + 0x81F9, 0x00F8, 0x0BB1, 0x029F, 0x0BCE, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BB1, 0x029F, 0x0BDB, + 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, + 0x1C62, 0x02BF, 0x81F9, 0x00F8, 0x0BB1, 0x029F, + 0x0BE8, 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, + 0x0E10, 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, + 0x0BB1, 0x029F, 0x0BA4, 0x00C0, 0x0E43, 0x0081, + 0x0B95, 0x00C2, 0x0E10, 0x0083, 0x0E48, 0x02BF, + 0x845D, 0x00F8, 0x0BB1, 0x029F, 0x0BB0, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x0083, + 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BB1, 0x029F, + 0x0BBC, 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, + 0x0E10, 0x0083, 0x0E48, 0x02BF, 0x845D, 0x00F8, + 0x0BB1, 0x029F, 0x0BCE, 0x00C0, 0x0E43, 0x0081, + 0x0B95, 0x00C2, 0x0E10, 0x0083, 0x0E48, 0x02BF, + 0x845D, 0x00F8, 0x0BB1, 0x029F, 0x0BDB, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x0083, + 0x0E48, 0x02BF, 0x845D, 0x00F8, 0x0BB1, 0x029F, + 0x0BE8, 0x0118, 0x01D4, 0x0252, 0x02F8, 0x0509, + 0x051D, 0x01FB, 0x066A, 0x0D27, 0x01F5, 0x056E, + 0x056A, 0x056C, 0x023F, 0x0531, 0x0570, 0x0DA1, + 0x020B, 0x0082, 0x0E17, 0x0875, 0x0876, 0x0882, + 0x088E, 0x08A0, 0x08AC, 0x08C3, 0x08DA, 0x0875, + 0x08F7, 0x0904, 0x0911, 0x0924, 0x0931, 0x094A, + 0x0963, 0x0875, 0x0982, 0x098E, 0x099A, 0x0875, + 0x09AC, 0x09B9, 0x09C6, 0x09D9, 0x09E5, 0x09F2, + 0x09FF, 0x09D9, 0x0A0C, 0x0A19, 0x0A26, 0x0875, + 0x0982, 0x098E, 0x099A, 0x0875, 0x09AC, 0x09B9, + 0x09C6, 0x0A33, 0x0A40, 0x0A4E, 0x0A5C, 0x0A33, + 0x0A6A, 0x0A78, 0x0A86, 0x0875, 0x0A94, 0x0AA0, + 0x0AAC, 0x0875, 0x0ABE, 0x0ACB, 0x0AD8, 0x0AEB, + 0x0AF7, 0x0B04, 0x0B11, 0x0AEB, 0x0B1E, 0x0B2B, + 0x0B38, 0x0875, 0x0A94, 0x0AA0, 0x0AAC, 0x0875, + 0x0ABE, 0x0ACB, 0x0AD8, 0x0B45, 0x0B50, 0x0B5E, + 0x0B6C, 0x0B45, 0x0B7A, 0x0B88, 0x0B96, 0x0875, + 0x0BA4, 0x0BB0, 0x0BBC, 0x0875, 0x0BCE, 0x0BDB, + 0x0BE8, 0x0AEB, 0x0BFB, 0x0C08, 0x0C15, 0x0AEB, + 0x0C22, 0x0C2F, 0x0C3C, 0x0875, 0x0BA4, 0x0BB0, + 0x0BBC, 0x0875, 0x0BCE, 0x0BDB, 0x0BE8, 0x0B45, + 0x0C49, 0x0C57, 0x0C65, 0x0B45, 0x0C73, 0x0C81, + 0x0C8F, 0x069E, 0x0753, 0x0814, 0x1000, 0x1200, + 0x1400, 0x8E00, 0x8100, 0x8970, 0x191C, 0x2ECE, + 0x2CCF, 0x16CD, 0x0E80, 0x16C9, 0x0000, 0x16CB, + 0x0100, 0x1F7E, 0x1F3C, 0x8100, 0x26C9, 0x02A0, + 0x0004, 0x029C, 0x0D36, 0x191E, 0x191C, 0x2ECE, + 0x2CCF, 0x16CD, 0x0280, 0x16C9, 0x0000, 0x16CB, + 0x0280, 0x1C80, 0x0080, 0x0280, 0x00C1, 0x0E1B, + 0x0085, 0x0000, 0x0089, 0x007F, 0x0082, 0x0F00, + 0x0083, 0x16B4, 0x1CE3, 0x8100, 0x26C9, 0x02A0, + 0x0004, 0x029C, 0x0D54, 0x8F00, 0x8A78, 0x8C68, + 0xF100, 0x1A3F, 0x84E3, 0x107E, 0xF2E3, 0xF2E7, + 0xF278, 0x6E68, 0xF132, 0x1A3F, 0x119E, 0x0D70, + 0x1C67, 0x84E3, 0x107E, 0xF2E3, 0xF2E7, 0xF278, + 0x6E68, 0xF132, 0x1A3F, 0x1C67, 0x84E3, 0x107E, + 0xF2E3, 0xF2E7, 0xF200, 0x6E00, 0x1B5E, 0x00E1, + 0x0E1B, 0x0080, 0x0280, 0x0083, 0x0F00, 0x0081, + 0x0000, 0x0082, 0x0140, 0x0089, 0xFFFF, 0x8900, + 0x8100, 0x8F00, 0x11A0, 0x0D90, 0x197F, 0x9930, + 0x1B1E, 0x1B3F, 0x7D29, 0x1B5F, 0x1B5D, 0x8E00, + 0x1FDB, 0x1F99, 0x2ECE, 0x2CCF, 0x16CD, 0x0E80, + 0x16C9, 0x0001, 0x16CB, 0x0100, 0x02BF, 0x0652, + 0x1C04, 0x029F, 0x0068, 0x8E00, 0x8100, 0x8970, + 0x191C, 0x2ECE, 0x2CCF, 0x16CD, 0x07C0, 0x16C9, + 0x0001, 0x16CB, 0x0500, 0x02BF, 0x0652, 0x8100, + 0x8970, 0x191C, 0x2ECE, 0x2CCF, 0x16CD, 0x07C0, + 0x16C9, 0x0000, 0x8900, 0x0D20, 0x2DCB, 0x4C00, + 0x1C80, 0x0080, 0x07C0, 0x0083, 0x0000, 0x1C43, + 0x0A00, 0x27C9, 0x03A0, 0x0004, 0x029C, 0x0DC3, + 0x2ECE, 0x2CCF, 0x16CD, 0x07D0, 0x16C9, 0x0000, + 0x16CB, 0x04E0, 0x8F00, 0x80F0, 0x80C0, 0x6A00, + 0x4800, 0x114F, 0x0DDE, 0x80F0, 0x80C0, 0x6B32, + 0x4922, 0x80F0, 0x80C0, 0x6A3A, 0x482A, 0x80F0, + 0x80C0, 0x6B32, 0x4922, 0x1B5F, 0x1B5D, 0x80F0, + 0x80C0, 0x6800, 0x7C00, 0x4A00, 0x114F, 0x0DF5, + 0x80F0, 0x80C0, 0x6932, 0x7D00, 0x4B22, 0x80F0, + 0x80C0, 0x683A, 0x7C00, 0x4A2A, 0x80F0, 0x80C0, + 0x6932, 0x7D00, 0x4B22, 0x1B5F, 0x1B5D, 0x1C04, + 0x029F, 0x0068, 0x8F00, 0x80F1, 0x80C1, 0x6A00, + 0x4800, 0x114F, 0x0E0E, 0x80F1, 0x80C1, 0x6B32, + 0x4922, 0x80F1, 0x80C1, 0x6A3A, 0x482A, 0x80F1, + 0x80C1, 0x6B32, 0x4922, 0x1B5F, 0x1B5D, 0x8E00, + 0x02DF, 0x8E00, 0x8100, 0x8970, 0x191C, 0x2ECE, + 0x2CCF, 0x16CD, 0x0400, 0x16C9, 0x0001, 0x16CB, + 0x0780, 0x02BF, 0x0652, 0x8100, 0x8970, 0x191C, + 0x2ECE, 0x2CCF, 0x16CD, 0x0A40, 0x16C9, 0x0001, + 0x16CB, 0x0280, 0x02BF, 0x0652, 0x8100, 0x8970, + 0x191C, 0x2ECE, 0x2CCF, 0x16CD, 0x0E48, 0x16C9, + 0x0000, 0x16CB, 0x0280, 0x0081, 0x0E48, 0x0082, + 0x0000, 0x0083, 0x0000, 0x02BF, 0x0652, 0x02BF, + 0x0E00, 0x8100, 0x8970, 0x191C, 0x2ECE, 0x2CCF, + 0x16CD, 0x0E48, 0x16C9, 0x0000, 0x16CB, 0x0280, + 0x0081, 0x0E48, 0x0082, 0x0140, 0x0083, 0x0140, + 0x02BF, 0x0652, 0x02BF, 0x0E00, 0x8100, 0x8970, + 0x191C, 0x2ECE, 0x2CCF, 0x16CD, 0x0E48, 0x16C9, + 0x0000, 0x16CB, 0x0280, 0x0081, 0x0E48, 0x0082, + 0x07C0, 0x0083, 0x07C0, 0x02BF, 0x0652, 0x02BF, + 0x0E00, 0x8100, 0x8970, 0x191C, 0x2ECE, 0x2CCF, + 0x16CD, 0x0E48, 0x16C9, 0x0000, 0x16CB, 0x0280, + 0x0081, 0x0E48, 0x0082, 0x0900, 0x0083, 0x0900, + 0x02BF, 0x0652, 0x02BF, 0x0E00, 0x029F, 0x0068, + 0x8E00, 0x16FC, 0xECC0, 0x1FCC, 0x1D9E, 0x2EFD, + 0x26FC, 0x02A0, 0x8000, 0x029C, 0x0E8E, 0x0000, + 0x0000, 0x0000, 0x02FF, 0x8E00, 0x00F0, 0x0E17, + 0x00FE, 0x0E18, 0x00FC, 0x0E19, 0x1FCC, 0x1D9E, + 0x16FC, 0xFEED, 0x2EFD, 0x26FC, 0x02A0, 0x8000, + 0x029C, 0x0EA3, 0x00D0, 0x0E17, 0x00DE, 0x0E18, + 0x00DC, 0x0E19, 0x0000, 0x0000, 0x0000, 0x0000, + 0x02FF, 0x8E00, 0x1DBC, 0x1DBE, 0x8100, 0x00DE, + 0x0BB7, 0x0601, 0x0295, 0x0EBF, 0x0E00, 0x00FE, + 0x0B87, 0x8100, 0x00DE, 0x0B88, 0x0601, 0x0295, + 0x0EC9, 0x8100, 0x1FCD, 0x1F8D, 0x02FF, 0x8100, + 0x00DC, 0x0BE1, 0x7600, 0x00FC, 0x0BE1, 0x8100, + 0x1FCD, 0x1F8D, 0x02FF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x02FF, 0x8E00, 0x1DBC, 0x1DBE, + 0x8100, 0x00DE, 0x0BB7, 0x0601, 0x0295, 0x0EE8, + 0x0E00, 0x00FE, 0x0B87, 0x1FCD, 0x1F8D, 0x02FF, + 0x8100, 0x00DE, 0x0B88, 0x0601, 0x0295, 0x0EFA, + 0x00DE, 0x0BDA, 0x2EDA, 0x00DE, 0x0BDB, 0x2EDB, + 0x00DE, 0x0BDC, 0x2EDC, 0x1FCD, 0x1F8D, 0x02FF, + 0x00DE, 0x0BDA, 0x2EDA, 0x26DB, 0x2EDB, 0x26DC, + 0x2EDC, 0x8100, 0x00DC, 0x0BE1, 0x7600, 0x00FC, + 0x0BE1, 0x8100, 0x1FCD, 0x1F8D, 0x02FF, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x02FF, 0x0000, + 0x0000, 0x0000, 0x0000, 0x02FF, 0x0F28, 0x0F2B, + 0x0F63, 0x0F66, 0x8E00, 0x8100, 0x8900, 0x02BF, + 0x0F69, 0x27FF, 0x009E, 0x0F16, 0x4C00, 0x1C7E, + 0x0313, 0x1C7F, 0x176F, 0x0021, 0x029F, 0x0030, + 0x0021, 0x8100, 0x8900, 0x02BF, 0x0F69, 0x24FF, + 0x02BF, 0x0F6F, 0x25FF, 0x02BF, 0x0F6F, 0x27FF, + 0x2ECE, 0x2CCF, 0x16C9, 0x0001, 0x2FCD, 0x2DCB, + 0x8100, 0x8900, 0x02BF, 0x0F69, 0x24FF, 0x1C9E, + 0x1CBC, 0x02BF, 0x0F6F, 0x25FF, 0x02BF, 0x0F6F, + 0x27FF, 0x1CDF, 0x1CFD, 0x8100, 0x02BF, 0x0F69, + 0x26FF, 0x1C1E, 0x8900, 0x02BF, 0x0F6F, 0x20FF, + 0x1F5F, 0x02BF, 0x0F69, 0x21FF, 0x02BF, 0x0F69, + 0x23FF, 0x26C9, 0x02A0, 0x0004, 0x029C, 0x0F5B, + 0x029F, 0x80B5, 0x0021, 0x029F, 0x8000, 0x0021, + 0x029F, 0x0045, 0x0021, 0x26FE, 0x02C0, 0x8000, + 0x029C, 0x0F69, 0x02DF, 0x27FE, 0x03C0, 0x8000, + 0x029C, 0x0F6F, 0x02DF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000 +}; diff --git a/src/dolphin/ax/__ax.h b/src/dolphin/ax/__ax.h new file mode 100644 index 0000000000..7e0c6e7112 --- /dev/null +++ b/src/dolphin/ax/__ax.h @@ -0,0 +1,84 @@ +#ifndef _DOLPHIN_AX_INTERNAL_H_ +#define _DOLPHIN_AX_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// AXAlloc +AXVPB* __AXGetStackHead(u32 priority); +void __AXServiceCallbackStack(void); +void __AXInitVoiceStacks(void); +void __AXAllocInit(void); +void __AXAllocQuit(void); +void __AXPushFreeStack(AXVPB* p); +AXVPB* __AXPopFreeStack(void); +void __AXPushCallbackStack(AXVPB* p); +AXVPB* __AXPopCallbackStack(void); +void __AXRemoveFromStack(AXVPB* p); +void __AXPushStackHead(AXVPB* p, u32 priority); +AXVPB* __AXPopStackFromBottom(u32 priority); + +// AXAux +void __AXAuxInit(void); +void __AXAuxQuit(void); +void __AXGetAuxAInput(u32* p); +void __AXGetAuxAOutput(u32* p); +void __AXGetAuxBInput(u32* p); +void __AXGetAuxBOutput(u32* p); +void __AXProcessAux(void); +void __AXGetAuxAInputDpl2(u32* p); +void __AXGetAuxAOutputDpl2R(u32* p); +void __AXGetAuxAOutputDpl2Ls(u32* p); +void __AXGetAuxAOutputDpl2Rs(u32* p); +void __AXGetAuxBForDPL2(u32* p); +void __AXGetAuxBOutputDPL2(u32* p); + +// AXCL +extern u32 __AXClMode; + +// AXComp +extern u16 __AXCompressorTable[3360]; + +u32 __AXGetCommandListCycles(void); +u32 __AXGetCommandListAddress(void); +void __AXWriteToCommandList(u16 data); +void __AXNextFrame(void* sbuffer, void* buffer); +void __AXClInit(void); +void __AXClQuit(void); + +// AXOut +void __AXOutNewFrame(u32 lessDspCycles); +void __AXOutAiCallback(void); +void __AXOutInitDSP(void); +void __AXOutInit(u32 outputBufferMode); +void __AXOutQuit(void); + +// AXProf +AXPROFILE* __AXGetCurrentProfile(void); + +// AXSPB +u32 __AXGetStudio(void); +void __AXDepopFade(s32* hostSum, s32* dspVolume, s16* dspDelta); +void __AXPrintStudio(void); +void __AXSPBInit(void); +void __AXSPBQuit(void); +void __AXDepopVoice(AXPB* p); + +// AXVPB +u32 __AXGetNumVoices(void); +void __AXServiceVPB(AXVPB *pvpb); +void __AXDumpVPB(AXVPB* pvpb); +void __AXSyncPBs(u32 lessDspCycles); +AXPB* __AXGetPBs(void); +void __AXSetPBDefault(AXVPB* p); +void __AXVPBInit(void); +void __AXVPBQuit(void); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_AX_INTERNAL_H_ diff --git a/src/dolphin/axart/axart.c b/src/dolphin/axart/axart.c new file mode 100644 index 0000000000..93c42abb3f --- /dev/null +++ b/src/dolphin/axart/axart.c @@ -0,0 +1,330 @@ +#include +#include +#include + +static AXART_SOUND* __AXARTSoundList; + +void AXARTInit(void) { + __AXARTSoundList = 0; + AXARTSet3DDistanceScale(40.0f); + AXARTSet3DDopplerScale(20.0f); +} + +void AXARTQuit(void) { + BOOL old; + AXART_SOUND* sound; + + old = OSDisableInterrupts(); + + for (sound = __AXARTSoundList; sound != 0; sound = (AXART_SOUND*)sound->next) { + MIXReleaseChannel(sound->axvpb); + } + + __AXARTSoundList = 0; + OSRestoreInterrupts(old); +} + +void AXARTServiceSounds(void) { + AXART_SOUND* sound; + + for (sound = __AXARTSoundList; sound != 0; sound = (AXART_SOUND*)sound->next) { + AXARTServiceSound(sound); + } +} + +void AXARTInitSound(AXART_SOUND* sound, AXVPB* voice, u32 sampleRate) { + ASSERTLINE(141, sound); + ASSERTLINE(142, voice); + + sound->articulators = NULL; + sound->axvpb = voice; + sound->sampleRate = sampleRate; +} + +void AXARTAddSound(AXART_SOUND* sound) { + AXART_ART* articulator; + AXVPB* axvpb; + s32 cents; + s32 atten; + s32 auxA; + s32 auxB; + f32 pitch; + u8 pan; + u8 span; + u8 src; + u16 itdL; + u16 itdR; + BOOL old; + + ASSERTLINE(173, sound); + ASSERTLINE(174, sound->axvpb); + + AXSetVoiceItdOn(sound->axvpb); + + cents = atten = auxA = auxB = 0; + pitch = sound->sampleRate / 32000.0f; + pan = 0x40; + span = 0x7F; + src = 1; + itdL = itdR = 0; + articulator = sound->articulators; + + while (articulator != 0) { + switch (articulator->type) { + case AXART_TYPE_3D: + AXART3DSound((AXART_3D*)articulator); + pan = ((AXART_3D*)articulator)->pan; + span = ((AXART_3D*)articulator)->span; + itdL = ((AXART_3D*)articulator)->itdL; + itdR = ((AXART_3D*)articulator)->itdR; + src = ((AXART_3D*)articulator)->src; + pitch += ((AXART_3D*)articulator)->pitch; + atten += ((AXART_3D*)articulator)->attenuation; + break; + case AXART_TYPE_PANNING: + pan = ((AXART_PANNING*)articulator)->pan; + span = ((AXART_PANNING*)articulator)->span; + break; + case AXART_TYPE_ITD: + itdL = ((AXART_ITD*)articulator)->itdL; + itdR = ((AXART_ITD*)articulator)->itdR; + break; + case AXART_TYPE_SRC: + src = ((AXART_SRC*)articulator)->src; + break; + case AXART_TYPE_PITCH: + cents += ((AXART_PITCH*)articulator)->cents; + break; + case AXART_TYPE_PITCH_ENV: + cents += ((AXART_PITCH_ENV*)articulator)->cents; + break; + case AXART_TYPE_PITCH_MOD: + cents += (s32)(((AXART_PITCH_MOD*)articulator)->cents * ((AXART_PITCH_MOD*)articulator)->lfo.output); + break; + case AXART_TYPE_VOLUME: + atten += ((AXART_VOLUME*)articulator)->attenuation; + break; + case AXART_TYPE_AUX_A_VOLUME: + auxA += ((AXART_AUXA_VOLUME*)articulator)->attenuation; + break; + case AXART_TYPE_AUX_B_VOLUME: + auxB += ((AXART_AUXB_VOLUME*)articulator)->attenuation; + break; + case AXART_TYPE_VOLUME_ENV: + atten += ((AXART_VOLUME_ENV*)articulator)->attenuation; + break; + case AXART_TYPE_AUX_A_VOLUME_ENV: + auxA += ((AXART_AUXA_VOLUME_ENV*)articulator)->attenuation; + break; + case AXART_TYPE_AUX_B_VOLUME_ENV: + auxB += ((AXART_AUXB_VOLUME_ENV*)articulator)->attenuation; + break; + case AXART_TYPE_VOLUME_MOD: + atten += (s32)(((AXART_VOLUME_MOD*)articulator)->attenuation * ((AXART_VOLUME_MOD*)articulator)->lfo.output); + break; + case AXART_TYPE_AUX_A_VOLUME_MOD: + auxA += (s32)(((AXART_AUXA_VOLUME_MOD*)articulator)->attenuation * ((AXART_AUXA_VOLUME_MOD*)articulator)->lfo.output); + break; + case AXART_TYPE_AUX_B_VOLUME_MOD: + auxB += (s32)(((AXART_AUXB_VOLUME_MOD*)articulator)->attenuation * ((AXART_AUXA_VOLUME_MOD*)articulator)->lfo.output); + break; + case AXART_TYPE_LPF: + AXARTLpf((AXART_LPF*)articulator, sound->axvpb); + break; + case AXART_TYPE_NONE: + default: + ASSERTMSGLINE(306, 0, "unknown articulator type!\n"); + } + + articulator = articulator->next; + } + + pitch *= AXARTCents(cents >> 0x10); + axvpb = sound->axvpb; + + AXSetVoiceSrcType(axvpb, src); + AXSetVoiceSrcRatio(axvpb, pitch); + AXSetVoiceItdTarget(axvpb, itdL, itdR); + MIXInitChannel(sound->axvpb, 0, atten >> 0x10, auxA >> 0x10, auxB >> 0x10, pan, span, 0); + old = OSDisableInterrupts(); + + if (__AXARTSoundList != 0) { + __AXARTSoundList->prev = sound; + sound->next = __AXARTSoundList; + } else { + sound->next = 0; + } + + sound->prev = 0; + __AXARTSoundList = sound; + OSRestoreInterrupts(old); +} + +void AXARTRemoveSound(AXART_SOUND* sound) { + BOOL old; + + ASSERTLINE(369, sound); + + old = OSDisableInterrupts(); + + if (sound == __AXARTSoundList) { + __AXARTSoundList = sound->next; + if (__AXARTSoundList != 0) { + __AXARTSoundList->prev = 0; + } + } else { + AXART_SOUND* prev = sound->prev; + AXART_SOUND* next = sound->next; + + prev->next = next; + if (next != 0) { + next->prev = prev; + } + } + + OSRestoreInterrupts(old); + MIXReleaseChannel(sound->axvpb); +} + +void AXARTInitLfo(AXART_LFO* lfo, f32* samples, u32 length, f32 delta) { + ASSERTLINE(417, samples); + ASSERTLINE(418, length); + + lfo->lfo = samples; + lfo->length = length; + lfo->delta = delta; + lfo->sampleIndex = 0; + lfo->counter = lfo->sample1 = lfo->sample = lfo->output = 0.0f; +} + +void AXARTInitArt3D(AXART_3D* articulator) { + ASSERTLINE(446, articulator); + + articulator->art.type = AXART_TYPE_3D; + articulator->hAngle = articulator->vAngle = articulator->dist = articulator->closingSpeed = articulator->update = 0.0f; + articulator->pan = 64; + articulator->span = 127; + articulator->src = 1; + articulator->itdL = articulator->itdR = 0; + articulator->pitch = 1.0f; + articulator->attenuation = -0x03C00000; +} + +void AXARTInitArtPanning(AXART_PANNING* articulator) { + ASSERTLINE(481, articulator); + + articulator->art.type = AXART_TYPE_PANNING; + articulator->pan = 64; + articulator->span = 127; +} + +void AXARTInitArtItd(AXART_ITD* articulator) { + ASSERTLINE(503, articulator); + + articulator->art.type = AXART_TYPE_ITD; + articulator->itdL = articulator->itdR = 0; +} + +void AXARTInitArtSrctype(AXART_SRC* articulator) { + ASSERTLINE(526, articulator); + + articulator->art.type = AXART_TYPE_SRC; + articulator->src = 1; +} + +void AXARTInitArtPitch(AXART_PITCH* articulator) { + ASSERTLINE(547, articulator); + + articulator->art.type = AXART_TYPE_PITCH; + articulator->cents = 0; +} + +void AXARTInitArtPitchEnv(AXART_PITCH_ENV* articulator) { + ASSERTLINE(569, articulator); + + articulator->art.type = AXART_TYPE_PITCH_ENV; + articulator->delta = articulator->target = articulator->cents = 0; +} + +void AXARTInitArtPitchMod(AXART_PITCH_MOD* articulator) { + ASSERTLINE(594, articulator); + + articulator->art.type = AXART_TYPE_PITCH_MOD; + articulator->cents = 0; + AXARTInitLfo(&articulator->lfo, AXARTSine, AXART_SINE_CNT, 0.0f); +} + +void AXARTInitArtVolume(AXART_VOLUME* articulator) { + ASSERTLINE(617, articulator); + + articulator->art.type = AXART_TYPE_VOLUME; + articulator->attenuation = 0; +} + +void AXARTInitArtAuxAVolume(AXART_AUXA_VOLUME* articulator) { + ASSERTLINE(639, articulator); + + articulator->art.type = AXART_TYPE_AUX_A_VOLUME; + articulator->attenuation = 0; +} + +void AXARTInitArtAuxBVolume(AXART_AUXB_VOLUME* articulator) { + ASSERTLINE(661, articulator); + + articulator->art.type = AXART_TYPE_AUX_B_VOLUME; + articulator->attenuation = 0; +} + +void AXARTInitArtVolumeEnv(AXART_VOLUME_ENV* articulator) { + ASSERTLINE(683, articulator); + + articulator->art.type = AXART_TYPE_VOLUME_ENV; + articulator->delta = articulator->target = articulator->attenuation = 0; +} + +void AXARTInitArtAuxAVolumeEnv(AXART_AUXA_VOLUME_ENV* articulator) { + ASSERTLINE(707, articulator); + + articulator->art.type = AXART_TYPE_AUX_A_VOLUME_ENV; + articulator->delta = articulator->target = articulator->attenuation = 0; +} + +void AXARTInitArtAuxBVolumeEnv(AXART_AUXB_VOLUME_ENV* articulator) { + ASSERTLINE(731, articulator); + + articulator->art.type = AXART_TYPE_AUX_B_VOLUME_ENV; + articulator->delta = articulator->target = articulator->attenuation = 0; +} + +void AXARTInitArtVolumeMod(AXART_VOLUME_MOD* articulator) { + ASSERTLINE(756, articulator); + + articulator->art.type = AXART_TYPE_VOLUME_MOD; + articulator->attenuation = 0; + AXARTInitLfo(&articulator->lfo, AXARTSine, AXART_SINE_CNT, 0.0f); +} + +void AXARTInitArtAuxAVolumeMod(AXART_AUXA_VOLUME_MOD* articulator) { + ASSERTLINE(781, articulator); + + articulator->art.type = AXART_TYPE_AUX_A_VOLUME_MOD; + articulator->attenuation = 0; + AXARTInitLfo(&articulator->lfo, AXARTSine, AXART_SINE_CNT, 0.0f); +} + +void AXARTInitArtAuxBVolumeMod(AXART_AUXB_VOLUME_MOD* articulator) { + ASSERTLINE(806, articulator); + + articulator->art.type = AXART_TYPE_AUX_B_VOLUME_MOD; + articulator->attenuation = 0; + AXARTInitLfo(&articulator->lfo, AXARTSine, AXART_SINE_CNT, 0.0f); +} + +void AXARTInitArtLpf(AXART_LPF* articulator) { + ASSERTLINE(830, articulator); + + articulator->art.type = AXART_TYPE_LPF; + articulator->initLPF = 1; + articulator->frequency = 0; + articulator->update = 1; +} diff --git a/src/dolphin/axart/axart3d.c b/src/dolphin/axart/axart3d.c new file mode 100644 index 0000000000..b2d90db404 --- /dev/null +++ b/src/dolphin/axart/axart3d.c @@ -0,0 +1,317 @@ +#include +#include +#include + +static u8 __AXART3DPan[360] = { + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, + 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, + 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F +}; + +static u8 __AXART3DSpan[360] = { + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78, + 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70, + 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, 0x68, + 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60, + 0x5F, 0x5E, 0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x58, + 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, + 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49, 0x48, + 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, + 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38, + 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, + 0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28, + 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, + 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, + 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, + 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 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, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, +}; + +static u8 __AXART3DPanDPL2[360] = { + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, + 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, + 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, + 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70, + 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, + 0x63, 0x62, 0x61, 0x60, 0x5F, 0x5E, 0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x58, + 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4F, 0x4E, 0x4D, 0x4C, + 0x4B, 0x4A, 0x49, 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, + 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, + 0x33, 0x32, 0x31, 0x30, 0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28, + 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1F, 0x1E, 0x1D, 0x1C, + 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, + 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, + 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F +}; + +static u8 __AXART3DItdL[360] = { + 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, 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, + 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, 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, + 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, 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, + 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, 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, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, + 0x1E, 0x1E, 0x1E, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, + 0x1D, 0x1D, 0x1D, 0x1D, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x1B, 0x1B, 0x1B, + 0x1B, 0x1B, 0x1B, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1A, 0x19, 0x19, 0x19, 0x19, 0x19, 0x18, 0x18, + 0x18, 0x18, 0x17, 0x17, 0x17, 0x16, 0x16, 0x15, + 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, + 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, + 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, +}; + +static u8 __AXART3DItdR[360] = { + 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x16, 0x17, 0x17, 0x17, 0x18, 0x18, + 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x19, 0x1A, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, + 0x1B, 0x1B, 0x1B, 0x1B, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1D, 0x1D, + 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1E, 0x1E, 0x1E, + 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, + 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, + 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, + 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, + 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, 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, + 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, 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, + 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, 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, + 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, 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, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static u8 __AXART3DSrc[360+1] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, +}; + +static f32 __AXART3DDopplerScale = 0; +static f32 __AXART3DDistanceScale = 0; + +void AXARTSet3DDopplerScale(f32 scale) { + ASSERTLINE(323, scale > 0); + __AXART3DDopplerScale = scale; +} + +void AXARTSet3DDistanceScale(f32 scale) { + ASSERTLINE(340, scale > 0); + __AXART3DDistanceScale = scale; +} + +void AXART3DSound(AXART_3D* articulator) { + u32 hAngle; + u32 vAngle; + + if (articulator->update) { + if (articulator->hAngle > 0) { + hAngle = (articulator->hAngle / 6.283185f) * 360.0f; + } else if (articulator->hAngle < 0) { + hAngle = 360.0f + (articulator->hAngle / 6.283185f) * 360.0f; + } else { + hAngle = 0; + } + + // @BUG? - hAngle missing a bounds assert + + if (articulator->vAngle > 0) { + vAngle = (articulator->vAngle / 6.283185f) * 360.0f; + } else if (articulator->vAngle < 0) { + vAngle = 360.0f + (articulator->vAngle / 6.283185f) * 360.0f; + } else { + vAngle = 0; + } + + ASSERTLINE(379, vAngle <= 360); + + articulator->update = 0; + + if (MIXGetSoundMode() == 3) { + articulator->pan = __AXART3DPanDPL2[hAngle]; + } else { + articulator->pan = __AXART3DPan[hAngle]; + } + + articulator->span = __AXART3DSpan[hAngle]; + articulator->itdL = __AXART3DItdL[hAngle]; + articulator->itdR = __AXART3DItdR[hAngle]; + articulator->src = __AXART3DSrc[vAngle]; + articulator->pitch = articulator->closingSpeed / __AXART3DDopplerScale; + articulator->attenuation = (articulator->dist / __AXART3DDistanceScale) * -3932160.0f; + } +} diff --git a/src/dolphin/axart/axartcents.c b/src/dolphin/axart/axartcents.c new file mode 100644 index 0000000000..6086bf4766 --- /dev/null +++ b/src/dolphin/axart/axartcents.c @@ -0,0 +1,280 @@ +#include +#include +#include + +static f32 __AXLFOCentsTable[100] = { + 1.000000f, + 1.000578f, + 1.001156f, + 1.001734f, + 1.002313f, + 1.002892f, + 1.003472f, + 1.004052f, + 1.004632f, + 1.005212f, + 1.005793f, + 1.006374f, + 1.006956f, + 1.007537f, + 1.008120f, + 1.008702f, + 1.009285f, + 1.009868f, + 1.010451f, + 1.011035f, + 1.011619f, + 1.012204f, + 1.012789f, + 1.013374f, + 1.013959f, + 1.014545f, + 1.015132f, + 1.015718f, + 1.016305f, + 1.016892f, + 1.017480f, + 1.018068f, + 1.018656f, + 1.019244f, + 1.019833f, + 1.020423f, + 1.021012f, + 1.021602f, + 1.022192f, + 1.022783f, + 1.023374f, + 1.023965f, + 1.024557f, + 1.025149f, + 1.025741f, + 1.026334f, + 1.026927f, + 1.027520f, + 1.028114f, + 1.028708f, + 1.029302f, + 1.029897f, + 1.030492f, + 1.031087f, + 1.031683f, + 1.032279f, + 1.032876f, + 1.033472f, + 1.034070f, + 1.034667f, + 1.035265f, + 1.035863f, + 1.036462f, + 1.037060f, + 1.037660f, + 1.038259f, + 1.038859f, + 1.039459f, + 1.040060f, + 1.040661f, + 1.041262f, + 1.041864f, + 1.042466f, + 1.043068f, + 1.043671f, + 1.044274f, + 1.044877f, + 1.045481f, + 1.046085f, + 1.046689f, + 1.047294f, + 1.047899f, + 1.048505f, + 1.049111f, + 1.049717f, + 1.050323f, + 1.050930f, + 1.051537f, + 1.052145f, + 1.052753f, + 1.053361f, + 1.053970f, + 1.054579f, + 1.055188f, + 1.055798f, + 1.056408f, + 1.057018f, + 1.057629f, + 1.058240f, + 1.058851f, +}; + +static f32 __AXLFOOctavesTableUp[12] = { + 1.0f, 2.0f, 4.0f, 8.0f, 16.0f, 32.0f, 64.0f, 128.0f, + 256.0f, 512.0f, 1024.0f, 2048.0f, +}; + +static f32 __AXLFOSemitonesTableUp[12] = { + 1.000000f, + 1.059463f, + 1.122462f, + 1.189207f, + 1.259921f, + 1.334840f, + 1.414214f, + 1.498307f, + 1.587401f, + 1.681793f, + 1.781797f, + 1.887749f, +}; + +static f32 __AXLFOSemitonesTableDown[128] = { + 1.000000f, + 0.943874f, + 0.890899f, + 0.840896f, + 0.793701f, + 0.749154f, + 0.707107f, + 0.667420f, + 0.629961f, + 0.594604f, + 0.561231f, + 0.529732f, + 0.500000f, + 0.471937f, + 0.445449f, + 0.420448f, + 0.396850f, + 0.374577f, + 0.353553f, + 0.333710f, + 0.314980f, + 0.297302f, + 0.280616f, + 0.264866f, + 0.250000f, + 0.235969f, + 0.222725f, + 0.210224f, + 0.198425f, + 0.187288f, + 0.176777f, + 0.166855f, + 0.157490f, + 0.148651f, + 0.140308f, + 0.132433f, + 0.125000f, + 0.117984f, + 0.111362f, + 0.105112f, + 0.099213f, + 0.093644f, + 0.088388f, + 0.083427f, + 0.078745f, + 0.074325f, + 0.070154f, + 0.066216f, + 0.062500f, + 0.058992f, + 0.055681f, + 0.052556f, + 0.049606f, + 0.046822f, + 0.044194f, + 0.041714f, + 0.039373f, + 0.037163f, + 0.035077f, + 0.033108f, + 0.031250f, + 0.029496f, + 0.027841f, + 0.026278f, + 0.024803f, + 0.023411f, + 0.022097f, + 0.020857f, + 0.019686f, + 0.018581f, + 0.017538f, + 0.016554f, + 0.015625f, + 0.014748f, + 0.013920f, + 0.013139f, + 0.012402f, + 0.011706f, + 0.011049f, + 0.010428f, + 0.009843f, + 0.009291f, + 0.008769f, + 0.008277f, + 0.007813f, + 0.007374f, + 0.006960f, + 0.006570f, + 0.006201f, + 0.005853f, + 0.005524f, + 0.005214f, + 0.004922f, + 0.004645f, + 0.004385f, + 0.004139f, + 0.003906f, + 0.003687f, + 0.003480f, + 0.003285f, + 0.003100f, + 0.002926f, + 0.002762f, + 0.002607f, + 0.002461f, + 0.002323f, + 0.002192f, + 0.002069f, + 0.001953f, + 0.001844f, + 0.001740f, + 0.001642f, + 0.001550f, + 0.001463f, + 0.001381f, + 0.001304f, + 0.001230f, + 0.001161f, + 0.001096f, + 0.001035f, + 0.000977f, + 0.000922f, + 0.000870f, + 0.000821f, + 0.000775f, + 0.000732f, + 0.000691f, + 0.000652f, +}; + +f32 AXARTCents(s32 cents) { + if (cents > 0) { + s32 octaves = cents / 1200; + s32 semitones = (cents % 1200) / 100; + cents %= 100; + + return __AXLFOOctavesTableUp[octaves] * __AXLFOSemitonesTableUp[semitones] * __AXLFOCentsTable[cents]; + } else if (cents < 0) { + s32 semitones = cents / 100; + cents %= 100; + + if (cents != 0) { + cents += 100; + semitones -= 1; + } + + semitones *= -1; + return __AXLFOSemitonesTableDown[semitones] * __AXLFOCentsTable[cents]; + } else { + return 1.0f; + } +} diff --git a/src/dolphin/axart/axartenv.c b/src/dolphin/axart/axartenv.c new file mode 100644 index 0000000000..278bfb5dfb --- /dev/null +++ b/src/dolphin/axart/axartenv.c @@ -0,0 +1,33 @@ +#include +#include +#include + +void AXARTPitchEnv(AXART_PITCH_ENV* articulator) { + if (articulator->cents != articulator->target) { + articulator->cents += articulator->delta; + if (articulator->delta > 0) { + if (articulator->cents > articulator->target) { + articulator->cents = articulator->target; + } + } else if (articulator->delta < 0) { + if (articulator->cents < articulator->target) { + articulator->cents = articulator->target; + } + } + } +} + +void AXARTVolumeEnv(AXART_VOLUME_ENV* articulator) { + if (articulator->attenuation != articulator->target) { + articulator->attenuation += articulator->delta; + if (articulator->delta > 0) { + if (articulator->attenuation > articulator->target) { + articulator->attenuation = articulator->target; + } + } else if (articulator->delta < 0) { + if (articulator->attenuation < articulator->target) { + articulator->attenuation = articulator->target; + } + } + } +} diff --git a/src/dolphin/axart/axartlfo.c b/src/dolphin/axart/axartlfo.c new file mode 100644 index 0000000000..58c9f45abd --- /dev/null +++ b/src/dolphin/axart/axartlfo.c @@ -0,0 +1,85 @@ +#include +#include +#include + +f32 AXARTSine[64] = { + 0.0f, 0.09802f, 0.19509f, 0.29028f, 0.38268f, 0.4714f, 0.55557f, 0.63439f, + 0.70711f, 0.77301f, 0.83147f, 0.88192f, 0.92388f, 0.95694f, 0.98079f, 0.99518f, + 1.0f, 0.99518f, 0.98079f, 0.95694f, 0.92388f, 0.88192f, 0.83147f, 0.77301f, + 0.70711f, 0.63439f, 0.55557f, 0.4714f, 0.38268f, 0.29028f, 0.19509f, 0.09802f, + 0.0f, -0.09802f, -0.19509f, -0.29028f, -0.38268f, -0.4714f, -0.55557f, -0.63439f, + -0.70711f, -0.77301f, -0.83147f, -0.88192f, -0.92388f, -0.95694f, -0.98079f, -0.99518f, + -1.0f, -0.99518f, -0.98079f, -0.95694f, -0.92388f, -0.88192f, -0.83147f, -0.77301f, + -0.70711f, -0.63439f, -0.55557f, -0.4714f, -0.38268f, -0.29028f, -0.19509f, -0.09802f, +}; + +static f32 AXARTSquare[64] = { + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, + -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, + -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, + -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, +}; + +static f32 AXARTSaw[64] = { + -1.0f, -0.96875f, -0.9375f, -0.90625f, -0.875f, -0.84375f, -0.8125f, -0.78125f, + -0.75f, -0.71875f, -0.6875f, -0.65625f, -0.625f, -0.59375f, -0.5625f, -0.53125f, + -0.5f, -0.46875f, -0.4375f, -0.40625f, -0.375f, -0.34375f, -0.3125f, -0.28125f, + -0.25f, -0.21875f, -0.1875f, -0.15625f, -0.125f, -0.09375f, -0.0625f, -0.03125f, + 0.0f, 0.03125f, 0.0625f, 0.09375f, 0.125f, 0.15625f, 0.1875f, 0.21875f, + 0.25f, 0.28125f, 0.3125f, 0.34375f, 0.375f, 0.40625f, 0.4375f, 0.46875f, + 0.5f, 0.53125f, 0.5625f, 0.59375f, 0.625f, 0.65625f, 0.6875f, 0.71875f, + 0.75f, 0.78125f, 0.8125f, 0.84375f, 0.875f, 0.90625f, 0.9375f, 0.96875f, +}; + +static f32 AXARTReverseSaw[64] = { + 1.0f, 0.96875f, 0.9375f, 0.90625f, 0.875f, 0.84375f, 0.8125f, 0.78125f, + 0.75f, 0.71875f, 0.6875f, 0.65625f, 0.625f, 0.59375f, 0.5625f, 0.53125f, + 0.5f, 0.46875f, 0.4375f, 0.40625f, 0.375f, 0.34375f, 0.3125f, 0.28125f, + 0.25f, 0.21875f, 0.1875f, 0.15625f, 0.125f, 0.09375f, 0.0625f, 0.03125f, + 0.0f, -0.03125f, -0.0625f, -0.09375f, -0.125f, -0.15625f, -0.1875f, -0.21875f, + -0.25f, -0.28125f, -0.3125f, -0.34375f, -0.375f, -0.40625f, -0.4375f, -0.46875f, + -0.5f, -0.53125f, -0.5625f, -0.59375f, -0.625f, -0.65625f, -0.6875f, -0.71875f, + -0.75f, -0.78125f, -0.8125f, -0.84375f, -0.875f, -0.90625f, -0.9375f, -0.96875f, +}; + +static f32 AXARTTriangle[64] = { + 0.0f, 0.0625f, 0.125f, 0.1875f, 0.25f, 0.3125f, 0.375f, 0.4375f, + 0.5f, 0.5625f, 0.625f, 0.6875f, 0.75f, 0.8125f, 0.875f, 0.9375f, + 1.0f, 0.9375f, 0.875f, 0.8125f, 0.75f, 0.6875f, 0.625f, 0.5625f, + 0.5f, 0.4375f, 0.375f, 0.3125f, 0.25f, 0.1875f, 0.125f, 0.0625f, + 0.0f, -0.0625f, -0.125f, -0.1875f, -0.25f, -0.3125f, -0.375f, -0.4375f, + -0.5f, -0.5625f, -0.625f, -0.6875f, -0.75f, -0.8125f, -0.875f, -0.9375f, + -1.0f, -0.9375f, -0.875f, -0.8125f, -0.75f, -0.6875f, -0.625f, -0.5625f, + -0.5f, -0.4375f, -0.375f, -0.3125f, -0.25f, -0.1875f, -0.125f, -0.0625f, +}; + +static f32 AXARTNoise[64] = { + -0.759363f, -0.805919f, -0.62015f, -0.78302f, 0.263439f, 0.467792f, -0.102506f, 0.700646f, + 0.852924f, 0.586413f, 0.32763f, 0.313143f, 0.66009f, 0.778686f, -0.698379f, -0.635841f, + -0.087795f, 0.577847f, 0.887183f, -0.325427f, -0.890347f, 0.111084f, -0.325035f, 0.43995f, + -0.62506f, -0.515152f, -0.299054f, -0.353217f, 0.512053f, 0.03931f, 0.869222f, -0.626512f, + 0.017653f, 0.891789f, -0.191419f, 0.411077f, 0.965653f, 0.134522f, -0.761372f, 0.543137f, + -0.887949f, 0.454729f, 0.860104f, -0.005229f, 0.28682f, -0.036344f, -0.976264f, -0.400756f, + 0.662483f, -0.44099f, -0.02479f, 0.066671f, -0.045242f, 0.150543f, 0.810762f, -0.35605f, + 0.364502f, 0.63764f, -0.212945f, 0.394563f, 0.496392f, 0.727584f, -0.564585f, 0.040292f, +}; + +void AXARTLfo(AXART_LFO* lfo) { + lfo->counter += lfo->delta; + + if (lfo->counter >= 1.0f) { + f32 lfoSamples = lfo->counter; + + lfo->counter -= lfoSamples; + lfo->sampleIndex += (u32)lfoSamples; + lfo->sampleIndex %= lfo->length; + lfo->sample1 = lfo->sample; + lfo->sample = lfo->lfo[lfo->sampleIndex]; + } + + lfo->output = lfo->sample1 - lfo->counter * (lfo->sample1 - lfo->sample); +} diff --git a/src/dolphin/axart/axartlpf.c b/src/dolphin/axart/axartlpf.c new file mode 100644 index 0000000000..c2aecfa9f8 --- /dev/null +++ b/src/dolphin/axart/axartlpf.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include "fake_tgmath.h" + +static u16 __coefs[48] = { + 0x6A09, 0x15F6, 0x6871, 0x178E, 0x6463, 0x1B9C, + 0x5DB3, 0x224C, 0x5618, 0x29E7, 0x4D7A, 0x3285, + 0x4367, 0x3C98, 0x3A5A, 0x45A5, 0x31C5, 0x4E3A, + 0x2924, 0x56DB, 0x2244, 0x5DBB, 0x1C50, 0x63AF, + 0x16C0, 0x693F, 0x1292, 0x6D6D, 0x0F18, 0x70E7, + 0x0BF5, 0x740A, 0x09A9, 0x7656, 0x07CA, 0x7835, + 0x0646, 0x79B9, 0x04ED, 0x7B12, 0x03F5, 0x7C0A, + 0x032D, 0x7CD2, 0x027D, 0x7D82, 0x01FE, 0x7E01 +}; + +void AXARTLpf(AXART_LPF* articulator, AXVPB* voice) { + u32 i; + ASSERTLINE(68, articulator); + ASSERTLINE(69, voice); + + if (articulator->update != 0) { + if (articulator->initLPF != 0) { + articulator->initLPF = 0; + voice->pb.lpf.on = 1; + voice->pb.lpf.yn1 = 0; + voice->sync |= 0x200000; + } else { + voice->sync |= 0x400000; + } + + i = articulator->frequency; + ASSERTMSGLINE(90, i < 24, "AXART: roll off frequency should be < 24"); + + i *= 2; + voice->pb.lpf.a0 = __coefs[i]; + + i++; + voice->pb.lpf.b0 = __coefs[i]; + articulator->update = 0; + } +} diff --git a/src/dolphin/axart/axartsound.c b/src/dolphin/axart/axartsound.c new file mode 100644 index 0000000000..732171dbb0 --- /dev/null +++ b/src/dolphin/axart/axartsound.c @@ -0,0 +1,122 @@ +#include +#include +#include + +void AXARTServiceSound(AXART_SOUND* sound) { + AXART_ART* articulator; + AXVPB* axvpb; + s32 cents; + s32 atten; + s32 auxA; + s32 auxB; + f32 pitch; + u8 pan; + u8 span; + u8 src; + u16 itdL; + u16 itdR; + + cents = atten = auxA = auxB = 0; + pitch = sound->sampleRate / 32000.0f; + pan = 64; + span = 127; + src = 1; + itdL = itdR = 0; + + for (articulator = sound->articulators; articulator != 0; articulator = (AXART_ART*)articulator->next) { + switch (articulator->type) { + case AXART_TYPE_3D: + AXART3DSound((AXART_3D*)articulator); + pan = ((AXART_3D*)articulator)->pan; + span = ((AXART_3D*)articulator)->span; + itdL = ((AXART_3D*)articulator)->itdL; + itdR = ((AXART_3D*)articulator)->itdR; + src = ((AXART_3D*)articulator)->src; + pitch += ((AXART_3D*)articulator)->pitch; + atten += ((AXART_3D*)articulator)->attenuation; + break; + case AXART_TYPE_PANNING: + pan = ((AXART_PANNING*)articulator)->pan; + span = ((AXART_PANNING*)articulator)->span; + break; + case AXART_TYPE_ITD: + itdL = ((AXART_ITD*)articulator)->itdL; + itdR = ((AXART_ITD*)articulator)->itdR; + break; + case AXART_TYPE_SRC: + src = ((AXART_SRC*)articulator)->src; + break; + case AXART_TYPE_PITCH: + cents += ((AXART_PITCH*)articulator)->cents; + break; + case AXART_TYPE_PITCH_ENV: + AXARTPitchEnv((AXART_PITCH_ENV*)articulator); + cents += ((AXART_PITCH_ENV*)articulator)->cents; + break; + case AXART_TYPE_PITCH_MOD: + AXARTLfo(&((AXART_PITCH_MOD*)articulator)->lfo); + cents += (s32)(((AXART_PITCH_MOD*)articulator)->cents * ((AXART_PITCH_MOD*)articulator)->lfo.output); + break; + case AXART_TYPE_VOLUME: + atten += ((AXART_VOLUME*)articulator)->attenuation; + break; + case AXART_TYPE_AUX_A_VOLUME: + auxA += ((AXART_AUXA_VOLUME*)articulator)->attenuation; + break; + case AXART_TYPE_AUX_B_VOLUME: + auxB += ((AXART_AUXB_VOLUME*)articulator)->attenuation; + break; + case AXART_TYPE_VOLUME_ENV: + AXARTVolumeEnv((AXART_VOLUME_ENV*)articulator); + atten += ((AXART_VOLUME_ENV*)articulator)->attenuation; + break; + case AXART_TYPE_AUX_A_VOLUME_ENV: + AXARTVolumeEnv((AXART_VOLUME_ENV*)articulator); + auxA += ((AXART_AUXA_VOLUME_ENV*)articulator)->attenuation; + break; + case AXART_TYPE_AUX_B_VOLUME_ENV: + AXARTVolumeEnv((AXART_VOLUME_ENV*)articulator); + auxB += ((AXART_AUXB_VOLUME_ENV*)articulator)->attenuation; + break; + case AXART_TYPE_VOLUME_MOD: + AXARTLfo(&((AXART_VOLUME_MOD*)articulator)->lfo); + atten += (s32)(((AXART_VOLUME_MOD*)articulator)->attenuation * ((AXART_VOLUME_MOD*)articulator)->lfo.output); + break; + case AXART_TYPE_AUX_A_VOLUME_MOD: + AXARTLfo(&((AXART_VOLUME_MOD*)articulator)->lfo); + auxA += (s32)(((AXART_AUXA_VOLUME_MOD*)articulator)->attenuation * ((AXART_AUXA_VOLUME_MOD*)articulator)->lfo.output); + break; + case AXART_TYPE_AUX_B_VOLUME_MOD: + AXARTLfo(&((AXART_VOLUME_MOD*)articulator)->lfo); + auxB += (s32)(((AXART_AUXB_VOLUME_MOD*)articulator)->attenuation * ((AXART_AUXB_VOLUME_MOD*)articulator)->lfo.output); + break; + case AXART_TYPE_LPF: + AXARTLpf((AXART_LPF*)articulator, sound->axvpb); + break; + default: +#ifdef DEBUG + OSPanic(__FILE__, 196, "unknown articulator type!\n"); +#endif + break; + } + } + + pitch *= AXARTCents(cents >> 16); + axvpb = sound->axvpb; + AXSetVoiceSrcType(axvpb, src); + AXSetVoiceSrcRatio(axvpb, pitch); + AXSetVoiceItdTarget(axvpb, itdL, itdR); + MIXSetInput(axvpb, atten >> 16); + MIXSetAuxA(axvpb, auxA >> 16); + MIXSetAuxB(axvpb, auxB >> 16); + MIXSetPan(axvpb, pan); + MIXSetSPan(axvpb, span); +} + +void AXARTAddArticulator(AXART_SOUND* sound, AXART_ART* articulator) { + ASSERTLINE(232, sound); + ASSERTLINE(233, articulator); + + articulator->next = sound->articulators; + sound->articulators = articulator; +} diff --git a/src/dolphin/axfx/__axfx.h b/src/dolphin/axfx/__axfx.h new file mode 100644 index 0000000000..17ac09f948 --- /dev/null +++ b/src/dolphin/axfx/__axfx.h @@ -0,0 +1,17 @@ +#ifndef _DOLPHIN_AX_INTERNAL_H_ +#define _DOLPHIN_AX_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern void* (*__AXFXAlloc)(u32); +extern void (*__AXFXFree)(void*); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dolphin/axfx/axfx.c b/src/dolphin/axfx/axfx.c new file mode 100644 index 0000000000..64c25fc063 --- /dev/null +++ b/src/dolphin/axfx/axfx.c @@ -0,0 +1,20 @@ +#include +#include + +static void* __AXFXAllocFunction(u32 bytes) { + return OSAlloc(bytes); +} + +static void __AXFXFreeFunction(void* p) { + OSFree(p); +} + +void* (*__AXFXAlloc)(u32) = __AXFXAllocFunction; +void (*__AXFXFree)(void*) = __AXFXFreeFunction; + +void AXFXSetHooks(void* (*alloc)(u32), void (*free)(void*)) { + ASSERTLINE(46, alloc && free); + + __AXFXAlloc = alloc; + __AXFXFree = free; +} diff --git a/src/dolphin/axfx/chorus.c b/src/dolphin/axfx/chorus.c new file mode 100644 index 0000000000..56bcffca8d --- /dev/null +++ b/src/dolphin/axfx/chorus.c @@ -0,0 +1,507 @@ +#include +#include +#include + +#include "__axfx.h" + +static f32 rsmpTab12khz[512] = { + 0.097503662109f, 0.802215576172f, 0.101593017578f, -0.000976562500f, 0.093505859375f, + 0.802032470703f, 0.105804443359f, -0.001037597656f, 0.089599609375f, 0.801696777344f, + 0.110107421875f, -0.001159667969f, 0.085784912109f, 0.801177978516f, 0.114471435547f, + -0.001281738281f, 0.082031250000f, 0.800476074219f, 0.118927001953f, -0.001403808594f, + 0.078369140625f, 0.799621582031f, 0.123474121094f, -0.001525878906f, 0.074798583984f, + 0.798614501953f, 0.128143310547f, -0.001647949219f, 0.071350097656f, 0.797424316406f, + 0.132873535156f, -0.001770019531f, 0.067962646484f, 0.796051025391f, 0.137695312500f, + -0.001922607422f, 0.064697265625f, 0.794525146484f, 0.142608642578f, -0.002044677734f, + 0.061492919922f, 0.792846679688f, 0.147613525391f, -0.002197265625f, 0.058349609375f, + 0.790985107422f, 0.152709960938f, -0.002319335938f, 0.055328369141f, 0.788940429688f, + 0.157897949219f, -0.002471923828f, 0.052368164062f, 0.786743164062f, 0.163177490234f, + -0.002655029297f, 0.049499511719f, 0.784423828125f, 0.168518066406f, -0.002807617188f, + 0.046722412109f, 0.781890869141f, 0.173980712891f, -0.002990722656f, 0.044006347656f, + 0.779205322266f, 0.179504394531f, -0.003143310547f, 0.041412353516f, 0.776367187500f, + 0.185119628906f, -0.003326416016f, 0.038879394531f, 0.773376464844f, 0.190826416016f, + -0.003509521484f, 0.036407470703f, 0.770233154297f, 0.196594238281f, -0.003692626953f, + 0.034027099609f, 0.766937255859f, 0.202484130859f, -0.003875732422f, 0.031738281250f, + 0.763488769531f, 0.208435058594f, -0.004058837891f, 0.029510498047f, 0.759857177734f, + 0.214447021484f, -0.004272460938f, 0.027374267578f, 0.756103515625f, 0.220550537109f, + -0.004455566406f, 0.025299072266f, 0.752197265625f, 0.226745605469f, -0.004669189453f, + 0.023315429688f, 0.748168945312f, 0.233001708984f, -0.004852294922f, 0.021392822266f, + 0.743988037109f, 0.239318847656f, -0.005065917969f, 0.019561767578f, 0.739654541016f, + 0.245727539062f, -0.005310058594f, 0.017791748047f, 0.735198974609f, 0.252197265625f, + -0.005523681641f, 0.016052246094f, 0.730590820312f, 0.258728027344f, -0.005706787109f, + 0.014404296875f, 0.725860595703f, 0.265350341797f, -0.005920410156f, 0.012817382812f, + 0.721008300781f, 0.272033691406f, -0.006164550781f, 0.011322021484f, 0.716003417969f, + 0.278778076172f, -0.006378173828f, 0.009887695312f, 0.710906982422f, 0.285583496094f, + -0.006561279297f, 0.008514404297f, 0.705657958984f, 0.292449951172f, -0.006774902344f, + 0.007202148438f, 0.700317382812f, 0.299346923828f, -0.007019042969f, 0.005920410156f, + 0.694854736328f, 0.306335449219f, -0.007232666016f, 0.004699707031f, 0.689270019531f, + 0.313385009766f, -0.007415771484f, 0.003570556641f, 0.683563232422f, 0.320465087891f, + -0.007629394531f, 0.002471923828f, 0.677734375000f, 0.327606201172f, -0.007873535156f, + 0.001434326172f, 0.671844482422f, 0.334777832031f, -0.008087158203f, 0.000457763672f, + 0.665832519531f, 0.341979980469f, -0.008270263672f, -0.000488281250f, 0.659729003906f, + 0.349243164062f, -0.008453369141f, -0.001342773438f, 0.653533935547f, 0.356567382812f, + -0.008636474609f, -0.002166748047f, 0.647216796875f, 0.363891601562f, -0.008850097656f, + -0.002960205078f, 0.640838623047f, 0.371276855469f, -0.009033203125f, -0.003692626953f, + 0.634338378906f, 0.378692626953f, -0.009216308594f, -0.004364013672f, 0.627777099609f, + 0.386138916016f, -0.009338378906f, -0.004974365234f, 0.621154785156f, 0.393615722656f, + -0.009490966797f, -0.005584716797f, 0.614440917969f, 0.401092529297f, -0.009643554688f, + -0.006134033203f, 0.607635498047f, 0.408599853516f, -0.009796142578f, -0.006652832031f, + 0.600769042969f, 0.416107177734f, -0.009918212891f, -0.007141113281f, 0.593841552734f, + 0.423645019531f, -0.010009765625f, -0.007568359375f, 0.586853027344f, 0.431213378906f, + -0.010131835938f, -0.007965087891f, 0.579772949219f, 0.438751220703f, -0.010223388672f, + -0.008331298828f, 0.572662353516f, 0.446319580078f, -0.010284423828f, -0.008666992188f, + 0.565521240234f, 0.453887939453f, -0.010345458984f, -0.008972167969f, 0.558319091797f, + 0.461456298828f, -0.010406494141f, -0.009216308594f, 0.551055908203f, 0.469024658203f, + -0.010406494141f, -0.009460449219f, 0.543731689453f, 0.476593017578f, -0.010406494141f, + -0.009674072266f, 0.536407470703f, 0.484130859375f, -0.010375976562f, -0.009857177734f, + 0.529022216797f, 0.491668701172f, -0.010375976562f, -0.010009765625f, 0.521606445312f, + 0.499176025391f, -0.010314941406f, -0.010131835938f, 0.514160156250f, 0.506683349609f, + -0.010253906250f, -0.010253906250f, 0.506683349609f, 0.514160156250f, -0.010131835938f, + -0.010314941406f, 0.499176025391f, 0.521606445312f, -0.010009765625f, -0.010375976562f, + 0.491668701172f, 0.529022216797f, -0.009857177734f, -0.010375976562f, 0.484130859375f, + 0.536407470703f, -0.009674072266f, -0.010406494141f, 0.476593017578f, 0.543731689453f, + -0.009460449219f, -0.010406494141f, 0.469024658203f, 0.551055908203f, -0.009216308594f, + -0.010406494141f, 0.461456298828f, 0.558319091797f, -0.008972167969f, -0.010345458984f, + 0.453887939453f, 0.565521240234f, -0.008666992188f, -0.010284423828f, 0.446319580078f, + 0.572662353516f, -0.008331298828f, -0.010223388672f, 0.438751220703f, 0.579772949219f, + -0.007965087891f, -0.010131835938f, 0.431213378906f, 0.586853027344f, -0.007568359375f, + -0.010009765625f, 0.423645019531f, 0.593841552734f, -0.007141113281f, -0.009918212891f, + 0.416107177734f, 0.600769042969f, -0.006652832031f, -0.009796142578f, 0.408599853516f, + 0.607635498047f, -0.006134033203f, -0.009643554688f, 0.401092529297f, 0.614440917969f, + -0.005584716797f, -0.009490966797f, 0.393615722656f, 0.621154785156f, -0.004974365234f, + -0.009338378906f, 0.386138916016f, 0.627777099609f, -0.004364013672f, -0.009216308594f, + 0.378692626953f, 0.634338378906f, -0.003692626953f, -0.009033203125f, 0.371276855469f, + 0.640838623047f, -0.002960205078f, -0.008850097656f, 0.363891601562f, 0.647216796875f, + -0.002166748047f, -0.008636474609f, 0.356567382812f, 0.653533935547f, -0.001342773438f, + -0.008453369141f, 0.349243164062f, 0.659729003906f, -0.000488281250f, -0.008270263672f, + 0.341979980469f, 0.665832519531f, 0.000457763672f, -0.008087158203f, 0.334777832031f, + 0.671844482422f, 0.001434326172f, -0.007873535156f, 0.327606201172f, 0.677734375000f, + 0.002471923828f, -0.007629394531f, 0.320465087891f, 0.683563232422f, 0.003570556641f, + -0.007415771484f, 0.313385009766f, 0.689270019531f, 0.004699707031f, -0.007232666016f, + 0.306335449219f, 0.694854736328f, 0.005920410156f, -0.007019042969f, 0.299346923828f, + 0.700317382812f, 0.007202148438f, -0.006774902344f, 0.292449951172f, 0.705657958984f, + 0.008514404297f, -0.006561279297f, 0.285583496094f, 0.710906982422f, 0.009887695312f, + -0.006378173828f, 0.278778076172f, 0.716003417969f, 0.011322021484f, -0.006164550781f, + 0.272033691406f, 0.721008300781f, 0.012817382812f, -0.005920410156f, 0.265350341797f, + 0.725860595703f, 0.014404296875f, -0.005706787109f, 0.258728027344f, 0.730590820312f, + 0.016052246094f, -0.005523681641f, 0.252197265625f, 0.735198974609f, 0.017791748047f, + -0.005310058594f, 0.245727539062f, 0.739654541016f, 0.019561767578f, -0.005065917969f, + 0.239318847656f, 0.743988037109f, 0.021392822266f, -0.004852294922f, 0.233001708984f, + 0.748168945312f, 0.023315429688f, -0.004669189453f, 0.226745605469f, 0.752197265625f, + 0.025299072266f, -0.004455566406f, 0.220550537109f, 0.756103515625f, 0.027374267578f, + -0.004272460938f, 0.214447021484f, 0.759857177734f, 0.029510498047f, -0.004058837891f, + 0.208435058594f, 0.763488769531f, 0.031738281250f, -0.003875732422f, 0.202484130859f, + 0.766937255859f, 0.034027099609f, -0.003692626953f, 0.196594238281f, 0.770233154297f, + 0.036407470703f, -0.003509521484f, 0.190826416016f, 0.773376464844f, 0.038879394531f, + -0.003326416016f, 0.185119628906f, 0.776367187500f, 0.041412353516f, -0.003143310547f, + 0.179504394531f, 0.779205322266f, 0.044006347656f, -0.002990722656f, 0.173980712891f, + 0.781890869141f, 0.046722412109f, -0.002807617188f, 0.168518066406f, 0.784423828125f, + 0.049499511719f, -0.002655029297f, 0.163177490234f, 0.786743164062f, 0.052368164062f, + -0.002471923828f, 0.157897949219f, 0.788940429688f, 0.055328369141f, -0.002319335938f, + 0.152709960938f, 0.790985107422f, 0.058349609375f, -0.002197265625f, 0.147613525391f, + 0.792846679688f, 0.061492919922f, -0.002044677734f, 0.142608642578f, 0.794525146484f, + 0.064697265625f, -0.001922607422f, 0.137695312500f, 0.796051025391f, 0.067962646484f, + -0.001770019531f, 0.132873535156f, 0.797424316406f, 0.071350097656f, -0.001647949219f, + 0.128143310547f, 0.798614501953f, 0.074798583984f, -0.001525878906f, 0.123474121094f, + 0.799621582031f, 0.078369140625f, -0.001403808594f, 0.118927001953f, 0.800476074219f, + 0.082031250000f, -0.001281738281f, 0.114471435547f, 0.801177978516f, 0.085784912109f, + -0.001159667969f, 0.110107421875f, 0.801696777344f, 0.089599609375f, -0.001037597656f, + 0.105804443359f, 0.802032470703f, 0.093505859375f, -0.000976562500f, 0.101593017578f, + 0.802215576172f, 0.097503662109f, +}; + +const static double i2fMagic = 4503601774854144.0; + +// prototypes +static void do_src1(AXFX_CHORUS_SRCINFO* src); +static void do_src2(AXFX_CHORUS_SRCINFO* src); + +asm static void do_src1(register AXFX_CHORUS_SRCINFO* src) { + nofralloc + stwu r1, -64(r1) + stmw r26, 40(r1) + lwz r4, AXFX_CHORUS_SRCINFO.posLo(src) + lwz r5, AXFX_CHORUS_SRCINFO.posHi(src) + lwz r6, AXFX_CHORUS_SRCINFO.pitchLo(src) + lwz r8, AXFX_CHORUS_SRCINFO.trigger(src) + lwz r7, AXFX_CHORUS_SRCINFO.target(src) + lwz r31, AXFX_CHORUS_SRCINFO.smpBase(src) + lwz r30, AXFX_CHORUS_SRCINFO.dest(src) + lwz r9, AXFX_CHORUS_SRCINFO.old(src) + lis r10, 0x4330 + stw r10, 8(r1) + stw r10, 16(r1) + stw r10, 24(r1) + stw r10, 32(r1) + lis r10, i2fMagic@ha + lfd f9, i2fMagic@l(r10) + slwi r10, r5, 2 + lwz r11, 0(r9) + lwz r29, 4(r9) + lwz r28, 8(r9) + lwzx r27, r31, r10 + xoris r11, r11, 0x8000 + xoris r29, r29, 0x8000 + stw r11, 12(r1) + xoris r28, r28, 0x8000 + stw r29, 20(r1) + xoris r27, r27, 0x8000 + stw r28, 28(r1) + lfd f1, 8(r1) + stw r27, 36(r1) + lfd f2, 16(r1) + fsubs f1, f1, f9 + lfd f3, 24(r1) + fsubs f2, f2, f9 + lfd f4, 32(r1) + fsubs f3, f3, f9 + fsubs f4, f4, f9 + li r26, -4 + lis r12, rsmpTab12khz@ha + addi r12, r12, rsmpTab12khz@l + li r9, 160 + mtctr r9 +L_000000AC: + rlwinm r10, r4, 7, 21, 27 + addc r4, r4, r6 + add r10, r10, r12 + mcrxr cr0 + lfs f5, 0(r10) + beq L_000000F4 + lfs f6, 4(r10) + fmuls f10, f1, f5 + lfs f7, 8(r10) + fmadds f10, f2, f6, f10 + lfs f8, 12(r10) + fmadds f10, f3, f7, f10 + addi r30, r30, 4 + fmadds f10, f4, f8, f10 + fctiwz f10, f10 + stfiwx f10, r26, r30 + bdnz L_000000AC + b L_00000160 +L_000000F4: + addi r5, r5, 1 + lfs f6, 4(r10) + fmuls f10, f1, f5 + cmpw r5, r8 + fmr f1, f2 + lfs f7, 8(r10) + fmadds f10, f2, f6, f10 + fmr f2, f3 + lfs f8, 12(r10) + fmadds f10, f3, f7, f10 + addi r30, r30, 4 + fmr f3, f4 + bne+ L_0000012C + mr r5, r7 +L_0000012C: + fmadds f10, f4, f8, f10 + slwi r9, r5, 2 + bdz L_00000158 + lwzx r10, r9, r31 + fctiwz f10, f10 + xoris r10, r10, 0x8000 + stw r10, 12(r1) + stfiwx f10, r26, r30 + lfd f4, 8(r1) + fsubs f4, f4, f9 + b L_000000AC +L_00000158: + fctiwz f10, f10 + stfiwx f10, r26, r30 +L_00000160: + lwz r9, AXFX_CHORUS_SRCINFO.old(src) + fctiwz f1, f1 + fctiwz f2, f2 + fctiwz f3, f3 + stfiwx f1, r0, r9 + addi r10, r9, 4 + stfiwx f2, r0, r10 + addi r10, r9, 8 + stfiwx f3, r0, r10 + stw r4, AXFX_CHORUS_SRCINFO.posLo(src) + stw r5, AXFX_CHORUS_SRCINFO.posHi(src) + lmw r26, 40(r1) + addi r1, r1, 64 + blr +} + +asm static void do_src2(register AXFX_CHORUS_SRCINFO* src) { + nofralloc + stwu r1, -64(r1) + stmw r26, 40(r1) + lwz r4, AXFX_CHORUS_SRCINFO.posLo(src) + lwz r5, AXFX_CHORUS_SRCINFO.posHi(src) + lwz r6, AXFX_CHORUS_SRCINFO.pitchLo(src) + lwz r8, AXFX_CHORUS_SRCINFO.trigger(src) + lwz r7, AXFX_CHORUS_SRCINFO.target(src) + lwz r31, AXFX_CHORUS_SRCINFO.smpBase(src) + lwz r30, AXFX_CHORUS_SRCINFO.dest(src) + lwz r9, AXFX_CHORUS_SRCINFO.old(src) + lis r10, 0x4330 + stw r10, 8(r1) + stw r10, 16(r1) + stw r10, 24(r1) + stw r10, 32(r1) + lis r10, i2fMagic@ha + lfd f9, i2fMagic@l(r10) + slwi r10, r5, 2 + lwz r11, 0(r9) + lwz r29, 4(r9) + lwz r28, 8(r9) + lwzx r27, r31, r10 + xoris r11, r11, 0x8000 + xoris r29, r29, 0x8000 + stw r11, 12(r1) + xoris r28, r28, 0x8000 + stw r29, 20(r1) + xoris r27, r27, 0x8000 + stw r28, 28(r1) + lfd f1, 8(r1) + stw r27, 36(r1) + lfd f2, 16(r1) + fsubs f1, f1, f9 + lfd f3, 24(r1) + fsubs f2, f2, f9 + lfd f4, 32(r1) + fsubs f3, f3, f9 + fsubs f4, f4, f9 + li r26, -4 + lis r12, rsmpTab12khz@ha + addi r12, r12, rsmpTab12khz@l + li r9, 160 + mtctr r9 +L_00000244: + rlwinm r10, r4, 7, 21, 27 + addc r4, r4, r6 + add r10, r10, r12 + mcrxr cr0 + addi r5, r5, 1 + lfs f5, 0(r10) + beq L_000002C0 + lfs f6, 4(r10) + fmuls f10, f1, f5 + cmpw r5, r8 + fmr f1, f2 + lfs f7, 8(r10) + fmadds f10, f2, f6, f10 + fmr f2, f3 + lfs f8, 12(r10) + fmadds f10, f3, f7, f10 + addi r30, r30, 4 + fmr f3, f4 + bne+ L_00000294 + mr r5, r7 +L_00000294: + fmadds f10, f4, f8, f10 + slwi r9, r5, 2 + bdz L_00000344 + lwzx r10, r9, r31 + fctiwz f10, f10 + xoris r10, r10, 0x8000 + stw r10, 12(r1) + stfiwx f10, r26, r30 + lfd f4, 8(r1) + fsubs f4, f4, f9 + b L_00000244 +L_000002C0: + cmpw r5, r8 + lfs f6, 4(r10) + bne+ L_000002D0 + mr r5, r7 +L_000002D0: + slwi r11, r5, 2 + addi r5, r5, 1 + lwzx r29, r11, r31 + fmuls f10, f1, f5 + cmpw r5, r8 + xoris r29, r29, 0x8000 + fmr f1, f3 + lfs f7, 8(r10) + stw r29, 12(r1) + fmadds f10, f2, f6, f10 + lfs f8, 12(r10) + fmadds f10, f3, f7, f10 + lfd f3, 8(r1) + fmr f2, f4 + addi r30, r30, 4 + fsubs f3, f3, f9 + bne+ L_00000318 + mr r5, r7 +L_00000318: + fmadds f10, f4, f8, f10 + slwi r9, r5, 2 + bdz L_00000344 + lwzx r10, r9, r31 + fctiwz f10, f10 + xoris r10, r10, 0x8000 + stw r10, 12(r1) + stfiwx f10, r26, r30 + lfd f4, 8(r1) + fsubs f4, f4, f9 + b L_00000244 +L_00000344: + fctiwz f10, f10 + stfiwx f10, r26, r30 + lwz r9, AXFX_CHORUS_SRCINFO.old(src) + fctiwz f1, f1 + fctiwz f2, f2 + fctiwz f3, f3 + stfiwx f1, r0, r9 + addi r10, r9, 4 + stfiwx f2, r0, r10 + addi r10, r9, 8 + stfiwx f3, r0, r10 + stw r4, AXFX_CHORUS_SRCINFO.posLo(src) + stw r5, AXFX_CHORUS_SRCINFO.posHi(src) + lmw r26, 40(r1) + addi r1, r1, 64 + blr +} + +int AXFXChorusInit(AXFX_CHORUS* c) { + s32* left; + s32* right; + s32* sur; + u32 i; + BOOL old; + + ASSERTMSGLINE(1074, c->baseDelay >= 5 && c->baseDelay <= 15 && c->variation >= 0 && c->variation <= 5 && c->period >= 500 && c->period <= 10000, "The value of specified parameter is out of range."); + + if (c->baseDelay < 5 || c->baseDelay > 15 || c->variation < 0 || c->variation > 5 || c->period < 500 || c->period > 10000) { + return 0; + } + + old = OSDisableInterrupts(); + c->work.lastLeft[0] = __AXFXAlloc(0x1680); + ASSERTMSGLINE(0x442, c->work.lastLeft[0], "Can't allocate the memory."); + + if (c->work.lastLeft[0] != NULL) { + c->work.lastRight[0] = (void*)(c->work.lastLeft[0] + 0x1E0); + c->work.lastSur[0] = (void*)(c->work.lastRight[0] + 0x1E0); + + for (i = 1; i < 3; i++) { + c->work.lastLeft[i] = (void*)&c->work.lastLeft[0][i * 0xA0]; + c->work.lastRight[i] = (void*)&c->work.lastRight[0][i * 0xA0]; + c->work.lastSur[i] = (void*)&c->work.lastSur[0][i * 0xA0]; + } + + left = c->work.lastLeft[0]; + right = c->work.lastRight[0]; + sur = c->work.lastSur[0]; + + for (i = 0; i < 0x140; i++) { + *left++ = 0; + *right++ = 0; + *sur++ = 0; + } + + c->work.currentLast = 1; + c->work.oldLeft[0] = c->work.oldLeft[1] = c->work.oldLeft[2] = c->work.oldLeft[3] = 0; + c->work.oldRight[0] = c->work.oldRight[1] = c->work.oldRight[2] = c->work.oldRight[3] = 0; + c->work.oldSur[0] = c->work.oldSur[1] = c->work.oldSur[2] = c->work.oldSur[3] = 0; + c->work.src.trigger = 0x1E0; + c->work.src.target = 0; + OSRestoreInterrupts(old); + return AXFXChorusSettings(c); + } + + OSRestoreInterrupts(old); + return 0; +} + +int AXFXChorusShutdown(AXFX_CHORUS* c) { + BOOL old; + + old = OSDisableInterrupts(); + __AXFXFree(c->work.lastLeft[0]); + OSRestoreInterrupts(old); + return 1; +} + +int AXFXChorusSettings(AXFX_CHORUS* c) { + BOOL old; + + ASSERTMSGLINE(1159, c->baseDelay >= 5 && c->baseDelay <= 15 && c->variation >= 0 && c->variation <= 5 && c->period >= 500 && c->period <= 10000, "The value of specified parameter is out of range."); + if (c->baseDelay < 5 || c->baseDelay > 15 || c->variation < 0 || c->variation > 5 || c->period < 500 || c->period > 10000) { + return 0; + } + + old = OSDisableInterrupts(); + c->work.currentPosHi = 0x140 - ((c->baseDelay - 5) << 5); + c->work.currentPosLo = 0; + c->work.currentPosHi = (c->work.currentPosHi + ((c->work.currentLast - 1) * 0xA0/1)) % 480; + c->work.pitchOffsetPeriod = ((c->period / 5) + 1) & ~(1); + c->work.pitchOffsetPeriodCount = c->work.pitchOffsetPeriod >> 1; + c->work.pitchOffset = (c->variation << 0x10) / (c->work.pitchOffsetPeriod * 5); + OSRestoreInterrupts(old); + return 1; +} + +void AXFXChorusCallback(AXFX_BUFFERUPDATE* bufferUpdate, AXFX_CHORUS* chorus) { + s32* leftD; + s32* rightD; + s32* surD; + s32* leftS; + s32* rightS; + s32* surS; + u32 i; + u8 nextCurrentLast; + + nextCurrentLast = (chorus->work.currentLast + 1) % 3; + leftD = chorus->work.lastLeft[nextCurrentLast]; + rightD = chorus->work.lastRight[nextCurrentLast]; + surD = chorus->work.lastSur[nextCurrentLast]; + leftS = bufferUpdate->left; + rightS = bufferUpdate->right; + surS = bufferUpdate->surround; + + for (i = 0; i < 0xA0; i++) { + *leftD++ = *leftS++; + *rightD++ = *rightS++; + *surD++ = *surS++; + } + + chorus->work.src.pitchHi = (chorus->work.pitchOffset >> 0x10) + 1; + chorus->work.src.pitchLo = (chorus->work.pitchOffset & 0xFFFF) << 0x10; + + if (--chorus->work.pitchOffsetPeriodCount == 0) { + chorus->work.pitchOffsetPeriodCount = chorus->work.pitchOffsetPeriod; + chorus->work.pitchOffset = -chorus->work.pitchOffset; + } + + for (i = 0; i < 3; i++) { + chorus->work.src.posHi = chorus->work.currentPosHi; + chorus->work.src.posLo = chorus->work.currentPosLo; + switch (i) { + case 0: + chorus->work.src.smpBase = chorus->work.lastLeft[0]; + chorus->work.src.dest = bufferUpdate->left; + chorus->work.src.old = &chorus->work.oldLeft[0]; + break; + case 1: + chorus->work.src.smpBase = chorus->work.lastRight[0]; + chorus->work.src.dest = bufferUpdate->right; + chorus->work.src.old = &chorus->work.oldRight[0]; + break; + case 2: + chorus->work.src.smpBase = chorus->work.lastSur[0]; + chorus->work.src.dest = bufferUpdate->surround; + chorus->work.src.old = &chorus->work.oldSur[0]; + break; + } + switch(chorus->work.src.pitchHi) { + case 0: + do_src1(&chorus->work.src); + break; + case 1: + do_src2(&chorus->work.src); + break; + } + } + + chorus->work.currentPosHi = (chorus->work.src.posHi % 480); + chorus->work.currentPosLo = chorus->work.src.posLo; + chorus->work.currentLast = nextCurrentLast; +} diff --git a/src/dolphin/axfx/delay.c b/src/dolphin/axfx/delay.c new file mode 100644 index 0000000000..5c26e59c33 --- /dev/null +++ b/src/dolphin/axfx/delay.c @@ -0,0 +1,148 @@ +#include +#include +#include + +#include "__axfx.h" + +void AXFXDelayCallback(AXFX_BUFFERUPDATE* bufferUpdate, AXFX_DELAY* delay) { + s32 l; + s32 r; + s32 s; + s32* lBuf; + s32* rBuf; + s32* sBuf; + u32 i; + s32* left; + s32* right; + s32* sur; + + left = bufferUpdate->left; + right = bufferUpdate->right; + sur = bufferUpdate->surround; + lBuf = delay->left + (delay->currentPos[0] * 0xA0); + rBuf = delay->right + (delay->currentPos[1] * 0xA0); + sBuf = delay->sur + (delay->currentPos[2] * 0xA0); + + for (i = 0; i < 160; i++) { + l = *lBuf; + r = *rBuf; + s = *sBuf; + *lBuf++ = *left + ((s32)(l* delay->currentFeedback[0]) >> 7); + *rBuf++ = *right + ((s32)(r* delay->currentFeedback[1]) >> 7); + *sBuf++ = *sur + ((s32)(s* delay->currentFeedback[2]) >> 7); + *left++ = (s32)(l* delay->currentOutput[0]) >> 7; + *right++ = (s32)(r* delay->currentOutput[1]) >> 7; + *sur++ = (s32)(s* delay->currentOutput[2]) >> 7; + } + + delay->currentPos[0] = (s32) ((delay->currentPos[0] + 1) % delay->currentSize[0]); + delay->currentPos[1] = (s32) ((delay->currentPos[1] + 1) % delay->currentSize[1]); + delay->currentPos[2] = (s32) ((delay->currentPos[2] + 1) % delay->currentSize[2]); +} + +int AXFXDelaySettings(AXFX_DELAY* delay) { + u32 i; + s32* l; + s32* r; + s32* s; + BOOL old; + + ASSERTMSGLINE(67, delay->delay[0] >= 10 && delay->delay[0] <= 5000 && + delay->delay[1] >= 10 && delay->delay[1] <= 5000 && + delay->delay[2] >= 10 && delay->delay[2] <= 5000 && + delay->feedback[0] >= 0 && delay->feedback[0] <= 100 && + delay->feedback[1] >= 0 && delay->feedback[1] <= 100 && + delay->feedback[2] >= 0 && delay->feedback[2] <= 100 && + delay->output[0] >= 0 && delay->output[0] <= 100 && + delay->output[1] >= 0 && delay->output[1] <= 100 && + delay->output[2] >= 0 && delay->output[2] <= 100, + "The value of specified parameter is out of range."); + + if (delay->delay[0] < 10 || delay->delay[0] > 5000 || + delay->delay[1] < 10 || delay->delay[1] > 5000 || + delay->delay[2] < 10 || delay->delay[2] > 5000 || + delay->feedback[0] < 0 || delay->feedback[0] > 100 || + delay->feedback[1] < 0 || delay->feedback[1] > 100 || + delay->feedback[2] < 0 || delay->feedback[2] > 100 || + delay->output[0] < 0 || delay->output[0] > 100 || + delay->output[1] < 0 || delay->output[1] > 100 || + delay->output[2] < 0 || delay->output[2] > 100) + { + return 0; + } + + AXFXDelayShutdown(delay); + old = OSDisableInterrupts(); + + for (i = 0; i < 3; i++) { + delay->currentSize[i] = (((delay->delay[i] - 5) << 5) + 0x9F) / 160U; + delay->currentPos[i] = 0; + delay->currentFeedback[i] = (delay->feedback[i] << 7) / 100U; + delay->currentOutput[i] = (delay->output[i] << 7) / 100U; + } + + delay->left = __AXFXAlloc(delay->currentSize[0] * 0xA0 * 4); + delay->right = __AXFXAlloc(delay->currentSize[1] * 0xA0 * 4); + delay->sur = __AXFXAlloc(delay->currentSize[2] * 0xA0 * 4); + + ASSERTMSGLINE(98, delay->left && delay->right && delay->sur, "Can't allocate the memory."); + + if (delay->left == NULL || delay->right == NULL || delay->sur == NULL) { + AXFXDelayShutdown(delay); + return 0; + } + + l = delay->left; + r = delay->right; + s = delay->sur; + + for (i = 0; i < delay->currentSize[0] * 0xA0; i++) { + *l++ = 0; + } + + for (i = 0; i < delay->currentSize[1] * 0xA0; i++) { + *r++ = 0; + } + + for (i = 0; i < delay->currentSize[2] * 0xA0; i++) { + *s++ = 0; + } + + OSRestoreInterrupts(old); + return 1; +} + +int AXFXDelayInit(AXFX_DELAY* delay) { + BOOL old; + + old = OSDisableInterrupts(); + delay->left = NULL; + delay->right = NULL; + delay->sur = NULL; + OSRestoreInterrupts(old); + AXFXDelaySettings(delay); +} + +int AXFXDelayShutdown(AXFX_DELAY* delay) { + BOOL old; + + old = OSDisableInterrupts(); + if (delay->left) { + __AXFXFree(delay->left); + } + + if (delay->right) { + __AXFXFree(delay->right); + } + + if (delay->sur) { + __AXFXFree(delay->sur); + } + + delay->left = NULL; + delay->right = NULL; + delay->sur = NULL; + + OSRestoreInterrupts(old); + return 1; +} diff --git a/src/dolphin/axfx/reverb_hi.c b/src/dolphin/axfx/reverb_hi.c new file mode 100644 index 0000000000..f7707000d8 --- /dev/null +++ b/src/dolphin/axfx/reverb_hi.c @@ -0,0 +1,735 @@ +#include +#include +#include +#include "fake_tgmath.h" + +#include "__axfx.h" + +// prototypes +static void DLsetdelay(AXFX_REVHI_DELAYLINE* dl, s32 lag); +static int DLcreate(AXFX_REVHI_DELAYLINE* dl, s32 max_length); +static void DLdelete(AXFX_REVHI_DELAYLINE* dl); +static int ReverbHICreate(AXFX_REVHI_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 preDelay, f32 crosstalk); +static int ReverbHIModify(AXFX_REVHI_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 preDelay, f32 crosstalk); +static void HandleReverb(s32* sptr, AXFX_REVHI_WORK* rv, s32 k); +static void ReverbHICallback(s32* left, s32* right, s32* surround, AXFX_REVHI_WORK* rv); +static void ReverbHIFree(AXFX_REVHI_WORK* rv); + +static void DLsetdelay(AXFX_REVHI_DELAYLINE* dl, s32 lag) { + dl->outPoint = dl->inPoint - (lag * 4); + while (dl->outPoint < 0) { + dl->outPoint += dl->length; + } +} + +static int DLcreate(AXFX_REVHI_DELAYLINE* dl, s32 max_length) { + dl->length = (max_length * 4); + dl->inputs = __AXFXAlloc(max_length << 2); + ASSERTMSGLINE(51, dl->inputs, "Can't allocate the memory."); + if (dl->inputs == NULL) { + return 0; + } + + memset(dl->inputs, 0, max_length << 2); + dl->lastOutput = 0.0f; + DLsetdelay(dl, max_length >> 1); + dl->inPoint = 0; + dl->outPoint = 0; + return 1; +} + +static void DLdelete(AXFX_REVHI_DELAYLINE* dl) { + __AXFXFree(dl->inputs); +} + +static int ReverbHICreate(AXFX_REVHI_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 preDelay, f32 crosstalk) { + u8 i; + u8 k; + static s32 lens[8] = { + 0x000006FD, + 0x000007CF, + 0x0000091D, + 0x000001B1, + 0x00000095, + 0x0000002F, + 0x00000049, + 0x00000043 + }; + + ASSERTMSGLINE(105, coloration >= 0.0f && coloration <= 1.0f && + time >= 0.01f && time <= 10.0f && + mix >= 0.0f && mix <= 1.0f && + crosstalk >= 0.0f && crosstalk <= 1.0f && + damping >= 0.0f && damping <= 1.0f && + preDelay >= 0.0f && preDelay <= 0.1f, + "The value of specified parameter is out of range."); + + if ((coloration < 0.0f ) || (coloration > 1.0f ) + || (time < 0.01f) || (time > 10.0f) + || (mix < 0.0f ) || (mix > 1.0f ) + || (crosstalk < 0.0f ) || (crosstalk > 1.0f ) + || (damping < 0.0f ) || (damping > 1.0f ) + || (preDelay < 0.0f ) || (preDelay > 0.1f )) { + return 0; + } + + memset(rv, 0, sizeof(AXFX_REVHI_WORK)); + + for (k = 0; k < 3; k++) { + for (i = 0; i < 3; i++) { + if (DLcreate(&rv->C[i + (k * 3)], lens[i] + 2) == 0) { + ReverbHIFree(rv); + return 0; + } + + DLsetdelay(&rv->C[i + (k * 3)], lens[i]); + rv->combCoef[i + (k * 3)] = powf(10.0f, (lens[i] * -3) / (32000.0f * time)); + } + + for (i = 0; i < 2; i++) { + if (DLcreate(&rv->AP[i + (k * 3)], lens[i + 3] + 2) == 0) { + ReverbHIFree(rv); + return 0; + } + DLsetdelay(&rv->AP[i + (k * 3)], lens[i + 3]); + } + + if (DLcreate(&rv->AP[2 + (k * 3)], lens[k + 5] + 2) == 0) { + ReverbHIFree(rv); + return 0; + } + DLsetdelay(&rv->AP[2 + (k * 3)], lens[k + 5]); + rv->lpLastout[k] = 0.0f; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->crosstalk = crosstalk; + rv->damping = damping; + if (rv->damping < 0.05f) { + rv->damping = 0.05f; + } + rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); + + if (0.0f != preDelay) { + rv->preDelayTime = (32000.0f * preDelay); + for(i = 0; i < 3; i++) { + rv->preDelayLine[i] = __AXFXAlloc(rv->preDelayTime * 4); + ASSERTMSGLINE(173, rv->preDelayLine[i], "Can't allocate the memory."); + if (rv->preDelayLine[i] == NULL) { + ReverbHIFree(rv); + return 0; + } + + memset(rv->preDelayLine[i], 0, rv->preDelayTime * 4); + rv->preDelayPtr[i] = rv->preDelayLine[i]; + } + } else { + rv->preDelayTime = 0; + for(i = 0; i < 3; i++) { + rv->preDelayPtr[i] = 0; + rv->preDelayLine[i] = 0; + } + } + + return 1; +} + +static int ReverbHIModify(AXFX_REVHI_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 preDelay, f32 crosstalk) { + u8 i; + + ASSERTMSGLINE(209, coloration >= 0.0f && coloration <= 1.0f && + time >= 0.01f && time <= 10.0f && + mix >= 0.0f && mix <= 1.0f && + crosstalk >= 0.0f && crosstalk <= 1.0f && + damping >= 0.0f && damping <= 1.0f && + preDelay >= 0.0f && preDelay <= 0.1f, + "The value of specified parameter is out of range."); + + if ((coloration < 0.0f ) || (coloration > 1.0f ) + || (time < 0.01f) || (time > 10.0f ) + || (mix < 0.0f ) || (mix > 1.0f ) + || (crosstalk < 0.0f ) || (crosstalk > 1.0f ) + || (damping < 0.0f ) || (damping > 1.0f ) + || (preDelay < 0.0f ) || (preDelay > 0.1f)) { + return 0; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->crosstalk = crosstalk; + rv->damping = damping; + if (rv->damping < 0.05f) { + rv->damping = 0.05f; + } + rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); + + for (i = 0; i < 9; i++) { + DLdelete(&rv->AP[i]); + } + + for (i = 0; i < 9; i++) { + DLdelete(&rv->C[i]); + } + + if (rv->preDelayTime) { + for (i = 0; i < 3; i++) { + __AXFXFree(rv->preDelayLine[i]); + } + } + + return ReverbHICreate(rv, coloration, time, mix, damping, preDelay, crosstalk); +} + +const static double i2fMagic = 4503601774854144.0; +const static f32 value1_0 = 1.0f; +const static f32 value0_3 = 0.3f; +const static f32 value0_6 = 0.6f; + +asm static void DoCrossTalk(register s32* l, register s32* r, register f32 cross, register f32 invcross) { + nofralloc + stwu r1, -48(r1) + stfd f14, 40(r1) + lis r5, i2fMagic@ha + lfd f0, i2fMagic@l(r5) + lis r5, 0x4330 // 176.0f (0x43300000) + stw r5, 8(r1) + stw r5, 16(r1) + stw r5, 24(r1) + stw r5, 32(r1) + ps_merge00 f3, invcross, cross + ps_merge00 f4, cross, invcross + lis r5, value1_0@ha + lfs f5, value1_0@l(r5) + li r5, 79 + mtctr r5 + li r10, -8 + li r11, -4 + ps_muls0 f4, f4, f5 + lwz r6, 0(l) + lwz r7, 0(r) + xoris r6, r6, 0x8000 + lwz r8, 4(l) + xoris r7, r7, 0x8000 + lwz r9, 4(r) + xoris r8, r8, 0x8000 + stw r6, 12(r1) + xoris r9, r9, 0x8000 + stw r7, 20(r1) + stw r8, 28(r1) + stw r9, 36(r1) + lfd f5, 8(r1) + lfd f6, 16(r1) + fsubs f5, f5, f0 + lfd f7, 24(r1) + fsubs f6, f6, f0 + lfd f8, 32(r1) + fsubs f7, f7, f0 + fsubs f8, f8, f0 +loop: + ps_merge00 f9, f5, f6 + lwzu r6, 8(l) + ps_merge00 f10, f7, f8 + lwzu r7, 8(r) + xoris r6, r6, 0x8000 + lwz r8, 4(l) + ps_mul f11, f9, f3 + xoris r7, r7, 0x8000 + ps_mul f12, f9, f4 + lwz r9, 4(r) + ps_mul f13, f10, f3 + xoris r8, r8, 0x8000 + ps_mul f14, f10, f4 + stw r6, 12(r1) + ps_sum0 f11, f11, f11, f11 + xoris r9, r9, 0x8000 + ps_sum0 f12, f12, f12, f12 + stw r7, 20(r1) + ps_sum0 f13, f13, f13, f13 + stw r8, 28(r1) + ps_sum0 f14, f14, f14, f14 + stw r9, 36(r1) + fctiw f11, f11 + lfd f5, 8(r1) + fctiw f12, f12 + lfd f6, 16(r1) + fctiw f13, f13 + fsubs f5, f5, f0 + fctiw f14, f14 + lfd f7, 24(r1) + stfiwx f11, r10, l + fsubs f6, f6, f0 + stfiwx f12, r10, r + lfd f8, 32(r1) + stfiwx f13, r11, l + fsubs f7, f7, f0 + stfiwx f14, r11, r + fsubs f8, f8, f0 + bdnz loop + ps_merge00 f9, f5, f6 + addi l, l, 8 + ps_merge00 f10, f7, f8 + addi r, r, 8 + ps_mul f11, f9, f3 + ps_mul f12, f9, f4 + ps_mul f13, f10, f3 + ps_mul f14, f10, f4 + ps_sum0 f11, f11, f11, f11 + ps_sum0 f12, f12, f12, f12 + ps_sum0 f13, f13, f13, f13 + ps_sum0 f14, f14, f14, f14 + fctiw f11, f11 + fctiw f12, f12 + fctiw f13, f13 + fctiw f14, f14 + stfiwx f11, r10, l + stfiwx f12, r10, r + stfiwx f13, r11, l + stfiwx f14, r11, r + lfd f14, 40(r1) + addi r1, r1, 48 + blr +} + +asm static void HandleReverb(register s32* sptr, register AXFX_REVHI_WORK* rv, register s32 k) { + nofralloc + stwu r1, -0xc0(r1) + stmw r14, 0x8(r1) + stfd f14, 0x60(r1) + stfd f15, 0x68(r1) + stfd f16, 0x70(r1) + stfd f17, 0x78(r1) + stfd f18, 0x80(r1) + stfd f19, 0x88(r1) + stfd f20, 0x90(r1) + stfd f21, 0x98(r1) + stfd f22, 0xa0(r1) + stfd f23, 0xa8(r1) + stfd f24, 0xb0(r1) + stfd f25, 0xb8(r1) + stw k, 0x50(r1) + stw rv, 0x54(r1) + lis r31, value0_3@ha + lfs f6, value0_3@l(r31) + lis r31, value0_6@ha + lfs f9, value0_6@l(r31) + lis r31, i2fMagic@ha + lfd f5, i2fMagic@l(r31) + lfs f2, AXFX_REVHI_WORK.allPassCoeff(rv) + lfs f15, AXFX_REVHI_WORK.damping(rv) + lfs f8, AXFX_REVHI_WORK.level(rv) + fmuls f3, f8, f9 + fsubs f4, f9, f3 + slwi r30, k, 1 + add r30, r30, k + mulli r31, r30, 0x14 + addi r29, rv, AXFX_REVHI_WORK.C + add r29, r29, r31 + addi r27, rv, AXFX_REVHI_WORK.AP + add r27, r27, r31 + slwi r31, r30, 2 + add r31, r31, rv + lfs f22, AXFX_REVHI_WORK.combCoef[0](r31) + lfs f23, AXFX_REVHI_WORK.combCoef[1](r31) + lfs f24, AXFX_REVHI_WORK.combCoef[2](r31) + slwi r31, k, 2 + add r31, r31, rv + lfs f25, AXFX_REVHI_WORK.lpLastout[0](r31) + lwz r31, AXFX_REVHI_WORK.preDelayTime(rv) + lis r30, 0x4330 + stw r30, 0x58(r1) + subi r22, r31, 1 + slwi r22, r22, 2 + slwi r28, k, 2 + add r28, r28, rv + cmpwi cr7, r31, 0 + lwz r21, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r29) // C[0] + lwz r20, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r29) // C[0] + lwz r19, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r29) // C[1] + lwz r18, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r29) // C[1] + lwz r17, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r29) // C[2] + lwz r16, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r29) // C[2] + lfs f16, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r29) // C[0] + lfs f17, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r29) // C[1] + lfs f18, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r29) // C[2] + lwz r25, AXFX_REVHI_DELAYLINE.length + 0x00(r29) // C[0] + lwz r24, AXFX_REVHI_DELAYLINE.length + 0x14(r29) // C[1] + lwz r23, AXFX_REVHI_DELAYLINE.length + 0x28(r29) // C[2] + lwz r4, AXFX_REVHI_DELAYLINE.inputs + 0x00(r29) // C[0] + lwz r5, AXFX_REVHI_DELAYLINE.inputs + 0x14(r29) // C[1] + lwz r6, AXFX_REVHI_DELAYLINE.inputs + 0x28(r29) // C[2] + lwz r12, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r27) // AP[0] + lwz r11, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r27) // AP[0] + lwz r10, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r27) // AP[1] + lwz r9, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r27) // AP[1] + lwz r8, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r27) // AP[2] + lwz r7, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r27) // AP[2] + lfs f19, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r27) // AP[0] + lfs f20, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r27) // AP[1] + lfs f21, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r27) // AP[2] + lwz r15, AXFX_REVHI_DELAYLINE.length + 0x00(r27) // AP[0] + lwz r14, AXFX_REVHI_DELAYLINE.length + 0x14(r27) // AP[1] + //? missing load for length of AP[3]? Maybe intentional? + lwz r30, 0(r3) + xoris r30, r30, 0x8000 + stw r30, 0x5c(r1) + lfd f12, 0x58(r1) + fsubs f12, f12, f5 + li r31, 159 + mtctr r31 +L_00000964: + fmr f13, f12 + beq cr7, L_00000994 + lwz r30, AXFX_REVHI_WORK.preDelayLine(r28) + lwz r29, AXFX_REVHI_WORK.preDelayPtr(r28) + add r31, r22, r30 + addi r29, r29, 4 + lfs f13, -4(r29) + cmpw r29, r31 + stfs f12, -4(r29) + bne+ L_00000990 + mr r29, r30 +L_00000990: + stw r29, AXFX_REVHI_WORK.preDelayPtr(r30) +L_00000994: + fmadds f8, f22, f16, f13 + lwzu r29, 4(r3) + fmadds f9, f23, f17, f13 + stfsx f8, rv, r21 + addi r21, r21, 4 + stfsx f9, k, r19 + lfsx f14, rv, r20 + addi r20, r20, 4 + lfsx f17, k, r18 + cmpw r21, r25 + cmpw cr1, r20, r25 + addi r19, r19, 4 + addi r18, r18, 4 + fmr f16, f14 + cmpw cr5, r19, r24 + fadds f14, f14, f17 + cmpw cr6, r18, r24 + bne+ L_000009E0 + li r21, 0 +L_000009E0: + fmadds f8, f24, f18, f13 + bne+ cr1, L_000009EC + li r20, 0 +L_000009EC: + stfsx f8, r6, r17 + addi r17, r17, 4 + bne+ cr5, L_000009FC + li r19, 0 +L_000009FC: + lfsx f18, r6, r16 + addi r16, r16, 4 + cmpw r17, r23 + bne+ cr6, L_00000A10 + li r18, 0 +L_00000A10: + fadds f14, f14, f18 + cmpw cr1, r16, r23 + lwz r26, AXFX_REVHI_DELAYLINE.inputs(r27) + fmadds f9, f2, f19, f14 + bne+ L_00000A28 + li r17, 0 +L_00000A28: + bne+ cr1, L_00000A30 + li r16, 0 +L_00000A30: + xoris r29, r29, 0x8000 + stfsx f9, r26, r12 + fnmsubs f14, f2, f9, f19 + addi r12, r12, 4 + lfsx f19, r26, r11 + cmpw cr5, r12, r15 + addi r11, r11, 4 + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x14(r27) + cmpw cr6, r11, r15 + fmadds f8, f2, f20, f14 + bne+ cr5, L_00000A60 + li r12, 0x0 +L_00000A60: + stw r29, 0x5c(r1) + stfsx f8, r26, r10 + fnmsubs f14, f2, f8, f20 + addi r10, r10, 4 + bne+ cr6, L_00000A78 + li r11, 0 +L_00000A78: + lfsx f20, r26, r9 + cmpw r10, r14 + fmuls f14, f14, f6 + addi r9, r9, 4 + cmpw cr1, r9, r14 + lfd f10, 0x58(r1) + fmadds f14, f15, f25, f14 + bne+ L_00000A9C + li r10, 0 +L_00000A9C: + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x28(r27) + fmadds f9, f2, f21, f14 + fmr f25, f14 + bne+ cr1, L_00000AB0 + li r9, 0 +L_00000AB0: + stfsx f9, r26, r8 + fnmsubs f14, f2, f9, f21 + lwz r31, AXFX_REVHI_DELAYLINE.length + 0x28(r27) + fmuls f8, f4, f12 + lfsx f21, r26, r7 + addi r8, r8, 4 + addi r7, r7, 4 + fmadds f14, f3, f14, f8 + cmpw cr5, r8, r31 + cmpw cr6, r7, r31 + fctiwz f14, f14 + bne+ cr5, L_00000AE4 + li r8, 0 +L_00000AE4: + bne+ cr6, L_00000AEC + li r7, 0 +L_00000AEC: + li r31, -4 + fsubs f12, f10, f5 + stfiwx f14, sptr, r31 + bdnz L_00000964 + fmr f13, f12 + beq cr7, L_00000B2C + lwz r30, AXFX_REVHI_WORK.preDelayLine(r28) + lwz r29, AXFX_REVHI_WORK.preDelayPtr(r28) + add r31, r22, r30 + addi r29, r29, 4 + lfs f13, -4(r29) + cmpw r29, r31 + stfs f12, -4(r29) + bne+ L_00000B28 + mr r29, r30 +L_00000B28: + stw r29, AXFX_REVHI_WORK.preDelayPtr(r30) +L_00000B2C: + fmadds f8, f22, f16, f13 + fmadds f9, f23, f17, f13 + stfsx f8, rv, r21 + addi r21, r21, 4 + stfsx f9, k, r19 + lfsx f14, rv, r20 + addi r20, r20, 4 + lfsx f17, k, r18 + cmpw r21, r25 + cmpw cr1, r20, r25 + addi r19, r19, 4 + addi r18, r18, 4 + fmr f16, f14 + cmpw cr5, r19, r24 + fadds f14, f14, f17 + cmpw cr6, r18, r24 + bne+ L_00000B74 + li r21, 0 +L_00000B74: + fmadds f8, f24, f18, f13 + bne+ cr1, L_00000B80 + li r20, 0 +L_00000B80: + stfsx f8, r6, r17 + addi r17, r17, 4 + bne+ cr5, L_00000B90 + li r19, 0 +L_00000B90: + lfsx f18, r6, r16 + addi r16, r16, 4 + cmpw r17, r23 + bne+ cr6, L_00000BA4 + li r18, 0 +L_00000BA4: + fadds f14, f14, f18 + cmpw cr1, r16, r23 + lwz r26, AXFX_REVHI_DELAYLINE.inputs(r27) + fmadds f9, f2, f19, f14 + bne+ L_00000BBC + li r17, 0 +L_00000BBC: + bne+ cr1, L_00000BC4 + li r16, 0 +L_00000BC4: + stfsx f9, r26, r12 + fnmsubs f14, f2, f9, f19 + addi r12, r12, 4 + lfsx f19, r26, r11 + cmpw cr5, r12, r15 + addi r11, r11, 4 + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x14(r27) + cmpw cr6, r11, r15 + fmadds f8, f2, f20, f14 + bne+ cr5, L_00000BF0 + li r12, 0 +L_00000BF0: + stfsx f8, r26, r10 + fnmsubs f14, f2, f8, f20 + addi r10, r10, 4 + bne+ cr6, L_00000C04 + li r11, 0 +L_00000C04: + lfsx f20, r26, r9 + cmpw r10, r14 + fmuls f14, f14, f6 + addi r9, r9, 4 + cmpw cr1, r9, r14 + fmadds f14, f15, f25, f14 + bne+ L_00000C24 + li r10, 0 +L_00000C24: + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x28(r27) + lwz k, 0x50(r1) + lwz rv, 0x54(r1) + fmadds f9, f2, f21, f14 + fmr f25, f14 + bne+ cr1, L_00000C40 + li r9, 0 +L_00000C40: + stfsx f9, r26, r8 + fnmsubs f14, f2, f9, f21 + lwz r29, AXFX_REVHI_DELAYLINE.length + 0x28(r27) + fmuls f8, f4, f12 + lfsx f21, r26, r7 + addi r8, r8, 4 + addi r7, r7, 4 + fmadds f14, f3, f14, f8 + cmpw cr5, r8, r29 + cmpw cr6, r7, r29 + fctiwz f14, f14 + bne+ cr5, L_00000C74 + li r8, 0 +L_00000C74: + bne+ cr6, L_00000C7C + li r7, 0 +L_00000C7C: + slwi r30, k, 1 + add r30, r30, k + mulli r31, r30, 0x14 // sizeof AXFX_REVHI_DELAYLINE + stfiwx f14, r0, sptr + addi r29, rv, AXFX_REVHI_WORK.C + add r29, r29, r31 + stw r21, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r29) // C[0] + stw r20, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r29) // C[0] + stw r19, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r29) // C[1] + stw r18, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r29) // C[1] + stw r17, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r29) // C[2] + stw r16, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r29) // C[2] + stfs f16, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r29) // C[0] + stfs f17, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r29) // C[1] + stfs f18, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r29) // C[2] + stw r12, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r27) // AP[0] + stw r11, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r27) // AP[0] + stw r10, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r27) // AP[1] + stw r9, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r27) // AP[1] + stw r8, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r27) // AP[2] + stw r7, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r27) // AP[2] + stfs f19, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r27) // AP[0] + stfs f20, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r27) // AP[1] + stfs f21, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r27) // AP[2] + slwi r31, k, 2 + add r31, r31, rv + stfs f25, AXFX_REVHI_WORK.lpLastout(r31) + lfd f14, 0x60(r1) + lfd f15, 0x68(r1) + lfd f16, 0x70(r1) + lfd f17, 0x78(r1) + lfd f18, 0x80(r1) + lfd f19, 0x88(r1) + lfd f20, 0x90(r1) + lfd f21, 0x98(r1) + lfd f22, 0xa0(r1) + lfd f23, 0xa8(r1) + lfd f24, 0xb0(r1) + lfd f25, 0xb8(r1) + lmw r14, 0x8(r1) + addi r1, r1, 0xc0 + blr +} + +static void ReverbHICallback(s32* left, s32* right, s32* surround, AXFX_REVHI_WORK* rv) { + u8 k; + + for (k = 0; k < 3; k++) { + switch(k) { + case 0: + if (0.0f != rv->crosstalk) { + DoCrossTalk(left, right, 0.5f * rv->crosstalk, 1.0f - (0.5f * rv->crosstalk)); + } + HandleReverb(left, rv, 0); + break; + case 1: + HandleReverb(right, rv, 1); + break; + case 2: + HandleReverb(surround, rv, 2); + break; + } + } +} + +static void ReverbHIFree(AXFX_REVHI_WORK* rv) { + u8 i; + + for (i = 0; i < 9; i++) { + if (rv->AP[i].inputs != 0) { + DLdelete(&rv->AP[i]); + rv->AP[i].inputs = NULL; + } + } + + for (i = 0; i < 9; i++) { + if (rv->C[i].inputs != 0) { + DLdelete(&rv->C[i]); + rv->C[i].inputs = NULL; + } + } + + if (rv->preDelayTime) { + for (i = 0; i < 3; i++) { + if (rv->preDelayLine[i] != 0) { + __AXFXFree(rv->preDelayLine[i]); + rv->preDelayLine[i] = NULL; + } + } + } +} + +int AXFXReverbHiInit(AXFX_REVERBHI* rev) { + int ret; + BOOL old; + + old = OSDisableInterrupts(); + rev->tempDisableFX = 0; + ret = ReverbHICreate(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, rev->preDelay, rev->crosstalk); + OSRestoreInterrupts(old); + return ret; +} + +int AXFXReverbHiShutdown(AXFX_REVERBHI* rev) { + BOOL old; + + old = OSDisableInterrupts(); + ReverbHIFree(&rev->rv); + OSRestoreInterrupts(old); + return 1; +} + +int AXFXReverbHiSettings(AXFX_REVERBHI* rev) { + int ret; + BOOL old; + + old = OSDisableInterrupts(); + rev->tempDisableFX = 1; + ret = ReverbHIModify(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, rev->preDelay, rev->crosstalk); + rev->tempDisableFX = 0; + OSRestoreInterrupts(old); + return ret; +} + +void AXFXReverbHiCallback(AXFX_BUFFERUPDATE* bufferUpdate, AXFX_REVERBHI* reverb) { + if (reverb->tempDisableFX == 0) { + ReverbHICallback(bufferUpdate->left, bufferUpdate->right, bufferUpdate->surround, &reverb->rv); + } +} diff --git a/src/dolphin/axfx/reverb_hi_4ch.c b/src/dolphin/axfx/reverb_hi_4ch.c new file mode 100644 index 0000000000..df10073336 --- /dev/null +++ b/src/dolphin/axfx/reverb_hi_4ch.c @@ -0,0 +1,611 @@ +#include +#include +#include +#include "fake_tgmath.h" + +#include "__axfx.h" + +static void ReverbHIDpl2Free(AXFX_REVHI_WORK_DPL2* rv); + +static void DLsetdelayDpl2(AXFX_REVHI_DELAYLINE* dl, s32 lag) { + dl->outPoint = dl->inPoint - (lag * 4); + while (dl->outPoint < 0) { + dl->outPoint += dl->length; + } +} + +static int DLcreateDpl2(AXFX_REVHI_DELAYLINE* dl, s32 max_length) { + dl->length = (max_length * 4); + dl->inputs = __AXFXAlloc(max_length << 2); + ASSERTMSGLINE(62, dl->inputs, "Can't allocate the memory."); + if (dl->inputs == NULL) { + return 0; + } + + memset(dl->inputs, 0, max_length << 2); + dl->lastOutput = 0.0f; + DLsetdelayDpl2(dl, max_length >> 1); + dl->inPoint = 0; + dl->outPoint = 0; + return 1; +} + +static void DLdeleteDpl2(AXFX_REVHI_DELAYLINE* dl) { + __AXFXFree(dl->inputs); +} + +static int ReverbHICreateDpl2(AXFX_REVHI_WORK_DPL2* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 preDelay) { + u8 i; + u8 k; + + static s32 lens[9] = { + 0x000006FD, + 0x000007CF, + 0x0000091D, + 0x000001B1, + 0x00000095, + 0x0000002F, + 0x00000049, + 0x00000043, + 0x00000047 + }; + + ASSERTMSGLINE(117, coloration >= 0.0f && coloration <= 1.0f && + time >= 0.01f && time <= 10.0f && + mix >= 0.0f && mix <= 1.0f && + damping >= 0.0f && damping <= 1.0f && + preDelay >= 0.0f && preDelay <= 0.1f, + "The value of specified parameter is out of range."); + + if ((coloration < 0.0f ) || (coloration > 1.0f ) + || (time < 0.01f) || (time > 10.0f) + || (mix < 0.0f ) || (mix > 1.0f ) + || (damping < 0.0f ) || (damping > 1.0f ) + || (preDelay < 0.0f ) || (preDelay > 0.1f )) { + return 0; + } + + memset(rv, 0, sizeof(AXFX_REVHI_WORK_DPL2)); + + for (k = 0; k < 4; k++) { + for (i = 0; i < 3; i++) { + if (DLcreateDpl2(&rv->C[i + (k * 3)], lens[i] + 2) == 0) { + ReverbHIDpl2Free(rv); + return 0; + } + + DLsetdelayDpl2(&rv->C[i + (k * 3)], lens[i]); + rv->combCoef[i + (k * 3)] = powf(10.0f, (lens[i] * -3) / (32000.0f * time)); + } + + for (i = 0; i < 2; i++) { + if (DLcreateDpl2(&rv->AP[i + (k * 3)], lens[i + 3] + 2) == 0) { + ReverbHIDpl2Free(rv); + return 0; + } + + DLsetdelayDpl2(&rv->AP[i + (k * 3)], lens[i + 3]); + } + + if (DLcreateDpl2(&rv->AP[2 + (k * 3)], lens[k + 5] + 2) == 0) { + ReverbHIDpl2Free(rv); + return 0; + } + + DLsetdelayDpl2(&rv->AP[2 + (k * 3)], lens[k + 5]); + rv->lpLastout[k] = 0.0f; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->damping = damping; + if (rv->damping < 0.05f) { + rv->damping = 0.05f; + } + + rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); + if (0.0f != preDelay) { + rv->preDelayTime = (32000.0f * preDelay); + for (i = 0; i < 4; i++) { + rv->preDelayLine[i] = __AXFXAlloc(rv->preDelayTime * 4); + ASSERTMSGLINE(188, rv->preDelayLine[i], "Can't allocate the memory."); + if (rv->preDelayLine[i] == NULL) { + ReverbHIDpl2Free(rv); + return 0; + } + + memset(rv->preDelayLine[i], 0, rv->preDelayTime * 4); + rv->preDelayPtr[i] = rv->preDelayLine[i]; + } + } else { + rv->preDelayTime = 0; + for (i = 0; i < 4; i++) { + rv->preDelayPtr[i] = 0; + rv->preDelayLine[i] = 0; + } + } + + return 1; +} + +static int ReverbHIModifyDpl2(AXFX_REVHI_WORK_DPL2* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 preDelay) { + u8 i; + + ASSERTMSGLINE(222, coloration >= 0.0f && coloration <= 1.0f && + time >= 0.01f && time <= 10.0f && + mix >= 0.0f && mix <= 1.0f && + damping >= 0.0f && damping <= 1.0f && + preDelay >= 0.0f && preDelay <= 0.1f, + "The value of specified parameter is out of range."); + + if ((coloration < 0.0f ) || (coloration > 1.0f ) + || (time < 0.01f) || (time > 10.0f ) + || (mix < 0.0f ) || (mix > 1.0f ) + || (damping < 0.0f ) || (damping > 1.0f ) + || (preDelay < 0.0f ) || (preDelay > 0.1f)) { + return 0; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->damping = damping; + if (rv->damping < 0.05f) { + rv->damping = 0.05f; + } + rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); + + for (i = 0; i < 12; i++) { + DLdeleteDpl2(&rv->AP[i]); + } + + for (i = 0; i < 12; i++) { + DLdeleteDpl2(&rv->C[i]); + } + + if (rv->preDelayTime) { + for (i = 0; i < 4; i++) { + __AXFXFree(rv->preDelayLine[i]); + } + } + + return ReverbHICreateDpl2(rv, coloration, time, mix, damping, preDelay); +} + + +const static f32 value0_6 = 0.6f; +const static f32 value0_3 = 0.3f; +const static double i2fMagic = 4503601774854144.0; + +asm static void HandleReverbDpl2(register s32* sptr, register AXFX_REVHI_WORK_DPL2* rv, register s32 k) { + nofralloc + stwu r1, -0xc0(r1) + stmw r14, 0x8(r1) + stfd f14, 0x60(r1) + stfd f15, 0x68(r1) + stfd f16, 0x70(r1) + stfd f17, 0x78(r1) + stfd f18, 0x80(r1) + stfd f19, 0x88(r1) + stfd f20, 0x90(r1) + stfd f21, 0x98(r1) + stfd f22, 0xa0(r1) + stfd f23, 0xa8(r1) + stfd f24, 0xb0(r1) + stfd f25, 0xb8(r1) + stw k, 0x50(r1) + stw rv, 0x54(r1) + lis r31, value0_3@ha + lfs f6, value0_3@l(r31) + lis r31, value0_6@ha + lfs f9, value0_6@l(r31) + lis r31, i2fMagic@ha + lfd f5, i2fMagic@l(r31) + lfs f2, AXFX_REVHI_WORK_DPL2.allPassCoeff(rv) + lfs f15, AXFX_REVHI_WORK_DPL2.damping(rv) + lfs f8, AXFX_REVHI_WORK_DPL2.level(rv) + fmuls f3, f8, f9 + fsubs f4, f9, f3 + slwi r30, k, 1 + add r30, r30, k + mulli r31, r30, 0x14 + addi r29, rv, AXFX_REVHI_WORK_DPL2.C + add r29, r29, r31 + addi r27, rv, AXFX_REVHI_WORK_DPL2.AP + add r27, r27, r31 + slwi r31, r30, 2 + add r31, r31, rv + lfs f22, AXFX_REVHI_WORK_DPL2.combCoef[0](r31) + lfs f23, AXFX_REVHI_WORK_DPL2.combCoef[1](r31) + lfs f24, AXFX_REVHI_WORK_DPL2.combCoef[2](r31) + slwi r31, k, 2 + add r31, r31, rv + lfs f25, AXFX_REVHI_WORK_DPL2.lpLastout[0](r31) + lwz r31, AXFX_REVHI_WORK_DPL2.preDelayTime(rv) + lis r30, 0x4330 + stw r30, 0x58(r1) + subi r22, r31, 1 + slwi r22, r22, 2 + slwi r28, k, 2 + add r28, r28, rv + cmpwi cr7, r31, 0 + lwz r21, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r29) // C[0] + lwz r20, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r29) // C[0] + lwz r19, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r29) // C[1] + lwz r18, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r29) // C[1] + lwz r17, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r29) // C[2] + lwz r16, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r29) // C[2] + lfs f16, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r29) // C[0] + lfs f17, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r29) // C[1] + lfs f18, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r29) // C[2] + lwz r25, AXFX_REVHI_DELAYLINE.length + 0x00(r29) // C[0] + lwz r24, AXFX_REVHI_DELAYLINE.length + 0x14(r29) // C[1] + lwz r23, AXFX_REVHI_DELAYLINE.length + 0x28(r29) // C[2] + lwz r4, AXFX_REVHI_DELAYLINE.inputs + 0x00(r29) // C[0] + lwz r5, AXFX_REVHI_DELAYLINE.inputs + 0x14(r29) // C[1] + lwz r6, AXFX_REVHI_DELAYLINE.inputs + 0x28(r29) // C[2] + lwz r12, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r27) // AP[0] + lwz r11, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r27) // AP[0] + lwz r10, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r27) // AP[1] + lwz r9, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r27) // AP[1] + lwz r8, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r27) // AP[2] + lwz r7, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r27) // AP[2] + lfs f19, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r27) // AP[0] + lfs f20, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r27) // AP[1] + lfs f21, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r27) // AP[2] + lwz r15, AXFX_REVHI_DELAYLINE.length + 0x00(r27) // AP[0] + lwz r14, AXFX_REVHI_DELAYLINE.length + 0x14(r27) // AP[1] + //? missing load for length of AP[3]? Maybe intentional? + lwz r30, 0(r3) + xoris r30, r30, 0x8000 + stw r30, 0x5c(r1) + lfd f12, 0x58(r1) + fsubs f12, f12, f5 + li r31, 159 + mtctr r31 +L_00000964: + fmr f13, f12 + beq cr7, L_00000994 + lwz r30, AXFX_REVHI_WORK_DPL2.preDelayLine(r28) + lwz r29, AXFX_REVHI_WORK_DPL2.preDelayPtr(r28) + add r31, r22, r30 + addi r29, r29, 4 + lfs f13, -4(r29) + cmpw r29, r31 + stfs f12, -4(r29) + bne+ L_00000990 + mr r29, r30 +L_00000990: + stw r29, AXFX_REVHI_WORK_DPL2.preDelayPtr(r30) +L_00000994: + fmadds f8, f22, f16, f13 + lwzu r29, 4(r3) + fmadds f9, f23, f17, f13 + stfsx f8, rv, r21 + addi r21, r21, 4 + stfsx f9, k, r19 + lfsx f14, rv, r20 + addi r20, r20, 4 + lfsx f17, k, r18 + cmpw r21, r25 + cmpw cr1, r20, r25 + addi r19, r19, 4 + addi r18, r18, 4 + fmr f16, f14 + cmpw cr5, r19, r24 + fadds f14, f14, f17 + cmpw cr6, r18, r24 + bne+ L_000009E0 + li r21, 0 +L_000009E0: + fmadds f8, f24, f18, f13 + bne+ cr1, L_000009EC + li r20, 0 +L_000009EC: + stfsx f8, r6, r17 + addi r17, r17, 4 + bne+ cr5, L_000009FC + li r19, 0 +L_000009FC: + lfsx f18, r6, r16 + addi r16, r16, 4 + cmpw r17, r23 + bne+ cr6, L_00000A10 + li r18, 0 +L_00000A10: + fadds f14, f14, f18 + cmpw cr1, r16, r23 + lwz r26, AXFX_REVHI_DELAYLINE.inputs(r27) + fmadds f9, f2, f19, f14 + bne+ L_00000A28 + li r17, 0 +L_00000A28: + bne+ cr1, L_00000A30 + li r16, 0 +L_00000A30: + xoris r29, r29, 0x8000 + stfsx f9, r26, r12 + fnmsubs f14, f2, f9, f19 + addi r12, r12, 4 + lfsx f19, r26, r11 + cmpw cr5, r12, r15 + addi r11, r11, 4 + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x14(r27) + cmpw cr6, r11, r15 + fmadds f8, f2, f20, f14 + bne+ cr5, L_00000A60 + li r12, 0x0 +L_00000A60: + stw r29, 0x5c(r1) + stfsx f8, r26, r10 + fnmsubs f14, f2, f8, f20 + addi r10, r10, 4 + bne+ cr6, L_00000A78 + li r11, 0 +L_00000A78: + lfsx f20, r26, r9 + cmpw r10, r14 + fmuls f14, f14, f6 + addi r9, r9, 4 + cmpw cr1, r9, r14 + lfd f10, 0x58(r1) + fmadds f14, f15, f25, f14 + bne+ L_00000A9C + li r10, 0 +L_00000A9C: + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x28(r27) + fmadds f9, f2, f21, f14 + fmr f25, f14 + bne+ cr1, L_00000AB0 + li r9, 0 +L_00000AB0: + stfsx f9, r26, r8 + fnmsubs f14, f2, f9, f21 + lwz r31, AXFX_REVHI_DELAYLINE.length + 0x28(r27) + fmuls f8, f4, f12 + lfsx f21, r26, r7 + addi r8, r8, 4 + addi r7, r7, 4 + fmadds f14, f3, f14, f8 + cmpw cr5, r8, r31 + cmpw cr6, r7, r31 + fctiwz f14, f14 + bne+ cr5, L_00000AE4 + li r8, 0 +L_00000AE4: + bne+ cr6, L_00000AEC + li r7, 0 +L_00000AEC: + li r31, -4 + fsubs f12, f10, f5 + stfiwx f14, sptr, r31 + bdnz L_00000964 + fmr f13, f12 + beq cr7, L_00000B2C + lwz r30, AXFX_REVHI_WORK_DPL2.preDelayLine(r28) + lwz r29, AXFX_REVHI_WORK_DPL2.preDelayPtr(r28) + add r31, r22, r30 + addi r29, r29, 4 + lfs f13, -4(r29) + cmpw r29, r31 + stfs f12, -4(r29) + bne+ L_00000B28 + mr r29, r30 +L_00000B28: + stw r29, AXFX_REVHI_WORK_DPL2.preDelayPtr(r30) +L_00000B2C: + fmadds f8, f22, f16, f13 + fmadds f9, f23, f17, f13 + stfsx f8, rv, r21 + addi r21, r21, 4 + stfsx f9, k, r19 + lfsx f14, rv, r20 + addi r20, r20, 4 + lfsx f17, k, r18 + cmpw r21, r25 + cmpw cr1, r20, r25 + addi r19, r19, 4 + addi r18, r18, 4 + fmr f16, f14 + cmpw cr5, r19, r24 + fadds f14, f14, f17 + cmpw cr6, r18, r24 + bne+ L_00000B74 + li r21, 0 +L_00000B74: + fmadds f8, f24, f18, f13 + bne+ cr1, L_00000B80 + li r20, 0 +L_00000B80: + stfsx f8, r6, r17 + addi r17, r17, 4 + bne+ cr5, L_00000B90 + li r19, 0 +L_00000B90: + lfsx f18, r6, r16 + addi r16, r16, 4 + cmpw r17, r23 + bne+ cr6, L_00000BA4 + li r18, 0 +L_00000BA4: + fadds f14, f14, f18 + cmpw cr1, r16, r23 + lwz r26, AXFX_REVHI_DELAYLINE.inputs(r27) + fmadds f9, f2, f19, f14 + bne+ L_00000BBC + li r17, 0 +L_00000BBC: + bne+ cr1, L_00000BC4 + li r16, 0 +L_00000BC4: + stfsx f9, r26, r12 + fnmsubs f14, f2, f9, f19 + addi r12, r12, 4 + lfsx f19, r26, r11 + cmpw cr5, r12, r15 + addi r11, r11, 4 + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x14(r27) + cmpw cr6, r11, r15 + fmadds f8, f2, f20, f14 + bne+ cr5, L_00000BF0 + li r12, 0 +L_00000BF0: + stfsx f8, r26, r10 + fnmsubs f14, f2, f8, f20 + addi r10, r10, 4 + bne+ cr6, L_00000C04 + li r11, 0 +L_00000C04: + lfsx f20, r26, r9 + cmpw r10, r14 + fmuls f14, f14, f6 + addi r9, r9, 4 + cmpw cr1, r9, r14 + fmadds f14, f15, f25, f14 + bne+ L_00000C24 + li r10, 0 +L_00000C24: + lwz r26, AXFX_REVHI_DELAYLINE.inputs + 0x28(r27) + lwz k, 0x50(r1) + lwz rv, 0x54(r1) + fmadds f9, f2, f21, f14 + fmr f25, f14 + bne+ cr1, L_00000C40 + li r9, 0 +L_00000C40: + stfsx f9, r26, r8 + fnmsubs f14, f2, f9, f21 + lwz r29, AXFX_REVHI_DELAYLINE.length + 0x28(r27) + fmuls f8, f4, f12 + lfsx f21, r26, r7 + addi r8, r8, 4 + addi r7, r7, 4 + fmadds f14, f3, f14, f8 + cmpw cr5, r8, r29 + cmpw cr6, r7, r29 + fctiwz f14, f14 + bne+ cr5, L_00000C74 + li r8, 0 +L_00000C74: + bne+ cr6, L_00000C7C + li r7, 0 +L_00000C7C: + slwi r30, k, 1 + add r30, r30, k + mulli r31, r30, 0x14 // sizeof AXFX_REVHI_DELAYLINE + stfiwx f14, r0, sptr + addi r29, rv, AXFX_REVHI_WORK_DPL2.C + add r29, r29, r31 + stw r21, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r29) // C[0] + stw r20, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r29) // C[0] + stw r19, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r29) // C[1] + stw r18, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r29) // C[1] + stw r17, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r29) // C[2] + stw r16, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r29) // C[2] + stfs f16, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r29) // C[0] + stfs f17, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r29) // C[1] + stfs f18, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r29) // C[2] + stw r12, AXFX_REVHI_DELAYLINE.inPoint + 0x00(r27) // AP[0] + stw r11, AXFX_REVHI_DELAYLINE.outPoint + 0x00(r27) // AP[0] + stw r10, AXFX_REVHI_DELAYLINE.inPoint + 0x14(r27) // AP[1] + stw r9, AXFX_REVHI_DELAYLINE.outPoint + 0x14(r27) // AP[1] + stw r8, AXFX_REVHI_DELAYLINE.inPoint + 0x28(r27) // AP[2] + stw r7, AXFX_REVHI_DELAYLINE.outPoint + 0x28(r27) // AP[2] + stfs f19, AXFX_REVHI_DELAYLINE.lastOutput + 0x00(r27) // AP[0] + stfs f20, AXFX_REVHI_DELAYLINE.lastOutput + 0x14(r27) // AP[1] + stfs f21, AXFX_REVHI_DELAYLINE.lastOutput + 0x28(r27) // AP[2] + slwi r31, k, 2 + add r31, r31, rv + stfs f25, AXFX_REVHI_WORK_DPL2.lpLastout(r31) + lfd f14, 0x60(r1) + lfd f15, 0x68(r1) + lfd f16, 0x70(r1) + lfd f17, 0x78(r1) + lfd f18, 0x80(r1) + lfd f19, 0x88(r1) + lfd f20, 0x90(r1) + lfd f21, 0x98(r1) + lfd f22, 0xa0(r1) + lfd f23, 0xa8(r1) + lfd f24, 0xb0(r1) + lfd f25, 0xb8(r1) + lmw r14, 0x8(r1) + addi r1, r1, 0xc0 + blr +} + +static void ReverbHICallbackDpl2(s32* l, s32* r, s32* ls, s32* rs, AXFX_REVHI_WORK_DPL2* rv) { + HandleReverbDpl2(l, rv, 0); + HandleReverbDpl2(r, rv, 1); + HandleReverbDpl2(ls, rv, 2); + HandleReverbDpl2(rs, rv, 3); +} + +static void ReverbHIDpl2Free(AXFX_REVHI_WORK_DPL2* rv) { + u8 i; + + for (i = 0; i < 12; i++) { + if (rv->AP[i].inputs != 0) { + DLdeleteDpl2(&rv->AP[i]); + rv->AP[i].inputs = 0; + } + } + + for (i = 0; i < 12; i++) { + if (rv->C[i].inputs != 0) { + DLdeleteDpl2(&rv->C[i]); + rv->C[i].inputs = 0; + } + } + + if (rv->preDelayTime) { + for (i = 0; i < 4; i++) { + if (rv->preDelayLine[i] != 0) { + __AXFXFree(rv->preDelayLine[i]); + rv->preDelayLine[i] = 0; + } + } + } +} + +int AXFXReverbHiInitDpl2(AXFX_REVERBHI_DPL2* reverb) { + int ret; + BOOL old; + + old = OSDisableInterrupts(); + reverb->tempDisableFX = 0; + ret = ReverbHICreateDpl2(&reverb->rv, reverb->coloration, reverb->time, reverb->mix, reverb->damping, reverb->preDelay); + OSRestoreInterrupts(old); + return ret; +} + +int AXFXReverbHiShutdownDpl2(AXFX_REVERBHI_DPL2* reverb) { + BOOL old; + + old = OSDisableInterrupts(); + ReverbHIDpl2Free(&reverb->rv); + OSRestoreInterrupts(old); + return 1; +} + +int AXFXReverbHiSettingsDpl2(AXFX_REVERBHI_DPL2* rev) { + int ret; + BOOL old; + + old = OSDisableInterrupts(); + rev->tempDisableFX = 1; + ret = ReverbHIModifyDpl2(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, rev->preDelay); + rev->tempDisableFX = 0; + OSRestoreInterrupts(old); + return ret; +} + +void AXFXReverbHiCallbackDpl2(AXFX_BUFFERUPDATE_DPL2* bufferUpdate, AXFX_REVERBHI_DPL2* reverb) { + ASSERTMSGLINE(1399, AXGetMode() == 2, "AX mode isn't AX_MODE_DPL2. AX mode must be AX_MODE_DPL2 for using AXFXReverbHiCallbackDpl2"); + + if (reverb->tempDisableFX == 0) { + HandleReverbDpl2(bufferUpdate->L, &reverb->rv, 0); + HandleReverbDpl2(bufferUpdate->R, &reverb->rv, 1); + HandleReverbDpl2(bufferUpdate->Ls, &reverb->rv, 2); + HandleReverbDpl2(bufferUpdate->Rs, &reverb->rv, 3); + } +} diff --git a/src/dolphin/axfx/reverb_std.c b/src/dolphin/axfx/reverb_std.c new file mode 100644 index 0000000000..6703890a76 --- /dev/null +++ b/src/dolphin/axfx/reverb_std.c @@ -0,0 +1,501 @@ +#include +#include +#include +#include "fake_tgmath.h" + +#include "__axfx.h" + +// prototypes +static void DLsetdelay(AXFX_REVSTD_DELAYLINE* dl, s32 lag); +static int DLcreate(AXFX_REVSTD_DELAYLINE* dl, s32 max_length); +static void DLdelete(AXFX_REVSTD_DELAYLINE* dl); +static int ReverbSTDCreate(AXFX_REVSTD_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 predelay); +static int ReverbSTDModify(AXFX_REVSTD_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 predelay); +static void HandleReverb(s32* sptr, AXFX_REVSTD_WORK* rv); +static void ReverbSTDCallback(s32* left, s32* right, s32* surround, AXFX_REVSTD_WORK* rv); +static void ReverbSTDFree(AXFX_REVSTD_WORK* rv); + +static void DLsetdelay(AXFX_REVSTD_DELAYLINE* dl, s32 lag) { + dl->outPoint = dl->inPoint - (lag * 4); + while (dl->outPoint < 0) { + dl->outPoint += dl->length; + } +} + +static int DLcreate(AXFX_REVSTD_DELAYLINE* dl, s32 max_length) { + dl->length = (max_length * 4); + dl->inputs = __AXFXAlloc(max_length * 4); + ASSERTMSGLINE(49, dl->inputs, "Can't allocate the memory."); + if (dl->inputs == NULL) { + return 0; + } + + memset(dl->inputs, 0, max_length * 4); + dl->lastOutput = 0.0f; + DLsetdelay(dl, max_length >> 1); + dl->inPoint = 0; + dl->outPoint = 0; + return 1; +} + +static void DLdelete(AXFX_REVSTD_DELAYLINE* dl) { + __AXFXFree(dl->inputs); +} + +// NONMATCHING RELEASE - regalloc +static int ReverbSTDCreate(AXFX_REVSTD_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 predelay) { + u8 i; + u8 k; + static s32 lens[4] = { + 0x000006FD, + 0x000007CF, + 0x000001B1, + 0x00000095, + }; + + ASSERTMSGLINE(109, coloration >= 0.0f && coloration <= 1.0f && + time >= 0.01f && time <= 10.0f && + mix >= 0.0f && mix <= 1.0f && + damping >= 0.0f && damping <= 1.0f && + predelay >= 0.0f && predelay <= 0.1f, + "The value of specified parameter is out of range."); + + if ((coloration < 0.0f ) || (coloration > 1.0f ) + || (time < 0.01f) || (time > 10.0f) + || (mix < 0.0f ) || (mix > 1.0f ) + || (damping < 0.0f ) || (damping > 1.0f ) + || (predelay < 0.0f ) || (predelay > 0.1f )) { + return 0; + } + + memset(rv, 0, sizeof(AXFX_REVSTD_WORK)); + + for (k = 0; k < 3; k++) { + for (i = 0; i < 2; i++) { + if (DLcreate(&rv->C[i + (k * 2)], lens[i] + 2) == 0) { + ReverbSTDFree(rv); + return 0; + } + DLsetdelay(&rv->C[i + (k * 2)], lens[i]); + rv->combCoef[i + (k * 2)] = powf(10.0f, (lens[i] * -3) / (32000.0f * time)); + } + + for (i = 0; i < 2; i++) { + if (DLcreate(&rv->AP[i + (k * 2)], lens[i + 2] + 2) == 0) { + ReverbSTDFree(rv); + return 0; + } + DLsetdelay(&rv->AP[i + (k * 2)], lens[i + 2]); + } + rv->lpLastout[k] = 0.0f; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->damping = damping; + if (rv->damping < 0.05f) { + rv->damping = 0.05f; + } + rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); + + if (0.0f != predelay) { + rv->preDelayTime = (32000.0f * predelay); + for (i = 0; i < 3; i++) { + rv->preDelayLine[i] = __AXFXAlloc(rv->preDelayTime * 4); + ASSERTMSGLINE(162, rv->preDelayLine[i], "Can't allocate the memory."); + if (rv->preDelayLine[i] == NULL) { + ReverbSTDFree(rv); + return 0; + } + + memset(rv->preDelayLine[i], 0, rv->preDelayTime * 4); + rv->preDelayPtr[i] = rv->preDelayLine[i]; + } + } else { + rv->preDelayTime = 0; + for (i = 0; i < 3; i++) { + rv->preDelayPtr[i] = 0; + rv->preDelayLine[i] = 0; + } + } + + return 1; +} + +static int ReverbSTDModify(AXFX_REVSTD_WORK* rv, f32 coloration, f32 time, f32 mix, f32 damping, f32 predelay) { + u8 i; + + ASSERTMSGLINE(196, coloration >= 0.0f && coloration <= 1.0f && + time >= 0.01f && time <= 10.0f && + mix >= 0.0f && mix <= 1.0f && + damping >= 0.0f && damping <= 1.0f && + predelay >= 0.0f && predelay <= 0.1f, + "The value of specified parameter is out of range."); + + + if ((coloration < 0.0f ) || (coloration > 1.0f ) + || (time < 0.01f) || (time > 10.0f) + || (mix < 0.0f ) || (mix > 1.0f ) + || (damping < 0.0f ) || (damping > 1.0f ) + || (predelay < 0.0f ) || (predelay > 0.1f )) { + return 0; + } + + rv->allPassCoeff = coloration; + rv->level = mix; + rv->damping = damping; + if (rv->damping < 0.05f) { + rv->damping = 0.05f; + } + rv->damping = (1.0f - (0.05f + (0.8f * rv->damping))); + + for (i = 0; i < 6; i++) { + DLdelete(&rv->AP[i]); + } + + for (i = 0; i < 6; i++) { + DLdelete(&rv->C[i]); + } + + if (rv->preDelayTime) { + for (i = 0; i < 3; i++) { + __AXFXFree(rv->preDelayLine[i]); + } + } + + return ReverbSTDCreate(rv, coloration, time, mix, damping, predelay); +} + +const static f32 value0_3 = 0.3f; +const static f32 value0_6 = 0.6f; +const static double i2fMagic = 4503601774854144.0; + +asm static void HandleReverb(register s32* sptr, register AXFX_REVSTD_WORK* rv) { + nofralloc + stwu r1, -144(r1) + stmw r17, 8(r1) + stfd f14, 88(r1) + stfd f15, 96(r1) + stfd f16, 104(r1) + stfd f17, 112(r1) + stfd f18, 120(r1) + stfd f19, 128(r1) + stfd f20, 136(r1) + lis r31, value0_3@ha + lfs f6, value0_3@l(r31) + lis r31, value0_6@ha + lfs f9, value0_6@l(r31) + lis r31, i2fMagic@ha + lfd f5, i2fMagic@l(r31) + lfs f2, AXFX_REVSTD_WORK.allPassCoeff(rv) + lfs f11, AXFX_REVSTD_WORK.damping(rv) + lfs f8, AXFX_REVSTD_WORK.level(rv) + fmuls f3, f8, f9 + fsubs f4, f9, f3 + lis r30, 0x4330 // 176.0f (0x43300000) + stw r30, 80(r1) + li r5, 0 +L_00000638: + slwi r31, r5, 3 + add r31, r31, rv + lfs f19, AXFX_REVSTD_WORK.combCoef[0](r31) + lfs f20, AXFX_REVSTD_WORK.combCoef[1](r31) + slwi r31, r5, 2 + add r31, r31, rv + lfs f7, AXFX_REVSTD_WORK.lpLastout[0](r31) + lwz r27, AXFX_REVSTD_WORK.preDelayLine[0](r31) + lwz r28, AXFX_REVSTD_WORK.preDelayPtr[0](r31) + lwz r31, AXFX_REVSTD_WORK.preDelayTime(rv) + subi r22, r31, 1 + slwi r22, r22, 2 + add r22, r22, r27 + cmpwi cr7, r31, 0 + mulli r31, r5, 0x28 // sizeof(AXFX_REVSTD_DELAYLINE * 2) + addi r29, rv, AXFX_REVSTD_WORK.C + add r29, r29, r31 + addi r30, rv, AXFX_REVSTD_WORK.AP + add r30, r30, r31 + lwz r21, AXFX_REVSTD_DELAYLINE.inPoint + 0x00(r29) // C array + 0 + lwz r20, AXFX_REVSTD_DELAYLINE.outPoint + 0x00(r29) // C array + 0 + lwz r19, AXFX_REVSTD_DELAYLINE.inPoint + 0x14(r29) // C array + 1 + lwz r18, AXFX_REVSTD_DELAYLINE.outPoint + 0x14(r29) // C array + 1 + lfs f15, AXFX_REVSTD_DELAYLINE.lastOutput + 0x00(r29) // C array + 0 + lfs f16, AXFX_REVSTD_DELAYLINE.lastOutput + 0x14(r29) // C array + 1 + lwz r26, AXFX_REVSTD_DELAYLINE.length + 0x00(r29) // C array + 0 + lwz r25, AXFX_REVSTD_DELAYLINE.length + 0x14(r29) // C array + 1 + lwz r7, AXFX_REVSTD_DELAYLINE.inputs + 0x00(r29) // C array + 0 + lwz r8, AXFX_REVSTD_DELAYLINE.inputs + 0x14(r29) // C array + 1 + lwz r12, AXFX_REVSTD_DELAYLINE.inPoint + 0x00(r30) // AP array + 0 + lwz r11, AXFX_REVSTD_DELAYLINE.outPoint + 0x00(r30) // AP array + 0 + lwz r10, AXFX_REVSTD_DELAYLINE.inPoint + 0x14(r30) // AP array + 1 + lwz r9, AXFX_REVSTD_DELAYLINE.outPoint + 0x14(r30) // AP array + 1 + lfs f17, AXFX_REVSTD_DELAYLINE.lastOutput + 0x00(r30) // AP array + 0 + lfs f18, AXFX_REVSTD_DELAYLINE.lastOutput + 0x14(r30) // AP array + 1 + lwz r24, AXFX_REVSTD_DELAYLINE.length + 0x00(r30) // AP array + 0 + lwz r23, AXFX_REVSTD_DELAYLINE.length + 0x14(r30) // AP array + 1 + lwz r17, AXFX_REVSTD_DELAYLINE.inputs + 0x00(r30) // AP array + 0 + lwz r6, AXFX_REVSTD_DELAYLINE.inputs + 0x14(r30) // AP array + 1 + lwz r30, 0(sptr) + xoris r30, r30, 0x8000 + stw r30, 84(r1) + lfd f12, 80(r1) + fsubs f12, f12, f5 + li r31, 159 + mtctr r31 +L_000006F0: + fmr f13, f12 + beq cr7, L_00000710 + lfs f13, 0(r28) + addi r28, r28, 4 + cmpw r28, r22 + stfs f12, -4(r28) + bne+ L_00000710 + mr r28, r27 +L_00000710: + fmadds f8, f19, f15, f13 + lwzu r29, 4(sptr) + fmadds f9, f20, f16, f13 + stfsx f8, r7, r21 + addi r21, r21, 4 + stfsx f9, r8, r19 + lfsx f14, r7, r20 + addi r20, r20, 4 + lfsx f16, r8, r18 + cmpw r21, r26 + cmpw cr1, r20, r26 + addi r19, r19, 4 + addi r18, r18, 4 + fmr f15, f14 + cmpw cr5, r19, r25 + fadds f14, f14, f16 + cmpw cr6, r18, r25 + bne+ L_0000075C + li r21, 0 +L_0000075C: + xoris r29, r29, 0x8000 + fmadds f9, f2, f17, f14 + bne+ cr1, L_0000076C + li r20, 0 +L_0000076C: + stw r29, 84(r1) + bne+ cr5, L_00000778 + li r19, 0 +L_00000778: + stfsx f9, r17, r12 + fnmsubs f14, f2, f9, f17 + addi r12, r12, 4 + bne+ cr6, L_0000078C + li r18, 0 +L_0000078C: + lfsx f17, r17, r11 + cmpw cr5, r12, r24 + addi r11, r11, 4 + cmpw cr6, r11, r24 + bne+ cr5, L_000007A4 + li r12, 0 +L_000007A4: + bne+ cr6, L_000007AC + li r11, 0 +L_000007AC: + fmuls f14, f14, f6 + lfd f10, 80(r1) + fmadds f14, f11, f7, f14 + fmadds f9, f2, f18, f14 + fmr f7, f14 + stfsx f9, r6, r10 + fnmsubs f14, f2, f9, f18 + fmuls f8, f4, f12 + lfsx f18, r6, r9 + addi r10, r10, 4 + addi r9, r9, 4 + fmadds f14, f3, f14, f8 + cmpw cr5, r10, r23 + cmpw cr6, r9, r23 + fctiwz f14, f14 + bne+ cr5, L_000007F0 + li r10, 0 +L_000007F0: + bne+ cr6, L_000007F8 + li r9, 0 +L_000007F8: + li r31, -4 + fsubs f12, f10, f5 + stfiwx f14, sptr, r31 + bdnz L_000006F0 + fmr f13, f12 + beq cr7, L_00000828 + lfs f13, 0(r28) + addi r28, r28, 4 + cmpw r28, r22 + stfs f12, -4(r28) + bne+ L_00000828 + mr r28, r27 +L_00000828: + fmadds f8, f19, f15, f13 + fmadds f9, f20, f16, f13 + stfsx f8, r7, r21 + addi r21, r21, 4 + stfsx f9, r8, r19 + lfsx f14, r7, r20 + addi r20, r20, 4 + lfsx f16, r8, r18 + cmpw r21, r26 + cmpw cr1, r20, r26 + addi r19, r19, 4 + addi r18, r18, 4 + fmr f15, f14 + cmpw cr5, r19, r25 + fadds f14, f14, f16 + cmpw cr6, r18, r25 + bne+ L_00000870 + li r21, 0 +L_00000870: + fmadds f9, f2, f17, f14 + bne+ cr1, L_0000087C + li r20, 0 +L_0000087C: + bne+ cr5, L_00000884 + li r19, 0 +L_00000884: + stfsx f9, r17, r12 + fnmsubs f14, f2, f9, f17 + addi r12, r12, 4 + bne+ cr6, L_00000898 + li r18, 0 +L_00000898: + lfsx f17, r17, r11 + cmpw cr5, r12, r24 + addi r11, r11, 4 + cmpw cr6, r11, r24 + bne+ cr5, L_000008B0 + li r12, 0 +L_000008B0: + bne+ cr6, L_000008B8 + li r11, 0 +L_000008B8: + fmuls f14, f14, f6 + fmadds f14, f11, f7, f14 + mulli r31, r5, 0x28 // sizeof(AXFX_REVSTD_DELAYLINE * 2) + fmadds f9, f2, f18, f14 + fmr f7, f14 + addi r29, rv, AXFX_REVSTD_WORK.C + add r29, r29, r31 + stfsx f9, r6, r10 + fnmsubs f14, f2, f9, f18 + fmuls f8, f4, f12 + lfsx f18, r6, r9 + addi r10, r10, 4 + addi r9, r9, 4 + fmadds f14, f3, f14, f8 + cmpw cr5, r10, r23 + cmpw cr6, r9, r23 + fctiwz f14, f14 + bne+ cr5, L_00000904 + li r10, 0 +L_00000904: + bne+ cr6, L_0000090C + li r9, 0 +L_0000090C: + addi r30, rv, AXFX_REVSTD_WORK.AP + add r30, r30, r31 + stfiwx f14, r0, sptr + stw r21, AXFX_REVSTD_DELAYLINE.inPoint + 0x00(r29) // C array + 0 + stw r20, AXFX_REVSTD_DELAYLINE.outPoint + 0x00(r29) // C array + 0 + stw r19, AXFX_REVSTD_DELAYLINE.inPoint + 0x14(r29) // C array + 1 + stw r18, AXFX_REVSTD_DELAYLINE.outPoint + 0x14(r29) // C array + 1 + addi sptr, sptr, 4 + stfs f15, AXFX_REVSTD_DELAYLINE.lastOutput + 0x00(r29) // C array + 0 + stfs f16, AXFX_REVSTD_DELAYLINE.lastOutput + 0x14(r29) // C array + 1 + slwi r31, r5, 2 + add r31, r31, rv + addi r5, r5, 1 + stw r12, AXFX_REVSTD_DELAYLINE.inPoint + 0x00(r30) // AP array + 0 + stw r11, AXFX_REVSTD_DELAYLINE.outPoint + 0x00(r30) // AP array + 0 + stw r10, AXFX_REVSTD_DELAYLINE.inPoint + 0x14(r30) // AP array + 1 + stw r9, AXFX_REVSTD_DELAYLINE.outPoint + 0x14(r30) // AP array + 1 + cmpwi r5, 3 + stfs f17, AXFX_REVSTD_DELAYLINE.lastOutput + 0x00(r30) // AP array + 0 + stfs f18, AXFX_REVSTD_DELAYLINE.lastOutput + 0x14(r30) // AP array + 1 + stfs f7, AXFX_REVSTD_WORK.lpLastout(r31) + stw r28, AXFX_REVSTD_WORK.preDelayPtr(r31) + bne L_00000638 + lfd f14, 88(r1) + lfd f15, 96(r1) + lfd f16, 104(r1) + lfd f17, 112(r1) + lfd f18, 120(r1) + lfd f19, 128(r1) + lfd f20, 136(r1) + lmw r17, 8(r1) + addi r1, r1, 144 + blr +} + +static void ReverbSTDCallback(s32* left, s32* right, s32* surround, AXFX_REVSTD_WORK* rv) { + HandleReverb(left, rv); +} + +static void ReverbSTDFree(AXFX_REVSTD_WORK* rv) { + u8 i; + + for (i = 0; i < 6; i++) { + if (rv->AP[i].inputs != 0) { + DLdelete(&rv->AP[i]); + rv->AP[i].inputs = NULL; + } + } + + for (i = 0; i < 6; i++) { + if (rv->C[i].inputs != 0) { + DLdelete(&rv->C[i]); + rv->C[i].inputs = NULL; + } + } + + if (rv->preDelayTime) { + for (i = 0; i < 3; i++) { + if (rv->preDelayLine[i] != 0) { + __AXFXFree(rv->preDelayLine[i]); + rv->preDelayLine[i] = NULL; + } + } + } +} + +int AXFXReverbStdInit(AXFX_REVERBSTD* rev) { + int ret; + BOOL old; + + old = OSDisableInterrupts(); + rev->tempDisableFX = 0; + ret = ReverbSTDCreate(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, rev->preDelay); + OSRestoreInterrupts(old); + return ret; +} + +int AXFXReverbStdShutdown(AXFX_REVERBSTD* rev) { + BOOL old; + + old = OSDisableInterrupts(); + ReverbSTDFree(&rev->rv); + OSRestoreInterrupts(old); + return 1; +} + +int AXFXReverbStdSettings(AXFX_REVERBSTD* rev) { + int ret; + BOOL old; + + old = OSDisableInterrupts(); + rev->tempDisableFX = 1; + ret = ReverbSTDModify(&rev->rv, rev->coloration, rev->time, rev->mix, rev->damping, rev->preDelay); + rev->tempDisableFX = 0; + OSRestoreInterrupts(old); + return ret; +} + +void AXFXReverbStdCallback(AXFX_BUFFERUPDATE* bufferUpdate, AXFX_REVERBSTD* reverb) { + if (reverb->tempDisableFX == 0) { + ReverbSTDCallback(bufferUpdate->left, bufferUpdate->right, bufferUpdate->surround, &reverb->rv); + } +} diff --git a/src/dolphin/base/PPCArch.c b/src/dolphin/base/PPCArch.c index 9c3fade3db..511f1022e9 100644 --- a/src/dolphin/base/PPCArch.c +++ b/src/dolphin/base/PPCArch.c @@ -1,118 +1,199 @@ -#include "dolphin/base/PPCArch.h" -// clang-format off +#include +#include -/* 80339CC0-80339CC8 -00001 0008+00 0/0 0/0 0/0 .text PPCMfmsr */ -asm u32 PPCMfmsr(void) { - nofralloc - mfmsr r3 - blr +asm u32 PPCMfmsr() { + nofralloc + mfmsr r3 + blr } -/* 80339CC8-80339CD0 -00001 0008+00 0/0 0/0 0/0 .text PPCMtmsr */ asm void PPCMtmsr(register u32 newMSR) { - nofralloc - mtmsr newMSR - blr + nofralloc + mtmsr newMSR + blr } -/* 80339CD0-80339CD8 -00001 0008+00 0/0 0/0 0/0 .text PPCMfhid0 */ -asm u32 PPCMfhid0(void) { - nofralloc - mfspr r3, HID0 - blr +asm u32 PPCOrMsr(register u32 value) { + nofralloc + mfmsr r4 + or value, r4, value + blr +} + +asm u32 PPCAndMsr(register u32 value) { + nofralloc + mfmsr r4 + and value, r4, value + blr +} + +asm u32 PPCAndCMsr(register u32 value) { + nofralloc + mfmsr r4 + andc value, r4, value + blr +} + +asm u32 PPCMfhid0() { + nofralloc + mfspr r3, HID0 + blr } -/* 80339CD8-80339CE0 -00001 0008+00 0/0 0/0 0/0 .text PPCMthid0 */ asm void PPCMthid0(register u32 newHID0) { - nofralloc - mtspr HID0, newHID0 - blr + nofralloc + mtspr HID0, newHID0 + blr } -/* 80339CE0-80339CE8 -00001 0008+00 0/0 0/0 0/0 .text PPCMfl2cr */ -asm u32 PPCMfl2cr(void) { - nofralloc - mfspr r3, L2CR - blr +asm u32 PPCMfhid1() { + nofralloc + mfspr r3, HID1 + blr +} + +asm u32 PPCMfl2cr() { + nofralloc + mfspr r3, L2CR + blr } -/* 80339CE8-80339CF0 -00001 0008+00 0/0 0/0 0/0 .text PPCMtl2cr */ asm void PPCMtl2cr(register u32 newL2cr) { - nofralloc - mtspr L2CR, newL2cr - blr + nofralloc + mtspr L2CR, newL2cr + blr } -/* 80339CF0-80339CF8 -00001 0008+00 0/0 0/0 0/0 .text PPCMtdec */ asm void PPCMtdec(register u32 newDec) { - nofralloc - mtdec newDec - blr + nofralloc + mtdec newDec + blr } -/* 80339CF8-80339D00 -00001 0008+00 0/0 0/0 0/0 .text PPCSync */ -asm void PPCSync(void) { - nofralloc - sc - blr +asm u32 PPCMfdec() { + nofralloc + mfdec r3 + blr } -/* 80339D00-80339D14 334640 0014+00 0/0 7/7 0/0 .text PPCHalt */ -asm void PPCHalt(void) { +asm void PPCSync() { + nofralloc + sc + blr +} + +asm void PPCEieio() { + nofralloc + mfmsr r5 + rlwinm r6, r5, 0, 17, 15 + mtmsr r6 + mfspr r3, HID0 + ori r4, r3, 0x8 + mtspr HID0, r4 + isync + eieio + isync + mtspr HID0, r3 + mtmsr r5 + isync + blr +} + +asm void PPCHalt() { nofralloc sync - -_spin: +loop: nop li r3, 0 nop - b _spin + b loop +} + +asm u32 PPCMfmmcr0() { + nofralloc + mfspr r3, MMCR0 + blr } -/* 80339D14-80339D1C -00001 0008+00 0/0 0/0 0/0 .text PPCMtmmcr0 */ asm void PPCMtmmcr0(register u32 newMmcr0) { - nofralloc - mtspr MMCR0, newMmcr0 - blr + nofralloc + mtspr MMCR0, newMmcr0 + blr +} + +asm u32 PPCMfmmcr1() { + nofralloc + mfspr r3, MMCR1 + blr } -/* 80339D1C-80339D24 -00001 0008+00 0/0 0/0 0/0 .text PPCMtmmcr1 */ asm void PPCMtmmcr1(register u32 newMmcr1) { - nofralloc - mtspr MMCR1, newMmcr1 - blr + nofralloc + mtspr MMCR1, newMmcr1 + blr +} + +asm u32 PPCMfpmc1() { + nofralloc + mfspr r3, PMC1 + blr } -/* 80339D24-80339D2C -00001 0008+00 0/0 0/0 0/0 .text PPCMtpmc1 */ asm void PPCMtpmc1(register u32 newPmc1) { - nofralloc - mtspr PMC1, newPmc1 - blr + nofralloc + mtspr PMC1, newPmc1 + blr +} + +asm u32 PPCMfpmc2() { + nofralloc + mfspr r3, PMC2 + blr } -/* 80339D2C-80339D34 -00001 0008+00 0/0 0/0 0/0 .text PPCMtpmc2 */ asm void PPCMtpmc2(register u32 newPmc2) { - nofralloc - mtspr PMC2, newPmc2 - blr + nofralloc + mtspr PMC2, newPmc2 + blr +} + +asm u32 PPCMfpmc3() { + nofralloc + mfspr r3, PMC3 + blr } -/* 80339D34-80339D3C -00001 0008+00 0/0 0/0 0/0 .text PPCMtpmc3 */ asm void PPCMtpmc3(register u32 newPmc3) { - nofralloc - mtspr PMC3, newPmc3 - blr + nofralloc + mtspr PMC3, newPmc3 + blr +} + +asm u32 PPCMfpmc4() { + nofralloc + mfspr r3, PMC4 + blr } -/* 80339D3C-80339D44 -00001 0008+00 0/0 0/0 0/0 .text PPCMtpmc4 */ asm void PPCMtpmc4(register u32 newPmc4) { - nofralloc - mtspr PMC4, newPmc4 - blr + nofralloc + mtspr PMC4, newPmc4 + blr } -/* 80339D44-80339D64 334684 0020+00 0/0 2/2 0/0 .text PPCMffpscr */ -u32 PPCMffpscr(void) { +asm u32 PPCMfsia() { + nofralloc + mfspr r3, SIA + blr +} + +asm void PPCMtsia(register u32 newSia) { + nofralloc + mtspr SIA, newSia + blr +} + +u32 PPCMffpscr() { union FpscrUnion m; asm { @@ -120,10 +201,9 @@ u32 PPCMffpscr(void) { stfd fp31, m.f; } - return m.u.fpscr; + return m.u.fpscr; } -/* 80339D64-80339D8C 3346A4 0028+00 0/0 2/2 0/0 .text PPCMtfpscr */ void PPCMtfpscr(register u32 newFPSCR) { union FpscrUnion m; @@ -136,36 +216,77 @@ void PPCMtfpscr(register u32 newFPSCR) { } } -/* 80339D8C-80339D94 -00001 0008+00 0/0 0/0 0/0 .text PPCMfhid2 */ -asm u32 PPCMfhid2(void) { - nofralloc - mfspr r3, HID2 - blr +asm u32 PPCMfhid2() { + nofralloc + mfspr r3, HID2 + blr } -/* 80339D94-80339D9C -00001 0008+00 0/0 0/0 0/0 .text PPCMthid2 */ asm void PPCMthid2(register u32 newhid2) { - nofralloc - mtspr HID2, newhid2 - blr + nofralloc + mtspr HID2, newhid2 + blr +} + +asm u32 PPCMfwpar() { + nofralloc + sync + mfspr r3, WPAR + blr } -/* 80339D9C-80339DA4 -00001 0008+00 0/0 0/0 0/0 .text PPCMtwpar */ asm void PPCMtwpar(register u32 newwpar) { - nofralloc - mtspr WPAR, newwpar - blr + nofralloc + mtspr WPAR, newwpar + blr +} + +asm u32 PPCMfdmaU() { + nofralloc + mfspr r3, DMA_U + blr +} + +asm u32 PPCMfdmaL() { + nofralloc + mfspr r3, DMA_L + blr +} + +asm void PPCMtdmaU(register u32 newdmau) { + nofralloc + mtspr DMA_U, newdmau + blr +} + +asm void PPCMtdmaL(register u32 newdmal) { + nofralloc + mtspr DMA_L, newdmal + blr +} + +asm u32 PPCMfpvr() { + nofralloc + mfspr r3, PVR + blr +} + +void PPCEnableSpeculation(void) { + PPCMthid0(PPCMfhid0() & ~HID0_SPD); } -/* 80339DA4-80339DCC 3346E4 0028+00 0/0 1/1 0/0 .text PPCDisableSpeculation */ void PPCDisableSpeculation(void) { PPCMthid0(PPCMfhid0() | HID0_SPD); } -/* 80339DCC-80339DD4 -00001 0008+00 0/0 0/0 0/0 .text PPCSetFpNonIEEEMode */ +asm void PPCSetFpIEEEMode() { + nofralloc + mtfsb0 29 + blr +} + asm void PPCSetFpNonIEEEMode() { nofralloc mtfsb1 29 blr } -// clang-format on \ No newline at end of file diff --git a/src/dolphin/base/PPCPm.c b/src/dolphin/base/PPCPm.c new file mode 100644 index 0000000000..d5ffcb4bb0 --- /dev/null +++ b/src/dolphin/base/PPCPm.c @@ -0,0 +1,34 @@ +#include +#include + +void PMBegin(void) { + PPCMtmmcr0(0); + PPCMtmmcr1(0); + PPCMtpmc1(0); + PPCMtpmc2(0); + PPCMtpmc3(0); + PPCMtpmc4(0); + PPCMtmmcr0(0x4F); + PPCMtmmcr1(0x78800000); +} + +void PMEnd(void) { + PPCMtmmcr0(0); + PPCMtmmcr1(0); +} + +void PMCycles(void) { + PPCMfpmc1(); +} + +void PML1FetchMisses(void) { + PPCMfpmc2(); +} + +void PML1MissCycles(void) { + PPCMfpmc3(); +} + +void PMInstructions(void) { + PPCMfpmc4(); +} diff --git a/src/dolphin/card/CARDBios.c b/src/dolphin/card/CARDBios.c index 88206f3122..e29345675a 100644 --- a/src/dolphin/card/CARDBios.c +++ b/src/dolphin/card/CARDBios.c @@ -1,36 +1,48 @@ -#include "dolphin/card.h" -#include "dolphin/os.h" -#include "dolphin/card/CARDPriv.h" +#include -/* 80450A60-80450A68 -00001 0004+04 1/1 0/0 0/0 .sdata __CARDVersion */ -char* __CARDVersion = "<< Dolphin SDK - CARD\trelease build: Apr 5 2004 04:15:35 (0x2301) >>"; +#include "__card.h" -static BOOL OnReset(BOOL); -static void TimeoutHandler(OSAlarm* alarm, OSContext* context); -static s32 Retry(s32 chan); -static void UnlockedCallback(s32 chan, s32 result); +#if DEBUG +const char* __CARDVersion = "<< Dolphin SDK - CARD\tdebug build: Apr 5 2004 03:56:53 (0x2301) >>"; +#else +const char* __CARDVersion = "<< Dolphin SDK - CARD\trelease build: Apr 5 2004 04:15:35 (0x2301) >>"; +#endif -/* 80352A30-80352A34 34D370 0004+00 0/0 5/5 0/0 .text __CARDDefaultApiCallback */ -void __CARDDefaultApiCallback(s32 chan, s32 result) {} +u32 __CARDFreq = EXI_FREQ_16M; -/* 8044CDE0-8044CE00 079B00 0020+00 0/1 3/3 0/0 .bss __CARDDiskNone */ -DVDDiskID __CARDDiskNone; - -/* 8044CBC0-8044CDE0 0798E0 0220+00 16/16 27/27 0/0 .bss __CARDBlock */ CARDControl __CARDBlock[2]; -/* 80352A34-80352A68 34D374 0034+00 0/0 7/7 0/0 .text __CARDSyncCallback */ +static u16 __CARDEncode; +static u16 __CARDFastMode; + +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); + +static OSResetFunctionInfo ResetFunctionInfo = {OnReset, 127}; + +void __CARDDefaultApiCallback(s32 chan, s32 result) {} + void __CARDSyncCallback(s32 chan, s32 result) { - OSWakeupThread(&__CARDBlock[chan].threadQueue); + CARDControl* card; + card = &__CARDBlock[chan]; + OSWakeupThread(&card->threadQueue); } -/* 80352A68-80352B40 34D3A8 00D8+00 0/0 1/1 0/0 .text __CARDExtHandler */ 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); @@ -53,13 +65,13 @@ void __CARDExtHandler(s32 chan, OSContext* context) { } } -/* 80352B40-80352C58 34D480 0118+00 0/0 1/1 0/0 .text __CARDExiHandler */ 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); @@ -77,12 +89,12 @@ void __CARDExiHandler(s32 chan, OSContext* context) { goto error; } - if ((result = (status & 0x18) ? CARD_RESULT_IOERROR : CARD_RESULT_READY) == - CARD_RESULT_IOERROR && + if ((result = (status & 0x18) ? CARD_RESULT_IOERROR : CARD_RESULT_READY) == CARD_RESULT_IOERROR && --card->retry > 0) { result = Retry(chan); - if (result >= 0) { + if (result >= 0) + { return; } goto fatal; @@ -99,28 +111,29 @@ fatal: } } -/* 80352C58-80352D00 34D598 00A8+00 3/3 0/0 0/0 .text __CARDTxHandler */ void __CARDTxHandler(s32 chan, OSContext* context) { CARDControl* card; CARDCallback callback; - BOOL err; + int err; + ASSERTLINE(365, 0 <= chan && chan < 2); + card = &__CARDBlock[chan]; err = !EXIDeselect(chan); EXIUnlock(chan); callback = card->txCallback; - if (callback) { - card->txCallback = 0; + card->txCallback = NULL; callback(chan, (!err && EXIProbe(chan)) ? CARD_RESULT_READY : CARD_RESULT_NOCARD); } } -/* 80352D00-80352D84 34D640 0084+00 2/2 2/2 0/0 .text __CARDUnlockedHandler */ void __CARDUnlockedHandler(s32 chan, OSContext* context) { CARDControl* card; CARDCallback callback; + ASSERTLINE(412, 0 <= chan && chan < 2); + card = &__CARDBlock[chan]; callback = card->unlockCallback; if (callback) { @@ -129,80 +142,123 @@ void __CARDUnlockedHandler(s32 chan, OSContext* context) { } } -/* 80352D84-80352E44 34D6C4 00C0+00 0/0 1/1 0/0 .text __CARDEnableInterrupt */ s32 __CARDEnableInterrupt(s32 chan, BOOL enable) { BOOL err; u32 cmd; - if (!EXISelect(chan, 0, 4)) { + ASSERTLINE(431, 0 <= chan && chan < 2); + + if (!EXISelect(chan, 0, CARDFreq)) { return CARD_RESULT_NOCARD; } cmd = enable ? 0x81010000 : 0x81000000; err = FALSE; - err |= !EXIImm(chan, &cmd, 2, 1, NULL); + err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, NULL); err |= !EXISync(chan); err |= !EXIDeselect(chan); return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; } -/* 80352E44-80352F34 34D784 00F0+00 1/1 2/2 0/0 .text __CARDReadStatus */ s32 __CARDReadStatus(s32 chan, u8* status) { BOOL err; u32 cmd; - if (!EXISelect(chan, 0, 4)) { + ASSERTLINE(450, 0 <= chan && chan < 2); + + if (!EXISelect(chan, 0, CARDFreq)) { return CARD_RESULT_NOCARD; } cmd = 0x83000000; err = FALSE; - err |= !EXIImm(chan, &cmd, 2, 1, NULL); + err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, NULL); err |= !EXISync(chan); - err |= !EXIImm(chan, status, 1, 0, NULL); + err |= !EXIImm(chan, status, 1, EXI_READ, NULL); err |= !EXISync(chan); err |= !EXIDeselect(chan); return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; } -/* 80352F34-80353024 34D874 00F0+00 0/0 1/1 0/0 .text __CARDReadVendorID */ -s32 __CARDReadVendorID(s32 chan, u16* vendorId) { +int __CARDReadVendorID(s32 chan, u16* id) { BOOL err; u32 cmd; - if (!EXISelect(chan, 0, 4)) { + ASSERTLINE(471, 0 <= chan && chan < 2); + + if (!EXISelect(chan, 0, CARDFreq)) { return CARD_RESULT_NOCARD; } - cmd = 0x85000000; - err = FALSE; - err |= !EXIImm(chan, &cmd, 2, 1, NULL); + err = 0; + err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, 0); err |= !EXISync(chan); - err |= !EXIImm(chan, vendorId, 2, 0, NULL); + err |= !EXIImm(chan, id, 2, EXI_READ, 0); err |= !EXISync(chan); err |= !EXIDeselect(chan); return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; } -/* 80353024-803530D0 34D964 00AC+00 1/1 1/1 0/0 .text __CARDClearStatus */ s32 __CARDClearStatus(s32 chan) { BOOL err; u32 cmd; - if (!EXISelect(chan, 0, 4)) { + ASSERTLINE(492, 0 <= chan && chan < 2); + + if (!EXISelect(chan, 0, CARDFreq)) { return CARD_RESULT_NOCARD; } cmd = 0x89000000; err = FALSE; - err |= !EXIImm(chan, &cmd, 1, 1, 0); + err |= !EXIImm(chan, &cmd, 1, EXI_WRITE, 0); err |= !EXISync(chan); err |= !EXIDeselect(chan); return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; } -/* 803530D0-80353174 34DA10 00A4+00 2/2 0/0 0/0 .text TimeoutHandler */ +s32 __CARDSleep(s32 chan) { + int err; + u32 cmd; + + ASSERTLINE(511, 0 <= chan && chan < 2); + + if (!EXISelect(chan, 0, CARDFreq)) { + return CARD_RESULT_NOCARD; + } + cmd = 0x88000000; + err = 0; + err |= !EXIImm(chan, &cmd, 1, EXI_WRITE, 0); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + + if(err) { + return CARD_RESULT_NOCARD; + } + return CARD_RESULT_READY; +} + +s32 __CARDWakeup(s32 chan) { + int err; + u32 cmd; + + ASSERTLINE(530, 0 <= chan && chan < 2); + if (!EXISelect(chan, 0, CARDFreq)) { + return CARD_RESULT_NOCARD; + } + cmd = 0x87000000; + err = 0; + err |= !EXIImm(chan, &cmd, 1, EXI_WRITE, 0); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + + if(err) { + return CARD_RESULT_NOCARD; + } + return CARD_RESULT_READY; +} + static void TimeoutHandler(OSAlarm* alarm, OSContext* context) { s32 chan; CARDControl* card; @@ -214,6 +270,8 @@ static void TimeoutHandler(OSAlarm* alarm, OSContext* context) { } } + ASSERTLINE(578, 0 <= chan && chan < 2); + if (!card->attached) { return; } @@ -229,8 +287,9 @@ static void TimeoutHandler(OSAlarm* alarm, OSContext* context) { static void SetupTimeoutAlarm(CARDControl* card) { OSCancelAlarm(&card->alarm); switch (card->cmd[0]) { - case 0xF2: - OSSetAlarm(&card->alarm, OSMillisecondsToTicks(100), TimeoutHandler); + case 0xF2: + OSSetAlarm(&card->alarm, OSMillisecondsToTicks(100), + TimeoutHandler); break; case 0xF3: break; @@ -244,31 +303,30 @@ static void SetupTimeoutAlarm(CARDControl* card) { OSSetAlarm(&card->alarm, OSSecondsToTicks((OSTime)2) * (card->sectorSize / 0x2000), TimeoutHandler); break; - default: - break; } } -/* 80353174-80353414 34DAB4 02A0+00 2/2 0/0 0/0 .text Retry */ static s32 Retry(s32 chan) { CARDControl* card; - card = &__CARDBlock[chan]; - if (!EXISelect(chan, 0, 4)) { + ASSERTLINE(654, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + if (!EXISelect(chan, 0, CARDFreq)) { EXIUnlock(chan); return CARD_RESULT_NOCARD; } SetupTimeoutAlarm(card); - if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1)) { + 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, 1)) + !EXIImmEx(chan, (u8* )card->workArea + sizeof(CARDID), card->latency, EXI_WRITE)) { EXIDeselect(chan); EXIUnlock(chan); @@ -281,8 +339,8 @@ static s32 Retry(s32 chan) { return CARD_RESULT_READY; } - if (!EXIDma(chan, card->buffer, (s32)((card->cmd[0] == 0x52) ? 512 : card->pageSize), - card->mode, __CARDTxHandler)) + if (!EXIDma(chan, card->buffer, (s32)((card->cmd[0] == 0x52) ? 512 : card->pageSize), card->mode, + __CARDTxHandler)) { EXIDeselect(chan); EXIUnlock(chan); @@ -292,11 +350,12 @@ static s32 Retry(s32 chan) { return CARD_RESULT_READY; } -/* 80353414-80353524 34DD54 0110+00 1/1 0/0 0/0 .text UnlockedCallback */ 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; @@ -313,10 +372,9 @@ static void UnlockedCallback(s32 chan, s32 result) { case 0x52: callback = card->txCallback; if (callback) { - card->txCallback = 0; + card->txCallback = NULL; callback(chan, result); } - break; case 0xF2: case 0xF4: @@ -331,7 +389,6 @@ static void UnlockedCallback(s32 chan, s32 result) { } } -/* 80353524-80353748 34DE64 0224+00 3/3 0/0 0/0 .text __CARDStart */ static s32 __CARDStart(s32 chan, CARDCallback txCallback, CARDCallback exiCallback) { BOOL enabled; CARDControl* card; @@ -339,6 +396,8 @@ static s32 __CARDStart(s32 chan, CARDCallback txCallback, CARDCallback exiCallba enabled = OSDisableInterrupts(); + ASSERTLINE(784, 0 <= chan && chan < 2); + card = &__CARDBlock[chan]; if (!card->attached) { result = CARD_RESULT_NOCARD; @@ -346,16 +405,19 @@ static s32 __CARDStart(s32 chan, CARDCallback txCallback, CARDCallback exiCallba 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)) { + if (!EXISelect(chan, 0, CARDFreq)) { EXIUnlock(chan); result = CARD_RESULT_NOCARD; } else { @@ -373,14 +435,18 @@ static s32 __CARDStart(s32 chan, CARDCallback txCallback, CARDCallback exiCallba #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)) +#define BA(x) ((u8)((x)&0x7f)) -/* 80353748-8035387C 34E088 0134+00 0/0 2/2 0/0 .text __CARDReadSegment */ 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); @@ -394,12 +460,12 @@ s32 __CARDReadSegment(s32 chan, CARDCallback callback) { if (result == CARD_RESULT_BUSY) { result = CARD_RESULT_READY; } else if (result >= 0) { - if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1) || - !EXIImmEx(chan, (u8*)card->workArea + sizeof(CARDID), card->latency, - 1) || // XXX use DMA if possible + 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 = 0; + card->txCallback = NULL; EXIDeselect(chan); EXIUnlock(chan); result = CARD_RESULT_NOCARD; @@ -407,17 +473,21 @@ s32 __CARDReadSegment(s32 chan, CARDCallback callback) { result = CARD_RESULT_READY; } } + return result; } -/* 8035387C-803539B8 34E1BC 013C+00 0/0 2/2 0/0 .text __CARDWritePage */ s32 __CARDWritePage(s32 chan, CARDCallback callback) { CARDControl* card; s32 result; - card = &__CARDBlock[chan]; + 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; + if (card->pageSize > 0x80) { card->cmd[1] = AD1(card->addr) | 0x80; } else { @@ -435,7 +505,7 @@ s32 __CARDWritePage(s32 chan, CARDCallback callback) { if (result == CARD_RESULT_BUSY) { result = CARD_RESULT_READY; } else if (result >= 0) { - if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1) || + if (!EXIImmEx(chan, card->cmd, card->cmdlen, EXI_WRITE) || !EXIDma(chan, card->buffer, card->pageSize, card->mode, __CARDTxHandler)) { card->exiCallback = 0; @@ -446,21 +516,58 @@ s32 __CARDWritePage(s32 chan, CARDCallback callback) { result = CARD_RESULT_READY; } } + + return result; +} + +s32 __CARDErase(s32 chan, CARDCallback callback) { + CARDControl* card; + s32 result; + + ASSERTLINE(962, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + card->cmd[0] = 0xF4; + card->cmd[1] = 0; + card->cmd[2] = 0; + 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) == 0) { + result = CARD_RESULT_NOCARD; + card->exiCallback = 0; + } else { + result = CARD_RESULT_READY; + } + + EXIDeselect(chan); + EXIUnlock(chan); + } + return result; } -/* 803539B8-80353AC8 34E2F8 0110+00 0/0 6/6 0/0 .text __CARDEraseSector */ 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); + if (card->pageSize > 0x80) { if (callback) { callback(chan, 0); } return 0; } + card->cmd[0] = 0xF1; card->cmd[1] = AD1(addr); card->cmd[2] = AD2(addr); @@ -473,9 +580,9 @@ s32 __CARDEraseSector(s32 chan, u32 addr, CARDCallback callback) { if (result == CARD_RESULT_BUSY) { result = CARD_RESULT_READY; } else if (result >= 0) { - if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1)) { - card->exiCallback = NULL; + if (!EXIImmEx(chan, card->cmd, card->cmdlen, EXI_WRITE)) { result = CARD_RESULT_NOCARD; + card->exiCallback = NULL; } else { result = CARD_RESULT_READY; } @@ -486,22 +593,6 @@ s32 __CARDEraseSector(s32 chan, u32 addr, CARDCallback callback) { return result; } -/* 803D1E80-803D1EA0 -00001 0010+10 1/1 0/0 0/0 .data ResetFunctionInfo */ -static OSResetFunctionInfo ResetFunctionInfo = { - OnReset, - 127, - NULL, - NULL, -}; - -/* 80451918-80451920 -00001 0004+04 3/3 0/0 0/0 .sbss None */ -/* 80451918 0002+00 data_80451918 __CARDEncode */ -static u16 __CARDEncode; - -/* 8045191A 0002+00 data_8045191A __CARDFastMode */ -static u16 __CARDFastMode; - -/* 80353AC8-80353B74 34E408 00AC+00 0/0 1/1 0/0 .text CARDInit */ void CARDInit(void) { int chan; @@ -523,34 +614,69 @@ void CARDInit(void) { OSInitThreadQueue(&card->threadQueue); OSCreateAlarm(&card->alarm); } - __CARDSetDiskID((DVDDiskID*)OSPhysicalToCached(0x0)); + __CARDSetDiskID((void*)OSPhysicalToCached(0)); OSRegisterResetFunction(&ResetFunctionInfo); } -/* 80353B74-80353B7C 34E4B4 0008+00 0/0 2/2 0/0 .text __CARDGetFontEncode */ u16 __CARDGetFontEncode(void) { return __CARDEncode; } -/* 80353B7C-80353BB4 34E4BC 0038+00 1/1 0/0 0/0 .text __CARDSetDiskID */ +u16 __CARDSetFontEncode(u16 encode) { + u16 prev = __CARDEncode; + + switch (encode) { + case CARD_ENCODE_ANSI: + case CARD_ENCODE_SJIS: + __CARDEncode = encode; + break; + } + + return prev; +} + void __CARDSetDiskID(const DVDDiskID* id) { __CARDBlock[0].diskID = id ? id : &__CARDDiskNone; __CARDBlock[1].diskID = id ? id : &__CARDDiskNone; } -/* 80353BB4-80353C6C 34E4F4 00B8+00 1/1 10/10 0/0 .text __CARDGetControlBlock */ +const DVDDiskID* CARDGetDiskID(s32 chan) { + ASSERTLINE(1168, 0 <= chan && chan < 2); + return __CARDBlock[chan].diskID; +} + +s32 CARDSetDiskID(s32 chan, const DVDDiskID* diskID) { + BOOL enabled; + CARDControl* card; + + card = &__CARDBlock[chan]; + ASSERTLINE(1189, 0 <= chan && chan < 2); + + enabled = OSDisableInterrupts(); + + if (card->result == CARD_RESULT_BUSY) { + return CARD_RESULT_BUSY; + } + + card->diskID = diskID != 0 ? diskID : (const DVDDiskID*)OSPhysicalToCached(0); + OSRestoreInterrupts(enabled); + return 0; +} + s32 __CARDGetControlBlock(s32 chan, CARDControl** pcard) { BOOL enabled; s32 result; CARDControl* card; card = &__CARDBlock[chan]; - if (chan < 0 || chan >= 2 || card->diskID == NULL) { + + 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) { @@ -558,28 +684,42 @@ s32 __CARDGetControlBlock(s32 chan, CARDControl** pcard) { } else { card->result = CARD_RESULT_BUSY; result = CARD_RESULT_READY; - card->apiCallback = 0; + card->apiCallback = NULL; *pcard = card; } + OSRestoreInterrupts(enabled); return result; } -/* 80353C6C-80353CD0 34E5AC 0064+00 0/0 24/24 0/0 .text __CARDPutControlBlock */ 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; } -/* 80353CD0-80353E20 34E610 0150+00 0/0 1/1 0/0 .text CARDFreeBlocks */ +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; @@ -616,16 +756,47 @@ s32 CARDFreeBlocks(s32 chan, s32* byteNotUsed, s32* filesNotUsed) { return __CARDPutControlBlock(card, CARD_RESULT_READY); } -s32 CARDGetResultCode(s32 chan) { +s32 CARDGetEncoding(s32 chan, u16* encode) { CARDControl* card; - if (chan < 0 || chan >= 2) { - return CARD_RESULT_FATAL_ERROR; + CARDID* id; + s32 result; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; } - card = &__CARDBlock[chan]; - return card->result; + + id = card->workArea; + *encode = id->encode; + return __CARDPutControlBlock(card, CARD_RESULT_READY); +} + +s32 CARDGetMemSize(s32 chan, u16* size) { + CARDControl* card; + s32 result; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + *size = card->size; + return __CARDPutControlBlock(card, CARD_RESULT_READY); +} + +s32 CARDGetSectorSize(s32 chan, u32* size) { + CARDControl* card; + s32 result; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + *size = card->sectorSize; + return __CARDPutControlBlock(card, CARD_RESULT_READY); } -/* 80353E20-80353EB8 34E760 0098+00 0/0 7/7 0/0 .text __CARDSync */ s32 __CARDSync(s32 chan) { CARDControl* block; s32 result; @@ -633,16 +804,16 @@ s32 __CARDSync(s32 chan) { block = &__CARDBlock[chan]; enabled = OSDisableInterrupts(); - while ((result = CARDGetResultCode(chan)) == -1) { + while ((result = CARDGetResultCode(chan)) == CARD_RESULT_BUSY) { OSSleepThread(&block->threadQueue); } + OSRestoreInterrupts(enabled); return result; } -/* 80353EB8-80353F08 34E7F8 0050+00 1/0 0/0 0/0 .text OnReset */ -static BOOL OnReset(BOOL f) { - if (!f) { +static BOOL OnReset(BOOL final) { + if (!final) { if (CARDUnmount(0) == CARD_RESULT_BUSY || CARDUnmount(1) == CARD_RESULT_BUSY) { return FALSE; } @@ -651,11 +822,35 @@ static BOOL OnReset(BOOL f) { return TRUE; } -/* 80353F08-80353F24 34E848 001C+00 0/0 1/1 0/0 .text CARDGetFastMode */ +BOOL CARDSetFastMode(BOOL enable) { + u16 prev = __CARDFastMode; + __CARDFastMode = enable ? TRUE : FALSE; + + return prev ? TRUE : FALSE; +} + BOOL CARDGetFastMode(void) { - if (__CARDFastMode != 0) { - return TRUE; + return __CARDFastMode ? TRUE : FALSE; +} + +s32 CARDGetCurrentMode(s32 chan, u32* mode) { + CARDControl* card; + s32 result; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; } - return FALSE; -} \ No newline at end of file + switch (card->pageSize) { + case 512: + *mode = 1; + break; + case 128: + default: + *mode = 0; + break; + } + + return __CARDPutControlBlock(card, CARD_RESULT_READY); +} diff --git a/src/dolphin/card/CARDBlock.c b/src/dolphin/card/CARDBlock.c index ad9ec06746..b7af255ddf 100644 --- a/src/dolphin/card/CARDBlock.c +++ b/src/dolphin/card/CARDBlock.c @@ -1,40 +1,41 @@ -#include "dolphin/card/CARDBlock.h" -#include "dolphin/card.h" -#include "dolphin/card/CARDPriv.h" +#include +#include "__card.h" + +// prototypes static void WriteCallback(s32 chan, s32 result); static void EraseCallback(s32 chan, s32 result); -/* 80355414-8035541C 34FD54 0008+00 0/0 5/5 0/0 .text __CARDGetFatBlock */ -u16* __CARDGetFatBlock(CARDControl* card) { +void* __CARDGetFatBlock(CARDControl* card) { + ASSERTLINE(57, card->currentFat); return card->currentFat; } -/* 8035541C-803554F0 34FD5C 00D4+00 1/1 0/0 0/0 .text WriteCallback */ static void WriteCallback(s32 chan, s32 result) { CARDControl* card; CARDCallback callback; - u16* fat; - u16* fatBack; + u16* fat0; + u16* fat1; card = &__CARDBlock[chan]; if (result >= 0) { - fat = (u16*)((u8*)card->workArea + 0x6000); - fatBack = (u16*)((u8*)card->workArea + 0x8000); + fat0 = (u16*)((u8*)card->workArea + 0x6000); + fat1 = (u16*)((u8*)card->workArea + 0x8000); - if (card->currentFat == fat) { - card->currentFat = fatBack; - memcpy(fatBack, fat, 0x2000); + ASSERTLINE(82, card->currentFat); + if (card->currentFat == fat0) { + card->currentFat = fat1; + memcpy(fat1, fat0, 0x2000); } else { - card->currentFat = fat; - memcpy(fat, fatBack, 0x2000); + ASSERTLINE(90, card->currentFat == fat1); + card->currentFat = fat0; + memcpy(fat0, fat1, 0x2000); } } - if (card->apiCallback == NULL) { + if (!card->apiCallback) __CARDPutControlBlock(card, result); - } callback = card->eraseCallback; if (callback) { @@ -43,32 +44,27 @@ static void WriteCallback(s32 chan, s32 result) { } } -/* 803554F0-803555B8 34FE30 00C8+00 1/1 0/0 0/0 .text EraseCallback */ static void EraseCallback(s32 chan, s32 result) { - CARDControl* card; + CARDControl* card = &__CARDBlock[chan]; CARDCallback callback; - u32 temp[2]; /* this compiler sucks */ u16* fat; u32 addr; - card = &__CARDBlock[chan]; - if (result < 0) { + 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) { + if (result < 0) goto error; - } return; error: - if (card->apiCallback == NULL) { + if (!card->apiCallback) __CARDPutControlBlock(card, result); - } + callback = card->eraseCallback; if (callback) { card->eraseCallback = NULL; @@ -76,7 +72,6 @@ error: } } -/* 803555B8-803556D0 34FEF8 0118+00 0/0 1/1 0/0 .text __CARDAllocBlock */ s32 __CARDAllocBlock(s32 chan, u32 cBlock, CARDCallback callback) { CARDControl* card; u16* fat; @@ -85,57 +80,81 @@ s32 __CARDAllocBlock(s32 chan, u32 cBlock, CARDCallback callback) { u16 prevBlock; u16 count; + ASSERTLINE(182, 0 < cBlock); + ASSERTLINE(183, 0 <= chan && chan < 2); + card = &__CARDBlock[chan]; - if (!card->attached) { + if (!card->attached) return CARD_RESULT_NOCARD; - } fat = __CARDGetFatBlock(card); - if (fat[3] < cBlock) { + 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) { + if (card->cBlock - 5 < ++count) return CARD_RESULT_BROKEN; - } iBlock++; - if (!CARDIsValidBlockNo(card, iBlock)) { + if (!CARDIsValidBlockNo(card, iBlock)) iBlock = 5; - } if (fat[iBlock] == 0x0000u) { - if (startBlock == 0xFFFF) { + if (startBlock == 0xFFFF) startBlock = iBlock; - } else { + else fat[prevBlock] = iBlock; - } prevBlock = iBlock; fat[iBlock] = 0xFFFF; --cBlock; } } + fat[4] = iBlock; card->startBlock = startBlock; + return __CARDUpdateFatBlock(chan, fat, callback); +} + +s32 __CARDFreeBlock(s32 chan, u16 nBlock, CARDCallback callback) { + CARDControl* card; + u16* fat; + u16 nextBlock; + + ASSERTLINE(253, 0 <= chan && chan < 2); + + card = &__CARDBlock[chan]; + if (!card->attached) + return CARD_RESULT_NOCARD; + + fat = __CARDGetFatBlock(card); + while (nBlock != 0xFFFF) { + if (!CARDIsValidBlockNo(card, nBlock)) + return CARD_RESULT_BROKEN; + + nextBlock = fat[nBlock]; + fat[nBlock] = 0; + nBlock = nextBlock; + ++fat[3]; + } return __CARDUpdateFatBlock(chan, fat, callback); } -/* 803556D0-8035577C 350010 00AC+00 1/1 1/1 0/0 .text __CARDUpdateFatBlock */ 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; - - return __CARDEraseSector(chan, (((u32)fat - (u32)card->workArea) / 8192u) * card->sectorSize, - EraseCallback); -} \ No newline at end of file + addr = (((char*)fat - (char*)card->workArea) / 8192u) * card->sectorSize; + return __CARDEraseSector(chan, addr, EraseCallback); +} diff --git a/src/dolphin/card/CARDCheck.c b/src/dolphin/card/CARDCheck.c index e1c6b1b9e4..4a9b78c736 100644 --- a/src/dolphin/card/CARDCheck.c +++ b/src/dolphin/card/CARDCheck.c @@ -1,35 +1,33 @@ -#include "dolphin/card/CARDCheck.h" -#include "dolphin/card.h" -#include "dolphin/card/CARDPriv.h" -#include "dolphin/os/OSRtc.h" +#include +#include "os/__os.h" +#include "__card.h" + +// prototypes static s32 VerifyID(CARDControl* card); -static s32 VerifyDir(CARDControl* card, int* outCurrent); -static s32 VerifyFAT(CARDControl* card, int* outCurrent); +static s32 VerifyDir(CARDControl* card, int* pcurrent); +static s32 VerifyFAT(CARDControl* card, int* pcurrent); -/* 803559E0-80355B90 350320 01B0+00 0/0 3/3 0/0 .text __CARDCheckSum */ 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) { + if (*checksum == 0xFFFF) *checksum = 0; - } - if (*checksumInv == 0xFFFF) { + if (*checksumInv == 0xFFFF) *checksumInv = 0; - } } -/* 80355B90-80355E14 3504D0 0284+00 2/2 0/0 0/0 .text VerifyID */ static s32 VerifyID(CARDControl* card) { CARDID* id; u16 checksum; @@ -40,18 +38,15 @@ static s32 VerifyID(CARDControl* card) { id = card->workArea; - if (id->deviceID != 0 || id->size != card->size) { + 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) { + 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)) { @@ -62,15 +57,14 @@ static s32 VerifyID(CARDControl* card) { } __OSUnlockSramEx(FALSE); - if (id->encode != __CARDGetFontEncode()) { + + if (id->encode != __CARDGetFontEncode()) return CARD_RESULT_ENCODING; - } return CARD_RESULT_READY; } -/* 80355E14-80356054 350754 0240+00 2/2 0/0 0/0 .text VerifyDir */ -static s32 VerifyDir(CARDControl* card, int* outCurrent) { +static s32 VerifyDir(CARDControl* card, int* pcurrent) { CARDDir* dir[2]; CARDDirCheck* check[2]; u16 checkSum; @@ -82,7 +76,7 @@ static s32 VerifyDir(CARDControl* card, int* outCurrent) { 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]); + 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; @@ -93,25 +87,24 @@ static s32 VerifyDir(CARDControl* card, int* outCurrent) { if (0 == errors) { if (card->currentDir == 0) { - if ((check[0]->checkCode - check[1]->checkCode) < 0) { + if ((check[0]->checkCode - check[1]->checkCode) < 0) current = 0; - } else { + else current = 1; - } card->currentDir = dir[current]; memcpy(dir[current], dir[current ^ 1], CARD_SYSTEM_BLOCK_SIZE); } else { current = (card->currentDir == dir[0]) ? 0 : 1; } } - if (outCurrent) { - *outCurrent = current; - } + + if (pcurrent) + *pcurrent = current; + return errors; } -/* 80356054-803562D8 350994 0284+00 2/2 0/0 0/0 .text VerifyFAT */ -static s32 VerifyFAT(CARDControl* card, int* outCurrent) { +static s32 VerifyFAT(CARDControl* card, int* pcurrent) { u16* fat[2]; u16* fatp; u16 nBlock; @@ -126,8 +119,7 @@ static s32 VerifyFAT(CARDControl* card, int* outCurrent) { 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); + __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; @@ -137,10 +129,10 @@ static s32 VerifyFAT(CARDControl* card, int* outCurrent) { cFree = 0; for (nBlock = CARD_NUM_SYSTEM_BLOCK; nBlock < card->cBlock; nBlock++) { - if (fatp[nBlock] == CARD_FAT_AVAIL) { + if (fatp[nBlock] == CARD_FAT_AVAIL) cFree++; - } } + if (cFree != fatp[CARD_FAT_FREEBLOCKS]) { ++errors; current = i; @@ -151,37 +143,36 @@ static s32 VerifyFAT(CARDControl* card, int* outCurrent) { if (0 == errors) { if (card->currentFat == 0) { - if (((s16)fat[0][CARD_FAT_CHECKCODE] - (s16)fat[1][CARD_FAT_CHECKCODE]) < 0) { + if (((s16)fat[0][CARD_FAT_CHECKCODE] - (s16)fat[1][CARD_FAT_CHECKCODE]) < 0) current = 0; - } else { + else current = 1; - } card->currentFat = fat[current]; memcpy(fat[current], fat[current ^ 1], CARD_SYSTEM_BLOCK_SIZE); - } else { + } else current = (card->currentFat == fat[0]) ? 0 : 1; - } - } - if (outCurrent) { - *outCurrent = current; } + + if (pcurrent) + *pcurrent = current; + return errors; } -/* 803562D8-80356364 350C18 008C+00 0/0 1/1 0/0 .text __CARDVerify */ s32 __CARDVerify(CARDControl* card) { s32 result; int errors; result = VerifyID(card); - if (result < 0) { + if (result < 0) return result; - } errors = VerifyDir(card, NULL); errors += VerifyFAT(card, NULL); switch (errors) { - case 0: + case 0: + ASSERTLINE(301, card->currentDir); + ASSERTLINE(302, card->currentFat); return CARD_RESULT_READY; case 1: return CARD_RESULT_BROKEN; @@ -190,7 +181,6 @@ s32 __CARDVerify(CARDControl* card) { } } -/* 80356364-803568F4 350CA4 0590+00 1/1 0/0 0/0 .text CARDCheckExAsync */ s32 CARDCheckExAsync(s32 chan, s32* xferBytes, CARDCallback callback) { CARDControl* card; CARDDir* dir[2]; @@ -208,6 +198,8 @@ s32 CARDCheckExAsync(s32 chan, s32* xferBytes, CARDCallback callback) { BOOL updateDir = FALSE; BOOL updateOrphan = FALSE; + ASSERTLINE(346, 0 <= chan && chan < 2); + if (xferBytes) { *xferBytes = 0; } @@ -233,15 +225,21 @@ s32 CARDCheckExAsync(s32 chan, s32* xferBytes, CARDCallback callback) { 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; @@ -267,6 +265,7 @@ s32 CARDCheckExAsync(s32 chan, s32* xferBytes, CARDCallback callback) { return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); } } + if (cBlock != ent->length || iBlock != 0xFFFF) { return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); } @@ -287,10 +286,12 @@ s32 CARDCheckExAsync(s32 chan, s32* xferBytes, CARDCallback callback) { 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], @@ -322,18 +323,21 @@ s32 CARDCheckExAsync(s32 chan, s32* xferBytes, CARDCallback callback) { return CARD_RESULT_READY; } -/* 803568F4-80356948 351234 0054+00 0/0 2/2 0/0 .text CARDCheck */ -s32 CARDCheck(s32 chan) { +s32 CARDCheckAsync(s32 chan, CARDCallback callback) { s32 xferBytes; + return CARDCheckExAsync(chan, &xferBytes, callback); +} - s32 result = CARDCheckExAsync(chan, &xferBytes, __CARDSyncCallback); - if (result >= 0) { - if (&xferBytes == NULL) { - return result; - } - - return __CARDSync(chan); +s32 CARDCheckEx(s32 chan, s32* xferBytes) { + s32 result = CARDCheckExAsync(chan, xferBytes, __CARDSyncCallback); + if (result < 0 || xferBytes == 0) { + return result; } - return result; -} \ No newline at end of file + return __CARDSync(chan); +} + +s32 CARDCheck(s32 chan) { + s32 xferBytes; + return CARDCheckEx(chan, &xferBytes); +} diff --git a/src/dolphin/card/CARDCreate.c b/src/dolphin/card/CARDCreate.c index 3060ebd22d..7da5ab0911 100644 --- a/src/dolphin/card/CARDCreate.c +++ b/src/dolphin/card/CARDCreate.c @@ -1,11 +1,10 @@ -#include "dolphin/card/CARDCreate.h" -#include "dolphin/card.h" -#include "dolphin/card/CARDPriv.h" -#include "dolphin/dvd.h" +#include +#include "__card.h" + +// prototypes static void CreateCallbackFat(s32 chan, s32 result); -/* 80358108-80358238 352A48 0130+00 1/1 0/0 0/0 .text CreateCallbackFat */ static void CreateCallbackFat(s32 chan, s32 result) { CARDControl* card; CARDDir* dir; @@ -14,54 +13,52 @@ static void CreateCallbackFat(s32 chan, s32 result) { card = &__CARDBlock[chan]; callback = card->apiCallback; - card->apiCallback = 0; - if (result < 0) { - goto error; - } + card->apiCallback = NULL; - 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 = CARD_ATTR_PUBLIC; - ent->copyTimes = 0; - ent->startBlock = card->startBlock; + if (result >= 0) { + dir = __CARDGetDirBlock(card); + ent = &dir[card->freeNo]; + memcpy(ent->gameName, card->diskID->gameName, sizeof(ent->gameName)); + memcpy(ent->company, card->diskID->company, sizeof(ent->company)); + ent->permission = 4; + ent->copyTimes = 0; - ent->bannerFormat = 0; - ent->iconAddr = 0xFFFFFFFF; - ent->iconFormat = 0; - ent->iconSpeed = 0; - ent->commentAddr = 0xFFFFFFFF; + 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 = (u32)OSTicksToSeconds(OSGetTime()); - result = __CARDUpdateDir(chan, callback); - if (result < 0) { - goto error; - } - return; - -error: - __CARDPutControlBlock(card, result); - if (callback) { - callback(chan, result); + 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); + } } } -/* 80358238-80358458 352B78 0220+00 1/1 0/0 0/0 .text CARDCreateAsync */ -s32 CARDCreateAsync(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo, - CARDCallback callback) { +s32 CARDCreateAsync(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo, CARDCallback callback) { CARDControl* card; CARDDir* dir; CARDDir* ent; - s32 result; u16 fileNo; u16 freeNo; u16* fat; + 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; @@ -72,7 +69,9 @@ s32 CARDCreateAsync(s32 chan, const char* fileName, u32 size, CARDFileInfo* file return result; } - if (size <= 0 || (size % card->sectorSize) != 0) { + ASSERTLINE(188, 0 < size && (size % card->sectorSize) == 0); + + if (size <= 0 || (size % card->sectorSize) != 0) { return CARD_RESULT_FATAL_ERROR; } @@ -84,10 +83,9 @@ s32 CARDCreateAsync(s32 chan, const char* fileName, u32 size, CARDFileInfo* file 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)) - { + } else if (memcmp(ent->gameName, card->diskID->gameName, sizeof(ent->gameName)) == 0 && + memcmp(ent->company, card->diskID->company, sizeof(ent->company)) == 0 && + __CARDCompareFileName(ent, fileName)) { return __CARDPutControlBlock(card, CARD_RESULT_EXIST); } } @@ -118,7 +116,6 @@ s32 CARDCreateAsync(s32 chan, const char* fileName, u32 size, CARDFileInfo* file return result; } -/* 80358458-803584A0 352D98 0048+00 0/0 1/1 0/0 .text CARDCreate */ s32 CARDCreate(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo) { s32 result = CARDCreateAsync(chan, fileName, size, fileInfo, __CARDSyncCallback); if (result < 0) { @@ -126,4 +123,4 @@ s32 CARDCreate(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo) } return __CARDSync(chan); -} \ No newline at end of file +} diff --git a/src/dolphin/card/CARDDelete.c b/src/dolphin/card/CARDDelete.c new file mode 100644 index 0000000000..0acf24be1c --- /dev/null +++ b/src/dolphin/card/CARDDelete.c @@ -0,0 +1,108 @@ +#include + +#include "__card.h" + +// prototypes +static void DeleteCallback(s32 chan, s32 result); + +static void DeleteCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + callback = card->apiCallback; + card->apiCallback = NULL; + + if (result < 0) + goto error; + + result = __CARDFreeBlock(chan, card->startBlock, callback); + if (result < 0) + goto error; + return; + +error: + __CARDPutControlBlock(card, result); + if (callback) + callback(chan, result); +} + +s32 CARDFastDeleteAsync(s32 chan, s32 fileNo, CARDCallback callback) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + + ASSERTLINE(133, 0 <= fileNo && fileNo < CARD_MAX_FILE); + ASSERTLINE(134, 0 <= chan && chan < 2); + + 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 = __CARDIsWritable(card, ent); + if (result < 0) + return __CARDPutControlBlock(card, result); + + if (__CARDIsOpened(card, fileNo)) + return __CARDPutControlBlock(card, CARD_RESULT_BUSY); + + card->startBlock = ent->startBlock; + memset(ent, 0xff, sizeof(CARDDir)); + + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + result = __CARDUpdateDir(chan, DeleteCallback); + if (result < 0) + __CARDPutControlBlock(card, result); + return result; +} + +s32 CARDFastDelete(s32 chan, s32 fileNo) { + s32 result = CARDFastDeleteAsync(chan, fileNo, __CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(chan); +} + +s32 CARDDeleteAsync(s32 chan, const char* fileName, CARDCallback callback) { + CARDControl* card; + s32 fileNo; + s32 result; + CARDDir* dir; + CARDDir* ent; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + return result; + result = __CARDGetFileNo(card, fileName, &fileNo); + if (result < 0) + return __CARDPutControlBlock(card, result); + if (__CARDIsOpened(card, fileNo)) + return __CARDPutControlBlock(card, CARD_RESULT_BUSY); + + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + card->startBlock = ent->startBlock; + memset(ent, 0xff, sizeof(CARDDir)); + + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + result = __CARDUpdateDir(chan, DeleteCallback); + if (result < 0) + __CARDPutControlBlock(card, result); + return result; +} + +s32 CARDDelete(s32 chan, const char* fileName) { + s32 result = CARDDeleteAsync(chan, fileName, __CARDSyncCallback); + if (result < 0) + return result; + + return __CARDSync(chan); +} diff --git a/src/dolphin/card/CARDDir.c b/src/dolphin/card/CARDDir.c index 04b0280400..e154a9c428 100644 --- a/src/dolphin/card/CARDDir.c +++ b/src/dolphin/card/CARDDir.c @@ -1,93 +1,84 @@ -#include "dolphin/card/CARDDir.h" -#include "dolphin/card.h" -#include "dolphin/card/CARDPriv.h" +#include +#include "__card.h" + +// prototypes static void WriteCallback(s32 chan, s32 result); static void EraseCallback(s32 chan, s32 result); -/* 8035577C-80355784 3500BC 0008+00 0/0 10/10 0/0 .text __CARDGetDirBlock */ CARDDir* __CARDGetDirBlock(CARDControl* card) { + ASSERTLINE(54, card->currentDir); return card->currentDir; } -/* 80355784-80355854 3500C4 00D0+00 1/1 0/0 0/0 .text WriteCallback */ static void WriteCallback(s32 chan, s32 result) { - CARDControl* card; + CARDControl* card = &__CARDBlock[chan]; CARDCallback callback; - card = &__CARDBlock[chan]; - if (0 <= result) { + 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); } } -error: - if (card->apiCallback == 0) { + if (!card->apiCallback) __CARDPutControlBlock(card, result); - } + callback = card->eraseCallback; if (callback) { - card->eraseCallback = 0; + card->eraseCallback = NULL; callback(chan, result); } } -/* 80355854-8035591C 350194 00C8+00 1/1 0/0 0/0 .text EraseCallback */ static void EraseCallback(s32 chan, s32 result) { - CARDControl* card; + CARDControl* card = &__CARDBlock[chan]; CARDCallback callback; CARDDir* dir; - u32 tmp[2]; u32 addr; - card = &__CARDBlock[chan]; - if (result < 0) { - goto error; + 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; } - dir = __CARDGetDirBlock(card); - addr = ((u32)dir - (u32)card->workArea) / 0x2000 * card->sectorSize; - result = __CARDWrite(chan, addr, 0x2000, dir, WriteCallback); - if (result < 0) { - goto error; - } - - return; - -error: - if (card->apiCallback == 0) { + if (!card->apiCallback) __CARDPutControlBlock(card, result); - } + callback = card->eraseCallback; if (callback) { - card->eraseCallback = 0; + card->eraseCallback = NULL; callback(chan, result); } } -/* 8035591C-803559E0 35025C 00C4+00 0/0 4/4 0/0 .text __CARDUpdateDir */ s32 __CARDUpdateDir(s32 chan, CARDCallback callback) { CARDControl* card; CARDDirCheck* check; - u32 tmp[2]; u32 addr; CARDDir* dir; + ASSERTLINE(173, 0 <= chan && chan < 2); + card = &__CARDBlock[chan]; - if (!card->attached) { + if (!card->attached) return CARD_RESULT_NOCARD; - } dir = __CARDGetDirBlock(card); - check = __CARDGetDirCheck(dir); + check = CARDGetDirCheck(dir); ++check->checkCode; __CARDCheckSum(dir, 0x2000 - sizeof(u32), &check->checkSum, &check->checkSumInv); DCStoreRange(dir, 0x2000); @@ -95,4 +86,4 @@ s32 __CARDUpdateDir(s32 chan, CARDCallback callback) { card->eraseCallback = callback; addr = ((u32)dir - (u32)card->workArea) / 0x2000 * card->sectorSize; return __CARDEraseSector(chan, addr, EraseCallback); -} \ No newline at end of file +} diff --git a/src/dolphin/card/CARDErase.c b/src/dolphin/card/CARDErase.c new file mode 100644 index 0000000000..73bb8ef04b --- /dev/null +++ b/src/dolphin/card/CARDErase.c @@ -0,0 +1,102 @@ +#include + +#include "__card.h" + +static void EraseCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + u16* fat; + CARDDir* dir; + CARDDir* ent; + CARDFileInfo* fileInfo; + + card = &__CARDBlock[chan]; + + if (result >= 0) { + fileInfo = card->fileInfo; + if (fileInfo->length < 0) { + result = CARD_RESULT_CANCELED; + goto error; + } + + fileInfo->length -= card->sectorSize; + if (fileInfo->length <= 0) { + dir = __CARDGetDirBlock(card); + ent = dir + fileInfo->fileNo; + ent->time = OSTicksToSeconds(OSGetTime()); + callback = card->apiCallback; + card->apiCallback = NULL; + + result = __CARDUpdateDir(chan, callback); + } else { + fat = __CARDGetFatBlock(card); + fileInfo->offset += card->sectorSize; + fileInfo->iBlock = fat[fileInfo->iBlock]; + + if (fileInfo->iBlock < 5 || fileInfo->iBlock >= card->cBlock) { + result = CARD_RESULT_BROKEN; + goto error; + } + + result = __CARDEraseSector(chan, card->sectorSize * fileInfo->iBlock, EraseCallback); + } + + if (result < 0) { + goto error; + } + return; + } + +error: + callback = card->apiCallback; + card->apiCallback = NULL; + __CARDPutControlBlock(card, result); + ASSERTLINE(98, callback); + callback(chan, result); +} + +s32 CARDEraseAsync(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDCallback callback) { + CARDControl* card; + s32 result; + CARDDir* dir; + CARDDir* ent; + + ASSERTLINE(132, 0 < length); + + result = __CARDSeek(fileInfo, length, offset, &card); + if (result < 0) { + return result; + } + + ASSERTLINE(138, OFFSET(offset, card->sectorSize) == 0); + ASSERTLINE(139, OFFSET(length, card->sectorSize) == 0); + + if (OFFSET(offset, card->sectorSize) != 0 || OFFSET(length, card->sectorSize) != 0) { + return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR); + } + + dir = __CARDGetDirBlock(card); + ent = dir + fileInfo->fileNo; + result = __CARDIsWritable(card, ent); + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + + result = __CARDEraseSector(fileInfo->chan, card->sectorSize * fileInfo->iBlock, EraseCallback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + + return result; +} + +s32 CARDErase(CARDFileInfo* fileInfo, s32 length, s32 offset) { + s32 result = CARDEraseAsync(fileInfo, length, offset, __CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(fileInfo->chan); +} diff --git a/src/dolphin/card/CARDFormat.c b/src/dolphin/card/CARDFormat.c index ba1801cfd0..7bcc76daa1 100644 --- a/src/dolphin/card/CARDFormat.c +++ b/src/dolphin/card/CARDFormat.c @@ -1,51 +1,42 @@ -#include "dolphin/card/CARDFormat.h" -#include "dolphin/card.h" -#include "dolphin/card/CARDPriv.h" -#include "dolphin/os/OSRtc.h" -#include "dolphin/vi.h" +#include -static void FormatCallback(s32 chan, s32 result); +#include "os/__os.h" +#include "__card.h" -/* 80357484-803575C8 351DC4 0144+00 1/1 0/0 0/0 .text FormatCallback */ static void FormatCallback(s32 chan, s32 result) { CARDControl* card; CARDCallback callback; card = &__CARDBlock[chan]; - if (result < 0) { + if (result < 0) goto error; - } ++card->formatStep; if (card->formatStep < CARD_NUM_SYSTEM_BLOCK) { result = __CARDEraseSector(chan, (u32)card->sectorSize * card->formatStep, FormatCallback); - if (0 <= result) { + 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) { + (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); + 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); + memcpy(card->currentFat, (u8*)card->workArea + (3 + 1) * CARD_SYSTEM_BLOCK_SIZE, CARD_SYSTEM_BLOCK_SIZE); } error: callback = card->apiCallback; - card->apiCallback = 0; + card->apiCallback = NULL; __CARDPutControlBlock(card, result); + ASSERTLINE(133, callback); callback(chan, result); } -/* 803575C8-80357C20 351F08 0658+00 1/1 0/0 0/0 .text __CARDFormatRegionAsync */ s32 __CARDFormatRegionAsync(s32 chan, u16 encode, CARDCallback callback) { CARDControl* card; CARDID* id; @@ -55,21 +46,22 @@ s32 __CARDFormatRegionAsync(s32 chan, u16 encode, CARDCallback callback) { s32 result; OSSram* sram; OSSramEx* sramEx; - u16 viDTVStatus; + 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) { + if (result < 0) return result; - } id = (CARDID*)card->workArea; memset(id, 0xff, CARD_SYSTEM_BLOCK_SIZE); - viDTVStatus = __VIRegs[55]; + dvdstatus = __VIRegs[55]; id->encode = encode; - sram = __OSLockSram(); *(u32*)&id->serial[20] = sram->counterBias; *(u32*)&id->serial[24] = sram->language; @@ -85,7 +77,7 @@ s32 __CARDFormatRegionAsync(s32 chan, u16 encode, CARDCallback callback) { } __OSUnlockSramEx(FALSE); - *(u32*)&id->serial[28] = viDTVStatus; + *(u32*)&id->serial[28] = dvdstatus; *(OSTime*)&id->serial[12] = time; id->deviceID = 0; @@ -97,19 +89,19 @@ s32 __CARDFormatRegionAsync(s32 chan, u16 encode, CARDCallback callback) { dir = (CARDDir*)((u8*)card->workArea + (1 + i) * CARD_SYSTEM_BLOCK_SIZE); memset(dir, 0xff, CARD_SYSTEM_BLOCK_SIZE); - check = __CARDGetDirCheck(dir); + check = CARDGetDirCheck(dir); check->checkCode = i; - __CARDCheckSum(dir, CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &check->checkSum, - &check->checkSumInv); + __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]); + __CARDCheckSum(&fat[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &fat[CARD_FAT_CHECKSUM], + &fat[CARD_FAT_CHECKSUMINV]); } card->apiCallback = callback ? callback : __CARDDefaultApiCallback; @@ -117,18 +109,29 @@ s32 __CARDFormatRegionAsync(s32 chan, u16 encode, CARDCallback callback) { card->formatStep = 0; result = __CARDEraseSector(chan, (u32)card->sectorSize * card->formatStep, FormatCallback); - if (result < 0) { + if (result < 0) __CARDPutControlBlock(card, result); - } return result; } -/* 80357C20-80357C74 352560 0054+00 0/0 1/1 0/0 .text CARDFormat */ -s32 CARDFormat(s32 chan) { - s32 result = __CARDFormatRegionAsync(chan, __CARDGetFontEncode(), __CARDSyncCallback); +s32 __CARDFormatRegion(s32 chan, u16 encode) { + s32 result = __CARDFormatRegionAsync(chan, encode, &__CARDSyncCallback); if (result < 0) { return result; } return __CARDSync(chan); -} \ No newline at end of file +} + +s32 CARDFormatAsync(s32 chan, CARDCallback callback) { + return __CARDFormatRegionAsync(chan, __CARDGetFontEncode(), callback); +} + +s32 CARDFormat(s32 chan) { + s32 result = __CARDFormatRegionAsync(chan, __CARDGetFontEncode(), &__CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(chan); +} diff --git a/src/dolphin/card/CARDMount.c b/src/dolphin/card/CARDMount.c index 0b0c200a1a..4ca607dc3b 100644 --- a/src/dolphin/card/CARDMount.c +++ b/src/dolphin/card/CARDMount.c @@ -1,20 +1,21 @@ -#include "dolphin/card/CARDMount.h" -#include "dolphin/card.h" -#include "dolphin/card/CARDPriv.h" -#include "dolphin/os/OSRtc.h" +#include +#include -u8 GameChoice AT_ADDRESS(0x800030E3); +#include "os/__os.h" +#include "__card.h" -static BOOL IsCard(u32 id); -static s32 DoMount(s32 chan); -static void DoUnmount(s32 chan, s32 result); - -/* 803D2000-803D2020 02F120 0020+00 3/3 0/0 0/0 .data SectorSizeTable */ static u32 SectorSizeTable[8] = { 8 * 1024, 16 * 1024, 32 * 1024, 64 * 1024, 128 * 1024, 256 * 1024, 0, 0, }; -/* 80356948-80356A14 351288 00CC+00 2/2 0/0 0/0 .text IsCard */ +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); + static BOOL IsCard(u32 id) { u32 size; s32 sectorSize; @@ -52,20 +53,25 @@ static BOOL IsCard(u32 id) { return TRUE; } -/* 80356A14-80356A4C 351354 0038+00 0/0 1/1 0/0 .text CARDProbe */ -s32 CARDProbe(s32 chan) { - s32 result; +void __CARDDisable(BOOL disable) { + BOOL enabled = OSDisableInterrupts(); - if (GameChoice & 0x80) { - result = 0; - } else { - result = EXIProbe(chan); + __gUnknown800030E3 &= ~0x80; + if (disable) { + __gUnknown800030E3 |= 0x80; } - return result; + OSRestoreInterrupts(enabled); +} + +int CARDProbe(s32 chan) { + if (__gUnknown800030E3 & 0x80) { + return 0; + } else { + return EXIProbe(chan); + } } -/* 80356A4C-80356BC8 35138C 017C+00 0/0 1/1 0/0 .text CARDProbeEx */ s32 CARDProbeEx(s32 chan, s32* memSize, s32* sectorSize) { u32 id; CARDControl* card; @@ -73,11 +79,10 @@ s32 CARDProbeEx(s32 chan, s32* memSize, s32* sectorSize) { s32 result; int probe; - if (chan < 0 || 2 <= chan) { + if (chan < 0 || 2 <= chan) return CARD_RESULT_FATAL_ERROR; - } - if (GameChoice & 0x80) { + if (__gUnknown800030E3 & 0x80) { return CARD_RESULT_NOCARD; } @@ -85,33 +90,33 @@ s32 CARDProbeEx(s32 chan, s32* memSize, s32* sectorSize) { enabled = OSDisableInterrupts(); probe = EXIProbeEx(chan); - if (probe == -1) { + if (probe == -1) result = CARD_RESULT_NOCARD; - } else if (probe == 0) { + else if (probe == 0) result = CARD_RESULT_BUSY; - } else if (card->attached) { - if (card->mountStep < 1) { + else if (card->attached) { + if (card->mountStep < 1) result = CARD_RESULT_BUSY; - } else { - if (memSize) { + else { + if (memSize) *memSize = card->size; - } - if (sectorSize) { + + if (sectorSize) *sectorSize = card->sectorSize; - } + result = CARD_RESULT_READY; } - } else if ((EXIGetState(chan) & 8)) { + } + else if ((EXIGetState(chan) & 8)) result = CARD_RESULT_WRONGDEVICE; - } else if (!EXIGetID(chan, 0, &id)) { + else if (!EXIGetID(chan, 0, &id)) result = CARD_RESULT_BUSY; - } else if (IsCard(id)) { - if (memSize) { + else if (IsCard(id)) { + if (memSize) *memSize = (s32)(id & 0xfc); - } - if (sectorSize) { + + if (sectorSize) *sectorSize = SectorSizeTable[(id & 0x00003800) >> 11]; - } result = CARD_RESULT_READY; } else { result = CARD_RESULT_WRONGDEVICE; @@ -121,13 +126,6 @@ s32 CARDProbeEx(s32 chan, s32* memSize, s32* sectorSize) { return result; } -/* ############################################################################################## */ -/* 803D2020-803D2040 02F140 0020+00 1/1 0/0 0/0 .data LatencyTable */ -static u32 LatencyTable[8] = { - 4, 8, 16, 32, 64, 128, 256, 512, -}; - -/* 80356BC8-8035701C 351508 0454+00 2/2 0/0 0/0 .text DoMount */ static s32 DoMount(s32 chan) { CARDControl* card; u32 id; @@ -138,8 +136,9 @@ static s32 DoMount(s32 chan) { u8 checkSum; int step; - card = &__CARDBlock[chan]; + ASSERTLINE(399, 0 <= chan && chan < 2); + card = &__CARDBlock[chan]; if (card->mountStep == 0) { if (EXIGetID(chan, 0, &id) == 0) { result = CARD_RESULT_NOCARD; @@ -148,36 +147,39 @@ static s32 DoMount(s32 chan) { } else { result = CARD_RESULT_WRONGDEVICE; } - if (result < 0) { + + 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 = __CARDReadVendorID(chan, &card->vendorID); - if (result < 0) { + if (result < 0) goto error; + + if (CARDGetFastMode() && (card->vendorID >> 8) == 0xEC) { + card->pageSize = 512; + } else { + card->pageSize = 128; } - if (CARDGetFastMode() && (card->vendorID >> 8) == 0xec) { - card->pageSize = 0x200; - } else { - card->pageSize = 0x80; - } result = __CARDClearStatus(chan); - if (result < 0) { + if (result < 0) goto error; - } result = __CARDReadStatus(chan, &status); - if (result < 0) { + if (result < 0) goto error; - } if (!EXIProbe(chan)) { result = CARD_RESULT_NOCARD; @@ -186,9 +188,8 @@ static s32 DoMount(s32 chan) { if (!(status & 0x40)) { result = __CARDUnlock(chan, card->id); - if (result < 0) { + if (result < 0) goto error; - } checkSum = 0; sram = __OSLockSramEx(); @@ -205,9 +206,9 @@ static s32 DoMount(s32 chan) { checkSum = 0; sram = __OSLockSramEx(); - for (i = 0; i < 12; i++) { + for (i = 0; i < 12; i++) checkSum += sram->flashID[chan][i]; - } + __OSUnlockSramEx(FALSE); if (sram->flashIDCheckSum[chan] != (u8)~checkSum) { result = CARD_RESULT_IOERROR; @@ -224,7 +225,7 @@ static s32 DoMount(s32 chan) { vendorID = *(u16*)sram->flashID[chan]; __OSUnlockSramEx(FALSE); - if (__CARDVendorID == 0xffff || vendorID != __CARDVendorID) { + if (__CARDVendorID == 0xFFFF || vendorID != __CARDVendorID) { result = CARD_RESULT_WRONGDEVICE; goto error; } @@ -233,9 +234,8 @@ static s32 DoMount(s32 chan) { card->mountStep = 2; result = __CARDEnableInterrupt(chan, TRUE); - if (result < 0) { + if (result < 0) goto error; - } EXISetExiCallback(chan, __CARDExiHandler); EXIUnlock(chan); @@ -244,10 +244,9 @@ static s32 DoMount(s32 chan) { 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) { + (u8 *)card->workArea + (CARD_SYSTEM_BLOCK_SIZE * step), __CARDMountCallback); + if (result < 0) __CARDPutControlBlock(card, result); - } return result; error: @@ -256,23 +255,21 @@ error: return result; } -/* 8035701C-80357154 35195C 0138+00 2/2 1/1 0/0 .text __CARDMountCallback */ void __CARDMountCallback(s32 chan, s32 result) { CARDControl* card; CARDCallback callback; - card = &__CARDBlock[chan]; + 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) { + if (0 <= result) return; - } - } else { + } else result = __CARDVerify(card); - } break; case CARD_RESULT_UNLOCKED: card->unlockCallback = __CARDMountCallback; @@ -282,9 +279,8 @@ void __CARDMountCallback(s32 chan, s32 result) { card->unlockCallback = 0; result = DoMount(chan); - if (0 <= result) { + if (result >= 0) return; - } break; case CARD_RESULT_IOERROR: case CARD_RESULT_NOCARD: @@ -293,22 +289,23 @@ void __CARDMountCallback(s32 chan, s32 result) { } callback = card->apiCallback; - card->apiCallback = 0; + card->apiCallback = NULL; __CARDPutControlBlock(card, result); + ASSERTLINE(620, callback); callback(chan, result); } -/* 80357154-803572F4 351A94 01A0+00 1/1 0/0 0/0 .text CARDMountAsync */ -s32 CARDMountAsync(s32 chan, void* workArea, CARDCallback detachCallback, - CARDCallback attachCallback) { +s32 CARDMountAsync(s32 chan, void* workArea, CARDCallback detachCallback, CARDCallback attachCallback) { CARDControl* card; BOOL enabled; - if (chan < 0 || 2 <= chan) { - return CARD_RESULT_FATAL_ERROR; - } + ASSERTLINE(652, workArea && ((u32) workArea % 32 == 0)); + ASSERTLINE(653, 0 <= chan && chan < 2); - if (GameChoice & 0x80) { + if (chan < 0 || 2 <= chan) + return CARD_RESULT_FATAL_ERROR; + + if (__gUnknown800030E3 & 0x80) { return CARD_RESULT_NOCARD; } @@ -348,29 +345,27 @@ s32 CARDMountAsync(s32 chan, void* workArea, CARDCallback detachCallback, OSRestoreInterrupts(enabled); card->unlockCallback = __CARDMountCallback; - if (!EXILock(chan, 0, __CARDUnlockedHandler)) { + if (!EXILock(chan, 0, __CARDUnlockedHandler)) return CARD_RESULT_READY; - } - card->unlockCallback = 0; + card->unlockCallback = 0; return DoMount(chan); } -/* 803572F4-8035733C 351C34 0048+00 0/0 1/1 0/0 .text CARDMount */ -s32 CARDMount(s32 chan, void* workArea, CARDCallback attachCb) { - s32 result = CARDMountAsync(chan, workArea, attachCb, __CARDSyncCallback); - if (result < 0) { - return result; - } +s32 CARDMount(s32 chan, void* workArea, CARDCallback detachCallback) { + s32 result = CARDMountAsync(chan, workArea, detachCallback, __CARDSyncCallback); + if (result < 0) + return result; return __CARDSync(chan); } -/* 8035733C-803573D8 351C7C 009C+00 2/2 0/0 0/0 .text DoUnmount */ 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) { @@ -384,15 +379,16 @@ static void DoUnmount(s32 chan, s32 result) { OSRestoreInterrupts(enabled); } -/* 803573D8-80357484 351D18 00AC+00 0/0 2/2 0/0 .text CARDUnmount */ s32 CARDUnmount(s32 chan) { CARDControl* card; s32 result; + ASSERTLINE(793, 0 <= chan && chan < 2); + result = __CARDGetControlBlock(chan, &card); - if (result < 0) { + if (result < 0) return result; - } + DoUnmount(chan, CARD_RESULT_NOCARD); return CARD_RESULT_READY; } diff --git a/src/dolphin/card/CARDNet.c b/src/dolphin/card/CARDNet.c index 9528501ef6..5f43d3becf 100644 --- a/src/dolphin/card/CARDNet.c +++ b/src/dolphin/card/CARDNet.c @@ -1,20 +1,30 @@ -#include "dolphin/card/CARDNet.h" -#include "dolphin/card.h" -#include "dolphin/card/CARDPriv.h" +#include + +#include "os/__os.h" +#include "__card.h" -/* 80450A70 0002+00 data_80450A70 __CARDVendorID */ u16 __CARDVendorID = 0xFFFF; +u8 __CARDPermMask = 0x1C; -/* 80450A72 0006+00 data_80450A72 None */ -u8 data_80450A72 = 0x1C; +u16 CARDSetVendorID(u16 vendorID) { + u16 prevID = __CARDVendorID; + __CARDVendorID = vendorID; + + return prevID; +} + +u16 CARDGetVendorID() { + return __CARDVendorID; +} -/* 80359158-8035921C 353A98 00C4+00 0/0 1/1 0/0 .text CARDGetSerialNo */ s32 CARDGetSerialNo(s32 chan, u64* serialNo) { CARDControl* card; - CARDID* id; - int i; - u64 code; s32 result; + CARDID* id; + u64 code; + int i; + + ASSERTLINE(105, 0 <= chan && chan < 2); if (!(0 <= chan && chan < 2)) { return CARD_RESULT_FATAL_ERROR; @@ -32,4 +42,97 @@ s32 CARDGetSerialNo(s32 chan, u64* serialNo) { *serialNo = code; return __CARDPutControlBlock(card, CARD_RESULT_READY); -} \ No newline at end of file +} + +s32 CARDGetUniqueCode(s32 chan, u64* uniqueCode) { + CARDControl* card; + s32 result; + OSSramEx* sram; + + ASSERTLINE(146, 0 <= chan && chan < 2); + + if (!(0 <= chan && chan < 2)) { + return CARD_RESULT_FATAL_ERROR; + } + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + sram = __OSLockSramEx(); + memcpy(uniqueCode, &sram->flashID[chan][4], 8); + __OSUnlockSramEx(0); + return __CARDPutControlBlock(card, CARD_RESULT_READY); +} + +s32 CARDGetAttributes(s32 chan, s32 fileNo, u8* attr) { + CARDDir dirent; + s32 result; + + result = __CARDGetStatusEx(chan, fileNo, &dirent); + if (result == 0) { + *attr = dirent.permission; + } + + return result; +} + +#define CARDCheckAttr(attr, flag) ((u32)(attr & flag) != 0) + +s32 CARDSetAttributesAsync(s32 chan, s32 fileNo, u8 attr, CARDCallback callback) { + CARDDir dirent; + s32 result; + + if (attr & ~__CARDPermMask) { + return CARD_RESULT_NOPERM; + } + + result = __CARDGetStatusEx(chan, fileNo, &dirent); + if (result < 0) { + return result; + } + + if ((CARDCheckAttr(dirent.permission, 0x20) && !CARDCheckAttr(attr, 0x20)) || (CARDCheckAttr(dirent.permission, 0x40) && !CARDCheckAttr(attr, 0x40))) { + return CARD_RESULT_NOPERM; + } + + if ((CARDCheckAttr(attr, 0x20) && CARDCheckAttr(attr, 0x40)) || (CARDCheckAttr(attr, 0x20) && CARDCheckAttr(dirent.permission, 0x40)) || (CARDCheckAttr(attr, 0x40) && CARDCheckAttr(dirent.permission, 0x20))) { + return CARD_RESULT_NOPERM; + } + + dirent.permission = attr; + return __CARDSetStatusExAsync(chan, fileNo, &dirent, callback); +} + +s32 CARDSetAttributes(s32 chan, s32 fileNo, u8 attr) { + s32 result; + + result = CARDSetAttributesAsync(chan, fileNo, attr, __CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(chan); +} + +static int __CARDEnablePerm(u8 perm, BOOL enable) { + int prev; + prev = __CARDPermMask & perm ? TRUE : FALSE; + + if (enable) { + __CARDPermMask |= perm; + } else { + __CARDPermMask &= ~perm; + } + + return prev; +} + +int __CARDEnableGlobal(BOOL enable) { + return __CARDEnablePerm(0x20, enable); +} + +int __CARDEnableCompany(BOOL enable) { + return __CARDEnablePerm(0x40, enable); +} diff --git a/src/dolphin/card/CARDOpen.c b/src/dolphin/card/CARDOpen.c index db5948be39..bd86568291 100644 --- a/src/dolphin/card/CARDOpen.c +++ b/src/dolphin/card/CARDOpen.c @@ -1,124 +1,86 @@ -#include "dolphin/card/CARDOpen.h" -#include "dolphin/card.h" -#include "dolphin/card/CARDPriv.h" -#include "dolphin/dvd.h" +#include + +#include "__card.h" -/* 80357C74-80357CDC 3525B4 0068+00 1/1 1/1 0/0 .text __CARDCompareFileName */ BOOL __CARDCompareFileName(CARDDir* ent, const char* fileName) { - char* entName; + char* entName = (char*)ent->fileName; char c1; char c2; - int n; + int n = CARD_FILENAME_MAX; - entName = (char*)ent->fileName; - n = CARD_FILENAME_MAX; - while (0 <= --n) { - if ((c1 = *entName++) != (c2 = *fileName++)) { + while (--n >= 0) { + if ((c1 = *entName++) != (c2 = *fileName++)) return FALSE; - } else if (c2 == '\0') { + else if (c2 == '\0') return TRUE; - } } - if (*fileName == '\0') { + if (*fileName == '\0') return TRUE; - } - return FALSE; } -/* 80357CDC-80357D70 35261C 0094+00 2/2 0/0 0/0 .text __CARDAccess */ s32 __CARDAccess(CARDControl* card, CARDDir* ent) { - const DVDDiskID* diskId = card->diskID; - if (ent->gameName[0] == 0xFF) { - return CARD_RESULT_NOFILE; - } + const DVDDiskID* diskID = card->diskID; - if (diskId == &__CARDDiskNone || (memcmp(ent->gameName, diskId->game_name, 4) == 0 && - memcmp(ent->company, diskId->company, 2) == 0)) - { + if (ent->gameName[0] == 0xFF) + return CARD_RESULT_NOFILE; + + if (diskID == &__CARDDiskNone + || (memcmp(ent->gameName, diskID->gameName, sizeof(ent->gameName)) == 0 + && memcmp(ent->company, diskID->company, sizeof(ent->company)) == 0)) return CARD_RESULT_READY; - } return CARD_RESULT_NOPERM; } -/* 80357D70-80357EA4 3526B0 0134+00 0/0 2/2 0/0 .text __CARDIsWritable */ s32 __CARDIsWritable(CARDControl* card, CARDDir* ent) { - s32 retVal; - const DVDDiskID* diskId = card->diskID; - u8 val; - if ((u8)ent->gameName[0] == 0xFFu) { - retVal = CARD_RESULT_NOFILE; - } else if (diskId == &__CARDDiskNone || (memcmp(ent->gameName, diskId->game_name, 4) == 0 && - memcmp(ent->company, diskId->company, 2) == 0)) - { - retVal = CARD_RESULT_READY; - } else { - retVal = CARD_RESULT_NOPERM; - } + const DVDDiskID* diskID = card->diskID; + s32 result; + u8 perm; - if (retVal == CARD_RESULT_NOPERM) { - val = ent->permission & data_80450A72; - if (val & 0x20u && (memcmp(ent->gameName, __CARDDiskNone.game_name, 4) == 0 && - memcmp(ent->company, __CARDDiskNone.company, 2) == 0)) + result = __CARDAccess(card, ent); + if (result == CARD_RESULT_NOPERM) { + perm = ent->permission & __CARDPermMask; + if (perm & 0x20 && (memcmp(ent->gameName, __CARDDiskNone.gameName, sizeof(ent->gameName)) == 0 && + memcmp(ent->company, __CARDDiskNone.company, sizeof(ent->company)) == 0)) { return CARD_RESULT_READY; - } else if (val & 0x40 && (memcmp(ent->gameName, __CARDDiskNone.game_name, 4) == 0 && - memcmp(ent->company, diskId->company, 2) == 0)) + } else if (perm & 0x40 && (memcmp(ent->gameName, __CARDDiskNone.gameName, sizeof(ent->gameName)) == 0 && + memcmp(ent->company, diskID->company, sizeof(ent->company)) == 0)) { return CARD_RESULT_READY; } } - return retVal; + return result; } -/* 80357EA4-80357F98 3527E4 00F4+00 0/0 2/2 0/0 .text __CARDIsReadable */ s32 __CARDIsReadable(CARDControl* card, CARDDir* ent) { - u8 val; - s32 retVal; - const DVDDiskID* diskId = card->diskID; - - retVal = __CARDAccess(card, ent); - - if (retVal == CARD_RESULT_NOPERM) { - val = ent->permission & data_80450A72; - if (val & 0x20u && (memcmp(ent->gameName, __CARDDiskNone.game_name, 4) == 0 && - memcmp(ent->company, __CARDDiskNone.company, 2) == 0)) - { - retVal = CARD_RESULT_READY; - } else if (val & 0x40 && (memcmp(ent->gameName, __CARDDiskNone.game_name, 4) == 0 && - memcmp(ent->company, diskId->company, 2) == 0)) - { - retVal = CARD_RESULT_READY; - } - } - - if (retVal == CARD_RESULT_NOPERM && (ent->permission & 0x4)) { + s32 result = __CARDIsWritable(card, ent); + if (result == CARD_RESULT_NOPERM && (ent->permission & 0x4)) { return CARD_RESULT_READY; } - return retVal; + return result; } -static inline s32 __CARDGetFileNo(CARDControl* card, const char* fileName, s32* pfileNo) { +s32 __CARDGetFileNo(CARDControl* card, const char* fileName, s32* pfileNo) { CARDDir* dir; CARDDir* ent; s32 fileNo; s32 result; - if (!card->attached) { + 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) { + + if (result < 0) continue; - } if (__CARDCompareFileName(ent, fileName)) { *pfileNo = fileNo; return CARD_RESULT_READY; @@ -128,26 +90,30 @@ static inline s32 __CARDGetFileNo(CARDControl* card, const char* fileName, s32* return CARD_RESULT_NOFILE; } -/* 80357F98-803580B4 3528D8 011C+00 0/0 3/3 0/0 .text CARDOpen */ -s32 CARDOpen(s32 chan, const char* fileName, CARDFileInfo* fileInfo) { +s32 CARDFastOpen(s32 chan, s32 fileNo, CARDFileInfo* fileInfo) { CARDControl* card; CARDDir* dir; CARDDir* ent; s32 result; - s32 fileNo; + + ASSERTLINE(278, 0 <= fileNo && fileNo < CARD_MAX_FILE); + ASSERTLINE(279, 0 <= chan && chan < 2); + + if (fileNo < 0 || fileNo >= CARD_MAX_FILE) + return CARD_RESULT_FATAL_ERROR; fileInfo->chan = -1; result = __CARDGetControlBlock(chan, &card); - if (result < 0) { + if (result < 0) return result; - } - result = __CARDGetFileNo(card, fileName, &fileNo); + + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + result = __CARDIsReadable(card, ent); if (0 <= result) { - dir = __CARDGetDirBlock(card); - ent = &dir[fileNo]; - if (!CARDIsValidBlockNo(card, ent->startBlock)) { + if (!CARDIsValidBlockNo(card, ent->startBlock)) result = CARD_RESULT_BROKEN; - } else { + else { fileInfo->chan = chan; fileInfo->fileNo = fileNo; fileInfo->offset = 0; @@ -157,16 +123,52 @@ s32 CARDOpen(s32 chan, const char* fileName, CARDFileInfo* fileInfo) { return __CARDPutControlBlock(card, result); } -/* 803580B4-80358108 3529F4 0054+00 0/0 3/3 0/0 .text CARDClose */ +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) { + if (result < 0) return result; - } fileInfo->chan = -1; return __CARDPutControlBlock(card, CARD_RESULT_READY); -} \ No newline at end of file +} + +BOOL __CARDIsOpened(CARDControl* card, s32 fileNo) { + return FALSE; +} diff --git a/src/dolphin/card/CARDProgram.c b/src/dolphin/card/CARDProgram.c new file mode 100644 index 0000000000..2e603777fa --- /dev/null +++ b/src/dolphin/card/CARDProgram.c @@ -0,0 +1,100 @@ +#include + +#include "__card.h" + +#define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) +#define CARD_PROGRAM_SIZE 128 + +static void ProgramCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + u16* fat; + CARDFileInfo* fileInfo; + s32 length; + + card = &__CARDBlock[chan]; + + if (result >= 0) { + 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) { + fat = __CARDGetFatBlock(card); + fileInfo->offset += length; + fileInfo->iBlock = fat[fileInfo->iBlock]; + + if (fileInfo->iBlock < 5 || fileInfo->iBlock >= card->cBlock) { + result = CARD_RESULT_BROKEN; + goto error; + } + + ASSERTLINE(94, OFFSET(fileInfo->length, CARD_PROGRAM_SIZE) == 0); + ASSERTLINE(95, OFFSET(fileInfo->offset, card->sectorSize) == 0); + + result = __CARDWrite(chan, card->sectorSize * fileInfo->iBlock, fileInfo->length < card->sectorSize ? fileInfo->length : card->sectorSize, card->buffer, ProgramCallback); + if (result >= 0) { + return; + } + } + } + +error: + callback = card->apiCallback; + card->apiCallback = NULL; + __CARDPutControlBlock(card, result); + ASSERTLINE(114, callback); + callback(chan, result); +} + +s32 CARDProgramAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, CARDCallback callback) { + CARDControl* card; + s32 result; + CARDDir* dir; + CARDDir* ent; + + ASSERTLINE(147, buf && OFFSET(buf, 32) == 0); + ASSERTLINE(148, OFFSET(offset, CARD_PROGRAM_SIZE) == 0); + ASSERTLINE(149, 0 < length && OFFSET(length, CARD_PROGRAM_SIZE) == 0); + + if (offset & 0x7F || length & 0x7F) { + return CARD_RESULT_FATAL_ERROR; + } + + result = __CARDSeek(fileInfo, length, offset, &card); + if (result < 0) { + return result; + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileInfo->fileNo]; + result = __CARDIsWritable(card, ent); + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + + DCStoreRange(buf, length); + + card->apiCallback = callback ? callback : &__CARDDefaultApiCallback; + offset = fileInfo->offset & (card->sectorSize - 1); + length = length < (card->sectorSize - offset) ? length : card->sectorSize - offset; + + result = __CARDWrite(fileInfo->chan, offset + (card->sectorSize * fileInfo->iBlock), length, buf, ProgramCallback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + + return result; +} + +s32 CARDProgram(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset) { + s32 result = CARDProgramAsync(fileInfo, buf, length, offset, __CARDSyncCallback); + if (result < 0) + return result; + + return __CARDSync(fileInfo->chan); +} diff --git a/src/dolphin/card/CARDRaw.c b/src/dolphin/card/CARDRaw.c new file mode 100644 index 0000000000..584a9be9c2 --- /dev/null +++ b/src/dolphin/card/CARDRaw.c @@ -0,0 +1,82 @@ +#include + +#include "__card.h" + +s32 __CARDRawReadAsync(s32 chan, void* buf, s32 length, s32 offset, CARDCallback callback) { + CARDControl* card; + s32 result; + + ASSERTLINE(59, buf && ((u32) buf % 32) == 0); + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + + ASSERTLINE(67, 0 < length && (length % CARD_SEG_SIZE) == 0 && length < CARD_MAX_SIZE); + ASSERTLINE(68, (offset % card->sectorSize) == 0); + + DCInvalidateRange(buf, length); + result = __CARDRead(chan, offset, length, buf, callback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + return result; +} + +s32 __CARDRawRead(s32 chan, void* buf, s32 length, s32 offset) { + s32 result = __CARDRawReadAsync(chan, buf, length, offset, __CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(chan); +} + +static void EraseCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + callback = card->apiCallback; + card->apiCallback = NULL; + + __CARDPutControlBlock(card, result); + + ASSERTLINE(117, callback); + callback(chan, result); +} + +s32 __CARDRawEraseAsync(s32 chan, s32 offset, CARDCallback callback) { + CARDControl* card; + s32 result; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + + if (offset % card->sectorSize) { + return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR); + } + + if ((card->size * 1024 * 1024) / 8 <= offset) { + return __CARDPutControlBlock(card, CARD_RESULT_LIMIT); + } + + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + result = __CARDEraseSector(chan, offset, EraseCallback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + return result; +} + +s32 __CARDRawErase(s32 chan, s32 offset) { + s32 result = __CARDRawEraseAsync(chan, offset, __CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(chan); +} diff --git a/src/dolphin/card/CARDRdwr.c b/src/dolphin/card/CARDRdwr.c index 47ff06d963..8350f57ac4 100644 --- a/src/dolphin/card/CARDRdwr.c +++ b/src/dolphin/card/CARDRdwr.c @@ -1,107 +1,105 @@ -#include "dolphin/card/CARDRdwr.h" -#include "dolphin/card.h" -#include "dolphin/card/CARDPriv.h" +#include +#include "__card.h" + +// prototypes static void BlockReadCallback(s32 chan, s32 result); static void BlockWriteCallback(s32 chan, s32 result); -/* 80355184-80355260 34FAC4 00DC+00 1/1 0/0 0/0 .text BlockReadCallback */ static void BlockReadCallback(s32 chan, s32 result) { CARDControl* card; CARDCallback callback; card = &__CARDBlock[chan]; - if (result < 0) { - goto error; + + 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; + } + } } - card->xferred += CARD_SEG_SIZE; - - card->addr += CARD_SEG_SIZE; - (u8*)card->buffer += CARD_SEG_SIZE; - if (--card->repeat <= 0) { - goto error; - } - - result = __CARDReadSegment(chan, BlockReadCallback); - if (result < 0) { - goto error; - } - return; - -error: - if (card->apiCallback == 0) { + if (!card->apiCallback) { __CARDPutControlBlock(card, result); } + callback = card->xferCallback; if (callback) { - card->xferCallback = 0; + card->xferCallback = NULL; callback(chan, result); } } -/* 80355260-803552C4 34FBA0 0064+00 0/0 3/3 0/0 .text __CARDRead */ 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) { + if (card->attached == 0) { return CARD_RESULT_NOCARD; } - card->xferCallback = callback; - card->repeat = (int)(length / CARD_SEG_SIZE); + card->repeat = (length / 512u); card->addr = addr; card->buffer = dst; - return __CARDReadSegment(chan, BlockReadCallback); } -/* 803552C4-803553AC 34FC04 00E8+00 1/1 0/0 0/0 .text BlockWriteCallback */ static void BlockWriteCallback(s32 chan, s32 result) { + CARDControl* card; CARDCallback callback; - CARDControl* card = &__CARDBlock[chan]; - if (result < 0) { - goto error; + card = &__CARDBlock[chan]; + if (result >= 0) { + card->xferred += card->pageSize; + card->addr += card->pageSize; + ((u8*)card->buffer) += card->pageSize; + + if (--card->repeat > 0) { + result = __CARDWritePage(chan, BlockWriteCallback); + if (result >= 0) { + return; + } + } } - card->xferred += card->pageSize; - - card->addr += card->pageSize; - (u8*)card->buffer += card->pageSize; - if (--card->repeat <= 0) { - goto error; - } - - result = __CARDWritePage(chan, BlockWriteCallback); - if (result < 0) { - goto error; - } - return; - -error: - if (card->apiCallback == 0) { + if (!card->apiCallback) { __CARDPutControlBlock(card, result); } + callback = card->xferCallback; if (callback) { - card->xferCallback = 0; + card->xferCallback = NULL; callback(chan, result); } } -/* 803553AC-80355414 34FCEC 0068+00 0/0 4/4 0/0 .text __CARDWrite */ s32 __CARDWrite(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback) { CARDControl* card; card = &__CARDBlock[chan]; - if (!card->attached) { + + 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 / card->pageSize); + card->repeat = (length / card->pageSize); card->addr = addr; card->buffer = dst; - return __CARDWritePage(chan, BlockWriteCallback); -} \ No newline at end of file +} + +s32 CARDGetXferredBytes(s32 chan) { + ASSERTLINE(183, 0 <= chan && chan < 2); + return __CARDBlock[chan].xferred; +} diff --git a/src/dolphin/card/CARDRead.c b/src/dolphin/card/CARDRead.c index 5f552fee15..74bd544a6f 100644 --- a/src/dolphin/card/CARDRead.c +++ b/src/dolphin/card/CARDRead.c @@ -1,10 +1,12 @@ -#include "dolphin/card/CARDRead.h" -#include "dolphin/card.h" -#include "dolphin/card/CARDPriv.h" +#include +#include "__card.h" + +#define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) + +// prototypes static void ReadCallback(s32 chan, s32 result); -/* 803584A0-80358658 352DE0 01B8+00 1/1 1/1 0/0 .text __CARDSeek */ s32 __CARDSeek(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDControl** pcard) { CARDControl* card; CARDDir* dir; @@ -12,41 +14,42 @@ s32 __CARDSeek(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDControl** pca s32 result; u16* fat; - result = __CARDGetControlBlock(fileInfo->chan, &card); - if (result < 0) { - return result; - } + ASSERTLINE(98, 0 <= fileInfo->chan && fileInfo->chan < 2); + ASSERTLINE(99, 0 <= fileInfo->fileNo && fileInfo->fileNo < CARD_MAX_FILE); - if (!CARDIsValidBlockNo(card, fileInfo->iBlock) || - card->cBlock * card->sectorSize <= fileInfo->offset) - { + 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]; - if (ent->length * card->sectorSize <= offset || - ent->length * card->sectorSize < offset + length) - { + + 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)) { + 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)) { + if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); - } } fileInfo->offset = offset; @@ -55,7 +58,6 @@ s32 __CARDSeek(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDControl** pca return CARD_RESULT_READY; } -/* 80358658-80358788 352F98 0130+00 1/1 0/0 0/0 .text ReadCallback */ static void ReadCallback(s32 chan, s32 result) { CARDControl* card; CARDCallback callback; @@ -64,9 +66,8 @@ static void ReadCallback(s32 chan, s32 result) { s32 length; card = &__CARDBlock[chan]; - if (result < 0) { + if (result < 0) goto error; - } fileInfo = card->fileInfo; if (fileInfo->length < 0) { @@ -74,11 +75,10 @@ static void ReadCallback(s32 chan, s32 result) { goto error; } - length = (s32)TRUNC(fileInfo->offset + card->sectorSize, card->sectorSize) - fileInfo->offset; + length = TRUNC(fileInfo->offset + card->sectorSize, card->sectorSize) - fileInfo->offset; fileInfo->length -= length; - if (fileInfo->length <= 0) { + if (fileInfo->length <= 0) goto error; - } fat = __CARDGetFatBlock(card); fileInfo->offset += length; @@ -88,60 +88,59 @@ static void ReadCallback(s32 chan, s32 result) { 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) { + (fileInfo->length < card->sectorSize) ? fileInfo->length : card->sectorSize, card->buffer, + ReadCallback); + if (result < 0) goto error; - } return; error: callback = card->apiCallback; - card->apiCallback = 0; + card->apiCallback = NULL; __CARDPutControlBlock(card, result); + ASSERTLINE(217, callback); callback(chan, result); } -/* 80358788-803588CC 3530C8 0144+00 1/1 0/0 0/0 .text CARDReadAsync */ -s32 CARDReadAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, - CARDCallback callback) { +s32 CARDReadAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, CARDCallback callback) { CARDControl* card; s32 result; CARDDir* dir; CARDDir* ent; - if (OFFSET(offset, CARD_SEG_SIZE) != 0 || OFFSET(length, CARD_SEG_SIZE) != 0) { + 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) { + if (result < 0) return result; - } dir = __CARDGetDirBlock(card); ent = &dir[fileInfo->fileNo]; result = __CARDIsReadable(card, ent); - - if (result < 0) { + 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) { + result = __CARDRead(fileInfo->chan, card->sectorSize * (u32)fileInfo->iBlock + offset, length, buf, ReadCallback); + if (result < 0) __CARDPutControlBlock(card, result); - } return result; } -/* 803588CC-80358914 35320C 0048+00 0/0 2/2 0/0 .text CARDRead */ s32 CARDRead(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset) { s32 result = CARDReadAsync(fileInfo, buf, length, offset, __CARDSyncCallback); if (result < 0) { @@ -149,4 +148,27 @@ s32 CARDRead(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset) { } return __CARDSync(fileInfo->chan); -} \ No newline at end of file +} + +s32 CARDCancel(CARDFileInfo* fileInfo) { + BOOL enabled; + s32 result; + CARDControl* card; + + ASSERTLINE(338, 0 <= fileInfo->chan && fileInfo->chan < 2); + ASSERTLINE(339, 0 <= fileInfo->fileNo && fileInfo->fileNo < CARD_MAX_FILE); + + enabled = OSDisableInterrupts(); + + card = &__CARDBlock[fileInfo->chan]; + result = CARD_RESULT_READY; + if (!card->attached) + result = CARD_RESULT_NOCARD; + else if (card->result == CARD_RESULT_BUSY && card->fileInfo == fileInfo) { + fileInfo->length = -1; + result = CARD_RESULT_CANCELED; + } + + OSRestoreInterrupts(enabled); + return result; +} diff --git a/src/dolphin/card/CARDRename.c b/src/dolphin/card/CARDRename.c new file mode 100644 index 0000000000..0a76aca32b --- /dev/null +++ b/src/dolphin/card/CARDRename.c @@ -0,0 +1,70 @@ +#include + +#include "__card.h" + +s32 CARDRenameAsync(s32 chan, const char* old, const char* new, CARDCallback callback) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + int fileNo; + int newNo; + int oldNo; + + ASSERTLINE(0x56, 0 <= chan && chan < 2); + ASSERTLINE(0x57, *old != 0xff && *new != 0xff); + ASSERTLINE(0x58, *old != 0x00 && *new != 0x00); + + if (old[0] == 0xFF || new[0] == 0xFF || old[0] == 0 || new[0] == 0) + return CARD_RESULT_FATAL_ERROR; + if (CARD_FILENAME_MAX < (u32)strlen(old) || CARD_FILENAME_MAX < (u32)strlen(new)) + return CARD_RESULT_NAMETOOLONG; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + return result; + + newNo = oldNo = -1; + dir = __CARDGetDirBlock(card); + for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) { + ent = &dir[fileNo]; + if (ent->gameName[0] == 0xFF) + continue; + + if (memcmp(ent->gameName, card->diskID->gameName, sizeof(ent->gameName)) != 0 + || memcmp(ent->company, card->diskID->company, sizeof(ent->company)) != 0) + continue; + + if (__CARDCompareFileName(ent, old)) + oldNo = fileNo; + if (__CARDCompareFileName(ent, new)) + newNo = fileNo; + } + + if (oldNo == -1) + return __CARDPutControlBlock(card, CARD_RESULT_NOFILE); + if (newNo != -1) + return __CARDPutControlBlock(card, CARD_RESULT_EXIST); + + ent = &dir[oldNo]; + result = __CARDIsWritable(card, ent); + if (result < 0) + return __CARDPutControlBlock(card, result); + + strncpy((char*)ent->fileName, new, CARD_FILENAME_MAX); + ent->time = (u32)OSTicksToSeconds(OSGetTime()); + + result = __CARDUpdateDir(chan, callback); + if (result < 0) + __CARDPutControlBlock(card, result); + + return result; +} + +s32 CARDRename(s32 chan, const char* old, const char* new) { + s32 result = CARDRenameAsync(chan, old, new, __CARDSyncCallback); + if (result < 0) + return result; + + return __CARDSync(chan); +} diff --git a/src/dolphin/card/CARDStat.c b/src/dolphin/card/CARDStat.c index 553cc9ba37..f99455b42b 100644 --- a/src/dolphin/card/CARDStat.c +++ b/src/dolphin/card/CARDStat.c @@ -1,17 +1,14 @@ -#include "dolphin/card/CARDStat.h" -#include "dolphin/card.h" -#include "dolphin/card/CARDPriv.h" +#include -static void UpdateIconOffsets(CARDDir* ent, CARDStat* stat); +#include "__card.h" -/* 80358C90-80358E88 3535D0 01F8+00 2/2 0/0 0/0 .text UpdateIconOffsets */ static void UpdateIconOffsets(CARDDir* ent, CARDStat* stat) { u32 offset; BOOL iconTlut; int i; offset = ent->iconAddr; - if (offset == 0xFFFFFFFF) { + if (offset == 0xffffffff) { stat->bannerFormat = 0; stat->iconFormat = 0; stat->iconSpeed = 0; @@ -29,11 +26,11 @@ static void UpdateIconOffsets(CARDDir* ent, CARDStat* stat) { case CARD_STAT_BANNER_RGB5A3: stat->offsetBanner = offset; offset += 2 * CARD_BANNER_WIDTH * CARD_BANNER_HEIGHT; - stat->offsetBannerTlut = 0xFFFFFFFF; + stat->offsetBannerTlut = 0xffffffff; break; default: - stat->offsetBanner = 0xFFFFFFFF; - stat->offsetBannerTlut = 0xFFFFFFFF; + stat->offsetBanner = 0xffffffff; + stat->offsetBannerTlut = 0xffffffff; break; } @@ -49,7 +46,7 @@ static void UpdateIconOffsets(CARDDir* ent, CARDStat* stat) { offset += 2 * CARD_ICON_WIDTH * CARD_ICON_HEIGHT; break; default: - stat->offsetIcon[i] = 0xFFFFFFFF; + stat->offsetIcon[i] = 0xffffffff; break; } } @@ -58,25 +55,26 @@ static void UpdateIconOffsets(CARDDir* ent, CARDStat* stat) { stat->offsetIconTlut = offset; offset += 2 * 256; } else { - stat->offsetIconTlut = 0xFFFFFFFF; + stat->offsetIconTlut = 0xffffffff; } stat->offsetData = offset; } -/* 80358E88-80358F9C 3537C8 0114+00 0/0 2/2 0/0 .text CARDGetStatus */ s32 CARDGetStatus(s32 chan, s32 fileNo, CARDStat* stat) { CARDControl* card; CARDDir* dir; CARDDir* ent; s32 result; - if (fileNo < 0 || CARD_MAX_FILE <= fileNo) { + 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) { + if (result < 0) return result; - } dir = __CARDGetDirBlock(card); ent = &dir[fileNo]; @@ -97,16 +95,21 @@ s32 CARDGetStatus(s32 chan, s32 fileNo, CARDStat* stat) { UpdateIconOffsets(ent, stat); } + return __CARDPutControlBlock(card, result); } -/* 80358F9C-80359110 3538DC 0174+00 1/1 0/0 0/0 .text CARDSetStatusAsync */ 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 && @@ -114,17 +117,16 @@ s32 CARDSetStatusAsync(s32 chan, s32 fileNo, CARDStat* stat, CARDCallback callba { return CARD_RESULT_FATAL_ERROR; } + result = __CARDGetControlBlock(chan, &card); - if (result < 0) { + if (result < 0) return result; - } dir = __CARDGetDirBlock(card); ent = &dir[fileNo]; result = __CARDIsWritable(card, ent); - if (result < 0) { + if (result < 0) return __CARDPutControlBlock(card, result); - } ent->bannerFormat = stat->bannerFormat; ent->iconAddr = stat->iconAddr; @@ -139,13 +141,11 @@ s32 CARDSetStatusAsync(s32 chan, s32 fileNo, CARDStat* stat, CARDCallback callba ent->time = (u32)OSTicksToSeconds(OSGetTime()); result = __CARDUpdateDir(chan, callback); - if (result < 0) { + if (result < 0) __CARDPutControlBlock(card, result); - } return result; } -/* 80359110-80359158 353A50 0048+00 0/0 1/1 0/0 .text CARDSetStatus */ s32 CARDSetStatus(s32 chan, s32 fileNo, CARDStat* stat) { s32 result = CARDSetStatusAsync(chan, fileNo, stat, __CARDSyncCallback); if (result < 0) { @@ -153,4 +153,4 @@ s32 CARDSetStatus(s32 chan, s32 fileNo, CARDStat* stat) { } return __CARDSync(chan); -} \ No newline at end of file +} diff --git a/src/dolphin/card/CARDStatEx.c b/src/dolphin/card/CARDStatEx.c new file mode 100644 index 0000000000..681dbd5a8c --- /dev/null +++ b/src/dolphin/card/CARDStatEx.c @@ -0,0 +1,124 @@ +#include +#include + +#include "__card.h" + +s32 __CARDGetStatusEx(s32 chan, s32 fileNo, CARDDir* dirent) { + ASSERTLINE(85, 0 <= chan && chan < 2); + ASSERTLINE(86, 0 <= fileNo && fileNo < CARD_MAX_FILE); + + if ((fileNo < 0) || (fileNo >= CARD_MAX_FILE)) { + return CARD_RESULT_FATAL_ERROR; + } + + { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result = __CARDGetControlBlock(chan, &card); + + if (result < 0) { + return result; + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + result = __CARDIsReadable(card, ent); + if (result >= 0) { + memcpy(dirent, ent, 0x40); + } + return __CARDPutControlBlock(card, result); + } +} + +s32 __CARDSetStatusExAsync(s32 chan, s32 fileNo, CARDDir* dirent, CARDCallback callback) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + u8* p; + s32 i; + + ASSERTLINE(142, 0 <= fileNo && fileNo < CARD_MAX_FILE); + ASSERTLINE(143, 0 <= chan && chan < 2); + ASSERTLINE(144, *dirent->fileName != 0xff && *dirent->fileName != 0x00); + + ASSERTMSGLINE(152, dirent->iconAddr == 0xffffffff || dirent->iconAddr < CARD_READ_SIZE, "CARDSetStatus[Async](): stat->iconAddr must be 0xffffffff or less than CARD_READ_SIZE."); + ASSERTMSGLINE(155, dirent->commentAddr == 0xffffffff || (dirent->commentAddr & 0x1FFF) <= 8128, "CARDSetStatus[Async](): comment strings (set by stat->commentAddr) must not cross 8KB byte boundary."); + + if ((fileNo < 0) || (fileNo >= CARD_MAX_FILE) || ((u8) dirent->fileName[0] == 0xFF) || ((u8) dirent->fileName[0] == 0)) { + return CARD_RESULT_FATAL_ERROR; + } + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + result = __CARDIsWritable(card, ent); + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + + for (p = dirent->fileName; p < (u8*)&dirent->time; p++) { + if (*p != 0) { + continue; + } + while ((++p) < (u8*)&dirent->time) { + *p = 0; + } + break; + } + + if (dirent->permission & 0x20) { + memset(dirent->gameName, 0, sizeof(dirent->gameName)); + memset(dirent->company, 0, sizeof(dirent->company)); + } + + if (dirent->permission & 0x40) { + memset(dirent->gameName, 0, sizeof(dirent->gameName)); + } + + if ((memcmp(&ent->fileName, &dirent->fileName, 32) != 0) || (memcmp(ent->gameName, dirent->gameName, 4) != 0) || (memcmp(ent->company, dirent->company, 2) != 0)) { + for(i = 0; i < CARD_MAX_FILE; i++) { + if (i != fileNo) { + CARDDir* ent = &dir[i]; // sure, just redeclare ent again... + if (((u8) ent->gameName[0] != 0xFF) + && (memcmp(&ent->gameName, &dirent->gameName, 4) == 0) + && (memcmp(&ent->company, &dirent->company, 2) == 0) + && (memcmp(&ent->fileName, &dirent->fileName, 0x20) == 0)) { + return __CARDPutControlBlock(card, -7); + } + } + } + memcpy(&ent->fileName, &dirent->fileName, 0x20); + memcpy(&ent->gameName, &dirent->gameName, 4); + memcpy(&ent->company, &dirent->company, 2); + } + + ent->time = dirent->time; + ent->bannerFormat = dirent->bannerFormat; + ent->iconAddr = dirent->iconAddr; + ent->iconFormat = dirent->iconFormat; + ent->iconSpeed = dirent->iconSpeed; + ent->commentAddr = dirent->commentAddr; + ent->permission = dirent->permission; + ent->copyTimes = dirent->copyTimes; + + result = __CARDUpdateDir(chan, callback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + return result; +} + +s32 __CARDSetStatusEx(s32 chan, s32 fileNo, CARDDir* dirent) { + s32 result = __CARDSetStatusExAsync(chan, fileNo, dirent, &__CARDSyncCallback); + if (result < 0) { + return result; + } + + return __CARDSync(chan); +} diff --git a/src/dolphin/card/CARDUnlock.c b/src/dolphin/card/CARDUnlock.c index fcf54a4067..2287abf7e2 100644 --- a/src/dolphin/card/CARDUnlock.c +++ b/src/dolphin/card/CARDUnlock.c @@ -1,15 +1,81 @@ -#include "dolphin/card/CARDUnlock.h" -#include "dolphin/card.h" -#include "dolphin/card/CARDPriv.h" -#include "dolphin/os.h" +#include +#include +#include +#include "__card.h" + +static u8 CardData[352] ATTRIBUTE_ALIGN(DOLPHIN_ALIGNMENT) = { + 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, s32 mode); +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); -/* 80353F24-80354090 34E864 016C+00 1/1 0/0 0/0 .text bitrev */ +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; @@ -19,9 +85,9 @@ static u32 bitrev(u32 data) { wk = 0; for (i = 0; i < 32; i++) { if (i > 15) { - if (i == 31) { + if (i == 31) wk |= (((data & (0x01 << 31)) >> 31) & 0x01); - } else { + else { wk |= ((data & (0x01 << i)) >> j); j += 2; } @@ -30,6 +96,7 @@ static u32 bitrev(u32 data) { k++; } } + return wk; } @@ -38,16 +105,16 @@ static u32 bitrev(u32 data) { #define SEC_AD3(x) ((u8)(((x) >> 19) & 0x03)) #define SEC_BA(x) ((u8)(((x) >> 12) & 0x7f)) -/* 80354090-803541D4 34E9D0 0144+00 2/2 0/0 0/0 .text ReadArrayUnlock */ -static s32 ReadArrayUnlock(s32 chan, u32 data, void* rbuf, s32 rlen, s32 mode) { +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)) { + if (!EXISelect(chan, 0, CARDFreq)) return CARD_RESULT_NOCARD; - } data &= 0xfffff000; memset(cmd, 0, 5); @@ -64,27 +131,25 @@ static s32 ReadArrayUnlock(s32 chan, u32 data, void* rbuf, s32 rlen, s32 mode) { err = FALSE; err |= !EXIImmEx(chan, cmd, 5, 1); - err |= !EXIImmEx(chan, (u8*)card->workArea + (u32)sizeof(CARDID), card->latency, 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; } -/* ############################################################################################## */ -/* 80450A68-80450A70 0004E8 0004+04 2/2 0/0 0/0 .sdata next */ -static unsigned long int next = 1; +static u32 GetInitVal(void) { + u32 tmp; + u32 tick; -static int CARDRand(void) { - next = next * 1103515245 + 12345; - return (int)((unsigned int)(next / 65536) % 32768); + tick = OSGetTick(); + CARDSrand(tick); + tmp = 0x7fec8000; + tmp |= CARDRand(); + tmp &= 0xfffff000; + return tmp; } -static void CARDSrand(unsigned int seed) { - next = seed; -} - -/* 803541D4-80354298 34EB14 00C4+00 2/2 0/0 0/0 .text DummyLen */ static s32 DummyLen(void) { u32 tick; u32 wk; @@ -103,97 +168,21 @@ static s32 DummyLen(void) { tick = OSGetTick(); tmp = (s32)(tick << wk); wk++; - if (wk > 16) { + if (wk > 16) wk = 1; - } CARDSrand((u32)tmp); tmp = CARDRand(); tmp &= 0x0000001f; tmp += 1; max++; } - if (tmp < 4) { + + if (tmp < 4) tmp = 4; - } return tmp; } -/* ############################################################################################## */ -/* 803D1EA0-803D2000 02EFC0 0160+00 1/1 0/0 0/0 .data CardData */ -static u8 CardData[] ALIGN_DECL(32) = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x02, 0xFF, 0x00, 0x21, - 0x13, 0x06, 0x12, 0x03, 0x12, 0x04, 0x13, 0x05, 0x00, 0x92, 0x00, 0xFF, 0x00, 0x88, 0xFF, 0xFF, - 0x00, 0x89, 0xFF, 0xFF, 0x00, 0x8A, 0xFF, 0xFF, 0x00, 0x8B, 0xFF, 0xFF, 0x8F, 0x00, 0x02, 0xBF, - 0x00, 0x88, 0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x00, 0x16, 0xFB, 0x00, 0x01, 0x02, 0xBF, - 0x00, 0x8E, 0x25, 0xFF, 0x03, 0x80, 0xFF, 0x00, 0x02, 0x94, 0x00, 0x27, 0x02, 0xBF, 0x00, 0x8E, - 0x1F, 0xDF, 0x24, 0xFF, 0x02, 0x40, 0x0F, 0xFF, 0x00, 0x98, 0x04, 0x00, 0x00, 0x9A, 0x00, 0x10, - 0x00, 0x99, 0x00, 0x00, 0x8E, 0x00, 0x02, 0xBF, 0x00, 0x94, 0x02, 0xBF, 0x86, 0x44, 0x02, 0xBF, - 0x00, 0x88, 0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x03, 0x16, 0xFB, 0x00, 0x01, 0x8F, 0x00, - 0x02, 0xBF, 0x00, 0x8E, 0x03, 0x80, 0xCD, 0xD1, 0x02, 0x94, 0x00, 0x48, 0x27, 0xFF, 0x03, 0x80, - 0x00, 0x01, 0x02, 0x95, 0x00, 0x5A, 0x03, 0x80, 0x00, 0x02, 0x02, 0x95, 0x80, 0x00, 0x02, 0x9F, - 0x00, 0x48, 0x00, 0x21, 0x8E, 0x00, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, - 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC5, 0xFF, 0xFF, - 0x03, 0x40, 0x0F, 0xFF, 0x1C, 0x9F, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC7, 0xFF, 0xFF, 0x02, 0xBF, - 0x00, 0x8E, 0x00, 0xC6, 0xFF, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC0, 0xFF, 0xFF, 0x02, 0xBF, - 0x00, 0x8E, 0x20, 0xFF, 0x03, 0x40, 0x0F, 0xFF, 0x1F, 0x5F, 0x02, 0xBF, 0x00, 0x8E, 0x21, 0xFF, - 0x02, 0xBF, 0x00, 0x8E, 0x23, 0xFF, 0x12, 0x05, 0x12, 0x06, 0x02, 0x9F, 0x80, 0xB5, 0x00, 0x21, - 0x27, 0xFC, 0x03, 0xC0, 0x80, 0x00, 0x02, 0x9D, 0x00, 0x88, 0x02, 0xDF, 0x27, 0xFE, 0x03, 0xC0, - 0x80, 0x00, 0x02, 0x9C, 0x00, 0x8E, 0x02, 0xDF, 0x2E, 0xCE, 0x2C, 0xCF, 0x00, 0xF8, 0xFF, 0xCD, - 0x00, 0xF9, 0xFF, 0xC9, 0x00, 0xFA, 0xFF, 0xCB, 0x26, 0xC9, 0x02, 0xC0, 0x00, 0x04, 0x02, 0x9D, - 0x00, 0x9C, 0x02, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -typedef struct DecodeParameters { - u8* inputAddr; - u32 inputLength; - u32 aramAddr; - u8* outputAddr; -} DecodeParameters; - -static u32 GetInitVal(void) { - u32 tmp; - u32 tick; - - tick = OSGetTick(); - CARDSrand(tick); - tmp = 0x7fec8000; - tmp |= CARDRand(); - tmp &= 0xfffff000; - return tmp; -} - -static u32 exnor_1st(u32 data, u32 rshift) { - u32 wk; - u32 w; - u32 i; - - w = data; - for (i = 0; i < rshift; i++) { - wk = ~(w ^ (w >> 7) ^ (w >> 15) ^ (w >> 23)); - w = (w >> 1) | ((wk << 30) & 0x40000000); - } - return w; -} - -static u32 exnor(u32 data, u32 lshift) { - u32 wk; - u32 w; - u32 i; - - w = data; - for (i = 0; i < lshift; i++) { - // 1bit Left Shift - wk = ~(w ^ (w << 7) ^ (w << 15) ^ (w << 23)); - w = (w << 1) | ((wk >> 30) & 0x00000002); - // printf("i=%d, w=%8x\n", i, w); - } - return w; -} - -/* 80354298-80354DF0 34EBD8 0B58+00 0/0 1/1 0/0 .text __CARDUnlock */ s32 __CARDUnlock(s32 chan, u8 flashID[12]) { u32 init_val; u32 data; @@ -215,14 +204,14 @@ s32 __CARDUnlock(s32 chan, u8 flashID[12]) { CARDControl* card; DSPTaskInfo* task; - DecodeParameters* param; + CARDDecParam* param; u8* input; u8* output; card = &__CARDBlock[chan]; task = &card->task; - param = (DecodeParameters*)card->workArea; - input = (u8*)((u8*)param + sizeof(DecodeParameters)); + param = (CARDDecParam*)card->workArea; + input = (u8*)((u8* )param + sizeof(CARDDecParam)); input = (u8*)OSRoundUp32B(input); output = input + 32; @@ -231,9 +220,8 @@ s32 __CARDUnlock(s32 chan, u8 flashID[12]) { dummy = DummyLen(); rlen = dummy; - if (ReadArrayUnlock(chan, init_val, rbuf, rlen, 0) < 0) { + if (ReadArrayUnlock(chan, init_val, rbuf, rlen, 0) < 0) return CARD_RESULT_NOCARD; - } rshift = (u32)(dummy * 8 + 1); wk = exnor_1st(init_val, rshift); @@ -243,10 +231,10 @@ s32 __CARDUnlock(s32 chan, u8 flashID[12]) { dummy = DummyLen(); rlen = 20 + dummy; data = 0; - if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) { + if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) return CARD_RESULT_NOCARD; - } - dp = (u32*)rbuf; + + dp = (u32* )rbuf; para1A = *dp++; para1B = *dp++; Ans1 = *dp++; @@ -257,26 +245,31 @@ s32 __CARDUnlock(s32 chan, u8 flashID[12]) { 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)); @@ -292,10 +285,10 @@ s32 __CARDUnlock(s32 chan, u8 flashID[12]) { DCFlushRange(input, 8); DCInvalidateRange(output, 4); - DCFlushRange(param, sizeof(DecodeParameters)); + DCFlushRange(param, sizeof(CARDDecParam)); task->priority = 255; - task->iram_mmem_addr = (u16*)OSPhysicalToCached(CardData); + task->iram_mmem_addr = (u16*)OSCachedToPhysical(CardData); task->iram_length = 0x160; task->iram_addr = 0; task->dsp_init_vector = 0x10; @@ -313,21 +306,22 @@ s32 __CARDUnlock(s32 chan, u8 flashID[12]) { return CARD_RESULT_READY; } -/* 80354DF0-80354E60 34F730 0070+00 1/1 0/0 0/0 .text InitCallback */ static void InitCallback(void* _task) { s32 chan; CARDControl* card; DSPTaskInfo* task; - DecodeParameters* param; + CARDDecParam* param; task = _task; for (chan = 0; chan < 2; ++chan) { card = &__CARDBlock[chan]; - if ((DSPTaskInfo*)&card->task == task) { + if ((DSPTaskInfo*)&card->task == task) break; - } } - param = (DecodeParameters*)card->workArea; + + ASSERTLINE(514, 0 <= chan && chan < 2); + + param = (CARDDecParam*)card->workArea; DSPSendMailToDSP(0xff000000); while (DSPCheckMailToDSP()) @@ -338,7 +332,6 @@ static void InitCallback(void* _task) { ; } -/* 80354E60-80355184 34F7A0 0324+00 1/1 0/0 0/0 .text DoneCallback */ static void DoneCallback(void* _task) { u8 rbuf[64]; u32 data; @@ -354,20 +347,21 @@ static void DoneCallback(void* _task) { CARDControl* card; s32 result; DSPTaskInfo* task; - DecodeParameters* param; + CARDDecParam* param; u8* input; u8* output; task = _task; for (chan = 0; chan < 2; ++chan) { card = &__CARDBlock[chan]; - if ((DSPTaskInfo*)&card->task == task) { + if ((DSPTaskInfo* )&card->task == task) break; - } } - param = (DecodeParameters*)card->workArea; - input = (u8*)((u8*)param + sizeof(DecodeParameters)); + ASSERTLINE(563, 0 <= chan && chan < 2); + + param = (CARDDecParam*)card->workArea; + input = (u8*)((u8*)param + sizeof(CARDDecParam)); input = (u8*)OSRoundUp32B(input); output = input + 32; @@ -394,15 +388,18 @@ static void DoneCallback(void* _task) { __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); -} \ No newline at end of file +} diff --git a/src/dolphin/card/CARDWrite.c b/src/dolphin/card/CARDWrite.c index ec35693c87..ad9fa4a273 100644 --- a/src/dolphin/card/CARDWrite.c +++ b/src/dolphin/card/CARDWrite.c @@ -1,12 +1,11 @@ -#include "dolphin/card/CARDWrite.h" -#include "dolphin/card.h" -#include "dolphin/card/CARDPriv.h" -#include "dolphin/os/OSTime.h" +#include +#include "__card.h" + +// prototypes static void WriteCallback(s32 chan, s32 result); static void EraseCallback(s32 chan, s32 result); -/* 80358914-80358A84 353254 0170+00 1/1 0/0 0/0 .text WriteCallback */ static void WriteCallback(s32 chan, s32 result) { CARDControl* card; CARDCallback callback; @@ -16,114 +15,109 @@ static void WriteCallback(s32 chan, s32 result) { CARDFileInfo* fileInfo; card = &__CARDBlock[chan]; - if (result < 0) { - goto error; - } - - fileInfo = card->fileInfo; - if (fileInfo->length < 0) { - result = CARD_RESULT_CANCELED; - goto error; - } - - fileInfo->length -= card->sectorSize; - if (fileInfo->length <= 0) { - dir = __CARDGetDirBlock(card); - ent = &dir[fileInfo->fileNo]; - ent->time = (u32)OSTicksToSeconds(OSGetTime()); - callback = card->apiCallback; - card->apiCallback = 0; - result = __CARDUpdateDir(chan, callback); - } else { - fat = __CARDGetFatBlock(card); - fileInfo->offset += card->sectorSize; - fileInfo->iBlock = fat[fileInfo->iBlock]; - if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) { - result = CARD_RESULT_BROKEN; - goto error; + if (result >= 0) { + fileInfo = card->fileInfo; + if (fileInfo->length < 0) { + result = CARD_RESULT_CANCELED; + goto after; } - result = __CARDEraseSector(chan, card->sectorSize * (u32)fileInfo->iBlock, EraseCallback); + fileInfo->length -= card->sectorSize; + if (fileInfo->length <= 0) { + dir = __CARDGetDirBlock(card); + ent = dir + fileInfo->fileNo; + ent->time = OSGetTime()/(__OSBusClock/4); + callback = card->apiCallback; + card->apiCallback = NULL; + result = __CARDUpdateDir(chan, callback); + goto check; + } else { + fat = __CARDGetFatBlock(card); + fileInfo->offset += card->sectorSize; + fileInfo->iBlock = fat[fileInfo->iBlock]; + if ((fileInfo->iBlock < 5) || (fileInfo->iBlock >= card->cBlock)) { + result = CARD_RESULT_BROKEN; + goto after; + } + result = __CARDEraseSector(chan, card->sectorSize * fileInfo->iBlock, EraseCallback); +check:; + if (result < 0) { + goto after; + } + } + } else { +after:; + callback = card->apiCallback; + card->apiCallback = NULL; + __CARDPutControlBlock(card, result); + ASSERTLINE(0x86, callback); + callback(chan, result); } - - if (result < 0) { - goto error; - } - return; - -error: - callback = card->apiCallback; - card->apiCallback = 0; - __CARDPutControlBlock(card, result); - callback(chan, result); } -/* 80358A84-80358B34 3533C4 00B0+00 2/2 0/0 0/0 .text EraseCallback */ static void EraseCallback(s32 chan, s32 result) { CARDControl* card; CARDCallback callback; CARDFileInfo* fileInfo; card = &__CARDBlock[chan]; - if (result < 0) { - goto error; + if (result >= 0) { + fileInfo = card->fileInfo; + ASSERTLINE(161, OFFSET(fileInfo->offset, card->sectorSize) == 0); + result = __CARDWrite(chan, card->sectorSize * fileInfo->iBlock, card->sectorSize, card->buffer, WriteCallback); + if (result < 0) { + goto after; + } + } else { +after:; + callback = card->apiCallback; + card->apiCallback = NULL; + __CARDPutControlBlock(card, result); + ASSERTLINE(175, callback); + callback(chan, result); } - - fileInfo = card->fileInfo; - result = __CARDWrite(chan, card->sectorSize * (u32)fileInfo->iBlock, card->sectorSize, - card->buffer, WriteCallback); - if (result < 0) { - goto error; - } - return; - -error: - callback = card->apiCallback; - card->apiCallback = 0; - __CARDPutControlBlock(card, result); - callback(chan, result); } -/* 80358B34-80358C48 353474 0114+00 1/1 0/0 0/0 .text CARDWriteAsync */ -s32 CARDWriteAsync(CARDFileInfo* fileInfo, const void* buf, s32 length, s32 offset, - CARDCallback callback) { +s32 CARDWriteAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, CARDCallback callback) { CARDControl* card; s32 result; CARDDir* dir; CARDDir* ent; + ASSERTLINE(210, buf && ((u32) buf % 32) == 0); + ASSERTLINE(211, 0 < length); + result = __CARDSeek(fileInfo, length, offset, &card); if (result < 0) { return result; } - if (OFFSET(offset, card->sectorSize) != 0 || OFFSET(length, card->sectorSize) != 0) { + ASSERTLINE(217, OFFSET(offset, card->sectorSize) == 0); + ASSERTLINE(218, OFFSET(length, card->sectorSize) == 0); + + if (OFFSET(offset, card->sectorSize) != 0 || OFFSET(length, card->sectorSize) != 0) return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR); - } dir = __CARDGetDirBlock(card); ent = &dir[fileInfo->fileNo]; result = __CARDIsWritable(card, ent); - if (result < 0) { + if (result < 0) return __CARDPutControlBlock(card, result); - } DCStoreRange((void*)buf, (u32)length); card->apiCallback = callback ? callback : __CARDDefaultApiCallback; card->buffer = (void*)buf; - result = - __CARDEraseSector(fileInfo->chan, card->sectorSize * (u32)fileInfo->iBlock, EraseCallback); - if (result < 0) { + + result = __CARDEraseSector(fileInfo->chan, card->sectorSize * (u32)fileInfo->iBlock, EraseCallback); + if (result < 0) __CARDPutControlBlock(card, result); - } return result; } -/* 80358C48-80358C90 353588 0048+00 0/0 2/2 0/0 .text CARDWrite */ -s32 CARDWrite(CARDFileInfo* fileInfo, const void* buf, s32 length, s32 offset) { +s32 CARDWrite(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset) { s32 result = CARDWriteAsync(fileInfo, buf, length, offset, __CARDSyncCallback); if (result < 0) { return result; } return __CARDSync(fileInfo->chan); -} \ No newline at end of file +} diff --git a/src/dolphin/card/__card.h b/src/dolphin/card/__card.h new file mode 100644 index 0000000000..4625c63962 --- /dev/null +++ b/src/dolphin/card/__card.h @@ -0,0 +1,104 @@ +#ifndef _DOLPHIN_CARD_INTERNAL_H_ +#define _DOLPHIN_CARD_INTERNAL_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// CARDStatEx +s32 __CARDGetStatusEx(s32 chan, s32 fileNo, CARDDir* dirent); +s32 __CARDSetStatusExAsync(s32 chan, s32 fileNo, CARDDir* dirent, CARDCallback callback); +s32 __CARDSetStatusEx(s32 chan, s32 fileNo, CARDDir* dirent); + +// CARDUnlock +s32 __CARDUnlock(s32 chan, u8 flashID[12]); + +// CARDRead +s32 __CARDSeek(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDControl** pcard); + +// CARDRdwr +s32 __CARDRead(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback); +s32 __CARDWrite(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback); + +// CARDRaw +s32 __CARDRawReadAsync(s32 chan, void* buf, s32 length, s32 offset, CARDCallback callback); +s32 __CARDRawRead(s32 chan, void* buf, s32 length, s32 offset); +s32 __CARDRawErase(s32 chan, s32 offset); +s32 __CARDRawEraseAsync(s32 chan, s32 offset, CARDCallback callback); + +// CARDOpen +BOOL __CARDCompareFileName(CARDDir* ent, const char* fileName); +s32 __CARDAccess(CARDControl* card, CARDDir* ent); +s32 __CARDIsPublic(CARDDir* ent); +s32 __CARDGetFileNo(CARDControl* card, const char* fileName, s32* pfileNo); +BOOL __CARDIsOpened(CARDControl* card, s32 fileNo); +s32 __CARDIsWritable(CARDControl* card, CARDDir* ent); +s32 __CARDIsReadable(CARDControl* card, CARDDir* ent); + +// CARDNet +extern u16 __CARDVendorID; +extern u8 __CARDPermMask; +int __CARDEnableGlobal(int enable); +int __CARDEnableCompany(int enable); + +// CARDMount +void __CARDMountCallback(s32 chan, s32 result); +void __CARDDisable(BOOL disable); + +// CARDFormat +s32 CARDFormatAsync(s32 chan, CARDCallback callback); +s32 __CARDFormatRegionAsync(s32 chan, u16 encode, CARDCallback callback); +s32 __CARDFormatRegion(s32 chan, u16 encode); + +// CARDDir +CARDDir* __CARDGetDirBlock(CARDControl* card); +s32 __CARDUpdateDir(s32 chan, CARDCallback callback); + +// CARDCheck +void __CARDCheckSum(void* ptr, int length, u16* checksum, u16* checksumInv); +s32 __CARDVerify(CARDControl* card); + +// CARDBlock +void* __CARDGetFatBlock(CARDControl* card); +s32 __CARDAllocBlock(s32 chan, u32 cBlock, CARDCallback callback); +s32 __CARDFreeBlock(s32 chan, u16 nBlock, CARDCallback callback); +s32 __CARDUpdateFatBlock(s32 chan, u16* fat, CARDCallback callback); + +// CARDBios +extern CARDControl __CARDBlock[2]; + +extern DVDDiskID* __CARDDiskID; +extern DVDDiskID __CARDDiskNone; + +void __CARDDefaultApiCallback(s32 chan, s32 result); +void __CARDSyncCallback(s32 chan, s32 result); +void __CARDExtHandler(s32 chan, OSContext* context); +void __CARDExiHandler(s32 chan, OSContext* context); +void __CARDTxHandler(s32 chan, OSContext* context); +void __CARDUnlockedHandler(s32 chan, OSContext* context); +int __CARDReadNintendoID(s32 chan, u32* id); +s32 __CARDEnableInterrupt(s32 chan, BOOL enable); +s32 __CARDReadStatus(s32 chan, u8* status); +int __CARDReadVendorID(s32 chan, u16* id); +s32 __CARDClearStatus(s32 chan); +s32 __CARDSleep(s32 chan); +s32 __CARDWakeup(s32 chan); +s32 __CARDReadSegment(s32 chan, CARDCallback callback); +s32 __CARDWritePage(s32 chan, CARDCallback callback); +s32 __CARDErase(s32 chan, CARDCallback callback); +s32 __CARDEraseSector(s32 chan, u32 addr, CARDCallback callback); +void __CARDSetDiskID(const DVDDiskID* id); +s32 __CARDGetControlBlock(s32 chan, CARDControl **pcard); +s32 __CARDPutControlBlock(CARDControl* card, s32 result); +s32 __CARDSync(s32 chan); +u16 __CARDGetFontEncode(void); +u16 __CARDSetFontEncode(u16 encode); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_CARD_INTERNAL_H_ diff --git a/src/dolphin/db/db.c b/src/dolphin/db/db.c index 21c0f0211b..3e16342bc3 100644 --- a/src/dolphin/db/db.c +++ b/src/dolphin/db/db.c @@ -1,46 +1,59 @@ -#include "dolphin/db.h" +#include +#include +#include -/* 80451708-8045170C 000C08 0004+00 2/2 0/0 0/0 .sbss __DBInterface */ -static DBInterface* __DBInterface; +u8 DBStack[0x1000]; +u8* DBStackEnd = DBStack + (sizeof(DBStack) - 8); +BOOL DBVerbose; +DBInterface* __DBInterface; -/* 8045170C-80451710 000C0C 0004+00 1/1 0/0 0/0 .sbss DBVerbose */ -static int DBVerbose; - -/* 80346398-803463C0 340CD8 0028+00 0/0 1/1 0/0 .text DBInit */ void DBInit(void) { - __DBInterface = (DBInterface*)OSPhysicalToCached(OS_DBINTERFACE_ADDR); - __DBInterface->ExceptionDestination = (void (*)())OSCachedToPhysical(__DBExceptionDestination); + __DBInterface = OSPhysicalToCached(0x40); + __DBInterface->ExceptionDestination = (void *)OSCachedToPhysical(__DBExceptionDestination); DBVerbose = TRUE; } -/* 803463C0-80346408 340D00 0048+00 1/1 0/0 0/0 .text __DBExceptionDestinationAux */ -void __DBExceptionDestinationAux(void) { - u32* contextAddr = (void*)0x00C0; - OSContext* context = (OSContext*)OSPhysicalToCached(*contextAddr); +BOOL DBIsDebuggerPresent(void) { + if (__DBInterface == NULL) + return FALSE; + return __DBInterface->bPresent; +} +void __DBExceptionDestinationAux(void) { + u32* contextAddr; + OSContext* context; + + contextAddr = (void*)0xC0; + context = OSPhysicalToCached(*contextAddr); OSReport("DBExceptionDestination\n"); OSDumpContext(context); PPCHalt(); } -/* 80346408-80346418 340D48 0010+00 1/1 0/0 0/0 .text __DBExceptionDestination */ -/* clang-format off */ asm void __DBExceptionDestination(void) { nofralloc - mfmsr r3 - ori r3, r3, 0x10|0x20 - mtmsr r3 - + mfmsr r3 + ori r3, r3, 0x30 + mtmsr r3 b __DBExceptionDestinationAux } -/* clang-format on */ -/* 80346418-80346434 340D58 001C+00 0/0 1/1 0/0 .text __DBIsExceptionMarked */ BOOL __DBIsExceptionMarked(__OSException exception) { - u32 mask = 1 << exception; - - return (BOOL)(__DBInterface->exceptionMask & mask); + u32 mask = (1 << exception); + return __DBInterface->exceptionMask & mask; } -/* 80346434-80346484 340D74 0050+00 0/0 4/4 0/0 .text DBPrintf */ -void DBPrintf(char* format, ...) {} \ No newline at end of file +void __DBMarkException(__OSException exception, int value) { + u32 mask = (1 << exception); + + if (value != 0) + __DBInterface->exceptionMask = __DBInterface->exceptionMask | mask; + else + __DBInterface->exceptionMask = __DBInterface->exceptionMask & ~mask; +} + +void __DBSetPresent(u32 value) { + __DBInterface->bPresent = value; +} + +void DBPrintf(char* str, ...) {} diff --git a/src/dolphin/demo/DEMOAVX.c b/src/dolphin/demo/DEMOAVX.c new file mode 100644 index 0000000000..27d49172d1 --- /dev/null +++ b/src/dolphin/demo/DEMOAVX.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include "fake_tgmath.h" + +static s16 __AVX_internal_buffer[3200] ATTRIBUTE_ALIGN(32); + +static void (*__AVX_save_isr)(void); + +static u32 __AVX_num_frames; +static u32 __AVX_num_filled; +static u32 __AVX_curr_frame; + +static u16* __AVX_buffer; +static s16* __AVX_left_buffer; +static s16* __AVX_right_buffer; +static u32 __AVX_write_ptr = 0; +static u32 __AVX_buffer_size = 0; + +static BOOL flag = FALSE; + +static void __DEMOAVX_isr(void) { + u32 frame_address; + + if (__AVX_save_isr) { + (*__AVX_save_isr)(); + + frame_address = 0x80000000 | AIGetDMAStartAddr(); + ASSERTMSGLINE(83, frame_address, "AVX: frame address is NULL!\n"); + + DCInvalidateRange((void*)frame_address, 640); + memcpy((void *)&__AVX_buffer[__AVX_curr_frame * 320], (void*)frame_address, 640); + DCFlushRange((void*)&__AVX_buffer[__AVX_curr_frame * 320], 640); + + __AVX_curr_frame = (__AVX_curr_frame + 1) % __AVX_num_frames; + __AVX_num_filled = (__AVX_num_filled + 1) % 10; + if (__AVX_curr_frame > 4) { + flag = TRUE; + } + } +} + +u32 DEMOAVXGetNumFilled(void) { + u32 tmp; + BOOL old; + + old = OSDisableInterrupts(); + + tmp = __AVX_num_filled; + __AVX_num_filled = 0; + + OSRestoreInterrupts(old); + return tmp; +} + +u32 DEMOAVXGetFrameCounter(void) { + return __AVX_curr_frame; +} + +u32 DEMOAVXRefreshBuffer(u32* start_index, u32* end_index) { + u32 num_filled; + u32 curr_frame; + u32 i; + u32 j; + + if (flag) { + num_filled = DEMOAVXGetNumFilled(); + curr_frame = (__AVX_num_frames + DEMOAVXGetFrameCounter() - num_filled) % __AVX_num_frames; + + *start_index = __AVX_write_ptr; + + for (i = 0; i < num_filled; i++) { + DCInvalidateRange((void*)&__AVX_buffer[curr_frame * 320], 640); + + for (j = 0; j < 320; j += 2) { + __AVX_left_buffer [__AVX_write_ptr] = __AVX_buffer[curr_frame * 320 + j]; + __AVX_right_buffer[__AVX_write_ptr] = __AVX_buffer[curr_frame * 320 + j + 1]; + __AVX_write_ptr = (__AVX_write_ptr + 1) % __AVX_buffer_size; + } + + curr_frame = (curr_frame + 1) % __AVX_num_frames; + } + + *end_index = __AVX_write_ptr; + return num_filled * 160; + } + + return 0; +} + +void DEMOAVXInit(s16* left, s16* right, u32 size) { + __AVX_left_buffer = left; + __AVX_right_buffer = right; + __AVX_write_ptr = 0; + __AVX_buffer_size = size; + + DEMOAVXAttach(__AVX_internal_buffer, 10); +} + +void DEMOAVXAttach(void* buffer, u32 num_frames) { + BOOL old; + u32 i; + + __AVX_buffer = (u16*)buffer; + __AVX_num_frames = num_frames; + __AVX_num_filled = 0; + __AVX_curr_frame = 0; + + for (i = 0; i < num_frames * 320; i++) { + __AVX_buffer[i] = 0; + } + + DCFlushRange(__AVX_buffer, num_frames * 320); + + old = OSDisableInterrupts(); + __AVX_save_isr = AIRegisterDMACallback(__DEMOAVX_isr); + OSRestoreInterrupts(old); +} diff --git a/src/dolphin/demo/DEMOFont.c b/src/dolphin/demo/DEMOFont.c new file mode 100644 index 0000000000..9b371704c2 --- /dev/null +++ b/src/dolphin/demo/DEMOFont.c @@ -0,0 +1,773 @@ +#include +#include + +u32 DEMOFontBitmap[768] ATTRIBUTE_ALIGN(32) = { + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x000FF000, + 0x000FF000, + 0x000FF000, + 0x000FF000, + 0x000FF000, + 0x00000000, + 0x000FF000, + 0x00000000, + 0x00F00F00, + 0x00F00F00, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00F00F00, + 0x00F00F00, + 0x0FFFFFF0, + 0x00F00F00, + 0x0FFFFFF0, + 0x00F00F00, + 0x00F00F00, + 0x00000000, + 0x0000F000, + 0x00FFFFF0, + 0x0F00F000, + 0x00FFFF00, + 0x0000F0F0, + 0x0FFFFF00, + 0x0000F000, + 0x00000000, + 0x0FF000F0, + 0x0FF00F00, + 0x0000F000, + 0x000F0000, + 0x00F00FF0, + 0x0F000FF0, + 0x00000000, + 0x00000000, + 0x000F0000, + 0x00F0F000, + 0x00F0F000, + 0x00FF0000, + 0x0F000FF0, + 0x0F0000F0, + 0x00FFFF00, + 0x00000000, + 0x000FF000, + 0x000FF000, + 0x0000F000, + 0x000F0000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x0000F000, + 0x000F0000, + 0x00F00000, + 0x00F00000, + 0x00F00000, + 0x000F0000, + 0x0000F000, + 0x00000000, + 0x000F0000, + 0x0000F000, + 0x00000F00, + 0x00000F00, + 0x00000F00, + 0x0000F000, + 0x000F0000, + 0x00000000, + 0x00000000, + 0x00F000F0, + 0x000F0F00, + 0x00FFFFF0, + 0x000F0F00, + 0x00F000F0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x0000F000, + 0x0000F000, + 0x00FFFFF0, + 0x0000F000, + 0x0000F000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x000FF000, + 0x000FF000, + 0x0000F000, + 0x000F0000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00FFFFF0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x000FF000, + 0x000FF000, + 0x00000000, + 0x000000F0, + 0x00000F00, + 0x0000F000, + 0x000F0000, + 0x00F00000, + 0x0F000000, + 0x00000000, + 0x00000000, + 0x000FF000, + 0x00F00F00, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x00F00F00, + 0x000FF000, + 0x00000000, + 0x0000F000, + 0x000FF000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x000FFF00, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x000000F0, + 0x00000F00, + 0x0000F000, + 0x000F0000, + 0x0FFFFFF0, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x000000F0, + 0x0000FF00, + 0x000000F0, + 0x0F0000F0, + 0x00FFFF00, + 0x00000000, + 0x00000F00, + 0x0000FF00, + 0x000F0F00, + 0x00F00F00, + 0x0FFFFFF0, + 0x00000F00, + 0x00000F00, + 0x00000000, + 0x0FFFFFF0, + 0x0F000000, + 0x0F000000, + 0x0FFFFF00, + 0x000000F0, + 0x0F0000F0, + 0x00FFFF00, + 0x00000000, + 0x000FFF00, + 0x00F00000, + 0x0F000000, + 0x0FFFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x00FFFF00, + 0x00000000, + 0x0FFFFFF0, + 0x0F0000F0, + 0x00000F00, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x00FFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x00FFFF00, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x00FFFFF0, + 0x000000F0, + 0x000000F0, + 0x00FFFF00, + 0x00000000, + 0x00000000, + 0x000FF000, + 0x000FF000, + 0x00000000, + 0x000FF000, + 0x000FF000, + 0x00000000, + 0x00000000, + 0x000FF000, + 0x000FF000, + 0x00000000, + 0x000FF000, + 0x000FF000, + 0x0000F000, + 0x000F0000, + 0x00000000, + 0x00000F00, + 0x0000F000, + 0x000F0000, + 0x00F00000, + 0x000F0000, + 0x0000F000, + 0x00000F00, + 0x00000000, + 0x00000000, + 0x00000000, + 0x0FFFFFF0, + 0x00000000, + 0x0FFFFFF0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00F00000, + 0x000F0000, + 0x0000F000, + 0x00000F00, + 0x0000F000, + 0x000F0000, + 0x00F00000, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x0000FF00, + 0x000FF000, + 0x00000000, + 0x000FF000, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x0F000FF0, + 0x0F00F0F0, + 0x0F00FFF0, + 0x0F000000, + 0x00FFFFF0, + 0x00000000, + 0x000FF000, + 0x00F00F00, + 0x0F0000F0, + 0x0F0000F0, + 0x0FFFFFF0, + 0x0F0000F0, + 0x0F0000F0, + 0x00000000, + 0x0FFFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x0FFFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x0FFFFF00, + 0x00000000, + 0x000FFF00, + 0x00F000F0, + 0x0F000000, + 0x0F000000, + 0x0F000000, + 0x00F000F0, + 0x000FFF00, + 0x00000000, + 0x0FFFF000, + 0x0F000F00, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x0F000F00, + 0x0FFFF000, + 0x00000000, + 0x0FFFFFF0, + 0x0F000000, + 0x0F000000, + 0x0FFFFF00, + 0x0F000000, + 0x0F000000, + 0x0FFFFFF0, + 0x00000000, + 0x0FFFFFF0, + 0x0F000000, + 0x0F000000, + 0x0FFFFF00, + 0x0F000000, + 0x0F000000, + 0x0F000000, + 0x00000000, + 0x000FFF00, + 0x00F00000, + 0x0F000000, + 0x0F00FFF0, + 0x0F0000F0, + 0x00F000F0, + 0x000FFF00, + 0x00000000, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x0FFFFFF0, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x00000000, + 0x000FFF00, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x000FFF00, + 0x00000000, + 0x0000FFF0, + 0x00000F00, + 0x00000F00, + 0x00000F00, + 0x00000F00, + 0x0F000F00, + 0x00FFF000, + 0x00000000, + 0x0F0000F0, + 0x0F000F00, + 0x0F00F000, + 0x0FFF0000, + 0x0F00F000, + 0x0F000F00, + 0x0F0000F0, + 0x00000000, + 0x0F000000, + 0x0F000000, + 0x0F000000, + 0x0F000000, + 0x0F000000, + 0x0F000000, + 0x0FFFFFF0, + 0x00000000, + 0x0F00000F, + 0x0FF000FF, + 0x0F0F0F0F, + 0x0F00F00F, + 0x0F00F00F, + 0x0F00000F, + 0x0F00000F, + 0x00000000, + 0x0F0000F0, + 0x0FF000F0, + 0x0F0F00F0, + 0x0F00F0F0, + 0x0F00F0F0, + 0x0F000FF0, + 0x0F0000F0, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x00FFFF00, + 0x00000000, + 0x0FFFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x0FFFFF00, + 0x0F000000, + 0x0F000000, + 0x0F000000, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x0F00F0F0, + 0x0F000F00, + 0x00FFF0F0, + 0x00000000, + 0x0FFFFF00, + 0x0F0000F0, + 0x0F0000F0, + 0x0FFFFF00, + 0x0F00F000, + 0x0F000F00, + 0x0F0000F0, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x0F000000, + 0x00FFFF00, + 0x000000F0, + 0x0F0000F0, + 0x00FFFF00, + 0x00000000, + 0x0FFFFFFF, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x00000000, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x00FFFF00, + 0x00000000, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x0F0000F0, + 0x00F00F00, + 0x00F00F00, + 0x000FF000, + 0x00000000, + 0x0F00000F, + 0x0F00000F, + 0x0F00000F, + 0x0F00F00F, + 0x0F00F00F, + 0x0F00F00F, + 0x00FF0FF0, + 0x00000000, + 0x0F0000F0, + 0x0F0000F0, + 0x00F00F00, + 0x000FF000, + 0x00F00F00, + 0x0F0000F0, + 0x0F0000F0, + 0x00000000, + 0x0F00000F, + 0x00F000F0, + 0x000F0F00, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x00000000, + 0x0FFFFFF0, + 0x000000F0, + 0x00000F00, + 0x000FF000, + 0x00F00000, + 0x0F000000, + 0x0FFFFFF0, + 0x00000000, + 0x000FFF00, + 0x000F0000, + 0x000F0000, + 0x000F0000, + 0x000F0000, + 0x000F0000, + 0x000FFF00, + 0x00000000, + 0x0F000000, + 0x00F00000, + 0x000F0000, + 0x0000F000, + 0x00000F00, + 0x000000F0, + 0x00000000, + 0x00000000, + 0x00FFF000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x00FFF000, + 0x00000000, + 0x000FF000, + 0x00F00F00, + 0x0F0000F0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x0FFFFFF0, + 0x00000000, + 0x000FF000, + 0x000FF000, + 0x000F0000, + 0x0000F000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00FFFF00, + 0x0F000F00, + 0x0F000F00, + 0x0F000F00, + 0x00FFFFF0, + 0x00000000, + 0x00F00000, + 0x00F00000, + 0x00F00000, + 0x00FFFF00, + 0x00F000F0, + 0x00F000F0, + 0x00FFFF00, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00FFFF00, + 0x0F000000, + 0x0F000000, + 0x0F000000, + 0x00FFFF00, + 0x00000000, + 0x000000F0, + 0x000000F0, + 0x000000F0, + 0x000FFFF0, + 0x00F000F0, + 0x00F000F0, + 0x000FFFF0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00FFFF00, + 0x0F0000F0, + 0x0FFFFFF0, + 0x0F000000, + 0x00FFFF00, + 0x00000000, + 0x0000FF00, + 0x000F0000, + 0x000F0000, + 0x0FFFFF00, + 0x000F0000, + 0x000F0000, + 0x000F0000, + 0x00000000, + 0x00000000, + 0x000FFFF0, + 0x00F000F0, + 0x00F000F0, + 0x000FFFF0, + 0x000000F0, + 0x000FFF00, + 0x00000000, + 0x00F00000, + 0x00F00000, + 0x00F00000, + 0x00F0FF00, + 0x00FF00F0, + 0x00F000F0, + 0x00F000F0, + 0x00000000, + 0x00000000, + 0x0000F000, + 0x00000000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x00000000, + 0x00000F00, + 0x00000000, + 0x00000F00, + 0x00000F00, + 0x00000F00, + 0x00F00F00, + 0x000FF000, + 0x00000000, + 0x00000000, + 0x00F00000, + 0x00F00000, + 0x00F00F00, + 0x00F0F000, + 0x00FFF000, + 0x00F00F00, + 0x00000000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x00000F00, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00F0FF00, + 0x0F0F00F0, + 0x0F0F00F0, + 0x0F0F00F0, + 0x0F0F00F0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00F0FF00, + 0x00FF00F0, + 0x00F000F0, + 0x00F000F0, + 0x00F000F0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x000FFF00, + 0x00F000F0, + 0x00F000F0, + 0x00F000F0, + 0x000FFF00, + 0x00000000, + 0x00000000, + 0x00FFF000, + 0x00F00F00, + 0x00F00F00, + 0x00FFF000, + 0x00F00000, + 0x00F00000, + 0x00000000, + 0x00000000, + 0x000FFF00, + 0x00F00F00, + 0x00F00F00, + 0x000FFF00, + 0x00000F00, + 0x00000FF0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00F0FFF0, + 0x00FF0000, + 0x00F00000, + 0x00F00000, + 0x00F00000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x000FFFF0, + 0x00F00000, + 0x000FFF00, + 0x000000F0, + 0x00FFFF00, + 0x00000000, + 0x00000000, + 0x0000F000, + 0x00FFFFF0, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x00000FF0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00F000F0, + 0x00F000F0, + 0x00F000F0, + 0x00F000F0, + 0x000FFFF0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00F000F0, + 0x00F000F0, + 0x00F000F0, + 0x000F0F00, + 0x0000F000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x0F0000F0, + 0x0F00F0F0, + 0x0F00F0F0, + 0x0F00F0F0, + 0x00FF0F00, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00F000F0, + 0x000F0F00, + 0x0000F000, + 0x000F0F00, + 0x00F000F0, + 0x00000000, + 0x00000000, + 0x0F000F00, + 0x0F000F00, + 0x00F00F00, + 0x000FFF00, + 0x00000F00, + 0x00FFF000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00FFFFF0, + 0x00000F00, + 0x0000F000, + 0x000F0000, + 0x00FFFFF0, + 0x00000000, + 0x00000F00, + 0x0000F000, + 0x0000F000, + 0x00FF0000, + 0x0000F000, + 0x0000F000, + 0x00000F00, + 0x00000000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x0000F000, + 0x00000000, + 0x000F0000, + 0x0000F000, + 0x0000F000, + 0x00000FF0, + 0x0000F000, + 0x0000F000, + 0x000F0000, + 0x00000000, + 0x00FF00FF, + 0x0F00FF00, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00FF0000, + 0x0FF00000, + 0xFFFFFFFF, + 0xFFFFF000, + 0xFFFFF000, + 0xFFF00000, + 0x00000000 +}; diff --git a/src/dolphin/demo/DEMOInit.c b/src/dolphin/demo/DEMOInit.c new file mode 100644 index 0000000000..630c2f5db4 --- /dev/null +++ b/src/dolphin/demo/DEMOInit.c @@ -0,0 +1,432 @@ +#include +#include +#include +#include +#include + +#include "__demo.h" + +extern u8 DemoStatEnable; + +static GXRenderModeObj rmodeobj; + +static u8 DemoFirstFrame = 1; + +static void* DefaultFifo = NULL; +static GXFifoObj* DefaultFifoObj = NULL; +static GXRenderModeObj* rmode; +static u32 allocatedFrameBufferSize; +static int GPHangWorkaround; +static u32 FrameCount; +static u32 FrameMissThreshold; +void* DemoFrameBuffer1; +void* DemoFrameBuffer2; +void* DemoCurrentBuffer; + +// prototypes +static void __DEMOInitRenderMode(GXRenderModeObj* mode); +static void __DEMOInitMem(void); +static void __DEMOInitGX(void); +static void __DEMOInitVI(void); +static void __DEMOInitForEmu(void); +static void __NoHangRetraceCallback(u32 count); +static void __NoHangDoneRender(void); +static void __DEMODiagnoseHang(void); + +void DEMOInit(GXRenderModeObj* mode) { + OSInit(); + DVDInit(); + VIInit(); + DEMOPadInit(); + __DEMOInitRenderMode(mode); + __DEMOInitMem(); + VIConfigure(rmode); + DefaultFifo = OSAllocFromHeap(__OSCurrHeap, 0x40000); + DefaultFifoObj = GXInit(DefaultFifo, 0x40000); + __DEMOInitGX(); + __DEMOInitVI(); +} + +static void __DEMOInitRenderMode(GXRenderModeObj* mode) { + if (mode != NULL) { + rmodeobj = *mode; + rmode = &rmodeobj; + return; + } + + switch(VIGetTvFormat()) { + case VI_NTSC: + rmode = &GXNtsc480IntDf; + break; + case VI_PAL: + rmode = &GXPal528IntDf; + break; + case VI_EURGB60: + rmode = &GXEurgb60Hz480IntDf; + break; + case VI_MPAL: + rmode = &GXMpal480IntDf; + break; + default: + OSPanic(__FILE__, 473, "DEMOInit: invalid TV format\n"); + break; + } + + GXAdjustForOverscan(rmode, &rmodeobj, 0, 16); + rmode = &rmodeobj; +} + +static void __DEMOInitMem(void) { + void* arenaLo = OSGetArenaLo(); + void* arenaHi = OSGetArenaHi(); + u32 fbSize = ((u16)(rmode->fbWidth + 15) & 0xFFF0) * rmode->xfbHeight * 2; + allocatedFrameBufferSize = fbSize; + + DemoFrameBuffer1 = (void*)OSRoundUp32B(arenaLo); + DemoFrameBuffer2 = (void*)OSRoundUp32B((u32)DemoFrameBuffer1 + fbSize); + DemoCurrentBuffer = DemoFrameBuffer2; + + arenaLo = (void*)OSRoundUp32B((u32)DemoFrameBuffer2 + fbSize); + OSSetArenaLo(arenaLo); + + arenaLo = OSGetArenaLo(); + arenaHi = OSGetArenaHi(); + arenaLo = OSInitAlloc(arenaLo, arenaHi, 1); + OSSetArenaLo(arenaLo); + + arenaLo = (void*)OSRoundUp32B(arenaLo); + arenaHi = (void*)OSRoundDown32B(arenaHi); + OSSetCurrentHeap(OSCreateHeap(arenaLo, arenaHi)); + OSSetArenaLo((arenaLo = arenaHi)); +} + +static void __DEMOInitGX(void) { + u16 xfbHeight; + f32 yScale; + + GXSetViewport(0.0f, 0.0f, rmode->fbWidth, rmode->efbHeight, 0.0f, 1.0f); + GXSetScissor(0, 0, rmode->fbWidth, rmode->efbHeight); + + yScale = GXGetYScaleFactor(rmode->efbHeight, rmode->xfbHeight); + xfbHeight = GXSetDispCopyYScale(yScale); + + GXSetDispCopySrc(0, 0, rmode->fbWidth, rmode->efbHeight); + GXSetDispCopyDst(rmode->fbWidth, xfbHeight); + GXSetCopyFilter(rmode->aa, rmode->sample_pattern, 1, rmode->vfilter); + + if (rmode->aa != 0) { + GXSetPixelFmt(2, 0); + } else { + GXSetPixelFmt(0, 0); + } + + GXCopyDisp(DemoCurrentBuffer, 1); + GXSetDispCopyGamma(0); +} + +static void __DEMOInitVI(void) { + u32 nin; + + VISetNextFrameBuffer(DemoFrameBuffer1); + DemoCurrentBuffer = DemoFrameBuffer2; + VIFlush(); + VIWaitForRetrace(); + nin = rmode->viTVmode & 1; + if (nin != 0) { + VIWaitForRetrace(); + } +} + +static void __DEMOInitForEmu(void) {} + +void DEMOBeforeRender(void) { + if (GPHangWorkaround != 0) { + GXSetDrawSync(0xFEEB); + GXClearGPMetric(); + } + + if (rmode->field_rendering != 0) { + GXSetViewportJitter(0.0f, 0.0f, rmode->fbWidth, rmode->efbHeight, 0.0f, 1.0f, VIGetNextField()); + } else { + GXSetViewport(0.0f, 0.0f, rmode->fbWidth, rmode->efbHeight, 0.0f, 1.0f); + } + + GXInvalidateVtxCache(); + GXInvalidateTexAll(); +} + +void DEMODoneRender(void) { + if (GPHangWorkaround != 0) { + ASSERTMSGLINE(749, !DemoStatEnable, "DEMOStats and GP hang diagnosis are mutually exclusive"); + __NoHangDoneRender(); + return; + } + + if (DemoStatEnable != 0) { + GXDrawDone(); + DEMOUpdateStats(1); + DEMOPrintStats(); + GXDrawDone(); + DEMOUpdateStats(0); + } + + GXSetZMode(1, 3, 1); + GXSetColorUpdate(1); + GXCopyDisp(DemoCurrentBuffer, 1); + GXDrawDone(); + DEMOSwapBuffers(); +} + +void DEMOSwapBuffers(void) { + VISetNextFrameBuffer(DemoCurrentBuffer); + if (DemoFirstFrame != 0) { + VISetBlack(0); + DemoFirstFrame = 0; + } + + VIFlush(); + VIWaitForRetrace(); + + if ((u32)DemoCurrentBuffer == (u32)DemoFrameBuffer1) { + DemoCurrentBuffer = DemoFrameBuffer2; + } else { + DemoCurrentBuffer = DemoFrameBuffer1; + } +} + +void DEMOSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, GXTevColorArg d) { + u32 swap = 0; + + if (a == GX_CC_TEXC) { + swap = 0xF; + } else if (a >= GX_CC_TEXRRR) { + swap = a; + a = GX_CC_TEXC; + } + + if (b == GX_CC_TEXC) { + swap = 0xF; + } else if (b >= GX_CC_TEXRRR) { + swap = b; + b = GX_CC_TEXC; + } + + if (c == GX_CC_TEXC) { + swap = 0xF; + } else if (c >= GX_CC_TEXRRR) { + swap = c; + c = GX_CC_TEXC; + } + + if (d == GX_CC_TEXC) { + swap = 0xF; + } else if (d >= GX_CC_TEXRRR) { + swap = d; + d = GX_CC_TEXC; + } + + GXSetTevColorIn(stage, a, b, c, d); + if (swap != 0) { + GXSetTevSwapMode(stage, 0, swap - 0xF); + } +} + +void DEMOSetTevOp(GXTevStageID id, GXTevMode mode) { + GXTevColorArg carg = GX_CC_RASC; + GXTevAlphaArg aarg = GX_TEVSTAGE5; + + if (id != 0) { + carg = 0; + aarg = 0; + } + + switch(mode) { + case 0: + DEMOSetTevColorIn(id, 0xF, 8, carg, 0xF); + GXSetTevAlphaIn(id, 7, 4, aarg, 7); + break; + case 1: + DEMOSetTevColorIn(id, carg, 8, 9, 0xF); + GXSetTevAlphaIn(id, 7, 7, 7, aarg); + break; + case 2: + DEMOSetTevColorIn(id, carg, 0xC, 8, 0xF); + GXSetTevAlphaIn(id, 7, 4, aarg, 7); + break; + case 3: + DEMOSetTevColorIn(id, 0xF, 0xF, 0xF, 8); + GXSetTevAlphaIn(id, 7, 7, 7, 4); + break; + case 4: + DEMOSetTevColorIn(id, 0xF, 0xF, 0xF, carg); + GXSetTevAlphaIn(id, 7, 7, 7, aarg); + break; + default: + ASSERTMSGLINE(914, FALSE, "DEMOSetTevOp: Invalid Tev Mode"); + break; + } + + GXSetTevColorOp(id, 0, 0, 0, 1, 0); + GXSetTevAlphaOp(id, 0, 0, 0, 1, 0); +} + +GXRenderModeObj* DEMOGetRenderModeObj(void) { + return rmode; +} + +u32 DEMOGetCurrentBuffer(void) { + return (u32)DemoCurrentBuffer; +} + +void DEMOEnableGPHangWorkaround(u32 timeoutFrames) { + if (timeoutFrames != 0) { + ASSERTMSGLINE(989, !DemoStatEnable, "DEMOStats and GP hang diagnosis are mutually exclusive"); + GPHangWorkaround = 1; + FrameMissThreshold = timeoutFrames; + VISetPreRetraceCallback(__NoHangRetraceCallback); + DEMOSetGPHangMetric(1); + } else { + GPHangWorkaround = 0; + FrameMissThreshold = 0; + DEMOSetGPHangMetric(0); + VISetPreRetraceCallback(NULL); + } +} + +static void __NoHangRetraceCallback(u32 count) { + static u32 ovFrameCount = 0; + static u32 lastOvc = 0; + u32 ovc; + u8 overhi; + u8 junk; + + FrameCount++; + + GXGetGPStatus(&overhi, &junk, &junk, &junk, &junk); + ovc = GXGetOverflowCount(); + + if (overhi && ovc == lastOvc) { + ovFrameCount++; + if (ovFrameCount >= FrameMissThreshold) { + OSReport("---------WARNING : HANG AT HIGH WATERMARK----------\n"); + __DEMODiagnoseHang(); + OSPanic(__FILE__, 1048, "Halting program"); + } + } else { + lastOvc = ovc; + ovFrameCount = 0; + } +} + +static void __NoHangDoneRender(void) { + BOOL abort = FALSE; + + GXCopyDisp(DemoCurrentBuffer, 1); + GXSetDrawSync(0xB00B); + + FrameCount = 0; + + while (GXReadDrawSync() != 0xB00B && !abort) { + if (FrameCount >= FrameMissThreshold) { + OSReport("---------WARNING : ABORTING FRAME----------\n"); + abort = TRUE; + __DEMODiagnoseHang(); + DEMOReInit(rmode); + DEMOSetGPHangMetric(1); + } + } + + DEMOSwapBuffers(); +} + +void DEMOSetGPHangMetric(u8 enable) { + if (enable) { + GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE); + + GXCmd1u8(0x61); + GXParam1u32(0x2402C004); + + GXCmd1u8(0x61); + GXParam1u32(0x23000020); + + GXCmd1u8(0x10); + GXParam1u16(0); + GXParam1u16(0x1006); + GXParam1u32(0x84400); + } else { + GXCmd1u8(0x61); + GXParam1u32(0x24000000); + + GXCmd1u8(0x61); + GXParam1u32(0x23000000); + + GXCmd1u8(0x10); + GXParam1u16(0); + GXParam1u16(0x1006); + GXParam1u32(0); + } +} + +static void __DEMODiagnoseHang(void) { + u32 xfTop0, xfBot0, suRdy0, r0Rdy0; + u32 xfTop1, xfBot1, suRdy1, r0Rdy1; + u32 xfTopD, xfBotD, suRdyD, r0RdyD; + u8 readIdle, cmdIdle; + u8 junk; + + GXReadXfRasMetric(&xfBot0, &xfTop0, &r0Rdy0, &suRdy0); + GXReadXfRasMetric(&xfBot1, &xfTop1, &r0Rdy1, &suRdy1); + + xfTopD = (xfTop1 - xfTop0) == 0; + xfBotD = (xfBot1 - xfBot0) == 0; + suRdyD = (suRdy1 - suRdy0) > 0; + r0RdyD = (r0Rdy1 - r0Rdy0) > 0; + + GXGetGPStatus(&junk, &junk, &readIdle, &cmdIdle, &junk); + OSReport("GP status %d%d%d%d%d%d --> ", readIdle, cmdIdle, xfTopD, xfBotD, suRdyD, r0RdyD); + + if (xfBotD == 0 && suRdyD != 0) { + OSReport("GP hang due to XF stall bug.\n"); + } else if (xfTopD == 0 && xfBotD != 0 && suRdyD != 0) { + OSReport("GP hang due to unterminated primitive.\n"); + } else if (cmdIdle == 0 && xfTopD != 0 && xfBotD != 0 && suRdyD != 0) { + OSReport("GP hang due to illegal instruction.\n"); + } else if (readIdle != 0 && cmdIdle != 0 && xfTopD != 0 && xfBotD != 0 && suRdyD != 0 && r0RdyD != 0) { + OSReport("GP appears to be not hung (waiting for input).\n"); + } else { + OSReport("GP is in unknown state.\n"); + } +} + +void DEMOReInit(GXRenderModeObj* mode) { + u32 fbSize; + GXFifoObj tmpobj; + void* tmpFifo; + GXFifoObj* realFifoObj; + void* realFifoBase; + u32 realFifoSize; + + tmpFifo = OSAlloc(64 * 1024); + + realFifoObj = GXGetCPUFifo(); + realFifoBase = GXGetFifoBase(realFifoObj); + realFifoSize = GXGetFifoSize(realFifoObj); + + GXAbortFrame(); + + GXInitFifoBase(&tmpobj, tmpFifo, 64 * 1024); + + GXSetCPUFifo(&tmpobj); + GXSetGPFifo(&tmpobj); + + __DEMOInitRenderMode(mode); + + fbSize = ((u16)(rmode->fbWidth + 15) & ~0xF) * rmode->xfbHeight * 2; + ASSERTMSGLINE(1260, fbSize <= allocatedFrameBufferSize, "DEMOReInit - Previously allocated frame buffer is too small for the new render mode."); + DefaultFifoObj = GXInit(realFifoBase, realFifoSize); + + __DEMOInitGX(); + VIConfigure(rmode); + __DEMOInitVI(); + OSFree(tmpFifo); +} diff --git a/src/dolphin/demo/DEMOPad.c b/src/dolphin/demo/DEMOPad.c new file mode 100644 index 0000000000..3320523b9f --- /dev/null +++ b/src/dolphin/demo/DEMOPad.c @@ -0,0 +1,120 @@ +#include +#include +#include + +#include "__demo.h" + +static u32 PadChanMask[4] = { + PAD_CHAN0_BIT, + PAD_CHAN1_BIT, + PAD_CHAN2_BIT, + PAD_CHAN3_BIT, +}; + +static PADStatus Pad[4]; +DEMODMPad DemoPad[4]; + +u32 DemoNumValidPads; + +// prototypes +static void DEMOPadCopy(PADStatus* pad, DEMODMPad* dmpad); + +static void DEMOPadCopy(PADStatus* pad, DEMODMPad* dmpad) { + u16 dirs; + + if (pad->err != -3) { + dirs = 0; + if (pad->stickX < -0x30) { + dirs |= 0x4000; + } + if (pad->stickX > 0x30) { + dirs |= 0x8000; + } + if (pad->stickY < -0x30) { + dirs |= 0x2000; + } + if (pad->stickY > 0x30) { + dirs |= 0x1000; + } + if (pad->substickX < -0x30) { + dirs |= 0x400; + } + if (pad->substickX > 0x30) { + dirs |= 0x800; + } + if (pad->substickY < -0x30) { + dirs |= 0x200; + } + if (pad->substickY > 0x30) { + dirs |= 0x100; + } + + dmpad->dirsNew = (dirs & (dmpad->dirs ^ dirs)); + dmpad->dirsReleased = (dmpad->dirs & (dmpad->dirs ^ dirs)); + dmpad->dirs = dirs; + dmpad->buttonDown = (pad->button & (dmpad->pst.button ^ pad->button)); + dmpad->buttonUp = (dmpad->pst.button & (dmpad->pst.button ^ pad->button)); + dmpad->stickDeltaX = (pad->stickX - dmpad->pst.stickX); + dmpad->stickDeltaY = (pad->stickY - dmpad->pst.stickY); + dmpad->substickDeltaX = (pad->substickX - dmpad->pst.substickX); + dmpad->substickDeltaY = (pad->substickY - dmpad->pst.substickY); + dmpad->pst = *pad; + } else { + dmpad->dirsNew = dmpad->dirsReleased = 0; + dmpad->buttonDown = dmpad->buttonUp = 0; + dmpad->stickDeltaX = dmpad->stickDeltaY = 0; + dmpad->substickDeltaX = dmpad->substickDeltaY = 0; + } +} + +void DEMOPadRead(void) { + s32 i; + u32 ResetReq = 0; + + PADRead(&Pad[0]); + PADClamp(&Pad[0]); + + DemoNumValidPads = 0; + + for (i = 0; i < 4; i++) { + if (Pad[i].err == 0 || Pad[i].err == -3) { + DemoNumValidPads++; + } else if (Pad[i].err == -1) { + ResetReq |= PadChanMask[i]; + } + + DEMOPadCopy(&Pad[i], &DemoPad[i]); + } + + if (ResetReq != 0) { + PADReset(ResetReq); + } +} + +void DEMOPadInit(void) { + s32 i; + + PADInit(); + + for (i = 0; i < 4; i++) { + DemoPad[i].pst.button = 0; + DemoPad[i].pst.stickX = 0; + DemoPad[i].pst.stickY = 0; + DemoPad[i].pst.substickX = 0; + DemoPad[i].pst.substickY = 0; + DemoPad[i].pst.triggerLeft = 0; + DemoPad[i].pst.triggerRight = 0; + DemoPad[i].pst.analogA = 0; + DemoPad[i].pst.analogB = 0; + DemoPad[i].pst.err = 0; + DemoPad[i].buttonDown = 0; + DemoPad[i].buttonUp = 0; + DemoPad[i].dirs = 0; + DemoPad[i].dirsNew = 0; + DemoPad[i].dirsReleased = 0; + DemoPad[i].stickDeltaX = 0; + DemoPad[i].stickDeltaY = 0; + DemoPad[i].substickDeltaX = 0; + DemoPad[i].substickDeltaY = 0; + } +} diff --git a/src/dolphin/demo/DEMOPuts.c b/src/dolphin/demo/DEMOPuts.c new file mode 100644 index 0000000000..af0ea2fe27 --- /dev/null +++ b/src/dolphin/demo/DEMOPuts.c @@ -0,0 +1,403 @@ +#include +#include +#include +#include + +#include "__demo.h" + +static GXTexObj fontTexObj; + +static s32 fontShift; +static OSFontHeader* FontData; +static void* LastSheet; +static s16 FontSize; +static s16 FontSpace; + +// prototypes +static void DrawFontChar(int x, int y, int z, int xChar, int yChar); +static void LoadSheet(void* image, GXTexMapID texMapID); + +void DEMOSetFontType(s32 attr) { + switch(attr) { + case DM_FT_RVS: + GXSetBlendMode(GX_BM_LOGIC, GX_BL_ZERO, GX_BL_ZERO, GX_LO_INVCOPY); + break; + case DM_FT_XLU: + GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR); + break; + case DM_FT_OPQ: + default: + GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR); + break; + } +} + +void DEMOLoadFont(GXTexMapID texMap, GXTexMtx texMtx, DMTexFlt texFlt) { + Mtx fontTMtx; + u16 width; + u16 height; + + width = 64; + height = 0x1800 / width; + GXInitTexObj(&fontTexObj, (void*)DEMOFontBitmap, width, (u16)height, GX_TF_I4, GX_CLAMP, GX_CLAMP, 0); + + if (texFlt == DMTF_POINTSAMPLE) { + GXInitTexObjLOD(&fontTexObj, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1); + fontShift = 0; + } else { + fontShift = 1; + } + + GXLoadTexObj(&fontTexObj, texMap); + MTXScale(fontTMtx, 1.0f / width, 1.0f / height, 1.0f); + GXLoadTexMtxImm(fontTMtx, texMtx, GX_MTX2x4); + GXSetNumTexGens(1); + GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, texMtx); +} + +void DEMOSetupScrnSpc(s32 width, s32 height, f32 depth) { + Mtx44 pMtx; + Mtx mMtx; + f32 top; + + if (DEMOGetRenderModeObj()->field_rendering && !VIGetNextField()) { + top = -0.667f; + } else { + top = 0.0f; + } + + MTXOrtho(pMtx, top, height, 0.0f, width, 0.0f, -depth); + GXSetProjection(pMtx, GX_ORTHOGRAPHIC); + MTXIdentity(mMtx); + GXLoadPosMtxImm(mMtx, GX_PNMTX0); + GXSetCurrentMtx(GX_PNMTX0); +} + +void DEMOInitCaption(s32 font_type, s32 width, s32 height) { + DEMOSetupScrnSpc(width, height, 100.0f); + GXSetZMode(GX_ENABLE, GX_ALWAYS, GX_ENABLE); + GXSetNumChans(0); + GXSetNumTevStages(1); + GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + DEMOLoadFont(GX_TEXMAP0, GX_TEXMTX0, DMTF_POINTSAMPLE); + DEMOSetFontType(font_type); +} + +void DEMOPuts(s16 x, s16 y, s16 z, char* string) { + char* str; + s32 s; + s32 t; + s32 c; + s32 w; + s32 len; + s32 i; + + str = string; + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 1); + + // calc len + len = 0; + while (1) { + c = *(str++); + if ((c >= 0x20) && (c <= 0x7F)) { + len++; + continue; + } + + if (len > 0) { + GXBegin(GX_QUADS, GX_VTXFMT0, len * 4); + for(i = 0; i < len; i++) { + w = string[i] - 0x20; + s = fontShift + ((w % 8) * 0x10); + t = fontShift + ((w / 8) * 0x10); + GXPosition3s16(x + (i * 8), y, z); + GXTexCoord2s16(s, t); + GXPosition3s16(x + (i * 8) + 8, y, z); + GXTexCoord2s16(s + 0x10, t); + GXPosition3s16(x + (i * 8) + 8, y + 8, z); + GXTexCoord2s16(s + 0x10, t + 0x10); + GXPosition3s16(x + (i * 8), y + 8, z); + GXTexCoord2s16(s, t + 0x10); + } + GXEnd(); + len = 0; + } + + string = str; + if (c == 0xA) { + y += 0x8; + } else { + break; + } + } +} + +void DEMOPrintf(s16 x, s16 y, s16 z, char* fmt, ...) { + va_list vlist; + char buf[256]; + + va_start(vlist, fmt); + vsprintf(buf, fmt, vlist); + DEMOPuts(x, y, z, buf); + va_end(vlist); +} + +OSFontHeader* DEMOInitROMFont(void) { + switch (OSGetFontEncode()) { + case OS_FONT_ENCODE_SJIS: + FontData = OSAlloc(OS_FONT_SIZE_SJIS); + break; + case OS_FONT_ENCODE_ANSI: + FontData = OSAlloc(OS_FONT_SIZE_ANSI); + break; + default: + FontData = OSAlloc(0x141020); + break; + } + + if (!FontData) { + OSPanic(__FILE__, 446, "Ins. memory to load ROM font."); + } + + if (OSInitFont(FontData) == 0) { + OSPanic(__FILE__, 450, "ROM font is available in boot ROM ver 0.8 or later."); + } + + FontSize = FontData->cellWidth * 16; + FontSpace = -16; + return FontData; +} + +void DEMOSetROMFontSize(s16 size, s16 space) { + FontSize = size * 16; + FontSpace = space * 16; +} + +void DEMOGetROMFontSize(s16* size, s16* space) { + if (size != 0) { + *size = FontSize / 16; + } + + if (space != 0) { + *space = FontSpace / 16; + } +} + +static void DrawFontChar(int x, int y, int z, int xChar, int yChar) { + s16 posLeft = x; + s16 posRight = posLeft + FontSize; + s16 posTop = y - (FontData->ascent * FontSize / FontData->cellWidth); + s16 posBottom = y + (FontData->descent * FontSize / FontData->cellWidth); + + s16 texLeft = xChar; + s16 texRight = (xChar + FontData->cellWidth); + s16 texTop = yChar; + s16 texBottom = (yChar + FontData->cellHeight); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3s16(posLeft, posTop, z); + GXTexCoord2s16(texLeft, texTop); + GXPosition3s16(posRight, posTop, z); + GXTexCoord2s16(texRight, texTop); + GXPosition3s16(posRight, posBottom, z); + GXTexCoord2s16(texRight, texBottom); + GXPosition3s16(posLeft, posBottom, z); + GXTexCoord2s16(texLeft, texBottom); + GXEnd(); +} + +static void LoadSheet(void* image, GXTexMapID texMapID) { + Mtx mtx; + GXTexObj texObj; + + if (LastSheet != image) { + LastSheet = image; + GXInitTexObj(&texObj, image, FontData->sheetWidth, FontData->sheetHeight, FontData->sheetFormat, 0, 0, 0); + GXInitTexObjLOD(&texObj, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1); + GXLoadTexObj(&texObj, texMapID); + MTXScale(mtx, 1.0f / FontData->sheetWidth, 1.0f / FontData->sheetHeight, 1.0f); + GXLoadTexMtxImm(mtx, GX_TEXMTX0, GX_MTX2x4); + GXSetNumTexGens(1); + GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0); + } +} + +int DEMORFPuts(s16 x, s16 y, s16 z, char* string) { + s32 cx; + void* image; + s32 xChar; + s32 yChar; + s32 width; + + ASSERTLINE(583, FontData); + LastSheet = NULL; + + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 4); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0); + + x *= 16; + y *= 16; + z *= 16; + + width = 0; + while (*string != 0) { + if (*string == '\n') { + width = 0; + y += FontData->leading * FontSize / FontData->cellWidth; + string++; + } else if (*string == '\t') { + width += 8 * (FontSize + FontSpace); + width -= width % (8 * (FontSize + FontSpace)); + string++; + } else { + string = OSGetFontTexture(string, &image, &xChar, &yChar, &cx); + LoadSheet(image, GX_TEXMAP0); + DrawFontChar(x + width, y, z, xChar, yChar); + width = FontSpace + ((FontSize * cx) / FontData->cellWidth) + width; + } + } + + return (width + 15) / 16; +} + +int DEMORFPutsEx(s16 x, s16 y, s16 z, char* string, s16 maxWidth, int length) { + s32 cx; + void* image; + s32 xChar; + s32 yChar; + s32 width; + char* end; + + ASSERTLINE(636, FontData); + LastSheet = NULL; + + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 4); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0); + + x *= 16; + y *= 16; + z *= 16; + maxWidth *= 16; + + end = (char*)&string[length]; + width = 0; + while (*string && string < end) { + if (*string == '\n') { + width = 0; + y += FontData->leading * FontSize / FontData->cellWidth; + string++; + } else { + string = OSGetFontTexture(string, &image, &xChar, &yChar, &cx); + if (maxWidth < width + (FontSize * cx / FontData->cellWidth) + FontSpace) { + width = 0; + y += FontData->leading * FontSize / FontData->cellWidth; + } + LoadSheet(image, GX_TEXMAP0); + DrawFontChar(x + width, y, z, xChar, yChar); + width = FontSpace + (FontSize * cx / FontData->cellWidth) + width; + } + } + + return (width + 15) / 16; +} + +int DEMORFPrintf(s16 x, s16 y, s16 z, char* fmt, ...) { + va_list vlist; + char buf[256]; + + va_start(vlist, fmt); + vsprintf(buf, fmt, vlist); + DEMORFPuts(x, y, z, buf); +} + +char* DEMODumpROMFont(char* string) { + u32 image[288]; + void* temp; + int i; + int j; + s32 width; + + ASSERTLINE(724, FontData); + + switch (OSGetFontEncode()) { + case OS_FONT_ENCODE_SJIS: + temp = (u8*)FontData + OS_FONT_SIZE_SJIS - OS_FONT_ROM_SIZE_SJIS; + break; + case OS_FONT_ENCODE_ANSI: + temp = (u8*)FontData + OS_FONT_SIZE_ANSI - OS_FONT_ROM_SIZE_ANSI; + break; + default: + temp = (u8*)FontData + 0xF4020; + break; + } + + temp = (void*)OSRoundDown32B(temp); + OSLoadFont(FontData, temp); + + memset(image, 0, sizeof(image)); + string = OSGetFontTexel(string, &image[0], 0, 0xC, &width); + for (i = 0; i < 0x30; i++) { + j = (i % 8) + ((i / 8) * 0x30); + OSReport("%08x%08x%08x%08x%08x%08x\n", image[j], image[j+8], image[j+0x10], image[j+0x18], image[j+0x20], image[j+0x28]); + } + + OSReport("\nwidth %d\n", width); + OSInitFont(FontData); + return string; +} + +int DEMOGetRFTextWidth(char* string) { + s32 cx; + s32 width; + s32 maxWidth; + + ASSERTLINE(779, FontData); + maxWidth = width = 0; + + while (*string != 0) { + if (*string == '\n') { + if (maxWidth < width) { + maxWidth = width; + } + + width = 0; + } + + string = OSGetFontWidth(string, &cx); + width = FontSpace + ((FontSize * cx) / FontData->cellWidth) + width; + } + + if (maxWidth < width) { + maxWidth = width; + } + + return (maxWidth + 15) / 16; +} + +int DEMOGetRFTextHeight(char* string) { + s32 height; + + ASSERTLINE(815, FontData); + + height = 1; + while (*string) { + if (*string == '\n') { + height++; + } + string++; + } + + height *= FontData->leading * FontSize / FontData->cellWidth; + return (height + 15) / 16; +} diff --git a/src/dolphin/demo/DEMOStats.c b/src/dolphin/demo/DEMOStats.c new file mode 100644 index 0000000000..ca79effef3 --- /dev/null +++ b/src/dolphin/demo/DEMOStats.c @@ -0,0 +1,416 @@ +#include +#include +#include + +#include "__demo.h" + +u8 DemoStatEnable = 0; +static DemoStatData* DemoStat; +static u32 DemoStatIndx; +static u32 DemoStatMaxIndx; +static u32 DemoStatClocks; +static u32 DemoStatDisp; +static u32 DemoStatStrLen; +static u32 topPixIn; +static u32 topPixOut; +static u32 botPixIn; +static u32 botPixOut; +static u32 clrPixIn; +static u32 copyClks; +static u32 vcCheck; +static u32 vcMiss; +static u32 vcStall; +static u32 cpReq; +static u32 tcReq; +static u32 cpuRdReq; +static u32 cpuWrReq; +static u32 dspReq; +static u32 ioReq; +static u32 viReq; +static u32 peReq; +static u32 rfReq; +static u32 fiReq; + +// prototypes +static void DEMOWriteStats(u8 update); +static void DEMOWriteStats(u8 update); + +void DEMOSetStats(DemoStatData* stat, u32 nstats, DEMO_STAT_DISP disp) { + if (stat == 0 || nstats == 0) { + DemoStatEnable = FALSE; + } else { + DemoStatEnable = TRUE; + DemoStat = stat; + DemoStatIndx = 0; + DemoStatMaxIndx = nstats; + DemoStatDisp = disp; + DemoStatStrLen = strlen(DemoStat->text); + } +} + +static void DEMOWriteStats(u8 update) { + u32 cnt0; + u32 cnt1; + u32 cnt2; + u32 cnt3; + u32 cnt4; + u32 cnt5; + u32 cnt6; + u32 cnt7; + u32 cnt8; + u32 cnt9; + + switch (DemoStat[DemoStatIndx].stat_type) { + case DEMO_STAT_GP0: + if (update) { + cnt0 = GXReadGP0Metric(); + DemoStat[DemoStatIndx].count = cnt0; + GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE); + } else { + GXSetGPMetric(DemoStat[DemoStatIndx].stat, GX_PERF1_NONE); + GXClearGPMetric(); + } + break; + case DEMO_STAT_GP1: + if (update) { + cnt0 = GXReadGP1Metric(); + DemoStat[DemoStatIndx].count = cnt0; + GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE); + } else { + GXSetGPMetric(GX_PERF0_NONE, DemoStat[DemoStatIndx].stat); + GXClearGPMetric(); + } + break; + case DEMO_STAT_MEM: + if (update) { + GXReadMemMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5, &cnt6, &cnt7, &cnt8, &cnt9); + cpReq = cnt0; + tcReq = cnt1; + cpuRdReq = cnt2; + cpuWrReq = cnt3; + dspReq = cnt4; + ioReq = cnt5; + viReq = cnt6; + peReq = cnt7; + rfReq = cnt8; + fiReq = cnt9; + } else { + GXClearMemMetric(); + } + break; + case DEMO_STAT_PIX: + if (update) { + GXReadPixMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5); + topPixIn = cnt0; + topPixOut = cnt1; + botPixIn = cnt2; + botPixOut = cnt3; + clrPixIn = cnt4; + copyClks = cnt5; + } else { + GXClearPixMetric(); + } + break; + case DEMO_STAT_VC: + if (update) { + GXReadVCacheMetric(&cnt0, &cnt1, &cnt2); + vcCheck = cnt0; + vcMiss = cnt1; + vcStall = cnt2; + } else { + GXSetVCacheMetric(0); + GXClearVCacheMetric(); + } + break; + case DEMO_STAT_FR: + if (update) { + GXReadPixMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5); + topPixIn = cnt0; + topPixOut = cnt1; + botPixIn = cnt2; + botPixOut = cnt3; + clrPixIn = cnt4; + copyClks = cnt5; + DemoStatClocks = GXReadGP0Metric(); + GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE); + } else { + GXClearPixMetric(); + GXSetGPMetric(GX_PERF0_CLOCKS, GX_PERF1_NONE); + GXClearGPMetric(); + } + break; + case DEMO_STAT_TBW: + case DEMO_STAT_TBP: + GXClearPixMetric(); + if (update) { + GXReadPixMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5); + topPixIn = cnt0; + topPixOut = cnt1; + botPixIn = cnt2; + botPixOut = cnt3; + clrPixIn = cnt4; + copyClks = cnt5; + DemoStatClocks = GXReadGP0Metric(); + GXReadMemMetric(&cnt0, &cnt1, &cnt2, &cnt3, &cnt4, &cnt5, &cnt6, &cnt7, &cnt8, &cnt9); + tcReq = cnt1; + GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE); + } else { + GXClearMemMetric(); + GXSetGPMetric(GX_PERF0_CLOCKS, GX_PERF1_NONE); + GXClearGPMetric(); + } + break; + case DEMO_STAT_MYC: + case DEMO_STAT_MYR: + break; + default: + OSPanic(__FILE__, 295, "DEMOSetStats: Unknown demo stat type\n"); + } +} + +void DEMOUpdateStats(u8 inc) { + DEMOWriteStats(inc); + if (inc) { + DemoStatIndx = DemoStatIndx + 1; + if (DemoStatIndx == DemoStatMaxIndx) { + DemoStatIndx = 0; + } + } +} + +void DEMOPrintStats(void) { + GXRenderModeObj* rmode; + u32 i; + s16 text_x; + s16 text_y; + s16 text_yinc; + u16 wd; + u16 ht; + f32 rate; + + if (DemoStatDisp == DEMO_STAT_IO) { + for (i = 0; i < DemoStatMaxIndx; i++) { + switch (DemoStat[i].stat_type) { + case DEMO_STAT_PIX: + switch (DemoStat[i].stat) { + case 0: + OSReport("%s: %8d\n", DemoStat[i].text, topPixIn); + break; + case 1: + OSReport("%s: %8d\n", DemoStat[i].text, topPixOut); + break; + case 2: + OSReport("%s: %8d\n", DemoStat[i].text, botPixIn); + break; + case 3: + OSReport("%s: %8d\n", DemoStat[i].text, botPixOut); + break; + case 4: + OSReport("%s: %8d\n", DemoStat[i].text, clrPixIn); + break; + case 5: + OSReport("%s: %8d\n", DemoStat[i].text, copyClks); + break; + } + break; + case DEMO_STAT_FR: + rate = 162.0f * (topPixIn + botPixIn) / (f32) (DemoStatClocks - copyClks); + OSReport("%s: %8.2f\n", DemoStat[i].text, rate); + break; + case DEMO_STAT_TBW: + rate = 162.0f * (tcReq << 5) / (f32) (DemoStatClocks - copyClks); + OSReport("%s: %8.2f\n", DemoStat[i].text, rate); + break; + case DEMO_STAT_TBP: + rate = (tcReq << 5) / (f32) (topPixIn + botPixIn); + OSReport("%s: %8.2f\n", DemoStat[i].text, rate); + break; + case DEMO_STAT_VC: + switch (DemoStat[i].stat) { + case 0: + OSReport("%s: %8d\n", DemoStat[i].text, vcCheck); + break; + case 1: + OSReport("%s: %8d\n", DemoStat[i].text, vcMiss); + break; + case 2: + OSReport("%s: %8d\n", DemoStat[i].text, vcStall); + break; + } + break; + case DEMO_STAT_MYR: + rate = DemoStat[i].stat / (f32) DemoStat[i].count; + OSReport("%s: %8.2f\n", DemoStat[i].text, rate); + break; + case DEMO_STAT_MEM: + switch (DemoStat[i].stat) { + case 0: + OSReport("%s: %8d\n", DemoStat[i].text, cpReq); + break; + case 1: + OSReport("%s: %8d\n", DemoStat[i].text, tcReq); + break; + case 2: + OSReport("%s: %8d\n", DemoStat[i].text, cpuRdReq); + break; + case 3: + OSReport("%s: %8d\n", DemoStat[i].text, cpuWrReq); + break; + case 4: + OSReport("%s: %8d\n", DemoStat[i].text, dspReq); + break; + case 5: + OSReport("%s: %8d\n", DemoStat[i].text, ioReq); + break; + case 6: + OSReport("%s: %8d\n", DemoStat[i].text, viReq); + break; + case 7: + OSReport("%s: %8d\n", DemoStat[i].text, peReq); + break; + case 8: + OSReport("%s: %8d\n", DemoStat[i].text, rfReq); + break; + case 9: + OSReport("%s: %8d\n", DemoStat[i].text, fiReq); + break; + } + break; + default: + OSReport("%s: %8d\n", DemoStat[i].text, DemoStat[i].count); + break; + } + } + } else { + rmode = DEMOGetRenderModeObj(); + switch (DemoStatDisp) { + case DEMO_STAT_TL: + text_x = 0x10; + text_y = 0x10; + text_yinc = 0xA; + wd = rmode->fbWidth; + ht = rmode->xfbHeight; + break; + case DEMO_STAT_BL: + text_x = 0x10; + text_y = rmode->xfbHeight - 0x18; + text_yinc = -0xA; + wd = rmode->fbWidth; + ht = rmode->xfbHeight; + break; + case DEMO_STAT_TLD: + text_x = 8; + text_y = 8; + text_yinc = 9; + wd = rmode->fbWidth / 2; + ht = rmode->xfbHeight / 2; + break; + case DEMO_STAT_BLD: + text_x = 8; + text_y = (rmode->xfbHeight - 0x18) / 2; + text_yinc = -9; + wd = rmode->fbWidth / 2; + ht = rmode->xfbHeight / 2; + break; + } + DEMOInitCaption(0, wd, ht); + for (i = 0; i < DemoStatMaxIndx; i++) { + switch (DemoStat[i].stat_type) { + case DEMO_STAT_PIX: + switch (DemoStat[i].stat) { + case 0: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, topPixIn); + break; + case 1: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, topPixOut); + break; + case 2: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, botPixIn); + break; + case 3: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, botPixOut); + break; + case 4: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, clrPixIn); + break; + case 5: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, copyClks); + break; + } + break; + case DEMO_STAT_FR: + rate = 162.0f * (topPixIn + botPixIn) / (f32) (DemoStatClocks - copyClks); + DEMOPrintf(text_x, text_y, 0, "%s: %8.2f\n", DemoStat[i].text, rate); + break; + case DEMO_STAT_TBW: + rate = 162.0f * (tcReq << 5) / (f32) (DemoStatClocks - copyClks); + DEMOPrintf(text_x, text_y, 0, "%s: %8.2f\n", DemoStat[i].text, rate); + break; + case DEMO_STAT_TBP: + rate = (tcReq << 5) / (f32) (topPixIn - botPixIn); + DEMOPrintf(text_x, text_y, 0, "%s: %8.3f\n", DemoStat[i].text, rate); + break; + case DEMO_STAT_VC: + switch (DemoStat[i].stat) { + case 0: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, vcCheck); + break; + case 1: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, vcMiss); + break; + case 2: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, vcStall); + break; + } + break; + case DEMO_STAT_MEM: + switch (DemoStat[i].stat) { + case 0: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, cpReq); + break; + case 1: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, tcReq); + break; + case 2: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, cpuRdReq); + break; + case 3: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, cpuWrReq); + break; + case 4: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, dspReq); + break; + case 5: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, ioReq); + break; + case 6: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, viReq); + break; + case 7: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, peReq); + break; + case 8: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, rfReq); + break; + case 9: + DEMOPrintf(text_x, text_y, 0, "%s: %8d\n", DemoStat[i].text, fiReq); + break; + } + break; + case DEMO_STAT_GP0: + case DEMO_STAT_GP1: + case DEMO_STAT_MYC: + DEMOPrintf(text_x, text_y, 0, "%s: %8d", DemoStat[i].text, DemoStat[i].count); + break; + case DEMO_STAT_MYR: + rate = DemoStat[i].stat / (f32) DemoStat[i].count; + DEMOPrintf(text_x, text_y, 0, "%s: %8.3f", DemoStat[i].text, rate); + break; + default: + OSReport("Undefined stat type %d in DEMOPrintStats()\n", DemoStat[i].stat_type); + break; + } + text_y += text_yinc; + } + } +} diff --git a/src/dolphin/demo/DEMOWin.c b/src/dolphin/demo/DEMOWin.c new file mode 100644 index 0000000000..108e3769a5 --- /dev/null +++ b/src/dolphin/demo/DEMOWin.c @@ -0,0 +1,981 @@ +#include +#include +#include + + +static u32 __DEMOWIN_PAD_repeat_threshold = 0x0000000F; +static u32 __DEMOWIN_PAD_repeat_rate = 0x00000002; + +DEMOWindow* __first_node; +DEMOWindow* __last_node; +DEMOWindow* __curr_node; +GXRenderModeObj* __rmp; + +s32 fontShift = 0; + +// functions +static void __DEMOWin_add_node(DEMOWindow* handle); +static void __DEMOWin_delete_node(DEMOWindow* handle); +static void __DEMOWin_puts_n(s16 x, s16 y, s16 z, u16 n, char* string); +static void __DEMOWinMenu_refesh_menu(DEMOWindow* w); +static u16 __DEMOWinMenu_get_user_input(DEMOWinPadInfo* p); +static void __DEMOWinList_refresh_list(DEMOWindow* w); + +void DEMOWinInit() { + __first_node = NULL; + __last_node = NULL; + __curr_node = NULL; + __rmp = DEMOGetRenderModeObj(); + GXSetCopyClear((GXColor){0, 0, 0, 0}, 0xFFFFFF); +} + +DEMOWindow* DEMOWinCreateWindow(s32 x1, s32 y1, s32 x2, s32 y2, char* caption, u16 scroll, void* func) { + DEMOWindow* handle; + ASSERTMSGLINE(188, x1 < x2, "DEMOWIN: Illegal X coords for window\n"); + ASSERTMSGLINE(189, y1 < y2, "DEMOWIN: Illegal y coords for window\n"); + + handle = (void*)OSAlloc(sizeof(DEMOWindow)); + ASSERTMSGLINE(193, handle, "DEMOWIN: FAILED TO ALLOCATE WINDOW!\n"); + + handle->x1 = x1; + handle->y1 = y1; + handle->x2 = x2; + handle->y2 = y2; + handle->pixel_width = (x2 - x1) + 1; + handle->pixel_height = (y2 - y1) + 1; + handle->caption = caption; + handle->char_width = (handle->pixel_width / 8) - 1; + handle->char_height = (handle->pixel_height / 8) - 2; + handle->x_cal = (((handle->pixel_width - (handle->char_width * 8)) + 1) / 2); + handle->y_cal = (((handle->pixel_height - 7) - (handle->char_height * 8)) / 2); + handle->num_scroll_lines = scroll; + handle->total_lines = handle->char_height + handle->num_scroll_lines; + handle->curr_output_line = 0; + handle->curr_output_col = 0; + handle->curr_view_line = 0; + handle->refresh = func; + handle->flags = 0; + handle->priority = 0; + + handle->buffer = (void*)OSAlloc(handle->total_lines * handle->char_width); + ASSERTMSGLINE(249, handle->buffer, "DEMOWinCreateWindow(): Unable to allocation buffer!\n"); + memset(handle->buffer, ' ', handle->total_lines * handle->char_width); // set to all empty spaces + + DEMOWinSetWindowColor(handle, DEMOWIN_ITEM_DEFAULT, 0, 0, 0, 0); + handle->cursor_line = -1; + handle->parent = 0; + __DEMOWin_add_node(handle); + return handle; +} + +void DEMOWinDestroyWindow(DEMOWindow* handle) { + BOOL old; + ASSERTMSGLINE(287, handle, "DEMOWinDestroyWindow(): NULL handle!\n"); + old = OSDisableInterrupts(); + __DEMOWin_delete_node(handle); + OSFree(handle->buffer); + OSFree(handle); + OSRestoreInterrupts(old); +} + +void DEMOWinOpenWindow(DEMOWindow* handle) { + ASSERTMSGLINE(321, handle, "DEMOWinOpenWindow(): NULL handle!\n"); + handle->flags |= DEMOWIN_FLAGS_OPENED; +} + +void DEMOWinCloseWindow(DEMOWindow* handle) { + ASSERTMSGLINE(337, handle, "DEMOWinCloseWindow(): NULL handle!\n"); + handle->flags &= ~(DEMOWIN_FLAGS_OPENED); +} + +void DEMOWinSetWindowColor(DEMOWindow* handle, u32 item, u8 r, u8 g, u8 b, u8 a) { + ASSERTMSGLINE(355, handle, "DEMOWinSetWinColor(): NULL window handle\n"); + + switch(item) { + case DEMOWIN_ITEM_CAP: // set cap + handle->cap.r = r; + handle->cap.g = g; + handle->cap.b = b; + handle->cap.a = a; + return; + case DEMOWIN_ITEM_BORDER: // set border + handle->border.r = r; + handle->border.g = g; + handle->border.b = b; + handle->border.a = a; + return; + case DEMOWIN_ITEM_BKGND: // set background + handle->bkgnd.r = r; + handle->bkgnd.g = g; + handle->bkgnd.b = b; + handle->bkgnd.a = a; + return; + case DEMOWIN_ITEM_DEFAULT: // default window colors + // RGB 26, 31, 33; Cinder (grey) + handle->bkgnd.r = 26; + handle->bkgnd.g = 31; + handle->bkgnd.b = 33; + handle->bkgnd.a = 255; + // RGB 85, 31, 31; Burnt Crimson (red) + handle->cap.r = 85; + handle->cap.g = 31; + handle->cap.b = 31; + handle->cap.a = 255; + // RGB 69, 37, 37; Bulgarian Rose (red) + handle->border.r = 69; + handle->border.g = 37; + handle->border.b = 37; + handle->border.a = 255; + return; + default: + ASSERTMSGLINE(398, FALSE, "DEMOWinSetWinColor(): Unknown item\n"); + return; + } +} + +void DEMOWinLogPrintf(DEMOWindow* handle, char* fmt, ...) { + va_list vlist; + char buffer[128]; + u16 len; + u16 i; + BOOL old; + u16 index; + + va_start(vlist, fmt); + vsprintf(buffer, fmt, vlist); + + old = OSDisableInterrupts(); + len = strlen(buffer); + for (i = 0; i < len; i++) { + if(buffer[i] == 0xA) { + handle->curr_output_line = (handle->curr_output_line + 1) % handle->total_lines; + handle->curr_view_line = (handle->curr_view_line + 1) % handle->total_lines; + handle->curr_output_col = 0; + index = handle->curr_output_col + (handle->curr_output_line* handle->char_width); + memset(&handle->buffer[index], ' ', handle->char_width); + } else { + index = handle->curr_output_col + (handle->curr_output_line* handle->char_width); + handle->buffer[index] = buffer[i]; + handle->curr_output_col++; + } + + if (handle->curr_output_col >= handle->char_width) { + handle->curr_output_col = 0; + handle->curr_output_line = (handle->curr_output_line + 1) % handle->total_lines; + handle->curr_view_line = (handle->curr_view_line + 1) % handle->total_lines; + index = handle->curr_output_col + (handle->curr_output_line* handle->char_width); + memset(&handle->buffer[index], ' ', handle->char_width); + } + } + + OSRestoreInterrupts(old); + va_end(vlist); +} + +void DEMOWinPrintfXY(DEMOWindow* handle, u16 col, u16 row, char* fmt, ...) { + BOOL old; + va_list vlist; + char string[128]; + u16 buffer_row; + u16 i; + u16 index; + + if (row >= handle->char_height || col >= handle->char_width) { + return; + } + + old = OSDisableInterrupts(); + va_start(vlist, fmt); + vsprintf(string, fmt, vlist); + buffer_row = ((handle->curr_view_line + handle->total_lines) - (handle->char_height - 1)) % handle->total_lines; + buffer_row = (((buffer_row) + row) % handle->total_lines); + string[handle->char_width - col] = 0; + index = (col + buffer_row* handle->char_width); + + for (i = 0; i < strlen(string); i++) { + handle->buffer[index + i] = string[i]; + } + + OSRestoreInterrupts(old); +} + +void DEMOWinScrollWindow(DEMOWindow* handle, u32 dir) { + BOOL old; + u16 n; + u16 v_start; + + ASSERTMSGLINE(550, handle, "DEMOWinScrollWindow(): NULL handle!\n"); + ASSERTMSGLINE(551, handle->num_scroll_lines, "DEMOWinScrollWindow(): No scrollback buffer!\n"); + + switch(dir) { + case 1: + old = OSDisableInterrupts(); + n = (handle->curr_view_line + handle->total_lines - 1) % handle->total_lines; + v_start = ((n + handle->total_lines) - handle->char_height + 1) % handle->total_lines; + if (v_start != handle->curr_output_line) { + handle->curr_view_line = n; + } + OSRestoreInterrupts(old); + return; + case 2: + old = OSDisableInterrupts(); + if (handle->curr_view_line != handle->curr_output_line) { + handle->curr_view_line = (handle->curr_view_line + 1) % handle->total_lines; + } + OSRestoreInterrupts(old); + return; + case 0: + old = OSDisableInterrupts(); + handle->curr_view_line = handle->curr_output_line; + OSRestoreInterrupts(old); + return; + default: + ASSERTMSGLINE(586, FALSE, "DEMOWinScrollWindow(): Unknown token\n"); + return; + } +} + +void DEMOWinBringToFront(DEMOWindow* handle) { + DEMOWindow* ptr; + ASSERTMSGLINE(609, __first_node, "DEMOWinBringToFront(): Window list is empty!\n"); + ASSERTMSGLINE(610, handle, "DEMOWinBringToFront(): NULL handle!\n"); + + if (handle->priority) { + for(ptr = __first_node; ptr; ptr = ptr->next) { + ptr->priority = 1; + } + handle->priority = 0; + } +} + +void DEMOWinSendToBack(DEMOWindow* handle) { + ASSERTMSGLINE(645, handle, "DEMOWinSendToBack(): NULL handle!\n"); + handle->priority = 1; +} + +void DEMOWinClearRow(DEMOWindow* handle, u16 row) { + u16 buffer_row; + u16 index; + u16 i; + BOOL old; + + ASSERTMSGLINE(669, handle, "DEMOWinClearRow(): NULL handle!\n"); + + if (row < handle->char_height) { + old = OSDisableInterrupts(); + buffer_row = (((handle->curr_view_line + handle->total_lines) - (handle->char_height - 1)) % handle->total_lines); + buffer_row = (((buffer_row + row) % handle->total_lines)); + index = (buffer_row* handle->char_width); + + for (i = 0; i < handle->char_width; i++) { + handle->buffer[index + i] = ' '; + } + + OSRestoreInterrupts(old); + } +} + +void DEMOWinClearWindow(DEMOWindow* handle) { + u16 buffer_row; + u16 index; + u16 i; + BOOL old; + + ASSERTMSGLINE(718, handle, "DEMOWinClearWindow(): NULL handle!\n"); + + old = OSDisableInterrupts(); + buffer_row = ((handle->curr_view_line + handle->total_lines) - (handle->char_height - 1)) % handle->total_lines; + + for (i = 0; i < handle->char_height; i++) { + index = buffer_row* handle->char_width; + memset(&handle->buffer[index], ' ', handle->char_width); + buffer_row = (buffer_row + 1) % handle->total_lines; + } + + OSRestoreInterrupts(old); +} + +void DEMOWinClearBuffer(DEMOWindow* handle) { + BOOL old; + + ASSERTMSGLINE(752, handle, "DEMOWinClearBuffer(): NULL handle!\n"); + old = OSDisableInterrupts(); + memset(handle->buffer, ' ', handle->total_lines* handle->char_width); + OSRestoreInterrupts(old); +} + +void DEMOWinRefresh(void) { + DEMOWindow* ptr; + u16 i; + u16 index; + u16 n; + u16 y; + BOOL old; + + ASSERTMSGLINE(792, __first_node, "DEMOWinRefresh(): Windowlist is empty!\n"); + + for (ptr = __first_node; ptr; ptr = ptr->next) { + if (ptr->flags & DEMOWIN_FLAGS_OPENED) { + GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE); + GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); + GXSetNumTexGens(0); + GXSetNumTevStages(1); + GXSetLineWidth(6, GX_TO_ZERO); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32(ptr->x1, ptr->y1, ptr->priority); + GXColor4u8(ptr->bkgnd.r, ptr->bkgnd.g, ptr->bkgnd.b, ptr->bkgnd.a); + GXPosition3f32(ptr->x2, ptr->y1, ptr->priority); + GXColor4u8(ptr->bkgnd.r, ptr->bkgnd.g, ptr->bkgnd.b, ptr->bkgnd.a); + GXPosition3f32(ptr->x2, ptr->y2, ptr->priority); + GXColor4u8(ptr->bkgnd.r, ptr->bkgnd.g, ptr->bkgnd.b, ptr->bkgnd.a); + GXPosition3f32(ptr->x1, ptr->y2, ptr->priority); + GXColor4u8(ptr->bkgnd.r, ptr->bkgnd.g, ptr->bkgnd.b, ptr->bkgnd.a); + GXEnd(); + + GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32(ptr->x1, ptr->y1, ptr->priority); + GXColor4u8(ptr->cap.r, ptr->cap.g, ptr->cap.b, 255); + GXPosition3f32(ptr->x2, ptr->y1, ptr->priority); + GXColor4u8(0, 0, 0, 0x40); + GXPosition3f32(ptr->x2, ptr->y1 + 10, ptr->priority); + GXColor4u8(0, 0, 0, 0x40); + GXPosition3f32(ptr->x1, ptr->y1 + 10, ptr->priority); + GXColor4u8(ptr->cap.r, ptr->cap.g, ptr->cap.b, 255); + GXEnd(); + + GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR); + + // macro? + do { + // would initialize on init, but DWARF order for 2nd macro suggests they didnt init on same declare. + u8 r1; + u8 g1; + u8 b1; + u8 r2; + u8 g2; + u8 b2; + u8 a; + + r1 = 1.3 * (f32)ptr->border.r; + g1 = 1.3 * (f32)ptr->border.g; + b1 = 1.3 * (f32)ptr->border.b; + r2 = 0.4 * (f32)ptr->border.r; + g2 = 0.4 * (f32)ptr->border.g; + b2 = 0.4 * (f32)ptr->border.b; + a = 64; + + GXSetLineWidth(6, GX_TO_ZERO); + + GXBegin(GX_LINESTRIP, GX_VTXFMT0, 7); + GXPosition3f32(ptr->x1, ptr->y1, ptr->priority); + GXColor4u8(r1, g1, b1, a); + GXPosition3f32(ptr->x2, ptr->y1, ptr->priority); + GXColor4u8(r1, g1, b1, a); + GXPosition3f32(ptr->x2, ptr->y1, ptr->priority); + GXColor4u8(r2, g2, b2, a); + GXPosition3f32(ptr->x2, ptr->y2, ptr->priority); + GXColor4u8(r2, g2, b2, a); + GXPosition3f32(ptr->x1, ptr->y2, ptr->priority); + GXColor4u8(r2, g2, b2, a); + GXPosition3f32(ptr->x1, ptr->y2, ptr->priority); + GXColor4u8(r1, g1, b1, a); + GXPosition3f32(ptr->x1, ptr->y1, ptr->priority); + GXColor4u8(r1, g1, b1, a); + GXEnd(); + } while(0); + + if (ptr->refresh) { + ptr->refresh(ptr); + } + + DEMOInitCaption(DM_FT_XLU, __rmp->fbWidth, __rmp->efbHeight); + GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE); + + old = OSDisableInterrupts(); + y = (ptr->y2 - 8) - ptr->y_cal; + n = ptr->curr_view_line; + index = n* ptr->char_width; + + for (i = 0; i < ptr->char_height; i++) { + __DEMOWin_puts_n(ptr->x1 + ptr->x_cal, y, ptr->priority, ptr->char_width, (void*)&ptr->buffer[index]); + y = y - 8; + n = (n + (ptr->total_lines) - 1) % ptr->total_lines; + index = n* ptr->char_width; + } + + DEMOPrintf(ptr->x1 + 2, ptr->y1, ptr->priority, "%s", ptr->caption); + + if (ptr->cursor_line >= 0) { + GXSetLineWidth(6, GX_TO_ZERO); + GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE); + GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); + GXSetNumTexGens(0); + GXSetNumTevStages(1); + GXSetLineWidth(6, GX_TO_ZERO); + + // macro? + do { + u8 r; + u8 g; + u8 b; + u8 a; + s32 curr_y; + + curr_y = (ptr->y2 - 8) - ptr->y_cal; + curr_y -= ((ptr->char_height - 1) * 8) - ptr->cursor_line * 8; + r = 1.9 * (f32)ptr->bkgnd.r; + g = 1.9 * (f32)ptr->bkgnd.g; + b = 1.9 * (f32)ptr->bkgnd.b; + + a = 100; + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32(ptr->x1, curr_y, ptr->priority); + GXColor4u8(r, g, b, a); + GXPosition3f32(ptr->x2, curr_y, ptr->priority); + GXColor4u8(r, g, b, a); + GXPosition3f32(ptr->x2, (f32)(curr_y + 8), ptr->priority); + GXColor4u8(r, g, b, a); + GXPosition3f32(ptr->x1, (f32)(curr_y + 8), ptr->priority); + GXColor4u8(r, g, b, a); + GXEnd(); + } while(0); + } + OSRestoreInterrupts(old); + } + } +} + +static void __DEMOWin_add_node(DEMOWindow* handle) { + ASSERTMSGLINE(1032, handle, "__add_node(): you're adding a NULL node!\n"); + + // WHY. why it backwards. who writes like this? + if (NULL == __last_node) { + __curr_node = handle; + __last_node = handle; + __first_node = handle; + handle->next = 0; + handle->prev = 0; + ASSERTMSGLINE(1042, __first_node, " > __first_node: NULL HANDLE!\n"); + } else { + __last_node->next = handle; + handle->next = 0; + handle->prev = __last_node; + __last_node = handle; + } + + handle->flags |= DEMOWIN_FLAGS_INIT; +} + +static void __DEMOWin_delete_node(DEMOWindow* handle) { + ASSERTMSGLINE(1071, handle, "__delete_node(): you're deleting a NULL node!\n"); + + if (__first_node == handle) { + if (handle->next) { + __first_node = handle->next; + handle->next->prev = NULL; + } else { + __first_node = __last_node = NULL; + } + } else if (__last_node == handle) { + if (handle->prev) { + __last_node = handle->prev; + handle->prev->next = NULL; + } else { + __first_node = __last_node = NULL; + } + } else { + handle->prev->next = handle->next; + handle->next->prev = handle->prev; + } + + handle->flags &= ~(DEMOWIN_FLAGS_INIT); +} + +static void __DEMOWin_puts_n(s16 x, s16 y, s16 z, u16 n, char* string) { + s32 s; + s32 t; + s32 w; + s32 len; + s32 i; + + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 1); + + len = n; + if (len > 0) { + GXBegin(GX_QUADS, GX_VTXFMT0, len * 4); + for (i = 0; i < len; i++) { + w = string[i] - 0x20; + s = fontShift + (((w) % 8) * 16); + t = fontShift + (((w) / 8) * 16); + GXPosition3s16(x + (i * 8), y, z); + GXTexCoord2s16(s, t); + GXPosition3s16(x + (i * 8) + 8, y, z); + GXTexCoord2s16(s + 16, t); + GXPosition3s16(x + (i * 8) + 8, y + 8, z); + GXTexCoord2s16(s + 16, t + 16); + GXPosition3s16(x + (i * 8), y + 8, z); + GXTexCoord2s16(s, t + 16); + } + GXEnd(); + } +} + +DEMOWinMenu* DEMOWinCreateMenuWindow(DEMOWinMenu* menu, u16 x, u16 y) { + DEMOWinMenuItem* ptr; + + ptr = menu->items; + menu->max_str_len = strlen(menu->title); + menu->num_items = 0; + + while(!(ptr->flags & 0x80000000)) { + if (strlen(ptr->name) > menu->max_str_len) { + menu->max_str_len = strlen(ptr->name); + } + menu->num_items++; + ptr++; + } + + if (menu->num_items > menu->max_display_items) { + menu->num_display_items = menu->max_display_items; + } else { + menu->num_display_items = menu->num_items; + } + + menu->handle = DEMOWinCreateWindow((s16)x, (s16)y, (s16)(((menu->max_str_len + 7) * 8) + 4 + x), (s16)(((menu->num_display_items + 2) * 8) + 4 + y), menu->title, 0, __DEMOWinMenu_refesh_menu); + menu->handle->parent = menu; + if (menu->num_items) { + return menu; + } + + return NULL; +} + +void DEMOWinDestroyMenuWindow(DEMOWinMenu* menu) { + if (menu->handle) { + DEMOWinCloseWindow(menu->handle); + DEMOWinDestroyWindow(menu->handle); + menu->handle = NULL; + } +} + +u32 DEMOWinMenuChild(DEMOWinMenu* menu, int child_flag) { + DEMOWinPadInfo* pad; + DEMOWindow* handle; + u16 user_input; + int exit_flag; + u32 result; + + exit_flag = 0; + result = 0; + handle = menu->handle; + pad = &menu->handle->pad; + + DEMOWinOpenWindow(handle); + DEMOWinBringToFront(handle); + menu->curr_pos = 0; + menu->display_pos = 0; + + if(menu->cb_open) { + menu->cb_open(menu, menu->curr_pos); + } + + DEMOWinPadInit(pad); + DEMOBeforeRender(); + DEMOWinRefresh(); + DEMODoneRender(); + DEMOWinPadRead(pad); + DEMOBeforeRender(); + DEMOWinRefresh(); + DEMODoneRender(); + + while (!exit_flag) { + user_input = __DEMOWinMenu_get_user_input(pad); + switch(user_input) { + case 1: + menu->curr_pos = ((menu->curr_pos - 1 + menu->num_items) % menu->num_items) & 0xFFFF; + while (menu->items[menu->curr_pos].flags & 9) { + menu->curr_pos = ((menu->curr_pos - 1 + menu->num_items) % menu->num_items) & 0xFFFF; + } + if (menu->cb_move) { + menu->cb_move(menu, menu->curr_pos); + } + break; + case 2: + menu->curr_pos = ((menu->curr_pos + 1) % menu->num_items) & 0xFFFF; + while (menu->items[menu->curr_pos].flags & 9) { + menu->curr_pos = ((menu->curr_pos + 1) % menu->num_items) & 0xFFFF; + } + if (menu->cb_move) { + menu->cb_move(menu, menu->curr_pos); + } + break; + case 3: + if (child_flag == 1) { + exit_flag = 1; + if (menu->cb_cancel) { + menu->cb_cancel(menu, menu->curr_pos); + } + } + break; + case 4: + if (menu->cb_move) { + menu->cb_move(menu, menu->curr_pos); + } + if (menu->items[menu->curr_pos].link) { + if (menu->items[menu->curr_pos].link->handle) { + menu->items[menu->curr_pos].link->handle->x1 = (handle->x1 + 20) & 0xFFFF; + menu->items[menu->curr_pos].link->handle->y1 = (handle->y1 + 20) & 0xFFFF; + result = DEMOWinMenuChild(menu->items[menu->curr_pos].link, 1); + if (menu->items[menu->curr_pos].link->flags & 1) { + exit_flag = 1; + } + } else { + DEMOWinCreateMenuWindow(menu->items[menu->curr_pos].link, (handle->x1 + 20), (handle->y1 + 20)); + result = DEMOWinMenuChild(menu->items[menu->curr_pos].link, 1); + if (menu->items[menu->curr_pos].link->flags & 1) { + exit_flag = 1; + } + DEMOWinDestroyMenuWindow(menu->items[menu->curr_pos].link); + } + VIWaitForRetrace(); + DEMOWinPadRead(pad); + } + break; + case 5: + if (menu->cb_select) { + menu->cb_select(menu, menu->curr_pos); + } + if (menu->items[menu->curr_pos].link) { + if (menu->items[menu->curr_pos].link->handle) { + menu->items[menu->curr_pos].link->handle->x1 = (handle->x1 + 20) & 0xFFFF; + menu->items[menu->curr_pos].link->handle->y1 = (handle->y1 + 20) & 0xFFFF; + result = DEMOWinMenuChild(menu->items[menu->curr_pos].link, 1); + if (menu->items[menu->curr_pos].link->flags & 1) { + exit_flag = 1; + } + } else { + DEMOWinCreateMenuWindow(menu->items[menu->curr_pos].link, (handle->x1 + 20), (handle->y1 + 20)); + result = DEMOWinMenuChild(menu->items[menu->curr_pos].link, 1); + if (menu->items[menu->curr_pos].link->flags & 1) { + exit_flag = 1; + } + DEMOWinDestroyMenuWindow(menu->items[menu->curr_pos].link); + } + VIWaitForRetrace(); + DEMOWinPadRead(pad); + } else if (menu->items[menu->curr_pos].function) { + menu->items[menu->curr_pos].function(menu, menu->curr_pos, &result); + if (menu->items[menu->curr_pos].flags & 0x10) { + exit_flag = 1; + } + VIWaitForRetrace(); + DEMOWinPadRead(pad); + } + break; + case 6: + if (menu->cb_cancel) { + menu->cb_cancel(menu, menu->curr_pos); + } + exit_flag = 1; + break; + } + + if (menu->curr_pos > (menu->display_pos + menu->num_display_items - 1)) { + menu->display_pos = (menu->curr_pos - menu->num_display_items) + 1; + } else if (menu->curr_pos < menu->display_pos) { + menu->display_pos = menu->curr_pos; + } + + if (menu->display_pos > menu->curr_pos) { + handle->cursor_line = (menu->display_pos - menu->curr_pos); + } else { + handle->cursor_line = (menu->curr_pos - menu->display_pos); + } + + DEMOBeforeRender(); + DEMOWinRefresh(); + DEMODoneRender(); + } + + DEMOWinCloseWindow(handle); + DEMOBeforeRender(); + DEMOWinRefresh(); + DEMODoneRender(); + return result; +} + +static void __DEMOWinMenu_refesh_menu(DEMOWindow* w) { + DEMOWinMenu* m; + s32 i; + s32 j; + char check; + char para_start; + char para_end; + char link; + + DEMOWinClearWindow(w); + m = w->parent; + j = m->display_pos; + + for (i = 0; i < m->num_display_items; j++, i++) { + if (m->items[j].flags & 8) { + if (strlen(m->items[j & 0xFFFF].name)) { + DEMOWinPrintfXY(w, 0, i, " %s ", m->items[j & 0xFFFF].name); + } + } else { + check = (s8)((m->items[j].flags & 4) ? 'X' : ' '); + para_start = (s8)((m->items[j].flags & 1) ? '(' : ' '); + para_end = (s8)((m->items[j].flags & 1) ? ')' : ' '); + link = (s8)((NULL != m->items[j].link) ? '>' : ' '); + DEMOWinPrintfXY(w, 0, i, "%c %c%s%c %c", check, para_start, m->items[j & 0xFFFF].name, para_end, link); + } + } +} + +void DEMOWinPadInit(DEMOWinPadInfo* p) { + u16 i; + + for (i = 0; i < 4; i++) { + p->old_button[i] = 0; + p->changed_button[i] = 0; + p->repeat_button[i] = 0; + p->repeat_ctr[i] = 0; + } +} + +void DEMOWinPadRead(DEMOWinPadInfo* p) { + PADStatus* pad; + u16 index; + u32 curr; + u32 old; + u32 repeat; + + PADRead(p->pads); + + for (index = 0; index < 4; index++) { + old = p->old_button[index]; + pad = &p->pads[index]; + + curr = ((pad->stickX > 0x40 ? 0x00040000 : 0) + | (pad->stickX < -0x40 ? 0x00080000 : 0) + | (pad->stickY > 0x40 ? 0x00010000 : 0) + | (pad->stickY < -0x40 ? 0x00020000 : 0) + | (pad->substickX > +0x40 ? 0x00400000 : 0) + | (pad->substickX < -0x40 ? 0x00800000 : 0) + | (pad->substickY > +0x40 ? 0x00100000 : 0) + | (pad->substickY < -0x40 ? 0x00200000 : 0) + | (pad->triggerLeft > +0x80 ? 0x02000000 : 0) + | (pad->triggerRight > +0x80 ? 0x01000000 : 0) + | pad->button); + + p->changed_button[index] = (curr & (old ^ curr)); + if (curr) { + if (old == curr) { + p->repeat_ctr[index]++; + } else { + p->repeat_ctr[index] = 1; + } + } else { + p->repeat_ctr[index] = 0; + } + + repeat = p->repeat_ctr[index]; + + if (repeat == 1) { + p->repeat_button[index] = curr; + } else if (repeat > __DEMOWIN_PAD_repeat_threshold) { + if (((repeat - __DEMOWIN_PAD_repeat_threshold) % __DEMOWIN_PAD_repeat_rate) == 0) { + p->repeat_button[index] = curr; + } else { + p->repeat_button[index] = 0; + } + } else { + p->repeat_button[index] = 0; + } + + p->old_button[index] = curr; + } +} + +static u16 __DEMOWinMenu_get_user_input(DEMOWinPadInfo* p) { + u16 user_input; + + DEMOWinPadRead(p); + if (p->repeat_button[0] & 0x00010008) { + user_input = 1; + } else if (p->repeat_button[0] & 0x00020004) { + user_input = 2; + } else if (p->repeat_button[0] & 0x00080001) { + user_input = 3; + } else if (p->repeat_button[0] & 0x00040002) { + user_input = 4; + } else if (p->changed_button[0] & 0x00000100) { + user_input = 5; + } else if (p->changed_button[0] & 0x00000200) { + user_input = 6; + } else { + user_input = 0; + } + + return user_input; +} + +void DEMOWinSetRepeat(u32 threshold, u32 rate) { + __DEMOWIN_PAD_repeat_rate = rate; + __DEMOWIN_PAD_repeat_threshold = threshold; +} + +void DEMOWinResetRepeat(void) { + __DEMOWIN_PAD_repeat_threshold = 15; + __DEMOWIN_PAD_repeat_rate = 2; +} + +DEMOWinListbox* DEMOWinCreateListWindow(DEMOWinListbox* list, u16 x, u16 y) { + DEMOWinListboxItem* ptr; + ASSERTMSGLINE(1846, list, "DEMOWinCreateListWindow(): List is NULL!\n"); + + ptr = list->items; + list->max_str_len = strlen(list->title); + list->num_items = 0; + + while (!(ptr->flags & 0x80000000)) { + if (strlen(ptr->name) > list->max_str_len) { + list->max_str_len = strlen(ptr->name); + } + list->num_items++; + ptr++; + } + + if (list->num_items > list->max_display_items) { + list->num_display_items = list->max_display_items; + } else { + list->num_display_items = list->num_items; + } + + list->handle = DEMOWinCreateWindow((s16)x, (s16)y, (s16)((list->max_str_len + 7) * 8 + 4 + x), (s16)((list->num_display_items + 2) * 8 + 4 + y), list->title, 0, __DEMOWinList_refresh_list); + list->handle->parent = list; + if (list->num_items) { + return list; + } + return NULL; +} + +void DEMOWinDestroyListWindow(DEMOWinListbox* list) { + if (list->handle) { + DEMOWinCloseWindow(list->handle); + DEMOWinDestroyWindow(list->handle); + list->handle = NULL; + } +} + +static void __DEMOWinList_refresh_list(DEMOWindow* w) { + DEMOWinListbox* l; + s32 i; + s32 j; + + l = w->parent; + l->curr_pos = (l->curr_pos % l->num_items); + if (l->curr_pos > (l->display_pos + l->num_display_items - 1)) { + l->display_pos = (l->curr_pos - l->num_display_items + 1); + } else if(l->curr_pos < l->display_pos) { + l->display_pos = l->curr_pos; + } + + if (l->cursor_state != 0) { + if(l->display_pos > l->curr_pos) { + w->cursor_line = (l->display_pos - l->curr_pos); + } else { + w->cursor_line = (l->curr_pos - l->display_pos); + } + } else { + w->cursor_line = -1; + } + + DEMOWinClearWindow(w); + + j = l->display_pos; + for (i = 0; i < l->num_display_items; i++) { + if (!(l->items[j].flags & 0x8)) { + DEMOWinPrintfXY(w, 0, i, " %s ", l->items[j & 0xFFFF].name); + } + j++; + } +} + +void DEMOWinListSetCursor(DEMOWinListbox* list, int x) { + list->cursor_state = x; +} + +s32 DEMOWinListScrollList(DEMOWinListbox* list, u32 dir) { + ASSERTMSGLINE(2032, list, "DEMOWinListScrollList(): NULL handle!\n"); + + switch(dir) { + case 1: + if (list->display_pos) { + list->display_pos = (u16)((list->display_pos - 1 + list->num_items) % list->num_items); + } + break; + case 2: + if (list->display_pos < (list->num_items - list->num_display_items)) { + list->display_pos = (u16)((list->display_pos + 1) % list->num_items); + } + break; + case 0: + list->display_pos = 0; + break; + default: + ASSERTMSGLINE(2057, FALSE, "DEMOWinListScrollList(): Invalid dimension!\n"); + break; + } + + if (list->curr_pos > (list->display_pos + list->num_display_items - 1)) { + list->curr_pos = (list->display_pos + list->num_display_items - 1); + } else if (list->curr_pos < list->display_pos) { + list->curr_pos = list->display_pos; + } + + return list->display_pos; +} + +s32 DEMOWinListMoveCursor(DEMOWinListbox* list, u32 dir) { + ASSERTMSGLINE(2092, list, "DEMOWinListScrollList(): NULL handle!\n"); + + switch (dir) { + case 1: + list->curr_pos = (list->curr_pos + list->num_items - 1) % list->num_items; + break; + case 2: + list->curr_pos = (list->curr_pos + 1) % list->num_items; + break; + default: + ASSERTMSGLINE(2105, FALSE, "DEMOWinListMoveCursor(): Invalid dimension!\n"); + break; + } + + return list->curr_pos; +} diff --git a/src/dolphin/demo/__demo.h b/src/dolphin/demo/__demo.h new file mode 100644 index 0000000000..47f08264e5 --- /dev/null +++ b/src/dolphin/demo/__demo.h @@ -0,0 +1,11 @@ +#ifndef _DOLPHIN_DEMO_INTERNAL_H_ +#define _DOLPHIN_DEMO_INTERNAL_H_ + +#include + +extern struct STRUCT_DEMOWIN * __first_node; +extern struct STRUCT_DEMOWIN * __last_node; +extern struct STRUCT_DEMOWIN * __curr_node; +extern struct _GXRenderModeObj * __rmp; + +#endif // _DOLPHIN_DEMO_INTERNAL_H_ diff --git a/src/dolphin/dsp/__dsp.h b/src/dolphin/dsp/__dsp.h new file mode 100644 index 0000000000..0e56af8ab8 --- /dev/null +++ b/src/dolphin/dsp/__dsp.h @@ -0,0 +1,27 @@ +#ifndef _DOLPHIN_DSP_INTERNAL_H_ +#define _DOLPHIN_DSP_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern DSPTaskInfo* __DSP_first_task; +extern DSPTaskInfo* __DSP_last_task; +extern DSPTaskInfo* __DSP_curr_task; +extern DSPTaskInfo* __DSP_tmp_task; + +__declspec(weak) void __DSPHandler(__OSInterrupt, OSContext*); +void __DSP_exec_task(DSPTaskInfo*, DSPTaskInfo*); +void __DSP_boot_task(DSPTaskInfo*); +void __DSP_insert_task(DSPTaskInfo*); +void __DSP_add_task(DSPTaskInfo* task); +void __DSP_remove_task(DSPTaskInfo* task); +void __DSP_debug_printf(const char* fmt, ...); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dolphin/dsp/dsp.c b/src/dolphin/dsp/dsp.c index 9e2845501c..d5570b1f77 100644 --- a/src/dolphin/dsp/dsp.c +++ b/src/dolphin/dsp/dsp.c @@ -1,80 +1,185 @@ -#include "dolphin/dsp.h" -#include "dolphin/dsp/dsp_debug.h" -#include "dolphin/dsp/dsp_task.h" +#include +#include +#include -/* 80450A58-80450A60 -00001 0004+04 1/1 0/0 0/0 .sdata __DSPVersion */ -static char* __DSPVersion = "<< Dolphin SDK - DSP\trelease build: Apr 5 2004 04:15:32 (0x2301) >>"; +#include "__dsp.h" + +#define BUILD_DATE "Apr 5 2004" +#if DEBUG +#define BUILD_TIME "03:56:49" +#else +#define BUILD_TIME "04:15:32" +#endif + +#ifdef DEBUG +const char* __DSPVersion = "<< Dolphin SDK - DSP\tdebug build: Apr 5 2004 03:56:49 (0x2301) >>"; +#else +const char* __DSPVersion = "<< Dolphin SDK - DSP\trelease build: Apr 5 2004 04:15:32 (0x2301) >>"; +#endif + +extern DSPTaskInfo* __DSP_rude_task; +extern int __DSP_rude_task_pending; + +static BOOL __DSP_init_flag; -/* 80451900-80451908 000E00 0004+04 1/1 0/0 0/0 .sbss __DSP_init_flag */ -static s32 __DSP_init_flag; -/* 80352430-80352440 34CD70 0010+00 0/0 5/5 0/0 .text DSPCheckMailToDSP */ u32 DSPCheckMailToDSP(void) { - return (__DSPRegs[0] >> 0xF) & 1; + return (__DSPRegs[0] & (1 << 15)) >> 15; } -/* 80352440-80352450 34CD80 0010+00 0/0 4/4 0/0 .text DSPCheckMailFromDSP */ u32 DSPCheckMailFromDSP(void) { - return (__DSPRegs[2] >> 0xF) & 1; + return (__DSPRegs[2] & (1 << 15)) >> 15; +} + +u32 DSPReadCPUToDSPMbox(void) { + return (__DSPRegs[0] << 16) | __DSPRegs[1]; } -/* 80352450-80352468 34CD90 0018+00 0/0 4/4 0/0 .text DSPReadMailFromDSP */ u32 DSPReadMailFromDSP(void) { - u16 reg1; - u16 reg2; - reg1 = __DSPRegs[2]; - reg2 = __DSPRegs[3]; - return reg1 << 16 | reg2; + return (__DSPRegs[2] << 16) | __DSPRegs[3]; } -/* 80352468-8035247C 34CDA8 0014+00 0/0 5/5 0/0 .text DSPSendMailToDSP */ void DSPSendMailToDSP(u32 mail) { __DSPRegs[0] = mail >> 16; - __DSPRegs[1] = mail; + __DSPRegs[1] = mail & 0xFFFF; } -/* 8035247C-803524BC 34CDBC 0040+00 0/0 1/1 0/0 .text DSPAssertInt */ void DSPAssertInt(void) { - u32 oldInt; - u16 reg; + BOOL old; + u16 tmp; - oldInt = OSDisableInterrupts(); - - reg = __DSPRegs[5]; - reg = (reg & ~0xA8) | 0x2; - __DSPRegs[5] = reg; - - OSRestoreInterrupts(oldInt); + old = OSDisableInterrupts(); + tmp = __DSPRegs[5]; + tmp = (tmp & ~0xA8) | 2; + __DSPRegs[5] = tmp; + OSRestoreInterrupts(old); } -/* 803524BC-80352580 34CDFC 00C4+00 0/0 2/2 0/0 .text DSPInit */ void DSPInit(void) { - u32 oldInt; - u16 reg; - __DSP_debug_printf("DSPInit(): Build Date: %s %s\n", "Apr 5 2004", "04:15:32"); + BOOL old; + u16 tmp; - if (__DSP_init_flag == 1) { + __DSP_debug_printf("DSPInit(): Build Date: %s %s\n", BUILD_DATE, BUILD_TIME); + + if (__DSP_init_flag == 1) return; - } OSRegisterVersion(__DSPVersion); - oldInt = OSDisableInterrupts(); + old = OSDisableInterrupts(); __OSSetInterruptHandler(7, __DSPHandler); - __OSUnmaskInterrupts(0x1000000); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_DSP_DSP); - reg = __DSPRegs[5]; - reg = (reg & ~0xA8) | 0x800; - __DSPRegs[5] = reg; - reg = __DSPRegs[5]; - reg = reg & ~0xAC; - __DSPRegs[5] = reg; + tmp = __DSPRegs[5]; + tmp = (tmp & ~0xA8) | 0x800; + __DSPRegs[5] = tmp; - __DSP_tmp_task = NULL; - __DSP_curr_task = NULL; - __DSP_last_task = NULL; - __DSP_first_task = NULL; + tmp = __DSPRegs[5]; + __DSPRegs[5] = tmp = tmp & ~0xAC; + + __DSP_first_task = __DSP_last_task = __DSP_curr_task = __DSP_tmp_task = NULL; __DSP_init_flag = 1; - OSRestoreInterrupts(oldInt); -} \ No newline at end of file + OSRestoreInterrupts(old); +} + +BOOL DSPCheckInit(void) { + return __DSP_init_flag; +} + +void DSPReset(void) { + BOOL old; + u16 tmp; + + old = OSDisableInterrupts(); + tmp = __DSPRegs[5]; + tmp = (tmp & ~0xA8) | 0x800 | 1; + __DSPRegs[5] = tmp; + __DSP_init_flag = 0; + OSRestoreInterrupts(old); +} + +void DSPHalt(void) { + BOOL old; + u16 tmp; + + old = OSDisableInterrupts(); + tmp = __DSPRegs[5]; + tmp = (tmp & ~0xA8) | 4; + __DSPRegs[5] = tmp; + OSRestoreInterrupts(old); +} + +void DSPUnhalt(void) { + BOOL old; + u16 tmp; + + old = OSDisableInterrupts(); + tmp = __DSPRegs[5]; + tmp = (tmp & ~0xAC); + __DSPRegs[5] = tmp; + OSRestoreInterrupts(old); +} + +u32 DSPGetDMAStatus(void) { + return (__DSPRegs[5] & (1 << 9)); +} + +DSPTaskInfo* DSPAddTask(DSPTaskInfo* task) { + BOOL old; + + ASSERTMSGLINE(556, __DSP_init_flag == 1, "DSPAddTask(): DSP driver not initialized!\n"); + + old = OSDisableInterrupts(); + + __DSP_insert_task(task); + task->state = 0; + task->flags = 1; + + OSRestoreInterrupts(old); + if (task == __DSP_first_task) + __DSP_boot_task(task); + return task; +} + +DSPTaskInfo* DSPCancelTask(DSPTaskInfo* task) { + BOOL old; + + ASSERTMSGLINE(592, __DSP_init_flag == 1, "DSPCancelTask(): DSP driver not initialized!\n"); + + old = OSDisableInterrupts(); + + task->flags |= 2; + + OSRestoreInterrupts(old); + return task; +} + +DSPTaskInfo* DSPAssertTask(DSPTaskInfo* task) { + s32 old; + + ASSERTMSGLINE(623, __DSP_init_flag == 1, "DSPAssertTask(): DSP driver not initialized!\n"); + ASSERTMSGLINE(624, task->flags & 1, "DSPAssertTask(): Specified task not in active task list!\n"); + + old = OSDisableInterrupts(); + + if (__DSP_curr_task == task) { + __DSP_rude_task = task; + __DSP_rude_task_pending = 1; + OSRestoreInterrupts(old); + return task; + } + + if (task->priority < __DSP_curr_task->priority) { + __DSP_rude_task = task; + __DSP_rude_task_pending = 1; + if (__DSP_curr_task->state == 1) { + DSPAssertInt(); + } + OSRestoreInterrupts(old); + return task; + } + + OSRestoreInterrupts(old); + return NULL; +} diff --git a/src/dolphin/dsp/dsp_debug.c b/src/dolphin/dsp/dsp_debug.c index ba31fce8f9..3cb3fb098f 100644 --- a/src/dolphin/dsp/dsp_debug.c +++ b/src/dolphin/dsp/dsp_debug.c @@ -1,4 +1,9 @@ -#include "dolphin/dsp/dsp_debug.h" +#include -/* 80352580-803525D0 34CEC0 0050+00 0/0 2/2 0/0 .text __DSP_debug_printf */ -void __DSP_debug_printf(const char* fmt, ...) {} \ No newline at end of file +#include "__dsp.h" + +void __DSP_debug_printf(const char* fmt, ...) {} + +DSPTaskInfo* __DSPGetCurrentTask(void) { + return __DSP_curr_task; +} diff --git a/src/dolphin/dsp/dsp_perf.c b/src/dolphin/dsp/dsp_perf.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/dolphin/dsp/dsp_task.c b/src/dolphin/dsp/dsp_task.c index 407333b115..be844c3e17 100644 --- a/src/dolphin/dsp/dsp_task.c +++ b/src/dolphin/dsp/dsp_task.c @@ -1,182 +1,327 @@ -#include "dolphin/dsp/dsp_task.h" -#include "dolphin/dsp/dsp_debug.h" +#include + +#include +#include + +#include "__dsp.h" + +static u32 t0, t1, t2; // unused -/* 80451914-80451918 000E14 0004+00 2/2 2/2 0/0 .sbss __DSP_curr_task */ DSPTaskInfo* __DSP_curr_task; - -/* 80451910-80451914 000E10 0004+00 2/2 2/2 0/0 .sbss __DSP_first_task */ DSPTaskInfo* __DSP_first_task; - -/* 8045190C-80451910 000E0C 0004+00 2/2 1/1 0/0 .sbss __DSP_last_task */ DSPTaskInfo* __DSP_last_task; - -/* 80451908-8045190C 000E08 0004+00 0/0 1/1 0/0 .sbss __DSP_tmp_task */ DSPTaskInfo* __DSP_tmp_task; +DSPTaskInfo* __DSP_rude_task; +int __DSP_rude_task_pending; -void __DSP_exec_task(); -void __DSP_boot_task(); -void __DSP_insert_task(); -void __DSP_remove_task(); +void __DSPHandler(__OSInterrupt intr, OSContext* context) { + u8 unused[4]; + OSContext exceptionContext; + u16 tmp; + u32 mail; -/* 803525D0-80352770 34CF10 01A0+00 0/0 1/1 0/0 .text __DSP_exec_task */ -void __DSP_exec_task(DSPTaskInfo* curr, DSPTaskInfo* next) { - if (curr) { - DSPSendMailToDSP((u32)(curr->dram_mmem_addr)); - while (DSPCheckMailToDSP()) - ; - DSPSendMailToDSP((u32)(curr->dram_length)); - while (DSPCheckMailToDSP()) - ; - DSPSendMailToDSP((u32)(curr->dram_addr)); - while (DSPCheckMailToDSP()) - ; - } else { - DSPSendMailToDSP((u32)(0)); - while (DSPCheckMailToDSP()) - ; - DSPSendMailToDSP((u32)(0)); - while (DSPCheckMailToDSP()) - ; - DSPSendMailToDSP((u32)(0)); - while (DSPCheckMailToDSP()) - ; - } + tmp = __DSPRegs[5]; + tmp = (tmp & ~0x28) | 0x80; + __DSPRegs[5] = tmp; - DSPSendMailToDSP((u32)(next->iram_mmem_addr)); - while (DSPCheckMailToDSP()) - ; - DSPSendMailToDSP((u32)(next->iram_length)); - while (DSPCheckMailToDSP()) - ; - DSPSendMailToDSP((u32)(next->iram_addr)); - while (DSPCheckMailToDSP()) - ; - - if (DSP_TASK_STATE_INIT == next->state) { - DSPSendMailToDSP((u32)(next->dsp_init_vector)); - while (DSPCheckMailToDSP()) - ; - DSPSendMailToDSP((u32)(0)); - while (DSPCheckMailToDSP()) - ; - DSPSendMailToDSP((u32)(0)); - while (DSPCheckMailToDSP()) - ; - DSPSendMailToDSP((u32)(0)); - while (DSPCheckMailToDSP()) - ; - } else { - DSPSendMailToDSP((u32)(next->dsp_resume_vector)); - while (DSPCheckMailToDSP()) - ; - DSPSendMailToDSP((u32)(next->dram_mmem_addr)); - while (DSPCheckMailToDSP()) - ; - - DSPSendMailToDSP((u32)(next->dram_length)); - while (DSPCheckMailToDSP()) - ; - - DSPSendMailToDSP((u32)(next->dram_addr)); - while (DSPCheckMailToDSP()) - ; - } -} - -#define MSG_BASE 0x80F30000 - -/* 80352770-803528FC 34D0B0 018C+00 0/0 1/1 0/0 .text __DSP_boot_task */ -void __DSP_boot_task(DSPTaskInfo* task) { - volatile u32 mail; - - while (!DSPCheckMailFromDSP()) + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + ASSERTMSGLINE(143, __DSP_curr_task != NULL, "__DSPHandler(): No current task! Someone set us up the bomb!\n"); + + while (DSPCheckMailFromDSP() == 0) ; mail = DSPReadMailFromDSP(); + if ((__DSP_curr_task->flags & (1<<(31-0x1E))) && (mail + 0x232F0000) == 2) + mail = 0xDCD10003; - DSPSendMailToDSP(MSG_BASE | 0xA001); - while (DSPCheckMailToDSP()) { - } - DSPSendMailToDSP((u32)(task->iram_mmem_addr)); - while (DSPCheckMailToDSP()) { + switch (mail) { + case 0xDCD10000: + __DSP_curr_task->state = 1; + if (__DSP_curr_task->init_cb != NULL) + __DSP_curr_task->init_cb(__DSP_curr_task); + break; + case 0xDCD10001: + __DSP_curr_task->state = 1; + if (__DSP_curr_task->res_cb != NULL) + __DSP_curr_task->res_cb(__DSP_curr_task); + break; + case 0xDCD10002: + if (__DSP_rude_task_pending) { + if (__DSP_curr_task == __DSP_rude_task) { + DSPSendMailToDSP(0xCDD10003); + while (DSPCheckMailToDSP() != 0) + ; + __DSP_rude_task = NULL; + __DSP_rude_task_pending = 0; + + if (__DSP_curr_task->res_cb != NULL) + __DSP_curr_task->res_cb(__DSP_curr_task); + } else { + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP() != 0) + ; + __DSP_exec_task(__DSP_curr_task, __DSP_rude_task); + __DSP_curr_task->state = 2; + __DSP_curr_task = __DSP_rude_task; + __DSP_rude_task = NULL; + __DSP_rude_task_pending = 0; + } + } else { + if (__DSP_curr_task->next == NULL) { + if (__DSP_curr_task == __DSP_first_task) { + DSPSendMailToDSP(0xCDD10003); + while (DSPCheckMailToDSP() != 0) + ; + if (__DSP_curr_task->res_cb != NULL) + __DSP_curr_task->res_cb(__DSP_curr_task); + } else { + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP() != 0) + ; + __DSP_exec_task(__DSP_curr_task, __DSP_first_task); + __DSP_curr_task->state = 2; + __DSP_curr_task = __DSP_first_task; + } + } else { + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP() != 0) + ; + __DSP_exec_task(__DSP_curr_task, __DSP_curr_task->next); + __DSP_curr_task->state = 2; + __DSP_curr_task = __DSP_curr_task->next; + } + } + break; + case 0xDCD10003: + if (__DSP_rude_task_pending) { + if (__DSP_curr_task->done_cb != NULL) + __DSP_curr_task->done_cb(__DSP_curr_task); + + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP() != 0) + ; + __DSP_exec_task(NULL, __DSP_rude_task); + __DSP_remove_task(__DSP_curr_task); + __DSP_curr_task = __DSP_rude_task; + __DSP_rude_task = NULL; + __DSP_rude_task_pending = 0; + } else { + if (__DSP_curr_task->next == NULL) { + if (__DSP_curr_task == __DSP_first_task) { + if (__DSP_curr_task->done_cb != NULL) + __DSP_curr_task->done_cb(__DSP_curr_task); + + DSPSendMailToDSP(0xCDD10002); + while (DSPCheckMailToDSP() != 0) + ; + __DSP_curr_task->state = 3; + __DSP_remove_task(__DSP_curr_task); + } else { + if (__DSP_curr_task->done_cb != NULL) + __DSP_curr_task->done_cb(__DSP_curr_task); + + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP() != 0) + ; + __DSP_curr_task->state = 3; + __DSP_exec_task(NULL, __DSP_first_task); + __DSP_curr_task = __DSP_first_task; + __DSP_remove_task(__DSP_last_task); + } + } else { + if (__DSP_curr_task->done_cb != NULL) + __DSP_curr_task->done_cb(__DSP_curr_task); + + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP() != 0) + ; + __DSP_curr_task->state = 3; + __DSP_exec_task(NULL, __DSP_curr_task->next); + __DSP_curr_task = __DSP_curr_task->next; + __DSP_remove_task(__DSP_curr_task->prev); + } + } + break; + case 0xDCD10004: + if (__DSP_curr_task->req_cb != NULL) + __DSP_curr_task->req_cb(__DSP_curr_task); + break; + default: + ASSERTMSGLINEV(519, 0, "__DSPHandler(): Unknown msg from DSP 0x%08X - task sync failed!\n", mail); } - DSPSendMailToDSP(MSG_BASE | 0xC002); - while (DSPCheckMailToDSP()) { - } - DSPSendMailToDSP((u32)(task->iram_addr & 0xffff)); - while (DSPCheckMailToDSP()) { - } - - DSPSendMailToDSP(MSG_BASE | 0xA002); - while (DSPCheckMailToDSP()) { - } - DSPSendMailToDSP(task->iram_length); - while (DSPCheckMailToDSP()) { - } - - DSPSendMailToDSP(MSG_BASE | 0xB002); - while (DSPCheckMailToDSP()) { - } - DSPSendMailToDSP(0x00000000); - while (DSPCheckMailToDSP()) { - } - - DSPSendMailToDSP(MSG_BASE | 0xD001); - while (DSPCheckMailToDSP()) { - } - DSPSendMailToDSP((u32)(0xffff & task->dsp_init_vector)); - while (DSPCheckMailToDSP()) { - } - - __DSP_debug_printf("DSP is booting task: 0x%08X\n", task); - __DSP_debug_printf("__DSP_boot_task() : IRAM MMEM ADDR: 0x%08X\n", - (u32)(task->iram_mmem_addr)); - __DSP_debug_printf("__DSP_boot_task() : IRAM DSP ADDR : 0x%08X\n", (u32)(task->iram_addr)); - __DSP_debug_printf("__DSP_boot_task() : IRAM LENGTH : 0x%08X\n", (u32)(task->iram_length)); - __DSP_debug_printf("__DSP_boot_task() : DRAM MMEM ADDR: 0x%08X\n", (u32)(task->dram_length)); - __DSP_debug_printf("__DSP_boot_task() : Start Vector : 0x%08X\n", - (u32)(task->dsp_init_vector)); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +void __DSP_exec_task(DSPTaskInfo* curr, DSPTaskInfo* next) { + ASSERTMSGLINE(552, next != NULL, "__DSP_exec_task(): NULL task. It is to weep.\n"); + + if (curr != NULL) { + DSPSendMailToDSP((u32)curr->dram_mmem_addr); + while (DSPCheckMailToDSP() != 0) + ; + DSPSendMailToDSP(curr->dram_length); + while (DSPCheckMailToDSP() != 0) + ; + DSPSendMailToDSP(curr->dram_addr); + while (DSPCheckMailToDSP() != 0) + ; + } else { + DSPSendMailToDSP(0); + while (DSPCheckMailToDSP() != 0) + ; + DSPSendMailToDSP(0); + while (DSPCheckMailToDSP() != 0) + ; + DSPSendMailToDSP(0); + while (DSPCheckMailToDSP() != 0) + ; + } + + DSPSendMailToDSP((u32)next->iram_mmem_addr); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(next->iram_length); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(next->iram_addr); + while (DSPCheckMailToDSP() != 0) + ; + + if (next->state == 0) { + DSPSendMailToDSP(next->dsp_init_vector); + while (DSPCheckMailToDSP() != 0) + ; + DSPSendMailToDSP(0); + while (DSPCheckMailToDSP() != 0) + ; + DSPSendMailToDSP(0); + while (DSPCheckMailToDSP() != 0) + ; + DSPSendMailToDSP(0); + while (DSPCheckMailToDSP() != 0) + ; + } else { + DSPSendMailToDSP(next->dsp_resume_vector); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP((u32)next->dram_mmem_addr); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(next->dram_length); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(next->dram_addr); + while (DSPCheckMailToDSP() != 0) + ; + } +} + +void __DSP_boot_task(DSPTaskInfo* task) { + volatile u32 mail; + + ASSERTMSGLINE(634, task != NULL, "__DSP_boot_task(): NULL task!\n"); + while (DSPCheckMailFromDSP() == 0) + ; + + mail = DSPReadMailFromDSP(); + ASSERTMSGLINEV(640, mail == 0x8071FEED, "__DSP_boot_task(): Failed to sync DSP on boot! (0x%08X)\n", mail); + + DSPSendMailToDSP(0x80F3A001); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP((u32)task->iram_mmem_addr); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(0x80F3C002); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(task->iram_addr & 0xFFFF); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(0x80F3A002); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(task->iram_length); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(0x80F3B002); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(0); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(0x80F3D001); + while (DSPCheckMailToDSP() != 0) + ; + + DSPSendMailToDSP(task->dsp_init_vector); + while (DSPCheckMailToDSP() != 0) + ; + + __DSP_debug_printf("DSP is booting task: 0x%08X\n", (u32)task); + __DSP_debug_printf("__DSP_boot_task() : IRAM MMEM ADDR: 0x%08X\n", (u32)task->iram_mmem_addr); + __DSP_debug_printf("__DSP_boot_task() : IRAM DSP ADDR : 0x%08X\n", task->iram_addr); + __DSP_debug_printf("__DSP_boot_task() : IRAM LENGTH : 0x%08X\n", task->iram_length); + __DSP_debug_printf("__DSP_boot_task() : DRAM MMEM ADDR: 0x%08X\n", task->dram_length); + __DSP_debug_printf("__DSP_boot_task() : Start Vector : 0x%08X\n", task->dsp_init_vector); } -/* 803528FC-8035299C 34D23C 00A0+00 0/0 1/1 0/0 .text __DSP_insert_task */ void __DSP_insert_task(DSPTaskInfo* task) { DSPTaskInfo* temp; if (__DSP_first_task == NULL) { - __DSP_first_task = __DSP_last_task = __DSP_curr_task = task; + __DSP_curr_task = task; + __DSP_first_task = __DSP_last_task = task; task->next = task->prev = NULL; - } else { - temp = __DSP_first_task; + return; + } - while (temp) { - if (task->priority < temp->priority) { - task->prev = temp->prev; - temp->prev = task; - task->next = temp; - if (task->prev == NULL) { - __DSP_first_task = task; - } else { - (task->prev)->next = task; - } - break; - } - temp = temp->next; + temp = __DSP_first_task; + while (temp != NULL) { + if (task->priority < temp->priority) { + task->prev = temp->prev; + temp->prev = task; + task->next = temp; + if (task->prev == NULL) + __DSP_first_task = task; + else + task->prev->next = task; + break; } + temp = temp->next; + } - if (temp == NULL) { - __DSP_last_task->next = task; - task->next = NULL; - task->prev = __DSP_last_task; - __DSP_last_task = task; - } + if (temp == NULL) { + __DSP_last_task->next = task; + task->next = NULL; + task->prev = __DSP_last_task; + __DSP_last_task = task; } } -// Unused, but close enough. void __DSP_add_task(DSPTaskInfo* task) { + ASSERTMSGLINE(771, task != NULL, "__DSP_add_task(): Why are you adding a NULL task?\n"); + if (__DSP_last_task == NULL) { - __DSP_first_task = __DSP_last_task = __DSP_curr_task = task; + __DSP_curr_task = task; + __DSP_last_task = task; + __DSP_first_task = task; task->next = task->prev = NULL; } else { __DSP_last_task->next = task; @@ -184,29 +329,34 @@ void __DSP_add_task(DSPTaskInfo* task) { task->prev = __DSP_last_task; __DSP_last_task = task; } - __DSP_debug_printf("__DSP_add_task() : Added task : 0x%08X\n", (u32)(task->next)); + + task->state = 0; + __DSP_debug_printf("__DSP_add_task() : Added task : 0x%08X\n", (u32)task); } -/* 8035299C-80352A30 34D2DC 0094+00 0/0 1/1 0/0 .text __DSP_remove_task */ void __DSP_remove_task(DSPTaskInfo* task) { - task->flags = DSP_TASK_FLAG_CLEARALL; - task->state = DSP_TASK_STATE_DONE; + ASSERTMSGLINE(813, task != NULL, "__DSP_remove_task(): NULL task! Why? WHY?!?!\n"); + task->flags = 0; + task->state = 3; if (__DSP_first_task == task) { - if (task->next) { - __DSP_first_task = (task->next); + if (task->next != NULL) { + __DSP_first_task = task->next; task->next->prev = NULL; - } else { - __DSP_first_task = __DSP_last_task = __DSP_curr_task = NULL; } - } else if (__DSP_last_task == task) { - __DSP_last_task = (task->prev); + else + __DSP_first_task = __DSP_last_task = __DSP_curr_task = NULL; + return; + } + + if (__DSP_last_task == task) { + __DSP_last_task = task->prev; task->prev->next = NULL; __DSP_curr_task = __DSP_first_task; - - } else { - __DSP_curr_task = task->next; - task->prev->next = task->next; - task->next->prev = task->prev; + return; } -} \ No newline at end of file + + __DSP_curr_task = task->next; + task->prev->next = task->next; + task->next->prev = task->prev; +} diff --git a/src/dolphin/dtk/dtk.c b/src/dolphin/dtk/dtk.c new file mode 100644 index 0000000000..c1bfd0520f --- /dev/null +++ b/src/dolphin/dtk/dtk.c @@ -0,0 +1,483 @@ +#include +#include +#include +#include + +static DTKTrack* __DTKCurrentTrack; +static DTKTrack* __DTKPlayListHead; +static DTKTrack* __DTKPlayListTail; +static volatile u32 __DTKState; +static volatile u32 __DTKTempState; +static volatile u32 __DTKRepeatMode; +static volatile u32 __DTKPosition; +static volatile u32 __DTKInterruptFrequency; +static volatile u8 __DTKVolumeL; +static volatile u8 __DTKVolumeR; +static volatile u32 __DTKShutdownFlag; +static volatile u32 __DTKTrackEnded; +static DTKFlushCallback __DTKFlushCallback; +static int __busy_for_ais_address; + +static DVDCommandBlock __block_for_run_callback; +static DVDCommandBlock __block_for_prep_callback; +static DVDCommandBlock __block_for_stream_status; +static DVDCommandBlock __block_for_ais_isr; +static DVDCommandBlock __block_for_flushtracks; +static DVDCommandBlock __block_for_repeatmode; +static DVDCommandBlock __block_for_set_state; +static DVDCommandBlock __block_for_next_track; +static DVDCommandBlock __block_for_prev_track; + +static void __DTKStartAi(void) { + AISetStreamVolLeft(__DTKVolumeL); + AISetStreamVolRight(__DTKVolumeR); + AIResetStreamSampleCount(); + AISetStreamTrigger(__DTKInterruptFrequency); + AISetStreamPlayState(1); +} + +static void __DTKStopAi(void) { + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + AISetStreamPlayState(0); +} + +static void __DTKCheckUserCallback(DTKTrack* track, u32 event) { + ASSERTLINE(84, track); + if (track && track->callback && (track->eventMask & event)) { + track->callback(track->eventMask & event); + } +} + +static void __DTKForward(void) { + BOOL old = OSDisableInterrupts(); + if (__DTKCurrentTrack && __DTKCurrentTrack->next) { + __DTKCurrentTrack = __DTKCurrentTrack->next; + } + OSRestoreInterrupts(old); +} + +static void __DTKBackward(void) { + BOOL old = OSDisableInterrupts(); + if (__DTKCurrentTrack && __DTKCurrentTrack->prev) { + __DTKCurrentTrack = __DTKCurrentTrack->prev; + } + OSRestoreInterrupts(old); +} + +static void __DTKCallbackForStreamStatus(s32 result, DVDCommandBlock* block) { + if ((result & 0xFF) == 0) { + __DTKTrackEnded = 1; + __DTKPosition = 0; + } +} + +static void __DTKCallbackForRun(s32 result, DVDFileInfo* fileInfo) { + __DTKStartAi(); + DVDStopStreamAtEndAsync(&__block_for_run_callback, 0); + __DTKState = DTK_STATE_RUN; + __DTKCheckUserCallback(__DTKCurrentTrack, 1); +} + +static void __DTKCallbackForPreparePaused(s32 result, DVDFileInfo* fileInfo) { + __DTKStopAi(); + DVDStopStreamAtEndAsync(&__block_for_prep_callback, 0); + __DTKState = DTK_STATE_PAUSE; + __DTKCheckUserCallback(__DTKCurrentTrack, 32); +} + +static void __DTKPrepareCurrentTrack(void) { + DVDPrepareStreamAsync(&__DTKCurrentTrack->dvdFileInfo, 0, 0, __DTKCallbackForRun); +} + +static void __DTKPrepareCurrentTrackPaused(void) { + DVDPrepareStreamAsync(&__DTKCurrentTrack->dvdFileInfo, 0, 0, __DTKCallbackForPreparePaused); +} + +static void __DTKCallbackForPlaylist(s32 result, DVDCommandBlock* block) { + __DTKPosition = result; + __busy_for_ais_address = 0; + + if (__DTKTrackEnded) { + __DTKTrackEnded = 0; + __DTKCheckUserCallback(__DTKCurrentTrack, 16); + __DTKState = DTK_STATE_BUSY; + + switch (__DTKRepeatMode) { + case DTK_MODE_NOREPEAT: + if (__DTKCurrentTrack) { + if (__DTKCurrentTrack->next) { + __DTKCurrentTrack = __DTKCurrentTrack->next; + __DTKStopAi(); + __DTKPrepareCurrentTrack(); + } else { + __DTKCurrentTrack = __DTKPlayListHead; + __DTKStopAi(); + __DTKState = DTK_STATE_STOP; + } + } + break; + case DTK_MODE_ALLREPEAT: + if (__DTKCurrentTrack) { + if (__DTKCurrentTrack->next) { + __DTKCurrentTrack = __DTKCurrentTrack->next; + __DTKStopAi(); + __DTKPrepareCurrentTrack(); + } else { + __DTKCurrentTrack = __DTKPlayListHead; + __DTKStopAi(); + __DTKPrepareCurrentTrack(); + } + } + break; + case DTK_MODE_REPEAT1: + if (__DTKCurrentTrack) { + __DTKStopAi(); + __DTKPrepareCurrentTrack(); + } + break; + } + } else { + DVDGetStreamErrorStatusAsync(&__block_for_stream_status, __DTKCallbackForStreamStatus); + } +} + +static void __DTKCallbackForAIInterrupt(u32 count) { + AISetStreamTrigger(count + __DTKInterruptFrequency); + if (__DTKCurrentTrack && !__busy_for_ais_address) { + __busy_for_ais_address = 1; + DVDGetStreamPlayAddrAsync(&__block_for_ais_isr, __DTKCallbackForPlaylist); + } +} + +static void __DTKCallbackForFlush(s32 result, DVDCommandBlock* block) { + DTKTrack* track; + + AISetStreamPlayState(0); + track = __DTKPlayListHead; + while (track) { + DVDClose(&track->dvdFileInfo); + track = track->next; + } + + __DTKPlayListHead = NULL; + __DTKPlayListTail = NULL; + __DTKCurrentTrack = NULL; + __DTKState = DTK_STATE_STOP; + + if (__DTKFlushCallback) { + __DTKFlushCallback(); + __DTKFlushCallback = NULL; + } + + __DTKState = DTK_STATE_STOP; + __DTKShutdownFlag = 0; +} + +static void __DTKCallbackForStop(s32 result, DVDCommandBlock* block) { + __DTKCheckUserCallback(__DTKCurrentTrack, 2); + __DTKState = DTK_STATE_STOP; +} + +static void __DTKCallbackForNextTrack(s32 result, DVDCommandBlock* block) { + AISetStreamPlayState(0); + __DTKForward(); + __DTKState = DTK_STATE_STOP; + DTKSetState(__DTKTempState); +} + +static void __DTKCallbackForPrevTrack(s32 result, DVDCommandBlock* block) { + AISetStreamPlayState(0); + __DTKBackward(); + __DTKState = DTK_STATE_STOP; + DTKSetState(__DTKTempState); +} + +void DTKInit(void) { + __DTKCurrentTrack = NULL; + __DTKPlayListHead = NULL; + __DTKPlayListTail = NULL; + __DTKState = DTK_STATE_STOP; + __DTKRepeatMode = DTK_MODE_NOREPEAT; + __DTKPosition = 0; + __DTKInterruptFrequency = 48000; + __DTKVolumeL = 255; + __DTKVolumeR = 255; + + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + AIRegisterStreamCallback(__DTKCallbackForAIInterrupt); + AIResetStreamSampleCount(); + AISetStreamPlayState(0); +} + +void DTKShutdown(void) { + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + AIRegisterStreamCallback(NULL); + AIResetStreamSampleCount(); + AISetStreamPlayState(0); + + __DTKShutdownFlag = 1; + DTKFlushTracks(NULL); + __DTKState = DTK_STATE_STOP; + + while (__DTKShutdownFlag) {} +} + +u32 DTKQueueTrack(char* fileName, DTKTrack* track, u32 eventMask, DTKCallback callback) { + u32 startTrack; + BOOL old; + + startTrack = 0; + if (!DVDOpen(fileName, &track->dvdFileInfo)) { + return 1; + } + + old = OSDisableInterrupts(); + track->fileName = fileName; + track->eventMask = eventMask; + track->callback = callback; + + if (__DTKPlayListHead == NULL) { + __DTKPlayListHead = track; + __DTKPlayListTail = track; + track->prev = NULL; + track->next = NULL; + if (__DTKState == DTK_STATE_RUN) { + startTrack = 1; + } + } else { + __DTKPlayListTail->next = track; + track->prev = __DTKPlayListTail; + __DTKPlayListTail = track; + track->next = NULL; + } + + if (__DTKCurrentTrack == NULL) { + __DTKCurrentTrack = track; + } + + OSRestoreInterrupts(old); + __DTKCheckUserCallback(track, 8); + + if (startTrack != 0) { + __DTKState = DTK_STATE_BUSY; + __DTKPrepareCurrentTrack(); + } + + return 0; +} + +u32 DTKRemoveTrack(DTKTrack* track) { + BOOL old; + + if (track == __DTKCurrentTrack) { + return 2; + } + + old = OSDisableInterrupts(); + DVDClose(&track->dvdFileInfo); + + if (track == __DTKPlayListHead && track == __DTKPlayListTail) { + __DTKPlayListHead = NULL; + __DTKPlayListTail = NULL; + OSRestoreInterrupts(old); + return 0; + } + + if (track == __DTKPlayListHead) { + __DTKPlayListHead = track->next; + __DTKPlayListHead->prev = NULL; + if (__DTKRepeatMode == DTK_MODE_ALLREPEAT) { + __DTKPlayListTail->next = __DTKPlayListHead; + } + OSRestoreInterrupts(old); + return 0; + } + + if (track == __DTKPlayListTail) { + __DTKPlayListTail = track->prev; + __DTKPlayListTail->next = NULL; + if (__DTKRepeatMode == DTK_MODE_ALLREPEAT) { + __DTKPlayListTail->next = __DTKPlayListHead; + } + OSRestoreInterrupts(old); + return 0; + } + + track->prev->next = track->next; + track->next->prev = track->prev; + OSRestoreInterrupts(old); + return 0; +} + +int DTKFlushTracks(DTKFlushCallback callback) { + u32 temp; + + if (__DTKState == DTK_STATE_BUSY) { + return 0; + } + + temp = __DTKState; + __DTKState = DTK_STATE_BUSY; + __DTKFlushCallback = callback; + if (temp == DTK_STATE_RUN) { + DVDCancelStreamAsync(&__block_for_flushtracks, __DTKCallbackForFlush); + } else { + __DTKCallbackForFlush(0, 0); + } + return 1; +} + +void DTKSetSampleRate(u32 samplerate) { + // obsolete +} + +void DTKSetInterruptFrequency(u32 samples) { + __DTKInterruptFrequency = samples; + AIResetStreamSampleCount(); + AISetStreamTrigger(__DTKInterruptFrequency); +} + +void DTKSetRepeatMode(u32 repeat) { + __DTKRepeatMode = repeat; +} + +int DTKSetState(u32 state) { + if (__DTKState == state) { + return 1; + } + + if (__DTKState == DTK_STATE_BUSY) { + return 0; + } + + switch (state) { + case DTK_STATE_STOP: + if (__DTKCurrentTrack) { + __DTKState = DTK_STATE_BUSY; + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + AISetStreamPlayState(0); + DVDCancelStreamAsync(&__block_for_set_state, __DTKCallbackForStop); + } + break; + case DTK_STATE_RUN: + if (__DTKState == DTK_STATE_PAUSE) { + __DTKStartAi(); + __DTKState = DTK_STATE_RUN; + if (__DTKCurrentTrack) { + __DTKCheckUserCallback(__DTKCurrentTrack, 1); + } + } else if (__DTKCurrentTrack) { + __DTKState = DTK_STATE_BUSY; + __DTKPrepareCurrentTrack(); + } else { + __DTKState = DTK_STATE_RUN; + } + __DTKTrackEnded = 0; + break; + case DTK_STATE_PREPARE: + if (__DTKState == DTK_STATE_STOP) { + if (__DTKCurrentTrack) { + __DTKState = DTK_STATE_BUSY; + __DTKPrepareCurrentTrackPaused(); + } + __DTKTrackEnded = 0; + } + break; + case DTK_STATE_PAUSE: + AISetStreamPlayState(0); + if (__DTKState == DTK_STATE_RUN) { + __DTKState = DTK_STATE_PAUSE; + } + __DTKCheckUserCallback(__DTKCurrentTrack, 4); + break; + } + + return 1; +} + +int DTKNextTrack(void) { + if (__DTKState == DTK_STATE_BUSY) { + return 0; + } + + if (__DTKCurrentTrack) { + __DTKTempState = __DTKState; + __DTKState = DTK_STATE_BUSY; + if (__DTKTempState == DTK_STATE_RUN) { + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + DVDCancelStreamAsync(&__block_for_next_track, __DTKCallbackForNextTrack); + } else { + __DTKForward(); + __DTKState = __DTKTempState; + } + + return 1; + } + + return 0; +} + +int DTKPrevTrack(void) { + if (__DTKState == DTK_STATE_BUSY) { + return 0; + } + + if (__DTKCurrentTrack) { + __DTKTempState = __DTKState; + __DTKState = DTK_STATE_BUSY; + if (__DTKTempState == DTK_STATE_RUN) { + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + DVDCancelStreamAsync(&__block_for_prev_track, __DTKCallbackForPrevTrack); + } else { + __DTKBackward(); + __DTKState = __DTKTempState; + } + + return 1; + } + + return 0; +} + +u32 DTKGetSampleRate(void) { + return 1; // obsolete +} + +u32 DTKGetRepeatMode(void) { + return __DTKRepeatMode; +} + +u32 DTKGetState(void) { + return __DTKState; +} + +u32 DTKGetPosition(void) { + return __DTKPosition; +} + +u32 DTKGetInterruptFrequency(void) { + return __DTKInterruptFrequency; +} + +DTKTrack* DTKGetCurrentTrack(void) { + return __DTKCurrentTrack; +} + +void DTKSetVolume(u8 left, u8 right) { + __DTKVolumeL = left; + __DTKVolumeR = right; + if (__DTKState == DTK_STATE_RUN) { + AISetStreamVolLeft(left); + AISetStreamVolRight(right); + } +} + +u16 DTKGetVolume(void) { + return (__DTKVolumeL << 8) | __DTKVolumeR; +} diff --git a/src/dolphin/dvd/__dvd.h b/src/dolphin/dvd/__dvd.h new file mode 100644 index 0000000000..197c13ede7 --- /dev/null +++ b/src/dolphin/dvd/__dvd.h @@ -0,0 +1,53 @@ +#ifndef _DOLPHIN_DVD_INTERNAL_H_ +#define _DOLPHIN_DVD_INTERNAL_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// DVD +DVDCommandChecker __DVDSetOptionalCommandChecker(DVDCommandChecker func); +void __DVDSetImmCommand(u32 command); +void __DVDSetDmaCommand(u32 command); +void* __DVDGetIssueCommandAddr(void); +void __DVDAudioBufferConfig(DVDCommandBlock* block, u32 enable, u32 size, DVDCBCallback callback); +void __DVDPrepareResetAsync(DVDCBCallback callback); +int __DVDTestAlarm(const OSAlarm* alarm); + +// DVD ERROR +void __DVDStoreErrorCode(u32 error); + +// DVD FATAL +void __DVDPrintFatalMessage(void); + +// DVD FS +extern OSThreadQueue __DVDThreadQueue; +extern u32 __DVDLongFileNameFlag; + +void __DVDFSInit(void); + +// DVD LOW +void __DVDInitWA(void); +void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext* context); +void __DVDLowSetWAType(u32 type, s32 seekLoc); +int __DVDLowTestAlarm(const OSAlarm* alarm); + +// DVD QUEUE +void __DVDClearWaitingQueue(void); +int __DVDPushWaitingQueue(s32 prio, DVDCommandBlock* block); +DVDCommandBlock* __DVDPopWaitingQueue(void); +int __DVDCheckWaitingQueue(void); +int __DVDDequeueWaitingQueue(DVDCommandBlock* block); +int __DVDIsBlockInWaitingQueue(DVDCommandBlock* block); + +// FST LOAD +void __fstLoad(void); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_DVD_INTERNAL_H_ diff --git a/src/dolphin/dvd/dvd.c b/src/dolphin/dvd/dvd.c index 72063b12bd..3b7e9704a3 100644 --- a/src/dolphin/dvd/dvd.c +++ b/src/dolphin/dvd/dvd.c @@ -1,199 +1,146 @@ -#include "dolphin/dvd.h" -#include "dolphin/dvd/dvdlow.h" -#include "dolphin/os.h" +#include +#include +#include -/* 804509E8-804509EC -00001 0004+00 1/1 0/0 0/0 .sdata __DVDVersion */ -static char* __DVDVersion = "<< Dolphin SDK - DVD\trelease build: Apr 5 2004 04:14:51 (0x2301) >>"; +#include "os/__os.h" +#include "__dvd.h" -static void defaultOptionalCommandChecker(); +// externs +extern void __DVDPrintFatalMessage(); +extern int DVDCompareDiskID(const struct DVDDiskID * id1 /* r29 */, const struct DVDDiskID * id2 /* r30 */); +extern int __DVDLowTestAlarm(const OSAlarm * alarm /* r3 */); + +#ifdef DEBUG +const char* __DVDVersion = "<< Dolphin SDK - DVD\tdebug build: Apr 5 2004 03:56:07 (0x2301) >>"; +#else +const char* __DVDVersion = "<< Dolphin SDK - DVD\trelease build: Apr 5 2004 04:14:51 (0x2301) >>"; +#endif + +static BOOL autoInvalidation = TRUE; + +static void defaultOptionalCommandChecker(DVDCommandBlock*, DVDCommandCheckerCallback); +static DVDCommandChecker checkOptionalCommand = defaultOptionalCommandChecker; + +static DVDBB2 BB2; +static DVDDiskID CurrDiskID; +static DVDCommandBlock DummyCommandBlock; +static OSAlarm ResetAlarm; + +static DVDCommandBlock* executing; +static DVDDiskID* IDShouldBe; +static OSBootInfo* bootInfo; +static volatile int PauseFlag; +static volatile int PausingFlag; +static int AutoFinishing; +static BOOL FatalErrorFlag; +static volatile u32 CurrCommand; +static volatile u32 Canceling; +static void (*CancelCallback)(s32, DVDCommandBlock*); +static volatile u32 ResumeFromHere; +static volatile u32 CancelLastError; +static u32 LastError; +static volatile s32 NumInternalRetry; +static int ResetRequired; +static int CancelAllSyncComplete; +static volatile u32 ResetCount; +static BOOL FirstTimeInBootrom; +static u32 MotorState; +static int DVDInitialized; +void (*LastState)(DVDCommandBlock*); + +// prototypes static void stateReadingFST(); -static void cbForStateReadingFST(); -static void cbForStateError(); +static void cbForStateReadingFST(u32 intType); +static void cbForStateError(u32 intType); +static void stateError(u32 error); static void stateTimeout(); static void stateGettingError(); static u32 CategorizeError(u32 error); -static void cbForStateGettingError(); -static void cbForUnrecoveredError(); -static void cbForUnrecoveredErrorRetry(); +static BOOL CheckCancel(u32 resume); +static void cbForStateGettingError(u32 intType); +static void cbForUnrecoveredError(u32 intType); +static void cbForUnrecoveredErrorRetry(u32 intType); static void stateGoToRetry(); -static void cbForStateGoToRetry(); +static void cbForStateGoToRetry(u32 intType); static void stateCheckID(); static void stateCheckID3(); static void stateCheckID2a(); -static void cbForStateCheckID2a(); static void stateCheckID2(); -static void cbForStateCheckID1(); -static void cbForStateCheckID2(); -static void cbForStateCheckID3(); -static void AlarmHandler(); +static void cbForStateCheckID1(u32 intType); +static void cbForStateCheckID2(u32 intType); +static void cbForStateCheckID3(u32 intType); +static void cbForStateCheckID2a(u32 intType); +static void AlarmHandler(OSAlarm* alarm, OSContext* context); static void stateCoverClosed(); -static void stateCoverClosed_CMD(); -static void cbForStateCoverClosed(); +static void stateCoverClosed_CMD(DVDCommandBlock* command); +static void cbForStateCoverClosed(u32 intType); static void stateMotorStopped(); -static void cbForStateMotorStopped(); +static void cbForStateMotorStopped(u32 intType); static void stateReady(); -static void stateBusy(); -static void cbForStateBusy(); +static void stateBusy(DVDCommandBlock* block); +static BOOL IsImmCommandWithResult(u32 command); +static int IsDmaCommand(u32 command); +static void cbForStateBusy(u32 intType); +static int issueCommand(s32 prio, DVDCommandBlock* block); +static void cbForCancelStreamSync(s32 result, DVDCommandBlock* block); +static void cbForStopStreamAtEndSync(s32 result, DVDCommandBlock* block); +static void cbForGetStreamErrorStatusSync(s32 result, DVDCommandBlock* block); +static void cbForGetStreamPlayAddrSync(s32 result, DVDCommandBlock* block); +static void cbForGetStreamStartAddrSync(s32 result, DVDCommandBlock* block); +static void cbForGetStreamLengthSync(s32 result, DVDCommandBlock* block); +static void cbForChangeDiskSync(s32 result, DVDCommandBlock* block); +static void cbForStopMotorSync(s32 result, DVDCommandBlock* block); +static void cbForInquirySync(s32 result, DVDCommandBlock* block); static void cbForCancelSync(s32 result, DVDCommandBlock* block); -void __DVDPrepareResetAsync(DVDCBCallback callbac); -BOOL __DVDTestAlarm(OSAlarm* alarm); +static void cbForCancelAllSync(s32 result, DVDCommandBlock* block); -// -// External References: -// +static void defaultOptionalCommandChecker(DVDCommandBlock*, DVDCommandCheckerCallback) {} -void __DVDInitWA(); -void __DVDInterruptHandler(s16 interrupt, OSContext* context); -void DVDLowRead(); -void DVDLowSeek(); -void DVDLowWaitCoverClose(); -void DVDLowReadDiskID(); -void DVDLowStopMotor(); -void DVDLowRequestError(); -void DVDLowInquiry(); -void DVDLowAudioStream(); -void DVDLowRequestAudioStatus(); -void DVDLowAudioBufferConfig(); -void DVDLowReset(); -void DVDLowBreak(); -DVDLowCallback DVDLowClearCallback(); -BOOL __DVDLowTestAlarm(OSAlarm* alarm); -void __DVDFSInit(); -void __DVDClearWaitingQueue(); -BOOL __DVDPushWaitingQueue(); -DVDCommandBlock* __DVDPopWaitingQueue(); -BOOL __DVDCheckWaitingQueue(); -void __DVDDequeueWaitingQueue(); -void __DVDStoreErrorCode(); -BOOL DVDCompareDiskID(DVDDiskID*, DVDDiskID*); -void __DVDPrintFatalMessage(); -void __fstLoad(); -extern OSThreadQueue __DVDThreadQueue; +DVDCommandChecker __DVDSetOptionalCommandChecker(DVDCommandChecker func) { + DVDCommandChecker old = checkOptionalCommand; + checkOptionalCommand = func; + return checkOptionalCommand; +} -/* 803490EC-803490F0 343A2C 0004+00 1/0 0/0 0/0 .text defaultOptionalCommandChecker */ -static void defaultOptionalCommandChecker() {} - -/* 80451778-8045177C 000C78 0004+00 24/24 0/0 0/0 .sbss executing */ -static DVDCommandBlock* executing; - -/* 8045177C-80451780 000C7C 0004+00 4/4 0/0 0/0 .sbss IDShouldBe */ -static DVDDiskID* IDShouldBe; - -/* 80451780-80451784 000C80 0004+00 3/3 0/0 0/0 .sbss bootInfo */ -static OSBootInfo* bootInfo; - -/* 80451784-80451788 000C84 0004+00 8/8 0/0 0/0 .sbss PauseFlag */ -static volatile BOOL PauseFlag; - -/* 80451788-8045178C 000C88 0004+00 5/5 0/0 0/0 .sbss PausingFlag */ -static volatile BOOL PausingFlag; - -/* 8045178C-80451790 000C8C 0004+00 2/2 0/0 0/0 .sbss AutoFinishing */ -static volatile BOOL AutoFinishing; - -/* 80451790-80451794 000C90 0004+00 4/4 0/0 0/0 .sbss FatalErrorFlag */ -static volatile BOOL FatalErrorFlag; - -/* 80451794-80451798 000C94 0004+00 6/6 0/0 0/0 .sbss CurrCommand */ -static volatile u32 CurrCommand; - -/* 80451798-8045179C 000C98 0004+00 8/8 0/0 0/0 .sbss Canceling */ -static volatile u32 Canceling; - -/* 8045179C-804517A0 000C9C 0004+00 8/8 0/0 0/0 .sbss CancelCallback */ -static DVDCBCallback CancelCallback; - -/* 804517A0-804517A4 000CA0 0004+00 9/9 0/0 0/0 .sbss ResumeFromHere */ -static volatile u32 ResumeFromHere; - -/* 804517A4-804517A8 000CA4 0004+00 1/1 0/0 0/0 .sbss CancelLastError */ -static volatile u32 CancelLastError; - -/* 804517A8-804517AC 000CA8 0004+00 1/1 0/0 0/0 .sbss LastError */ -static volatile u32 LastError; - -/* 804517AC-804517B0 000CAC 0004+00 9/9 0/0 0/0 .sbss NumInternalRetry */ -static volatile s32 NumInternalRetry; - -/* 804517B0-804517B4 000CB0 0004+00 3/3 0/0 0/0 .sbss ResetRequired */ -static volatile BOOL ResetRequired; - -/* 804517B4-804517B8 000CB4 0004+00 1/1 0/0 0/0 .sbss FirstTimeInBootrom */ -static volatile BOOL FirstTimeInBootrom; - -/* 804517B8-804517BC 000CB8 0004+00 5/5 0/0 0/0 .sbss MotorState */ -static u32 MotorState; - -/* 804517BC-804517C0 000CBC 0004+00 1/1 0/0 0/0 .sbss DVDInitialized */ -static BOOL DVDInitialized; - -/* 803490F0-803491C8 343A30 00D8+00 0/0 3/3 0/0 .text DVDInit */ void DVDInit(void) { - if (DVDInitialized) { - return; - } + if (!DVDInitialized) { + OSRegisterVersion(__DVDVersion); + DVDInitialized = TRUE; - OSRegisterVersion(__DVDVersion); - DVDInitialized = TRUE; - __DVDFSInit(); - __DVDClearWaitingQueue(); - __DVDInitWA(); + __DVDFSInit(); + __DVDClearWaitingQueue(); + __DVDInitWA(); - bootInfo = (OSBootInfo*)OSPhysicalToCached(0x0000); - MotorState = 0; - IDShouldBe = &(bootInfo->disk_info); - __OSSetInterruptHandler(21, __DVDInterruptHandler); - __OSUnmaskInterrupts(0x400); - OSInitThreadQueue(&__DVDThreadQueue); + MotorState = 0; + bootInfo = (void*)OSPhysicalToCached(0); + IDShouldBe = &bootInfo->DVDDiskID; - __DIRegs[0] = 0x2A; - __DIRegs[1] = 0; + __OSSetInterruptHandler(0x15, __DVDInterruptHandler); + __OSUnmaskInterrupts(0x400); + OSInitThreadQueue(&__DVDThreadQueue); + __DIRegs[0] = 0x2A; + __DIRegs[1] = 0; - if (bootInfo->boot_code == 0xE5207C22) { - OSReport("load fst\n"); - __fstLoad(); - } else if (bootInfo->boot_code != 0xD15EA5E) { - FirstTimeInBootrom = TRUE; + if (bootInfo->magic == 0xE5207C22) { + OSReport("load fst\n"); + __fstLoad(); + } else if (bootInfo->magic == 0x0D15EA5E) { + + } else { + FirstTimeInBootrom = TRUE; + } } } -/* ############################################################################################## */ - -/* 8044C900-8044C920 079620 0020+00 8/8 0/0 0/0 .bss BB2 */ -static DVDBB2 BB2 ALIGN_DECL(32); - -/* 804509EC-804509F0 00046C 0004+00 6/6 0/0 0/0 .sdata autoInvalidation */ -static BOOL autoInvalidation = TRUE; - -/* 804509F0-804509F4 -00001 0004+00 1/1 0/0 0/0 .sdata checkOptionalCommand */ -static DVDOptionalCommandChecker checkOptionalCommand = defaultOptionalCommandChecker; - -/* 804509F4-804509FC 000474 0006+02 2/2 0/0 0/0 .sdata @23 */ - -typedef void (*stateFunc)(DVDCommandBlock* block); -/* 804517C0-804517C8 000CC0 0004+04 6/6 0/0 0/0 .sbss "dvd.c" LastState */ -static stateFunc LastState; - -/* 803491C8-8034925C 343B08 0094+00 1/1 0/0 0/0 .text stateReadingFST */ -void stateReadingFST() { - LastState = (stateFunc)stateReadingFST; - - if (bootInfo->fst_max_length < BB2.FSTLength) { - OSPanic(__FILE__, 661, "DVDChangeDisk(): FST in the new disc is too big. "); - } - - DVDLowRead(bootInfo->fst_location, OSRoundUp32B(BB2.FSTLength), BB2.FSTPosition, - cbForStateReadingFST); +static void stateReadingFST() { + LastState = stateReadingFST; + ASSERTLINE(652, ((u32)(bootInfo->FSTLocation) & (32 - 1)) == 0); + DVD_ASSERTMSGLINE(661, bootInfo->FSTMaxLength >= BB2.FSTLength, "DVDChangeDisk(): FST in the new disc is too big. "); + DVDLowRead(bootInfo->FSTLocation, (u32)(BB2.FSTLength + 0x1F) & 0xFFFFFFE0, BB2.FSTPosition, cbForStateReadingFST); } -/* ############################################################################################## */ -/* 8044C920-8044C940 079640 0020+00 2/3 0/0 0/0 .bss CurrDiskID */ -static DVDDiskID CurrDiskID ALIGN_DECL(32); +static u32 DmaCommand[1] = {0xFFFFFFFF}; -/* 8044C940-8044C970 079660 0030+00 10/14 0/0 0/0 .bss DummyCommandBlock */ -static DVDCommandBlock DummyCommandBlock; - -/* 8034925C-803492DC 343B9C 0080+00 2/2 0/0 0/0 .text cbForStateReadingFST */ static void cbForStateReadingFST(u32 intType) { DVDCommandBlock* finished; @@ -202,284 +149,275 @@ static void cbForStateReadingFST(u32 intType) { return; } - if (intType & 1) { + ASSERTLINE(680, (intType & DVD_INTTYPE_CVR) == 0); + + if (intType & DVD_INTTYPE_TC) { + ASSERTLINE(685, (intType & DVD_INTTYPE_DE) == 0); NumInternalRetry = 0; + __DVDFSInit(); finished = executing; executing = &DummyCommandBlock; - finished->state = 0; + finished->state = DVD_STATE_END; + if (finished->callback) { - (finished->callback)(0, finished); + finished->callback(0, finished); } stateReady(); - - } else { - stateGettingError(); + return; } + + ASSERTLINE(712, intType == DVD_INTTYPE_DE); + stateGettingError(); +} + +static void cbForStateError(u32 intType) { + DVDCommandBlock* finished; + executing->state = -1; + + if (intType == 16) { + stateTimeout(); + return; + } + + __DVDPrintFatalMessage(); + + FatalErrorFlag = TRUE; + finished = executing; + executing = &DummyCommandBlock; + + if (finished->callback) { + (finished->callback)(-1, finished); + } + + if (Canceling) { + Canceling = FALSE; + if (CancelCallback) + (CancelCallback)(0, finished); + } + + stateReady(); } static void stateError(u32 error) { __DVDStoreErrorCode(error); - DVDLowStopMotor(cbForStateError); + DVDLowStopMotor(&cbForStateError); } -/* 803492DC-80349388 343C1C 00AC+00 12/12 0/0 0/0 .text cbForStateError */ -static void cbForStateError(u32 intType) { - DVDCommandBlock* finished; - executing->state = -1; - - if (intType == 16) { - stateTimeout(); - return; - } - - __DVDPrintFatalMessage(); - - FatalErrorFlag = TRUE; - finished = executing; - executing = &DummyCommandBlock; - if (finished->callback) { - (finished->callback)(-1, finished); - } - - if (Canceling) { - Canceling = FALSE; - if (CancelCallback) - (CancelCallback)(0, finished); - } - - stateReady(); -} - -/* 80349388-803493BC 343CC8 0034+00 2/2 0/0 0/0 .text stateTimeout */ -static void stateTimeout(void) { - __DVDStoreErrorCode(0x1234568); +static void stateTimeout() { + __DVDStoreErrorCode(0x01234568); DVDReset(); cbForStateError(0); } -/* 803493BC-803493E4 343CFC 0028+00 1/1 0/0 0/0 .text stateGettingError */ -static void stateGettingError(void) { +static void stateGettingError() { DVDLowRequestError(cbForStateGettingError); } -/* 803493E4-80349498 343D24 00B4+00 1/1 0/0 0/0 .text CategorizeError */ static u32 CategorizeError(u32 error) { if (error == 0x20400) { LastError = error; return 1; } - - error &= 0xffffff; - - if ((error == 0x62800) || (error == 0x23a00) || (error == 0xb5a01)) { + + error &= 0x00FFFFFF; + if (error == 0x62800 || error == 0x23A00 || error == 0xB5A01) { return 0; } - ++NumInternalRetry; + NumInternalRetry++; if (NumInternalRetry == 2) { if (error == LastError) { LastError = error; return 1; - } else { - LastError = error; - return 2; } - } else { LastError = error; - - if ((error == 0x31100) || (executing->command == 5)) { - return 2; - } else { - return 3; - } + return 2; } + + LastError = error; + + if (error == 0x31100 || executing->command == DVD_COMMAND_READID) { + return 2; + } + + return 3; } static BOOL CheckCancel(u32 resume) { - DVDCommandBlock* finished; + DVDCommandBlock* finished; - if (Canceling) { - ResumeFromHere = resume; - Canceling = FALSE; + if (Canceling) { + ResumeFromHere = resume; + Canceling = FALSE; - finished = executing; - executing = &DummyCommandBlock; + finished = executing; + executing = &DummyCommandBlock; - finished->state = 10; - if (finished->callback) - (*finished->callback)(-3, finished); - if (CancelCallback) - (CancelCallback)(0, finished); - stateReady(); - return TRUE; - } - return FALSE; + finished->state = 10; + + if (finished->callback) + (*finished->callback)(-3, finished); + + if (CancelCallback) + (CancelCallback)(0, finished); + + stateReady(); + return TRUE; + } + + return FALSE; } -/* 80349498-803496FC 343DD8 0264+00 6/6 0/0 0/0 .text cbForStateGettingError */ static void cbForStateGettingError(u32 intType) { - u32 error; - u32 status; - u32 errorCategory; - u32 resume; + u32 error; + u32 status; + u32 errorCategory; + u32 resume; - if (intType == 16) { - __DVDStoreErrorCode(0x1234568); - DVDReset(); - cbForStateError(0); - return; - } + if (intType == 16) { + stateTimeout(); + return; + } - if (intType & 2) { - stateError(0x1234567); - return; - } + if (intType & 2) { + stateError(0x1234567); + return; + } - error = __DIRegs[8]; - status = error & 0xff000000; + ASSERTLINE(956, intType == DVD_INTTYPE_TC); - errorCategory = CategorizeError(error); + error = __DIRegs[8]; + status = error & 0xff000000; - if (errorCategory == 1) { - stateError(error); - return; - } + errorCategory = CategorizeError(error); - if ((errorCategory == 2) || (errorCategory == 3)) { - resume = 0; - } else { - if (status == 0x01000000) - resume = 4; - else if (status == 0x02000000) - resume = 6; - else if (status == 0x03000000) - resume = 3; - else - resume = 5; - } + if (errorCategory == 1) { + stateError(error); + return; + } - if (CheckCancel(resume)) - return; + if (errorCategory == 2 || errorCategory == 3) { + resume = 0; + } else { + if (status == 0x01000000) + resume = 4; + else if (status == 0x02000000) + resume = 6; + else if (status == 0x03000000) + resume = 3; + else + resume = 5; + } - if (errorCategory == 2) { - __DVDStoreErrorCode(error); - stateGoToRetry(); - return; - } + if (CheckCancel(resume)) + return; - if (errorCategory == 3) { - if ((error & 0x00ffffff) == 0x00031100) { - DVDLowSeek(executing->offset, cbForUnrecoveredError); - } else { - LastState(executing); - } - return; - } + if (errorCategory == 2) { + __DVDStoreErrorCode(error); + stateGoToRetry(); + return; + } - if (status == 0x01000000) { - executing->state = 5; - stateMotorStopped(); - return; - } else if (status == 0x02000000) { - executing->state = 3; - stateCoverClosed(); - return; - } else if (status == 0x03000000) { - executing->state = 4; - stateMotorStopped(); - return; - } else { - stateError(0x1234567); - return; - } + if (errorCategory == 3) { + if ((error & 0x00ffffff) == 0x00031100) { + DVDLowSeek(executing->offset, cbForUnrecoveredError); + } else { + LastState(executing); + } + return; + } + + if (status == 0x01000000) { + executing->state = 5; + stateMotorStopped(); + return; + } else if (status == 0x02000000) { + executing->state = 3; + stateCoverClosed(); + return; + } else if (status == 0x03000000) { + executing->state = 4; + stateMotorStopped(); + return; + } else { + stateError(0x1234567); + return; + } } -/* 803496FC-80349758 34403C 005C+00 1/1 0/0 0/0 .text cbForUnrecoveredError */ static void cbForUnrecoveredError(u32 intType) { - if (intType == 16) { - __DVDStoreErrorCode(0x1234568); - DVDReset(); - cbForStateError(0); - return; - } + if (intType == 16) { + stateTimeout(); + return; + } - if (intType & 1) { - stateGoToRetry(); - return; - } + if (intType & 1) { + stateGoToRetry(); + return; + } - DVDLowRequestError(cbForUnrecoveredErrorRetry); + ASSERTLINE(1055, intType == DVD_INTTYPE_DE); + DVDLowRequestError(cbForUnrecoveredErrorRetry); } -/* 80349758-803497D8 344098 0080+00 1/1 0/0 0/0 .text cbForUnrecoveredErrorRetry */ static void cbForUnrecoveredErrorRetry(u32 intType) { - if (intType == 16) { - __DVDStoreErrorCode(0x1234568); - DVDReset(); - cbForStateError(0); - return; - } + if (intType == 0x10) { + stateTimeout(); + } else { + if (intType & 2) { + stateError(0x01234567); + return; + } - if (intType & 2) { - stateError(0x1234567); - return; + stateError(__DIRegs[8]); } - - stateError(__DIRegs[8]); } -/* 803497D8-80349800 344118 0028+00 2/2 0/0 0/0 .text stateGoToRetry */ -static void stateGoToRetry(void) { +static void stateGoToRetry() { DVDLowStopMotor(cbForStateGoToRetry); } -/* 80349800-80349940 344140 0140+00 1/1 0/0 0/0 .text cbForStateGoToRetry */ static void cbForStateGoToRetry(u32 intType) { - if (intType == 16) { - __DVDStoreErrorCode(0x1234568); - DVDReset(); - cbForStateError(0); - return; - } + if (intType == 16) { + stateTimeout(); + return; + } - if (intType & 2) { - stateError(0x1234567); - return; - } + if (intType & 2) { + stateError(0x1234567); + return; + } - NumInternalRetry = 0; + ASSERTLINE(1104, intType == DVD_INTTYPE_TC); + NumInternalRetry = 0; - if ((CurrCommand == 4) || (CurrCommand == 5) || (CurrCommand == 13) || (CurrCommand == 15)) { - ResetRequired = TRUE; - } + if (CurrCommand == 4 || CurrCommand == 5 || CurrCommand == 13 || CurrCommand == 15) { + ResetRequired = TRUE; + } - if (!CheckCancel(2)) { - executing->state = 11; - stateMotorStopped(); - } + if (!CheckCancel(2)) { + executing->state = 11; + stateMotorStopped(); + } } -/* 80349940-80349A20 344280 00E0+00 1/1 0/0 0/0 .text stateCheckID */ -static void stateCheckID(void) { - switch (CurrCommand) { - case 3: - if (DVDCompareDiskID(&CurrDiskID, executing->disk_id)) { +static void stateCheckID() { + switch(CurrCommand) { + case DVD_COMMAND_CHANGE_DISK: + if (DVDCompareDiskID(&CurrDiskID, executing->id)) { memcpy(IDShouldBe, &CurrDiskID, sizeof(DVDDiskID)); - - executing->state = 1; - DCInvalidateRange(&BB2, sizeof(DVDBB2)); + executing->state = DVD_STATE_BUSY; + DCInvalidateRange(&BB2.bootFilePosition, 0x20); LastState = stateCheckID2a; stateCheckID2a(executing); - return; } else { DVDLowStopMotor(cbForStateCheckID1); } break; - default: - if (memcmp(&CurrDiskID, IDShouldBe, sizeof(DVDDiskID))) { + if (memcmp(&CurrDiskID, IDShouldBe, sizeof(DVDDiskID)) != 0) { DVDLowStopMotor(cbForStateCheckID1); } else { LastState = stateCheckID3; @@ -489,834 +427,1282 @@ static void stateCheckID(void) { } } -/* 80349A20-80349A54 344360 0034+00 1/1 0/0 0/0 .text stateCheckID3 */ -static void stateCheckID3(void) { - DVDLowAudioBufferConfig(IDShouldBe->is_streaming, 10, cbForStateCheckID3); +static void stateCheckID3() { + DVDLowAudioBufferConfig(IDShouldBe->streaming, 0xA, cbForStateCheckID3); } -/* 80349A54-80349A88 344394 0034+00 1/1 0/0 0/0 .text stateCheckID2a */ -static void stateCheckID2a(void) { - DVDLowAudioBufferConfig(IDShouldBe->is_streaming, 10, cbForStateCheckID2a); +static void stateCheckID2a() { + DVDLowAudioBufferConfig(IDShouldBe->streaming, 0xA, cbForStateCheckID2a); } -/* 80349A88-80349AF0 3443C8 0068+00 1/1 0/0 0/0 .text cbForStateCheckID2a */ static void cbForStateCheckID2a(u32 intType) { if (intType == 16) { - __DVDStoreErrorCode(0x1234568); - DVDReset(); - cbForStateError(0); - return; - } + stateTimeout(); + return; + } - if (intType & 1) { + ASSERTLINE(1227, (intType & DVD_INTTYPE_CVR) == 0); + + if (intType & DVD_INTTYPE_TC) { + ASSERTLINE(1232, (intType & DVD_INTTYPE_DE) == 0); NumInternalRetry = 0; stateCheckID2(executing); return; } - DVDLowRequestError(cbForStateGettingError); + ASSERTLINE(1243, intType == DVD_INTTYPE_DE); + stateGettingError(); } -/* 80349AF0-80349B28 344430 0038+00 1/1 0/0 0/0 .text stateCheckID2 */ static void stateCheckID2() { - DVDLowRead(&BB2, OSRoundUp32B(sizeof(BB2)), 0x420, cbForStateCheckID2); + DVDLowRead(&BB2, 0x20, 0x420, cbForStateCheckID2); } -/* 80349B28-80349C24 344468 00FC+00 1/1 0/0 0/0 .text cbForStateCheckID1 */ static void cbForStateCheckID1(u32 intType) { if (intType == 16) { - __DVDStoreErrorCode(0x1234568); - DVDReset(); - cbForStateError(0); - return; - } - - if (intType & 2) { - stateError(0x1234567); + stateTimeout(); + return; + } + + if (intType & DVD_INTTYPE_DE) { + stateError(0x01234567); return; } + ASSERTLINE(1279, intType == DVD_INTTYPE_TC); NumInternalRetry = 0; - if (!CheckCancel(1)) { - executing->state = 6; + if (CheckCancel(1) == FALSE) { + executing->state = DVD_STATE_WRONG_DISK; stateMotorStopped(); } } -/* 80349C24-80349CFC 344564 00D8+00 1/1 0/0 0/0 .text cbForStateCheckID2 */ - static void cbForStateCheckID2(u32 intType) { if (intType == 16) { - stateTimeout(); + stateTimeout(); + return; + } + + ASSERTLINE(1300, (intType & DVD_INTTYPE_CVR) == 0); + + if (intType & DVD_INTTYPE_TC) { + ASSERTLINE(1305, (intType & DVD_INTTYPE_DE) == 0); + NumInternalRetry = 0; + stateReadingFST(); return; } - if (intType & 1) { - NumInternalRetry = 0; - - LastState = (stateFunc)stateReadingFST; - - if (bootInfo->fst_max_length < BB2.FSTLength) { - OSPanic(__FILE__, 661, "DVDChangeDisk(): FST in the new disc is too big. "); - } - - DVDLowRead(bootInfo->fst_location, OSRoundUp32B(BB2.FSTLength), BB2.FSTPosition, - cbForStateReadingFST); - - } else { - stateGettingError(); - } + ASSERTLINE(1321, intType == DVD_INTTYPE_DE); + stateGettingError(); } -/* 80349CFC-80349DEC 34463C 00F0+00 1/1 0/0 0/0 .text cbForStateCheckID3 */ static void cbForStateCheckID3(u32 intType) { if (intType == 16) { - __DVDStoreErrorCode(0x1234568); - DVDReset(); - cbForStateError(0); + stateTimeout(); + return; + } + + ASSERTLINE(1336, (intType & DVD_INTTYPE_CVR) == 0); + + if (intType & DVD_INTTYPE_TC) { + ASSERTLINE(1341, (intType & DVD_INTTYPE_DE) == 0); + NumInternalRetry = 0; + if (CheckCancel(0) == FALSE) { + executing->state = DVD_STATE_BUSY; + stateBusy(executing); + } return; } - if (intType & 1) { - NumInternalRetry = 0; - - if (!CheckCancel(0)) { - executing->state = 1; - stateBusy(executing); - } - } else { - stateGettingError(); - } + ASSERTLINE(1355, intType == DVD_INTTYPE_DE); + stateGettingError(); } -/* 80349DEC-80349E30 34472C 0044+00 3/3 0/0 0/0 .text AlarmHandler */ static void AlarmHandler(OSAlarm* alarm, OSContext* context) { DVDReset(); DCInvalidateRange(&CurrDiskID, sizeof(DVDDiskID)); - LastState = stateCoverClosed_CMD; + LastState = &stateCoverClosed_CMD; stateCoverClosed_CMD(executing); } -/* ############################################################################################## */ -/* 8044C970-8044C998 079690 0028+00 1/4 0/0 0/0 .bss ResetAlarm */ -static OSAlarm ResetAlarm; - -/* 80349E30-80349F04 344770 00D4+00 1/1 0/0 0/0 .text stateCoverClosed */ -static void stateCoverClosed(void) { +static void stateCoverClosed() { DVDCommandBlock* finished; - switch (CurrCommand) { - case 5: - case 4: - case 13: - case 15: + switch(CurrCommand) { + case DVD_COMMAND_BSREAD: + case DVD_COMMAND_READID: + case DVD_COMMAND_AUDIO_BUFFER_CONFIG: + case DVD_COMMAND_BS_CHANGE_DISK: __DVDClearWaitingQueue(); finished = executing; executing = &DummyCommandBlock; if (finished->callback) { - (finished->callback)(-4, finished); + finished->callback(-4, finished); } stateReady(); break; - default: MotorState = 0; DVDReset(); OSCreateAlarm(&ResetAlarm); - OSSetAlarm(&ResetAlarm, OSMillisecondsToTicks(1150), AlarmHandler); + OSSetAlarm(&ResetAlarm, OSMillisecondsToTicks(1150), &AlarmHandler); break; } } -/* 80349F04-80349F34 344844 0030+00 1/1 0/0 0/0 .text stateCoverClosed_CMD */ -static void stateCoverClosed_CMD(DVDCommandBlock* block) { +static void stateCoverClosed_CMD(DVDCommandBlock* command) { DVDLowReadDiskID(&CurrDiskID, cbForStateCoverClosed); } -/* 80349F34-80349F98 344874 0064+00 1/1 0/0 0/0 .text cbForStateCoverClosed */ static void cbForStateCoverClosed(u32 intType) { if (intType == 16) { - __DVDStoreErrorCode(0x1234568); - DVDReset(); - cbForStateError(0); + stateTimeout(); + return; + } + + ASSERTLINE(1437, (intType & DVD_INTTYPE_CVR) == 0); + + if (intType & DVD_INTTYPE_TC) { + ASSERTLINE(1442, (intType & DVD_INTTYPE_DE) == 0); + NumInternalRetry = 0; + stateCheckID(); return; } - if (intType & 1) { - NumInternalRetry = 0; - stateCheckID(); - } else { - stateGettingError(); - } + ASSERTLINE(1454, intType == DVD_INTTYPE_DE); + stateGettingError(); } -/* 80349F98-80349FC0 3448D8 0028+00 3/3 0/0 0/0 .text stateMotorStopped */ -static void stateMotorStopped(void) { +static void stateMotorStopped() { DVDLowWaitCoverClose(cbForStateMotorStopped); } -/* 80349FC0-8034A0AC 344900 00EC+00 4/4 0/0 0/0 .text cbForStateMotorStopped */ static void cbForStateMotorStopped(u32 intType) { + ASSERTLINE(1483, intType == DVD_INTTYPE_CVR); __DIRegs[1] = 0; - executing->state = 3; + executing->state = DVD_STATE_COVER_CLOSED; stateCoverClosed(); } -/* 8034A0AC-8034A394 3449EC 02E8+00 18/18 0/0 0/0 .text stateReady */ static void stateReady() { - DVDCommandBlock* finished; - - if (!__DVDCheckWaitingQueue()) { - executing = (DVDCommandBlock*)NULL; + if (__DVDCheckWaitingQueue() == 0) { + executing = NULL; return; } - if (PauseFlag) { - PausingFlag = TRUE; - executing = (DVDCommandBlock*)NULL; + if (PauseFlag != 0) { + PausingFlag = 1; + executing = NULL; return; } executing = __DVDPopWaitingQueue(); if (FatalErrorFlag) { - executing->state = -1; + DVDCommandBlock* finished; + + executing->state = DVD_STATE_FATAL_ERROR; finished = executing; executing = &DummyCommandBlock; if (finished->callback) { - (finished->callback)(-1, finished); + (*finished->callback)(-1, finished); } + stateReady(); return; } CurrCommand = executing->command; - - if (ResumeFromHere) { + if (ResumeFromHere != 0) { switch (ResumeFromHere) { case 2: - executing->state = 11; + executing->state = DVD_STATE_RETRY; stateMotorStopped(); break; case 3: - executing->state = 4; + executing->state = DVD_STATE_NO_DISK; stateMotorStopped(); break; case 4: - executing->state = 5; + executing->state = DVD_STATE_COVER_OPEN; stateMotorStopped(); break; - case 7: - case 6: case 1: - executing->state = 3; + case 6: + case 7: + executing->state = DVD_STATE_COVER_CLOSED; stateCoverClosed(); break; case 5: stateError(CancelLastError); break; } + ResumeFromHere = 0; + return; + } + + if (MotorState == 0) { + executing->state = DVD_STATE_BUSY; + stateBusy(executing); } else { - if (MotorState == 0) { - executing->state = 1; - stateBusy(executing); - } else { - stateCoverClosed(); - } + stateCoverClosed(); } } -/* 8034A394-8034A6D4 344CD4 0340+00 4/3 0/0 0/0 .text stateBusy */ -#define MIN(a, b) (((a) > (b)) ? (b) : (a)) static void stateBusy(DVDCommandBlock* block) { DVDCommandBlock* finished; LastState = stateBusy; - switch (block->command) { - case 5: + + switch(block->command) { + case DVD_COMMAND_READID: __DIRegs[1] = __DIRegs[1]; - block->current_transfer_size = sizeof(DVDDiskID); - DVDLowReadDiskID(block->buffer, cbForStateBusy); - break; - case 1: - case 4: - if (!block->length) { + block->currTransferSize = 0x20; + DVDLowReadDiskID(block->addr, cbForStateBusy); + return; + case DVD_COMMAND_READ: + case DVD_COMMAND_BSREAD: + if (block->length == 0) { finished = executing; executing = &DummyCommandBlock; finished->state = 0; - if (finished->callback) { - finished->callback(0, finished); + + if (finished->callback != 0) { + (*finished->callback)(0, finished); } + stateReady(); } else { __DIRegs[1] = __DIRegs[1]; - block->current_transfer_size = MIN(block->length - block->transferred_size, 0x80000); - DVDLowRead((void*)((u8*)block->buffer + block->transferred_size), - block->current_transfer_size, block->offset + block->transferred_size, - cbForStateBusy); + block->currTransferSize = (block->length - block->transferredSize > 0x80000) ? 0x80000 : (block->length - block->transferredSize); + DVDLowRead((char*)block->addr + block->transferredSize, block->currTransferSize, block->offset + block->transferredSize, cbForStateBusy); } - break; - case 2: + return; + case DVD_COMMAND_SEEK: __DIRegs[1] = __DIRegs[1]; DVDLowSeek(block->offset, cbForStateBusy); - break; - case 3: + return; + case DVD_COMMAND_CHANGE_DISK: DVDLowStopMotor(cbForStateBusy); - break; - case 15: + return; + case DVD_COMMAND_BS_CHANGE_DISK: DVDLowStopMotor(cbForStateBusy); - break; - case 6: + return; + case DVD_COMMAND_INITSTREAM: __DIRegs[1] = __DIRegs[1]; - if (AutoFinishing) { - executing->current_transfer_size = 0; + if (AutoFinishing != 0) { + executing->currTransferSize = 0; DVDLowRequestAudioStatus(0, cbForStateBusy); - } else { - executing->current_transfer_size = 1; - DVDLowAudioStream(0, block->length, block->offset, cbForStateBusy); + return; } - break; - case 7: + executing->currTransferSize = 1; + DVDLowAudioStream(0, block->length, block->offset, cbForStateBusy); + return; + case DVD_COMMAND_CANCELSTREAM: __DIRegs[1] = __DIRegs[1]; - DVDLowAudioStream(0x10000, 0, 0, cbForStateBusy); - break; - case 8: + DVDLowAudioStream(0x10000, 0U, 0U, cbForStateBusy); + return; + case DVD_COMMAND_STOP_STREAM_AT_END: __DIRegs[1] = __DIRegs[1]; - AutoFinishing = TRUE; - DVDLowAudioStream(0, 0, 0, cbForStateBusy); - break; - case 9: + AutoFinishing = 1; + DVDLowAudioStream(0, 0U, 0U, cbForStateBusy); + return; + case DVD_COMMAND_REQUEST_AUDIO_ERROR: __DIRegs[1] = __DIRegs[1]; DVDLowRequestAudioStatus(0, cbForStateBusy); - break; - case 10: + return; + case DVD_COMMAND_REQUEST_PLAY_ADDR: __DIRegs[1] = __DIRegs[1]; DVDLowRequestAudioStatus(0x10000, cbForStateBusy); - break; - case 11: + return; + case DVD_COMMAND_REQUEST_START_ADDR: __DIRegs[1] = __DIRegs[1]; DVDLowRequestAudioStatus(0x20000, cbForStateBusy); - break; - case 12: + return; + case DVD_COMMAND_REQUEST_LENGTH: __DIRegs[1] = __DIRegs[1]; DVDLowRequestAudioStatus(0x30000, cbForStateBusy); - break; - case 13: + return; + case DVD_COMMAND_AUDIO_BUFFER_CONFIG: __DIRegs[1] = __DIRegs[1]; DVDLowAudioBufferConfig(block->offset, block->length, cbForStateBusy); - break; - case 14: + return; + case DVD_COMMAND_INQUIRY: __DIRegs[1] = __DIRegs[1]; - block->current_transfer_size = sizeof(DVDDriveInfo); - DVDLowInquiry(block->buffer, cbForStateBusy); - break; - case 16: + block->currTransferSize = 0x20; + DVDLowInquiry(block->addr, cbForStateBusy); + return; + case DVD_COMMAND_UNK_16: __DIRegs[1] = __DIRegs[1]; DVDLowStopMotor(cbForStateBusy); - break; + return; default: checkOptionalCommand(block, cbForStateBusy); - break; + return; } } -/* ############################################################################################## */ -/* 803D15EC-803D15F8 02E70C 000C+00 1/1 0/0 0/0 .data ImmCommand */ -static u32 ImmCommand[] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; -/* 804509FC-80450A00 00047C 0004+00 1/1 0/0 0/0 .sdata DmaCommand */ -static u32 DmaCommand[] = {0xFFFFFFFF}; +static u32 ImmCommand[3] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; + +void __DVDSetImmCommand(u32 command) { + static u32 immCount; + ASSERTLINE(1790, immCount < sizeof(ImmCommand)/sizeof(ImmCommand[0])); + ImmCommand[immCount++] = command; +} + +void __DVDSetDmaCommand(u32 command) { + static u32 dmaCount; + ASSERTLINE(1798, dmaCount < sizeof(DmaCommand)/sizeof(DmaCommand[0])); + DmaCommand[dmaCount++] = command; +} static BOOL IsImmCommandWithResult(u32 command) { u32 i; if (command == 9 || command == 10 || command == 11 || command == 12) { - return TRUE; + return 1; } - for (i = 0; i < sizeof(ImmCommand) / sizeof(ImmCommand[0]); i++) { - if (command == ImmCommand[i]) + for (i = 0; i < 3; i++) { + if (command == ImmCommand[i]) { return TRUE; + } } return FALSE; } -static BOOL IsDmaCommand(u32 command) { +static int IsDmaCommand(u32 command) { u32 i; - if (command == 1 || command == 4 || command == 5 || command == 14) - return TRUE; + if (command == 1 || command == 4 || command == 5 || command == 14) { + return 1; + } - for (i = 0; i < sizeof(DmaCommand) / sizeof(DmaCommand[0]); i++) { - if (command == DmaCommand[i]) + for (i = 0; i < 1; i++) { + if (command == DmaCommand[i]) { return TRUE; + } } return FALSE; } -/* 8034A6D4-8034AD2C 345014 0658+00 1/1 0/0 0/0 .text cbForStateBusy */ static void cbForStateBusy(u32 intType) { DVDCommandBlock* finished; + s32 result; if (intType == 16) { - stateTimeout(); - return; - } + stateTimeout(); + return; + } - if ((CurrCommand == 3) || (CurrCommand == 15)) { - if (intType & 2) { - stateError(0x1234567); + if ((CurrCommand == DVD_COMMAND_CHANGE_DISK) || (CurrCommand == DVD_COMMAND_BS_CHANGE_DISK)) { + if (intType & DVD_INTTYPE_DE) { + stateError(0x01234567); return; } + ASSERTLINE(1857, intType == DVD_INTTYPE_TC); NumInternalRetry = 0; - if (CurrCommand == 15) { - ResetRequired = TRUE; + if (CurrCommand == DVD_COMMAND_BS_CHANGE_DISK) { + ResetRequired = 1; } - if (CheckCancel(7)) { - return; + if (CheckCancel(7) == FALSE) { + executing->state = DVD_STATE_MOTOR_STOPPED; + stateMotorStopped(); } - - executing->state = 7; - stateMotorStopped(); return; } + ASSERTLINE(1877, (intType & DVD_INTTYPE_CVR) == 0); + if (IsDmaCommand(CurrCommand)) { - executing->transferred_size += executing->current_transfer_size - __DIRegs[6]; + executing->transferredSize += executing->currTransferSize - __DIRegs[6]; } if (intType & 8) { - Canceling = FALSE; + Canceling = 0; finished = executing; executing = &DummyCommandBlock; + finished->state = DVD_STATE_CANCELED; + + if (finished->callback) { + finished->callback(-3, finished); + } + + if (CancelCallback) { + CancelCallback(0, finished); + } - finished->state = 10; - if (finished->callback) - (*finished->callback)(-3, finished); - if (CancelCallback) - (CancelCallback)(0, finished); stateReady(); - return; } if (intType & 1) { + ASSERTLINE(1915, (intType & DVD_INTTYPE_DE) == 0); NumInternalRetry = 0; - if (CurrCommand == 16) { + if (CurrCommand == 0x10) { MotorState = 1; finished = executing; executing = &DummyCommandBlock; finished->state = 0; - if (finished->callback) { + + if (finished->callback != 0) { (*finished->callback)(0, finished); } + stateReady(); return; } - if (CheckCancel(0)) + if (CheckCancel(0) != FALSE) { return; + } if (IsDmaCommand(CurrCommand)) { - if (executing->transferred_size != executing->length) { + if (executing->transferredSize != executing->length) { stateBusy(executing); return; } finished = executing; executing = &DummyCommandBlock; - - finished->state = 0; + finished->state = DVD_STATE_END; if (finished->callback) { - (finished->callback)((s32)finished->transferred_size, finished); + finished->callback(finished->transferredSize, finished); } - stateReady(); - } else if (IsImmCommandWithResult(CurrCommand)) { - s32 result; - if ((CurrCommand == 11) || (CurrCommand == 10)) { - result = (s32)(__DIRegs[8] << 2); + stateReady(); + return; + } else if (IsImmCommandWithResult(CurrCommand)) { + if (CurrCommand == DVD_COMMAND_REQUEST_START_ADDR || CurrCommand == DVD_COMMAND_REQUEST_PLAY_ADDR) { + result = __DIRegs[8] * 4; } else { - result = (s32)__DIRegs[8]; + result = __DIRegs[8]; } + finished = executing; executing = &DummyCommandBlock; - - finished->state = 0; + finished->state = DVD_STATE_END; if (finished->callback) { - (finished->callback)(result, finished); + finished->callback(result, finished); } + stateReady(); - } else if (CurrCommand == 6) { - if (executing->current_transfer_size == 0) { + return; + } else if (CurrCommand == DVD_COMMAND_INITSTREAM) { + if (executing->currTransferSize == 0) { if (__DIRegs[8] & 1) { finished = executing; executing = &DummyCommandBlock; - - finished->state = 9; + finished->state = DVD_STATE_IGNORED; if (finished->callback) { - (finished->callback)(-2, finished); + finished->callback(-2, finished); } stateReady(); - } else { - AutoFinishing = FALSE; - executing->current_transfer_size = 1; - DVDLowAudioStream(0, executing->length, executing->offset, cbForStateBusy); + return; } - } else { - finished = executing; - executing = &DummyCommandBlock; - finished->state = 0; - if (finished->callback) { - (finished->callback)(0, finished); - } - stateReady(); + AutoFinishing = 0; + executing->currTransferSize = 1; + DVDLowAudioStream(0, executing->length, executing->offset, cbForStateBusy); + return; } + + finished = executing; + executing = &DummyCommandBlock; + finished->state = DVD_STATE_END; + if (finished->callback) { + finished->callback(0, finished); + } + + stateReady(); + return; } else { finished = executing; executing = &DummyCommandBlock; - - finished->state = 0; + finished->state = DVD_STATE_END; if (finished->callback) { - (finished->callback)(0, finished); + finished->callback(0, finished); } + stateReady(); + return; } } else { + ASSERTLINE(2063, intType == DVD_INTTYPE_DE); + if (CurrCommand == 14) { - stateError(0x01234567); - return; - } + stateError(0x01234567); + return; + } - if ((CurrCommand == 1 || CurrCommand == 4 || CurrCommand == 5 || CurrCommand == 14) && - (executing->transferred_size == executing->length)) - { - if (CheckCancel(0)) { - return; - } - finished = executing; - executing = &DummyCommandBlock; + if ((CurrCommand == 1 || CurrCommand == 4 || CurrCommand == 5 || CurrCommand == 14) + && (executing->transferredSize == executing->length)) { - finished->state = 0; - if (finished->callback) { - (finished->callback)((s32)finished->transferred_size, finished); - } - stateReady(); - return; - } + if (CheckCancel(0)) { + return; + } + finished = executing; + executing = &DummyCommandBlock; + + finished->state = DVD_STATE_END; + if (finished->callback) { + (finished->callback)((s32)finished->transferredSize, finished); + } + stateReady(); + return; + } stateGettingError(); } } -static BOOL issueCommand(s32 prio, DVDCommandBlock* block) { - BOOL level; - BOOL result; +void* __DVDGetIssueCommandAddr(void) { + return issueCommand; +} - if (autoInvalidation && - (block->command == 1 || block->command == 4 || block->command == 5 || block->command == 14)) - { - DCInvalidateRange(block->buffer, block->length); +static int issueCommand(s32 prio, DVDCommandBlock* block) { + BOOL level; + int result; + + if (autoInvalidation != 0 && (block->command == DVD_COMMAND_READ || block->command == DVD_COMMAND_BSREAD + || block->command == DVD_COMMAND_READID || block->command == DVD_COMMAND_INQUIRY)) { + DCInvalidateRange(block->addr, block->length); } level = OSDisableInterrupts(); +#if DEBUG + if (executing == block || block->state == DVD_STATE_WAITING && __DVDIsBlockInWaitingQueue(block)) { + ASSERTMSGLINE(2151, FALSE, "DVD library: Specified command block (or file info) is already in use\n"); + } +#endif - block->state = 2; + block->state = DVD_STATE_WAITING; result = __DVDPushWaitingQueue(prio, block); - - if ((executing == (DVDCommandBlock*)NULL) && (PauseFlag == FALSE)) { + if (executing == NULL && PauseFlag == 0) { stateReady(); } OSRestoreInterrupts(level); - return result; } -/* 8034AD2C-8034AE08 34566C 00DC+00 0/0 5/5 0/0 .text DVDReadAbsAsyncPrio */ -BOOL DVDReadAbsAsyncPrio(DVDCommandBlock* block, void* addr, s32 length, s32 offset, - DVDCBCallback callback, s32 prio) { - BOOL idle; - block->command = 1; - block->buffer = addr; +int DVDReadAbsAsyncPrio(DVDCommandBlock* block, void* addr, s32 length, s32 offset, DVDCBCallback callback, s32 prio) { + int idle; + + ASSERTMSGLINE(2191, block, "DVDReadAbsAsync(): null pointer is specified to command block address."); + ASSERTMSGLINE(2192, addr, "DVDReadAbsAsync(): null pointer is specified to addr."); + ASSERTMSGLINE(2194, !OFFSET(addr, 32), "DVDReadAbsAsync(): address must be aligned with 32 byte boundary."); + ASSERTMSGLINE(2196, !(length & (32-1)), "DVDReadAbsAsync(): length must be a multiple of 32."); + ASSERTMSGLINE(2198, !(offset & (4-1)), "DVDReadAbsAsync(): offset must be a multiple of 4."); + ASSERTMSGLINE(2200, length >= 0, "DVD read: negative value was specified to length of the read\n"); + + block->command = DVD_COMMAND_READ; + block->addr = addr; block->length = length; block->offset = offset; - block->transferred_size = 0; + block->transferredSize = 0; block->callback = callback; idle = issueCommand(prio, block); + ASSERTMSGLINE(2210, idle, "DVDReadAbsAsync(): command block is used for processing previous request."); return idle; } -/* 8034AE08-8034AED8 345748 00D0+00 0/0 1/1 0/0 .text DVDReadAbsAsyncForBS */ -BOOL DVDReadAbsAsyncForBS(DVDCommandBlock* block, void* addr, s32 length, s32 offset, - DVDCBCallback callback) { - BOOL idle; - block->command = 4; - block->buffer = addr; +int DVDSeekAbsAsyncPrio(DVDCommandBlock* block, s32 offset, DVDCBCallback callback, s32 prio) { + int idle; + + ASSERTMSGLINE(2233, block, "DVDSeekAbs(): null pointer is specified to command block address."); + ASSERTMSGLINE(2235, !(offset & (4-1)), "DVDSeekAbs(): offset must be a multiple of 4."); + + block->command = DVD_COMMAND_SEEK; + block->offset = offset; + block->callback = callback; + + idle = issueCommand(prio, block); + ASSERTMSGLINE(2242, idle, "DVDSeekAbs(): command block is used for processing previous request."); + return idle; +} + +int DVDReadAbsAsyncForBS(DVDCommandBlock* block, void* addr, s32 length, s32 offset, DVDCBCallback callback) { + int idle; + + ASSERTMSGLINE(2272, block, "DVDReadAbsAsyncForBS(): null pointer is specified to command block address."); + ASSERTMSGLINE(2273, addr, "DVDReadAbsAsyncForBS(): null pointer is specified to addr."); + ASSERTMSGLINE(2275, !OFFSET(addr, 32), "DVDReadAbsAsyncForBS(): address must be aligned with 32 byte boundary."); + ASSERTMSGLINE(2277, !(length & (32-1)), "DVDReadAbsAsyncForBS(): length must be a multiple of 32."); + ASSERTMSGLINE(2279, !(offset & (4-1)), "DVDReadAbsAsyncForBS(): offset must be a multiple of 4."); + + block->command = DVD_COMMAND_BSREAD; + block->addr = addr; block->length = length; block->offset = offset; - block->transferred_size = 0; + block->transferredSize = 0; block->callback = callback; idle = issueCommand(2, block); + ASSERTMSGLINE(2289, idle, "DVDReadAbsAsyncForBS(): command block is used for processing previous request."); return idle; } -/* 8034AED8-8034AFAC 345818 00D4+00 0/0 2/2 0/0 .text DVDReadDiskID */ -BOOL DVDReadDiskID(DVDCommandBlock* block, DVDDiskID* diskID, DVDCBCallback callback) { - BOOL idle; - block->command = 5; - block->buffer = diskID; - block->length = sizeof(DVDDiskID); +int DVDReadDiskID(DVDCommandBlock* block, DVDDiskID* diskID, DVDCBCallback callback) { + int idle; + + ASSERTMSGLINE(2312, block, "DVDReadDiskID(): null pointer is specified to command block address."); + ASSERTMSGLINE(2313, diskID, "DVDReadDiskID(): null pointer is specified to id address."); + ASSERTMSGLINE(2315, !OFFSET(diskID, 32), "DVDReadDiskID(): id must be aligned with 32 byte boundary."); + + block->command = DVD_COMMAND_READID; + block->addr = diskID; + block->length = 0x20; block->offset = 0; - block->transferred_size = 0; + block->transferredSize = 0; block->callback = callback; idle = issueCommand(2, block); + ASSERTMSGLINE(2325, idle, "DVDReadDiskID(): command block is used for processing previous request."); return idle; } -/* 8034AFAC-8034B068 3458EC 00BC+00 0/0 1/1 0/0 .text DVDCancelStreamAsync */ -BOOL DVDCancelStreamAsync(DVDCommandBlock* block, DVDCBCallback callback) { - BOOL idle; - block->command = 7; +int DVDPrepareStreamAbsAsync(DVDCommandBlock* block, u32 length, u32 offset, DVDCBCallback callback) { + int idle; + + block->command = DVD_COMMAND_INITSTREAM; + block->length = length; + block->offset = offset; block->callback = callback; idle = issueCommand(1, block); return idle; } -/* 8034B068-8034B138 3459A8 00D0+00 0/0 1/1 0/0 .text DVDInquiryAsync */ -BOOL DVDInquiryAsync(DVDCommandBlock* block, DVDDriveInfo* info, DVDCBCallback callback) { - BOOL idle; +int DVDCancelStreamAsync(DVDCommandBlock* block, DVDCBCallback callback) { + int idle; - block->command = 14; - block->buffer = (void*)info; - block->length = sizeof(DVDDriveInfo); - block->transferred_size = 0; + block->command = DVD_COMMAND_CANCELSTREAM; block->callback = callback; - - idle = issueCommand(2, block); - + idle = issueCommand(1, block); return idle; } -/* 8034B138-8034B17C 345A78 0044+00 15/15 2/2 0/0 .text DVDReset */ +s32 DVDCancelStream(DVDCommandBlock* block) { + int result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDCancelStreamAsync(block, cbForCancelStreamSync); + if (result == 0) { + return -1; + } + enabled = OSDisableInterrupts(); + + while (1) { + state = block->state; + if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { + retVal = block->transferredSize; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForCancelStreamSync(s32 result, DVDCommandBlock* block) { + block->transferredSize = (u32)result; + OSWakeupThread(&__DVDThreadQueue); +} + +int DVDStopStreamAtEndAsync(DVDCommandBlock* block, DVDCBCallback callback) { + int idle; + + block->command = DVD_COMMAND_STOP_STREAM_AT_END; + block->callback = callback; + idle = issueCommand(1, block); + return idle; +} + +s32 DVDStopStreamAtEnd(DVDCommandBlock* block) { + int result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDStopStreamAtEndAsync(block, cbForStopStreamAtEndSync); + if (result == 0) { + return -1; + } + enabled = OSDisableInterrupts(); + + while (1) { + state = block->state; + if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { + retVal = block->transferredSize; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForStopStreamAtEndSync(s32 result, DVDCommandBlock* block) { + block->transferredSize = (u32)result; + OSWakeupThread(&__DVDThreadQueue); +} + +int DVDGetStreamErrorStatusAsync(DVDCommandBlock* block, DVDCBCallback callback) { + int idle; + + block->command = DVD_COMMAND_REQUEST_AUDIO_ERROR; + block->callback = callback; + idle = issueCommand(1, block); + return idle; +} + +s32 DVDGetStreamErrorStatus(DVDCommandBlock* block) { + int result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDGetStreamErrorStatusAsync(block, cbForGetStreamErrorStatusSync); + if (result == 0) { + return -1; + } + enabled = OSDisableInterrupts(); + + while (1) { + state = block->state; + if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { + retVal = block->transferredSize; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForGetStreamErrorStatusSync(s32 result, DVDCommandBlock* block) { + block->transferredSize = (u32)result; + OSWakeupThread(&__DVDThreadQueue); +} + +int DVDGetStreamPlayAddrAsync(DVDCommandBlock* block, DVDCBCallback callback) { + int idle; + + block->command = DVD_COMMAND_REQUEST_PLAY_ADDR; + block->callback = callback; + idle = issueCommand(1, block); + return idle; +} + +s32 DVDGetStreamPlayAddr(DVDCommandBlock* block) { + int result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDGetStreamPlayAddrAsync(block, cbForGetStreamPlayAddrSync); + if (result == 0) { + return -1; + } + enabled = OSDisableInterrupts(); + + while (1) { + state = block->state; + if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { + retVal = block->transferredSize; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForGetStreamPlayAddrSync(s32 result, DVDCommandBlock* block) { + block->transferredSize = (u32)result; + OSWakeupThread(&__DVDThreadQueue); +} + +int DVDGetStreamStartAddrAsync(DVDCommandBlock* block, DVDCBCallback callback) { + int idle; + + block->command = DVD_COMMAND_REQUEST_START_ADDR; + block->callback = callback; + idle = issueCommand(1, block); + return idle; +} + +s32 DVDGetStreamStartAddr(DVDCommandBlock* block) { + int result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDGetStreamStartAddrAsync(block, cbForGetStreamStartAddrSync); + if (result == 0) { + return -1; + } + enabled = OSDisableInterrupts(); + + while (1) { + state = block->state; + if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { + retVal = block->transferredSize; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForGetStreamStartAddrSync(s32 result, DVDCommandBlock* block) { + block->transferredSize = (u32)result; + OSWakeupThread(&__DVDThreadQueue); +} + +int DVDGetStreamLengthAsync(DVDCommandBlock* block, DVDCBCallback callback) { + int idle; + + block->command = DVD_COMMAND_REQUEST_LENGTH; + block->callback = callback; + idle = issueCommand(1, block); + return idle; +} + +s32 DVDGetStreamLength(DVDCommandBlock* block) { + int result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDGetStreamLengthAsync(block, cbForGetStreamLengthSync); + if (result == 0) { + return -1; + } + enabled = OSDisableInterrupts(); + + while (1) { + state = block->state; + if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { + retVal = block->transferredSize; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForGetStreamLengthSync(s32 result, DVDCommandBlock* block) { + block->transferredSize = (u32)result; + OSWakeupThread(&__DVDThreadQueue); +} + +void __DVDAudioBufferConfig(DVDCommandBlock* block, u32 enable, u32 size, DVDCBCallback callback) { + int idle; + + block->command = DVD_COMMAND_AUDIO_BUFFER_CONFIG; + block->offset = enable; + block->length = size; + block->callback = callback; + idle = issueCommand(2, block); +} + +int DVDChangeDiskAsyncForBS(DVDCommandBlock* block, DVDCBCallback callback) { + int idle; + + ASSERTMSGLINE(2869, block, "DVDChangeDiskAsyncForBS(): null pointer is specified to command block address."); + + block->command = DVD_COMMAND_BS_CHANGE_DISK; + block->callback = callback; + idle = issueCommand(2, block); + ASSERTMSGLINE(2875, idle, "DVDChangeDiskAsyncForBS(): command block is used for processing previous request."); + return idle; +} + +int DVDChangeDiskAsync(DVDCommandBlock* block, DVDDiskID* id, DVDCBCallback callback) { + int idle; + + ASSERTMSGLINE(2896, block, "DVDChangeDisk(): null pointer is specified to command block address."); + ASSERTMSGLINE(2897, id, "DVDChangeDisk(): null pointer is specified to id address."); + + if (id->company[0] == 0) { + OSReport("DVDChangeDiskAsync(): You can't specify NULL to company name. \n"); + DVD_ASSERTMSGLINE(2902, 0, ""); + } + + block->command = DVD_COMMAND_CHANGE_DISK; + block->id = id; + block->callback = callback; + DCInvalidateRange(bootInfo->FSTLocation, bootInfo->FSTMaxLength); + + idle = issueCommand(2, block); + ASSERTMSGLINE(2913, idle, "DVDChangeDisk(): command block is used for processing previous request."); + return idle; +} + +s32 DVDChangeDisk(DVDCommandBlock* block, DVDDiskID* id) { + int result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDChangeDiskAsync(block, id, cbForChangeDiskSync); + if (result == 0) { + return -1; + } + + enabled = OSDisableInterrupts(); + while (1) { + state = block->state; + if (state == DVD_STATE_END) { + retVal = 0; + break; + } else if (state == DVD_STATE_FATAL_ERROR) { + retVal = -1; + break; + } else if (state == DVD_STATE_CANCELED) { + retVal = -3; + break; + } + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForChangeDiskSync(s32 result, DVDCommandBlock* block) { + OSWakeupThread(&__DVDThreadQueue); +} + +int DVDStopMotorAsync(DVDCommandBlock* block, DVDCBCallback callback) { + int idle; + ASSERTMSGLINE(2996, block, "DVDStopMotor(): Null address was specified for block"); + + block->command = DVD_COMMAND_UNK_16; + block->callback = callback; + + idle = issueCommand(2, block); + ASSERTMSGLINE(3002, idle, "DVDStopMotor(): command block is used for processing previous request."); + return idle; +} + +s32 DVDStopMotor(DVDCommandBlock* block) { + int result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDStopMotorAsync(block, cbForStopMotorSync); + if (result == 0) { + return -1; + } + + enabled = OSDisableInterrupts(); + while (1) { + state = block->state; + if (state == DVD_STATE_END) { + retVal = 0; + break; + } else if (state == DVD_STATE_FATAL_ERROR) { + retVal = -1; + break; + } else if (state == DVD_STATE_CANCELED) { + retVal = -3; + break; + } + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForStopMotorSync(s32 result, DVDCommandBlock* block) { + OSWakeupThread(&__DVDThreadQueue); +} + +int DVDInquiryAsync(DVDCommandBlock* block, DVDDriveInfo* info, DVDCBCallback callback) { + int idle; + + ASSERTMSGLINE(3085, block, "DVDInquiry(): Null address was specified for block"); + ASSERTMSGLINE(3086, info, "DVDInquiry(): Null address was specified for info"); + ASSERTMSGLINE(3088, !OFFSET(info, 32), "DVDInquiry(): Address for info is not 32 bytes aligned"); + + block->command = DVD_COMMAND_INQUIRY; + block->addr = info; + block->length = 0x20; + block->transferredSize = 0; + block->callback = callback; + idle = issueCommand(2, block); + return idle; +} + +s32 DVDInquiry(DVDCommandBlock* block, DVDDriveInfo* info) { + int result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDInquiryAsync(block, info, cbForInquirySync); + if (result == 0) { + return -1; + } + + enabled = OSDisableInterrupts(); + while (1) { + state = block->state; + if (state == DVD_STATE_END) { + retVal = (u32)block->transferredSize; + break; + } else if (state == DVD_STATE_FATAL_ERROR) { + retVal = -1; + break; + } else if (state == DVD_STATE_CANCELED) { + retVal = -3; + break; + } + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForInquirySync(s32 result, DVDCommandBlock* block) { + OSWakeupThread(&__DVDThreadQueue); +} + void DVDReset(void) { DVDLowReset(); __DIRegs[0] = 0x2A; __DIRegs[1] = __DIRegs[1]; - ResetRequired = FALSE; + ResetRequired = 0; ResumeFromHere = 0; } -/* 8034B17C-8034B1C8 345ABC 004C+00 0/0 6/6 0/0 .text DVDGetCommandBlockStatus */ +int DVDResetRequired(void) { + return ResetRequired; +} + s32 DVDGetCommandBlockStatus(const DVDCommandBlock* block) { BOOL enabled; s32 retVal; + ASSERTMSGLINE(3197, block, "DVDGetCommandBlockStatus(): null pointer is specified to command block address."); enabled = OSDisableInterrupts(); - if (block->state == 3) { - retVal = 1; - } else { - retVal = block->state; - } + if (block->state == 3) { + retVal = 1; + } else { + retVal = block->state; + } - OSRestoreInterrupts(enabled); - - return retVal; + OSRestoreInterrupts(enabled); + return retVal; } -/* 8034B1C8-8034B274 345B08 00AC+00 0/0 7/7 0/0 .text DVDGetDriveStatus */ -s32 DVDGetDriveStatus() { - BOOL enabled; - s32 retVal; - DVDCommandBlock* cmd; - - enabled = OSDisableInterrupts(); - - if (FatalErrorFlag) { - retVal = -1; - } else if (PausingFlag) { - retVal = 8; - } else { - cmd = executing; - if (cmd == (DVDCommandBlock*)NULL) { - retVal = 0; - } else if (cmd == &DummyCommandBlock) { - retVal = 0; - } else { - retVal = DVDGetCommandBlockStatus(executing); - } - } - - OSRestoreInterrupts(enabled); - - return retVal; +s32 DVDGetDriveStatus(void) { + BOOL enabled = OSDisableInterrupts(); + s32 retVal; + + if (FatalErrorFlag != FALSE) { + retVal = DVD_STATE_FATAL_ERROR; + } else { + if (PausingFlag != FALSE) { + retVal = DVD_STATE_PAUSING; + } else { + if (executing == NULL) { + retVal = DVD_STATE_END; + } else if (executing == &DummyCommandBlock) { + retVal = DVD_STATE_END; + } else { + retVal = DVDGetCommandBlockStatus((DVDCommandBlock*)executing); + } + } + } + OSRestoreInterrupts(enabled); + return retVal; } -/* 8034B274-8034B284 345BB4 0010+00 0/0 1/1 0/0 .text DVDSetAutoInvalidation */ BOOL DVDSetAutoInvalidation(BOOL autoInval) { BOOL prev; + prev = autoInvalidation; autoInvalidation = autoInval; return prev; } -/* 8034B284-8034B2D4 345BC4 0050+00 0/0 1/1 0/0 .text DVDResume */ +void DVDPause(void) { + BOOL level; + + level = OSDisableInterrupts(); + PauseFlag = 1; + if (executing == NULL) { + PausingFlag = 1; + } + OSRestoreInterrupts(level); +} + void DVDResume(void) { BOOL level; + level = OSDisableInterrupts(); - PauseFlag = FALSE; - if (PausingFlag) { - PausingFlag = FALSE; + PauseFlag = 0; + if (PausingFlag != 0) { + PausingFlag = 0; stateReady(); } OSRestoreInterrupts(level); } -/* ############################################################################################## */ -/* 803D15F8-803D163C 02E718 0041+03 0/0 0/0 0/0 .data @789 */ -static char string_DVDChangeDiskAsyncMsg[] = - "DVDChangeDiskAsync(): You can't specify NULL to company name. \n"; +int DVDCancelAsync(DVDCommandBlock* block, DVDCBCallback callback) { + BOOL enabled; + DVDLowCallback old; + DVDCommandBlock* finished; -/* 8034B2D4-8034B550 345C14 027C+00 3/2 0/0 0/0 .text DVDCancelAsync */ -BOOL DVDCancelAsync(DVDCommandBlock* block, DVDCBCallback callback) { - BOOL enabled; - DVDLowCallback old; - s32 state; + enabled = OSDisableInterrupts(); - enabled = OSDisableInterrupts(); + switch (block->state) { + case DVD_STATE_FATAL_ERROR: + case DVD_STATE_END: + case DVD_STATE_CANCELED: + if (callback) + (*callback)(0, block); + break; + case DVD_STATE_BUSY: + if (Canceling) { + OSRestoreInterrupts(enabled); + return FALSE; + } - state = block->state; - switch (state) { - case -1: - case 0: - case 10: - if (callback) - (*callback)(0, block); - break; + Canceling = TRUE; + CancelCallback = callback; + if (block->command == DVD_COMMAND_BSREAD || block->command == DVD_COMMAND_READ) { + DVDLowBreak(); + } + break; + case DVD_STATE_WAITING: + __DVDDequeueWaitingQueue(block); + block->state = DVD_STATE_CANCELED; - case 1: - if (Canceling) { - OSRestoreInterrupts(enabled); - return FALSE; - } + if (block->callback) + (block->callback)(-3, block); - Canceling = TRUE; - CancelCallback = callback; - if (block->command == 4 || block->command == 1) { - DVDLowBreak(); - } - break; + if (callback) + (*callback)(0, block); + break; + case DVD_STATE_COVER_CLOSED: + switch (block->command) { + case DVD_COMMAND_READID: + case DVD_COMMAND_BSREAD: + case DVD_COMMAND_AUDIO_BUFFER_CONFIG: + case DVD_COMMAND_BS_CHANGE_DISK: + if (callback) + (*callback)(0, block); + break; - case 2: - __DVDDequeueWaitingQueue(block); - block->state = 10; - if (block->callback) - (block->callback)(-3, block); - if (callback) - (*callback)(0, block); - break; + default: + if (Canceling) { + OSRestoreInterrupts(enabled); + return FALSE; + } + Canceling = TRUE; + CancelCallback = callback; + break; + } + break; + case DVD_STATE_NO_DISK: + case DVD_STATE_COVER_OPEN: + case DVD_STATE_WRONG_DISK: + case DVD_STATE_MOTOR_STOPPED: + case DVD_STATE_RETRY: + old = DVDLowClearCallback(); + ASSERTLINE(3418, old == cbForStateMotorStopped); - case 3: - switch (block->command) { - case 5: - case 4: - case 13: - case 15: - if (callback) - (*callback)(0, block); - break; + if (old != cbForStateMotorStopped) { + OSRestoreInterrupts(enabled); + return FALSE; + } - default: - if (Canceling) { - OSRestoreInterrupts(enabled); - return FALSE; - } - Canceling = TRUE; - CancelCallback = callback; - break; - } - break; - - case 4: - case 5: - case 6: - case 7: - case 11: - old = DVDLowClearCallback(); - if (old != cbForStateMotorStopped) { - OSRestoreInterrupts(enabled); - return FALSE; - } - - if (block->state == 4) - ResumeFromHere = 3; - if (block->state == 5) - ResumeFromHere = 4; - if (block->state == 6) - ResumeFromHere = 1; - if (block->state == 11) - ResumeFromHere = 2; - if (block->state == 7) - ResumeFromHere = 7; + if (block->state == DVD_STATE_NO_DISK) + ResumeFromHere = 3; + if (block->state == DVD_STATE_COVER_OPEN) + ResumeFromHere = 4; + if (block->state == DVD_STATE_WRONG_DISK) + ResumeFromHere = 1; + if (block->state == DVD_STATE_RETRY) + ResumeFromHere = 2; + if (block->state == DVD_STATE_MOTOR_STOPPED) + ResumeFromHere = 7; + finished = executing; executing = &DummyCommandBlock; - block->state = 10; - if (block->callback) { - (block->callback)(-3, block); - } - if (callback) { - (callback)(0, block); - } - stateReady(); - break; - } + block->state = DVD_STATE_CANCELED; + if (block->callback) { + (block->callback)(-3, block); + } - OSRestoreInterrupts(enabled); - return TRUE; + if (callback) { + (callback)(0, block); + } + stateReady(); + break; + } + + OSRestoreInterrupts(enabled); + return TRUE; } -/* 8034B550-8034B5FC 345E90 00AC+00 0/0 1/1 1/1 .text DVDCancel */ -s32 DVDCancel(DVDCommandBlock* block) { - BOOL result; +s32 DVDCancel(volatile DVDCommandBlock* block) { + int result; s32 state; u32 command; BOOL enabled; - result = DVDCancelAsync(block, cbForCancelSync); - - if (result == FALSE) { + result = DVDCancelAsync((void*)block, cbForCancelSync); + if (result == 0) { return -1; } enabled = OSDisableInterrupts(); - - for (;;) { - state = ((volatile DVDCommandBlock*)block)->state; - - if ((state == 0) || (state == -1) || (state == 10)) { + while (1) { + state = block->state; + if (state == DVD_STATE_END || state == DVD_STATE_FATAL_ERROR || state == DVD_STATE_CANCELED) { break; } - if (state == 3) { - command = ((volatile DVDCommandBlock*)block)->command; - - if ((command == 4) || (command == 5) || (command == 13) || (command == 15)) { + if (state == DVD_STATE_COVER_CLOSED) { + command = block->command; + if ((command == DVD_COMMAND_BSREAD) || (command == DVD_COMMAND_READID) || (command == DVD_COMMAND_AUDIO_BUFFER_CONFIG) || (command == DVD_COMMAND_BS_CHANGE_DISK)) { break; } } - OSSleepThread(&__DVDThreadQueue); } @@ -1324,104 +1710,28 @@ s32 DVDCancel(DVDCommandBlock* block) { return 0; } -/* 8034B5FC-8034B620 345F3C 0024+00 1/1 0/0 0/0 .text cbForCancelSync */ static void cbForCancelSync(s32 result, DVDCommandBlock* block) { OSWakeupThread(&__DVDThreadQueue); } -/* 8034B620-8034B628 345F60 0008+00 0/0 3/3 0/0 .text DVDGetCurrentDiskID */ -DVDDiskID* DVDGetCurrentDiskID(void) { - return (DVDDiskID*)OSPhysicalToCached(0); -} - -/* ############################################################################################## */ - -/* 8034B628-8034B720 345F68 00F8+00 1/0 4/4 0/0 .text DVDCheckDisk */ -BOOL DVDCheckDisk(void) { - BOOL enabled; - s32 retVal; - s32 state; - u32 coverReg; - - enabled = OSDisableInterrupts(); - - if (FatalErrorFlag) { - state = -1; - } else if (PausingFlag) { - state = 8; - } else { - if (executing == (DVDCommandBlock*)NULL) { - state = 0; - } else if (executing == &DummyCommandBlock) { - state = 0; - } else { - state = executing->state; - } - } - - switch (state) { - case 1: - case 9: - case 10: - case 2: - retVal = TRUE; - break; - - case -1: - case 11: - case 7: - case 3: - case 4: - case 5: - case 6: - retVal = FALSE; - break; - - case 0: - case 8: - coverReg = __DIRegs[1]; - if (((coverReg >> 2) & 1) || (coverReg & 1)) { - retVal = FALSE; - } else if (ResumeFromHere) { - retVal = 0; - } else { - retVal = 1; - } - } - - OSRestoreInterrupts(enabled); - - return retVal; -} - -void DVDPause(void) { - BOOL level; - level = OSDisableInterrupts(); - PauseFlag = TRUE; - if (executing == (DVDCommandBlock*)NULL) { - PausingFlag = TRUE; - } - OSRestoreInterrupts(level); -} - -BOOL DVDCancelAllAsync(DVDCBCallback callback) { +int DVDCancelAllAsync(DVDCBCallback callback) { BOOL enabled; DVDCommandBlock* p; - BOOL retVal; + int retVal; enabled = OSDisableInterrupts(); DVDPause(); - - while ((p = __DVDPopWaitingQueue()) != 0) { + while ((p = __DVDPopWaitingQueue())) { DVDCancelAsync(p, NULL); } - if (executing) + if (executing) { retVal = DVDCancelAsync(executing, callback); - else { - retVal = TRUE; - if (callback) - (*callback)(0, NULL); + } else { + retVal = 1; + if (callback) { + callback(0, NULL); + } } DVDResume(); @@ -1429,32 +1739,116 @@ BOOL DVDCancelAllAsync(DVDCBCallback callback) { return retVal; } -/* 8034B720-8034B83C 346060 011C+00 0/0 1/1 0/0 .text __DVDPrepareResetAsync */ -void __DVDPrepareResetAsync(DVDCBCallback callback) { +s32 DVDCancelAll(void) { + int result; BOOL enabled; enabled = OSDisableInterrupts(); + CancelAllSyncComplete = 0; + result = DVDCancelAllAsync(cbForCancelAllSync); + if (result == 0) { + OSRestoreInterrupts(enabled); + return -1; + } - __DVDClearWaitingQueue(); - - if (Canceling) { - CancelCallback = callback; - } else { - if (executing) { - executing->callback = NULL; + while (1) { + if (CancelAllSyncComplete == 0) { + OSSleepThread(&__DVDThreadQueue); + } else { + break; } - - DVDCancelAllAsync(callback); } OSRestoreInterrupts(enabled); + return 0; } -/* 8034B83C-8034B874 34617C 0038+00 0/0 1/1 0/0 .text __DVDTestAlarm */ -BOOL __DVDTestAlarm(OSAlarm* alarm) { - if (alarm == &ResetAlarm) { - return TRUE; - } +static void cbForCancelAllSync(s32 result, DVDCommandBlock* block) { + CancelAllSyncComplete = 1; + OSWakeupThread(&__DVDThreadQueue); +} +DVDDiskID* DVDGetCurrentDiskID(void) { + return (void*)OSPhysicalToCached(0); +} + +BOOL DVDCheckDisk(void) { + BOOL enabled; + s32 retVal; + s32 state; + u32 coverReg; + + enabled = OSDisableInterrupts(); + + if (FatalErrorFlag) { + state = -1; + } else if (PausingFlag) { + state = 8; + } else { + if (executing == NULL) { + state = 0; + } else if (executing == &DummyCommandBlock) { + state = 0; + } else { + state = executing->state; + } + } + + switch (state) { + case DVD_STATE_BUSY: + case DVD_STATE_IGNORED: + case DVD_STATE_CANCELED: + case DVD_STATE_WAITING: + retVal = TRUE; + break; + case DVD_STATE_FATAL_ERROR: + case DVD_STATE_RETRY: + case DVD_STATE_MOTOR_STOPPED: + case DVD_STATE_COVER_CLOSED: + case DVD_STATE_NO_DISK: + case DVD_STATE_COVER_OPEN: + case DVD_STATE_WRONG_DISK: + retVal = FALSE; + break; + case DVD_STATE_END: + case DVD_STATE_PAUSING: + coverReg = __DIRegs[1]; + if (((coverReg >> 2) & 1) || (coverReg & 1)) { + retVal = FALSE; + } else if (ResumeFromHere != 0) { + retVal = FALSE; + } else { + retVal = TRUE; + } + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +void __DVDPrepareResetAsync(DVDCBCallback callback) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + + __DVDClearWaitingQueue(); + + if (Canceling) { + CancelCallback = callback; + } else { + if (executing) { + executing->callback = NULL; + } + + DVDCancelAllAsync(callback); + } + + OSRestoreInterrupts(enabled); +} + +int __DVDTestAlarm(const OSAlarm* alarm) { + if (alarm == &ResetAlarm) { + return 1; + } return __DVDLowTestAlarm(alarm); -} \ No newline at end of file +} diff --git a/src/dolphin/dvd/dvdFatal.c b/src/dolphin/dvd/dvdFatal.c index 4759de77f1..abb3a64f3c 100644 --- a/src/dolphin/dvd/dvdFatal.c +++ b/src/dolphin/dvd/dvdFatal.c @@ -1,13 +1,95 @@ -#include "dolphin/dvd/dvdFatal.h" -#include "dolphin/types.h" +#include +#include -/* 804517C8-804517D0 000CC8 0004+04 1/1 0/0 0/0 .sbss FatalFunc */ -static void (*FatalFunc)(void) = NULL; +#include "__dvd.h" -/* 8034BCFC-8034BD2C 34663C 0030+00 0/0 1/1 0/0 .text __DVDPrintFatalMessage */ -void __DVDPrintFatalMessage(void) { - if (!FatalFunc) { - return; +static void (*FatalFunc)(); + +const char* Japanese = + "\n\n\nエラーが発生しました。\n\n" + "本体のパワーボタンを押して電源をOFFにし、\n" + "本体の取扱説明書の指示に従ってください。"; + +const char* English = + "\n\n\nAn error has occurred.\n" + "Turn the power off and refer to the\n" + "Nintendo GameCube Instruction Booklet\n" + "for further instructions."; + +// TODO: need solution to compile special characters in a cleaner way +const char* const Europe[6] = { + { + "\n\n\nAn error has occurred.\n" + "Turn the power off and refer to the\n" + "Nintendo GameCube Instruction Booklet\n" + "for further instructions." + }, + { + "\n\n\nEin Fehler ist aufgetreten.\n" + "Bitte schalten Sie den Nintendo GameCube\n" + "aus und lesen Sie die Bedienungsanleitung,\n" + "um weitere Informationen zu erhalten." + }, + { + "\n\n\nUne erreur est survenue.\n" + "Eteignez la console et r\xE9" "f" "\xE9rez-vous au\n" + "manuel d'instructions Nintendo GameCube\n" + "pour de plus amples informations." + }, + { + "\n\n\nSe ha producido un error.\n" + "Apaga la consola y consulta el manual\n" + "de instrucciones de Nintendo GameCube\n" + "para obtener m\xE1" "s informaci\xF3" "n." + }, + { + "\n\n\nSi \xE8" " verificato un errore.\n" + "Spegni (OFF) e controlla il manuale\n" + "d'istruzioni del Nintendo GameCube\n" + "per ulteriori indicazioni." + }, + { + "\n\n\nEr is een fout opgetreden.\n" + "Zet de Nintendo GameCube uit en\n" + "raadpleeg de handleiding van de\n" + "Nintendo GameCube voor nadere\n" + "instructies." + }, +}; + +static void ShowMessage(void) { + const char* message; + GXColor bg = {0x00, 0x00, 0x00, 0x00}; + GXColor fg = {0xFF, 0xFF, 0xFF, 0x00}; + + if (VIGetTvFormat() == VI_NTSC) { + if (OSGetFontEncode() == OS_FONT_ENCODE_SJIS) { + message = Japanese; + } else { + message = English; + } + } else { + message = Europe[OSGetLanguage()]; } - FatalFunc(); -} \ No newline at end of file + + OSFatal(fg, bg, message); +} + +int DVDSetAutoFatalMessaging(BOOL enable) { + BOOL enabled; + int prev; + + enabled = OSDisableInterrupts(); + + prev = FatalFunc ? 1 : 0; + FatalFunc = enable ? ShowMessage : NULL; + + OSRestoreInterrupts(enabled); + return prev; +} + +void __DVDPrintFatalMessage(void) { + if (FatalFunc) { + FatalFunc(); + } +} diff --git a/src/dolphin/dvd/dvderror.c b/src/dolphin/dvd/dvderror.c index 7c6f98bacd..894312ed1d 100644 --- a/src/dolphin/dvd/dvderror.c +++ b/src/dolphin/dvd/dvderror.c @@ -1,62 +1,77 @@ -#include "dolphin/dvd/dvderror.h" -#include "dolphin/os/OSRtc.h" +#include +#include +#include -static u8 ErrorCode2Num(u32 errorCode); -void __DVDStoreErrorCode(); +#include "os/__os.h" +#include "__dvd.h" -/* 803D16A8-803D16F0 02E7C8 0048+00 1/1 0/0 0/0 .data ErrorTable */ -static u32 ErrorTable[] = { - 0, 0x00023A00, 0x00062800, 0x00030200, 0x00031100, 0x00052000, - 0x00052001, 0x00052100, 0x00052400, 0x00052401, 0x00052402, 0x000B5A01, - 0x00056300, 0x00020401, 0x00020400, 0x00040800, 0x00100007, 0, +static u32 ErrorTable[18] = { + 0x00000000, + 0x00023A00, + 0x00062800, + 0x00030200, + 0x00031100, + 0x00052000, + 0x00052001, + 0x00052100, + 0x00052400, + 0x00052401, + 0x00052402, + 0x000B5A01, + 0x00056300, + 0x00020401, + 0x00020400, + 0x00040800, + 0x00100007, + 0x00000000, }; -/* 8034BA6C-8034BB88 3463AC 011C+00 1/1 0/0 0/0 .text ErrorCode2Num */ +#define DIDNT_MATCH 29 + static u8 ErrorCode2Num(u32 errorCode) { - u32 i; + u32 i; - for (i = 0; i < sizeof(ErrorTable) / sizeof(ErrorTable[0]); i++) { - if (ErrorTable[i] == errorCode) { - return (u8)i; - } - } + for (i = 0; i < 18; i++) { + if (errorCode == ErrorTable[i]) { + ASSERTLINE(73, i < DIDNT_MATCH); + return i; + } + } - if ((errorCode >= 0x00100000) && (errorCode <= 0x00100008)) { - return 17; - } + if (errorCode >= 0x100000 && errorCode <= 0x100008) { + return 17; + } - return 29; + return DIDNT_MATCH; } -/* 8034BB88-8034BC04 3464C8 007C+00 0/0 12/12 0/0 .text __DVDStoreErrorCode */ static u8 Convert(u32 error) { u32 statusCode; u32 errorCode; u8 errorNum; - if (error == 0x01234567) - return 255; - - if (error == 0x01234568) - return 254; - - statusCode = (error & 0xff000000) >> 24; - errorCode = error & 0x00ffffff; + if (error == 0x01234567) { + return -1; + } else if (error == 0x01234568) { + return -2; + } + statusCode = (error >> 24) & 0xFF; + errorCode = error & 0x00FFFFFF; errorNum = ErrorCode2Num(errorCode); - if (statusCode >= 6) + if (statusCode >= 6) { statusCode = 6; + } - return (u8)(statusCode * 30 + errorNum); + return statusCode * 30 + errorNum; } void __DVDStoreErrorCode(u32 error) { - OSSramEx* sram; + OSSramEx* sram; u8 num; num = Convert(error); - - sram = __OSLockSramEx(); - sram->dvdErrorCode = num; - __OSUnlockSramEx(TRUE); -} \ No newline at end of file + sram = __OSLockSramEx(); + sram->dvdErrorCode = num; + __OSUnlockSramEx(TRUE); +} diff --git a/src/dolphin/dvd/dvdfs.c b/src/dolphin/dvd/dvdfs.c index 1ba29d3e0a..4a0a28282f 100644 --- a/src/dolphin/dvd/dvdfs.c +++ b/src/dolphin/dvd/dvdfs.c @@ -1,65 +1,44 @@ -#include "dolphin/dvd/dvdfs.h" -#include "dolphin/dvd.h" -#include "dolphin/os.h" +#include +#include -void __DVDFSInit(); -int DVDConvertPathToEntrynum(const char* path); -int DVDFastOpen(long entryNum, DVDFileInfo* info); -BOOL DVDOpen(const char* filename, DVDFileInfo* fileinfo); -BOOL DVDClose(DVDFileInfo* fileinfo); -static u32 entryToPath(u32 entry, char* path, u32 maxlen); -static BOOL DVDConvertEntrynumToPath(s32 entrynum, char* path, u32 maxlen); -static BOOL DVDGetCurrentDir(char* path, u32 maxlen); -BOOL DVDChangeDir(const char* dirname); -BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, - DVDCallback callback, s32 prio); -static void cbForReadAsync(); -int DVDReadPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, s32 prio); -static void cbForReadSync(); -BOOL DVDOpenDir(const char*, DVDDirectory* dir); -BOOL DVDReadDir(DVDDirectory* dir, DVDDirectoryEntry* entry); -BOOL DVDCloseDir(); +#include "__dvd.h" -typedef struct FSTEntry FSTEntry; +typedef struct FSTEntry { + /* 0x00 */ unsigned int isDirAndStringOff; + /* 0x04 */ unsigned int parentOrPosition; + /* 0x08 */ unsigned int nextEntryOrLength; +} FSTEntry; -struct FSTEntry { - unsigned int isDirAndStringOff; - unsigned int parentOrPosition; - unsigned int nextEntryOrLength; -}; - -/* 80451758-8045175C 000C58 0004+00 1/1 0/0 0/0 .sbss BootInfo */ static OSBootInfo* BootInfo; - -/* 8045175C-80451760 000C5C 0004+00 10/10 0/0 0/0 .sbss FstStart */ static FSTEntry* FstStart; - -/* 80451760-80451764 000C60 0004+00 5/5 0/0 0/0 .sbss FstStringStart */ static char* FstStringStart; - -/* 80451764-80451768 000C64 0004+00 2/2 0/0 0/0 .sbss MaxEntryNum */ -static unsigned int MaxEntryNum; - -/* 803484F0-80348528 342E30 0038+00 0/0 2/2 0/0 .text __DVDFSInit */ -void __DVDFSInit() { - BootInfo = (OSBootInfo*)OSPhysicalToCached(0); - FstStart = (FSTEntry*)BootInfo->fst_location; - - if (FstStart) { - MaxEntryNum = FstStart[0].nextEntryOrLength; - FstStringStart = (char*)&(FstStart[MaxEntryNum]); - } -} - -/* 80451768-8045176C 000C68 0004+00 4/4 0/0 0/0 .sbss currentDirectory */ +static u32 MaxEntryNum; static u32 currentDirectory; -/* 80451770-80451778 000C70 0008+00 2/2 3/3 0/0 .sbss __DVDThreadQueue */ OSThreadQueue __DVDThreadQueue; - -/* 8045176C-80451770 000C6C 0004+00 1/1 1/1 0/0 .sbss __DVDLongFileNameFlag */ u32 __DVDLongFileNameFlag; +// prototypes +static BOOL isSame(const char* path, const char* string); +static u32 myStrncpy(char* dest, char* src, u32 maxlen); +static u32 entryToPath(u32 entry, char* path, u32 maxlen); +static BOOL DVDConvertEntrynumToPath(s32 entrynum, char* path, u32 maxlen); +static void cbForReadAsync(s32 result, DVDCommandBlock* block); +static void cbForReadSync(s32 result, DVDCommandBlock* block); +static void cbForSeekAsync(s32 result, DVDCommandBlock* block); +static void cbForSeekSync(s32 result, DVDCommandBlock* block); +static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock* block); +static void cbForPrepareStreamSync(s32 result, DVDCommandBlock* block); + +void __DVDFSInit(void) { + BootInfo = (void*)OSPhysicalToCached(0); + FstStart = BootInfo->FSTLocation; + if (FstStart) { + MaxEntryNum = FstStart->nextEntryOrLength; + FstStringStart = (char*)FstStart + (MaxEntryNum* sizeof(FSTEntry)); + } +} + /* For convenience */ #define entryIsDir(i) (((FstStart[i].isDirAndStringOff & 0xff000000) == 0) ? FALSE : TRUE) #define stringOff(i) (FstStart[i].isDirAndStringOff & ~0xff000000) @@ -74,16 +53,15 @@ static BOOL isSame(const char* path, const char* string) { return FALSE; } } - - if ((*path == '/') || (*path == '\0')) { + + if (*path == '/' || *path == '\0') { return TRUE; } - + return FALSE; } -/* 80348528-8034881C 342E68 02F4+00 3/3 6/6 0/0 .text DVDConvertPathToEntrynum */ -int DVDConvertPathToEntrynum(const char* pathPtr) { +s32 DVDConvertPathToEntrynum(const char* pathPtr) { const char* ptr; char* stringPtr; BOOL isDir; @@ -94,9 +72,11 @@ int DVDConvertPathToEntrynum(const char* pathPtr) { const char* extentionStart; BOOL illegal; BOOL extention; - + + ASSERTMSGLINE(318, pathPtr, "DVDConvertPathToEntrynum(): null pointer is specified "); + dirLookAt = currentDirectory; - + while (1) { if (*pathPtr == '\0') { return (s32)dirLookAt; @@ -120,11 +100,11 @@ int DVDConvertPathToEntrynum(const char* pathPtr) { return (s32)dirLookAt; } } - + if (__DVDLongFileNameFlag == 0) { extention = FALSE; illegal = FALSE; - + for (ptr = pathPtr; (*ptr != '\0') && (*ptr != '/'); ptr++) { if (*ptr == '.') { if ((ptr - pathPtr > 8) || (extention == TRUE)) { @@ -133,195 +113,203 @@ int DVDConvertPathToEntrynum(const char* pathPtr) { } extention = TRUE; extentionStart = ptr + 1; - + } else if (*ptr == ' ') illegal = TRUE; } - + if ((extention == TRUE) && (ptr - extentionStart > 3)) illegal = TRUE; - + if (illegal) OSPanic(__FILE__, 387, - "DVDConvertEntrynumToPath(possibly DVDOpen or DVDChangeDir or DVDOpenDir): " - "specified directory " - "or file (%s) doesn't match standard 8.3 format. This is a temporary " - "restriction and will be " - "removed soon\n", - origPathPtr); + "DVDConvertEntrynumToPath(possibly DVDOpen or DVDChangeDir or DVDOpenDir): " + "specified directory or file (%s) doesn't match standard 8.3 format. This is a " + "temporary restriction and will be removed soon\n", + origPathPtr); } else { for (ptr = pathPtr; (*ptr != '\0') && (*ptr != '/'); ptr++) ; } - + isDir = (*ptr == '\0') ? FALSE : TRUE; length = (u32)(ptr - pathPtr); - + ptr = pathPtr; - + for (i = dirLookAt + 1; i < nextDir(dirLookAt); i = entryIsDir(i) ? nextDir(i) : (i + 1)) { if ((entryIsDir(i) == FALSE) && (isDir == TRUE)) { continue; } - + stringPtr = FstStringStart + stringOff(i); - + if (isSame(ptr, stringPtr) == TRUE) { goto next_hier; } } - + return -1; - - next_hier: + +next_hier: if (!isDir) { return (s32)i; } - + dirLookAt = i; pathPtr += length + 1; } } -/* 8034881C-80348890 34315C 0074+00 0/0 3/3 0/0 .text DVDFastOpen */ -int DVDFastOpen(s32 entrynum, DVDFileInfo* fileInfo) { - if ((entrynum < 0) || (entrynum >= MaxEntryNum) || entryIsDir(entrynum)) { +BOOL DVDFastOpen(s32 entrynum, DVDFileInfo* fileInfo) { + ASSERTMSGLINE(455, fileInfo, "DVDFastOpen(): null pointer is specified to file info address "); + ASSERTMSG1LINE(458, (entrynum >= 0) && ((u32) entrynum < (u32) MaxEntryNum), "DVDFastOpen(): specified entry number '%d' is out of range ", entrynum); + ASSERTMSG1LINE(461, !entryIsDir(entrynum), "DVDFastOpen(): entry number '%d' is assigned to a directory ", entrynum); + + if (entrynum < 0 || entrynum >= MaxEntryNum || entryIsDir(entrynum)) { return FALSE; } - - fileInfo->start_address = filePosition(entrynum); + + fileInfo->startAddr = filePosition(entrynum); fileInfo->length = fileLength(entrynum); fileInfo->callback = (DVDCallback)NULL; - fileInfo->block.state = DVD_STATE_END; - + fileInfo->cb.state = DVD_STATE_END; + return TRUE; } -/* 80348890-80348958 3431D0 00C8+00 0/0 3/3 1/1 .text DVDOpen */ BOOL DVDOpen(const char* fileName, DVDFileInfo* fileInfo) { s32 entry; char currentDir[128]; - + + ASSERTMSGLINE(491, fileName, "DVDOpen(): null pointer is specified to file name "); + ASSERTMSGLINE(492, fileInfo, "DVDOpen(): null pointer is specified to file info address "); + entry = DVDConvertPathToEntrynum(fileName); - + if (0 > entry) { DVDGetCurrentDir(currentDir, 128); OSReport("Warning: DVDOpen(): file '%s' was not found under %s.\n", fileName, currentDir); return FALSE; } - + if (entryIsDir(entry)) { + ASSERTMSG1LINE(506, !entryIsDir(entry), "DVDOpen(): directory '%s' is specified as a filename ", fileName); return FALSE; } - - fileInfo->start_address = filePosition(entry); + + fileInfo->startAddr = filePosition(entry); fileInfo->length = fileLength(entry); fileInfo->callback = (DVDCallback)NULL; - fileInfo->block.state = DVD_STATE_END; - + fileInfo->cb.state = DVD_STATE_END; + return TRUE; } -/* 80348958-8034897C 343298 0024+00 0/0 4/4 2/2 .text DVDClose */ BOOL DVDClose(DVDFileInfo* fileInfo) { - DVDCancel(&(fileInfo->block)); + ASSERTMSGLINE(530, fileInfo, "DVDClose(): null pointer is specified to file info address "); + DVDCancel(&(fileInfo->cb)); return TRUE; } static u32 myStrncpy(char* dest, char* src, u32 maxlen) { u32 i = maxlen; - + while ((i > 0) && (*src != 0)) { *dest++ = *src++; i--; } - + return (maxlen - i); } -/* 8034897C-80348ADC 3432BC 0160+00 2/2 0/0 0/0 .text entryToPath */ static u32 entryToPath(u32 entry, char* path, u32 maxlen) { char* name; u32 loc; - + if (entry == 0) { return 0; } - + name = FstStringStart + stringOff(entry); - + loc = entryToPath(parentDir(entry), path, maxlen); - + if (loc == maxlen) { return loc; } - + *(path + loc++) = '/'; - + loc += myStrncpy(path + loc, name, maxlen - loc); - + return loc; } -/* 80348ADC-80348C30 34341C 0154+00 1/1 0/0 0/0 .text DVDConvertEntrynumToPath */ static BOOL DVDConvertEntrynumToPath(s32 entrynum, char* path, u32 maxlen) { u32 loc; - + + ASSERTMSG1LINE(622, (entrynum >= 0) && (entrynum < MaxEntryNum), "DVDConvertEntrynumToPath: specified entrynum(%d) is out of range ", entrynum); + ASSERTMSG1LINE(624, maxlen > 1, "DVDConvertEntrynumToPath: maxlen should be more than 1 (%d is specified)", maxlen); + ASSERTMSGLINE(629, entryIsDir(entrynum), "DVDConvertEntrynumToPath: cannot convert an entry num for a file to path "); + loc = entryToPath((u32)entrynum, path, maxlen); - + if (loc == maxlen) { path[maxlen - 1] = '\0'; return FALSE; } - + if (entryIsDir(entrynum)) { if (loc == maxlen - 1) { path[loc] = '\0'; return FALSE; } - + path[loc++] = '/'; } - + path[loc] = '\0'; return TRUE; } -/* 80348C30-80348CF4 343570 00C4+00 1/1 0/0 0/0 .text DVDGetCurrentDir */ BOOL DVDGetCurrentDir(char* path, u32 maxlen) { + ASSERTMSG1LINE(671, (maxlen > 1), "DVDGetCurrentDir: maxlen should be more than 1 (%d is specified)", maxlen); return DVDConvertEntrynumToPath((s32)currentDirectory, path, maxlen); } -/* 80348CF4-80348D54 343634 0060+00 0/0 2/2 0/0 .text DVDChangeDir */ BOOL DVDChangeDir(const char* dirName) { s32 entry; + char currentDir[128]; + + ASSERTMSGLINE(693, dirName, "DVDChangeDir(): null pointer is specified to directory name "); entry = DVDConvertPathToEntrynum(dirName); - if ((entry < 0) || (entryIsDir(entry) == FALSE)) { + ASSERTMSG2LINE(701, entry >= 0, "DVDChangeDir(): directory '%s' is not found under %s ", dirName, (DVDGetCurrentDir(currentDir, 128), currentDir)); + ASSERTMSG1LINE(705, entryIsDir(entry), "DVDChangeDir(): file '%s' is specified as a directory name ", dirName); + + if (entry < 0 || entryIsDir(entry) == FALSE) { return FALSE; } - + currentDirectory = (u32)entry; - + return TRUE; } -#define DVD_MIN_TRANSFER_SIZE 32 - -/* 80348D54-80348E14 343694 00C0+00 0/0 2/2 0/0 .text DVDReadAsyncPrio */ -BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, - DVDCallback callback, s32 prio) { - if (!((0 <= offset) && (offset <= fileInfo->length))) { - OSPanic(__FILE__, 750, "DVDReadAsync(): specified area is out of the file "); - } - - if (!((0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE))) { - OSPanic(__FILE__, 756, "DVDReadAsync(): specified area is out of the file "); - } +BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, DVDCallback callback, s32 prio) { + ASSERTMSGLINE(736, fileInfo, "DVDReadAsync(): null pointer is specified to file info address "); + ASSERTMSGLINE(737, addr, "DVDReadAsync(): null pointer is specified to addr "); + ASSERTMSGLINE(741, !OFFSET(addr, 32), "DVDReadAsync(): address must be aligned with 32 byte boundaries "); + ASSERTMSGLINE(743, !(length & 0x1F), "DVDReadAsync(): length must be multiple of 32 byte "); + ASSERTMSGLINE(745, !(offset & 3), "DVDReadAsync(): offset must be multiple of 4 byte "); + DVD_ASSERTMSGLINE(750, (0 <= offset) && (offset <= fileInfo->length), "DVDReadAsync(): specified area is out of the file "); + + DVD_ASSERTMSGLINE(756, (0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE), "DVDReadAsync(): specified area is out of the file "); + fileInfo->callback = callback; - DVDReadAbsAsyncPrio(&(fileInfo->block), addr, length, (s32)(fileInfo->start_address + offset), + DVDReadAbsAsyncPrio(&(fileInfo->cb), addr, length, (s32)(fileInfo->startAddr + offset), cbForReadAsync, prio); - return TRUE; } @@ -329,59 +317,51 @@ BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, #define offsetof(type, memb) ((u32) & ((type*)0)->memb) #endif -/* 80348E14-80348E44 343754 0030+00 1/1 0/0 0/0 .text cbForReadAsync */ static void cbForReadAsync(s32 result, DVDCommandBlock* block) { DVDFileInfo* fileInfo; - fileInfo = (DVDFileInfo*)((char*)block - offsetof(DVDFileInfo, block)); + fileInfo = (DVDFileInfo*)((char*)block - offsetof(DVDFileInfo, cb)); + ASSERTLINE(774, (void*) &fileInfo->cb == (void*) block); if (fileInfo->callback) { (fileInfo->callback)(result, fileInfo); } } -/* 80348E44-80348F5C 343784 0118+00 0/0 9/9 3/3 .text DVDReadPrio */ -int DVDReadPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, s32 prio) { - BOOL result; +s32 DVDReadPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, s32 prio) { + int result; DVDCommandBlock* block; s32 state; BOOL enabled; - int retVal; + s32 retVal; - if (!((0 <= offset) && (offset <= fileInfo->length))) { - OSPanic(__FILE__, 820, "DVDRead(): specified area is out of the file "); - } + ASSERTMSGLINE(806, fileInfo, "DVDRead(): null pointer is specified to file info address "); + ASSERTMSGLINE(807, addr, "DVDRead(): null pointer is specified to addr "); + ASSERTMSGLINE(811, !OFFSET(addr, 32), "DVDRead(): address must be aligned with 32 byte boundaries "); + ASSERTMSGLINE(813, !(length & 0x1F), "DVDRead(): length must be multiple of 32 byte "); + ASSERTMSGLINE(815, !(offset & 3), "DVDRead(): offset must be multiple of 4 byte "); - if (!((0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE))) { - OSPanic(__FILE__, 826, "DVDRead(): specified area is out of the file "); - } + DVD_ASSERTMSGLINE(820, (0 <= offset) && (offset <= fileInfo->length), "DVDRead(): specified area is out of the file "); + DVD_ASSERTMSGLINE(826, (0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE), "DVDRead(): specified area is out of the file "); - block = &(fileInfo->block); - - result = DVDReadAbsAsyncPrio(block, addr, length, (s32)(fileInfo->start_address + offset), - cbForReadSync, prio); - - if (result == FALSE) { + block = &fileInfo->cb; + result = DVDReadAbsAsyncPrio(block, addr, length, fileInfo->startAddr + offset, cbForReadSync, prio); + if (result == 0) { return -1; } - enabled = OSDisableInterrupts(); while (1) { state = ((volatile DVDCommandBlock*)block)->state; - - if (state == DVD_STATE_END) { - retVal = (s32)block->transferred_size; + if (state == 0) { + retVal = (s32)block->transferredSize; + break; + } else if (state == -1) { + retVal = -1; + break; + } else if (state == 10) { + retVal = -3; break; } - if (state == DVD_STATE_FATAL_ERROR) { - retVal = DVD_RESULT_FATAL_ERROR; - break; - } - if (state == DVD_STATE_CANCELED) { - retVal = DVD_RESULT_CANCELED; - break; - } - OSSleepThread(&__DVDThreadQueue); } @@ -389,52 +369,262 @@ int DVDReadPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, s32 p return retVal; } -/* 80348F5C-80348F80 34389C 0024+00 1/1 0/0 0/0 .text cbForReadSync */ -/* This is based on the revolution SDK, these may not match in all cases */ static void cbForReadSync(s32 result, DVDCommandBlock* block) { OSWakeupThread(&__DVDThreadQueue); } -/* 80348F80-80349040 3438C0 00C0+00 0/0 3/3 0/0 .text DVDOpenDir */ -BOOL DVDOpenDir(const char* dirName, DVDDirectory* dir) { +int DVDSeekAsyncPrio(DVDFileInfo* fileInfo, s32 offset, DVDCallback callback, s32 prio) { + ASSERTMSGLINE(898, fileInfo, "DVDSeek(): null pointer is specified to file info address "); + ASSERTMSGLINE(902, !(offset & 3), "DVDSeek(): offset must be multiple of 4 byte "); + + DVD_ASSERTMSGLINE(907, (0 <= offset) && (offset <= fileInfo->length), "DVDSeek(): offset is out of the file "); + + fileInfo->callback = callback; + DVDSeekAbsAsyncPrio(&fileInfo->cb, (u32)(char*)fileInfo->startAddr + offset, cbForSeekAsync, prio); + return 1; +} + +static void cbForSeekAsync(s32 result, DVDCommandBlock* block) { + DVDFileInfo* fileInfo; + + fileInfo = (DVDFileInfo *)&block->next; + ASSERTLINE(925, (void*) &fileInfo->cb == (void*) block); + if (fileInfo->callback) { + (fileInfo->callback)(result, fileInfo); + } +} + +s32 DVDSeekPrio(DVDFileInfo* fileInfo, s32 offset, s32 prio) { + int result; + DVDCommandBlock* block; + s32 state; + BOOL enabled; + s32 retVal; + + ASSERTMSGLINE(955, fileInfo, "DVDSeek(): null pointer is specified to file info address "); + ASSERTMSGLINE(959, !(offset & 3), "DVDSeek(): offset must be multiple of 4 byte "); + ASSERTMSGLINE(963, (offset >= 0) && ((u32) offset <= (u32) fileInfo->length), "DVDSeek(): offset is out of the file "); + + block = &fileInfo->cb; + result = DVDSeekAbsAsyncPrio(block, (u32)(char*)fileInfo->startAddr + offset, cbForSeekSync, prio); + if (!result) { + return -1; + } + enabled = OSDisableInterrupts(); + + while (1) { + state = ((volatile DVDCommandBlock*)block)->state; + if (state == 0) { + retVal = 0; + break; + } else if (state == -1) { + retVal = -1; + break; + } else if (state == 10) { + retVal = -3; + break; + } + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForSeekSync(s32 result, DVDCommandBlock* block) { + OSWakeupThread(&__DVDThreadQueue); +} + +s32 DVDGetFileInfoStatus(const DVDFileInfo* fileInfo) { + return DVDGetCommandBlockStatus(&fileInfo->cb); +} + +BOOL DVDFastOpenDir(s32 entrynum, DVDDir* dir) { + ASSERTMSGLINE(1048, dir, "DVDFastOpenDir(): null pointer is specified to dir structure address "); + ASSERTMSG1LINE(1051, entrynum >= 0 && entrynum < MaxEntryNum, "DVDFastOpenDir(): specified entry number \'%d\' is out of range ", entrynum); + ASSERTMSG1LINE(1054, entryIsDir(entrynum), "DVDFastOpenDir(): entry number \'%d\' is assigned to a file ", entrynum); + + if (entrynum < 0 || entrynum >= MaxEntryNum || !entryIsDir(entrynum)) { + return FALSE; + } + + dir->entryNum = entrynum; + dir->location = entrynum + 1; + dir->next = FstStart[entrynum].nextEntryOrLength; + return TRUE; +} + +BOOL DVDOpenDir(const char* dirName, DVDDir* dir) { s32 entry; char currentDir[128]; - entry = DVDConvertPathToEntrynum(dirName); + ASSERTMSGLINE(1083, dirName, "DVDOpendir(): null pointer is specified to directory name "); + ASSERTMSGLINE(1084, dir, "DVDOpenDir(): null pointer is specified to dir structure address "); + + entry = DVDConvertPathToEntrynum(dirName); if (entry < 0) { - DVDGetCurrentDir(currentDir, 128); - OSReport("Warning: DVDOpenDir(): file '%s' was not found under %s.\n", dirName, currentDir); + DVDGetCurrentDir(currentDir, sizeof(currentDir)); + OSReport("Warning: DVDOpenDir(): file \'%s\' was not found under %s.\n", dirName, currentDir); return FALSE; } if (!entryIsDir(entry)) { + ASSERTMSG1LINE(1098, entryIsDir(entry), "DVDOpendir(): file \'%s\' is specified as a directory name ", dirName); return FALSE; } - dir->entry_number = (u32)entry; - dir->location = (u32)entry + 1; - dir->next = nextDir(entry); - + dir->entryNum = entry; + dir->location = entry + 1; + dir->next = nextDir(entry); return TRUE; } -/* 80349040-803490E4 343980 00A4+00 0/0 3/3 0/0 .text DVDReadDir */ -BOOL DVDReadDir(DVDDirectory* dir, DVDDirectoryEntry* dirent) { - u32 loc = dir->location; - if ((loc <= dir->entry_number) || (dir->next <= loc)) { - return FALSE; - } +int DVDReadDir(DVDDir* dir, DVDDirEntry* dirent) { + u32 loc; - dirent->entry_number = loc; - dirent->is_directory = entryIsDir(loc); + loc = dir->location; + if ((loc <= (u32) dir->entryNum) || ((u32) dir->next <= loc)) { + return 0; + } + dirent->entryNum = loc; + dirent->isDir = entryIsDir(loc); dirent->name = FstStringStart + stringOff(loc); - - dir->location = entryIsDir(loc) ? nextDir(loc) : (loc + 1); - - return TRUE; + dir->location = entryIsDir(loc) ? nextDir(loc) : loc + 1; + return 1; } -/* 803490E4-803490EC 343A24 0008+00 0/0 3/3 0/0 .text DVDCloseDir */ -BOOL DVDCloseDir() { +int DVDCloseDir(DVDDir* dir) { return 1; -} \ No newline at end of file +} + +void DVDRewindDir(DVDDir* dir) { + dir->location = dir->entryNum + 1; +} + +void* DVDGetFSTLocation(void) { + return BootInfo->FSTLocation; +} + +#define RoundUp32KB(x) (((u32)(x) + 32 * 1024 - 1) & ~(32 * 1024 - 1)) +#define Is32KBAligned(x) (((u32)(x) & (32 * 1024 - 1)) == 0) + +BOOL DVDPrepareStreamAsync(DVDFileInfo* fileInfo, u32 length, u32 offset, DVDCallback callback) { + u32 start; + + ASSERTMSGLINE(1205, fileInfo, "DVDPrepareStreamAsync(): NULL file info was specified"); + + start = fileInfo->startAddr + offset; + + DVD_ASSERTMSG2LINE(1211, Is32KBAligned(start), "DVDPrepareStreamAsync(): Specified start address (filestart(0x%x) + offset(0x%x)) is not 32KB aligned", fileInfo->startAddr, offset); + + if (length == 0) + length = fileInfo->length - offset; + + DVD_ASSERTMSG1LINE(1221, Is32KBAligned(length), "DVDPrepareStreamAsync(): Specified length (0x%x) is not a multiple of 32768(32*1024)", length); + + DVD_ASSERTMSG2LINE(1229, (offset <= fileInfo->length) && (offset + length <= fileInfo->length), "DVDPrepareStreamAsync(): The area specified (offset(0x%x), length(0x%x)) is out of the file", offset, length); + + fileInfo->callback = callback; + return DVDPrepareStreamAbsAsync(&(fileInfo->cb), length, fileInfo->startAddr + offset, cbForPrepareStreamAsync); +} + +static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock* block) { + DVDFileInfo* fileInfo; + + fileInfo = (DVDFileInfo*)((char*)block - offsetof(DVDFileInfo, cb)); + + ASSERTLINE(1248, (void*) &fileInfo->cb == (void*) block); + + if (fileInfo->callback) { + (fileInfo->callback)(result, fileInfo); + } +} + +s32 DVDPrepareStream(DVDFileInfo* fileInfo, u32 length, u32 offset) { + BOOL result; + DVDCommandBlock* block; + s32 state; + BOOL enabled; + s32 retVal; + u32 start; + + ASSERTMSGLINE(1282, fileInfo, "DVDPrepareStream(): NULL file info was specified"); + + start = fileInfo->startAddr + offset; + + DVD_ASSERTMSG2LINE(1288, Is32KBAligned(start), "DVDPrepareStream(): Specified start address (filestart(0x%x) + offset(0x%x)) is not 32KB aligned", fileInfo->startAddr, offset); + + if (length == 0) + length = fileInfo->length - offset; + + DVD_ASSERTMSG1LINE(1298, Is32KBAligned(length), "DVDPrepareStream(): Specified length (0x%x) is not a multiple of 32768(32*1024)", length); + + DVD_ASSERTMSG2LINE(1306, (offset <= fileInfo->length) && (offset + length <= fileInfo->length), "DVDPrepareStream(): The area specified (offset(0x%x), length(0x%x)) is out of the file", offset, length); + + block = &(fileInfo->cb); + result = DVDPrepareStreamAbsAsync(block, length, start, cbForPrepareStreamSync); + + if (result == FALSE) { + return -1; + } + + enabled = OSDisableInterrupts(); + + while (1) { + state = ((volatile DVDCommandBlock*)block)->state; + + if (state == DVD_STATE_END) { + retVal = 0; + break; + } + if (state == DVD_STATE_FATAL_ERROR) { + retVal = DVD_RESULT_FATAL_ERROR; + break; + } + if (state == DVD_STATE_CANCELED) { + retVal = -3; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +static void cbForPrepareStreamSync(s32 result, DVDCommandBlock* block) { + OSWakeupThread(&__DVDThreadQueue); +} + +s32 DVDGetTransferredSize(DVDFileInfo* fileinfo) { + s32 bytes; + DVDCommandBlock* cb; + + cb = &(fileinfo->cb); + + switch (cb->state) { + case DVD_STATE_COVER_CLOSED: + case DVD_STATE_NO_DISK: + case DVD_STATE_COVER_OPEN: + case DVD_STATE_WRONG_DISK: + case DVD_STATE_FATAL_ERROR: + case DVD_STATE_MOTOR_STOPPED: + case DVD_STATE_CANCELED: + case DVD_STATE_RETRY: + case DVD_STATE_END: + bytes = (s32)cb->transferredSize; + break; + case DVD_STATE_WAITING: + bytes = 0; + break; + case DVD_STATE_BUSY: + bytes = (s32)(cb->transferredSize + (cb->currTransferSize - __DIRegs[6])); + break; + default: + ASSERTMSG1LINE(1391, FALSE, "DVDGetTransferredSize(): Illegal state (%d)", cb->state); + break; + } + + return bytes; +} diff --git a/src/dolphin/dvd/dvdidutils.c b/src/dolphin/dvd/dvdidutils.c index 28b0530b56..a702a657fe 100644 --- a/src/dolphin/dvd/dvdidutils.c +++ b/src/dolphin/dvd/dvdidutils.c @@ -1,26 +1,97 @@ -#include "dolphin/dvd/dvdidutils.h" -#include "dolphin/dvd.h" +#include +#include -/* 8034BC04-8034BCFC 346544 00F8+00 0/0 1/1 0/0 .text DVDCompareDiskID */ -BOOL DVDCompareDiskID(DVDDiskID* id1, DVDDiskID* id2) { - if (id1->game_name[0] && id2->game_name[0] && - strncmp(&id1->game_name[0], &id2->game_name[0], 4)) { - return FALSE; +#include "__dvd.h" + +static u32 strnlen(const char* str, u32 maxlen) { + u32 i; + + for (i = 0; i < maxlen; i++) { + if (*str++ == 0) { + return i; + } } - if (!id1->company[0] || !id2->company[0] || strncmp(&id1->company[0], &id2->company[0], 2)) { - return FALSE; + return maxlen; +} + +int DVDCompareDiskID(const DVDDiskID* id1, const DVDDiskID* id2) { +#ifdef DEBUG + const char* game1; + const char* game2; + const char* company1; + const char* company2; + u8 diskNum1; + u8 diskNum2; + u8 version1; + u8 version2; + u32 length; + + ASSERTMSGLINE(64, id1, "DVDCompareDiskID(): Specified id1 is NULL\n"); + ASSERTMSGLINE(65, id2, "DVDCompareDiskID(): Specified id2 is NULL\n"); + + game1 = id1->gameName; + game2 = id2->gameName; + company1 = id1->company; + company2 = id2->company; + diskNum1 = id1->diskNumber; + diskNum2 = id2->diskNumber; + version1 = id1->gameVersion; + version2 = id2->gameVersion; + + length = strnlen(game1, sizeof(game1)); + ASSERTMSGLINE(78, length == 0 || length == 4, "DVDCompareDiskID(): Specified game name for id1 is neither NULL nor 4 character long\n"); + ASSERTMSGLINE(79, company1, "DVDCompareDiskID(): Specified company name for id1 is NULL\n"); + ASSERTMSGLINE(80, company1[1] != 0, "DVDCompareDiskID(): Specified company name for id1 is not 2 character long\n"); + ASSERTMSGLINE(81, diskNum1 == 0xFF || ((diskNum1 / 16) < 10 && diskNum1 % 16 < 10), "DVDCompareDiskID(): Specified disk number for id1 is neither 0xff nor a BCD number"); + ASSERTMSGLINE(82, version1 == 0xFF || ((version1 / 16) < 10 && version1 % 16 < 10), "DVDCompareDiskID(): Specified version number for id1 is neither 0xff nor a BCD number"); + + length = strnlen(game2, sizeof(game2)); + ASSERTMSGLINE(85, length == 0 || length == 4, "DVDCompareDiskID(): Specified game name for id2 is neither NULL nor 4 character long\n"); + ASSERTMSGLINE(86, company2, "DVDCompareDiskID(): Specified company name for id2 is NULL\n"); + ASSERTMSGLINE(87, company2[1] != 0, "DVDCompareDiskID(): Specified company name for id2 is not 2 character long\n"); + ASSERTMSGLINE(88, diskNum2 == 0xFF || ((diskNum2 / 16) < 10 && diskNum2 % 16 < 10), "DVDCompareDiskID(): Specified disk number for id2 is neither 0xff nor a BCD number"); + ASSERTMSGLINE(89, version2 == 0xFF || ((version2 / 16) < 10 && version2 % 16 < 10), "DVDCompareDiskID(): Specified version number for id2 is neither 0xff nor a BCD number"); +#endif + + if (id1->gameName[0] != 0 && id2->gameName[0] != 0 && strncmp(id1->gameName, id2->gameName, 4) != 0) { + return 0; } - if (id1->disk_number != 0xff && id2->disk_number != 0xff && - id1->disk_number != id2->disk_number) { - return FALSE; + if (id1->company[0] == 0 || id2->company[0] == 0 || strncmp(id1->company, id2->company, 2) != 0) { + return 0; } - if (id1->game_version != 0xff && id2->game_version != 0xff && - id1->game_version != id2->game_version) { - return FALSE; + if (id1->diskNumber != 0xFF && id2->diskNumber != 0xFF && id1->diskNumber != id2->diskNumber) { + return 0; } - return TRUE; -} \ No newline at end of file + if (id1->gameVersion != 0xFF && id2->gameVersion != 0xFF && id1->gameVersion != id2->gameVersion) { + return 0; + } + + return 1; +} + +DVDDiskID* DVDGenerateDiskID(DVDDiskID* id, const char* game, const char* company, u8 diskNum, u8 version) { + ASSERTMSGLINE(123, id, "DVDGenerateDiskID(): Specified id is NULL\n"); + ASSERTMSGLINE(124, game == NULL || strlen(game) == 4, "DVDGenerateDiskID(): Specified game name is neither NULL nor 4 character long\n"); + ASSERTMSGLINE(125, company, "DVDGenerateDiskID(): Specified company name is NULL\n"); + ASSERTMSGLINE(126, strlen(company) == 2, "DVDGenerateDiskID(): Specified company name is not 2 character long\n"); + ASSERTMSGLINE(127, diskNum == 0xFF || ((diskNum / 16) < 10 && diskNum % 16 < 10), "DVDGenerateDiskID(): Specified disk number is neither 0xff nor a BCD number"); + ASSERTMSGLINE(128, version == 0xFF || ((version / 16) < 10 && version % 16 < 10), "DVDGenerateDiskID(): Specified version number is neither 0xff nor a BCD number"); + + memset(id, 0, sizeof(DVDDiskID)); + + if (game != NULL) { + strncpy(id->gameName, game, 4); + } + + if (company != NULL) { + strncpy(id->company, company, 2); + } + + id->diskNumber = diskNum; + id->gameVersion = version; + return id; +} diff --git a/src/dolphin/dvd/dvdlow.c b/src/dolphin/dvd/dvdlow.c index 9387335fff..79dca99cb4 100644 --- a/src/dolphin/dvd/dvdlow.c +++ b/src/dolphin/dvd/dvdlow.c @@ -1,529 +1,534 @@ -#include "dolphin/dvd/dvdlow.h" -#include "dolphin/dvd.h" -#include "dolphin/os/OSAlarm.h" -#include "dolphin/os/OSContext.h" -#include "dolphin/os/OSReset.h" +#include +#include -void __DVDInitWA(); -void __DVDInterruptHandler(u32 arg0, OSContext* context); -static void AlarmHandler(); -static void AlarmHandlerForTimeout(); -static void Read(void* arg0, u32 arg1, u32 arg2, DVDLowCallback cb); -static void SeekTwiceBeforeRead(void* arg0, u32 arg1, u32 arg2, DVDLowCallback cb); -BOOL DVDLowRead(void* arg0, u32 arg1, u32 arg2, DVDLowCallback cb); -BOOL DVDLowSeek(u32 arg0, DVDLowCallback cb); -BOOL DVDLowWaitCoverClose(DVDLowCallback cb); -BOOL DVDLowReadDiskID(u32 arg0, DVDLowCallback cb); -BOOL DVDLowStopMotor(DVDLowCallback cb); -BOOL DVDLowRequestError(DVDLowCallback cb); -BOOL DVDLowInquiry(u32 arg0, DVDLowCallback cb); -BOOL DVDLowAudioStream(u32 arg0, u32 arg1, u32 arg2, DVDLowCallback cb); -BOOL DVDLowRequestAudioStatus(u32 arg0, DVDLowCallback cb); -BOOL DVDLowAudioBufferConfig(s32 arg0, u32 arg1, DVDLowCallback cb); -void DVDLowReset(); -BOOL DVDLowBreak(); -DVDLowCallback DVDLowClearCallback(); -void __DVDLowSetWAType(u32 arg0, u32 arg1); -BOOL __DVDLowTestAlarm(OSAlarm* alarm); +#include "__dvd.h" +#include "__os.h" -typedef struct DVDBuffer { - void* addr; - u32 length; - u32 offset; +#define DVD_WATYPE_MAX 2 + +static BOOL FirstRead = TRUE; +static volatile BOOL StopAtNextInt = FALSE; +static u32 LastLength = 0; +static DVDLowCallback Callback = NULL; +static DVDLowCallback ResetCoverCallback = NULL; +static volatile OSTime LastResetEnd = 0; +static volatile u32 ResetOccurred = FALSE; +static volatile BOOL WaitingCoverClose = FALSE; +static volatile BOOL Breaking = FALSE; +static volatile u32 WorkAroundType = 0; +static u32 WorkAroundSeekLocation = 0; +static volatile OSTime LastReadFinished = 0; +static OSTime LastReadIssued = 0; +static volatile BOOL LastCommandWasRead = FALSE; +static volatile u32 NextCommandNumber = 0; + +typedef struct { + void* addr; + u32 length; + u32 offset; } DVDBuffer; -typedef struct DVDCommand { - s32 cmd; - void* addr; - u32 length; - u32 offset; - DVDLowCallback callback; +typedef struct { + s32 command; + void* address; + u32 length; + u32 offset; + DVDLowCallback callback; } DVDCommand; -/* 8044C830-8044C870 079550 003C+04 6/6 0/0 0/0 .bss CommandList */ static DVDCommand CommandList[3]; - -/* 80451710-80451714 000C10 0004+00 12/12 0/0 0/0 .sbss StopAtNextInt */ -static volatile BOOL StopAtNextInt; - -/* 80451714-80451718 000C14 0004+00 1/1 0/0 0/0 .sbss LastLength */ -static u32 LastLength; - -/* 80451718-8045171C 000C18 0004+00 13/13 0/0 0/0 .sbss Callback */ -static DVDLowCallback Callback; - -/* 8045171C-80451720 000C1C 0004+00 1/1 0/0 0/0 .sbss ResetCoverCallback */ -static DVDLowCallback ResetCoverCallback; - -/* 80451720-80451724 000C20 0004+00 2/2 0/0 0/0 .sbss LastResetEnd */ -static volatile OSTime LastResetEnd; - -/* 80451728-8045172C 000C28 0004+00 2/2 0/0 0/0 .sbss ResetOccurred */ -static volatile u32 ResetOccurred; - -/* 8045172C-80451730 000C2C 0004+00 3/3 0/0 0/0 .sbss WaitingCoverClose */ -static volatile BOOL WaitingCoverClose; - -/* 80451730-80451734 000C30 0004+00 2/2 0/0 0/0 .sbss Breaking */ -static BOOL Breaking; - -/* 80451734-80451738 000C34 0004+00 2/2 0/0 0/0 .sbss WorkAroundType */ -static volatile u32 WorkAroundType; - -/* 80451738-80451740 000C38 0004+04 2/2 0/0 0/0 .sbss WorkAroundSeekLocation */ -static u32 WorkAroundSeekLocation[2]; - -/* 80451740-80451744 000C40 0004+00 2/2 0/0 0/0 .sbss LastReadFinished */ -static volatile OSTime LastReadFinished; - -/* 80451748-8045174C 000C48 0004+00 1/1 0/0 0/0 .sbss LastReadIssued */ -static OSTime LastReadIssued; - -/* 80451750-80451754 000C50 0004+00 2/2 0/0 0/0 .sbss LastCommandWasRead */ -static volatile BOOL LastCommandWasRead; - -/* 80451754-80451758 000C54 0004+00 5/5 0/0 0/0 .sbss NextCommandNumber */ -static volatile u32 NextCommandNumber; - -/* 80347674-803476B4 341FB4 0040+00 0/0 1/1 0/0 .text __DVDInitWA */ -void __DVDInitWA() { - NextCommandNumber = 0; - ((DVDCommand*)CommandList)[0].cmd = -1; - __DVDLowSetWAType(0, 0); - OSInitAlarm(); -} - -/* ############################################################################################## */ -/* 8044C870-8044C898 079590 0028+00 0/1 0/0 0/0 .bss AlarmForWA */ static OSAlarm AlarmForWA; - -/* 8044C898-8044C8C0 0795B8 0028+00 9/11 0/0 0/0 .bss AlarmForTimeout */ static OSAlarm AlarmForTimeout; - -/* 8044C8C0-8044C8E8 0795E0 0028+00 1/1 0/0 0/0 .bss AlarmForBreak */ static OSAlarm AlarmForBreak; - -/* 8044C8E8-8044C8F4 079608 000C+00 0/1 0/0 0/0 .bss Prev */ static DVDBuffer Prev; - -/* 8044C8F4-8044C900 079614 000C+00 0/2 0/0 0/0 .bss Curr */ static DVDBuffer Curr; -/* 804509D8-804509E0 000458 0004+04 2/2 0/0 0/0 .sdata FirstRead */ -static BOOL FirstRead = TRUE; +// prototypes +static void Read(void* address, u32 length, u32 offset, DVDLowCallback callback); +static void SetBreakAlarm(OSTime timeout); -/* 803476B4-80347994 341FF4 02E0+00 0/0 1/1 0/0 .text __DVDInterruptHandler */ -void __DVDInterruptHandler(u32 arg0, OSContext* context) { - u32 reg; - s32 rv; - u32 val = 0; - u32 val2; - u32 val3; - u32 val4; - OSContext localContext; - if (LastCommandWasRead) { - LastReadFinished = __OSGetSystemTime(); - FirstRead = FALSE; - Prev.addr = Curr.addr; - Prev.length = Curr.length; - Prev.offset = Curr.offset; - - if (StopAtNextInt == TRUE) { - val |= 8; - } - } - - LastCommandWasRead = FALSE; - StopAtNextInt = FALSE; - reg = __DIRegs[0]; - val4 = (reg & 0x2a); - val2 = (reg & 0x54) & (val4 << 1); - if (val2 & 0x40) { - val |= 8; - } - if (val2 & 0x10) { - val |= 1; - } - if (val2 & 0x4) { - val |= 2; - } - - if (val) { - ResetOccurred = FALSE; - OSCancelAlarm(&AlarmForTimeout); - } - __DIRegs[0] = val2 | (val4); - - if (ResetOccurred && (__OSGetSystemTime() - LastResetEnd) < (OSTime)OSMillisecondsToTicks(200)) - { - reg = __DIRegs[1]; - val2 = (reg & 0x4) & ((reg & 0x2) << 1); - if (val2 & 0x4) { - if (ResetCoverCallback) { - ResetCoverCallback(4); - } - ResetCoverCallback = NULL; - } - - __DIRegs[1] = __DIRegs[1]; - } else if (WaitingCoverClose) { - reg = __DIRegs[1]; - val3 = reg & 2; - val2 = (reg & 0x4) & ((reg & 0x2) << 1); - if (val2 & 4) { - val |= 4; - } - __DIRegs[1] = val2 | val3; - WaitingCoverClose = FALSE; - } else { - __DIRegs[1] = 0; - } - - if ((val & 8) && !Breaking) { - val &= ~0x8; - } - - if (val & 1) { - u32 num; - DVDCommand* command; - s32 cmd0 = CommandList[num = NextCommandNumber].cmd; - if (cmd0 == 1) { - NextCommandNumber++; - command = &CommandList[num]; - Read(command->addr, command->length, command->offset, command->callback); - rv = 1; - } else if (cmd0 == 2) { - NextCommandNumber++; - command = &CommandList[num]; - DVDLowSeek(command->offset, command->callback); - rv = 1; - } else { - rv = 0; - } - - if (rv) { - return; - } - } else { - CommandList[0].cmd = -1; - NextCommandNumber = 0; - } - - OSClearContext(&localContext); - OSSetCurrentContext(&localContext); - if (val) { - DVDLowCallback cb = Callback; - Callback = NULL; - if (cb) { - cb(val); - } - Breaking = FALSE; - } - - OSClearContext(&localContext); - OSSetCurrentContext(context); +void __DVDInitWA(void) { + NextCommandNumber = 0; + CommandList[0].command = -1; + __DVDLowSetWAType(0, 0); + OSInitAlarm(); +} + +static BOOL ProcessNextCommand(void) { + s32 n = NextCommandNumber; + + ASSERTLINE(310, n < 3); + + if (CommandList[n].command == 1) { + ++NextCommandNumber; + Read(CommandList[n].address, CommandList[n].length, CommandList[n].offset, CommandList[n].callback); + return TRUE; + } else if (CommandList[n].command == 2) { + ++NextCommandNumber; + DVDLowSeek(CommandList[n].offset, CommandList[n].callback); + return TRUE; + } + + return FALSE; +} + +void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext* context) { + DVDLowCallback cb; + OSContext exceptionContext; + u32 cause = 0; + u32 reg; + u32 intr; + u32 mask; + + if (LastCommandWasRead) { + LastReadFinished = __OSGetSystemTime(); + FirstRead = FALSE; + Prev.addr = Curr.addr; + Prev.length = Curr.length; + Prev.offset = Curr.offset; + + if (StopAtNextInt == TRUE) { + cause |= 8; + } + } + + LastCommandWasRead = FALSE; + StopAtNextInt = FALSE; + reg = __DIRegs[0]; + mask = reg & 0x2a; + intr = (reg & 0x54) & (mask << 1); + + if (intr & 0x40) { + cause |= 8; + } + + if (intr & 0x10) { + cause |= 1; + } + + if (intr & 4) { + cause |= 2; + } + + if (cause) { + ResetOccurred = FALSE; + OSCancelAlarm(&AlarmForTimeout); + } + + __DIRegs[0] = intr | mask; + + if (ResetOccurred && (__OSGetSystemTime() - LastResetEnd) < OSMillisecondsToTicks(200)) { + reg = __DIRegs[1]; + mask = reg & 0x2; + intr = (reg & 4) & (mask << 1); + if (intr & 4) { + if (ResetCoverCallback) { + ResetCoverCallback(4); + } + ResetCoverCallback = NULL; + } + + __DIRegs[1] = __DIRegs[1]; + } else if (WaitingCoverClose) { + reg = __DIRegs[1]; + mask = reg & 2; + intr = (reg & 4) & (mask << 1); + + if (intr & 4) { + cause |= 4; + } + + __DIRegs[1] = intr | mask; + WaitingCoverClose = FALSE; + } else { + __DIRegs[1] = 0; + } + + if ((cause & 8) && !Breaking) { + cause &= ~8; + } + + if (cause & 1) { + if (ProcessNextCommand()) { + return; + } + } else { + CommandList[0].command = -1; + NextCommandNumber = 0; + } + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + if (cause) { + cb = Callback; + Callback = NULL; + if (cb) { + cb(cause); + } + + Breaking = FALSE; + } + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); } -/* 80347994-80347A18 3422D4 0084+00 1/1 0/0 0/0 .text AlarmHandler */ static void AlarmHandler(OSAlarm* alarm, OSContext* context) { - DVDCommand* cmd; - u32 num; - s32 cmd0 = CommandList[num = NextCommandNumber].cmd; - - if (cmd0 == 1) { - ++NextCommandNumber; - cmd = &CommandList[num]; - Read(cmd->addr, cmd->length, cmd->offset, cmd->callback); - } else if (cmd0 == 2) { - ++NextCommandNumber; - cmd = &CommandList[num]; - DVDLowSeek(cmd->offset, cmd->callback); - } + BOOL processed = ProcessNextCommand(); + ASSERTLINE(652, processed); } -/* 80347A18-80347A88 342358 0070+00 9/9 0/0 0/0 .text AlarmHandlerForTimeout */ static void AlarmHandlerForTimeout(OSAlarm* alarm, OSContext* context) { - OSContext tmpContext; - DVDLowCallback callback; - __OSMaskInterrupts(0x400); - OSClearContext(&tmpContext); - OSSetCurrentContext(&tmpContext); - callback = Callback; - Callback = NULL; - if (callback != NULL) { - callback(0x10); - } - OSClearContext(&tmpContext); - OSSetCurrentContext(context); + DVDLowCallback cb; + OSContext exceptionContext; + + __OSMaskInterrupts(0x400); + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + cb = Callback; + Callback = NULL; + if (cb) { + cb(0x10); + } + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); } -static void __setAlarm(u32 seconds) { - u32 temp = OSSecondsToTicks(seconds); - OSCreateAlarm(&AlarmForTimeout); - OSSetAlarm(&AlarmForTimeout, (OSTime)temp, AlarmHandlerForTimeout); +static void SetTimeoutAlarm(OSTime timeout) { + OSCreateAlarm(&AlarmForTimeout); + OSSetAlarm(&AlarmForTimeout, timeout, AlarmHandlerForTimeout); } -/* 80347A88-80347B98 3423C8 0110+00 3/3 0/0 0/0 .text Read */ -void Read(void* arg0, u32 arg1, u32 arg2, DVDLowCallback cb) { - StopAtNextInt = FALSE; - Callback = cb; - LastCommandWasRead = TRUE; - LastReadIssued = __OSGetSystemTime(); - __DIRegs[2] = 0xA8000000; - __DIRegs[3] = arg2 >> 2; - __DIRegs[4] = arg1; - __DIRegs[5] = (u32)arg0; - __DIRegs[6] = arg1; - LastLength = arg1; - __DIRegs[7] = 3; - if (arg1 > 0xa00000) { - __setAlarm(20); - } else { - __setAlarm(10); - } +static void Read(void* address, u32 length, u32 offset, DVDLowCallback callback) { + Callback = callback; + StopAtNextInt = FALSE; + LastCommandWasRead = TRUE; + LastReadIssued = __OSGetSystemTime(); + + __DIRegs[2] = 0xa8000000; + __DIRegs[3] = offset / 4; + __DIRegs[4] = length; + __DIRegs[5] = (u32)address; + __DIRegs[6] = length; + LastLength = length; + __DIRegs[7] = 3; + + if (length > 0xa00000) { + SetTimeoutAlarm(OSSecondsToTicks(20)); + } else { + SetTimeoutAlarm(OSSecondsToTicks(10)); + } } -/* 80347B98-80347C18 3424D8 0080+00 1/1 0/0 0/0 .text SeekTwiceBeforeRead */ -void SeekTwiceBeforeRead(void* arg0, u32 arg1, u32 arg2, DVDLowCallback cb) { - u32 val; - u32 temp = arg2 & 0xffff8000; - if (temp == 0) { - val = 0; - } else { - val = temp + WorkAroundSeekLocation[0]; - } +static BOOL AudioBufferOn(void) { + DVDDiskID* id; - CommandList[0].cmd = 2; - CommandList[0].offset = val; - CommandList[0].callback = cb; - CommandList[1].cmd = 1; - CommandList[1].addr = arg0; - CommandList[1].length = arg1; - CommandList[1].offset = arg2; - CommandList[1].callback = cb; - CommandList[2].cmd = -1; - NextCommandNumber = 0; - DVDLowSeek(val, cb); -} - -BOOL HitCache() { - u32 uVar1 = (Prev.offset + Prev.length - 1) >> 15; - u32 uVar2 = (Curr.offset >> 15); - u32 iVar3 = (DVDGetCurrentDiskID()->is_streaming ? TRUE : FALSE) ? 5 : 15; - - if ((uVar2 > uVar1 - 2) || (uVar2 < uVar1 + iVar3 + 3)) { + id = DVDGetCurrentDiskID(); + if (id->streaming) { return TRUE; } + return FALSE; } +static BOOL HitCache(DVDBuffer* curr, DVDBuffer* prev) { + u32 blockNumOfPrevEnd = (prev->offset + prev->length - 1) >> 15; + u32 blockNumOfCurrStart = (curr->offset >> 15); + u32 cacheBlockSize = AudioBufferOn() ? 5 : 15; + + if ((blockNumOfCurrStart > blockNumOfPrevEnd - 2) || (blockNumOfCurrStart < blockNumOfPrevEnd + cacheBlockSize + 3)) { + return TRUE; + } + return FALSE; +} + static void DoJustRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { - CommandList[0].cmd = -1; - NextCommandNumber = 0; - Read(addr, length, offset, callback); + CommandList[0].command = -1; + NextCommandNumber = 0; + Read(addr, length, offset, callback); } -static void WaitBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback, - OSTime timeout) { - CommandList[0].cmd = 1; - CommandList[0].addr = addr; - CommandList[0].length = length; - CommandList[0].offset = offset; - CommandList[0].callback = callback; - CommandList[1].cmd = -1; - NextCommandNumber = 0; - OSCreateAlarm(&AlarmForWA); - OSSetAlarm(&AlarmForWA, timeout, AlarmHandler); +static void SeekTwiceBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { + u32 newOffset; + if ((offset & ~0x7FFF) == 0) { + newOffset = 0; + } else { + newOffset = (offset & ~0x7FFF) + WorkAroundSeekLocation; + } + + CommandList[0].command = 2; + CommandList[0].offset = newOffset; + CommandList[0].callback = callback; + CommandList[1].command = 1; + CommandList[1].address = addr; + CommandList[1].length = length; + CommandList[1].offset = offset; + CommandList[1].callback = callback; + CommandList[2].command = -1; + NextCommandNumber = 0; + DVDLowSeek(newOffset, callback); } -/* 80347C18-80347EB0 342558 0298+00 0/0 4/4 0/0 .text DVDLowRead */ -BOOL DVDLowRead(void* addr, u32 length, u32 offset, DVDLowCallback cb) { - OSTime diff; - u32 prev; +static void WaitBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback, OSTime wait) { + CommandList[0].command = 1; + CommandList[0].address = addr; + CommandList[0].length = length; + CommandList[0].offset = offset; + CommandList[0].callback = callback; + CommandList[1].command = -1; + NextCommandNumber = 0; + OSCreateAlarm(&AlarmForWA); + OSSetAlarm(&AlarmForWA, wait, AlarmHandler); +} - __DIRegs[6] = length; - Curr.addr = addr; - Curr.length = length; - Curr.offset = offset; +BOOL DVDLowRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { + u32 blockNumOfPrevEnd; + u32 blockNumOfCurrStart; + OSTime diff; - if (WorkAroundType == 0) { - DoJustRead(addr, length, offset, cb); - } else if (WorkAroundType == 1) { - if (FirstRead) { - SeekTwiceBeforeRead(addr, length, offset, cb); - } else { - if (!HitCache(&Curr, &Prev)) { - DoJustRead(addr, length, offset, cb); - } else { - prev = (Prev.offset + Prev.length - 1) >> 15; - if (prev == Curr.offset >> 15 || prev + 1 == Curr.offset >> 15) { - diff = __OSGetSystemTime() - LastReadFinished; - if (OSMillisecondsToTicks(5) < diff) { - DoJustRead(addr, length, offset, cb); - } else { - WaitBeforeRead(addr, length, offset, cb, - OSMillisecondsToTicks(5) - diff + - OSMicrosecondsToTicks(500)); - } - } else { - SeekTwiceBeforeRead(addr, length, offset, cb); - } - } - } + ASSERTMSGLINE(837, (((u32)addr) & 31) == 0, "DVDLowRead(): address must be aligned with 32 byte boundary."); + ASSERTMSGLINE(838, (length & 31) == 0, "DVDLowRead(): length must be a multiple of 32."); + ASSERTMSGLINE(839, (offset & 3) == 0, "DVDLowRead(): offset must be a multiple of 4."); + ASSERTMSGLINE(841, length != 0, "DVD read: 0 was specified to length of the read\n"); + + __DIRegs[6] = length; + Curr.addr = addr; + Curr.length = length; + Curr.offset = offset; + + if (WorkAroundType == 0) { + DoJustRead(addr, length, offset, callback); + } else if (WorkAroundType == 1) { + if (FirstRead) { + SeekTwiceBeforeRead(addr, length, offset, callback); + } else { + if (!HitCache(&Curr, &Prev)) { + DoJustRead(addr, length, offset, callback); + } else { + blockNumOfPrevEnd = (u32)((Prev.offset + Prev.length - 1) >> 15) & 0x1FFFF; + blockNumOfCurrStart = (u32)((Curr.offset >> 15) & 0x1FFFF); + if (blockNumOfPrevEnd == blockNumOfCurrStart || blockNumOfPrevEnd + 1 == blockNumOfCurrStart) { + diff = __OSGetSystemTime() - LastReadFinished; + if (OSMillisecondsToTicks(5) < diff) { + DoJustRead(addr, length, offset, callback); + } else { + WaitBeforeRead(addr, length, offset, callback, OSMillisecondsToTicks(5) - diff + OSMicrosecondsToTicks(500)); + } + } else { + SeekTwiceBeforeRead(addr, length, offset, callback); + } + } + } + } else { + ASSERTLINE(900, FALSE); } - return TRUE; + + return TRUE; } -/* 80347EB0-80347F44 3427F0 0094+00 3/3 2/2 0/0 .text DVDLowSeek */ -BOOL DVDLowSeek(u32 arg0, DVDLowCallback cb) { - Callback = cb; - StopAtNextInt = FALSE; - __DIRegs[2] = 0xAB000000; - __DIRegs[3] = arg0 >> 2; - __DIRegs[7] = 1; - __setAlarm(10); - return TRUE; +BOOL DVDLowSeek(u32 offset, DVDLowCallback callback) { + ASSERTMSGLINE(920, (offset & 3) == 0, "DVDLowSeek(): offset must be a multiple of 4."); + + Callback = callback; + StopAtNextInt = FALSE; + __DIRegs[2] = 0xab000000; + __DIRegs[3] = offset / 4; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; } -/* 80347F44-80347F70 342884 002C+00 0/0 3/3 0/0 .text DVDLowWaitCoverClose */ -BOOL DVDLowWaitCoverClose(DVDLowCallback cb) { - Callback = cb; - WaitingCoverClose = TRUE; - StopAtNextInt = FALSE; - __DIRegs[1] = 2; - return TRUE; +BOOL DVDLowWaitCoverClose(DVDLowCallback callback) { + Callback = callback; + WaitingCoverClose = TRUE; + StopAtNextInt = FALSE; + __DIRegs[1] = 2; + return TRUE; } -/* 80347F70-80348014 3428B0 00A4+00 0/0 2/2 0/0 .text DVDLowReadDiskID */ -BOOL DVDLowReadDiskID(u32 arg0, DVDLowCallback cb) { - Callback = cb; - StopAtNextInt = FALSE; - __DIRegs[2] = 0xA8000040; - __DIRegs[3] = 0; - __DIRegs[4] = 0x20; - __DIRegs[5] = arg0; - __DIRegs[6] = 0x20; - __DIRegs[7] = 3; - __setAlarm(10); - return 1; +BOOL DVDLowReadDiskID(DVDDiskID* diskID, DVDLowCallback callback) { + ASSERTMSGLINE(986, (((u32)diskID) & 31) == 0, "DVDLowReadID(): id must be aligned with 32 byte boundary."); + + Callback = callback; + StopAtNextInt = FALSE; + __DIRegs[2] = 0xa8000040; + __DIRegs[3] = 0; + __DIRegs[4] = sizeof(DVDDiskID); + __DIRegs[5] = (u32)diskID; + __DIRegs[6] = sizeof(DVDDiskID); + __DIRegs[7] = 3; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; } -/* 80348014-803480A0 342954 008C+00 0/0 9/9 0/0 .text DVDLowStopMotor */ -BOOL DVDLowStopMotor(DVDLowCallback cb) { - Callback = cb; - StopAtNextInt = FALSE; - __DIRegs[2] = 0xE3000000; - __DIRegs[7] = 1; - __setAlarm(10); - return 1; +BOOL DVDLowStopMotor(DVDLowCallback callback) { + Callback = callback; + StopAtNextInt = FALSE; + __DIRegs[2] = 0xe3000000; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; } -/* 803480A0-8034812C 3429E0 008C+00 0/0 7/7 0/0 .text DVDLowRequestError */ -BOOL DVDLowRequestError(DVDLowCallback cb) { - Callback = cb; - StopAtNextInt = FALSE; - __DIRegs[2] = 0xE0000000; - __DIRegs[7] = 1; - __setAlarm(10); - return 1; +BOOL DVDLowRequestError(DVDLowCallback callback) { + Callback = callback; + StopAtNextInt = FALSE; + __DIRegs[2] = 0xe0000000; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; } -/* 8034812C-803481C8 342A6C 009C+00 0/0 1/1 0/0 .text DVDLowInquiry */ -BOOL DVDLowInquiry(u32 arg0, DVDLowCallback cb) { - Callback = cb; - StopAtNextInt = FALSE; - __DIRegs[2] = 0x12000000; - __DIRegs[4] = 0x20; - __DIRegs[5] = arg0; - __DIRegs[6] = 0x20; - __DIRegs[7] = 3; - __setAlarm(10); - return 1; +BOOL DVDLowInquiry(DVDDriveInfo* info, DVDLowCallback callback) { + Callback = callback; + StopAtNextInt = FALSE; + __DIRegs[2] = 0x12000000; + __DIRegs[4] = sizeof(DVDDriveInfo); + __DIRegs[5] = (u32)info; + __DIRegs[6] = sizeof(DVDDriveInfo); + __DIRegs[7] = 3; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; } -/* 803481C8-80348260 342B08 0098+00 0/0 2/2 0/0 .text DVDLowAudioStream */ -BOOL DVDLowAudioStream(u32 arg0, u32 arg1, u32 arg2, DVDLowCallback cb) { - Callback = cb; - StopAtNextInt = FALSE; - __DIRegs[2] = arg0 | 0xe1000000; - __DIRegs[3] = arg2 >> 2; - __DIRegs[4] = arg1; - __DIRegs[7] = 1; - __setAlarm(10); - return 1; +BOOL DVDLowAudioStream(u32 subcmd, u32 length, u32 offset, DVDLowCallback callback) { + Callback = callback; + StopAtNextInt = FALSE; + __DIRegs[2] = subcmd | 0xe1000000; + __DIRegs[3] = offset >> 2; + __DIRegs[4] = length; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; } -/* 80348260-803482EC 342BA0 008C+00 0/0 1/1 0/0 .text DVDLowRequestAudioStatus */ -BOOL DVDLowRequestAudioStatus(u32 arg0, DVDLowCallback cb) { - Callback = cb; - StopAtNextInt = FALSE; - __DIRegs[2] = arg0 | 0xe2000000; - __DIRegs[7] = 1; - __setAlarm(10); - return 1; +BOOL DVDLowRequestAudioStatus(u32 subcmd, DVDLowCallback callback) { + Callback = callback; + StopAtNextInt = FALSE; + __DIRegs[2] = subcmd | 0xe2000000; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; } -/* 803482EC-80348388 342C2C 009C+00 0/0 3/3 0/0 .text DVDLowAudioBufferConfig */ -BOOL DVDLowAudioBufferConfig(s32 arg0, u32 arg1, DVDLowCallback cb) { - Callback = cb; - StopAtNextInt = FALSE; - __DIRegs[2] = arg1 | ((arg0 ? 0x10000 : 0) | 0xe4000000); - __DIRegs[7] = 1; - __setAlarm(10); - return 1; +BOOL DVDLowAudioBufferConfig(BOOL enable, u32 size, DVDLowCallback callback) { +#ifdef DEBUG + u32 bufSize; + u32 trigger; +#endif + + Callback = callback; + StopAtNextInt = FALSE; + +#ifdef DEBUG + bufSize = size & 0xF; + trigger = (size >> 4) & 0xF; + ASSERTLINE(1242, bufSize < 16); + ASSERTLINE(1243, trigger <= 2); +#endif + + __DIRegs[2] = 0xe4000000 | (enable != 0 ? 0x10000 : 0) | size; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; } -/* 80348388-80348444 342CC8 00BC+00 0/0 1/1 0/0 .text DVDLowReset */ -void DVDLowReset() { - u32 reg; - OSTime startTime; - __DIRegs[1] = 2; - reg = __PIRegs[9]; - __PIRegs[9] = (reg & ~4) | 1; - startTime = __OSGetSystemTime(); +void DVDLowReset(void) { + u32 reg; + OSTime resetStart; - while (__OSGetSystemTime() - startTime < OSMicrosecondsToTicks(12)) - ; + __DIRegs[1] = 2; + reg = __PIRegs[9]; + __PIRegs[9] = (reg & ~4) | 1; - __PIRegs[9] = reg | 5; - ResetOccurred = TRUE; - LastResetEnd = __OSGetSystemTime(); + resetStart = __OSGetSystemTime(); + while ((__OSGetSystemTime() - resetStart) < OSMicrosecondsToTicks(12)) + ; + + __PIRegs[9] = reg | 4 | 1; + ResetOccurred = TRUE; + LastResetEnd = __OSGetSystemTime(); } -/* 80348444-80348458 342D84 0014+00 0/0 1/1 0/0 .text DVDLowBreak */ -BOOL DVDLowBreak() { - StopAtNextInt = TRUE; - Breaking = TRUE; - return TRUE; -} +DVDLowCallback DVDLowSetResetCoverCallback(DVDLowCallback callback) { + DVDLowCallback old; + BOOL enabled; -/* 80348458-80348474 342D98 001C+00 0/0 1/1 0/0 .text DVDLowClearCallback */ -DVDLowCallback DVDLowClearCallback() { - DVDLowCallback rv; - __DIRegs[1] = 0; - rv = Callback; - WaitingCoverClose = FALSE; - Callback = NULL; - return rv; -} - -/* 80348474-803484B8 342DB4 0044+00 1/1 0/0 0/0 .text __DVDLowSetWAType */ -void __DVDLowSetWAType(u32 arg0, u32 arg1) { - BOOL enabled = OSDisableInterrupts(); - WorkAroundType = arg0; - WorkAroundSeekLocation[0] = arg1; + enabled = OSDisableInterrupts(); + old = ResetCoverCallback; + ResetCoverCallback = callback; OSRestoreInterrupts(enabled); + return old; } -/* 803484B8-803484F0 342DF8 0038+00 0/0 1/1 0/0 .text __DVDLowTestAlarm */ -BOOL __DVDLowTestAlarm(OSAlarm* alarm) { - if (alarm == &AlarmForBreak) { - return TRUE; +static void DoBreak(void) { + u32 statusReg; + + statusReg = __DIRegs[0]; + statusReg |= 0x40 | 1; + __DIRegs[0] = statusReg; + Breaking = TRUE; +} + +static void AlarmHandlerForBreak(OSAlarm* alarm, OSContext* context) { + if (__DIRegs[6] < LastLength) { + DoBreak(); + } else { + SetBreakAlarm(OSMillisecondsToTicks(20)); + } +} + +static void SetBreakAlarm(OSTime timeout) { + OSCreateAlarm(&AlarmForBreak); + OSSetAlarm(&AlarmForBreak, timeout, AlarmHandlerForBreak); +} + +BOOL DVDLowBreak(void) { + StopAtNextInt = TRUE; + Breaking = TRUE; + return TRUE; +} + +DVDLowCallback DVDLowClearCallback(void) { + DVDLowCallback old; + __DIRegs[1] = 0; + WaitingCoverClose = FALSE; + old = Callback; + Callback = NULL; + return old; +} + +u32 DVDLowGetCoverStatus(void) { + if ((__OSGetSystemTime() - LastResetEnd) < OSMillisecondsToTicks(100)) { + return 0; } + if (__DIRegs[1] & 1) { + return 1; + } + + return 2; +} + +void __DVDLowSetWAType(u32 type, s32 seekLoc) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + ASSERTLINE(1491, type < DVD_WATYPE_MAX); + WorkAroundType = type; + WorkAroundSeekLocation = seekLoc; + OSRestoreInterrupts(enabled); +} + +int __DVDLowTestAlarm(const OSAlarm* alarm) { + if (alarm == &AlarmForBreak) { + return 1; + } if (alarm == &AlarmForTimeout) { - return TRUE; + return 1; } - return FALSE; -} \ No newline at end of file + return 0; +} diff --git a/src/dolphin/dvd/dvdqueue.c b/src/dolphin/dvd/dvdqueue.c index 2b0e4e4997..2106f8cdad 100644 --- a/src/dolphin/dvd/dvdqueue.c +++ b/src/dolphin/dvd/dvdqueue.c @@ -1,52 +1,37 @@ -#include "dolphin/dvd/dvdqueue.h" -#include "dolphin/dvd.h" +#include +#include -void __DVDClearWaitingQueue(); -BOOL __DVDPushWaitingQueue(s32 prio, DVDCommandBlock* block); -DVDCommandBlock* __DVDPopWaitingQueue(void); -BOOL __DVDCheckWaitingQueue(void); -BOOL __DVDDequeueWaitingQueue(DVDCommandBlock* block); +#include "__dvd.h" -#define MAX_QUEUES 4 +static struct { + /* 0x00 */ DVDCommandBlock* next; + /* 0x04 */ DVDCommandBlock* prev; +} WaitingQueue[4]; -typedef struct { - DVDCommandBlock* next; - DVDCommandBlock* prev; -} DVDQueue; +// prototypes +static DVDCommandBlock* PopWaitingQueuePrio(s32 prio); -/* 8044C998-8044C9B8 0796B8 0020+00 4/4 0/0 0/0 .bss WaitingQueue */ -static DVDQueue WaitingQueue[MAX_QUEUES]; - -/* 8034B874-8034B8AC 3461B4 0038+00 0/0 5/5 0/0 .text __DVDClearWaitingQueue */ void __DVDClearWaitingQueue(void) { u32 i; + DVDCommandBlock* q; - for (i = 0; i < MAX_QUEUES; i++) { - DVDCommandBlock* q; - - q = (DVDCommandBlock*)&(WaitingQueue[i]); + for(i = 0; i < 4; i++) { + q = (DVDCommandBlock*)&WaitingQueue[i].next; q->next = q; q->prev = q; } } -/* 8034B8AC-8034B914 3461EC 0068+00 0/0 5/5 0/0 .text __DVDPushWaitingQueue */ -BOOL __DVDPushWaitingQueue(s32 prio, DVDCommandBlock* block) { - BOOL enabled; - DVDCommandBlock* q; - - enabled = OSDisableInterrupts(); - - q = (DVDCommandBlock*)&(WaitingQueue[prio]); +int __DVDPushWaitingQueue(s32 prio, DVDCommandBlock* block) { + BOOL enabled = OSDisableInterrupts(); + DVDCommandBlock* q = (DVDCommandBlock*)&WaitingQueue[prio]; q->prev->next = block; block->prev = q->prev; block->next = q; q->prev = block; - OSRestoreInterrupts(enabled); - - return TRUE; + return 1; } static DVDCommandBlock* PopWaitingQueuePrio(s32 prio) { @@ -55,83 +40,133 @@ static DVDCommandBlock* PopWaitingQueuePrio(s32 prio) { DVDCommandBlock* q; enabled = OSDisableInterrupts(); - - q = (DVDCommandBlock*)&(WaitingQueue[prio]); + q = (DVDCommandBlock*)&WaitingQueue[prio]; + ASSERTLINE(87, q->next != q); tmp = q->next; q->next = tmp->next; tmp->next->prev = q; - OSRestoreInterrupts(enabled); - - tmp->next = (DVDCommandBlock*)NULL; - tmp->prev = (DVDCommandBlock*)NULL; - + tmp->next = 0; + tmp->prev = 0; return tmp; } -/* 8034B914-8034B9B4 346254 00A0+00 0/0 2/2 0/0 .text __DVDPopWaitingQueue */ DVDCommandBlock* __DVDPopWaitingQueue(void) { u32 i; BOOL enabled; DVDCommandBlock* q; enabled = OSDisableInterrupts(); - - for (i = 0; i < MAX_QUEUES; i++) { - q = (DVDCommandBlock*)&(WaitingQueue[i]); + for (i = 0; i < 4; i++) { + q = (DVDCommandBlock*)&WaitingQueue[i]; if (q->next != q) { OSRestoreInterrupts(enabled); - return PopWaitingQueuePrio((s32)i); + return PopWaitingQueuePrio(i); } } OSRestoreInterrupts(enabled); - - return (DVDCommandBlock*)NULL; + return NULL; } -/* 8034B9B4-8034BA0C 3462F4 0058+00 0/0 1/1 0/0 .text __DVDCheckWaitingQueue */ -BOOL __DVDCheckWaitingQueue(void) { +int __DVDCheckWaitingQueue(void) { u32 i; BOOL enabled; DVDCommandBlock* q; enabled = OSDisableInterrupts(); - - for (i = 0; i < MAX_QUEUES; i++) { - q = (DVDCommandBlock*)&(WaitingQueue[i]); + for (i = 0; i < 4; i++) { + q = (DVDCommandBlock*)&WaitingQueue[i]; if (q->next != q) { OSRestoreInterrupts(enabled); - return TRUE; + return 1; } } OSRestoreInterrupts(enabled); - - return FALSE; + return 0; } -/* 8034BA0C-8034BA6C 34634C 0060+00 0/0 1/1 0/0 .text __DVDDequeueWaitingQueue */ -BOOL __DVDDequeueWaitingQueue(DVDCommandBlock* block) { +int __DVDDequeueWaitingQueue(DVDCommandBlock* block) { BOOL enabled; DVDCommandBlock* prev; DVDCommandBlock* next; enabled = OSDisableInterrupts(); - prev = block->prev; next = block->next; - - if ((prev == (DVDCommandBlock*)NULL) || (next == (DVDCommandBlock*)NULL)) { + if (prev == NULL || next == NULL) { OSRestoreInterrupts(enabled); - return FALSE; + return 0; } - prev->next = next; next->prev = prev; - OSRestoreInterrupts(enabled); + return 1; +} - return TRUE; -} \ No newline at end of file +int __DVDIsBlockInWaitingQueue(DVDCommandBlock* block) { + u32 i; + DVDCommandBlock* start; + DVDCommandBlock* q; + + for (i = 0; i < 4; i++) { + start = (DVDCommandBlock*)&WaitingQueue[i]; + if (start->next == start) { + continue; + } + + for (q = start->next; q != start; q = q->next) { + if (q == block) { + return 1; + } + } + } + + return 0; +} + +static char* CommandNames[16] = { + "", + "READ", + "SEEK", + "CHANGE_DISK", + "BSREAD", + "READID", + "INITSTREAM", + "CANCELSTREAM", + "STOP_STREAM_AT_END", + "REQUEST_AUDIO_ERROR", + "REQUEST_PLAY_ADDR", + "REQUEST_START_ADDR", + "REQUEST_LENGTH", + "AUDIO_BUFFER_CONFIG", + "INQUIRY", + "BS_CHANGE_DISK", +}; + +void DVDDumpWaitingQueue(void) { + u32 i; + DVDCommandBlock* start; + DVDCommandBlock* q; + + OSReport("==== DVD Waiting Queue Status ====\n"); + for (i = 0; i < 4; i++) { + OSReport("< Queue #%d > ", i); + start = (DVDCommandBlock*)&WaitingQueue[i]; + if (start->next == start) { + OSReport("None\n"); + } else { + OSReport("\n"); + for (q = start->next; q != start; q = q->next) { + OSReport("0x%08x: Command: %s ", q, CommandNames[q->command]); + if (q->command == 1) { + OSReport("Disk offset: %d, Length: %d, Addr: 0x%08x\n", q->offset, q->length, q->addr); + } else { + OSReport("\n"); + } + } + } + } +} diff --git a/src/dolphin/dvd/fstload.c b/src/dolphin/dvd/fstload.c index d1c684ae6f..555517ddf1 100644 --- a/src/dolphin/dvd/fstload.c +++ b/src/dolphin/dvd/fstload.c @@ -1,30 +1,35 @@ -#include "dolphin/dvd/fstload.h" -#include "dolphin/dvd.h" -#include "dolphin/os.h" +#include +#include +#include -/* 804517D0-804517D4 000CD0 0004+00 1/1 0/0 0/0 .sbss status */ -static s32 status; +#include "__dvd.h" -/* 804517D4-804517D8 000CD4 0004+00 2/2 0/0 0/0 .sbss bb2 */ +static u8 bb2Buf[63]; + +static u32 status; static DVDBB2* bb2; - -/* 804517D8-804517E0 000CD8 0004+04 2/2 0/0 0/0 .sbss idTmp */ static DVDDiskID* idTmp; -/* 8034BD2C-8034BE04 34666C 00D8+00 1/1 0/0 0/0 .text cb */ +// prototypes +static void cb(s32 result, DVDCommandBlock* block); + static void cb(s32 result, DVDCommandBlock* block) { if (result > 0) { - switch (status) { + switch(status) { case 0: status = 1; - DVDReadAbsAsyncForBS(block, bb2, OSRoundUp32B(sizeof(bb2)), 0x420, cb); - break; + DVDReadAbsAsyncForBS(block, bb2, 0x20, 0x420, cb); + return; case 1: status = 2; - DVDReadAbsAsyncForBS(block, bb2->FSTAddress, OSRoundUp32B(bb2->FSTLength), - bb2->FSTPosition, cb); + DVDReadAbsAsyncForBS(block, bb2->FSTAddress, (bb2->FSTLength + 0x1F) & 0xFFFFFFE0, bb2->FSTPosition, cb); + default: + return; } - } else if (result == -1) { + } + + if (result == -1) { + return; } else if (result == -4) { status = 0; DVDReset(); @@ -32,44 +37,50 @@ static void cb(s32 result, DVDCommandBlock* block) { } } -/* 8044C9B8-8044C9F8 0796D8 003F+01 1/1 0/0 0/0 .bss bb2Buf */ -static u8 bb2Buf[OSRoundUp32B(sizeof(DVDBB2)) + 31]; - -/* 8044C9F8-8044CA28 079718 0030+00 1/1 0/0 0/0 .bss block$18 */ -static u8 block[48]; - -/* 8034BE04-8034BF6C 346744 0168+00 0/0 1/1 0/0 .text __fstLoad */ void __fstLoad(void) { OSBootInfo* bootInfo; DVDDiskID* id; - u8 idTmpBuf[sizeof(DVDDiskID) + 31]; - static DVDCommandBlock block; + u8 idTmpBuf[63]; + s32 state; void* arenaHi; + static DVDCommandBlock block; arenaHi = OSGetArenaHi(); - bootInfo = (OSBootInfo*)OSPhysicalToCached(0); - - idTmp = (DVDDiskID*)(OSRoundUp32B(idTmpBuf)); - bb2 = (DVDBB2*)(OSRoundUp32B(bb2Buf)); + bootInfo = (void*)OSPhysicalToCached(0); + idTmp = (void*)OSRoundUp32B(idTmpBuf); + bb2 = (void*)OSRoundUp32B(bb2Buf); DVDReset(); DVDReadDiskID(&block, idTmp, cb); - while (DVDGetDriveStatus() != 0) - ; - bootInfo->fst_location = bb2->FSTAddress; - bootInfo->fst_max_length = bb2->FSTMaxLength; + while (1) { + state = DVDGetDriveStatus(); + if (state == 0) { + break; + } - id = &bootInfo->disk_info; + // weird switch that seemingly wont do anything but break out of its own switch. What was this for? Early DVD development pre-hardware? + switch(state) { + case DVD_STATE_FATAL_ERROR: break; + case DVD_STATE_BUSY: break; + case DVD_STATE_WAITING: break; + case DVD_STATE_COVER_CLOSED: break; + case DVD_STATE_NO_DISK: break; + case DVD_STATE_COVER_OPEN: break; + case DVD_STATE_MOTOR_STOPPED: break; + } + } - memcpy(id, idTmp, sizeof(DVDDiskID)); + bootInfo->FSTLocation = (void*)bb2->FSTAddress; + bootInfo->FSTMaxLength = bb2->FSTMaxLength; + id = &bootInfo->DVDDiskID; + memcpy(id, idTmp, 0x20); OSReport("\n"); - OSReport(" Game Name ... %c%c%c%c\n", id->game_name[0], id->game_name[1], id->game_name[2], - id->game_name[3]); + OSReport(" Game Name ... %c%c%c%c\n", id->gameName[0], id->gameName[1], id->gameName[2], id->gameName[3]); OSReport(" Company ..... %c%c\n", id->company[0], id->company[1]); - OSReport(" Disk # ...... %d\n", id->disk_number); - OSReport(" Game ver .... %d\n", id->game_version); - OSReport(" Streaming ... %s\n", (id->is_streaming == 0) ? "OFF" : "ON"); + OSReport(" Disk # ...... %d\n", id->diskNumber); + OSReport(" Game ver .... %d\n", id->gameVersion); + OSReport(" Streaming ... %s\n", !(id->streaming) ? "OFF" : "ON"); OSReport("\n"); OSSetArenaHi(bb2->FSTAddress); -} \ No newline at end of file +} diff --git a/src/dolphin/exi/EXIAd16.c b/src/dolphin/exi/EXIAd16.c new file mode 100644 index 0000000000..668dcaa140 --- /dev/null +++ b/src/dolphin/exi/EXIAd16.c @@ -0,0 +1,101 @@ +#include +#include + +static BOOL Initialized; + +int AD16Init(void) { + int err; + u32 cmd; + u32 id; + + if (Initialized) { + return 1; + } + + if (!EXILock(2, 0, NULL)) { + return 0; + } + + if (!EXISelect(2, 0, EXI_FREQ_1M)) { + EXIUnlock(2); + return 0; + } + + cmd = 0; + err = 0; + err |= !EXIImm(2, &cmd, 2, EXI_WRITE, NULL); + err |= !EXISync(2); + err |= !EXIImm(2, &id, 4, EXI_READ, NULL); + err |= !EXISync(2); + err |= !EXIDeselect(2); + + EXIUnlock(2); + if (err != 0 || (id - 0x04120000) != 0) { + return 0; + } + + Initialized = TRUE; + return 1; +} + +int AD16WriteReg(u32 word) { + int err; + u32 cmd; + + if (!Initialized || !EXILock(2, 0, NULL)) { + return 0; + } + + if (!EXISelect(2, 0, EXI_FREQ_8M)) { + EXIUnlock(2); + return 0; + } + + cmd = 0xA0000000; + err = 0; + err |= !EXIImm(2, &cmd, 1, EXI_WRITE, NULL); + err |= !EXISync(2); + err |= !EXIImm(2, &word, 4, EXI_WRITE, NULL); + err |= !EXISync(2); + err |= !EXIDeselect(2); + + EXIUnlock(2); + if (err != 0) { + return 0; + } + + return 1; +} + +int AD16ReadReg(u32* word) { + int err; + u32 cmd; + + if (!Initialized || !EXILock(2, 0, NULL)) { + return 0; + } + + if (!EXISelect(2, 0, EXI_FREQ_8M)) { + EXIUnlock(2); + return 0; + } + + cmd = 0xA2000000; + err = 0; + err |= !EXIImm(2, &cmd, 1, EXI_WRITE, NULL); + err |= !EXISync(2); + err |= !EXIImm(2, word, 4, EXI_READ, NULL); + err |= !EXISync(2); + err |= !EXIDeselect(2); + + EXIUnlock(2); + if (err != 0) { + return 0; + } + + return 1; +} + +BOOL AD16Probe(void) { + return Initialized; +} diff --git a/src/dolphin/exi/EXIBios.c b/src/dolphin/exi/EXIBios.c index 40fe1e1acf..4f4465bcbe 100644 --- a/src/dolphin/exi/EXIBios.c +++ b/src/dolphin/exi/EXIBios.c @@ -1,50 +1,62 @@ -#include "dolphin/exi/EXIBios.h" -#include "dolphin/os.h" - -/* 804509C0-804509C8 -00001 0004+04 1/1 0/0 0/0 .sdata __EXIVersion */ -static char* __EXIVersion = "<< Dolphin SDK - EXI\trelease build: Apr 5 2004 04:14:14 (0x2301) >>"; +#include #define REG_MAX 5 #define REG(chan, idx) (__EXIRegs[((chan) * REG_MAX) + (idx)]) -#define CPR_CS(x) ((1u << (x)) << 7) -#define CPR_CLK(x) ((x) << 4) +#define STATE_IDLE 0 +#define STATE_DMA 1 +#define STATE_IMM 2 +#define STATE_BUSY 3 +#define STATE_SELECTED 4 +#define STATE_ATTACHED 8 +#define STATE_LOCKED 16 -#define EXI_0CR(tstart, dma, rw, tlen) \ - ((((u32)(tstart)) << 0) | (((u32)(dma)) << 1) | (((u32)(rw)) << 2) | (((u32)(tlen)) << 4)) +#define MAX_CHAN 3 -static void SetExiInterruptMask(s32 chan, EXIControl* exi); -BOOL __EXIProbe(s32 chan); -static u32 EXIClearInterrupts(s32 chan, BOOL exi, BOOL tc, BOOL ext); -static void EXIIntrruptHandler(s16 interrupt, OSContext* context); -static void TCIntrruptHandler(s16 interrupt, OSContext* context); -static void EXTIntrruptHandler(s16 interrupt, OSContext* context); +#define MAX_IMM 4 +#define MAX_TYPE 3 +#define MAX_DEV 3 +#define MAX_FREQ 6 + +#define EXI_0LENGTH_EXILENGTH_MASK 0x03FFFFE0 + +#if DEBUG +const char * __EXIVersion = "<< Dolphin SDK - EXI\tdebug build: Apr 5 2004 03:55:29 (0x2301) >>"; +#else +const char * __EXIVersion = "<< Dolphin SDK - EXI\trelease build: Apr 5 2004 04:14:14 (0x2301) >>"; +#endif -/* 8044C570-8044C630 079290 00C0+00 20/20 0/0 0/0 .bss Ecb */ static EXIControl Ecb[3]; +static u32 IDSerialPort1; + +// external functions +extern void __OSEnableBarnacle(s32 chan, u32 dev); + +// prototypes +u32 EXIClearInterrupts(s32 chan, int exi, int tc, int ext); +static int __EXIProbe(s32 chan); -/* 80342C0C-80342D00 33D54C 00F4+00 4/4 0/0 0/0 .text SetExiInterruptMask */ static void SetExiInterruptMask(s32 chan, EXIControl* exi) { EXIControl* exi2; - exi2 = &Ecb[2]; + switch (chan) { case 0: - if ((exi->exiCallback == 0 && exi2->exiCallback == 0) || (exi->state & EXI_STATE_LOCKED)) { + if ((exi->exiCallback == 0 && exi2->exiCallback == 0) || (exi->state & STATE_LOCKED)) { __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_2_EXI); } else { __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_2_EXI); } break; case 1: - if (exi->exiCallback == 0 || (exi->state & EXI_STATE_LOCKED)) { + if (exi->exiCallback == 0 || (exi->state & STATE_LOCKED)) { __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXI); } else { __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXI); } break; case 2: - if (__OSGetInterruptHandler(OS_INTR_PI_DEBUG) == 0 || (exi->state & EXI_STATE_LOCKED)) { + if (__OSGetInterruptHandler(__OS_INTERRUPT_PI_DEBUG) == 0 || (exi->state & STATE_LOCKED)) { __OSMaskInterrupts(OS_INTERRUPTMASK_PI_DEBUG); } else { __OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_DEBUG); @@ -53,167 +65,184 @@ static void SetExiInterruptMask(s32 chan, EXIControl* exi) { } } -/* 80342D00-80342F5C 33D640 025C+00 2/2 9/9 0/0 .text EXIImm */ -s32 EXIImm(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) { - EXIControl* exi = &Ecb[chan]; - BOOL enabled; - - enabled = OSDisableInterrupts(); - if ((exi->state & EXI_STATE_BUSY) || !(exi->state & EXI_STATE_SELECTED)) { - OSRestoreInterrupts(enabled); - return FALSE; - } - - exi->tcCallback = callback; - if (exi->tcCallback) { - EXIClearInterrupts(chan, FALSE, TRUE, FALSE); - __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_TC >> (3 * chan)); - } - - exi->state |= EXI_STATE_IMM; - - if (type != EXI_READ) { - u32 data; - int i; - - data = 0; - for (i = 0; i < len; i++) { - data |= ((u8*)buf)[i] << ((3 - i) * 8); - } - REG(chan, 4) = data; - } - - exi->immBuf = buf; - exi->immLen = (type != EXI_WRITE) ? len : 0; - - REG(chan, 3) = EXI_0CR(1, 0, type, len - 1); - - OSRestoreInterrupts(enabled); - - return TRUE; -} - -/* 80342F5C-80342FFC 33D89C 00A0+00 0/0 7/7 0/0 .text EXIImmEx */ -s32 EXIImmEx(s32 chan, void* buf, s32 len, u32 mode) { - s32 xLen; - - while (len) { - xLen = (len < 4) ? len : 4; - if (!EXIImm(chan, buf, xLen, mode, NULL)) { - return FALSE; - } - - if (!EXISync(chan)) { - return FALSE; - } - - (u8*)buf += xLen; - len -= xLen; - } - return TRUE; -} - -/* 80342FFC-803430E8 33D93C 00EC+00 0/0 4/4 0/0 .text EXIDma */ -BOOL EXIDma(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) { - EXIControl* exi = &Ecb[chan]; - BOOL enabled; - - enabled = OSDisableInterrupts(); - if ((exi->state & EXI_STATE_BUSY) || !(exi->state & EXI_STATE_SELECTED)) { - OSRestoreInterrupts(enabled); - return FALSE; - } - - exi->tcCallback = callback; - if (exi->tcCallback) { - EXIClearInterrupts(chan, FALSE, TRUE, FALSE); - __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_TC >> (3 * chan)); - } - - exi->state |= EXI_STATE_DMA; - - REG(chan, 1) = (u32)buf & 0x3ffffe0; - REG(chan, 2) = (u32)len; - REG(chan, 3) = EXI_0CR(1, 1, type, 0); - - OSRestoreInterrupts(enabled); - - return TRUE; -} - static void CompleteTransfer(s32 chan) { - EXIControl* exi = &Ecb[chan]; + EXIControl* exi; u8* buf; u32 data; int i; int len; - if (exi->state & EXI_STATE_BUSY) { - if ((exi->state & EXI_STATE_IMM) && (len = exi->immLen)) { - buf = exi->immBuf; - data = REG(chan, 4); - for (i = 0; i < len; i++) { - *buf++ = (u8)((data >> ((3 - i) * 8)) & 0xff); + exi = &Ecb[chan]; + ASSERTLINE(366, 0 <= chan && chan < MAX_CHAN); + + if (exi->state & STATE_BUSY) { + if (exi->state & STATE_IMM) { + if ((len = exi->immLen) != 0) { + buf = exi->immBuf; + data = __EXIRegs[(chan * 5) + 4]; + for(i = 0; i < len; i++) { + *buf++ = data >> ((3 - i) * 8); + } } } - exi->state &= ~EXI_STATE_BUSY; + exi->state &= ~STATE_BUSY; } } -/* 803430E8-80343334 33DA28 024C+00 2/2 9/9 0/0 .text EXISync */ -BOOL EXISync(s32 chan) { - EXIControl* exi = &Ecb[chan]; - BOOL rc = FALSE; +int EXIImm(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) { + EXIControl* exi; + BOOL enabled; + u32 data; + int i; + + exi = &Ecb[chan]; + ASSERTLINE(404, exi->state & STATE_SELECTED); + ASSERTLINE(405, 0 <= chan && chan < MAX_CHAN); + ASSERTLINE(406, 0 < len && len <= MAX_IMM); + ASSERTLINE(407, type < MAX_TYPE); + enabled = OSDisableInterrupts(); + + if ((exi->state & STATE_BUSY) || !(exi->state & STATE_SELECTED)) { + OSRestoreInterrupts(enabled); + return 0; + } + + exi->tcCallback = callback; + if (exi->tcCallback) { + EXIClearInterrupts(chan, 0, 1, 0); + __OSUnmaskInterrupts(0x200000U >> (chan * 3)); + } + + exi->state |= STATE_IMM; + if (type != 0) { + data = 0; + for(i = 0; i < len; i++) { + data |= ((u8*)buf)[i] << ((3 - i) * 8); + } + __EXIRegs[(chan * 5) + 4] = data; + } + + exi->immBuf = buf; + exi->immLen = (type != 1) ? len : 0; + __EXIRegs[(chan * 5) + 3] = (type << 2) | 1 | ((len - 1) << 4); + OSRestoreInterrupts(enabled); + return 1; +} + +int EXIImmEx(s32 chan, void* buf, s32 len, u32 mode) { + s32 xLen; + + while (len) { + xLen = (len < 4) ? len : 4; + if (EXIImm(chan, buf, xLen, mode, 0) == 0) { + return 0; + } + if (EXISync(chan) == 0) { + return 0; + } + ((u8*)buf) += xLen; + len -= xLen; + } + + return 1; +} + +int EXIDma(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) { + EXIControl* exi; BOOL enabled; - while (exi->state & EXI_STATE_SELECTED) { - if (((REG(chan, 3) & 1) >> 0) == 0) { + exi = &Ecb[chan]; + + ASSERTLINE(509, exi->state & STATE_SELECTED); + ASSERTLINE(510, OFFSET(buf, 32) == 0); + ASSERTLINE(511, 0 < len && OFFSET(len, 32) == 0); + ASSERTLINE(513, ((u32) len & ~EXI_0LENGTH_EXILENGTH_MASK) == 0); + ASSERTLINE(515, type == EXI_READ || type == EXI_WRITE); + + enabled = OSDisableInterrupts(); + if ((exi->state & STATE_BUSY) || !(exi->state & STATE_SELECTED)) { + OSRestoreInterrupts(enabled); + return 0; + } + + exi->tcCallback = callback; + if ((u32)exi->tcCallback) { + EXIClearInterrupts(chan, 0, 1, 0); + __OSUnmaskInterrupts(0x200000U >> (chan * 3)); + } + + exi->state |= STATE_DMA; + __EXIRegs[(chan * 5) + 1] = (u32)buf & EXI_0LENGTH_EXILENGTH_MASK; + __EXIRegs[(chan * 5) + 2] = len; + __EXIRegs[(chan * 5) + 3] = (type * 4) | 3; + + OSRestoreInterrupts(enabled); + return 1; +} + +int EXISync(s32 chan) { + EXIControl* exi; + int rc; + BOOL enabled; + + exi = &Ecb[chan]; + rc = 0; + ASSERTLINE(565, 0 <= chan && chan < MAX_CHAN); + + while ((exi->state & STATE_SELECTED)) { + if (!(__EXIRegs[(chan * 5) + 3] & 1)) { enabled = OSDisableInterrupts(); - if (exi->state & EXI_STATE_SELECTED) { + if (exi->state & STATE_SELECTED) { CompleteTransfer(chan); - if (__OSGetDIConfig() != 0xff || (OSGetConsoleType() & 0xf0000000) == 0x20000000 || - exi->immLen != 4 || (REG(chan, 0) & 0x00000070) != (EXI_FREQ_1M << 4) || - (REG(chan, 4) != EXI_USB_ADAPTER && REG(chan, 4) != EXI_IS_VIEWER && - REG(chan, 4) != 0x04220001) || - __OSDeviceCode == 0x8200) - { - rc = TRUE; + if (__OSGetDIConfig() != 0xFF || (OSGetConsoleType() & 0xf0000000) == 0x20000000 || exi->immLen != 4 || (__EXIRegs[chan * 5] & 0x70) || (__EXIRegs[(chan * 5) + 4] != 0x01010000 && __EXIRegs[(chan * 5) + 4] != 0x05070000 && __EXIRegs[(chan * 5) + 4] != 0x04220001) || __OSDeviceCode == 0x8200) { + rc = 1; } } OSRestoreInterrupts(enabled); break; } } + + ASSERTLINE(593, !(exi->state & STATE_BUSY)); return rc; } -/* 80343334-8034337C 33DC74 0048+00 4/4 0/0 0/0 .text EXIClearInterrupts */ -u32 EXIClearInterrupts(s32 chan, BOOL exi, BOOL tc, BOOL ext) { +u32 EXIClearInterrupts(s32 chan, int exi, int tc, int ext) { u32 cpr; u32 prev; - prev = cpr = REG(chan, 0); - cpr &= 0x7f5; - if (exi) - cpr |= 2; - if (tc) - cpr |= 8; - if (ext) - cpr |= 0x800; - REG(chan, 0) = cpr; - return prev; + ASSERTLINE(614, 0 <= chan && chan < MAX_CHAN); + + cpr = prev = __EXIRegs[(chan * 5)]; + prev &= 0x7F5; + + if (exi != 0) { + prev |= 2; + } + + if (tc != 0) { + prev |= 8; + } + + if (ext != 0) { + prev |= 0x800; + } + + __EXIRegs[(chan * 5)] = prev; + return cpr; } -/* 8034337C-803433F8 33DCBC 007C+00 0/0 6/6 0/0 .text EXISetExiCallback */ EXICallback EXISetExiCallback(s32 chan, EXICallback exiCallback) { - EXIControl* exi = &Ecb[chan]; + EXIControl* exi; EXICallback prev; BOOL enabled; + exi = &Ecb[chan]; + ASSERTLINE(648, 0 <= chan && chan < MAX_CHAN); enabled = OSDisableInterrupts(); + prev = exi->exiCallback; exi->exiCallback = exiCallback; - if (chan != 2) { SetExiInterruptMask(chan, exi); } else { @@ -224,337 +253,394 @@ EXICallback EXISetExiCallback(s32 chan, EXICallback exiCallback) { return prev; } -s32 __EXIProbeStartTime[2] : (OS_BASE_CACHED | 0x30C0); +void EXIProbeReset() { + __gUnknown800030C0[0] = __gUnknown800030C0[1] = 0; + Ecb[0].idTime = Ecb[1].idTime = 0; + __EXIProbe(0); + __EXIProbe(1); +} -/* 803433F8-8034356C 33DD38 0174+00 7/7 0/0 0/0 .text __EXIProbe */ -static BOOL __EXIProbe(s32 chan) { - EXIControl* exi = &Ecb[chan]; +static int __EXIProbe(s32 chan) { + EXIControl* exi; BOOL enabled; - BOOL rc; + int rc; u32 cpr; s32 t; + exi = &Ecb[chan]; + ASSERTLINE(703, 0 <= chan && chan < MAX_CHAN); if (chan == 2) { - return TRUE; + return 1; } - rc = TRUE; + rc = 1; enabled = OSDisableInterrupts(); - cpr = REG(chan, 0); - if (!(exi->state & EXI_STATE_ATTACHED)) { - if (cpr & 0x00000800) { - EXIClearInterrupts(chan, FALSE, FALSE, TRUE); - __EXIProbeStartTime[chan] = exi->idTime = 0; + cpr = __EXIRegs[(chan * 5)]; + + if (!(exi->state & STATE_ATTACHED)) { + if (cpr & 0x800) { + EXIClearInterrupts(chan, 0, 0, 1); + __gUnknown800030C0[chan] = exi->idTime = 0; } - if (cpr & 0x00001000) { - t = (s32)(OSTicksToMilliseconds(OSGetTime()) / 100) + 1; - if (__EXIProbeStartTime[chan] == 0) { - __EXIProbeStartTime[chan] = t; + if (cpr & 0x1000) { + t = ((s32)(OSTicksToMilliseconds(OSGetTime()) / 100) + 1); + + if (__gUnknown800030C0[chan] == 0) { + __gUnknown800030C0[chan] = t; } - if (t - __EXIProbeStartTime[chan] < 300 / 100) { - rc = FALSE; + + if (t - (s32)__gUnknown800030C0[chan] < 3) { + rc = 0; } } else { - __EXIProbeStartTime[chan] = exi->idTime = 0; - rc = FALSE; + __gUnknown800030C0[chan] = exi->idTime = 0; + rc = 0; } - } else if (!(cpr & 0x00001000) || (cpr & 0x00000800)) { - __EXIProbeStartTime[chan] = exi->idTime = 0; - rc = FALSE; + } else if(!(cpr & 0x1000) || (cpr & 0x800)) { + __gUnknown800030C0[chan] = exi->idTime = 0; + rc = 0; } + OSRestoreInterrupts(enabled); - return rc; } -/* 8034356C-803435EC 33DEAC 0080+00 0/0 5/5 0/0 .text EXIProbe */ -BOOL EXIProbe(s32 chan) { +int EXIProbe(s32 chan) { EXIControl* exi = &Ecb[chan]; - BOOL rc; + int rc; u32 id; - + rc = __EXIProbe(chan); - if (rc && exi->idTime == 0) { - rc = EXIGetID(chan, 0, &id) ? TRUE : FALSE; + if (rc && !exi->idTime) { + rc = EXIGetID(chan, 0, &id) ? 1 : 0; } + return rc; } -/* 803435EC-803436A0 33DF2C 00B4+00 0/0 1/1 0/0 .text EXIProbeEx */ - s32 EXIProbeEx(s32 chan) { if (EXIProbe(chan)) { return 1; - } else if (__EXIProbeStartTime[chan] != 0) { + } + + if (__gUnknown800030C0[chan]) { return 0; - } else { - return -1; } + + return -1; } -/* 803436A0-803437AC 33DFE0 010C+00 0/0 2/2 0/0 .text EXIAttach */ -static BOOL __EXIAttach(s32 chan, EXICallback extCallback) { - EXIControl* exi = &Ecb[chan]; +static int __EXIAttach(s32 chan, EXICallback extCallback) { + EXIControl* exi; BOOL enabled; + exi = &Ecb[chan]; + ASSERTLINE(808, 0 <= chan && chan < 2); enabled = OSDisableInterrupts(); - if ((exi->state & EXI_STATE_ATTACHED) || __EXIProbe(chan) == FALSE) { + + if ((exi->state & STATE_ATTACHED) || !__EXIProbe(chan)) { OSRestoreInterrupts(enabled); - return FALSE; + return 0; } - EXIClearInterrupts(chan, TRUE, FALSE, FALSE); - + EXIClearInterrupts(chan, 1, 0, 0); exi->extCallback = extCallback; - __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT >> (3 * chan)); - exi->state |= EXI_STATE_ATTACHED; - OSRestoreInterrupts(enabled); + __OSUnmaskInterrupts(0x100000U >> (chan * 3)); + exi->state |= STATE_ATTACHED; - return TRUE; + OSRestoreInterrupts(enabled); + return 1; } -BOOL EXIAttach(s32 chan, EXICallback extCallback) { - EXIControl* exi = &Ecb[chan]; +int EXIAttach(s32 chan, EXICallback extCallback) { + EXIControl* exi; BOOL enabled; - BOOL rc; + int rc; + + exi = &Ecb[chan]; + ASSERTLINE(834, 0 <= chan && chan < 2); EXIProbe(chan); - enabled = OSDisableInterrupts(); if (exi->idTime == 0) { OSRestoreInterrupts(enabled); - return FALSE; + return 0; } + rc = __EXIAttach(chan, extCallback); OSRestoreInterrupts(enabled); return rc; } -/* 803437AC-80343868 33E0EC 00BC+00 0/0 3/3 0/0 .text EXIDetach */ -BOOL EXIDetach(s32 chan) { - EXIControl* exi = &Ecb[chan]; +int EXIDetach(s32 chan) { + EXIControl* exi; BOOL enabled; + exi = &Ecb[chan]; + ASSERTLINE(868, 0 <= chan && chan < 2); enabled = OSDisableInterrupts(); - if (!(exi->state & EXI_STATE_ATTACHED)) { + + if (!(exi->state & STATE_ATTACHED)) { OSRestoreInterrupts(enabled); - return TRUE; - } - if ((exi->state & EXI_STATE_LOCKED) && exi->dev == 0) { - OSRestoreInterrupts(enabled); - return FALSE; + return 1; } - exi->state &= ~EXI_STATE_ATTACHED; - __OSMaskInterrupts((OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_0_EXI) >> (3 * chan)); + if ((exi->state & STATE_LOCKED) && (exi->dev == 0)) { + OSRestoreInterrupts(enabled); + return 0; + } + + exi->state &= ~STATE_ATTACHED; + __OSMaskInterrupts(0x500000U >> (chan * 3)); + OSRestoreInterrupts(enabled); - return TRUE; + return 1; } -/* 80343868-80343994 33E1A8 012C+00 1/1 12/12 0/0 .text EXISelect */ -BOOL EXISelect(s32 chan, u32 dev, u32 freq) { - EXIControl* exi = &Ecb[chan]; +int EXISelectSD(s32 chan, u32 dev, u32 freq) { + EXIControl* exi; u32 cpr; BOOL enabled; + exi = &Ecb[chan]; + + ASSERTLINE(908, 0 <= chan && chan < MAX_CHAN); + ASSERTLINE(909, chan == 0 && dev < MAX_DEV || dev == 0); + ASSERTLINE(910, freq < MAX_FREQ); + ASSERTLINE(911, !(exi->state & STATE_SELECTED)); + enabled = OSDisableInterrupts(); - if ((exi->state & EXI_STATE_SELECTED) || - chan != 2 && (dev == 0 && !(exi->state & EXI_STATE_ATTACHED) && !__EXIProbe(chan) || - !(exi->state & EXI_STATE_LOCKED) || (exi->dev != dev))) - { + if ((exi->state & STATE_SELECTED) || ((chan != 2) && (((dev == 0) && !(exi->state & STATE_ATTACHED) && (EXIProbe(chan) == 0)) || !(exi->state & STATE_LOCKED) || (exi->dev != dev)))) { OSRestoreInterrupts(enabled); - return FALSE; + return 0; } - exi->state |= EXI_STATE_SELECTED; - cpr = REG(chan, 0); + exi->state |= STATE_SELECTED; + cpr = __EXIRegs[(chan * 5)]; cpr &= 0x405; - cpr |= CPR_CS(dev) | CPR_CLK(freq); - REG(chan, 0) = cpr; + cpr |= freq * 0x10; + __EXIRegs[(chan * 5)] = cpr; - if (exi->state & EXI_STATE_ATTACHED) { + if (exi->state & STATE_ATTACHED) { switch (chan) { case 0: - __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT); + __OSMaskInterrupts(0x100000U); break; case 1: - __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXT); + __OSMaskInterrupts(0x20000U); break; } } OSRestoreInterrupts(enabled); - return TRUE; + return 1; } -/* 80343994-80343AA4 33E2D4 0110+00 1/1 15/15 0/0 .text EXIDeselect */ -BOOL EXIDeselect(s32 chan) { - EXIControl* exi = &Ecb[chan]; +int EXISelect(s32 chan, u32 dev, u32 freq) { + EXIControl* exi; u32 cpr; BOOL enabled; - enabled = OSDisableInterrupts(); - if (!(exi->state & EXI_STATE_SELECTED)) { - OSRestoreInterrupts(enabled); - return FALSE; - } - exi->state &= ~EXI_STATE_SELECTED; - cpr = REG(chan, 0); - REG(chan, 0) = cpr & 0x405; + exi = &Ecb[chan]; - if (exi->state & EXI_STATE_ATTACHED) { + ASSERTLINE(966, 0 <= chan && chan < MAX_CHAN); + ASSERTLINE(967, chan == 0 && dev < MAX_DEV || dev == 0); + ASSERTLINE(968, freq < MAX_FREQ); + ASSERTLINE(969, !(exi->state & STATE_SELECTED)); + + enabled = OSDisableInterrupts(); + if ((exi->state & STATE_SELECTED) || ((chan != 2) && (((dev == 0) && !(exi->state & STATE_ATTACHED) && (__EXIProbe(chan) == 0)) || !(exi->state & STATE_LOCKED) || (exi->dev != dev)))) { + OSRestoreInterrupts(enabled); + return 0; + } + + exi->state |= STATE_SELECTED; + cpr = __EXIRegs[(chan * 5)]; + cpr &= 0x405; + cpr |= (((1 << dev) << 7) | (freq * 0x10)); + __EXIRegs[(chan * 5)] = cpr; + + if (exi->state & STATE_ATTACHED) { switch (chan) { case 0: - __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT); + __OSMaskInterrupts(0x100000U); break; case 1: - __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXT); + __OSMaskInterrupts(0x20000U); + break; + } + } + + OSRestoreInterrupts(enabled); + return 1; +} + +int EXIDeselect(s32 chan) { + EXIControl* exi; + u32 cpr; + BOOL enabled; + + exi = &Ecb[chan]; + ASSERTLINE(1020, 0 <= chan && chan < MAX_CHAN); + enabled = OSDisableInterrupts(); + + if (!(exi->state & STATE_SELECTED)) { + OSRestoreInterrupts(enabled); + return 0; + } + + exi->state &= ~STATE_SELECTED; + cpr = __EXIRegs[(chan * 5)]; + __EXIRegs[(chan * 5)] = cpr & 0x405; + + if (exi->state & STATE_ATTACHED) { + switch (chan) { + case 0: + __OSUnmaskInterrupts(0x100000U); + break; + case 1: + __OSUnmaskInterrupts(0x20000U); break; } } OSRestoreInterrupts(enabled); - if (chan != 2 && (cpr & CPR_CS(0))) { - return __EXIProbe(chan) ? TRUE : FALSE; + if ((chan != 2) && (cpr & 0x80)) { + if (__EXIProbe(chan) != 0) { + return 1; + } + return 0; } - return TRUE; + return 1; } -/* 80343AA4-80343B6C 33E3E4 00C8+00 1/1 0/0 0/0 .text EXIIntrruptHandler */ -static void EXIIntrruptHandler(s16 interrupt, OSContext* context) { +static void EXIIntrruptHandler(__OSInterrupt interrupt, OSContext* context) { s32 chan; EXIControl* exi; EXICallback callback; - chan = (interrupt - OS_INTR_EXI_0_EXI) / 3; + chan = (interrupt - 9) / 3; + + ASSERTLINE(1071, 0 <= chan && chan < MAX_CHAN); exi = &Ecb[chan]; - EXIClearInterrupts(chan, TRUE, FALSE, FALSE); + EXIClearInterrupts(chan, 1, 0, 0); + callback = exi->exiCallback; if (callback) { OSContext exceptionContext; OSClearContext(&exceptionContext); OSSetCurrentContext(&exceptionContext); - callback(chan, context); - OSClearContext(&exceptionContext); OSSetCurrentContext(context); } } -/* 80343B6C-80343D84 33E4AC 0218+00 1/1 0/0 0/0 .text TCIntrruptHandler */ -static void TCIntrruptHandler(s16 interrupt, OSContext* context) { - OSContext exceptionContext; +static void TCIntrruptHandler(__OSInterrupt interrupt, OSContext* context) { s32 chan; EXIControl* exi; EXICallback callback; - chan = (interrupt - OS_INTR_EXI_0_TC) / 3; + chan = (interrupt - 10) / 3; + + ASSERTLINE(1107, 0 <= chan && chan < MAX_CHAN); exi = &Ecb[chan]; - __OSMaskInterrupts(OS_INTERRUPTMASK(interrupt)); - EXIClearInterrupts(chan, FALSE, TRUE, FALSE); + __OSMaskInterrupts(0x80000000U >> interrupt); + EXIClearInterrupts(chan, 0, 1, 0); + callback = exi->tcCallback; if (callback) { - exi->tcCallback = 0; + OSContext exceptionContext; + + exi->tcCallback = NULL; CompleteTransfer(chan); OSClearContext(&exceptionContext); OSSetCurrentContext(&exceptionContext); - callback(chan, context); - OSClearContext(&exceptionContext); OSSetCurrentContext(context); } } -/* 80343D84-80343E54 33E6C4 00D0+00 1/1 0/0 0/0 .text EXTIntrruptHandler */ -static void EXTIntrruptHandler(s16 interrupt, OSContext* context) { +static void EXTIntrruptHandler(__OSInterrupt interrupt, OSContext* context) { s32 chan; EXIControl* exi; EXICallback callback; - chan = (interrupt - OS_INTR_EXI_0_EXT) / 3; - __OSMaskInterrupts((OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_0_EXI) >> (3 * chan)); + chan = (interrupt - 11) / 3; + + ASSERTLINE(1147, 0 <= chan && chan < 2); + __OSMaskInterrupts(0x500000U >> (chan * 3)); exi = &Ecb[chan]; callback = exi->extCallback; - exi->state &= ~EXI_STATE_ATTACHED; + exi->state &= ~STATE_ATTACHED; + if (callback) { OSContext exceptionContext; - + OSClearContext(&exceptionContext); OSSetCurrentContext(&exceptionContext); - - exi->extCallback = 0; + exi->extCallback = NULL; callback(chan, context); - OSClearContext(&exceptionContext); OSSetCurrentContext(context); } } -/* 804516D8-804516E0 000BD8 0004+04 2/2 0/0 0/0 .sbss IDSerialPort1 */ -static u32 IDSerialPort1[2 /* padding */]; +void EXIInit() { + u32 id; -/* 80343E54-80344028 33E794 01D4+00 0/0 1/1 0/0 .text EXIInit */ -void EXIInit(void) { - u32 idSerial; + while (((REG(0, 3) & 1) == 1) || ((REG(1, 3) & 1) == 1) || ((REG(2, 3) & 1) == 1)) {} - while (((REG(0, 3) & 1) == 1) || ((REG(1, 3) & 1) == 1) || ((REG(2, 3) & 1) == 1)) { - } + __OSMaskInterrupts(0x7F8000U); + __EXIRegs[0] = 0; + __EXIRegs[5] = 0; + __EXIRegs[10] = 0; + __EXIRegs[0] = 0x2000; + __OSSetInterruptHandler(9, EXIIntrruptHandler); + __OSSetInterruptHandler(10, TCIntrruptHandler); + __OSSetInterruptHandler(11, EXTIntrruptHandler); + __OSSetInterruptHandler(12, EXIIntrruptHandler); + __OSSetInterruptHandler(13, TCIntrruptHandler); + __OSSetInterruptHandler(14, EXTIntrruptHandler); + __OSSetInterruptHandler(15, EXIIntrruptHandler); + __OSSetInterruptHandler(16, TCIntrruptHandler); - __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_0_TC | - OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_1_EXI | - OS_INTERRUPTMASK_EXI_1_TC | OS_INTERRUPTMASK_EXI_1_EXT | - OS_INTERRUPTMASK_EXI_2_EXI | OS_INTERRUPTMASK_EXI_2_TC); + EXIGetID(0, 2, &IDSerialPort1); - REG(0, 0) = 0; - REG(1, 0) = 0; - REG(2, 0) = 0; - - REG(0, 0) = 0x00002000; - - __OSSetInterruptHandler(OS_INTR_EXI_0_EXI, EXIIntrruptHandler); - __OSSetInterruptHandler(OS_INTR_EXI_0_TC, TCIntrruptHandler); - __OSSetInterruptHandler(OS_INTR_EXI_0_EXT, EXTIntrruptHandler); - __OSSetInterruptHandler(OS_INTR_EXI_1_EXI, EXIIntrruptHandler); - __OSSetInterruptHandler(OS_INTR_EXI_1_TC, TCIntrruptHandler); - __OSSetInterruptHandler(OS_INTR_EXI_1_EXT, EXTIntrruptHandler); - __OSSetInterruptHandler(OS_INTR_EXI_2_EXI, EXIIntrruptHandler); - __OSSetInterruptHandler(OS_INTR_EXI_2_TC, TCIntrruptHandler); - - EXIGetID(0, 2, IDSerialPort1); if (__OSInIPL) { - __EXIProbeStartTime[0] = __EXIProbeStartTime[1] = 0; - Ecb[0].idTime = Ecb[1].idTime = 0; - __EXIProbe(0); - __EXIProbe(1); - } else if (EXIGetID(0, 0, &idSerial) && idSerial == 0x7010000) { + EXIProbeReset(); + } else if (EXIGetID(0, 0, &id) && id == 0x7010000) { __OSEnableBarnacle(1, 0); - } else if (EXIGetID(1, 0, &idSerial) && idSerial == 0x7010000) { + } else if (EXIGetID(1, 0, &id) && id == 0x7010000) { __OSEnableBarnacle(0, 2); } OSRegisterVersion(__EXIVersion); } -/* 80344028-8034411C 33E968 00F4+00 1/1 10/10 0/0 .text EXILock */ -BOOL EXILock(s32 chan, u32 dev, EXICallback unlockedCallback) { - EXIControl* exi = &Ecb[chan]; +int EXILock(s32 chan, u32 dev, EXICallback unlockedCallback) { + EXIControl* exi; BOOL enabled; int i; + exi = &Ecb[chan]; + ASSERTLINE(1259, 0 <= chan && chan < MAX_CHAN); + ASSERTLINE(1260, chan == 0 && dev < MAX_DEV || dev == 0); enabled = OSDisableInterrupts(); - if (exi->state & EXI_STATE_LOCKED) { + + if (exi->state & STATE_LOCKED) { if (unlockedCallback) { - for (i = 0; i < exi->items; i++) { + ASSERTLINE(1266, chan == 0 && exi->items < (MAX_DEV - 1) || exi->items == 0); + for(i = 0; i < exi->items; i++) { if (exi->queue[i].dev == dev) { OSRestoreInterrupts(enabled); - return FALSE; + return 0; } } exi->queue[exi->items].callback = unlockedCallback; @@ -562,76 +648,77 @@ BOOL EXILock(s32 chan, u32 dev, EXICallback unlockedCallback) { exi->items++; } OSRestoreInterrupts(enabled); - return FALSE; + return 0; } - exi->state |= EXI_STATE_LOCKED; + ASSERTLINE(1282, exi->items == 0); + exi->state |= STATE_LOCKED; exi->dev = dev; SetExiInterruptMask(chan, exi); - OSRestoreInterrupts(enabled); - return TRUE; + return 1; } -/* 8034411C-803441F8 33EA5C 00DC+00 0/0 14/14 0/0 .text EXIUnlock */ -BOOL EXIUnlock(s32 chan) { - EXIControl* exi = &Ecb[chan]; +int EXIUnlock(s32 chan) { + EXIControl* exi; BOOL enabled; EXICallback unlockedCallback; + exi = &Ecb[chan]; + ASSERTLINE(1306, 0 <= chan && chan < MAX_CHAN); enabled = OSDisableInterrupts(); - if (!(exi->state & EXI_STATE_LOCKED)) { - OSRestoreInterrupts(enabled); - return FALSE; - } - exi->state &= ~EXI_STATE_LOCKED; - SetExiInterruptMask(chan, exi); - if (0 < exi->items) { + if (!(exi->state & STATE_LOCKED)) { + OSRestoreInterrupts(enabled); + return 0; + } + + exi->state &= ~STATE_LOCKED; + SetExiInterruptMask(chan, exi); + if (exi->items > 0) { unlockedCallback = exi->queue[0].callback; - if (0 < --exi->items) { - memmove(&exi->queue[0], &exi->queue[1], sizeof(exi->queue[0]) * exi->items); + if (--exi->items > 0) { + memmove(&exi->queue[0], &exi->queue[1], exi->items * 8); } unlockedCallback(chan, 0); } OSRestoreInterrupts(enabled); - return TRUE; + return 1; } -/* 803441F8-80344210 33EB38 0018+00 0/0 2/2 0/0 .text EXIGetState */ u32 EXIGetState(s32 chan) { - EXIControl* exi = &Ecb[chan]; + EXIControl* exi; - return (u32)exi->state; + exi = &Ecb[chan]; + ASSERTLINE(1343, 0 <= chan && chan < MAX_CHAN); + return exi->state; } -/* 80344210-80344238 33EB50 0028+00 1/1 0/0 0/0 .text UnlockedHandler */ static void UnlockedHandler(s32 chan, OSContext* context) { u32 id; - EXIGetID(chan, 0, &id); } -/* 80344238-803445E8 33EB78 03B0+00 5/5 3/3 0/0 .text EXIGetID */ s32 EXIGetID(s32 chan, u32 dev, u32* id) { EXIControl* exi = &Ecb[chan]; - BOOL err; + int err; u32 cmd; s32 startTime; BOOL enabled; - if (chan == 0 && dev == 2 && IDSerialPort1[0] != 0) { - *id = IDSerialPort1[0]; + ASSERTLINE(1380, 0 <= chan && chan < MAX_CHAN); + if (chan == 0 && dev == 2 && IDSerialPort1 != 0) { + *id = IDSerialPort1; return 1; } - if (chan < 2 && dev == 0) { - if (!__EXIProbe(chan)) { + if ((chan < 2) && (dev == 0)) { + if ((__EXIProbe(chan) == 0)) { return 0; } - if (exi->idTime == __EXIProbeStartTime[chan]) { + if (exi->idTime == __gUnknown800030C0[chan]) { *id = exi->id; return exi->idTime; } @@ -640,41 +727,95 @@ s32 EXIGetID(s32 chan, u32 dev, u32* id) { return 0; } - startTime = __EXIProbeStartTime[chan]; + startTime = __gUnknown800030C0[chan]; } enabled = OSDisableInterrupts(); - err = !EXILock(chan, dev, (chan < 2 && dev == 0) ? UnlockedHandler : NULL); - if (!err) { - err = !EXISelect(chan, dev, EXI_FREQ_1M); - if (!err) { + err = !EXILock(chan, dev, (chan < 2 && dev == 0) ? &UnlockedHandler : NULL); + if (err == 0) { + err = !EXISelect(chan, dev, 0); + if (err == 0) { cmd = 0; - err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, NULL); + err |= !EXIImm(chan, &cmd, 2, 1, 0); err |= !EXISync(chan); - err |= !EXIImm(chan, id, 4, EXI_READ, NULL); + err |= !EXIImm(chan, id, 4, 0, 0); err |= !EXISync(chan); err |= !EXIDeselect(chan); } + EXIUnlock(chan); } OSRestoreInterrupts(enabled); - if (chan < 2 && dev == 0) { + if ((chan < 2) && (dev == 0)) { EXIDetach(chan); enabled = OSDisableInterrupts(); - err |= (startTime != __EXIProbeStartTime[chan]); + err |= __gUnknown800030C0[chan] != startTime; + if (!err) { exi->id = *id; exi->idTime = startTime; } + OSRestoreInterrupts(enabled); - return err ? 0 : exi->idTime; + if (err) { + return 0; + } + + return exi->idTime; } - return err ? 0 : !0; + if (err) { + return 0; + } + + return 1; +} + +s32 EXIGetType(s32 chan, u32 dev, u32* type) { + u32 _type; + s32 probe; + + probe = EXIGetID(chan, dev, &_type); + + if (!probe) { + return probe; + } + + switch (_type & ~0xFF) { + case 0x04020300: + case EXI_ETHER: + case 0x04020100: + case EXI_MIC: + *type = (_type & ~0xFF); + return probe; + default: + switch (_type & ~0xFFFF) { + case 0x00000000: + if (!(_type & 0x3803)) { + switch (_type & 0xFC) { + case EXI_MEMORY_CARD_59: + case EXI_MEMORY_CARD_123: + case EXI_MEMORY_CARD_251: + case EXI_MEMORY_CARD_507: + case EXI_MEMORY_CARD_1019: + case EXI_MEMORY_CARD_2043: + *type = _type & 0xFC; + return probe; + } + } + break; + case EXI_IS_VIEWER: + *type = EXI_IS_VIEWER; + return probe; + } + + *type = _type; + return probe; + } } char* EXIGetTypeString(u32 type) { @@ -693,18 +834,37 @@ char* EXIGetTypeString(u32 type) { return "Memory Card 2043"; case EXI_USB_ADAPTER: return "USB Adapter"; - case 0x80000000 | EXI_MEMORY_CARD_59: - case 0x80000000 | EXI_MEMORY_CARD_123: - case 0x80000000 | EXI_MEMORY_CARD_251: - case 0x80000000 | EXI_MEMORY_CARD_507: + case EXI_NPDP_GDEV: + return "GDEV"; + case EXI_MODEM: + return "Modem"; + case EXI_MARLIN: + return "Marlin"; + case EXI_AD16: + return "AD16"; + case EXI_RS232C: + return "RS232C"; + case 0x80000020: + case 0x80000080: + case 0x80000040: + case 0x80000008: + case 0x80000010: + case 0x80000004: return "Net Card"; case EXI_ETHER_VIEWER: return "Artist Ether"; - case EXI_MODEM: + case 0x4020100: + case 0x4020300: + case EXI_ETHER: + case 0x4220000: return "Broadband Adapter"; + case EXI_MIC: + return "Mic"; case EXI_STREAM_HANGER: return "Stream Hanger"; case EXI_IS_VIEWER: return "IS-DOL-VIEWER"; + default: + return "Unknown"; } -} \ No newline at end of file +} diff --git a/src/dolphin/exi/EXIUart.c b/src/dolphin/exi/EXIUart.c index 9aa9aa9c53..2d5c868aec 100644 --- a/src/dolphin/exi/EXIUart.c +++ b/src/dolphin/exi/EXIUart.c @@ -1,13 +1,20 @@ -#include "dolphin/exi/EXIUart.h" -#include "dolphin/exi/EXIBios.h" -#include "dolphin/os.h" +#include +#include +#include "__os.h" -#define EXI_TX 0x800400u -#define EXI_MAGIC 0xa5ff005a +static s32 Chan; +static u32 Dev; +static u32 Enabled; +static u32 BarnacleEnabled; + +// prototypes +int InitializeUART(void); +int ReadUARTN(void); +int WriteUARTN(void *buf, u32 len); +void __OSEnableBarnacle(s32 chan, u32 dev); -/* 803445E8-80344774 33EF28 018C+00 1/1 0/0 0/0 .text ProbeBarnacle */ static BOOL ProbeBarnacle(s32 chan, u32 dev, u32* revision) { - BOOL err; + int err; u32 cmd; if (chan != 2 && dev == 0 && !EXIAttach(chan, NULL)) { @@ -20,12 +27,13 @@ static BOOL ProbeBarnacle(s32 chan, u32 dev, u32* revision) { if (!err) { cmd = 0x20011300; err = FALSE; - err |= !EXIImm(chan, &cmd, 4, EXI_WRITE, NULL); + err |= !EXIImm(chan, &cmd, sizeof(cmd), EXI_WRITE, NULL); err |= !EXISync(chan); - err |= !EXIImm(chan, revision, 4, EXI_READ, NULL); + err |= !EXIImm(chan, revision, sizeof(revision), EXI_READ, NULL); err |= !EXISync(chan); err |= !EXIDeselect(chan); } + EXIUnlock(chan); } @@ -37,153 +45,150 @@ static BOOL ProbeBarnacle(s32 chan, u32 dev, u32* revision) { return FALSE; } - return (*revision != 0xFFFFFFFF) ? TRUE : FALSE; + if (*revision != 0xFFFFFFFF) { + return TRUE; + } + + return FALSE; } -/* 804516E0-804516E4 000BE0 0004+00 3/3 0/0 0/0 .sbss Chan */ -static s32 Chan; - -/* 804516E4-804516E8 000BE4 0004+00 3/3 0/0 0/0 .sbss Dev */ -static u32 Dev; - -/* 804516E8-804516EC 000BE8 0004+00 3/3 0/0 0/0 .sbss Enabled */ -static u32 Enabled; - -/* 804516EC-804516F0 000BEC 0004+00 2/2 0/0 0/0 .sbss BarnacleEnabled */ -static u32 BarnacleEnabled; - -/* 80344774-80344930 33F0B4 01BC+00 0/0 1/1 0/0 .text __OSEnableBarnacle */ void __OSEnableBarnacle(s32 chan, u32 dev) { u32 id; - if (EXIGetID(chan, dev, &id)) { - switch (id) { - case 0xffffffff: - case EXI_MEMORY_CARD_59: - case EXI_MEMORY_CARD_123: - case EXI_MEMORY_CARD_251: - case EXI_MEMORY_CARD_507: - case EXI_USB_ADAPTER: - case EXI_NPDP_GDEV: - case EXI_MODEM: - case EXI_MARLIN: - case 0x04220000: - case 0x04020100: - case 0x04020200: - case 0x04020300: - case 0x04040404: - case 0x04060000: - case 0x04120000: - case 0x04130000: - case 0x80000000 | EXI_MEMORY_CARD_59: - case 0x80000000 | EXI_MEMORY_CARD_123: - case 0x80000000 | EXI_MEMORY_CARD_251: - case 0x80000000 | EXI_MEMORY_CARD_507: - break; - default: - if (ProbeBarnacle(chan, dev, &id)) { - Chan = chan; - Dev = dev; - Enabled = BarnacleEnabled = EXI_MAGIC; - } + if (!EXIGetID(chan, dev, &id)) { + return; + } + + switch (id) { + case EXI_MEMORY_CARD_59: + case EXI_MEMORY_CARD_123: + case EXI_MEMORY_CARD_251: + case EXI_MEMORY_CARD_507: + case EXI_USB_ADAPTER: + case EXI_NPDP_GDEV: + case EXI_MODEM: + case 0x03010000: + case 0x04020100: + case EXI_ETHER: + case 0x04020300: + case 0x04220000: + case EXI_RS232C: + case EXI_MIC: + case EXI_AD16: + case EXI_STREAM_HANGER: + case 0x80000004: + case 0x80000008: + case 0x80000010: + case 0x80000020: + case 0xFFFFFFFF: + break; + default: + if (ProbeBarnacle(chan, dev, &id)) { + Chan = chan; + Dev = dev; + Enabled = BarnacleEnabled = 0xA5FF005A; break; } } } -/* 80344930-803449A0 33F270 0070+00 0/0 1/1 0/0 .text InitializeUART */ -u32 InitializeUART(u32 baudRate) { - if (BarnacleEnabled == EXI_MAGIC) { +int InitializeUART(void) { + if (BarnacleEnabled == 0xA5FF005A) { return 0; } - if (!(OSGetConsoleType() & OS_CONSOLE_DEVELOPMENT)) { + if ((OSGetConsoleType() & 0x10000000) == 0) { Enabled = 0; return 2; - } else { - Chan = 0; - Dev = 1; - Enabled = EXI_MAGIC; - return 0; } + + Chan = 0; + Dev = 1; + Enabled = 0xA5FF005A; + return 0; } -u32 ReadUARTN(void* bytes, unsigned long length) { +int ReadUARTN(void) { return 4; } static int QueueLength(void) { u32 cmd; - if (!EXISelect(Chan, Dev, EXI_FREQ_8M)) + if (EXISelect(Chan, Dev, 3) == 0) { return -1; + } - cmd = EXI_TX << 6; - EXIImm(Chan, &cmd, 4, EXI_WRITE, NULL); + cmd = 0x20010000; + EXIImm(Chan, &cmd, sizeof(cmd), EXI_WRITE, 0); EXISync(Chan); - - EXIImm(Chan, &cmd, 1, EXI_READ, NULL); + EXIImm(Chan, &cmd, 1, EXI_READ, 0); EXISync(Chan); EXIDeselect(Chan); - - return 16 - (int)((cmd >> 24) & 0xff); + return 0x10 - (cmd >> 0x18); } -/* 803449A0-80344BA0 33F2E0 0200+00 0/0 1/1 0/0 .text WriteUARTN */ -u32 WriteUARTN(const void* buf, unsigned long len) { +int WriteUARTN(void *buf, u32 len) { u32 cmd; + s32 xLen; int qLen; - long xLen; char* ptr; - BOOL locked; - u32 error; + int locked; + int error; - if (Enabled != EXI_MAGIC) + if ((Enabled - 0xA5FF0000) != 0x5A) { return 2; + } locked = EXILock(Chan, Dev, 0); - if (!locked) { + if (locked == 0) { return 0; + } else { + ptr = (char*)buf; } - for (ptr = (char*)buf; ptr - buf < len; ptr++) { - if (*ptr == '\n') - *ptr = '\r'; + while ((u32)ptr - (u32)buf < len) { + if (*(s8*)ptr == 0xA) { + *ptr = 0xD; + } + ptr++; } - error = 0; - cmd = (EXI_TX | 0x2000000) << 6; - while (len) { + cmd = 0xA0010000; + + while (len != 0) { qLen = QueueLength(); if (qLen < 0) { error = 3; break; } - - if (qLen < 12 && qLen < len) - continue; - - if (!EXISelect(Chan, Dev, EXI_FREQ_8M)) { - error = 3; - break; - } - - EXIImm(Chan, &cmd, 4, EXI_WRITE, NULL); - EXISync(Chan); - - while (qLen && len) { - if (qLen < 4 && qLen < len) + + if ((qLen >= 0xC) || (qLen >= len)) { + if (EXISelect(Chan, Dev, EXI_FREQ_8M) == 0) { + error = 3; break; - xLen = (len < 4) ? (long)len : 4; - EXIImm(Chan, (void*)buf, xLen, EXI_WRITE, NULL); - (u8*)buf += xLen; - len -= xLen; - qLen -= xLen; + } + + EXIImm(Chan, &cmd, sizeof(cmd), EXI_WRITE, 0); EXISync(Chan); + + while((qLen != 0) && (len != 0)) { + if ((qLen < 4) && (qLen < len)) { + break; + } + + xLen = len < 4 ? (long)len : 4; + + EXIImm(Chan, buf, xLen, EXI_WRITE, 0); + (char*)buf += xLen; + len -= xLen; + qLen -= xLen; + EXISync(Chan); + } + EXIDeselect(Chan); } - EXIDeselect(Chan); } EXIUnlock(Chan); return error; -} \ No newline at end of file +} diff --git a/src/dolphin/fileCache/fileCache.c b/src/dolphin/fileCache/fileCache.c new file mode 100644 index 0000000000..36151f4e8e --- /dev/null +++ b/src/dolphin/fileCache/fileCache.c @@ -0,0 +1,145 @@ +#include +#include + +DSCache DODisplayCache; +u8 DOCacheInitialized; + +static u8 AllocCacheNode(DSCacheNodePtr* cacheNode, char* name); +static void FreeCacheNode(DSCacheNodePtr* cacheNode); + +DSCacheNodePtr DSAddCacheNode(DSCachePtr cache, char* name, Ptr data, Ptr OSFreeFunc) { + DSCacheNodePtr cacheNode; + + cacheNode = NULL; + if (!AllocCacheNode(&cacheNode, name)) { + return NULL; + } + Strcpy(cacheNode->Name, name); + cacheNode->Data = data; + cacheNode->Free = (void (*)(Ptr *))OSFreeFunc; + cacheNode->ReferenceCount = 0; + DSInsertListObject(&cache->CacheNodeList, NULL, (Ptr)cacheNode); + return cacheNode; +} + +static u8 AllocCacheNode(DSCacheNodePtr* cacheNode, char* name) { + if (*cacheNode) { + FreeCacheNode(cacheNode); + } + + *cacheNode = OSAlloc(sizeof(DSCacheNode)); + if (!*cacheNode) { + return FALSE; + } + + (*cacheNode)->Name = OSAlloc(Strlen(name) + 1); + if (!(*cacheNode)->Name) { + return FALSE; + } + + return TRUE; +} + +void DSEmptyCache(DSCachePtr cache) { + DSCacheNodePtr cursor; + DSCacheNodePtr cacheNode; + + cursor = (DSCacheNodePtr)cache->CacheNodeList.Head; + while (cursor) { + cacheNode = cursor; + cursor = (DSCacheNodePtr)cursor->Link.Next; + DSRemoveListObject(&cache->CacheNodeList, (Ptr)cacheNode); + FreeCacheNode(&cacheNode); + } +} + +static DSCacheNodePtr FindCacheNode(DSCachePtr cache, char* name, Ptr data) { + DSCacheNodePtr cacheNode; + + cacheNode = (DSCacheNodePtr)cache->CacheNodeList.Head; + if (data) { + while (cacheNode) { + if (data == cacheNode->Data) { + return cacheNode; + } + cacheNode = (DSCacheNodePtr)cacheNode->Link.Next; + } + } else if (name) { + while (cacheNode) { + if (Strcmp(name, cacheNode->Name) == 0) { + return cacheNode; + } + cacheNode = (DSCacheNodePtr)cacheNode->Link.Next; + } + } + return NULL; +} + +Ptr DSGetCacheObj(DSCachePtr cache, char* name) { + DSCacheNodePtr cacheNode; + + cacheNode = FindCacheNode(cache, name, NULL); + if (cacheNode) { + cacheNode->ReferenceCount++; + return cacheNode->Data; + } + return NULL; +} + +static void FreeCacheNode(DSCacheNodePtr* cacheNode) { + if (*cacheNode) { + if ((*cacheNode)->Free) { + (*cacheNode)->Free(&(*cacheNode)->Data); + } + OSFree((*cacheNode)->Name); + OSFree(*cacheNode); + *cacheNode = NULL; + } +} + +void DSInitCache(DSCachePtr cache) { + DSCacheNode cacheNode; + + cache->PurgeFlag = DS_AUTO_PURGE; + DSInitList(&cache->CacheNodeList, (Ptr)&cacheNode, &cacheNode.Link); +} + +void DSPurgeCache(DSCachePtr cache) { + DSCacheNodePtr cursor; + DSCacheNodePtr cacheNode; + + cursor = (DSCacheNodePtr)cache->CacheNodeList.Head; + while (cursor) { + cacheNode = cursor; + cursor = (DSCacheNodePtr)cursor->Link.Next; + if (cacheNode->ReferenceCount == 0) { + DSRemoveListObject(&cache->CacheNodeList, (Ptr)cacheNode); + FreeCacheNode(&cacheNode); + } + } +} + +void DSReleaseCacheObj(DSCachePtr cache, Ptr data) { + DSCacheNodePtr cacheNode; + + cacheNode = FindCacheNode(cache, NULL, data); + if (cacheNode) { + if (cacheNode->ReferenceCount != 0) { + cacheNode->ReferenceCount--; + } + + if (cacheNode->ReferenceCount == 0 && cache->PurgeFlag == DS_AUTO_PURGE) { + DSRemoveListObject(&cache->CacheNodeList, (Ptr)cacheNode); + FreeCacheNode(&cacheNode); + } + } +} + +void DSSetCachePurgeFlag(DSCachePtr cache, u8 purgeFlag) { + cache->PurgeFlag = purgeFlag; +} + +void CSHInitDisplayCache(void) { + DSInitCache(&DODisplayCache); + DOCacheInitialized = TRUE; +} diff --git a/src/dolphin/gd/GDBase.c b/src/dolphin/gd/GDBase.c index 1da97c449d..a21e0d6bfa 100644 --- a/src/dolphin/gd/GDBase.c +++ b/src/dolphin/gd/GDBase.c @@ -1,45 +1,45 @@ -/** - * GDBase.c - * Description: - */ +#include +#include -#include "dolphin/gd/GDBase.h" +GDLObj* __GDCurrentDL = NULL; +static GDOverflowCb overflowcb = NULL; -/* 80360F98-80360FB0 35B8D8 0018+00 0/0 6/6 0/0 .text GDInitGDLObj */ -void GDInitGDLObj(GDLObj* obj, u8* start, u32 len) { - obj->start = start; - obj->ptr = start; - obj->end = start + len; - obj->length = len; +void GDInitGDLObj(GDLObj* dl, void* start, u32 length) { + ASSERTMSGLINE(40, !((u32)start & 0x1F), "start must be aligned to 32 bytes"); + ASSERTMSGLINE(41, !((u32)length & 0x1F), "length must be aligned to 32 bytes"); + dl->start = start; + dl->ptr = start; + dl->top = (u8*)start + length; + dl->length = length; } -/* ############################################################################################## */ -/* 80451980-80451984 000E80 0004+00 2/2 100/100 0/0 .sbss __GDCurrentDL */ -GDLObj* __GDCurrentDL = NULL; - -/* ############################################################################################## */ -/* 80451984-80451988 000E84 0004+00 1/1 0/0 0/0 .sbss overflowcb */ -static GDOverflowCallback overflowcb = NULL; - -/* 80360FB0-80360FDC 35B8F0 002C+00 0/0 2/2 0/0 .text GDFlushCurrToMem */ void GDFlushCurrToMem(void) { DCFlushRange(__GDCurrentDL->start, __GDCurrentDL->length); } -/* 80360FDC-803610D4 35B91C 00F8+00 0/0 2/2 0/0 .text GDPadCurr32 */ void GDPadCurr32(void) { - u32 i = ((u32)__GDCurrentDL->ptr & 31); + u32 n; - if (i) { - for (i; i < 32; i++) { + n = (u32)__GDCurrentDL->ptr & 0x1F; + if (n != 0) { + for (; n < 32; n = n + 1) { __GDWrite(0); } } } -/* 803610D4-80361104 35BA14 0030+00 0/0 41/41 0/0 .text GDOverflowed */ void GDOverflowed(void) { - if (overflowcb != NULL) { - overflowcb(); + if (overflowcb) { + (*overflowcb)(); + } else { + ASSERTMSGLINE(77, 0, "GDWrite: display list overflowed"); } -} \ No newline at end of file +} + +void GDSetOverflowCallback(GDOverflowCb callback) { + overflowcb = callback; +} + +GDOverflowCb GDGetOverflowCallback(void) { + return overflowcb; +} diff --git a/src/dolphin/gd/GDFile.c b/src/dolphin/gd/GDFile.c new file mode 100644 index 0000000000..47ec3af177 --- /dev/null +++ b/src/dolphin/gd/GDFile.c @@ -0,0 +1,64 @@ +#include +#include + +#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) + +s32 GDReadDLFile(const char* fName, u32* numDLs, u32* numPLs, GDGList** DLDescArray, GDGList** PLDescArray) { + DVDFileInfo finfo; + u32 length; + u32 i; + u8* buf; + GDFileHeader* hdr; + + *numDLs = *numPLs = 0; + *DLDescArray = *PLDescArray = NULL; + + if (!DVDOpen(fName, &finfo)) { + OSReport("Can't open file %s\n", fName); + return -3; + } + + length = finfo.length; + + if (NULL == (buf = OSAlloc(ROUND(length, 0x20)))) { + OSReport("Alloc failed\n"); + DVDClose(&finfo); + return -5; + } + + if (DVDReadPrio(&finfo, buf, ROUND(length, 0x20), 0, 2) != ROUND(length, 0x20)) { + OSReport("Error occurred when reading %s\n", fName); + DVDClose(&finfo); + OSFree(buf); + return -2; + } + + DVDClose(&finfo); + + hdr = (GDFileHeader*)buf; + + if (hdr->versionNumber != GD_FILE_VERSION_NUMBER) { + OSReport("Bad version number for GDL file %s\n", fName); + OSFree(buf); + return -4; + } + + *numDLs = hdr->numDLs; + *numPLs = hdr->numPLs; + + // Loaded pointers are relative to disc start, remap + // them to be relative to RAM start + *DLDescArray = (GDGList*)((u32)hdr->DLDescArray + (u32)hdr); + *PLDescArray = (GDGList*)((u32)hdr->PLDescArray + (u32)hdr); + + // And internal pointers too + for (i = 0; i < *numDLs; ++i) { + (*DLDescArray)[i].ptr = (void*)((u32)hdr + (u32)(*DLDescArray)[i].ptr); + } + + for (i = 0; i < *numPLs; ++i) { + (*PLDescArray)[i].ptr = (void*)((u32)hdr + (u32)(*PLDescArray)[i].ptr); + } + + return 0; +} diff --git a/src/dolphin/gd/GDGeometry.c b/src/dolphin/gd/GDGeometry.c index 16d522e76f..967acb7bf7 100644 --- a/src/dolphin/gd/GDGeometry.c +++ b/src/dolphin/gd/GDGeometry.c @@ -1,149 +1,430 @@ -#include "dolphin/gd.h" -#include "dolphin/os.h" +#include +#include -/* 80361104-80361700 35BA44 05FC+00 1/0 1/1 0/0 .text GDSetVtxDescv */ -void GDSetVtxDescv(GXVtxDescList* lists) { - u32 v1 = 0; // r31 - u32 v2 = 0; // r30 - u32 v3 = 0; // r29 - u32 v4 = 0; // r28 - u32 v5 = 0; // r27 - u32 v6 = 1; // r26 - u32 v7 = 0; // r25 - u32 v8 = 0; // r24 - u32 v9 = 0; // r23 - u32 v10 = 0; // r22 - u32 v11 = 0; // r21 - u32 v12 = 0; // r20 - u32 v13 = 0; // r19 - u32 v14 = 0; // r18 - u32 v15 = 0; // r17 - u32 v16 = 0; // r16 - u32 v17 = 0; // r15 +void GDSetVtxDescv(const GXVtxDescList* attrPtr) { + u32 nnorms = 0; + u32 ncols = 0; + u32 ntexs = 0; + u32 pnMtxIdx = GX_NONE; + u32 txMtxIdxMask = 0; + u32 posn = GX_DIRECT; + u32 norm = GX_NONE; + u32 col0 = GX_NONE; + u32 col1 = GX_NONE; + u32 tex0 = GX_NONE; + u32 tex1 = GX_NONE; + u32 tex2 = GX_NONE; + u32 tex3 = GX_NONE; + u32 tex4 = GX_NONE; + u32 tex5 = GX_NONE; + u32 tex6 = GX_NONE; + u32 tex7 = GX_NONE; - while (lists->attr != GX_VA_NULL) { - switch (lists->attr) { + for (; attrPtr->attr != GX_VA_NULL; ++attrPtr) { + ASSERTMSGLINE(91, attrPtr->attr >= GX_VA_PNMTXIDX && attrPtr->attr <= GX_VA_MAX_ATTR, "GDSetVtxDescv: invalid attribute"); + ASSERTMSGLINE(95, attrPtr->type >= GX_NONE && attrPtr->type <= GX_INDEX16, "GDSetVtxDescv: invalid type"); + + ASSERTMSGLINE(101, attrPtr->attr >= GX_VA_PNMTXIDX && attrPtr->attr <= GX_VA_TEX7MTXIDX ? (attrPtr->type == 0 || attrPtr->type == 1) : TRUE, "GDSetVtxDescv: invalid type for given attribute"); + + switch (attrPtr->attr) { case GX_VA_PNMTXIDX: - v4 = lists->type; + pnMtxIdx = attrPtr->type; break; case GX_VA_TEX0MTXIDX: - v5 = v5 & ~0x1 | lists->type; + txMtxIdxMask = (txMtxIdxMask & ~0x1) | (attrPtr->type << 0); break; case GX_VA_TEX1MTXIDX: - v5 = v5 & ~0x2 | lists->type << 1; + txMtxIdxMask = (txMtxIdxMask & ~0x2) | (attrPtr->type << 1); break; case GX_VA_TEX2MTXIDX: - v5 = v5 & ~0x4 | lists->type << 2; + txMtxIdxMask = (txMtxIdxMask & ~0x4) | (attrPtr->type << 2); break; case GX_VA_TEX3MTXIDX: - v5 = v5 & ~0x8 | lists->type << 3; + txMtxIdxMask = (txMtxIdxMask & ~0x8) | (attrPtr->type << 3); break; case GX_VA_TEX4MTXIDX: - v5 = v5 & ~0x10 | lists->type << 4; + txMtxIdxMask = (txMtxIdxMask & ~0x10) | (attrPtr->type << 4); break; case GX_VA_TEX5MTXIDX: - v5 = v5 & ~0x20 | lists->type << 5; + txMtxIdxMask = (txMtxIdxMask & ~0x20) | (attrPtr->type << 5); break; case GX_VA_TEX6MTXIDX: - v5 = v5 & ~0x40 | lists->type << 6; + txMtxIdxMask = (txMtxIdxMask & ~0x40) | (attrPtr->type << 6); break; case GX_VA_TEX7MTXIDX: - v5 = v5 & ~0x80 | lists->type << 7; + txMtxIdxMask = (txMtxIdxMask & ~0x80) | (attrPtr->type << 7); break; - case GX_VA_POS: - v6 = lists->type; + posn = attrPtr->type; break; case GX_VA_NRM: - if (lists->type != GX_NONE) { - v1 = 1; - v7 = lists->type; + if (attrPtr->type != GX_NONE) { + norm = attrPtr->type; + nnorms = 1; } break; case GX_VA_NBT: - if (lists->type != GX_NONE) { - v1 = 2; - v7 = lists->type; + if (attrPtr->type != GX_NONE) { + norm = attrPtr->type; + nnorms = 2; } break; case GX_VA_CLR0: - v8 = lists->type; - v2 += (v8 != 0); + col0 = attrPtr->type; + ncols += (col0 != GX_NONE); break; case GX_VA_CLR1: - v9 = lists->type; - v2 += (v9 != 0); + col1 = attrPtr->type; + ncols += (col1 != GX_NONE); break; case GX_VA_TEX0: - v10 = lists->type; - v3 += (v10 != 0); + tex0 = attrPtr->type; + ntexs += (tex0 != GX_NONE); break; case GX_VA_TEX1: - v11 = lists->type; - v3 += (v11 != 0); + tex1 = attrPtr->type; + ntexs += (tex1 != GX_NONE); break; case GX_VA_TEX2: - v12 = lists->type; - v3 += (v12 != 0); + tex2 = attrPtr->type; + ntexs += (tex2 != GX_NONE); break; case GX_VA_TEX3: - v13 = lists->type; - v3 += (v13 != 0); + tex3 = attrPtr->type; + ntexs += (tex3 != GX_NONE); break; case GX_VA_TEX4: - v14 = lists->type; - v3 += (v14 != 0); + tex4 = attrPtr->type; + ntexs += (tex4 != GX_NONE); break; case GX_VA_TEX5: - v15 = lists->type; - v3 += (v15 != 0); + tex5 = attrPtr->type; + ntexs += (tex5 != GX_NONE); break; case GX_VA_TEX6: - v16 = lists->type; - v3 += (v16 != 0); + tex6 = attrPtr->type; + ntexs += (tex6 != GX_NONE); break; case GX_VA_TEX7: - v17 = lists->type; - v3 += (v17 != 0); - break; - - case GX_POS_MTX_ARRAY: - case GX_NRM_MTX_ARRAY: - case GX_TEX_MTX_ARRAY: - case GX_LIGHT_ARRAY: + tex7 = attrPtr->type; + ntexs += (tex7 != GX_NONE); break; } - lists++; } - GDWriteCPCmd(0x50, v4 | v5 << 1 | v6 << 9 | v7 << 11 | v8 << 13 | v9 << 15); - GDWriteCPCmd(0x60, v10 | v11 << 2 | v12 << 4 | v13 << 6 | v14 << 8 | v15 << 10 | v16 << 12 | - v17 << 14); - GDWriteXFCmd(0x1008, v2 | v1 << 2 | v3 << 4); + GDWriteCPCmd(CP_REG_VCD_LO_ID, CP_REG_VCD_LO(pnMtxIdx, txMtxIdxMask, posn, norm, col0, col1)); + GDWriteCPCmd(CP_REG_VCD_HI_ID, CP_REG_VCD_HI(tex0, tex1, tex2, tex3, tex4, tex5, tex6, tex7)); + GDWriteXFCmd(XF_REG_INVERTEXSPEC_ID, XF_REG_INVTXSPEC(ncols, nnorms, ntexs)); } -/* 80361700-8036190C 35C040 020C+00 0/0 1/1 0/0 .text GDSetArray */ -void GDSetArray(GXAttr attr, const void* data, u8 stride) { - u32 v1; - if (attr == GX_VA_NBT) { - v1 = 1; - } else { - v1 = attr - 9; +void GDSetVtxAttrFmtv(GXVtxFmt vtxfmt, const GXVtxAttrFmtList* list) { + u32 posCnt = GX_POS_XYZ; + u32 posType = GX_F32; + u32 posFrac = 0; + + u32 nrmCnt = GX_NRM_XYZ; + u32 nrmType = GX_F32; + u32 nrmIdx3 = 0; + + u32 c0Cnt = GX_CLR_RGBA; + u32 c0Type = GX_RGBA8; + + u32 c1Cnt = GX_CLR_RGBA; + u32 c1Type = GX_RGBA8; + + u32 tx0Cnt = GX_TEX_ST; + u32 tx0Type = GX_F32; + u32 tx0Frac = 0; + + u32 tx1Cnt = GX_TEX_ST; + u32 tx1Type = GX_F32; + u32 tx1Frac = 0; + + u32 tx2Cnt = GX_TEX_ST; + u32 tx2Type = GX_F32; + u32 tx2Frac = 0; + + u32 tx3Cnt = GX_TEX_ST; + u32 tx3Type = GX_F32; + u32 tx3Frac = 0; + + u32 tx4Cnt = GX_TEX_ST; + u32 tx4Type = GX_F32; + u32 tx4Frac = 0; + + u32 tx5Cnt = GX_TEX_ST; + u32 tx5Type = GX_F32; + u32 tx5Frac = 0; + + u32 tx6Cnt = GX_TEX_ST; + u32 tx6Type = GX_F32; + u32 tx6Frac = 0; + + u32 tx7Cnt = GX_TEX_ST; + u32 tx7Type = GX_F32; + u32 tx7Frac = 0; + + ASSERTMSGLINE(221, vtxfmt < GX_MAX_VTXFMT, "GDSetVtxAttrFmtv: invalid vtx fmt"); + + for (; list->attr != GX_VA_NULL; ++list) { + ASSERTMSGLINE(226, list->attr >= GX_VA_POS && list->attr <= GX_VA_TEX7, "GDSetVtxAttrFmtv: invalid attribute"); + ASSERTMSGLINE(227, list->frac < 32, "GDSetVtxAttrFmtv: invalid frac value"); + + switch (list->attr) { + case GX_VA_POS: + posCnt = list->cnt; + posType = list->type; + posFrac = list->frac; + break; + case GX_VA_NRM: + case GX_VA_NBT: + nrmType = list->type; + if (list->cnt == GX_NRM_NBT3) { + nrmCnt = GX_NRM_NBT; + nrmIdx3 = 1; + } else { + nrmCnt = list->cnt; + nrmIdx3 = 0; + } + break; + case GX_VA_CLR0: + c0Cnt = list->cnt; + c0Type = list->type; + break; + case GX_VA_CLR1: + c1Cnt = list->cnt; + c1Type = list->type; + break; + case GX_VA_TEX0: + tx0Cnt = list->cnt; + tx0Type = list->type; + tx0Frac = list->frac; + break; + case GX_VA_TEX1: + tx1Cnt = list->cnt; + tx1Type = list->type; + tx1Frac = list->frac; + break; + case GX_VA_TEX2: + tx2Cnt = list->cnt; + tx2Type = list->type; + tx2Frac = list->frac; + break; + case GX_VA_TEX3: + tx3Cnt = list->cnt; + tx3Type = list->type; + tx3Frac = list->frac; + break; + case GX_VA_TEX4: + tx4Cnt = list->cnt; + tx4Type = list->type; + tx4Frac = list->frac; + break; + case GX_VA_TEX5: + tx5Cnt = list->cnt; + tx5Type = list->type; + tx5Frac = list->frac; + break; + case GX_VA_TEX6: + tx6Cnt = list->cnt; + tx6Type = list->type; + tx6Frac = list->frac; + break; + case GX_VA_TEX7: + tx7Cnt = list->cnt; + tx7Type = list->type; + tx7Frac = list->frac; + } } - GDWriteCPCmd(v1 + 0xA0, OSCachedToPhysical(data)); - GDWriteCPCmd(v1 + 0xB0, stride); + GDWriteCPCmd(vtxfmt + CP_REG_VAT_GRP0_ID, CP_REG_VAT_GRP0(posCnt, posType, posFrac, nrmCnt, nrmType, c0Cnt, c0Type, c1Cnt, c1Type, tx0Cnt, tx0Type, tx0Frac, 1, nrmIdx3)); + GDWriteCPCmd(vtxfmt + CP_REG_VAT_GRP1_ID, CP_REG_VAT_GRP1(tx1Cnt, tx1Type, tx1Frac, tx2Cnt, tx2Type, tx2Frac, tx3Cnt, tx3Type, tx3Frac, tx4Cnt, tx4Type, 1)); + GDWriteCPCmd(vtxfmt + CP_REG_VAT_GRP2_ID, CP_REG_VAT_GRP2(tx4Frac, tx5Cnt, tx5Type, tx5Frac, tx6Cnt, tx6Type, tx6Frac, tx7Cnt, tx7Type, tx7Frac)); } -/* 8036190C-80361B14 35C24C 0208+00 0/0 1/1 0/0 .text GDSetArrayRaw */ -void GDSetArrayRaw(GXAttr attr, u32 data, u8 stride) { - u32 v1; +void GDSetArray(GXAttr attr, void* base_ptr, u8 stride) { + s32 cpAttr; if (attr == GX_VA_NBT) { - v1 = 1; + cpAttr = GX_VA_TEX0MTXIDX; } else { - v1 = attr - 9; + cpAttr = attr - GX_VA_POS; } - GDWriteCPCmd(v1 + 0xA0, data); - GDWriteCPCmd(v1 + 0xB0, stride); -} \ No newline at end of file + GDWriteCPCmd(cpAttr + CP_REG_ARRAYBASE_ID, OSCachedToPhysical(base_ptr)); + GDWriteCPCmd(cpAttr + CP_REG_ARRAYSTRIDE_ID, stride); +} + +void GDSetArrayRaw(GXAttr attr, u32 base_ptr_raw, u8 stride) { + s32 cpAttr; + if (attr == GX_VA_NBT) { + cpAttr = GX_VA_TEX0MTXIDX; + } else { + cpAttr = attr - GX_VA_POS; + } + + GDWriteCPCmd(cpAttr + CP_REG_ARRAYBASE_ID, base_ptr_raw); + GDWriteCPCmd(cpAttr + CP_REG_ARRAYSTRIDE_ID, stride); +} + +void GDPatchArrayPtr(void* base_ptr) { + GDWrite_u32(OSCachedToPhysical(base_ptr)); +} + +void GDSetTexCoordGen(GXTexCoordID dst_coord, GXTexGenType func, GXTexGenSrc src_param, u8 normalize, u32 postmtx) { + u32 form; + u32 tgType; + u32 proj; + u32 row; + u32 embossRow; + u32 embossLit; + + form = 0; + proj = 0; + row = 5; + embossRow = 5; + embossLit = 0; + + ASSERTMSGLINE(432, dst_coord < GX_MAX_TEXCOORD, "GDSetTexCoordGen: invalid texcoord ID"); + + switch(src_param) { + case GX_TG_POS: + row = 0; + form = 1; + break; + case GX_TG_NRM: + row = 1; + form = 1; + break; + case GX_TG_BINRM: + row = 3; + form = 1; + break; + case GX_TG_TANGENT: + row = 4; + form = 1; + break; + case GX_TG_COLOR0: + row = 2; + break; + case GX_TG_COLOR1: + row = 2; + break; + case GX_TG_TEX0: + row = 5; + break; + case GX_TG_TEX1: + row = 6; + break; + case GX_TG_TEX2: + row = 7; + break; + case GX_TG_TEX3: + row = 8; + break; + case GX_TG_TEX4: + row = 9; + break; + case GX_TG_TEX5: + row = 10; + break; + case GX_TG_TEX6: + row = 11; + break; + case GX_TG_TEX7: + row = 12; + break; + case GX_TG_TEXCOORD0: + embossRow = 0; + break; + case GX_TG_TEXCOORD1: + embossRow = 1; + break; + case GX_TG_TEXCOORD2: + embossRow = 2; + break; + case GX_TG_TEXCOORD3: + embossRow = 3; + break; + case GX_TG_TEXCOORD4: + embossRow = 4; + break; + case GX_TG_TEXCOORD5: + embossRow = 5; + break; + case GX_TG_TEXCOORD6: + embossRow = 6; + break; + default: + ASSERTMSGLINE(457, 0, "GDSetTexCoordGen: invalid texgen source"); + break; + } + + switch (func) { + case GX_TG_MTX2x4: + tgType = 0; + break; + case GX_TG_MTX3x4: + tgType = 0; + proj = 1; + break; + case GX_TG_BUMP0: + case GX_TG_BUMP1: + case GX_TG_BUMP2: + case GX_TG_BUMP3: + case GX_TG_BUMP4: + case GX_TG_BUMP5: + case GX_TG_BUMP6: + case GX_TG_BUMP7: + ASSERTMSGLINE(481, src_param >= GX_TG_TEXCOORD0 && src_param <= GX_TG_TEXCOORD6, "GDSetTexCoordGen: invalid emboss source"); + tgType = 1; + embossLit = func - GX_TG_BUMP0; + break; + case GX_TG_SRTG: + if (src_param == GX_TG_COLOR0) { + tgType = 2; + } else { + tgType = 3; + } + break; + default: + ASSERTMSGLINE(495, 0, "GDSetTexCoordGen: invalid texgen function"); + break; + } + + GDWriteXFCmd(dst_coord + XF_REG_TEX0_ID, XF_REG_TEX(proj, form, tgType, row, embossRow, embossLit)); + GDWriteXFCmd(dst_coord + XF_REG_DUALTEX0_ID, XF_REG_DUALTEX(postmtx - 0x40, normalize)); +} + +void GDSetCullMode(GXCullMode mode) { + static u8 cm2hw[4] = { 0, 2, 1, 3 }; + + GDWriteBPCmd(0xFE00C000); + GDWriteBPCmd(cm2hw[mode] << 14); +} + +void GDSetGenMode(u8 nTexGens, u8 nChans, u8 nTevs) { + GDWriteBPCmd(0xFE003C3F); + GDWriteBPCmd(BP_GEN_MODE(nTexGens, nChans, nTevs - 1, 0, 0)); + + GDWriteXFCmd(XF_REG_NUMCOLORS_ID, nChans); + GDWriteXFCmd(XF_REG_NUMTEX_ID, nTexGens); +} + +void GDSetGenMode2(u8 nTexGens, u8 nChans, u8 nTevs, u8 nInds, GXCullMode cm) { + static u8 cm2hw[4] = { 0, 2, 1, 3 }; + + GDWriteBPCmd(0xFE07FC3F); + GDWriteBPCmd(BP_GEN_MODE(nTexGens, nChans, nTevs - 1, cm2hw[cm], nInds)); + + GDWriteXFCmd(XF_REG_NUMCOLORS_ID, nChans); + GDWriteXFCmd(XF_REG_NUMTEX_ID, nTexGens); +} + +void GDSetLPSize(u8 lineWidth, u8 pointSize, GXTexOffset lineOffset, GXTexOffset pointOffset, u8 lineHalfAspect) { + GDWriteBPCmd(BP_LP_SIZE(lineWidth, pointSize, lineOffset, pointOffset, lineHalfAspect, 0x22)); +} + +void GDSetCoPlanar(u8 enable) { + GDWriteBPCmd(0xFE080000); + GDWriteBPCmd(enable << 19); +} diff --git a/src/dolphin/gd/GDIndirect.c b/src/dolphin/gd/GDIndirect.c new file mode 100644 index 0000000000..104fce4bf8 --- /dev/null +++ b/src/dolphin/gd/GDIndirect.c @@ -0,0 +1,270 @@ +#include +#include + +void GDSetTevIndirect(GXTevStageID tev_stage, GXIndTexStageID ind_stage, + GXIndTexFormat format, GXIndTexBiasSel bias_sel, + GXIndTexMtxID matrix_sel, GXIndTexWrap wrap_s, + GXIndTexWrap wrap_t, u8 add_prev, u8 utc_lod, + GXIndTexAlphaSel alpha_sel) { + GDWriteBPCmd(BP_TEV_INDIRECT( + ind_stage & 3, + format & 3, + bias_sel & 7, + alpha_sel & 3, + matrix_sel & 0xF, + wrap_s & 7, + wrap_t & 7, + utc_lod & 1, + add_prev & 1, + 0x10 + (tev_stage & 0xF) + )); +} + +void GDSetIndTexMtx(GXIndTexMtxID mtx_id, const f32 offset[2][3], s8 scale_exp) { + u32 id_offset; + + switch (mtx_id) { + case GX_ITM_0: + id_offset = 0; + break; + case GX_ITM_1: + id_offset = 3; + break; + case GX_ITM_2: + id_offset = 6; + break; + default: + ASSERTMSGLINE(111, 0, "GDSetIndTexMtx: Invalid matrix id"); + break; + } + + scale_exp += 17; + + GDWriteBPCmd(BP_IND_MTX( + (s32)(offset[0][0] * 0x400) & 0x7FF, + (s32)(offset[1][0] * 0x400) & 0x7FF, + scale_exp & 3, + 6 + id_offset + )); + + GDWriteBPCmd(BP_IND_MTX( + (s32)(offset[0][1] * 0x400) & 0x7FF, + (s32)(offset[1][1] * 0x400) & 0x7FF, + (scale_exp >> 2) & 3, + 7 + id_offset + )); + + GDWriteBPCmd(BP_IND_MTX( + (s32)(offset[0][2] * 0x400) & 0x7FF, + (s32)(offset[1][2] * 0x400) & 0x7FF, + (scale_exp >> 4) & 3, + 8 + id_offset + )); +} + +void GDSetIndTexCoordScale(GXIndTexStageID indStageEven, GXIndTexScale scaleS0, + GXIndTexScale scaleT0, GXIndTexScale scaleS1, + GXIndTexScale scaleT1) { + GDWriteBPCmd(BP_IND_TEXCOORD_SCALE( + scaleS0 & 0xF, + scaleT0 & 0xF, + scaleS1 & 0xF, + scaleT1 & 0xF, + 0x25 + ((indStageEven >> 1) & 1) + )); +} + +void GDSetIndTexOrder(GXTexCoordID texCoord0, GXTexMapID texMap0, + GXTexCoordID texCoord1, GXTexMapID texMap1, + GXTexCoordID texCoord2, GXTexMapID texMap2, + GXTexCoordID texCoord3, GXTexMapID texMap3) { + GDWriteBPCmd(BP_IND_TEX_ORDER( + texMap0 & 7, + texCoord0 & 7, + texMap1 & 7, + texCoord1 & 7, + texMap2 & 7, + texCoord2 & 7, + texMap3 & 7, + texCoord3 & 7, + 0x27 + )); +} + +void GDSetTevDirect(GXTevStageID tev_stage) { + GDSetTevIndirect(tev_stage, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_OFF, GX_ITW_OFF, 0, 0, GX_ITBA_OFF); +} + +void GDSetTevIndWarp(GXTevStageID tev_stage, GXIndTexStageID ind_stage, u8 signed_offset, u8 replace_mode, GXIndTexMtxID matrix_sel) { + GXIndTexWrap wrap; + wrap = replace_mode ? GX_ITW_0 : GX_ITW_OFF; + + GDSetTevIndirect(tev_stage, + ind_stage, + GX_ITF_8, + signed_offset ? GX_ITB_STU : GX_ITB_NONE, + matrix_sel, + wrap, + wrap, + 0, + 0, + GX_ITBA_OFF); +} + +void GDSetTevIndTile(GXTevStageID tev_stage, GXIndTexStageID ind_stage, + u16 tilesize_s, u16 tilesize_t, u16 tilespacing_s, + u16 tilespacing_t, GXIndTexFormat format, + GXIndTexMtxID matrix_sel, GXIndTexBiasSel bias_sel, + GXIndTexAlphaSel alpha_sel) { + GXIndTexWrap wrap_s; + GXIndTexWrap wrap_t; + f32 mtx[2][3]; + + switch (tilesize_s) { + case 256: + wrap_s = GX_ITW_256; + break; + case 128: + wrap_s = GX_ITW_128; + break; + case 64: + wrap_s = GX_ITW_64; + break; + case 32: + wrap_s = GX_ITW_32; + break; + case 16: + wrap_s = GX_ITW_16; + break; + default: + ASSERTMSGLINE(268, 0, "GDSetTevIndTile: Invalid tilesize for S coordinate"); + wrap_s = GX_ITW_OFF; + break; + } + + switch (tilesize_t) { + case 256: + wrap_t = GX_ITW_256; + break; + case 128: + wrap_t = GX_ITW_128; + break; + case 64: + wrap_t = GX_ITW_64; + break; + case 32: + wrap_t = GX_ITW_32; + break; + case 16: + wrap_t = GX_ITW_16; + break; + default: + ASSERTMSGLINE(280, 0, "GDSetTevIndTile: Invalid tilesize for T coordinate"); + wrap_t = GX_ITW_OFF; + break; + } + + mtx[0][0] = (f32)tilespacing_s / 0x400; + mtx[0][1] = mtx[0][2] = 0.0f; + + mtx[1][1] = (f32)tilespacing_t / 0x400; + mtx[1][0] = mtx[1][2] = 0.0f; + GDSetIndTexMtx(matrix_sel, mtx, 10); + + GDSetTevIndirect(tev_stage, + ind_stage, + format, + bias_sel, + matrix_sel, + wrap_s, + wrap_t, + 0, + 1, + alpha_sel); +} + +void GDSetTevIndBumpST(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel) { + GXIndTexMtxID sm; + GXIndTexMtxID tm; + + switch(matrix_sel) { + case GX_ITM_0: + sm = GX_ITM_S0; + tm = GX_ITM_T0; + break; + case GX_ITM_1: + sm = GX_ITM_S1; + tm = GX_ITM_T1; + break; + case GX_ITM_2: + sm = GX_ITM_S2; + tm = GX_ITM_T2; + break; + default: + ASSERTMSGLINE(332, 0, "GDSetTevIndBumpST: Invalid matrix selection"); + break; + } + + GDSetTevIndirect(tev_stage, + ind_stage, + GX_ITF_8, + GX_ITB_ST, + sm, + GX_ITW_0, + GX_ITW_0, + 0, + 0, + GX_ITBA_OFF); + + GDSetTevIndirect(tev_stage + 1, + ind_stage, + GX_ITF_8, + GX_ITB_ST, + tm, + GX_ITW_0, + GX_ITW_0, + 1, + 0, + GX_ITBA_OFF); + + GDSetTevIndirect(tev_stage + 2, + ind_stage, + GX_ITF_8, + GX_ITB_NONE, + GX_ITM_OFF, + GX_ITW_OFF, + GX_ITW_OFF, + 1, + 0, + GX_ITBA_OFF); +} + +void GDSetTevIndBumpXYZ(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel) { + GDSetTevIndirect(tev_stage, + ind_stage, + GX_ITF_8, + GX_ITB_STU, + matrix_sel, + GX_ITW_OFF, + GX_ITW_OFF, + 0, + 0, + GX_ITBA_OFF); +} + +void GDSetTevIndRepeat(GXTevStageID tev_stage) { + GDSetTevIndirect(tev_stage, + GX_INDTEXSTAGE0, + GX_ITF_8, + GX_ITB_NONE, + GX_ITM_OFF, + GX_ITW_0, + GX_ITW_0, + 1, + 0, + GX_ITBA_OFF); +} + +void __GDSetIndTexMask(u32 mask) { + GDWriteBPCmd(BP_IND_MASK(mask & 0xFF, 0xF)); +} diff --git a/src/dolphin/gd/GDLight.c b/src/dolphin/gd/GDLight.c new file mode 100644 index 0000000000..96e08a447d --- /dev/null +++ b/src/dolphin/gd/GDLight.c @@ -0,0 +1,206 @@ +#include +#include + +void GDSetLightAttn(GXLightID light, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2) { + GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_ATTN_ID, 6); + GDWrite_f32(a0); + GDWrite_f32(a1); + GDWrite_f32(a2); + GDWrite_f32(k0); + GDWrite_f32(k1); + GDWrite_f32(k2); +} + +void GDSetLightSpot(GXLightID light, f32 cutoff, GXSpotFn spot_func) { + f32 a0; + f32 a1; + f32 a2; + f32 r; + f32 d; + f32 cr; + + if (cutoff <= 0.0f || cutoff > 90.0f) { + spot_func = 0; + } + + r = M_PI * cutoff / 180.0f; + cr = cosf(r); + + switch(spot_func) { + case GX_SP_FLAT: + a0 = -1000.0f * cr; + a1 = 1000.0f; + a2 = 0.0f; + break; + case GX_SP_COS: + a0 = -cr / (1.0f - cr); + a1 = 1.0f / (1.0f - cr); + a2 = 0.0f; + break; + case GX_SP_COS2: + a0 = 0.0f; + a1 = -cr / (1.0f - cr); + a2 = 1.0f / (1.0f - cr); + break; + case GX_SP_SHARP: + d = (1.0f - cr) * (1.0f - cr); + a0 = (cr * (cr - 2.0f)) / d; + a1 = 2.0f / d; + a2 = -1.0f / d; + break; + case GX_SP_RING1: + d = (1.0f - cr) * (1.0f - cr); + a0 = (-4.0f * cr) / d; + a1 = (4.0f * (1.0f + cr)) / d; + a2 = -4.0f / d; + break; + case GX_SP_RING2: + d = (1.0f - cr) * (1.0f - cr); + a0 = 1.0f - (2.0f * cr * cr) / d; + a1 = (4.0f * cr) / d; + a2 = -2.0f / d; + break; + case GX_SP_OFF: + default: + a0 = 1.0f; + a1 = 0.0f; + a2 = 0.0f; + break; + } + + GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_ATTN_ID, 3); + GDWrite_f32(a0); + GDWrite_f32(a1); + GDWrite_f32(a2); +} + +void GDSetLightDistAttn(GXLightID light, f32 ref_dist, f32 ref_br, GXDistAttnFn dist_func) { + f32 k0; + f32 k1; + f32 k2; + + if (ref_dist < 0.0f || ref_br <= 0.0f || ref_br >= 1.0f) { + dist_func = 0; + } + + switch (dist_func) { + case GX_DA_GENTLE: + k0 = 1.0f; + k1 = (1.0f - ref_br) / (ref_br * ref_dist); + k2 = 0.0f; + break; + case GX_DA_MEDIUM: + k0 = 1.0f; + k1 = (0.5f * (1.0f - ref_br)) / (ref_br * ref_dist); + k2 = (0.5f * (1.0f - ref_br)) / (ref_dist * (ref_br * ref_dist)); + break; + case GX_DA_STEEP: + k0 = 1.0f; + k1 = 0.0f; + k2 = (1.0f - ref_br) / (ref_dist * (ref_br * ref_dist)); + break; + case GX_DA_OFF: + default: + k0 = 1.0f; + k1 = 0.0f; + k2 = 0.0f; + break; + } + + GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_DISTATTN_ID, 3); + GDWrite_f32(k0); + GDWrite_f32(k1); + GDWrite_f32(k2); +} + +void GDSetLightColor(GXLightID light, GXColor color) { + GDWriteXFCmd(__GDLightID2Offset(light) + XF_LIGHT_COLOR_ID, color.r << 24 | color.g << 16 | color.b << 8 | color.a); +} + +void GDSetLightPos(GXLightID light, f32 x, f32 y, f32 z) { + GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_POS_ID, 3); + GDWrite_f32(x); + GDWrite_f32(y); + GDWrite_f32(z); +} + +void GDSetLightDir(GXLightID light, f32 nx, f32 ny, f32 nz) { + GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_DIR_ID, 3); + GDWrite_f32(nx); + GDWrite_f32(ny); + GDWrite_f32(nz); +} + +void GDSetSpecularDirHA(GXLightID light, f32 nx, f32 ny, f32 nz, f32 hx, f32 hy, f32 hz) { + f32 px; + f32 py; + f32 pz; + px = 1000000000000000000.0f * -nx; + py = 1000000000000000000.0f * -ny; + pz = 1000000000000000000.0f * -nz; + + GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_SPEC_DIR_ID, 6); + GDWrite_f32(px); + GDWrite_f32(py); + GDWrite_f32(pz); + GDWrite_f32(hx); + GDWrite_f32(hy); + GDWrite_f32(hz); +} + +void GDSetSpecularDir(GXLightID light, f32 nx, f32 ny, f32 nz) { + f32 px; + f32 py; + f32 pz; + f32 hx; + f32 hy; + f32 hz; + f32 mag; + + hx = -nx; + hy = -ny; + hz = 1.0f + -nz; + + mag = hx * hx + hy * hy + hz * hz; + if (mag != 0.0f) { + mag = 1.0f / sqrtf(mag); + } + + hx = hx * mag; + hy = hy * mag; + hz = hz * mag; + px = 1000000000000000000.0f * -nx; + py = 1000000000000000000.0f * -ny; + pz = 1000000000000000000.0f * -nz; + + GDWriteXFCmdHdr(__GDLightID2Offset(light) + XF_LIGHT_SPEC_DIR_ID, 6); + GDWrite_f32(px); + GDWrite_f32(py); + GDWrite_f32(pz); + GDWrite_f32(hx); + GDWrite_f32(hy); + GDWrite_f32(hz); +} + +void GDLoadLightObjIndx(u32 lt_obj_indx, GXLightID light) { + GDWriteXFIndxDCmd(__GDLightID2Offset(light) + XF_LIGHT_ID, 0x10, lt_obj_indx); +} + +void GDSetChanAmbColor(GXChannelID chan, GXColor color) { + GDWriteXFCmd((chan & 1) + XF_REG_AMBIENT0_ID, color.r << 24 | color.g << 16 | color.b << 8 | color.a); +} + +void GDSetChanMatColor(GXChannelID chan, GXColor color) { + GDWriteXFCmd((chan & 1) + XF_REG_MATERIAL0_ID, color.r << 24 | color.g << 16 | color.b << 8 | color.a); +} + +void GDSetChanCtrl(GXChannelID chan, u8 enable, GXColorSrc amb_src, GXColorSrc mat_src, u32 light_mask, GXDiffuseFn diff_fn, GXAttnFn attn_fn) { + u32 reg; + + reg = XF_REG_CHAN_CTRL(mat_src, enable, light_mask & 0xF, amb_src, attn_fn == GX_AF_SPEC ? GX_DF_NONE : diff_fn, attn_fn != GX_AF_NONE, attn_fn != GX_AF_SPEC, (light_mask >> 4) & 0xF); + GDWriteXFCmd((chan & 3) + XF_REG_COLOR0CNTRL_ID, reg); + + if (chan == 4 || chan == 5) { + GDWriteXFCmd(chan + XF_REG_MATERIAL0_ID, reg); + } +} diff --git a/src/dolphin/gd/GDPixel.c b/src/dolphin/gd/GDPixel.c new file mode 100644 index 0000000000..c18cf77841 --- /dev/null +++ b/src/dolphin/gd/GDPixel.c @@ -0,0 +1,118 @@ +#include +#include + +void GDSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color) { + f32 A; + f32 B; + f32 B_mant; + f32 C; + f32 A_f; + u32 b_expn; + u32 b_m; + u32 a_hex; + u32 c_hex; + u32 fsel; + u32 proj; + + ASSERTMSGLINE(62, farz >= 0.0f, "GDSetFog: The farz should be positive value"); + ASSERTMSGLINE(63, farz >= nearz, "GDSetFog: The farz should be larger than nearz"); + + fsel = type & 7; + proj = (type >> 3) & 1; + + if (proj != 0) { + if (farz == nearz || endz == startz) { + A_f = 0.0f; + C = 0.0f; + } else { + A = 1.0f / (endz - startz); + A_f = (farz - nearz) * A; + C = (startz - nearz) * A; + } + + b_expn = 0; + b_m = 0; + } else { + if (farz == nearz || endz == startz) { + A = 0.0f; + B = 0.5f; + C = 0.0f; + } else { + A = (farz * nearz) / ((farz - nearz) * (endz - startz)); + B = farz / (farz - nearz); + C = startz / (endz - startz); + } + + B_mant = B; + b_expn = 1; + + while (B_mant > 1.0) { + B_mant *= 0.5f; + b_expn++; + } + + while (B_mant > 0.0f && B_mant < 0.5) { + B_mant *= 2.0f; + b_expn--; + } + + A_f = A / (1 << b_expn); + b_m = (u32) (8388638.0f * B_mant); + } + + a_hex = *(u32*)&A_f; + c_hex = *(u32*)&C; + + GDWriteBPCmd(BP_FOG_UNK0(a_hex >> 12, 0xEE)); + GDWriteBPCmd(BP_FOG_UNK1(b_m, 0xEF)); + GDWriteBPCmd(BP_FOG_UNK2(b_expn, 0xF0)); + GDWriteBPCmd(BP_FOG_UNK3(c_hex >> 12, proj, fsel, 0xF1)); + GDWriteBPCmd(BP_FOG_COLOR(color.r, color.g, color.b, 0xF2)); +} + +void GDSetBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor, GXLogicOp logic_op) { + GDWriteBPCmd(0xFE00FFE3); + GDWriteBPCmd(BP_BLEND_MODE( + type == GX_BM_BLEND || type == GX_BM_SUBTRACT, + type == GX_BM_LOGIC, + 0, + 0, + 0, + dst_factor, + src_factor, + type == GX_BM_SUBTRACT, + logic_op, + 0x41 + )); +} + +void GDSetBlendModeEtc(GXBlendMode type, GXBlendFactor src_factor, + GXBlendFactor dst_factor, GXLogicOp logic_op, + u8 color_update_enable, u8 alpha_update_enable, + u8 dither_enable) { + GDWriteBPCmd(BP_BLEND_MODE( + type == GX_BM_BLEND || type == GX_BM_SUBTRACT, + type == GX_BM_LOGIC, + dither_enable, + color_update_enable, + alpha_update_enable, + dst_factor, + src_factor, + type == GX_BM_SUBTRACT, + logic_op, + 0x41 + )); +} + +void GDSetZMode(u8 compare_enable, GXCompare func, u8 update_enable) { + GDWriteBPCmd(BP_Z_MODE(compare_enable, func, update_enable, 0x40)); +} + +void GDSetDstAlpha(u8 enable, u8 alpha) { + GDWriteBPCmd(BP_DST_ALPHA(alpha, enable, 0x42)); +} + +void GDSetDrawSync(u16 token) { + GDWriteBPCmd(BP_TOKEN(token, 0x48)); + GDWriteBPCmd(BP_TOKEN(token, 0x47)); +} diff --git a/src/dolphin/gd/GDTev.c b/src/dolphin/gd/GDTev.c new file mode 100644 index 0000000000..69803e8a49 --- /dev/null +++ b/src/dolphin/gd/GDTev.c @@ -0,0 +1,159 @@ +#include +#include + +void GDSetTevOp(GXTevStageID stage, GXTevMode mode) { + GXTevColorArg carg = GX_CC_RASC; + GXTevAlphaArg aarg = GX_CA_RASA; + + if (stage != GX_TEVSTAGE0) { + carg = GX_CC_CPREV; + aarg = GX_CA_APREV; + } + + switch (mode) { + case GX_MODULATE: + GDSetTevColorCalc(stage, GX_CC_ZERO, GX_CC_TEXC, carg, GX_CC_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_TEXA, aarg, GX_CA_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0); + break; + case GX_DECAL: + GDSetTevColorCalc(stage, carg, GX_CC_TEXC, GX_CC_TEXA, GX_CC_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, aarg, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0); + break; + case GX_BLEND: + GDSetTevColorCalc(stage, carg, GX_CC_ONE, GX_CC_TEXC, GX_CC_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_TEXA, aarg, GX_CA_ZERO, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0); + break; + case GX_REPLACE: + GDSetTevColorCalc(stage, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0); + break; + case GX_PASSCLR: + GDSetTevColorCalc(stage, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, carg, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GDSetTevAlphaCalcAndSwap(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, aarg, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV, GX_TEV_SWAP0, GX_TEV_SWAP0); + break; + default: + ASSERTMSGLINE(110, 0, "GDSetTevOp: Invalid Tev Mode"); + break; + } +} + +void GDSetTevColorCalc(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, + GXTevColorArg c, GXTevColorArg d, GXTevOp op, + GXTevBias bias, GXTevScale scale, u8 clamp, + GXTevRegID out_reg) { + if (op <= GX_TEV_SUB) { + GDWriteBPCmd(BP_TEV_COLOR(d, c, b, a, bias, op & 1, clamp, scale, out_reg, stage * 2 + 0xC0)); + } else { + GDWriteBPCmd(BP_TEV_COLOR(d, c, b, a, 3, op & 1, clamp, (op >> 1) & 3, out_reg, stage * 2 + 0xC0)); + } +} + +void GDSetTevAlphaCalcAndSwap(GXTevStageID stage, GXTevAlphaArg a, + GXTevAlphaArg b, GXTevAlphaArg c, GXTevAlphaArg d, + GXTevOp op, GXTevBias bias, GXTevScale scale, + u8 clamp, GXTevRegID out_reg, + GXTevSwapSel ras_sel, GXTevSwapSel tex_sel) { + if (op <= GX_TEV_SUB) { + GDWriteBPCmd(BP_TEV_ALPHA(ras_sel, tex_sel, d, c, b, a, bias, op & 1, clamp, scale, out_reg, stage * 2 + 0xC1)); + } else { + GDWriteBPCmd(BP_TEV_ALPHA(ras_sel, tex_sel, d, c, b, a, 3, op & 1, clamp, (op >> 1) & 3, out_reg, stage * 2 + 0xC1)); + } +} + +void GDSetTevColor(GXTevRegID reg, GXColor color) { + u32 regRA; + u32 regBG; + + regRA = BP_TEV_COLOR_REG_RA(color.r, color.a, 0, 0xE0 + reg * 2); + regBG = BP_TEV_COLOR_REG_BG(color.b, color.g, 0, 0xE1 + reg * 2); + + GDWriteBPCmd(regRA); + GDWriteBPCmd(regBG); + GDWriteBPCmd(regBG); + GDWriteBPCmd(regBG); +} + +void GDSetTevColorS10(GXTevRegID reg, GXColorS10 color) { + u32 regRA; + u32 regBG; + + regRA = BP_TEV_COLOR_REG_RA(color.r & 0x7FF, color.a & 0x7FF, 0, 0xE0 + reg * 2); + regBG = BP_TEV_COLOR_REG_BG(color.b & 0x7FF, color.g & 0x7FF, 0, 0xE1 + reg * 2); + + GDWriteBPCmd(regRA); + GDWriteBPCmd(regBG); + GDWriteBPCmd(regBG); + GDWriteBPCmd(regBG); +} + +void GDSetTevKColor(GXTevKColorID reg, GXColor color) { + u32 regRA; + u32 regBG; + + regRA = BP_TEV_COLOR_REG_RA(color.r, color.a, 1, 0xE0 + reg * 2); + regBG = BP_TEV_COLOR_REG_BG(color.b, color.g, 1, 0xE1 + reg * 2); + + GDWriteBPCmd(regRA); + GDWriteBPCmd(regBG); +} + +void GDSetTevKonstantSel(GXTevStageID evenStage, GXTevKColorSel kcsel0, + GXTevKAlphaSel kasel0, GXTevKColorSel kcsel1, + GXTevKAlphaSel kasel1) { + GDWriteBPCmd(0xFEFFFFF0); + GDWriteBPCmd(BP_TEV_KSEL(0, 0, kcsel0, kasel0, kcsel1, kasel1, evenStage / 2 + 0xF6)); +} + +void GDSetTevSwapModeTable(GXTevSwapSel table, GXTevColorChan red, + GXTevColorChan green, GXTevColorChan blue, + GXTevColorChan alpha) { + GDWriteBPCmd(0xFE00000F); + GDWriteBPCmd(BP_TEV_KSEL(red, green, 0, 0, 0, 0, table * 2 + 0xF6)); + + GDWriteBPCmd(0xFE00000F); + GDWriteBPCmd(BP_TEV_KSEL(blue, alpha, 0, 0, 0, 0, table * 2 + 0xF7)); +} + +void GDSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1) { + GDWriteBPCmd(BP_ALPHA_COMPARE(ref0, ref1, comp0, comp1, op, 0xF3)); +} + +void GDSetZTexture(GXZTexOp op, GXTexFmt fmt, u32 bias) { + u32 zfmt; + + switch (fmt) { + case GX_TF_Z8: + zfmt = 0; + break; + case GX_TF_Z16: + zfmt = 1; + break; + case GX_TF_Z24X8: + zfmt = 2; + break; + default: + ASSERTMSGLINE(399, 0, "GDSetZTexture: Invalid format"); + zfmt = 2; + break; + } + + GDWriteBPCmd(BP_ZTEX_PARAMS_0(bias, 0xF4)); + GDWriteBPCmd(BP_ZTEX_PARAMS_1(zfmt, op, 0xF5)); +} + +void GDSetTevOrder(GXTevStageID evenStage, GXTexCoordID coord0, GXTexMapID map0, + GXChannelID color0, GXTexCoordID coord1, GXTexMapID map1, + GXChannelID color1) { + static u8 c2r[] = { 0, 1, 0, 1, 0, 1, 7, 5, 6, 0, 0, 0, 0, 0, 0, 7 }; + GDWriteBPCmd(BP_TEV_ORDER( + map0 & 7, + coord0 & 7, + map0 != GX_TEXMAP_NULL && !(map0 & GX_TEX_DISABLE), + c2r[color0 & 0xF], + map1 & 7, + coord1 & 7, + map1 != GX_TEXMAP_NULL && !(map1 & GX_TEX_DISABLE), + c2r[color1 & 0xF], + evenStage / 2 + 0x28 + )); +} diff --git a/src/dolphin/gd/GDTexture.c b/src/dolphin/gd/GDTexture.c new file mode 100644 index 0000000000..c3c1a6c729 --- /dev/null +++ b/src/dolphin/gd/GDTexture.c @@ -0,0 +1,104 @@ +#include +#include + +u8 GD2HWFiltConv[] = {0, 4, 1, 5, 2, 6}; + +u8 GDTexMode0Ids[8] = {128, 129, 130, 131, 160, 161, 162, 163}; +u8 GDTexMode1Ids[8] = {132, 133, 134, 135, 164, 165, 166, 167}; +u8 GDTexImage0Ids[8] = {136, 137, 138, 139, 168, 169, 170, 171}; +u8 GDTexImage1Ids[8] = {140, 141, 142, 143, 172, 173, 174, 175}; +u8 GDTexImage2Ids[8] = {144, 145, 146, 147, 176, 177, 178, 179}; +u8 GDTexImage3Ids[8] = {148, 149, 150, 151, 180, 181, 182, 183}; +u8 GDTexTlutIds[8] = {152, 153, 154, 155, 184, 185, 186, 187}; + +void GDSetTexLookupMode(GXTexMapID id, GXTexWrapMode wrap_s, + GXTexWrapMode wrap_t, GXTexFilter min_filt, + GXTexFilter mag_filt, f32 min_lod, f32 max_lod, + f32 lod_bias, u8 bias_clamp, u8 do_edge_lod, + GXAnisotropy max_aniso) { + GDWriteBPCmd(BP_TEX_MODE0(wrap_s, wrap_t, mag_filt == TRUE, GD2HWFiltConv[min_filt], !do_edge_lod, (u8)(32.0f * lod_bias), max_aniso, bias_clamp, GDTexMode0Ids[id])); + GDWriteBPCmd(BP_TEX_MODE1((u8)(16.0f * min_lod), (u8)(16.0f * max_lod), GDTexMode1Ids[id])); +} + +void GDSetTexImgAttr(GXTexMapID id, u16 width, u16 height, GXTexFmt format) { + GDWriteBPCmd(BP_IMAGE_ATTR(width - 1, height - 1, format, GDTexImage0Ids[id])); +} + +void GDSetTexImgPtr(GXTexMapID id, void* image_ptr) { + GDWriteBPCmd(BP_IMAGE_PTR(OSCachedToPhysical(image_ptr) >> 5, GDTexImage3Ids[id])); +} + +void GDSetTexImgPtrRaw(GXTexMapID id, u32 image_ptr_raw) { + GDWriteBPCmd(BP_IMAGE_PTR(image_ptr_raw, GDTexImage3Ids[id])); +} + +void GDPatchTexImgPtr(void* image_ptr) { + GDWrite_u24(OSCachedToPhysical(image_ptr) >> 5); +} + +void GDSetTexCached(GXTexMapID id, u32 tmem_even, GXTexCacheSize size_even, + u32 tmem_odd, GXTexCacheSize size_odd) { + GDWriteBPCmd(BP_TEX_CACHE_EVEN(tmem_even >> 5, size_even + 3, size_even + 3, 0, GDTexImage1Ids[id])); + + if (size_odd != 3 && tmem_odd < 0x100000) { + GDWriteBPCmd(BP_TEX_CACHE_ODD(tmem_odd >> 5, size_odd + 3, size_odd + 3, GDTexImage2Ids[id])); + } +} + + +void GDSetTexPreLoaded(GXTexMapID id, u32 tmem_even, u32 tmem_odd) { + GDWriteBPCmd(BP_TEX_CACHE_EVEN(tmem_even >> 5, 0, 0, 1, GDTexImage1Ids[id])); + + if (tmem_odd < 0x100000) { + GDWriteBPCmd(BP_TEX_CACHE_ODD(tmem_odd >> 5, 0, 0, GDTexImage2Ids[id])); + } +} + +void GDSetTexTlut(GXTexMapID id, u32 tmem_addr, GXTlutFmt format) { + GDWriteBPCmd(BP_TEX_TLUT((tmem_addr - 0x80000) >> 9, format, GDTexTlutIds[id])); +} + +void GDSetTexCoordScale(GXTexCoordID coord, u16 s_scale, u16 t_scale) { + GDWriteBPCmd(0xFE00FFFF); + GDWriteBPCmd(BP_TEXCOORD_S_SCALE(s_scale - 1, 0, 0, 0, 0, coord * 2 + 0x30)); + + GDWriteBPCmd(0xFE00FFFF); + GDWriteBPCmd(BP_TEXCOORD_T_SCALE(t_scale - 1, 0, 0, coord * 2 + 0x31)); +} + +void GDSetTexCoordScale2(GXTexCoordID coord, u16 s_scale, u8 s_bias, + u8 s_wrap, u16 t_scale, u8 t_bias, u8 t_wrap) { + GDWriteBPCmd(0xFE03FFFF); + GDWriteBPCmd(BP_TEXCOORD_S_SCALE(s_scale - 1, s_bias, s_wrap, 0, 0, coord * 2 + 0x30)); + GDWriteBPCmd(BP_TEXCOORD_T_SCALE(t_scale - 1, t_bias, t_wrap, coord * 2 + 0x31)); +} + +void GDSetTexCoordScaleAndTOEs(GXTexCoordID coord, u16 s_scale, u8 s_bias, + u8 s_wrap, u16 t_scale, u8 t_bias, u8 t_wrap, + u8 line_offset, u8 point_offset) { + GDWriteBPCmd(BP_TEXCOORD_S_SCALE(s_scale - 1, s_bias, s_wrap, line_offset, point_offset, coord * 2 + 0x30)); + GDWriteBPCmd(BP_TEXCOORD_T_SCALE(t_scale - 1, t_bias, t_wrap, coord * 2 + 0x31)); +} + +void GDLoadTlut(void* tlut_ptr, u32 tmem_addr, GXTlutSize size) { + ASSERTMSGLINE(488, !(tmem_addr & 0x1ff), "GDLoadTlut: invalid TMEM pointer"); + ASSERTMSGLINE(489, size <= 0x400, "GDLoadTlut: invalid TLUT size"); + + GDWriteBPCmd(0xFEFFFF00); + GDWriteBPCmd(0xF000000); + GDWriteBPCmd(BP_LOAD_TLUT0(OSCachedToPhysical(tlut_ptr) >> 5, 0x64)); + GDWriteBPCmd(BP_LOAD_TLUT1((tmem_addr - 0x80000) >> 9, size, 0x65)); + GDWriteBPCmd(0xFEFFFF00); + GDWriteBPCmd(0xF000000); +} + +void GDLoadTlutRaw(u32 tlut_ptr_raw, u32 tmem_addr, GXTlutSize size) { + ASSERTMSGLINE(527, size <= 0x400, "GDLoadTlut: invalid TLUT size"); + + GDWriteBPCmd(0xFEFFFF00); + GDWriteBPCmd(0xF000000); + GDWriteBPCmd(BP_LOAD_TLUT0(tlut_ptr_raw, 0x64)); + GDWriteBPCmd(BP_LOAD_TLUT1((tmem_addr - 0x80000) >> 9, size, 0x65)); + GDWriteBPCmd(0xFEFFFF00); + GDWriteBPCmd(0xF000000); +} diff --git a/src/dolphin/gd/GDTransform.c b/src/dolphin/gd/GDTransform.c new file mode 100644 index 0000000000..9ac9c66db8 --- /dev/null +++ b/src/dolphin/gd/GDTransform.c @@ -0,0 +1,127 @@ +#include +#include + +void GDLoadPosMtxImm(const Mtx mtx, u32 id) { + GDWriteXFCmdHdr(4 * id, 12); + GDWrite_f32(mtx[0][0]); + GDWrite_f32(mtx[0][1]); + GDWrite_f32(mtx[0][2]); + GDWrite_f32(mtx[0][3]); + GDWrite_f32(mtx[1][0]); + GDWrite_f32(mtx[1][1]); + GDWrite_f32(mtx[1][2]); + GDWrite_f32(mtx[1][3]); + GDWrite_f32(mtx[2][0]); + GDWrite_f32(mtx[2][1]); + GDWrite_f32(mtx[2][2]); + GDWrite_f32(mtx[2][3]); +} + +void GDLoadPosMtxIndx(u16 mtx_indx, u32 id) { + GDWriteXFIndxACmd(4 * id, 12, mtx_indx); +} + +void GDLoadNrmMtxImm(const Mtx mtx, u32 id) { + GDWriteXFCmdHdr(id * 3 + 0x400, 9); + GDWrite_f32(mtx[0][0]); + GDWrite_f32(mtx[0][1]); + GDWrite_f32(mtx[0][2]); + GDWrite_f32(mtx[1][0]); + GDWrite_f32(mtx[1][1]); + GDWrite_f32(mtx[1][2]); + GDWrite_f32(mtx[2][0]); + GDWrite_f32(mtx[2][1]); + GDWrite_f32(mtx[2][2]); +} + +void GDLoadNrmMtxImm3x3(const f32 mtx[3][3], u32 id) { + GDWriteXFCmdHdr(id * 3 + 0x400, 9); + GDWrite_f32(mtx[0][0]); + GDWrite_f32(mtx[0][1]); + GDWrite_f32(mtx[0][2]); + GDWrite_f32(mtx[1][0]); + GDWrite_f32(mtx[1][1]); + GDWrite_f32(mtx[1][2]); + GDWrite_f32(mtx[2][0]); + GDWrite_f32(mtx[2][1]); + GDWrite_f32(mtx[2][2]); +} + +void GDLoadNrmMtxIndx3x3(u16 mtx_indx, u32 id) { + GDWriteXFIndxBCmd(id * 3 + 0x400, 9, mtx_indx); +} + +void GDLoadTexMtxImm(const Mtx mtx, u32 id, GXTexMtxType type) { + u16 addr; + u8 count; + + if (id >= 0x40) { + ASSERTMSGLINE(178, type == GX_MTX3x4, "GDLoadTexMtxImm: invalid matrix type"); + addr = ((id - 0x40) << 2) + 0x500; + count = 12; + } else { + addr = 4 * id; + count = type == GX_MTX2x4 ? 8 : 12; + } + + GDWriteXFCmdHdr(addr,count); + GDWrite_f32(mtx[0][0]); + GDWrite_f32(mtx[0][1]); + GDWrite_f32(mtx[0][2]); + GDWrite_f32(mtx[0][3]); + GDWrite_f32(mtx[1][0]); + GDWrite_f32(mtx[1][1]); + GDWrite_f32(mtx[1][2]); + GDWrite_f32(mtx[1][3]); + + if (type == GX_MTX3x4) { + GDWrite_f32(mtx[2][0]); + GDWrite_f32(mtx[2][1]); + GDWrite_f32(mtx[2][2]); + GDWrite_f32(mtx[2][3]); + } +} + +void GDLoadTexMtxIndx(u16 mtx_indx, u32 id, GXTexMtxType type) { + u16 addr; + u8 count; + + if (id >= 0x40) { + ASSERTMSGLINE(227, type == GX_MTX3x4, "GDLoadTexMtxIndx: invalid matrix type"); + addr = ((id - 0x40) << 2) + 0x500; + count = 12; + } else { + addr = 4 * id; + count = type == GX_MTX2x4 ? 8 : 12; + } + + GDWriteXFIndxCCmd(addr, count, mtx_indx); +} + +void GDSetCurrentMtx(u32 pn, u32 t0, u32 t1, u32 t2, u32 t3, u32 t4, u32 t5, u32 t6, u32 t7) { + u32 regA; + u32 regB; + + regA = CP_MTX_REG_A(pn, t0, t1, t2, t3); + regB = CP_MTX_REG_B(t4, t5, t6, t7); + + GDWriteCPCmd(CP_MTX_REG_A_ID, regA); + GDWriteCPCmd(CP_MTX_REG_B_ID, regB); + GDWriteXFCmdHdr(XF_REG_MATRIXINDEX0_ID, 2); + GDWrite_u32(regA); + GDWrite_u32(regB); +} + +void GDSetProjection(const Mtx44 mtx, GXProjectionType type) { + u32 c; + c = type == GX_ORTHOGRAPHIC ? 3 : 2; + + GDWriteXFCmdHdr(XF_REG_PROJECTIONA_ID, 7); + GDWrite_f32(mtx[0][0]); + GDWrite_f32(mtx[0][c]); + GDWrite_f32(mtx[1][1]); + GDWrite_f32(mtx[1][c]); + GDWrite_f32(mtx[2][2]); + GDWrite_f32(mtx[2][3]); + GDWrite_u32(type); +} diff --git a/src/dolphin/gf/GFGeometry.cpp b/src/dolphin/gf/GFGeometry.cpp index 99b40dba1c..00be72ee01 100644 --- a/src/dolphin/gf/GFGeometry.cpp +++ b/src/dolphin/gf/GFGeometry.cpp @@ -1,21 +1,10 @@ -// -// Generated By: dol2asm -// Translation Unit: GFGeometry -// +#include +#include -#include "dolphin/gf/GFGeometry.h" - -/* 802CDDC8-802CDE54 2C8708 008C+00 0/0 0/0 1/1 .text GFSetGenMode2__FUcUcUcUc11_GXCullMode */ -// NONMATCHING regalloc -void GFSetGenMode2(u8 param_0, u8 param_1, u8 param_2, u8 param_3, _GXCullMode param_4) { +void GFSetGenMode2(u8 nTexGens, u8 nChans, u8 nTevs, u8 nInds, GXCullMode cm) { static u8 cm2hw[4] = {0, 2, 1, 3}; GFWriteBPCmd(0xFE07FC3F); - GFWriteBPCmd((param_0) | (param_1 << 4) | ((param_2 - 1) << 10) | (cm2hw[param_4] << 14) | (param_3 << 16)); - GFFill(0x1009, param_1); - GFFill(0x103f, param_0); + GFWriteBPCmd(GF_GEN_MODE(nTexGens, nChans, nTevs - 1, cm2hw[cm], nInds)); + GFWriteXFCmd(XF_REG_NUMCOLORS_ID, nChans); + GFWriteXFCmd(XF_REG_NUMTEX_ID, nTexGens); } - -/* 804508B0-804508B8 000330 0008+00 0/0 2/2 0/0 .sdata None */ -extern u8 data_804508B0[8] = { - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; diff --git a/src/dolphin/gf/GFLight.cpp b/src/dolphin/gf/GFLight.cpp index c9b58741b2..612c005ab3 100644 --- a/src/dolphin/gf/GFLight.cpp +++ b/src/dolphin/gf/GFLight.cpp @@ -1,9 +1,6 @@ -#include "dolphin/gf/GFLight.h" -#include "dolphin/gx.h" +#include +#include -/* 802CDE54-802CDE9C 2C8794 0048+00 0/0 0/0 1/1 .text GFSetChanAmbColor__F12_GXChannelID8_GXColor - */ -void GFSetChanAmbColor(_GXChannelID param_0, _GXColor param_1) { - GFFill((param_0 & 1) + 0x100a, - param_1.r << 0x18 | param_1.g << 0x10 | param_1.b << 8 | param_1.a); -} \ No newline at end of file +void GFSetChanAmbColor(GXChannelID chan, GXColor color) { + GFWriteXFCmd((chan & 1) + XF_REG_AMBIENT0_ID, color.r << 0x18 | color.g << 0x10 | color.b << 8 | color.a); +} diff --git a/src/dolphin/gf/GFPixel.cpp b/src/dolphin/gf/GFPixel.cpp index 375cd190c5..d78ca9247e 100644 --- a/src/dolphin/gf/GFPixel.cpp +++ b/src/dolphin/gf/GFPixel.cpp @@ -1,59 +1,74 @@ -#include "dolphin/gf/GFPixel.h" -#include "dolphin/gx.h" +#include +#include -/* 802CDE9C-802CE004 2C87DC 0168+00 0/0 1/1 0/0 .text GFSetFog__F10_GXFogTypeffff8_GXColor */ -void GFSetFog(GXFogType param_0, f32 param_1, f32 param_2, f32 param_3, f32 param_4, - GXColor param_5) { - s32 r30; - s32 r30shift2; - u32 stack_c_u32; - f32 stack_c; - f32 r30shift; - f32 f3; - f32 f5; - if (param_4 == param_3 || param_2 == param_1) { - f5 = 0.0f; - f3 = 0.5f; - stack_c = 0.0f; +void GFSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color) { + f32 A; + f32 B; + f32 B_mant; + f32 C; + f32 A_f; + u32 b_expn; + u32 b_m; + u32 a_hex; + u32 c_hex; + + ASSERTMSGLINE(62, farz >= 0.0f, "GFSetFog: The farz should be positive value"); + ASSERTMSGLINE(63, farz >= nearz, "GFSetFog: The farz should be larger than nearz"); + + if (farz == nearz || endz == startz) { + A = 0.0f; + B = 0.5f; + C = 0.0f; } else { - f5 = (param_4 * param_3) / ((param_4 - param_3) * (param_2 - param_1)); - f3 = param_4 / (param_4 - param_3); - stack_c = param_1 / (param_2 - param_1); + A = (farz * nearz) / ((farz - nearz) * (endz - startz)); + B = farz / (farz - nearz); + C = startz / (endz - startz); } - r30 = 1; + B_mant = B; + b_expn = 1; - while (f3 > 1.0) { - f3 *= 0.5f; - r30++; + while (B_mant > 1.0) { + B_mant *= 0.5f; + b_expn++; } - while (f3 > 0.0f && f3 < 0.5) { - f3 *= 2.0f; - r30--; + while (B_mant > 0.0f && B_mant < 0.5) { + B_mant *= 2.0f; + b_expn--; } - r30shift = (f5 / (1 << r30)); - r30shift2 = *(s32*)&r30shift; - stack_c_u32 = (*(u32*)&stack_c); - GFWriteBPCmd(((r30shift2 >> 12) & 0xfffff) | 0xee000000); - GFWriteBPCmd((u32)(8388638.0f * f3) | 0xef000000); - GFWriteBPCmd(r30 | 0xf0000000); - GFWriteBPCmd(((stack_c_u32 >> 12) & 0xfffff) | (((u32)param_0 << 21) & 0xffe00000) | - 0xf1000000); - GFWriteBPCmd(param_5.b | param_5.g << 8 | param_5.r << 16 | 0xf2000000); + A_f = A / (1 << b_expn); + b_m = (u32) (8388638.0f * B_mant); + + a_hex = *(u32*)&A_f; + c_hex = *(u32*)&C; + + GFWriteBPCmd(BP_FOG_UNK0(a_hex >> 12, 0xEE)); + GFWriteBPCmd(BP_FOG_UNK1(b_m, 0xEF)); + GFWriteBPCmd(BP_FOG_UNK2(b_expn, 0xF0)); + GFWriteBPCmd(BP_FOG_UNK3(c_hex >> 12, 0, type, 0xF1)); + GFWriteBPCmd(BP_FOG_COLOR(color.r, color.g, color.b, 0xF2)); } -/* 802CE004-802CE0A4 2C8944 00A0+00 0/0 1/1 0/0 .text - * GFSetBlendModeEtc__F12_GXBlendMode14_GXBlendFactor14_GXBlendFactor10_GXLogicOpUcUcUc */ -void GFSetBlendModeEtc(GXBlendMode param_0, GXBlendFactor param_1, GXBlendFactor param_2, - GXLogicOp param_3, u8 param_4, u8 param_5, u8 param_6) { - GFWriteBPCmd(((param_0 == 1) || (param_0 == 3)) | (param_0 == 2) << 1 | param_6 << 2 | - param_4 << 3 | param_5 << 4 | param_2 << 5 | param_1 << 8 | (param_0 == 3) << 11 | - param_3 << 12 | 0x41000000); +void GFSetBlendModeEtc(GXBlendMode type, GXBlendFactor src_factor, + GXBlendFactor dst_factor, GXLogicOp logic_op, + u8 color_update_enable, u8 alpha_update_enable, + u8 dither_enable) { + GFWriteBPCmd(BP_BLEND_MODE( + type == GX_BM_BLEND || type == GX_BM_SUBTRACT, + type == GX_BM_LOGIC, + dither_enable, + color_update_enable, + alpha_update_enable, + dst_factor, + src_factor, + type == GX_BM_SUBTRACT, + logic_op, + 0x41 + )); } -/* 802CE0A4-802CE0D0 2C89E4 002C+00 0/0 1/1 0/0 .text GFSetZMode__FUc10_GXCompareUc */ -void GFSetZMode(u8 param_0, GXCompare param_1, u8 param_2) { - GFWriteBPCmd(param_0 | param_1 << 1 | param_2 << 4 | 0x40000000); +void GFSetZMode(u8 compare_enable, GXCompare func, u8 update_enable) { + GFWriteBPCmd(BP_Z_MODE(compare_enable, func, update_enable, 0x40)); } diff --git a/src/dolphin/gf/GFTev.cpp b/src/dolphin/gf/GFTev.cpp index d812baef2e..20fd3e231d 100644 --- a/src/dolphin/gf/GFTev.cpp +++ b/src/dolphin/gf/GFTev.cpp @@ -1,14 +1,15 @@ -#include "dolphin/gf/GFTev.h" -#include "dolphin/gx.h" +#include +#include -/* 802CE0D0-802CE138 2C8A10 0068+00 0/0 0/0 1/1 .text - * GFSetTevColorS10__F11_GXTevRegID11_GXColorS10 */ -void GFSetTevColorS10(_GXTevRegID param_0, _GXColorS10 param_1) { - u32 uVar1 = (param_1.r & 0x7ffU) | ((param_1.a & 0x7ffU) << 12) | ((param_0 * 2 + 0xe0) << 24); - u32 uVar2 = (param_1.b & 0x7ffU) | ((param_1.g & 0x7ffU) << 12) | ((param_0 * 2 + 0xe1) << 24); +void GFSetTevColorS10(GXTevRegID reg, GXColorS10 color) { + u32 regRA; + u32 regBG; - GFWriteBPCmd(uVar1); - GFWriteBPCmd(uVar2); - GFWriteBPCmd(uVar2); - GFWriteBPCmd(uVar2); -} \ No newline at end of file + regRA = BP_TEV_COLOR_REG_RA(color.r & 0x7FF, color.a & 0x7FF, 0, 0xE0 + reg * 2); + regBG = BP_TEV_COLOR_REG_BG(color.b & 0x7FF, color.g & 0x7FF, 0, 0xE1 + reg * 2); + + GFWriteBPCmd(regRA); + GFWriteBPCmd(regBG); + GFWriteBPCmd(regBG); + GFWriteBPCmd(regBG); +} diff --git a/src/dolphin/gx/GXAttr.c b/src/dolphin/gx/GXAttr.c index 4f6ac60e62..136661d6df 100644 --- a/src/dolphin/gx/GXAttr.c +++ b/src/dolphin/gx/GXAttr.c @@ -1,689 +1,585 @@ -#include "dolphin/gx/GXAttr.h" -#include "dolphin/gx.h" +#include +#include -static inline void SETVCDATTR(GXAttr name, GXAttrType type) { - switch (name) { - case GX_VA_PNMTXIDX: - GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_POSMTXIDX_ST, GX_CP_VCD_LO_POSMTXIDX_END); - break; - case GX_VA_TEX0MTXIDX: - GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_TEX0MTXIDX_ST, - GX_CP_VCD_LO_TEX0MTXIDX_END); - break; - case GX_VA_TEX1MTXIDX: - GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_TEX1MTXIDX_ST, - GX_CP_VCD_LO_TEX1MTXIDX_END); - break; - case GX_VA_TEX2MTXIDX: - GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_TEX2MTXIDX_ST, - GX_CP_VCD_LO_TEX2MTXIDX_END); - break; - case GX_VA_TEX3MTXIDX: - GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_TEX3MTXIDX_ST, - GX_CP_VCD_LO_TEX3MTXIDX_END); - break; - case GX_VA_TEX4MTXIDX: - GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_TEX4MTXIDX_ST, - GX_CP_VCD_LO_TEX4MTXIDX_END); - break; - case GX_VA_TEX5MTXIDX: - GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_TEX5MTXIDX_ST, - GX_CP_VCD_LO_TEX5MTXIDX_END); - break; - case GX_VA_TEX6MTXIDX: - GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_TEX6MTXIDX_ST, - GX_CP_VCD_LO_TEX6MTXIDX_END); - break; - case GX_VA_TEX7MTXIDX: - GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_TEX7MTXIDX_ST, - GX_CP_VCD_LO_TEX7MTXIDX_END); - break; - case GX_VA_POS: - GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_POS_ST, GX_CP_VCD_LO_POS_END); - break; +#include "__gx.h" + +#define CHECK_ATTRPTR(line, attrPtr) ASSERTMSGLINE(line, (attrPtr) != NULL, "GXSetVtxDescv: attrPtr is NULL") +#define CHECK_ATTRNAME(line, attr) ASSERTMSGLINE(line, (attr) >= GX_VA_PNMTXIDX, "GXSetVtxDesc: Invalid vertex attribute name") +#define CHECK_ATTRNAME2(line, attr) ASSERTMSGLINE(line, (attr) <= GX_VA_TEX7 || (attr) == GX_VA_NBT, "GXSetVtxDesc: Invalid vertex attribute name") +#define CHECK_ATTRNAME3(line, attr) ASSERTMSGLINE(line, (attr) >= GX_VA_PNMTXIDX && (attr) < GX_VA_MAX_ATTR, "GXSetVtxDesc: Invalid vertex attribute name") +#define CHECK_ATTRNAME4(line, attr) ASSERTMSGLINE(line, ((attr) >= GX_VA_POS && (attr) <= GX_VA_TEX7) || (attr) == GX_VA_NBT, "GXSetVtxAttrFmt: Invalid vertex attribute name") +#define CHECK_ATTRNAME5(line, attr) ASSERTMSGLINE(line, (attr) >= GX_VA_POS && (attr) <= GX_LIGHT_ARRAY, "GXSetArray: Invalid vertex attribute name") +#define CHECK_ATTRTYPE(line, type) ASSERTMSGLINE(line, (type) >= GX_NONE && (type) <= GX_INDEX16, "GXSetVtxDesc: Invalid vertex attribute type") +#define CHECK_VTXFMT(line, vtxfmt) ASSERTMSGLINE(line, (vtxfmt) < GX_MAX_VTXFMT, "GXSetVtxAttrFmt: Format Index is out of range") +#define CHECK_FRAC(line, frac) ASSERTMSGLINE(line, (frac) < 32, "GXSetVtxAttrFmt: Frac value is >= 32") +#define CHECK_LISTPTR(line, list) ASSERTMSGLINE(line, (list) != NULL, "GXSetVtxAttrFmt: list pointer is NULL") +#define CHECK_MTXIDX(line, attr, type) ASSERTMSGLINE(line, (attr) > GX_VA_TEX7MTXIDX || (type) <= GX_VA_TEX0MTXIDX, "GXSetVtxDesc: GX_VA_*MTXIDX accepts GX_NONE or GX_DIRECT only") + +static void __GXXfVtxSpecs(void) { + u32 nCols = 0; + u32 nNrm; + u32 nTex; + u32 reg; + + nNrm = __GXData->hasBiNrms ? 2 : __GXData->hasNrms ? 1 : 0; + +#ifdef DEBUG + nCols = GET_REG_FIELD(__GXData->vcdLo, 2, 13) ? 1 : 0; + nCols += GET_REG_FIELD(__GXData->vcdLo, 2, 15) ? 1 : 0; +#else + nCols = 33 - __cntlzw(GET_REG_FIELD(__GXData->vcdLo, 4, 13)); + nCols /= 2; +#endif + +#ifdef DEBUG + nTex = 0; + nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 0) ? 1 : 0; + nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 2) ? 1 : 0; + nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 4) ? 1 : 0; + nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 6) ? 1 : 0; + nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 8) ? 1 : 0; + nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 10) ? 1 : 0; + nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 12) ? 1 : 0; + nTex += GET_REG_FIELD(__GXData->vcdHi, 2, 14) ? 1 : 0; +#else + nTex = 33 - __cntlzw(GET_REG_FIELD(__GXData->vcdHi, 16, 0)); + nTex /= 2; +#endif + + reg = (nCols) | (nNrm << 2) | (nTex << 4); + GX_WRITE_XF_REG(8, reg); + __GXData->bpSentNot = 1; +} + +static inline void SETVCDATTR(GXAttr Attr, GXAttrType Type) { + switch (Attr) { + case GX_VA_PNMTXIDX: SET_REG_FIELD(212, __GXData->vcdLo, 1, 0, Type); break; + case GX_VA_TEX0MTXIDX: SET_REG_FIELD(213, __GXData->vcdLo, 1, 1, Type); break; + case GX_VA_TEX1MTXIDX: SET_REG_FIELD(214, __GXData->vcdLo, 1, 2, Type); break; + case GX_VA_TEX2MTXIDX: SET_REG_FIELD(215, __GXData->vcdLo, 1, 3, Type); break; + case GX_VA_TEX3MTXIDX: SET_REG_FIELD(216, __GXData->vcdLo, 1, 4, Type); break; + case GX_VA_TEX4MTXIDX: SET_REG_FIELD(217, __GXData->vcdLo, 1, 5, Type); break; + case GX_VA_TEX5MTXIDX: SET_REG_FIELD(218, __GXData->vcdLo, 1, 6, Type); break; + case GX_VA_TEX6MTXIDX: SET_REG_FIELD(219, __GXData->vcdLo, 1, 7, Type); break; + case GX_VA_TEX7MTXIDX: SET_REG_FIELD(220, __GXData->vcdLo, 1, 8, Type); break; + case GX_VA_POS: SET_REG_FIELD(221, __GXData->vcdLo, 2, 9, Type); break; case GX_VA_NRM: - if (type != GX_NONE) { - __GXData->hasNrms = TRUE; - __GXData->hasBiNrms = FALSE; - __GXData->nrmType = type; + if (Type != GX_NONE) { + __GXData->hasNrms = 1; + __GXData->hasBiNrms = 0; + __GXData->nrmType = Type; } else { - __GXData->hasNrms = FALSE; + __GXData->hasNrms = 0; } break; case GX_VA_NBT: - if (type != GX_NONE) { - __GXData->hasBiNrms = TRUE; - __GXData->hasNrms = FALSE; - __GXData->nrmType = type; + if (Type != GX_NONE) { + __GXData->hasBiNrms = 1; + __GXData->hasNrms = 0; + __GXData->nrmType = Type; } else { - __GXData->hasBiNrms = FALSE; + __GXData->hasBiNrms = 0; } break; - case GX_VA_CLR0: - GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_CLRDIF_ST, GX_CP_VCD_LO_CLRDIF_END); - break; - case GX_VA_CLR1: - GX_SET_REG(__GXData->vcdLo, type, GX_CP_VCD_LO_CLRSPEC_ST, GX_CP_VCD_LO_CLRSPEC_END); - break; - case GX_VA_TEX0: - GX_SET_REG(__GXData->vcdHi, type, GX_CP_VCD_HI_TEX0COORD_ST, GX_CP_VCD_HI_TEX0COORD_END); - break; - case GX_VA_TEX1: - GX_SET_REG(__GXData->vcdHi, type, GX_CP_VCD_HI_TEX1COORD_ST, GX_CP_VCD_HI_TEX1COORD_END); - break; - case GX_VA_TEX2: - GX_SET_REG(__GXData->vcdHi, type, GX_CP_VCD_HI_TEX2COORD_ST, GX_CP_VCD_HI_TEX2COORD_END); - break; - case GX_VA_TEX3: - GX_SET_REG(__GXData->vcdHi, type, GX_CP_VCD_HI_TEX3COORD_ST, GX_CP_VCD_HI_TEX3COORD_END); - break; - case GX_VA_TEX4: - GX_SET_REG(__GXData->vcdHi, type, GX_CP_VCD_HI_TEX4COORD_ST, GX_CP_VCD_HI_TEX4COORD_END); - break; - case GX_VA_TEX5: - GX_SET_REG(__GXData->vcdHi, type, GX_CP_VCD_HI_TEX5COORD_ST, GX_CP_VCD_HI_TEX5COORD_END); - break; - case GX_VA_TEX6: - GX_SET_REG(__GXData->vcdHi, type, GX_CP_VCD_HI_TEX6COORD_ST, GX_CP_VCD_HI_TEX6COORD_END); - break; - case GX_VA_TEX7: - GX_SET_REG(__GXData->vcdHi, type, GX_CP_VCD_HI_TEX7COORD_ST, GX_CP_VCD_HI_TEX7COORD_END); - break; + case GX_VA_CLR0: SET_REG_FIELD(246, __GXData->vcdLo, 2, 13, Type); break; + case GX_VA_CLR1: SET_REG_FIELD(247, __GXData->vcdLo, 2, 15, Type); break; + case GX_VA_TEX0: SET_REG_FIELD(248, __GXData->vcdHi, 2, 0, Type); break; + case GX_VA_TEX1: SET_REG_FIELD(249, __GXData->vcdHi, 2, 2, Type); break; + case GX_VA_TEX2: SET_REG_FIELD(250, __GXData->vcdHi, 2, 4, Type); break; + case GX_VA_TEX3: SET_REG_FIELD(251, __GXData->vcdHi, 2, 6, Type); break; + case GX_VA_TEX4: SET_REG_FIELD(252, __GXData->vcdHi, 2, 8, Type); break; + case GX_VA_TEX5: SET_REG_FIELD(253, __GXData->vcdHi, 2, 10, Type); break; + case GX_VA_TEX6: SET_REG_FIELD(254, __GXData->vcdHi, 2, 12, Type); break; + case GX_VA_TEX7: SET_REG_FIELD(255, __GXData->vcdHi, 2, 14, Type); break; } } -void GXSetVtxDesc(GXAttr name, GXAttrType type) { - SETVCDATTR(name, type); +void GXSetVtxDesc(GXAttr attr, GXAttrType type) { + CHECK_GXBEGIN(264, "GXSetVtxDesc"); + CHECK_ATTRNAME(267, attr); + CHECK_ATTRNAME2(269, attr); + CHECK_ATTRTYPE(271, type); + CHECK_MTXIDX(274, attr, type); - // Set normal data type if enabled + SETVCDATTR(attr, type); if (__GXData->hasNrms || __GXData->hasBiNrms) { - GX_BITFIELD_SET(__GXData->vcdLo, 19, 2, __GXData->nrmType); + SET_REG_FIELD(280, __GXData->vcdLo, 2, 11, __GXData->nrmType); } else { - GX_BITFIELD_SET(__GXData->vcdLo, 19, 2, 0); + SET_REG_FIELD(0, __GXData->vcdLo, 2, 11, 0); } - - __GXData->dirtyState |= GX_DIRTY_VCD; + __GXData->dirtyState |= 8; } -/* 8035B124-8035B3AC 355A64 0288+00 1/0 0/0 1/1 .text GXSetVtxDescv */ -void GXSetVtxDescv(GXVtxDescList* list) { - for (; list->attr != GX_VA_NULL; list++) { - SETVCDATTR(list->attr, list->type); +void GXSetVtxDescv(const GXVtxDescList *attrPtr) { + CHECK_GXBEGIN(306, "GXSetVtxDescv"); + CHECK_ATTRPTR(307, attrPtr); + + while (attrPtr->attr != GX_VA_NULL) { + CHECK_ATTRNAME(311, attrPtr->attr); + CHECK_ATTRNAME2(314, attrPtr->attr); + CHECK_ATTRTYPE(317, attrPtr->type); + SETVCDATTR(attrPtr->attr, attrPtr->type); + attrPtr++; } - // Set normal data type if enabled if (__GXData->hasNrms || __GXData->hasBiNrms) { - GX_BITFIELD_SET(__GXData->vcdLo, 19, 2, __GXData->nrmType); + SET_REG_FIELD(326, __GXData->vcdLo, 2, 11, __GXData->nrmType); } else { - GX_BITFIELD_SET(__GXData->vcdLo, 19, 2, 0); + SET_REG_FIELD(326, __GXData->vcdLo, 2, 11, 0); } - - __GXData->dirtyState |= GX_DIRTY_VCD; + __GXData->dirtyState |= 8; } -static void __GXXfVtxSpecs(void) { - u32 normCount, colorCount, texCount; - - normCount = __GXData->hasBiNrms ? 2 : (__GXData->hasNrms ? 1 : 0); - - // Both fields in one access - colorCount = 33 - __cntlzw((__GXData->vcdLo & (0xf << 0xd)) >> 0xd); - colorCount /= 2; // equivalent to /=2 and >>= 1 - - // All 16 assigned bits in VCD_Hi - texCount = 33 - __cntlzw((__GXData->vcdHi & (0xffff << 0)) >> 0); - texCount /= 2; // equivalent to /=2 and >>= 1 - - GX_XF_LOAD_REG(GX_XF_REG_INVERTEXSPEC, (colorCount) | (normCount << 2) | (texCount << 4)); - __GXData->bpSentNot = GX_TRUE; - - return; -} - -/* 8035B3AC-8035B468 355CEC 00BC+00 0/0 2/2 0/0 .text __GXSetVCD */ void __GXSetVCD(void) { - GX_CP_LOAD_REG(GX_CP_REG_VCD_LO, __GXData->vcdLo); - GX_CP_LOAD_REG(GX_CP_REG_VCD_HI, __GXData->vcdHi); - + GX_WRITE_SOME_REG4(8, 0x50, __GXData->vcdLo, -12); + GX_WRITE_SOME_REG4(8, 0x60, __GXData->vcdHi, -12); __GXXfVtxSpecs(); } -/* 8035B468-8035B58C 355DA8 0124+00 0/0 2/2 0/0 .text __GXCalculateVLim */ void __GXCalculateVLim(void) { - static u8 tbl1[] = {0, 4, 1, 2}; - static u8 tbl2[] = {0, 8, 1, 2}; - static u8 tbl3[] = {0, 12, 1, 2}; + static u8 tbl1[] = { 0, 4, 1, 2 }; + static u8 tbl2[] = { 0, 8, 1, 2 }; + static u8 tbl3[] = { 0, 12, 1, 2 }; - u32 vlim; - u32 vcdLoReg; - u32 vcdHiReg; - s32 compCnt; + GXCompCnt nc = 0; + u32 vlm; + u32 b; + u32 vl; + u32 vh; + u32 va; - if (__GXData->vNum == 0) { - return; - } + if (__GXData->vNum != 0) { + vl = __GXData->vcdLo; + vh = __GXData->vcdHi; + va = __GXData->vatA[0]; + nc = GET_REG_FIELD(va, 1, 9); - vcdLoReg = __GXData->vcdLo; - vcdHiReg = __GXData->vcdHi; - - // GXCompCnt bit of normal parameters - compCnt = __GXData->vatA[GX_VTXFMT0]; - compCnt = (compCnt & 0x200) >> 9; - - vlim = GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_POSMTXIDX_ST, GX_CP_VCD_LO_POSMTXIDX_END); - vlim += GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_TEX0MTXIDX_ST, GX_CP_VCD_LO_TEX0MTXIDX_END); - vlim += GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_TEX1MTXIDX_ST, GX_CP_VCD_LO_TEX1MTXIDX_END); - vlim += GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_TEX2MTXIDX_ST, GX_CP_VCD_LO_TEX2MTXIDX_END); - vlim += GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_TEX3MTXIDX_ST, GX_CP_VCD_LO_TEX3MTXIDX_END); - vlim += GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_TEX4MTXIDX_ST, GX_CP_VCD_LO_TEX4MTXIDX_END); - vlim += GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_TEX5MTXIDX_ST, GX_CP_VCD_LO_TEX5MTXIDX_END); - vlim += GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_TEX6MTXIDX_ST, GX_CP_VCD_LO_TEX6MTXIDX_END); - vlim += GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_TEX7MTXIDX_ST, GX_CP_VCD_LO_TEX7MTXIDX_END); - - vlim += tbl3[GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_POS_ST, GX_CP_VCD_LO_POS_END)]; - vlim += tbl3[GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_NRM_ST, GX_CP_VCD_LO_NRM_END)] * - (compCnt == GX_NRM_NBT ? 3 : 1); - vlim += tbl1[GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_CLRDIF_ST, GX_CP_VCD_LO_CLRDIF_END)]; - vlim += tbl1[GX_GET_REG(vcdLoReg, GX_CP_VCD_LO_CLRSPEC_ST, GX_CP_VCD_LO_CLRSPEC_END)]; - - vlim += tbl2[GX_GET_REG(vcdHiReg, GX_CP_VCD_HI_TEX0COORD_ST, GX_CP_VCD_HI_TEX0COORD_END)]; - vlim += tbl2[GX_GET_REG(vcdHiReg, GX_CP_VCD_HI_TEX1COORD_ST, GX_CP_VCD_HI_TEX1COORD_END)]; - vlim += tbl2[GX_GET_REG(vcdHiReg, GX_CP_VCD_HI_TEX2COORD_ST, GX_CP_VCD_HI_TEX2COORD_END)]; - vlim += tbl2[GX_GET_REG(vcdHiReg, GX_CP_VCD_HI_TEX3COORD_ST, GX_CP_VCD_HI_TEX3COORD_END)]; - vlim += tbl2[GX_GET_REG(vcdHiReg, GX_CP_VCD_HI_TEX4COORD_ST, GX_CP_VCD_HI_TEX4COORD_END)]; - vlim += tbl2[GX_GET_REG(vcdHiReg, GX_CP_VCD_HI_TEX5COORD_ST, GX_CP_VCD_HI_TEX5COORD_END)]; - vlim += tbl2[GX_GET_REG(vcdHiReg, GX_CP_VCD_HI_TEX6COORD_ST, GX_CP_VCD_HI_TEX6COORD_END)]; - vlim += tbl2[GX_GET_REG(vcdHiReg, GX_CP_VCD_HI_TEX7COORD_ST, GX_CP_VCD_HI_TEX7COORD_END)]; - - __GXData->vLim = vlim; -} - -void GXGetVtxDesc(int param_0, GXAttrType* param_1) { - int local_38; - - switch (param_0) { - case 0: - local_38 = __GXData->vcdLo & 1; - break; - case 1: - local_38 = (__GXData->vcdLo & 2) >> 1; - break; - case 2: - local_38 = (__GXData->vcdLo & 4) >> 2; - break; - case 3: - local_38 = (__GXData->vcdLo & 8) >> 3; - break; - case 4: - local_38 = (__GXData->vcdLo & 0x10) >> 4; - break; - case 5: - local_38 = (__GXData->vcdLo & 0x20) >> 5; - break; - case 6: - local_38 = (__GXData->vcdLo & 0x40) >> 6; - break; - case 7: - local_38 = (__GXData->vcdLo & 0x80) >> 7; - break; - case 8: - local_38 = (__GXData->vcdLo & 0x100) >> 8; - break; - case 9: - local_38 = (__GXData->vcdLo & 0x600) >> 9; - break; - case 10: - if (__GXData->hasNrms != 0) { - local_38 = (__GXData->vcdLo & 0x1800) >> 11; + vlm = GET_REG_FIELD(vl, 1, 0); + vlm += (u8)GET_REG_FIELD(vl, 1, 1); + vlm += (u8)GET_REG_FIELD(vl, 1, 2); + vlm += (u8)GET_REG_FIELD(vl, 1, 3); + vlm += (u8)GET_REG_FIELD(vl, 1, 4); + vlm += (u8)GET_REG_FIELD(vl, 1, 5); + vlm += (u8)GET_REG_FIELD(vl, 1, 6); + vlm += (u8)GET_REG_FIELD(vl, 1, 7); + vlm += (u8)GET_REG_FIELD(vl, 1, 8); + vlm += tbl3[(u8)GET_REG_FIELD(vl, 2, 9)]; + + if (nc == 1) { + b = 3; } else { - local_38 = 0; + b = 1; } - break; - case 0x19: - if (__GXData->hasBiNrms != 0) { - local_38 = (__GXData->vcdLo & 0x1800) >> 11; - } else { - local_38 = 0; - } - break; - case 11: - local_38 = (__GXData->vcdLo & 0x6000) >> 13; - break; - case 12: - local_38 = (__GXData->vcdLo & 0x18000) >> 15; - break; - case 13: - local_38 = (__GXData->vcdHi & 3); - break; - case 14: - local_38 = (__GXData->vcdHi & 0xC) >> 2; - break; - case 15: - local_38 = (__GXData->vcdHi & 0x30) >> 4; - break; - case 16: - local_38 = (__GXData->vcdHi & 0xC0) >> 6; - break; - case 17: - local_38 = (__GXData->vcdHi & 0x300) >> 8; - break; - case 18: - local_38 = (__GXData->vcdHi & 0xC00) >> 10; - break; - case 19: - local_38 = (__GXData->vcdHi & 0x3000) >> 12; - break; - case 20: - local_38 = (__GXData->vcdHi & 0xC000) >> 14; - break; - default: - local_38 = 0; - break; - } - *param_1 = local_38; + vlm += tbl3[(u8)GET_REG_FIELD(vl, 2, 11)] * b; + vlm += tbl1[(u8)GET_REG_FIELD(vl, 2, 13)]; + vlm += tbl1[(u8)GET_REG_FIELD(vl, 2, 15)]; + vlm += tbl2[(u8)GET_REG_FIELD(vh, 2, 0)]; + vlm += tbl2[(u8)GET_REG_FIELD(vh, 2, 2)]; + vlm += tbl2[(u8)GET_REG_FIELD(vh, 2, 4)]; + vlm += tbl2[(u8)GET_REG_FIELD(vh, 2, 6)]; + vlm += tbl2[(u8)GET_REG_FIELD(vh, 2, 8)]; + vlm += tbl2[(u8)GET_REG_FIELD(vh, 2, 10)]; + vlm += tbl2[(u8)GET_REG_FIELD(vh, 2, 12)]; + vlm += tbl2[(u8)GET_REG_FIELD(vh, 2, 14)]; + __GXData->vLim = vlm; + } } -void GXGetVtxDescv(GXVtxDescList* attrPtr) { - int i; +void GXGetVtxDesc(GXAttr attr, GXAttrType* type) { + u32 cpType; - for (i = 0; i <= 0x14; i++) { - attrPtr[i].attr = (GXAttr)i; - GXGetVtxDesc(i, &attrPtr[i].type); + CHECK_GXBEGIN(458, "GXGetVtxDesc"); + CHECK_ATTRNAME3(460, attr); + + switch (attr) { + case GX_VA_PNMTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 0); break; + case GX_VA_TEX0MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 1); break; + case GX_VA_TEX1MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 2); break; + case GX_VA_TEX2MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 3); break; + case GX_VA_TEX3MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 4); break; + case GX_VA_TEX4MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 5); break; + case GX_VA_TEX5MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 6); break; + case GX_VA_TEX6MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 7); break; + case GX_VA_TEX7MTXIDX: cpType = GET_REG_FIELD(__GXData->vcdLo, 1, 8); break; + case GX_VA_POS: cpType = GET_REG_FIELD(__GXData->vcdLo, 2, 9); break; + case GX_VA_NRM: cpType = __GXData->hasNrms ? GET_REG_FIELD(__GXData->vcdLo, 2, 11) : 0; break; + case GX_VA_NBT: cpType = __GXData->hasBiNrms ? GET_REG_FIELD(__GXData->vcdLo, 2, 11) : 0; break; + case GX_VA_CLR0: cpType = GET_REG_FIELD(__GXData->vcdLo, 2, 13); break; + case GX_VA_CLR1: cpType = GET_REG_FIELD(__GXData->vcdLo, 2, 15); break; + case GX_VA_TEX0: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 0); break; + case GX_VA_TEX1: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 2); break; + case GX_VA_TEX2: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 4); break; + case GX_VA_TEX3: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 6); break; + case GX_VA_TEX4: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 8); break; + case GX_VA_TEX5: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 10); break; + case GX_VA_TEX6: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 12); break; + case GX_VA_TEX7: cpType = GET_REG_FIELD(__GXData->vcdHi, 2, 14); break; + default: cpType = 0; break; } - - attrPtr[i].attr = (GXAttr)0x19; - GXGetVtxDesc(0x19, &attrPtr[i].type); - - i++; - attrPtr[i].attr = (GXAttr)0xFF; + *type = cpType; +} + +void GXGetVtxDescv(GXVtxDescList* vcd) { + GXAttr attr; + + CHECK_GXBEGIN(511, "GXGetVtxDescv"); + CHECK_ATTRPTR(513, vcd); + + for (attr = GX_VA_PNMTXIDX; attr <= GX_VA_TEX7; attr++) { + vcd[attr].attr = attr; + GXGetVtxDesc(attr, &vcd[attr].type); + } + + vcd[attr].attr = GX_VA_NBT; + GXGetVtxDesc(GX_VA_NBT, &vcd[attr].type); + + attr++; + vcd[attr].attr = GX_VA_NULL; } -/* 8035B58C-8035B5C4 355ECC 0038+00 0/0 66/66 7/7 .text GXClearVtxDesc */ void GXClearVtxDesc(void) { + CHECK_GXBEGIN(543, "GXClearVtxDesc"); __GXData->vcdLo = 0; - GX_BITFIELD_SET(__GXData->vcdLo, 0x15, 2, GX_DIRECT); + SET_REG_FIELD(0, __GXData->vcdLo, 2, 9, 1); __GXData->vcdHi = 0; - __GXData->hasNrms = FALSE; - __GXData->hasBiNrms = FALSE; - __GXData->dirtyState |= GX_DIRTY_VCD; + __GXData->hasNrms = 0; + __GXData->hasBiNrms = 0; + __GXData->dirtyState |= 8; } -/* ############################################################################################## */ - -static inline void SETVAT(u32* vatA, u32* vatB, u32* vatC, GXAttr attr, GXCompCnt compCnt, - GXCompType compType, u8 shift) { +static inline void SETVAT(u32* va, u32* vb, u32* vc, GXAttr attr, GXCompCnt cnt, GXCompType type, u8 shft) { switch (attr) { case GX_VA_POS: - GX_SET_REG(*vatA, compCnt, GX_CP_VAT_GRP0_POS_CNT_ST, GX_CP_VAT_GRP0_POS_CNT_END); - GX_SET_REG(*vatA, compType, GX_CP_VAT_GRP0_POS_TYPE_ST, GX_CP_VAT_GRP0_POS_TYPE_END); - GX_SET_REG(*vatA, shift, GX_CP_VAT_GRP0_POS_SHIFT_ST, GX_CP_VAT_GRP0_POS_SHIFT_END); + SET_REG_FIELD(583, *va, 1, 0, cnt); + SET_REG_FIELD(584, *va, 3, 1, type); + SET_REG_FIELD(585, *va, 5, 4, shft); break; case GX_VA_NRM: case GX_VA_NBT: - GX_SET_REG(*vatA, compType, GX_CP_VAT_GRP0_NRM_TYPE_ST, GX_CP_VAT_GRP0_NRM_TYPE_END); - if (compCnt == GX_NRM_NBT3) { - // Probably because the compCnt can only be one bit? - GX_SET_REG(*vatA, GX_NRM_NBT, GX_CP_VAT_GRP0_NRM_CNT_ST, GX_CP_VAT_GRP0_NRM_CNT_END); - GX_SET_REG(*vatA, TRUE, GX_CP_VAT_GRP0_NRMIDX3_ST, GX_CP_VAT_GRP0_NRMIDX3_END); + SET_REG_FIELD(593, *va, 3, 10, type); + if (cnt == GX_NRM_NBT3) { + SET_REG_FIELD(0, *va, 1, 9, 1); + SET_REG_FIELD(0, *va, 1, 31, 1); } else { - GX_SET_REG(*vatA, compCnt, GX_CP_VAT_GRP0_NRM_CNT_ST, GX_CP_VAT_GRP0_NRM_CNT_END); - GX_SET_REG(*vatA, FALSE, GX_CP_VAT_GRP0_NRMIDX3_ST, GX_CP_VAT_GRP0_NRMIDX3_END); + SET_REG_FIELD(599, *va, 1, 9, cnt); + SET_REG_FIELD(599, *va, 1, 31, 0); } break; case GX_VA_CLR0: - GX_SET_REG(*vatA, compCnt, GX_CP_VAT_GRP0_CLRDIFF_CNT_ST, GX_CP_VAT_GRP0_CLRDIFF_CNT_END); - GX_SET_REG(*vatA, compType, GX_CP_VAT_GRP0_CLRDIFF_TYPE_ST, - GX_CP_VAT_GRP0_CLRDIFF_TYPE_END); + SET_REG_FIELD(605, *va, 1, 13, cnt); + SET_REG_FIELD(606, *va, 3, 14, type); break; case GX_VA_CLR1: - GX_SET_REG(*vatA, compCnt, GX_CP_VAT_GRP0_CLRSPEC_CNT_ST, GX_CP_VAT_GRP0_CLRSPEC_CNT_END); - GX_SET_REG(*vatA, compType, GX_CP_VAT_GRP0_CLRSPEC_TYPE_ST, - GX_CP_VAT_GRP0_CLRSPEC_TYPE_END); + SET_REG_FIELD(609, *va, 1, 0x11, cnt); + SET_REG_FIELD(610, *va, 3, 18, type); break; case GX_VA_TEX0: - GX_SET_REG(*vatA, compCnt, GX_CP_VAT_GRP0_TXC0_CNT_ST, GX_CP_VAT_GRP0_TXC0_CNT_END); - GX_SET_REG(*vatA, compType, GX_CP_VAT_GRP0_TXC0_TYPE_ST, GX_CP_VAT_GRP0_TXC0_TYPE_END); - GX_SET_REG(*vatA, shift, GX_CP_VAT_GRP0_TXC0_SHIFT_ST, GX_CP_VAT_GRP0_TXC0_SHIFT_END); + SET_REG_FIELD(613, *va, 1, 0x15, cnt); + SET_REG_FIELD(614, *va, 3, 0x16, type); + SET_REG_FIELD(615, *va, 5, 0x19, shft); break; case GX_VA_TEX1: - GX_SET_REG(*vatB, compCnt, GX_CP_VAT_GRP1_TXC1_CNT_ST, GX_CP_VAT_GRP1_TXC1_CNT_END); - GX_SET_REG(*vatB, compType, GX_CP_VAT_GRP1_TXC1_TYPE_ST, GX_CP_VAT_GRP1_TXC1_TYPE_END); - GX_SET_REG(*vatB, shift, GX_CP_VAT_GRP1_TXC1_SHIFT_ST, GX_CP_VAT_GRP1_TXC1_SHIFT_END); + SET_REG_FIELD(618, *vb, 1, 0, cnt); + SET_REG_FIELD(619, *vb, 3, 1, type); + SET_REG_FIELD(620, *vb, 5, 4, shft); break; case GX_VA_TEX2: - GX_SET_REG(*vatB, compCnt, GX_CP_VAT_GRP1_TXC2_CNT_ST, GX_CP_VAT_GRP1_TXC2_CNT_END); - GX_SET_REG(*vatB, compType, GX_CP_VAT_GRP1_TXC2_TYPE_ST, GX_CP_VAT_GRP1_TXC2_TYPE_END); - GX_SET_REG(*vatB, shift, GX_CP_VAT_GRP1_TXC2_SHIFT_ST, GX_CP_VAT_GRP1_TXC2_SHIFT_END); + SET_REG_FIELD(623, *vb, 1, 9, cnt); + SET_REG_FIELD(624, *vb, 3, 10, type); + SET_REG_FIELD(625, *vb, 5, 13, shft); break; case GX_VA_TEX3: - GX_SET_REG(*vatB, compCnt, GX_CP_VAT_GRP1_TXC3_CNT_ST, GX_CP_VAT_GRP1_TXC3_CNT_END); - GX_SET_REG(*vatB, compType, GX_CP_VAT_GRP1_TXC3_TYPE_ST, GX_CP_VAT_GRP1_TXC3_TYPE_END); - GX_SET_REG(*vatB, shift, GX_CP_VAT_GRP1_TXC3_SHIFT_ST, GX_CP_VAT_GRP1_TXC3_SHIFT_END); + SET_REG_FIELD(628, *vb, 1, 18, cnt); + SET_REG_FIELD(629, *vb, 3, 19, type); + SET_REG_FIELD(630, *vb, 5, 22, shft); break; case GX_VA_TEX4: - GX_SET_REG(*vatB, compCnt, GX_CP_VAT_GRP1_TXC4_CNT_ST, GX_CP_VAT_GRP1_TXC4_CNT_END); - GX_SET_REG(*vatB, compType, GX_CP_VAT_GRP1_TXC4_TYPE_ST, GX_CP_VAT_GRP1_TXC4_TYPE_END); - GX_SET_REG(*vatC, shift, GX_CP_VAT_GRP2_TXC4_SHIFT_ST, GX_CP_VAT_GRP2_TXC4_SHIFT_END); + SET_REG_FIELD(633, *vb, 1, 27, cnt); + SET_REG_FIELD(634, *vb, 3, 28, type); + SET_REG_FIELD(635, *vc, 5, 0, shft); break; case GX_VA_TEX5: - GX_SET_REG(*vatC, compCnt, GX_CP_VAT_GRP2_TXC5_CNT_ST, GX_CP_VAT_GRP2_TXC5_CNT_END); - GX_SET_REG(*vatC, compType, GX_CP_VAT_GRP2_TXC5_TYPE_ST, GX_CP_VAT_GRP2_TXC5_TYPE_END); - GX_SET_REG(*vatC, shift, GX_CP_VAT_GRP2_TXC5_SHIFT_ST, GX_CP_VAT_GRP2_TXC5_SHIFT_END); + SET_REG_FIELD(638, *vc, 1, 5, cnt); + SET_REG_FIELD(639, *vc, 3, 6, type); + SET_REG_FIELD(640, *vc, 5, 9, shft); break; case GX_VA_TEX6: - GX_SET_REG(*vatC, compCnt, GX_CP_VAT_GRP2_TXC6_CNT_ST, GX_CP_VAT_GRP2_TXC6_CNT_END); - GX_SET_REG(*vatC, compType, GX_CP_VAT_GRP2_TXC6_TYPE_ST, GX_CP_VAT_GRP2_TXC6_TYPE_END); - GX_SET_REG(*vatC, shift, GX_CP_VAT_GRP2_TXC6_SHIFT_ST, GX_CP_VAT_GRP2_TXC6_SHIFT_END); + SET_REG_FIELD(643, *vc, 1, 14, cnt); + SET_REG_FIELD(644, *vc, 3, 15, type); + SET_REG_FIELD(645, *vc, 5, 18, shft); break; case GX_VA_TEX7: - GX_SET_REG(*vatC, compCnt, GX_CP_VAT_GRP2_TXC7_CNT_ST, GX_CP_VAT_GRP2_TXC7_CNT_END); - GX_SET_REG(*vatC, compType, GX_CP_VAT_GRP2_TXC7_TYPE_ST, GX_CP_VAT_GRP2_TXC7_TYPE_END); - GX_SET_REG(*vatC, shift, GX_CP_VAT_GRP2_TXC7_SHIFT_ST, GX_CP_VAT_GRP2_TXC7_SHIFT_END); + SET_REG_FIELD(648, *vc, 1, 23, cnt); + SET_REG_FIELD(649, *vc, 3, 24, type); + SET_REG_FIELD(650, *vc, 5, 27, shft); break; } } -/* 8035B5C4-8035B820 355F04 025C+00 1/0 69/69 6/6 .text GXSetVtxAttrFmt */ -void GXSetVtxAttrFmt(GXVtxFmt format, GXAttr attr, GXCompCnt count, GXCompType type, u8 frac) { - u32* vA = (u32*)&__GXData->vatA[format]; - u32* vB = (u32*)&__GXData->vatB[format]; - u32* vC = &__GXData->vatC[format]; +void GXSetVtxAttrFmt(GXVtxFmt vtxfmt, GXAttr attr, GXCompCnt cnt, GXCompType type, u8 frac) { + u32* va; + u32* vb; + u32* vc; - SETVAT(vA, vB, vC, attr, count, type, frac); + CHECK_GXBEGIN(666, "GXSetVtxAttrFmt"); + CHECK_VTXFMT(667, vtxfmt); + CHECK_ATTRNAME4(671, attr); + CHECK_FRAC(672, frac); - __GXData->dirtyState |= GX_DIRTY_VAT; - __GXData->dirtyVAT |= (u8)(1 << (u8)format); + va = &__GXData->vatA[vtxfmt]; + vb = &__GXData->vatB[vtxfmt]; + vc = &__GXData->vatC[vtxfmt]; + SETVAT(va, vb, vc, attr, cnt, type, frac); + +#ifdef DEBUG + __GXVerifyVATImm(attr, cnt, type, frac); +#endif + + __GXData->dirtyState |= 0x10; + __GXData->dirtyVAT |= (u8)(1 << (u8)vtxfmt); } -/* 8035B820-8035BAA0 356160 0280+00 1/0 1/1 1/1 .text GXSetVtxAttrFmtv */ -void GXSetVtxAttrFmtv(GXVtxFmt format, GXVtxAttrFmtList* list) { - u32* vatA; - u32* vatB; - u32* vatC; +void GXSetVtxAttrFmtv(GXVtxFmt vtxfmt, const GXVtxAttrFmtList* list) { + u32* va; + u32* vb; + u32* vc; - vatA = (u32*)&__GXData->vatA[format]; - vatB = (u32*)&__GXData->vatB[format]; - vatC = &__GXData->vatC[format]; + CHECK_GXBEGIN(713, "GXSetVtxAttrFmtv"); + CHECK_LISTPTR(714, list); + CHECK_VTXFMT(715, vtxfmt); - for (; list->mAttrib != GX_VA_NULL; list++) { - SETVAT(vatA, vatB, vatC, list->mAttrib, list->mCompCnt, list->mCompType, list->mCompShift); + va = &__GXData->vatA[vtxfmt]; + vb = &__GXData->vatB[vtxfmt]; + vc = &__GXData->vatC[vtxfmt]; + + while (list->attr != GX_VA_NULL) { + CHECK_ATTRNAME4(725, list->attr); + CHECK_FRAC(726, list->frac); + SETVAT(va, vb, vc, list->attr, list->cnt, list->type, list->frac); +#ifdef DEBUG + __GXVerifyVATImm(list->attr, list->cnt, list->type, list->frac); +#endif + list++; } - - __GXData->dirtyState |= GX_DIRTY_VAT; - __GXData->dirtyVAT |= (u8)(1 << (u8)format); + __GXData->dirtyState |= 0x10; + __GXData->dirtyVAT |= (u8)(1 << (u8)vtxfmt); } -/* 8035BAA0-8035BB28 3563E0 0088+00 0/0 2/2 0/0 .text __GXSetVAT */ void __GXSetVAT(void) { - u32 i = 0; - u32 dirtyVAT = __GXData->dirtyVAT; + s32 i; + u32 dirty = __GXData->dirtyVAT; + + i = 0; do { - if (dirtyVAT & (1)) { - GX_CP_LOAD_REG(GX_CP_REG_VAT_GRP0 | i, __GXData->vatA[i]); - GX_CP_LOAD_REG(GX_CP_REG_VAT_GRP1 | i, __GXData->vatB[i]); - GX_CP_LOAD_REG(GX_CP_REG_VAT_GRP2 | i, __GXData->vatC[i]); + if (dirty & 1) { + GX_WRITE_SOME_REG4(8, i | 0x70, __GXData->vatA[i], i - 12); + GX_WRITE_SOME_REG4(8, i | 0x80, __GXData->vatB[i], i - 12); + GX_WRITE_SOME_REG4(8, i | 0x90, __GXData->vatC[i], i - 12); } - dirtyVAT >>= 1; + + dirty >>= 1; i++; - } while (dirtyVAT != 0); + } while (dirty != 0); __GXData->dirtyVAT = 0; } -static u8 GetFracForNrm(int param_0) { - int var_r31; - - switch (param_0) { - case 1: - var_r31 = 6; - break; - case 3: - var_r31 = 14; - break; - default: - case 2: - var_r31 = 0; - break; - } - - return var_r31; -} - -void GXGetVtxAttrFmtv(GXVtxFmt param_0, GXVtxAttrFmtList* param_1) { - s32 tmp; - s32 tmp2; - s32 tmp3; - int i; - -#ifdef DEBUG - // not fully matching - /* tmp = 1; - if (data_8074d3c8 != 0) { - OSPanic("GXAttr.c", 941, "\'GXGetVtxAttrFmtv\' is not allowed between GXBegin/GXEnd"); - tmp = 0; - } - - tmp2 = 1; - if (param_1 == NULL) { - OSPanic("GXAttr.c", 942, "GXSetVtxAttrFmt: list pointer is NULL"); - tmp2 = 0; - } - - tmp3 = 1; - if (param_0 >= 8) { - OSPanic("GXAttr.c", 943, "GXSetVtxAttrFmt: Format Index is out of range"); - tmp3 = 0; - } */ -#endif - - for (i = 9; i <= 0x14; i++) { - param_1->mAttrib = i; - GXGetVtxAttrFmt(param_0, i, ¶m_1->mCompCnt, ¶m_1->mCompType, ¶m_1->mCompShift); - param_1++; - } - - param_1->mAttrib = 0xFF; -} - -void GXGetVtxAttrFmt(GXVtxFmt param_0, int param_1, GXCompCnt* param_2, GXCompType* param_3, - u8* param_4) { - s32 tmp; - s32 tmp2; - GXCompCnt* tmp_1; - GXCompCnt* tmp_2; - u32* tmp_3; - -#ifdef DEBUG - // not fully matching - /* tmp = 1; - if (data_8074d3c8) { - OSPanic("GXAttr.c", 844, "\'GXGetVtxAttrFmt\' is not allowed between GXBegin/GXEnd"); - tmp = 0; - } - - tmp2 = 1; - if (param_0 >= 8) { - OSPanic("GXAttr.c", 845, "GXSetVtxAttrFmt: Format Index is out of range"); - tmp2 = 0; - } */ -#endif - - tmp_1 = (GXCompCnt*)&__GXData->vatA[param_0]; - tmp_2 = (GXCompCnt*)&__GXData->vatB[param_0]; - tmp_3 = &__GXData->vatC[param_0]; - - switch (param_1) { - case 9: - *param_2 = *tmp_1 & 1; - *param_3 = (*tmp_1 & 0xE) >> 1; - *param_4 = (*tmp_1 & 0x1F0) >> 4; - break; - case 10: - case 0x19: - *param_2 = (*tmp_1 & 0x200) >> 9; - if (*param_2 == 1 && ((*tmp_1 & 0x80000000) >> 31) != 0) { - *param_2 = 2; - } - - *param_3 = (*tmp_1 & 0x1C00) >> 10; - *param_4 = GetFracForNrm(*param_3); - break; - case 11: - *param_2 = (*tmp_1 & 0x2000) >> 0xd; - *param_3 = (*tmp_1 & 0x1C000) >> 0xe; - *param_4 = 0; - break; - case 12: - *param_2 = (*tmp_1 & 0x20000) >> 0x11; - *param_3 = (*tmp_1 & 0x1C0000) >> 0x12; - *param_4 = 0; - break; - case 13: - *param_2 = (*tmp_1 & 0x200000) >> 0x15; - *param_3 = (*tmp_1 & 0x1C00000) >> 0x16; - *param_4 = ((*tmp_1 & 0x3e000000)) >> 25; - break; - case 14: - *param_2 = *tmp_2 & 1; - *param_3 = (*tmp_2 & 0xE) >> 1; - *param_4 = (*tmp_2 & 0x1F0) >> 4; - break; - case 15: - *param_2 = (*tmp_2 & 0x200) >> 9; - *param_3 = (*tmp_2 & 0x1C00) >> 10; - *param_4 = (*tmp_2 & 0x3E000) >> 13; - break; - case 16: - *param_2 = (*tmp_2 & 0x40000) >> 0x12; - *param_3 = (*tmp_2 & 0x380000) >> 0x13; - *param_4 = (*tmp_2 & 0x7C00000) >> 0x16; - break; - case 17: - *param_2 = (*tmp_2 & 0x8000000) >> 0x1B; - *param_3 = (*tmp_2 & 0x70000000) >> 0x1C; - *param_4 = (*tmp_3 & 0x1F); - break; - case 18: - *param_2 = (*tmp_3 & 0x20) >> 5; - *param_3 = (*tmp_3 & 0x1C0) >> 6; - *param_4 = (*tmp_3 & 0x3E00) >> 9; - break; - case 19: - *param_2 = (*tmp_3 & 0x4000) >> 0xe; - *param_3 = (*tmp_3 & 0x38000) >> 0xf; - *param_4 = (*tmp_3 & 0x7c0000) >> 0x12; - break; - case 20: - *param_2 = (*tmp_3 & 0x800000) >> 0x17; - *param_3 = (*tmp_3 & 0x7000000) >> 0x18; - *param_4 = (*tmp_3 & 0xF8000000) >> 0x1b; - break; - default: - *param_2 = 1; - *param_3 = 0; - *param_4 = 0; - } -} - -/* 8035BB28-8035BB6C 356468 0044+00 0/0 13/13 5/5 .text GXSetArray */ -void GXSetArray(GXAttr attr, void* basePtr, u8 stride) { - s32 newAttr; - s32 attrReg; - - newAttr = attr; - if (newAttr == GX_VA_NBT) { - newAttr = GX_VA_NRM; - } - - attrReg = newAttr - GX_VA_POS; - - GX_CP_LOAD_REG(GX_BP_REG_SETMODE0_TEX4 | attrReg, - // Address -> offset? - (u32)basePtr & ~0xC0000000); - - GX_CP_LOAD_REG(GX_BP_REG_SETIMAGE2_TEX4 | attrReg, stride); -} - -/* 8035BB6C-8035BB7C 3564AC 0010+00 0/0 6/6 0/0 .text GXInvalidateVtxCache */ -void GXInvalidateVtxCache(void) { - GXWGFifo.u8 = GX_FIFO_CMD_INVAL_VTX; -} - -/* 8035BB7C-8035BDFC 3564BC 0280+00 2/0 46/46 5/5 .text GXSetTexCoordGen2 */ -void GXSetTexCoordGen2(GXTexCoordID id, GXTexGenType type, GXTexGenSrc src, u32 texMtxIdx, - GXBool normalize, u32 dualTexMtxIdx) { - u32 reg; - u32 inputRow; - GXXfTexReg inputForm; - - reg = 0; - inputForm = GX_XF_TEX_FORM_AB11; - inputRow = 5; - - switch (src) { - case GX_TG_POS: - inputRow = 0; - inputForm = GX_XF_TEX_FORM_ABC1; - break; - case GX_TG_NRM: - inputRow = 1; - inputForm = GX_XF_TEX_FORM_ABC1; - break; - case GX_TG_BINRM: - inputRow = 3; - inputForm = GX_XF_TEX_FORM_ABC1; - break; - case GX_TG_TANGENT: - inputRow = 4; - inputForm = GX_XF_TEX_FORM_ABC1; - break; - case GX_TG_COLOR0: - inputRow = 2; - break; - case GX_TG_COLOR1: - inputRow = 2; - break; - case GX_TG_TEX0: - inputRow = 5; - break; - case GX_TG_TEX1: - inputRow = 6; - break; - case GX_TG_TEX2: - inputRow = 7; - break; - case GX_TG_TEX3: - inputRow = 8; - break; - case GX_TG_TEX4: - inputRow = 9; - break; - case GX_TG_TEX5: - inputRow = 10; - break; - case GX_TG_TEX6: - inputRow = 11; - break; - case GX_TG_TEX7: - inputRow = 12; - break; - } +static inline u8 GetFracForNrm(GXCompType type) { + u8 frac; switch (type) { - case GX_TG_NRM: - GX_SET_REG(reg, GX_XF_TEX_PROJ_ST, GX_XF_TEX_PROJTYPE_ST, - GX_XF_TEX_PROJTYPE_END); // 2x4 projection - GX_SET_REG(reg, inputForm, GX_XF_TEX_INPUTFORM_ST, GX_XF_TEX_INPUTFORM_END); - GX_SET_REG(reg, GX_TG_POS, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END); - GX_SET_REG(reg, inputRow, GX_XF_TEX_SRCROW_ST, GX_XF_TEX_SRCROW_END); + case GX_S8: + frac = 6; break; - case GX_TG_POS: - GX_SET_REG(reg, GX_XF_TEX_PROJ_STQ, GX_XF_TEX_PROJTYPE_ST, - GX_XF_TEX_PROJTYPE_END); // 3x4 projection - GX_SET_REG(reg, inputForm, GX_XF_TEX_INPUTFORM_ST, GX_XF_TEX_INPUTFORM_END); - GX_SET_REG(reg, GX_TG_POS, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END); - GX_SET_REG(reg, inputRow, GX_XF_TEX_SRCROW_ST, GX_XF_TEX_SRCROW_END); + case GX_S16: + frac = 14; + break; + default: + case GX_U16: + frac = 0; + break; + } + + return frac; +} + +void GXGetVtxAttrFmt(GXVtxFmt fmt, GXAttr attr, GXCompCnt* cnt, GXCompType* type, u8* frac) { + u32* va; + u32* vb; + u32* vc; + + CHECK_GXBEGIN(833, "GXGetVtxAttrFmt"); + CHECK_VTXFMT(834, fmt); + + va = &__GXData->vatA[fmt]; + vb = &__GXData->vatB[fmt]; + vc = &__GXData->vatC[fmt]; + + switch (attr) { + case GX_VA_POS: + *cnt = GET_REG_FIELD(*va, 1, 0); + *type = GET_REG_FIELD(*va, 3, 1); + *frac = (u8)(*va >> 4) & 0x1F; // GET_REG_FIELD(*va, 5, 4) + return; + case GX_VA_NRM: + case GX_VA_NBT: + *cnt = GET_REG_FIELD(*va, 1, 9); + if (*cnt == GX_TEX_ST && (u8)(*va >> 0x1F) != 0) { + *cnt = GX_NRM_NBT3; + } + *type = GET_REG_FIELD(*va, 3, 10); + *frac = GetFracForNrm(*type); + return; + case GX_VA_CLR0: + *cnt = GET_REG_FIELD(*va, 1, 13); + *type = GET_REG_FIELD(*va, 3, 14); + *frac = 0; + return; + case GX_VA_CLR1: + *cnt = GET_REG_FIELD(*va, 1, 17); + *type = GET_REG_FIELD(*va, 3, 18); + *frac = 0; + return; + case GX_VA_TEX0: + *cnt = GET_REG_FIELD(*va, 1, 21); + *type = GET_REG_FIELD(*va, 3, 22); + *frac = (u8)(*va >> 0x19) & 0x1F; + return; + case GX_VA_TEX1: + *cnt = GET_REG_FIELD(*vb, 1, 0); + *type = GET_REG_FIELD(*vb, 3, 1); + *frac = (u8)(*vb >> 4) & 0x1F; + return; + case GX_VA_TEX2: + *cnt = GET_REG_FIELD(*vb, 1, 9); + *type = GET_REG_FIELD(*vb, 3, 10); + *frac = (u8)(*vb >> 0xD) & 0x1F; + return; + case GX_VA_TEX3: + *cnt = GET_REG_FIELD(*vb, 1, 18); + *type = GET_REG_FIELD(*vb, 3, 19); + *frac = (u8)(*vb >> 0x16) & 0x1F; + return; + case GX_VA_TEX4: + *cnt = GET_REG_FIELD(*vb, 1, 27); + *type = GET_REG_FIELD(*vb, 3, 28); + *frac = GET_REG_FIELD(*vc, 5, 0); + return; + case GX_VA_TEX5: + *cnt = GET_REG_FIELD(*vc, 1, 5); + *type = GET_REG_FIELD(*vc, 3, 6); + *frac = (u8)(*vc >> 9) & 0x1F; + return; + case GX_VA_TEX6: + *cnt = GET_REG_FIELD(*vc, 1, 14); + *type = GET_REG_FIELD(*vc, 3, 15); + *frac = (u8)(*vc >> 0x12) & 0x1F; + return; + case GX_VA_TEX7: + *cnt = GET_REG_FIELD(*vc, 1, 23); + *type = GET_REG_FIELD(*vc, 3, 24); + *frac = (int)(*vc >> 0x1B); + return; + default: + *cnt = GX_TEX_ST; + *type = GX_RGB565; + *frac = 0; + return; + } +} + +void GXGetVtxAttrFmtv(GXVtxFmt fmt, GXVtxAttrFmtList* vat) { + GXAttr attr; + + CHECK_GXBEGIN(930, "GXGetVtxAttrFmtv"); + CHECK_LISTPTR(931, vat); + CHECK_VTXFMT(932, fmt); + + for (attr = GX_VA_POS; attr <= GX_VA_TEX7; attr++) { + vat->attr = attr; + GXGetVtxAttrFmt(fmt, attr, &vat->cnt, &vat->type, &vat->frac); + vat++; + } + + vat->attr = GX_VA_NULL; +} + +void GXSetArray(GXAttr attr, void* base_ptr, u8 stride) { + GXAttr cpAttr; + u32 phyAddr; + + attr; // needed to match + + CHECK_GXBEGIN(963, "GXSetArray"); + if (attr == GX_VA_NBT) { + attr = GX_VA_NRM; + } + + CHECK_ATTRNAME5(966, attr); + cpAttr = attr - GX_VA_POS; + phyAddr = (u32)base_ptr & 0x3FFFFFFF; + + GX_WRITE_SOME_REG2(8, cpAttr | 0xA0, phyAddr, cpAttr - 12); + GX_WRITE_SOME_REG3(8, cpAttr | 0xB0, stride, cpAttr - 12); +} + +void GXInvalidateVtxCache(void) { + CHECK_GXBEGIN(988, "GXInvalidateVtxCache"); + GX_WRITE_U8(0x48); +} + +void GXSetTexCoordGen2(GXTexCoordID dst_coord, GXTexGenType func, GXTexGenSrc src_param, u32 mtx, GXBool normalize, u32 pt_texmtx) { + u32 reg = 0; + u32 row; + u32 bumprow; // unused + u32 form; + GXAttr mtxIdAttr; + + CHECK_GXBEGIN(1030, "GXSetTexCoordGen"); + ASSERTMSGLINE(1031, dst_coord < GX_MAX_TEXCOORD, "GXSetTexCoordGen: Invalid coordinate Id"); + + form = 0; + row = 5; + switch (src_param) { + case GX_TG_POS: row = 0; form = 1; break; + case GX_TG_NRM: row = 1; form = 1; break; + case GX_TG_BINRM: row = 3; form = 1; break; + case GX_TG_TANGENT: row = 4; form = 1; break; + case GX_TG_COLOR0: row = 2; break; + case GX_TG_COLOR1: row = 2; break; + case GX_TG_TEX0: row = 5; break; + case GX_TG_TEX1: row = 6; break; + case GX_TG_TEX2: row = 7; break; + case GX_TG_TEX3: row = 8; break; + case GX_TG_TEX4: row = 9; break; + case GX_TG_TEX5: row = 10; break; + case GX_TG_TEX6: row = 11; break; + case GX_TG_TEX7: row = 12; break; + case GX_TG_TEXCOORD0: bumprow; break; + case GX_TG_TEXCOORD1: bumprow; break; + case GX_TG_TEXCOORD2: bumprow; break; + case GX_TG_TEXCOORD3: bumprow; break; + case GX_TG_TEXCOORD4: bumprow; break; + case GX_TG_TEXCOORD5: bumprow; break; + case GX_TG_TEXCOORD6: bumprow; break; + default: + ASSERTMSGLINE(1059, 0, "GXSetTexCoordGen: Invalid source parameter"); + break; + } + + switch (func) { + case GX_TG_MTX2x4: + SET_REG_FIELD(1069, reg, 1, 1, 0); + SET_REG_FIELD(1069, reg, 1, 2, form); + SET_REG_FIELD(1071, reg, 3, 4, 0); + SET_REG_FIELD(1071, reg, 5, 7, row); + break; + case GX_TG_MTX3x4: + SET_REG_FIELD(1076, reg, 1, 1, 1); + SET_REG_FIELD(1076, reg, 1, 2, form); + SET_REG_FIELD(1076, reg, 3, 4, 0); + SET_REG_FIELD(1078, reg, 5, 7, row); break; case GX_TG_BUMP0: case GX_TG_BUMP1: @@ -693,70 +589,53 @@ void GXSetTexCoordGen2(GXTexCoordID id, GXTexGenType type, GXTexGenSrc src, u32 case GX_TG_BUMP5: case GX_TG_BUMP6: case GX_TG_BUMP7: - GX_SET_REG(reg, GX_XF_TEX_PROJ_ST, GX_XF_TEX_PROJTYPE_ST, - GX_XF_TEX_PROJTYPE_END); // 2x4 projection - GX_SET_REG(reg, inputForm, GX_XF_TEX_INPUTFORM_ST, GX_XF_TEX_INPUTFORM_END); - GX_SET_REG(reg, GX_TG_NRM, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END); - GX_SET_REG(reg, inputRow, GX_XF_TEX_SRCROW_ST, GX_XF_TEX_SRCROW_END); - GX_SET_REG(reg, src - GX_TG_TEXCOORD0, GX_XF_TEX_BUMPSRCTEX_ST, GX_XF_TEX_BUMPSRCTEX_END); - GX_SET_REG(reg, type - GX_TG_BUMP0, GX_XF_TEX_BUMPSRCLIGHT_ST, GX_XF_TEX_BUMPSRCLIGHT_END); + ASSERTMSGLINE(1091, src_param >= 12 && src_param <= 18, "GXSetTexCoordGen: Bump source texture value is invalid"); + SET_REG_FIELD(1093, reg, 1, 1, 0); + SET_REG_FIELD(1093, reg, 1, 2, form); + SET_REG_FIELD(1095, reg, 3, 4, 1); + SET_REG_FIELD(1095, reg, 5, 7, row); + SET_REG_FIELD(1096, reg, 3, 12, src_param - 12); + SET_REG_FIELD(1097, reg, 3, 15, func - 2); break; case GX_TG_SRTG: - GX_SET_REG(reg, GX_XF_TEX_PROJ_ST, GX_XF_TEX_PROJTYPE_ST, - GX_XF_TEX_PROJTYPE_END); // 2x4 projection - GX_SET_REG(reg, inputForm, GX_XF_TEX_INPUTFORM_ST, GX_XF_TEX_INPUTFORM_END); - - if (src == GX_TG_COLOR0) { - GX_SET_REG(reg, GX_XF_TG_CLR0, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END); + SET_REG_FIELD(1102, reg, 1, 1, 0); + SET_REG_FIELD(1102, reg, 1, 2, form); + if (src_param == GX_TG_COLOR0) { + SET_REG_FIELD(0, reg, 3, 4, 2); } else { - GX_SET_REG(reg, GX_XF_TG_CLR1, GX_XF_TEX_TEXGENTYPE_ST, GX_XF_TEX_TEXGENTYPE_END); + SET_REG_FIELD(0, reg, 3, 4, 3); } - GX_SET_REG(reg, 2, GX_XF_TEX_SRCROW_ST, GX_XF_TEX_SRCROW_END); + SET_REG_FIELD(0, reg, 5, 7, 2); break; default: + ASSERTMSGLINE(1113, 0, "GXSetTexCoordGen: Invalid function"); break; } - GX_XF_LOAD_REG(GX_XF_REG_TEX0 + id, reg); - + GX_WRITE_XF_REG(dst_coord + 0x40, reg); reg = 0; - GX_SET_REG(reg, dualTexMtxIdx - 0x40, GX_XF_MTXIDX0_GEOM_ST, GX_XF_MTXIDX0_GEOM_END); - GX_SET_REG(reg, normalize, GX_XF_DUALTEX_NORMALISE_ST, GX_XF_DUALTEX_NORMALISE_END); + SET_REG_FIELD(1132, reg, 6, 0, pt_texmtx - 64); + SET_REG_FIELD(1133, reg, 1, 8, normalize); + GX_WRITE_XF_REG(dst_coord + 0x50, reg); - GX_XF_LOAD_REG(GX_XF_REG_DUALTEX0 + id, reg); - - switch (id) { - case GX_TEXCOORD0: - GX_SET_REG(__GXData->matIdxA, texMtxIdx, GX_XF_MTXIDX0_TEX0_ST, GX_XF_MTXIDX0_TEX0_END); - break; - case GX_TEXCOORD1: - GX_SET_REG(__GXData->matIdxA, texMtxIdx, GX_XF_MTXIDX0_TEX1_ST, GX_XF_MTXIDX0_TEX1_END); - break; - case GX_TEXCOORD2: - GX_SET_REG(__GXData->matIdxA, texMtxIdx, GX_XF_MTXIDX0_TEX2_ST, GX_XF_MTXIDX0_TEX2_END); - break; - case GX_TEXCOORD3: - GX_SET_REG(__GXData->matIdxA, texMtxIdx, GX_XF_MTXIDX0_TEX3_ST, GX_XF_MTXIDX0_TEX3_END); - break; - case GX_TEXCOORD4: - GX_SET_REG(__GXData->matIdxB, texMtxIdx, GX_XF_MTXIDX1_TEX4_ST, GX_XF_MTXIDX1_TEX4_END); - break; - case GX_TEXCOORD5: - GX_SET_REG(__GXData->matIdxB, texMtxIdx, GX_XF_MTXIDX1_TEX5_ST, GX_XF_MTXIDX1_TEX5_END); - break; - case GX_TEXCOORD6: - GX_SET_REG(__GXData->matIdxB, texMtxIdx, GX_XF_MTXIDX1_TEX6_ST, GX_XF_MTXIDX1_TEX6_END); - break; - default: - GX_SET_REG(__GXData->matIdxB, texMtxIdx, GX_XF_MTXIDX1_TEX7_ST, GX_XF_MTXIDX1_TEX7_END); - break; + switch (dst_coord) { + case GX_TEXCOORD0: SET_REG_FIELD(1147, __GXData->matIdxA, 6, 6, mtx); break; + case GX_TEXCOORD1: SET_REG_FIELD(1148, __GXData->matIdxA, 6, 12, mtx); break; + case GX_TEXCOORD2: SET_REG_FIELD(1149, __GXData->matIdxA, 6, 18, mtx); break; + case GX_TEXCOORD3: SET_REG_FIELD(1150, __GXData->matIdxA, 6, 24, mtx); break; + case GX_TEXCOORD4: SET_REG_FIELD(1151, __GXData->matIdxB, 6, 0, mtx); break; + case GX_TEXCOORD5: SET_REG_FIELD(1152, __GXData->matIdxB, 6, 6, mtx); break; + case GX_TEXCOORD6: SET_REG_FIELD(1153, __GXData->matIdxB, 6, 12, mtx); break; + default: SET_REG_FIELD(1154, __GXData->matIdxB, 6, 18, mtx); break; } - __GXSetMatrixIndex(id + 1); + + mtxIdAttr = dst_coord + 1; + __GXSetMatrixIndex(mtxIdAttr); } -/* 8035BDFC-8035BE38 35673C 003C+00 0/0 59/59 6/6 .text GXSetNumTexGens */ -void GXSetNumTexGens(u8 count) { - GX_SET_REG(__GXData->genMode, count, GX_BP_GENMODE_NUMTEX_ST, GX_BP_GENMODE_NUMTEX_END); - GX_XF_LOAD_REG(GX_XF_REG_NUMTEX, count); - __GXData->dirtyState |= GX_DIRTY_GEN_MODE; -} \ No newline at end of file +void GXSetNumTexGens(u8 nTexGens) { + CHECK_GXBEGIN(1172, "GXSetNumTexGens"); + SET_REG_FIELD(1174, __GXData->genMode, 4, 0, nTexGens); + GX_WRITE_XF_REG(0x3F, nTexGens); + __GXData->dirtyState |= 4; +} diff --git a/src/dolphin/gx/GXBump.c b/src/dolphin/gx/GXBump.c index a1154976db..a8534b4092 100644 --- a/src/dolphin/gx/GXBump.c +++ b/src/dolphin/gx/GXBump.c @@ -1,203 +1,308 @@ -/** - * GXBump.c - * Description: - */ +#include +#include -#include "dolphin/gx/GXBump.h" -#include "dolphin/gx.h" +#include "__gx.h" -/* 8035ECC0-8035ED2C 359600 006C+00 1/1 3/3 0/0 .text GXSetTevIndirect */ -void GXSetTevIndirect(GXTevStageID tevStage, GXIndTexStageID texStage, GXIndTexFormat texFmt, - GXIndTexBiasSel biasSel, GXIndTexMtxID mtxID, GXIndTexWrap wrapS, - GXIndTexWrap wrapT, u8 addPrev, u8 utcLod, GXIndTexAlphaSel alphaSel) { - u32 field = 0; - u32 stage = tevStage + 0x10; +#if DEBUG +#define GX_WRITE_SOME_REG5(a, b) \ +do { \ + GX_WRITE_U8(a); \ + GX_WRITE_U32(b); \ + __gxVerif->rasRegs[(b >> 24) & 0xFF] = b; \ +} while (0) +#else +#define GX_WRITE_SOME_REG5(a, b) \ +do { \ + GX_WRITE_U8(a); \ + GX_WRITE_U32(b); \ +} while (0) +#endif - GX_BITFIELD_SET(field, 30, 2, texStage); - GX_BITFIELD_SET(field, 28, 2, texFmt); - GX_BITFIELD_SET(field, 25, 3, biasSel); - GX_BITFIELD_SET(field, 23, 2, alphaSel); - GX_BITFIELD_SET(field, 19, 4, mtxID); - GX_BITFIELD_SET(field, 16, 3, wrapS); - GX_BITFIELD_SET(field, 13, 3, wrapT); - GX_BITFIELD_SET(field, 12, 1, utcLod); - GX_BITFIELD_SET(field, 11, 1, addPrev); - GX_BITFIELD_SET(field, 0, 8, stage); - - GXWGFifo.u8 = 0x61; - GXWGFifo.s32 = field; +void GXSetTevIndirect(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexFormat format, GXIndTexBiasSel bias_sel, GXIndTexMtxID matrix_sel, GXIndTexWrap wrap_s, GXIndTexWrap wrap_t, GXBool add_prev, GXBool utc_lod, GXIndTexAlphaSel alpha_sel) { + u32 reg; + CHECK_GXBEGIN(146, "GXInitIndTexture"); + reg = 0; + SET_REG_FIELD(148, reg, 2, 0, ind_stage); + SET_REG_FIELD(149, reg, 2, 2, format); + SET_REG_FIELD(150, reg, 3, 4, bias_sel); + SET_REG_FIELD(151, reg, 2, 7, alpha_sel); + SET_REG_FIELD(152, reg, 4, 9, matrix_sel); + SET_REG_FIELD(153, reg, 3, 13, wrap_s); + SET_REG_FIELD(154, reg, 3, 16, wrap_t); + SET_REG_FIELD(155, reg, 1, 19, utc_lod); + SET_REG_FIELD(156, reg, 1, 20, add_prev); + SET_REG_FIELD(157, reg, 8, 24, tev_stage + 16); + GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, reg); __GXData->bpSentNot = 0; } -/* 8035ED2C-8035EEA4 35966C 0178+00 0/0 4/4 1/1 .text GXSetIndTexMtx */ -void GXSetIndTexMtx(GXIndTexMtxID mtxID, f32 offset[6], s8 scale_exp) { - u32 val; - u32 field; - f32 mtx2[6]; +void GXSetIndTexMtx(GXIndTexMtxID mtx_id, const f32 offset[2][3], s8 scale_exp) { + s32 mtx[6]; + u32 reg; + u32 id; - scale_exp += 17; + CHECK_GXBEGIN(186, "GXSetIndTexMtx"); - switch (mtxID) { + switch (mtx_id) { case GX_ITM_0: case GX_ITM_1: case GX_ITM_2: - val = mtxID - 1; + id = mtx_id - 1; break; case GX_ITM_S0: case GX_ITM_S1: case GX_ITM_S2: - val = mtxID - 5; + id = mtx_id - 5; break; case GX_ITM_T0: case GX_ITM_T1: case GX_ITM_T2: - val = mtxID - 9; + id = mtx_id - 9; break; - case GX_ITM_3: - case GX_ITM_S3: default: - val = 0; + id = 0; + break; } - field = 0; - GX_BITFIELD_SET(field, 21, 11, 1024.0f * offset[0]); - GX_BITFIELD_SET(field, 10, 11, 1024.0f * offset[3]); - GX_BITFIELD_SET(field, 8, 2, (scale_exp >> 0) & 3); - GX_BITFIELD_SET(field, 0, 8, val * 3 + 6); - GXWGFifo.u8 = 0x61; - GXWGFifo.s32 = field; + mtx[0] = (int)(1024.0f * offset[0][0]) & 0x7FF; + mtx[1] = (int)(1024.0f * offset[1][0]) & 0x7FF; + scale_exp += 17; + reg = 0; + SET_REG_FIELD(208, reg, 11, 0, mtx[0]); + SET_REG_FIELD(209, reg, 11, 11, mtx[1]); + SET_REG_FIELD(210, reg, 2, 22, scale_exp & 3); + SET_REG_FIELD(211, reg, 8, 24, id * 3 + 6); + GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, reg); - field = 0; - GX_BITFIELD_SET(field, 21, 11, 1024.0f * offset[1]); - GX_BITFIELD_SET(field, 10, 11, 1024.0f * offset[4]); - GX_BITFIELD_SET(field, 8, 2, (scale_exp >> 2) & 3); - GX_BITFIELD_SET(field, 0, 8, val * 3 + 7); - GXWGFifo.u8 = 0x61; - GXWGFifo.s32 = field; + mtx[2] = (int)(1024.0f * offset[0][1]) & 0x7FF; + mtx[3] = (int)(1024.0f * offset[1][1]) & 0x7FF; + reg = 0; + SET_REG_FIELD(217, reg, 11, 0, mtx[2]); + SET_REG_FIELD(218, reg, 11, 11, mtx[3]); + SET_REG_FIELD(219, reg, 2, 22, (scale_exp >> 2) & 3); + SET_REG_FIELD(220, reg, 8, 24, id * 3 + 7); + GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, reg); - field = 0; - GX_BITFIELD_SET(field, 21, 11, 1024.0f * offset[2]); - GX_BITFIELD_SET(field, 10, 11, 1024.0f * offset[5]); - GX_BITFIELD_SET(field, 8, 2, (scale_exp >> 4) & 3); - GX_BITFIELD_SET(field, 0, 8, val * 3 + 8); - GXWGFifo.u8 = 0x61; - GXWGFifo.s32 = field; + mtx[4] = (int)(1024.0f * offset[0][2]) & 0x7FF; + mtx[5] = (int)(1024.0f * offset[1][2]) & 0x7FF; + reg = 0; + SET_REG_FIELD(226, reg, 11, 0, mtx[4]); + SET_REG_FIELD(227, reg, 11, 11, mtx[5]); + SET_REG_FIELD(228, reg, 2, 22, (scale_exp >> 4) & 3); + SET_REG_FIELD(229, reg, 8, 24, id * 3 + 8); + GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, reg); __GXData->bpSentNot = 0; } -/* 8035EEA4-8035EFE8 3597E4 0144+00 0/0 5/5 0/0 .text GXSetIndTexCoordScale */ -void GXSetIndTexCoordScale(GXIndTexStageID texStage, GXIndTexScale scaleS, GXIndTexScale scaleT) { - GXData* data; +void GXSetIndTexCoordScale(GXIndTexStageID ind_state, GXIndTexScale scale_s, GXIndTexScale scale_t) { + CHECK_GXBEGIN(249, "GXSetIndTexScale"); - switch (texStage) { + switch (ind_state) { case GX_INDTEXSTAGE0: - data = __GXData; - GX_BITFIELD_SET(data->IndTexScale0, 28, 4, scaleS); - GX_BITFIELD_SET(data->IndTexScale0, 24, 4, scaleT); - GX_BITFIELD_SET(data->IndTexScale0, 0, 8, 0x25); - GXWGFifo.u8 = 0x61; - GXWGFifo.s32 = data->IndTexScale0; + SET_REG_FIELD(253, __GXData->IndTexScale0, 4, 0, scale_s); + SET_REG_FIELD(254, __GXData->IndTexScale0, 4, 4, scale_t); + SET_REG_FIELD(254, __GXData->IndTexScale0, 8, 24, 0x25); + GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->IndTexScale0); break; case GX_INDTEXSTAGE1: - data = __GXData; - GX_BITFIELD_SET(data->IndTexScale0, 20, 4, scaleS); - GX_BITFIELD_SET(data->IndTexScale0, 16, 4, scaleT); - GX_BITFIELD_SET(data->IndTexScale0, 0, 8, 0x25); - GXWGFifo.u8 = 0x61; - GXWGFifo.s32 = data->IndTexScale0; + SET_REG_FIELD(259, __GXData->IndTexScale0, 4, 8, scale_s); + SET_REG_FIELD(260, __GXData->IndTexScale0, 4, 12, scale_t); + SET_REG_FIELD(260, __GXData->IndTexScale0, 8, 24, 0x25); + GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->IndTexScale0); break; case GX_INDTEXSTAGE2: - data = __GXData; - GX_BITFIELD_SET(data->IndTexScale1, 28, 4, scaleS); - GX_BITFIELD_SET(data->IndTexScale1, 24, 4, scaleT); - GX_BITFIELD_SET(data->IndTexScale1, 0, 8, 0x26); - GXWGFifo.u8 = 0x61; - GXWGFifo.s32 = data->IndTexScale1; + SET_REG_FIELD(265, __GXData->IndTexScale1, 4, 0, scale_s); + SET_REG_FIELD(266, __GXData->IndTexScale1, 4, 4, scale_t); + SET_REG_FIELD(266, __GXData->IndTexScale1, 8, 24, 0x26); + GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->IndTexScale1); break; case GX_INDTEXSTAGE3: - data = __GXData; - GX_BITFIELD_SET(data->IndTexScale1, 20, 4, scaleS); - GX_BITFIELD_SET(data->IndTexScale1, 16, 4, scaleT); - GX_BITFIELD_SET(data->IndTexScale1, 0, 8, 0x26); - GXWGFifo.u8 = 0x61; - GXWGFifo.s32 = data->IndTexScale1; + SET_REG_FIELD(0x10F, __GXData->IndTexScale1, 4, 8, scale_s); + SET_REG_FIELD(0x110, __GXData->IndTexScale1, 4, 12, scale_t); + SET_REG_FIELD(0x110, __GXData->IndTexScale1, 8, 24, 0x26); + GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->IndTexScale1); + break; + default: + ASSERTMSGLINE(277, 0, "GXSetIndTexCoordScale: Invalid Indirect Stage Id"); break; } - __GXData->bpSentNot = 0; } -/* 8035EFE8-8035F0D4 359928 00EC+00 0/0 3/3 0/0 .text GXSetIndTexOrder */ -void GXSetIndTexOrder(GXIndTexStageID stage, GXTexCoordID coord, GXTexMapID map) { - GXData* data; +void GXSetIndTexOrder(GXIndTexStageID ind_stage, GXTexCoordID tex_coord, GXTexMapID tex_map) { + CHECK_GXBEGIN(302, "GXSetIndTexOrder"); - if (map == 0xFF) { - map = GX_TEXMAP0; + if (tex_map == GX_TEXMAP_NULL) { + tex_map = GX_TEXMAP0; } - if (coord == 0xFF) { - coord = GX_TEXCOORD0; + if (tex_coord == GX_TEXCOORD_NULL) { + tex_coord = GX_TEXCOORD0; } - switch (stage) { + ASSERTMSGLINE(314, tex_map < GX_MAX_TEXMAP, "GXSetIndTexOrder: Invalid direct texture Id"); + ASSERTMSGLINE(315, tex_coord < GX_MAX_TEXCOORD, "GXSetIndTexOrder: Invalid texture coord"); + + switch (ind_stage) { case GX_INDTEXSTAGE0: - data = __GXData; - GX_BITFIELD_SET(data->iref, 29, 3, map); - GX_BITFIELD_SET(data->iref, 26, 3, coord); + SET_REG_FIELD(319, __GXData->iref, 3, 0, tex_map); + SET_REG_FIELD(320, __GXData->iref, 3, 3, tex_coord); break; case GX_INDTEXSTAGE1: - data = __GXData; - GX_BITFIELD_SET(data->iref, 23, 3, map); - GX_BITFIELD_SET(data->iref, 20, 3, coord); + SET_REG_FIELD(323, __GXData->iref, 3, 6, tex_map); + SET_REG_FIELD(324, __GXData->iref, 3, 9, tex_coord); break; case GX_INDTEXSTAGE2: - data = __GXData; - GX_BITFIELD_SET(data->iref, 17, 3, map); - GX_BITFIELD_SET(data->iref, 14, 3, coord); + SET_REG_FIELD(327, __GXData->iref, 3, 12, tex_map); + SET_REG_FIELD(328, __GXData->iref, 3, 15, tex_coord); break; case GX_INDTEXSTAGE3: - data = __GXData; - GX_BITFIELD_SET(data->iref, 11, 3, map); - GX_BITFIELD_SET(data->iref, 8, 3, coord); + SET_REG_FIELD(331, __GXData->iref, 3, 18, tex_map); + SET_REG_FIELD(332, __GXData->iref, 3, 21, tex_coord); + break; + default: + ASSERTMSGLINE(335, 0, "GXSetIndTexOrder: Invalid Indirect Stage Id"); + break; + } + GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->iref); + __GXData->dirtyState |= 3; + __GXData->bpSentNot = 0; +} + +void GXSetNumIndStages(u8 nIndStages) { + CHECK_GXBEGIN(353, "GXSetNumIndStages"); + ASSERTMSGLINE(355, nIndStages <= 4, "GXSetNumIndStages: Exceeds max. number of indirect texture stages"); + SET_REG_FIELD(356, __GXData->genMode, 3, 16, nIndStages); + __GXData->dirtyState |= 6; +} + +void GXSetTevDirect(GXTevStageID tev_stage) { + CHECK_GXBEGIN(373, "GXSetTevDirect"); + GXSetTevIndirect(tev_stage, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_OFF, GX_ITW_OFF, GX_FALSE, GX_FALSE, GX_ITBA_OFF); +} + +void GXSetTevIndWarp(GXTevStageID tev_stage, GXIndTexStageID ind_stage, u8 signed_offset, u8 replace_mode, GXIndTexMtxID matrix_sel) { + GXIndTexWrap wrap = (replace_mode != 0) ? GX_ITW_0 : GX_ITW_OFF; + + CHECK_GXBEGIN(395, "GXSetTevIndWarp"); + GXSetTevIndirect(tev_stage, ind_stage, GX_ITF_8, (signed_offset != 0) ? GX_ITB_STU : GX_ITB_NONE, matrix_sel, wrap, wrap, GX_FALSE, GX_FALSE, GX_ITBA_OFF); +} + +void GXSetTevIndTile(GXTevStageID tev_stage, GXIndTexStageID ind_stage, u16 tilesize_s, + u16 tilesize_t, u16 tilespacing_s, u16 tilespacing_t, GXIndTexFormat format, + GXIndTexMtxID matrix_sel, GXIndTexBiasSel bias_sel, GXIndTexAlphaSel alpha_sel) +{ + GXIndTexWrap wrap_s; + GXIndTexWrap wrap_t; + f32 mtx[2][3]; + + CHECK_GXBEGIN(429, "GXSetTevIndTile"); + ASSERTMSGLINE(430, tev_stage < GX_MAX_TEVSTAGE, "GXSetTevIndTile: Invalid tev stage id"); + ASSERTMSGLINE(431, ind_stage < GX_MAX_INDTEXSTAGE, "GXSetTevIndTile: Invalid indirect stage id"); + + switch (tilesize_s) { + case 256: + wrap_s = GX_ITW_256; + break; + case 128: + wrap_s = GX_ITW_128; + break; + case 64: + wrap_s = GX_ITW_64; + break; + case 32: + wrap_s = GX_ITW_32; + break; + case 16: + wrap_s = GX_ITW_16; + break; + default: + ASSERTMSGLINE(440, 0, "GXSetTevIndTile: Invalid tilesize for S coordinate"); + wrap_s = GX_ITW_OFF; break; } - GXWGFifo.u8 = 0x61; - GXWGFifo.s32 = __GXData->iref; - GXSetWasteFlags(); + switch (tilesize_t) { + case 256: + wrap_t = GX_ITW_256; + break; + case 128: + wrap_t = GX_ITW_128; + break; + case 64: + wrap_t = GX_ITW_64; + break; + case 32: + wrap_t = GX_ITW_32; + break; + case 16: + wrap_t = GX_ITW_16; + break; + default: + ASSERTMSGLINE(452, 0, "GXSetTevIndTile: Invalid tilesize for T coordinate"); + wrap_t = GX_ITW_OFF; + break; + } + + mtx[0][0] = tilespacing_s / 1024.0f; + mtx[0][1] = mtx[0][2] = 0.0f; + mtx[1][1] = tilespacing_t / 1024.0f; + mtx[1][0] = mtx[1][2] = 0.0f; + GXSetIndTexMtx(matrix_sel, mtx, 10); + GXSetTevIndirect(tev_stage, ind_stage, format, bias_sel, matrix_sel, wrap_s, wrap_t, GX_FALSE, GX_TRUE, alpha_sel); } -/* 8035F0D4-8035F0F8 359A14 0024+00 0/0 43/43 7/7 .text GXSetNumIndStages */ -void GXSetNumIndStages(u8 num) { - GXData* data = __GXData; - GX_BITFIELD_SET(data->genMode, 13, 3, num); - data->dirtyState |= GX_DIRTY_BP_MASK | GX_DIRTY_GEN_MODE; +void GXSetTevIndBumpST(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel) { + GXIndTexMtxID sm; + GXIndTexMtxID tm; + + CHECK_GXBEGIN(492, "GXSetTevIndBumpST"); + + switch (matrix_sel) { + case GX_ITM_0: + sm = GX_ITM_S0; + tm = GX_ITM_T0; + break; + case GX_ITM_1: + sm = GX_ITM_S1; + tm = GX_ITM_T1; + break; + case GX_ITM_2: + sm = GX_ITM_S2; + tm = GX_ITM_T2; + break; + default: + ASSERTMSGLINE(509, 0, "GXSetTevIndBumpST: Invalid matrix selection"); + break; + } + + GXSetTevIndirect(tev_stage, ind_stage, GX_ITF_8, GX_ITB_ST, sm, GX_ITW_0, GX_ITW_0, GX_FALSE, GX_FALSE, GX_ITBA_OFF); + GXSetTevIndirect(tev_stage + 1, ind_stage, GX_ITF_8, GX_ITB_ST, tm, GX_ITW_0, GX_ITW_0, GX_TRUE, GX_FALSE, GX_ITBA_OFF); + GXSetTevIndirect(tev_stage + 2, ind_stage, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_OFF, GX_ITW_OFF, GX_TRUE, GX_FALSE, GX_ITBA_OFF); } -/* 8035F0F8-8035F140 359A38 0048+00 0/0 16/16 0/0 .text GXSetTevDirect */ -void GXSetTevDirect(GXTevStageID stage) { - GXSetTevIndirect(stage, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_OFF, - GX_ITW_OFF, FALSE, FALSE, GX_ITBA_OFF); +void GXSetTevIndBumpXYZ(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexMtxID matrix_sel) { + CHECK_GXBEGIN(561, "GXSetTevIndBumpXYZ"); + GXSetTevIndirect(tev_stage, ind_stage, GX_ITF_8, GX_ITB_STU, matrix_sel, GX_ITW_OFF, GX_ITW_OFF, GX_FALSE, GX_FALSE, GX_ITBA_OFF); +} + +void GXSetTevIndRepeat(GXTevStageID tev_stage) { + CHECK_GXBEGIN(590, "GXSetTevIndRepeat"); + GXSetTevIndirect(tev_stage, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_0, GX_ITW_0, GX_TRUE, GX_FALSE, GX_ITBA_OFF); } -/* 8035F140-8035F144 359A80 0004+00 0/0 2/2 0/0 .text __GXUpdateBPMask */ void __GXUpdateBPMask(void) {} -/* 8035F144-8035F174 359A84 0030+00 0/0 1/1 0/0 .text __GXSetIndirectMask */ void __GXSetIndirectMask(u32 mask) { - GXData* data = __GXData; + SET_REG_FIELD(664, __GXData->bpMask, 8, ~0xFF, mask); - GX_BITFIELD_SET(data->bpMask, 24, 8, mask); - GXWGFifo.u8 = 0x61; - GXWGFifo.s32 = data->bpMask; - data->bpSentNot = 0; + GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->bpMask); + __GXData->bpSentNot = 0; } -/* 8035F174-8035F198 359AB4 0024+00 0/0 4/4 0/0 .text __GXFlushTextureState */ void __GXFlushTextureState(void) { - GXWGFifo.u8 = 0x61; - GXWGFifo.s32 = __GXData->bpMask; + GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->bpMask); __GXData->bpSentNot = 0; -} \ No newline at end of file +} diff --git a/src/dolphin/gx/GXDisplayList.c b/src/dolphin/gx/GXDisplayList.c index 8eccdeb79c..ff53e8a8f2 100644 --- a/src/dolphin/gx/GXDisplayList.c +++ b/src/dolphin/gx/GXDisplayList.c @@ -1,22 +1,99 @@ -/** - * GXDisplayList.c - * Description: - */ +#include -#include "dolphin/gx/GXDisplayList.h" -#include "dolphin/gx.h" +#include +#include + +#include "__gx.h" + +static __GXFifoObj DisplayListFifo; +static volatile __GXFifoObj* OldCPUFifo; +static GXData __savedGXdata; + +void GXBeginDisplayList(void* list, u32 size) { + __GXFifoObj* CPUFifo = (__GXFifoObj*)GXGetCPUFifo(); + + CHECK_GXBEGIN(137, "GXBeginDisplayList"); + ASSERTMSGLINE(138, !__GXData->inDispList, "GXBeginDisplayList: display list already in progress"); + ASSERTMSGLINE(139, (size & 0x1F) == 0, "GXBeginDisplayList: size is not 32 byte aligned"); + ASSERTMSGLINE(140, ((u32)list & 0x1F) == 0, "GXBeginDisplayList: list is not 32 byte aligned"); -/* 8035FEF0-8035FF60 35A830 0070+00 0/0 20/20 4/4 .text GXCallDisplayList */ -void GXCallDisplayList(void* list, u32 nbytes) { if (__GXData->dirtyState != 0) { __GXSetDirtyState(); } - if (*(u32*)__GXData == 0) { + if (__GXData->dlSaveContext != 0) { + memcpy(&__savedGXdata, __GXData, sizeof(__savedGXdata)); + } + + DisplayListFifo.base = (u8*)list; + DisplayListFifo.top = (u8*)list + size - 4; + DisplayListFifo.size = size; + DisplayListFifo.count = 0; + DisplayListFifo.rdPtr = list; + DisplayListFifo.wrPtr = list; + __GXData->inDispList = 1; + GXSaveCPUFifo((GXFifoObj*)CPUFifo); + OldCPUFifo = CPUFifo; + GXSetCPUFifo((GXFifoObj*)&DisplayListFifo); + GXResetWriteGatherPipe(); +} + +u32 GXEndDisplayList(void) { + u32 ov; +#ifdef DEBUG + u32 reg; +#endif + BOOL enabled; + u32 cpenable; + + CHECK_GXBEGIN(195, "GXEndDisplayList"); + ASSERTMSGLINE(196, __GXData->inDispList == TRUE, "GXEndDisplayList: no display list in progress"); + GXFlush(); +#ifdef DEBUG + reg = GX_GET_PI_REG(5); + ov = (reg >> 26) & 1; +#else + ov = (GX_GET_PI_REG(5) >> 26) & 1; +#endif + __GXSaveCPUFifoAux(&DisplayListFifo); + ASSERTMSGLINE(213, !ov, "GXEndDisplayList: display list commands overflowed buffer"); + GXSetCPUFifo((GXFifoObj*)OldCPUFifo); + + if (__GXData->dlSaveContext != 0) { + enabled = OSDisableInterrupts(); + cpenable = __GXData->cpEnable; + memcpy(__GXData, &__savedGXdata, sizeof(*__GXData)); + __GXData->cpEnable = cpenable; + OSRestoreInterrupts(enabled); + } + + __GXData->inDispList = 0; + if (!ov) { + return DisplayListFifo.count; + } + + return 0; +} + +void GXCallDisplayList(void* list, u32 nbytes) { + CHECK_GXBEGIN(254, "GXCallDisplayList"); + ASSERTMSGLINE(255, !__GXData->inDispList, "GXCallDisplayList: display list already in progress"); + ASSERTMSGLINE(256, (nbytes & 0x1F) == 0, "GXCallDisplayList: nbytes is not 32 byte aligned"); + ASSERTMSGLINE(257, ((u32)list & 0x1F) == 0, "GXCallDisplayList: list is not 32 byte aligned"); + + if (__GXData->dirtyState != 0) { + __GXSetDirtyState(); + } + +#if DEBUG + __GXShadowDispList(list, nbytes); +#endif + + if (*(u32*)&__GXData->vNumNot == 0) { // checks both vNum and bpSent __GXSendFlushPrim(); } - GXWGFifo.u8 = 0x40; - GXWGFifo.u32 = (u32)list; - GXWGFifo.u32 = nbytes; -} \ No newline at end of file + GX_WRITE_U8(GX_CMD_CALL_DL); + GX_WRITE_U32(list); + GX_WRITE_U32(nbytes); +} diff --git a/src/dolphin/gx/GXDraw.c b/src/dolphin/gx/GXDraw.c index 42c4aa58cc..0ea0d0beb5 100644 --- a/src/dolphin/gx/GXDraw.c +++ b/src/dolphin/gx/GXDraw.c @@ -1,10 +1,14 @@ -#include "dolphin/gx/GXDraw.h" -#include "dolphin/gx.h" +#include + +#include +#include + +#include "__gx.h" static GXVtxDescList vcd[27]; static GXVtxAttrFmtList vat[27]; -void GetVertState(void) { +static void GetVertState(void) { GXGetVtxDescv(vcd); GXGetVtxAttrFmtv(GX_VTXFMT3, vat); GXClearVtxDesc(); @@ -14,58 +18,534 @@ void GetVertState(void) { GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0); } -void RestoreVertState(void) { +static void RestoreVertState(void) { GXSetVtxDescv(vcd); GXSetVtxAttrFmtv(GX_VTXFMT3, vat); } -// doesn't fully match debug +static void vsub(f32 p1[3], f32 p2[3], f32 u[3]) { + u32 i; + + for (i = 0; i < 3; i++) { + u[i] = p2[i] - p1[i]; + } +} + +static void vcross(f32 u[3], f32 v[3], f32 n[3]) { + f32 n1[3]; + + n1[0] = (u[1] * v[2]) - (u[2] * v[1]); + n1[1] = (u[2] * v[0]) - (u[0] * v[2]); + n1[2] = (u[0] * v[1]) - (u[1] * v[0]); + n[0] = n1[0]; + n[1] = n1[1]; + n[2] = n1[2]; +} + +static void normalize(f32 v[3]) { + f32 d = sqrtf((v[0] * v[0]) + (v[1] * v[1]) + (v[2] * v[2])); + + ASSERTMSGLINE(137, d != 0.0f, "normalize: zero length vector"); + v[0] /= d; + v[1] /= d; + v[2] /= d; +} + +static void myvertex(f32 v[3], f32 n[3]) { + GXPosition3f32(v[0], v[1], v[2]); + GXNormal3f32(n[0], n[1], n[2]); +} + +static void DumpTriangle(f32 v0[3], f32 v1[3], f32 v2[3]) { + GXBegin(GX_TRIANGLES, GX_VTXFMT3, 3); + myvertex(v0, v0); + myvertex(v1, v1); + myvertex(v2, v2); + GXEnd(); +} + +static void Subdivide(u8 depth, f32 v0[3], f32 v1[3], f32 v2[3]) { + f32 v01[3]; + f32 v12[3]; + f32 v20[3]; + u32 i; + + if (depth == 0) { + DumpTriangle(v0, v1, v2); + return; + } + + for (i = 0; i < 3; i++) { + v01[i] = v0[i] + v1[i]; + v12[i] = v1[i] + v2[i]; + v20[i] = v2[i] + v0[i]; + } + + normalize(v01); + normalize(v12); + normalize(v20); + Subdivide(depth - 1, v0, v01, v20); + Subdivide(depth - 1, v1, v12, v01); + Subdivide(depth - 1, v2, v20, v12); + Subdivide(depth - 1, v01, v12, v20); +} + +static void SubDivTriangle(u8 depth, u8 i, f32 (*data)[3], u8 (*ndx)[3]) { + f32 *x0 = data[ndx[i][0]]; + f32 *x1 = data[ndx[i][1]]; + f32 *x2 = data[ndx[i][2]]; + + Subdivide(depth, x0, x1, x2); +} + void GXDrawCylinder(u8 numEdges) { - f32 temp_f29; - f32 temp_f30; - f32 temp_f31; - s32 i; + f32 top; + f32 bottom; + f32 x[100]; + f32 y[100]; + f32 angle; - f32 sp1A0[100]; - f32 sp10[100]; - - temp_f31 = 1.0f; - temp_f30 = -temp_f31; + top = 1.0f; + bottom = -top; + ASSERTMSGLINE(216, numEdges <= 99, "GXDrawCylinder: too many edges"); GetVertState(); + for (i = 0; i <= numEdges; i++) { - temp_f29 = (i * 2.0f * 3.141593f) / numEdges; - sp1A0[i] = cosf(temp_f29); - sp10[i] = sinf(temp_f29); + angle = (3.1415927f * (2.0f * i)) / numEdges; + x[i] = cosf(angle); + y[i] = sinf(angle); } GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT3, (numEdges + 1) * 2); for (i = 0; i <= numEdges; i++) { - GXPosition3f32(sp1A0[i], sp10[i], temp_f30); - GXNormal3f32(sp1A0[i], sp10[i], 0.0f); - GXPosition3f32(sp1A0[i], sp10[i], temp_f31); - GXNormal3f32(sp1A0[i], sp10[i], 0.0f); + GXPosition3f32(x[i], y[i], bottom); + GXNormal3f32(x[i], y[i], 0.0f); + GXPosition3f32(x[i], y[i], top); + GXNormal3f32(x[i], y[i], 0.0f); + } GXEnd(); GXBegin(GX_TRIANGLEFAN, GX_VTXFMT3, numEdges + 2); - GXPosition3f32(0.0f, 0.0f, temp_f31); + GXPosition3f32(0.0f, 0.0f, top); GXNormal3f32(0.0f, 0.0f, 1.0f); for (i = 0; i <= numEdges; i++) { - GXPosition3f32(sp1A0[i], -sp10[i], temp_f31); + GXPosition3f32(x[i], -y[i], top); GXNormal3f32(0.0f, 0.0f, 1.0f); + } GXEnd(); GXBegin(GX_TRIANGLEFAN, GX_VTXFMT3, numEdges + 2); - GXPosition3f32(0.0f, 0.0f, temp_f30); + GXPosition3f32(0.0f, 0.0f, bottom); GXNormal3f32(0.0f, 0.0f, -1.0f); for (i = 0; i <= numEdges; i++) { - GXPosition3f32(sp1A0[i], sp10[i], temp_f30); + GXPosition3f32(x[i], y[i], bottom); GXNormal3f32(0.0f, 0.0f, -1.0f); } GXEnd(); RestoreVertState(); -} \ No newline at end of file +} + +void GXDrawTorus(f32 rc, u8 numc, u8 numt) { + GXAttrType ttype; + s32 i, j, k; + f32 s, t; + f32 x, y, z; + f32 twopi = 6.2831855f; + f32 rt; + + ASSERTMSGLINE(316, rc < 1.0f, "GXDrawTorus: doughnut too fat"); + + rt = 1.0f - rc; + GXGetVtxDesc(GX_VA_TEX0, &ttype); + GetVertState(); + + if (ttype != GX_NONE) { + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); + } + + for (i = 0; i < numc; i++) { + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT3, (numt + 1) * 2); + for (j = 0; j <= numt; j++) { + for (k = 1; k >= 0; k--) { + s = (i + k) % numc; + t = j % numt; + x = (rt - rc * cosf(s * twopi / numc)) * cosf(t * twopi / numt); + y = (rt - rc * cosf(s * twopi / numc)) * sinf(t * twopi / numt); + z = rc * sinf(s * twopi / numc); + GXPosition3f32(x, y, z); + x = -cosf(t * twopi / numt) * cosf(s * twopi / numc); + y = -sinf(t * twopi / numt) * cosf(s * twopi / numc); + z = sinf(s * twopi / numc); + GXNormal3f32(x, y, z); + if (ttype != GX_NONE) { + GXTexCoord2f32((i + k) / (f32)numc, j / (f32)numt); + } + } + } + GXEnd(); + } + RestoreVertState(); +} + +void GXDrawSphere(u8 numMajor, u8 numMinor) { + GXAttrType ttype; + f32 radius = 1.0f; + f32 majorStep = 3.1415927f / numMajor; + f32 minorStep = 6.2831855f / numMinor; + s32 i, j; + f32 a, b; + f32 r0, r1; + f32 z0, z1; + f32 c; + f32 x, y; + + GXGetVtxDesc(GX_VA_TEX0, &ttype); + GetVertState(); + + if (ttype != GX_NONE) { + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_TEX0, GX_TEX_ST, GX_RGBA6, 0); + } + + for (i = 0; i < numMajor; i++) { + a = i * majorStep; + b = a + majorStep; + r0 = radius * sinf(a); + r1 = radius * sinf(b); + z0 = radius * cosf(a); + z1 = radius * cosf(b); + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT3, (numMinor + 1) * 2); + for (j = 0; j <= numMinor; j++) { + c = j * minorStep; + x = cosf(c); + y = sinf(c); + GXPosition3f32(x * r1, y * r1, z1); + GXNormal3f32((x * r1) / radius, (y * r1) / radius, z1 / radius); + if (ttype != GX_NONE) { + GXTexCoord2f32((f32)j / (f32)numMinor, (f32)(i + 1) / (f32)numMajor); + } + GXPosition3f32(x * r0, y * r0, z0); + GXNormal3f32((x * r0) / radius, (y * r0) / radius, z0 / radius); + if (ttype != GX_NONE) { + GXTexCoord2f32((f32)j / (f32)numMinor, (f32)i / (f32)numMajor); + } + } + GXEnd(); + } + RestoreVertState(); +} + +static void GXDrawCubeFace(f32 nx, f32 ny, f32 nz, f32 tx, f32 ty, f32 tz, f32 bx, f32 by, f32 bz, GXAttrType binormal, GXAttrType texture) { + GXPosition3f32(0.57735026f * (nx + tx + bx), 0.57735026f * (ny + ty + by), 0.57735026f * (nz + tz + bz)); + GXNormal3f32(nx, ny, nz); + + if (binormal != GX_NONE) { + GXNormal3f32(tx, ty, tz); + GXNormal3f32(bx, by, bz); + } + + if (texture != GX_NONE) { + GXTexCoord2s8(1, 1); + } + + GXPosition3f32(0.57735026f * (nx - tx + bx), 0.57735026f * (ny - ty + by), 0.57735026f * (nz - tz + bz)); + GXNormal3f32(nx, ny, nz); + + if (binormal != GX_NONE) { + GXNormal3f32(tx, ty, tz); + GXNormal3f32(bx, by, bz); + } + + if (texture != GX_NONE) { + GXTexCoord2s8(0, 1); + } + + GXPosition3f32(0.57735026f * (nx - tx - bx), 0.57735026f * (ny - ty - by), 0.57735026f * (nz - tz - bz)); + GXNormal3f32(nx, ny, nz); + + if (binormal != GX_NONE) { + GXNormal3f32(tx, ty, tz); + GXNormal3f32(bx, by, bz); + } + + if (texture != GX_NONE) { + GXTexCoord2s8(0, 0); + } + + GXPosition3f32(0.57735026f * (nx + tx - bx), 0.57735026f * (ny + ty - by), 0.57735026f * (nz + tz - bz)); + GXNormal3f32(nx, ny, nz); + + if (binormal != GX_NONE) { + GXNormal3f32(tx, ty, tz); + GXNormal3f32(bx, by, bz); + } + + if (texture != GX_NONE) { + GXTexCoord2s8(1, 0); + } +} + +void GXDrawCube(void) { + GXAttrType ntype; + GXAttrType ttype; + + GXGetVtxDesc(GX_VA_NBT, &ntype); + GXGetVtxDesc(GX_VA_TEX0, &ttype); + GetVertState(); + if (ntype != GX_NONE) { + GXSetVtxDesc(GX_VA_NBT, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_NBT, GX_TEX_ST, GX_RGBA6, 0); + } + if (ttype != GX_NONE) { + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_TEX0, GX_TEX_ST, GX_RGB8, 0); + } + + GXBegin(GX_QUADS, GX_VTXFMT3, 24); + GXDrawCubeFace(-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, ntype, ttype); + GXDrawCubeFace(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, ntype, ttype); + GXDrawCubeFace(0.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, ntype, ttype); + GXDrawCubeFace(0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, ntype, ttype); + GXDrawCubeFace(0.0f, 0.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, ntype, ttype); + GXDrawCubeFace(0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, ntype, ttype); + GXEnd(); + + RestoreVertState(); +} + +static u32 polygons[12][5] = { + { 0, 12, 10, 11, 16 }, + { 1, 17, 8, 9, 13 }, + { 2, 14, 9, 8, 18 }, + { 3, 19, 11, 10, 15 }, + { 4, 14, 2, 3, 15 }, + { 5, 12, 0, 1, 13 }, + { 6, 17, 1, 0, 16 }, + { 7, 19, 3, 2, 18 }, + { 8, 17, 6, 7, 18 }, + { 9, 14, 4, 5, 13 }, + { 10, 12, 5, 4, 15 }, + { 11, 19, 7, 6, 16 }, +}; + +static f32 verts[20][3] = { + { -0.809015f, 0.0f, 0.309015f }, + { -0.809015f, 0.0f, -0.309015f }, + { 0.809015f, 0.0f, -0.309015f }, + { 0.809015f, 0.0f, 0.309015f }, + { 0.309015f, -0.809015f, 0.0f }, + { -0.309015f, -0.809015f, 0.0f }, + { -0.309015f, 0.809015f, 0 }, + { 0.309015f, 0.809015f, 0 }, + { 0.0f, 0.309015f, -0.809015f }, + { 0.0f, -0.309015f, -0.809015f }, + { 0.0f, -0.309015f, 0.809015f }, + { 0.0f, 0.309015f, 0.809015f }, + { -0.5f, -0.5f, 0.5 }, + { -0.5f, -0.5f, -0.5 }, + { 0.5f, -0.5f, -0.5 }, + { 0.5f, -0.5f, 0.5 }, + { -0.5f, 0.5f, 0.5 }, + { -0.5f, 0.5f, -0.5 }, + { 0.5f, 0.5f, -0.5 }, + { 0.5f, 0.5f, 0.5 }, +}; + +void GXDrawDodeca(void) { + u32 i; + f32 *p0; + f32 *p1; + f32 *p2; + f32 u[3]; + f32 v[3]; + f32 n[3]; + + GetVertState(); + for (i = 0; i < 12; i++) { + p0 = verts[polygons[i][0]]; + p1 = verts[polygons[i][1]]; + p2 = verts[polygons[i][2]]; + vsub(p1, p2, u); + vsub(p1, p0, v); + vcross(u, v, n); + normalize(n); + GXBegin(GX_TRIANGLEFAN, GX_VTXFMT3, 5); + myvertex(verts[polygons[i][4]], n); + myvertex(verts[polygons[i][3]], n); + myvertex(p2, n); + myvertex(p1, n); + myvertex(p0, n); + GXEnd(); + } + RestoreVertState(); +} + +static f32 odata[6][3] = { + { 1.0f, 0.0f, 0.0f }, + { -1.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f }, + { 0.0f, -1.0f, 0.0f }, + { 0.0f, 0.0f, 1.0f }, + { 0.0f, 0.0f, -1.0f }, +}; + +static u8 ondex[8][3] = { + { 0, 4, 2 }, + { 1, 2, 4 }, + { 0, 3, 4 }, + { 1, 4, 3 }, + { 0, 2, 5 }, + { 1, 5, 2 }, + { 0, 5, 3 }, + { 1, 3, 5 }, +}; + +void GXDrawOctahedron(void) { + s32 i; + + GetVertState(); + for (i = 7; i >= 0; i--) { + SubDivTriangle(0, i, odata, ondex); + } + RestoreVertState(); +} + +static f32 idata[12][3] = { + { -0.5257311f, 0.0f, 0.8506508f }, + { 0.5257311f, 0.0f, 0.8506508f }, + { -0.5257311f, 0.0f, -0.8506508f }, + { 0.5257311f, 0.0f, -0.8506508f }, + { 0.0f, 0.8506508f, 0.5257311f }, + { 0.0f, 0.8506508f, -0.5257311f }, + { 0.0f, -0.8506508f, 0.5257311f }, + { 0.0f, -0.8506508f, -0.5257311f }, + { 0.8506508f, 0.5257311f, 0.0f }, + { -0.8506508f, 0.5257311f, 0.0f }, + { 0.8506508f, -0.5257311f, 0.0f }, + { -0.8506508f, -0.5257311f, 0.0f }, +}; + +static u8 index[20][3] = { + { 0, 4, 1 }, + { 0, 9, 4 }, + { 9, 5, 4 }, + { 4, 5, 8 }, + { 4, 8, 1 }, + { 8, 10, 1 }, + { 8, 3, 10 }, + { 5, 3, 8 }, + { 5, 2, 3 }, + { 2, 7, 3 }, + { 7, 10, 3 }, + { 7, 6, 10 }, + { 7, 11, 6 }, + { 11, 0, 6 }, + { 0, 1, 6 }, + { 6, 1, 10 }, + { 9, 0, 11 }, + { 9, 11, 2 }, + { 9, 2, 5 }, + { 7, 2, 11 }, +}; + +void GXDrawIcosahedron(void) { + s32 i; + + GetVertState(); + for (i = 19; i >= 0; i--) { + SubDivTriangle(0, i, idata, index); + } + RestoreVertState(); +} + +void GXDrawSphere1(u8 depth) { + s32 i; + + GetVertState(); + for (i = 19; i >= 0; i--) { + SubDivTriangle(depth, i, idata, index); + } + RestoreVertState(); +} + +static u32 CmpNormal32(f32 n1[3], f32 n2[3]) { + u32 i; + + for (i = 0; i < 3; i++) { + if (n1[i] != n2[i]) + return FALSE; + } + return TRUE; +} + +static u32 nrm_cnt; +static f32* nrm_tab; + +static void AddNormal(f32 n[3]) { + u32 indx; + u32 i; + + for (i = 0; i < nrm_cnt; i++) { + if (CmpNormal32(n, &nrm_tab[i * 3])) + return; + } + indx = nrm_cnt * 3; + nrm_tab[indx + 0] = n[0]; + nrm_tab[indx + 1] = n[1]; + nrm_tab[indx + 2] = n[2]; + nrm_cnt++; +} + +static void SubdivideNrm(u8 depth, f32 v0[3], f32 v1[3], f32 v2[3]) { + f32 v01[3]; + f32 v12[3]; + f32 v20[3]; + u32 i; + + if (depth == 0) { + AddNormal(v0); + AddNormal(v1); + AddNormal(v2); + return; + } + + for (i = 0; i < 3; i++) { + v01[i] = v0[i] + v1[i]; + v12[i] = v1[i] + v2[i]; + v20[i] = v2[i] + v0[i]; + } + + normalize(v01); + normalize(v12); + normalize(v20); + SubdivideNrm(depth - 1, v0, v01, v20); + SubdivideNrm(depth - 1, v1, v12, v01); + SubdivideNrm(depth - 1, v2, v20, v12); + SubdivideNrm(depth - 1, v01, v12, v20); +} + +static void SubDivNrm(u8 depth, u8 i, f32 (*data)[3], u8 (*ndx)[3]) { + f32* x0 = data[ndx[i][0]]; + f32* x1 = data[ndx[i][1]]; + f32* x2 = data[ndx[i][2]]; + + SubdivideNrm(depth, x0, x1, x2); +} + +u32 GXGenNormalTable(u8 depth, f32* table) { + s32 i; + + nrm_cnt = 0; + nrm_tab = table; + for (i = 7; i >= 0; i--) { + SubDivNrm(depth, i, odata, ondex); + } + + return nrm_cnt; +} diff --git a/src/dolphin/gx/GXFifo.c b/src/dolphin/gx/GXFifo.c index 2faae888f9..1085da461b 100644 --- a/src/dolphin/gx/GXFifo.c +++ b/src/dolphin/gx/GXFifo.c @@ -1,367 +1,630 @@ -#include "dolphin/gx/GXFifo.h" -#include "dolphin/gx.h" -#include "dolphin/os.h" +#include +#include +#include +#include -static void GXInitFifoLimits(GXFifoObj* fifo, u32 hi_watermark, u32 lo_watermark); +#include "__gx.h" -/* 80451948-8045194C 000E48 0004+00 4/3 0/0 0/0 .sbss CPUFifo */ -static GXFifoObj* CPUFifo; +static __GXFifoObj* CPUFifo; +static __GXFifoObj* GPFifo; -/* 8045194C-80451950 000E4C 0004+00 4/3 0/0 0/0 .sbss GPFifo */ -static GXFifoObj* GPFifo; - -/* 80451950-80451954 000E50 0004+00 4/3 0/0 0/0 .sbss __GXCurrentThread */ static OSThread* __GXCurrentThread; - -/* 80451954-80451958 000E54 0004+00 3/3 0/0 0/0 .sbss None */ -static GXBool data_80451954; - -/* 80451958-8045195C 000E58 0004+00 2/2 0/0 0/0 .sbss GXOverflowSuspendInProgress */ -static u32 GXOverflowSuspendInProgress; - -/* 8045195C-80451960 000E5C 0004+00 2/2 0/0 0/0 .sbss BreakPointCB */ +static GXBool CPGPLinked; +static BOOL GXOverflowSuspendInProgress; static GXBreakPtCallback BreakPointCB; - -/* 80451960-80451968 000E60 0004+04 1/1 0/0 0/0 .sbss __GXOverflowCount */ static u32 __GXOverflowCount; -static void GXOverflowHandler() { - __GXOverflowCount += 1; +#if DEBUG +static BOOL IsWGPipeRedirected; +#endif + +void* __GXCurrentBP; + +static void __GXFifoReadEnable(void); +static void __GXFifoReadDisable(void); +static void __GXFifoLink(u8 en); +static void __GXWriteFifoIntEnable(u8 hiWatermarkEn, u8 loWatermarkEn); +static void __GXWriteFifoIntReset(u8 hiWatermarkClr, u8 loWatermarkClr); + +#if DEBUG +static char __data_0[] = "[GXOverflowHandler]"; +#endif + +static void GXOverflowHandler(__OSInterrupt interrupt, OSContext* context) { +#if DEBUG + if (__gxVerif->verifyLevel > GX_WARN_SEVERE) { + OSReport(__data_0); + } +#endif + ASSERTLINE(LINE(377, 377, 381), !GXOverflowSuspendInProgress); + + __GXOverflowCount++; __GXWriteFifoIntEnable(0, 1); __GXWriteFifoIntReset(1, 0); GXOverflowSuspendInProgress = TRUE; + +#if DEBUG + if (__gxVerif->verifyLevel > GX_WARN_SEVERE) { + OSReport("[GXOverflowHandler Sleeping]"); + } +#endif OSSuspendThread(__GXCurrentThread); } -static void GXUnderflowHandler() { +static void GXUnderflowHandler(s16 interrupt, OSContext* context) { +#if DEBUG + if (__gxVerif->verifyLevel > GX_WARN_SEVERE) { + OSReport("[GXUnderflowHandler]"); + } +#endif + ASSERTLINE(LINE(419, 419, 423), GXOverflowSuspendInProgress); + OSResumeThread(__GXCurrentThread); GXOverflowSuspendInProgress = FALSE; __GXWriteFifoIntReset(1, 1); __GXWriteFifoIntEnable(1, 0); } -static void GXBreakPointHandler(OSContext* context) { - OSContext bpContext; +#define SOME_SET_REG_MACRO(reg, size, shift, val) \ + do { \ + (reg) = (u32)__rlwimi((u32)(reg), (val), (shift), (32 - (shift) - (size)), (31 - (shift))); \ + } while (0); - FAST_FLAG_SET(__GXData->cpEnable, 0, 5, 1); +static void GXBreakPointHandler(__OSInterrupt interrupt, OSContext* context) { + OSContext exceptionContext; + + SOME_SET_REG_MACRO(__GXData->cpEnable, 1, 5, 0); GX_SET_CP_REG(1, __GXData->cpEnable); - - if (BreakPointCB) { - OSClearContext(&bpContext); - OSSetCurrentContext(&bpContext); + if (BreakPointCB != NULL) { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); BreakPointCB(); - OSClearContext(&bpContext); + OSClearContext(&exceptionContext); OSSetCurrentContext(context); } } -/* 8035A5A8-8035A6DC 354EE8 0134+00 1/1 0/0 0/0 .text GXCPInterruptHandler */ -static void GXCPInterruptHandler(s16 p1, OSContext* context) { +static void GXCPInterruptHandler(__OSInterrupt interrupt, OSContext* context) { __GXData->cpStatus = GX_GET_CP_REG(0); - - if ((__GXData->cpEnable >> 3 & 1) && (__GXData->cpStatus >> 1 & 1)) { - GXUnderflowHandler(); + if (GET_REG_FIELD(__GXData->cpEnable, 1, 3) && GET_REG_FIELD(__GXData->cpStatus, 1, 1)) { + GXUnderflowHandler(interrupt, context); } - - if ((__GXData->cpEnable >> 2 & 1) && (__GXData->cpStatus >> 0 & 1)) { - GXOverflowHandler(); + if (GET_REG_FIELD(__GXData->cpEnable, 1, 2) && GET_REG_FIELD(__GXData->cpStatus, 1, 0)) { + GXOverflowHandler(interrupt, context); } - - if ((__GXData->cpEnable >> 5 & 1) && (__GXData->cpStatus >> 4 & 1)) { - GXBreakPointHandler(context); + if (GET_REG_FIELD(__GXData->cpEnable, 1, 5) && GET_REG_FIELD(__GXData->cpStatus, 1, 4)) { + GXBreakPointHandler(interrupt, context); } } -/* 8035A6DC-8035A748 35501C 006C+00 0/0 2/2 0/0 .text GXInitFifoBase */ void GXInitFifoBase(GXFifoObj* fifo, void* base, u32 size) { - fifo->base = base; - fifo->end = (void*)((u32)base + size - 4); - fifo->size = size; - fifo->rw_dst = 0; - GXInitFifoLimits(fifo, size - 0x4000, OSRoundDown32B(size / 2)); + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + + ASSERTMSGLINE(LINE(542, 542, 546), realFifo != CPUFifo, "GXInitFifoBase: fifo is attached to CPU"); + ASSERTMSGLINE(LINE(544, 544, 548), realFifo != GPFifo, "GXInitFifoBase: fifo is attached to GP"); + ASSERTMSGLINE(LINE(546, 546, 550), ((u32)base & 0x1F) == 0, "GXInitFifoBase: base must be 32B aligned"); + ASSERTMSGLINE(LINE(548, 548, 552), base != NULL, "GXInitFifoBase: base pointer is NULL"); + ASSERTMSGLINE(LINE(550, 550, 554), (size & 0x1F) == 0, "GXInitFifoBase: size must be 32B aligned"); + ASSERTMSGLINE(LINE(552, 552, 556), size >= 0x10000, "GXInitFifoBase: fifo is not large enough"); + + realFifo->base = base; + realFifo->top = (u8*)base + size - 4; + realFifo->size = size; + realFifo->count = 0; + GXInitFifoLimits(fifo, size - 0x4000, (size >> 1) & ~0x1F); GXInitFifoPtrs(fifo, base, base); } -/* 8035A748-8035A7B8 355088 0070+00 1/1 1/1 0/0 .text GXInitFifoPtrs */ void GXInitFifoPtrs(GXFifoObj* fifo, void* readPtr, void* writePtr) { - int interrupts = OSDisableInterrupts(); - fifo->read_ptr = readPtr; - fifo->write_ptr = writePtr; - fifo->rw_dst = (u32)writePtr - (u32)readPtr; - if (fifo->rw_dst < 0) { - fifo->rw_dst += fifo->size; + __GXFifoObj* realFifo = (__GXFifoObj *)fifo; + BOOL enabled; + + ASSERTMSGLINE(LINE(592, 592, 596), realFifo != CPUFifo, "GXInitFifoPtrs: fifo is attached to CPU"); + ASSERTMSGLINE(LINE(594, 594, 598), realFifo != GPFifo, "GXInitFifoPtrs: fifo is attached to GP"); + ASSERTMSGLINE(LINE(596, 596, 600), ((u32)readPtr & 0x1F) == 0, "GXInitFifoPtrs: readPtr not 32B aligned"); + ASSERTMSGLINE(LINE(598, 598, 602), ((u32)writePtr & 0x1F) == 0, "GXInitFifoPtrs: writePtr not 32B aligned"); + ASSERTMSGLINE(LINE(601, 601, 605), realFifo->base <= readPtr && readPtr < realFifo->top, "GXInitFifoPtrs: readPtr not in fifo range"); + ASSERTMSGLINE(LINE(604, 604, 608), realFifo->base <= writePtr && writePtr < realFifo->top, "GXInitFifoPtrs: writePtr not in fifo range"); + + enabled = OSDisableInterrupts(); + realFifo->rdPtr = readPtr; + realFifo->wrPtr = writePtr; + realFifo->count = (u8*)writePtr - (u8*)readPtr; + if (realFifo->count < 0) { + realFifo->count += realFifo->size; } - OSRestoreInterrupts(interrupts); + OSRestoreInterrupts(enabled); } -/* 8035A7B8-8035A7C4 3550F8 000C+00 1/1 0/0 0/0 .text GXInitFifoLimits */ -static void GXInitFifoLimits(GXFifoObj* fifo, u32 hi_watermark, u32 lo_watermark) { - fifo->high_wtrmark = hi_watermark; - fifo->low_wtrmark = lo_watermark; +void GXInitFifoLimits(GXFifoObj* fifo, u32 hiWatermark, u32 loWatermark) { + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + + ASSERTMSGLINE(LINE(641, 641, 645), realFifo != GPFifo, "GXInitFifoLimits: fifo is attached to GP"); + ASSERTMSGLINE(LINE(643, 643, 647), (hiWatermark & 0x1F) == 0, "GXInitFifoLimits: hiWatermark not 32B aligned"); + ASSERTMSGLINE(LINE(645, 645, 649), (loWatermark & 0x1F) == 0, "GXInitFifoLimits: loWatermark not 32B aligned"); + ASSERTMSGLINE(LINE(647, 647, 651), hiWatermark < realFifo->top - realFifo->base, "GXInitFifoLimits: hiWatermark too large"); + ASSERTMSGLINE(LINE(649, 649, 653), loWatermark < hiWatermark, "GXInitFifoLimits: hiWatermark below lo watermark"); + + realFifo->hiWatermark = hiWatermark; + realFifo->loWatermark = loWatermark; } -/* 8035A7C4-8035A8EC 355104 0128+00 1/1 1/1 0/0 .text GXSetCPUFifo */ +#define GX_SET_PI_REG(offset, val) (*(volatile u32*)((volatile u32*)(__piReg) + (offset)) = val) + +// NONMATCHING DEBUG void GXSetCPUFifo(GXFifoObj* fifo) { - BOOL interrupts; - interrupts = OSDisableInterrupts(); + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + BOOL enabled = OSDisableInterrupts(); - CPUFifo = fifo; + CPUFifo = realFifo; + if (CPUFifo == GPFifo) { + u32 reg = 0; - if (fifo == GPFifo) { - u32 reg; - GX_SET_PI_REG(3, (u32)fifo->base & 0x3FFFFFFF); - GX_SET_PI_REG(4, (u32)fifo->end & 0x3FFFFFFF); - reg = 0; - GX_BITFIELD_SET(reg, 6, 21, (u32)fifo->write_ptr >> 5); - GX_BITFIELD_SET(reg, 5, 1, 0); + GX_SET_PI_REG(3, (u32)realFifo->base & 0x3FFFFFFF); + GX_SET_PI_REG(4, (u32)realFifo->top & 0x3FFFFFFF); + + SET_REG_FIELD(LINE(691, 691, 695), reg, 21, 5, (u32)realFifo->wrPtr >> 5); + SET_REG_FIELD(LINE(691, 691, 695), reg, 1, 26, 0); GX_SET_PI_REG(5, reg); - data_80451954 = GX_TRUE; + CPGPLinked = GX_TRUE; __GXWriteFifoIntReset(1, 1); __GXWriteFifoIntEnable(1, 0); __GXFifoLink(1); } else { u32 reg; - if (data_80451954) { - __GXFifoLink(0); - data_80451954 = GX_FALSE; - } - __GXWriteFifoIntEnable(0, 0); - GX_SET_PI_REG(3, (u32)fifo->base & 0x3FFFFFFF); - GX_SET_PI_REG(4, (u32)fifo->end & 0x3FFFFFFF); + if (CPGPLinked) { + __GXFifoLink(0); + CPGPLinked = GX_FALSE; + } + + __GXWriteFifoIntEnable(0, 0); reg = 0; - GX_BITFIELD_SET(reg, 6, 21, (u32)fifo->write_ptr >> 5); - GX_BITFIELD_SET(reg, 5, 1, 0); + GX_SET_PI_REG(3, (u32)realFifo->base & 0x3FFFFFFF); + GX_SET_PI_REG(4, (u32)realFifo->top & 0x3FFFFFFF); + SET_REG_FIELD(LINE(726, 726, 730), reg, 21, 5, (u32)realFifo->wrPtr >> 5); + SET_REG_FIELD(LINE(726, 726, 730), reg, 1, 26, 0); GX_SET_PI_REG(5, reg); } PPCSync(); - - OSRestoreInterrupts(interrupts); + OSRestoreInterrupts(enabled); } -/* 8035A8EC-8035AA8C 35522C 01A0+00 1/1 1/1 0/0 .text GXSetGPFifo */ void GXSetGPFifo(GXFifoObj* fifo) { - int interrupts = OSDisableInterrupts(); - u32 reg; + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + BOOL enabled = OSDisableInterrupts(); +#if SDK_REVISION >= 2 + u32 stbtmp; +#endif + __GXFifoReadDisable(); __GXWriteFifoIntEnable(0, 0); - GPFifo = fifo; - GX_SET_CP_REG(16, (u16)fifo->base); - GX_SET_CP_REG(18, (u16)fifo->end); - GX_SET_CP_REG(24, (u16)fifo->rw_dst); - GX_SET_CP_REG(26, (u16)fifo->write_ptr); - GX_SET_CP_REG(28, (u16)fifo->read_ptr); - GX_SET_CP_REG(20, (u16)fifo->high_wtrmark); - GX_SET_CP_REG(22, (u16)fifo->low_wtrmark); + GPFifo = realFifo; - GX_SET_CP_REG(17, ((u32)fifo->base & 0x3FFFFFFF) >> 16); - GX_SET_CP_REG(19, ((u32)fifo->end & 0x3FFFFFFF) >> 16); - GX_SET_CP_REG(25, (fifo->rw_dst) >> 16); - GX_SET_CP_REG(27, ((u32)fifo->write_ptr & 0x3FFFFFFF) >> 16); - GX_SET_CP_REG(29, ((u32)fifo->read_ptr & 0x3FFFFFFF) >> 16); - GX_SET_CP_REG(21, (fifo->high_wtrmark) >> 16); - GX_SET_CP_REG(23, (fifo->low_wtrmark) >> 16); + GX_SET_CP_REG(16, (u32)realFifo->base & 0xFFFF); + GX_SET_CP_REG(18, (u32)realFifo->top & 0xFFFF); + GX_SET_CP_REG(24, realFifo->count & 0xFFFF); + GX_SET_CP_REG(26, (u32)realFifo->wrPtr & 0xFFFF); + GX_SET_CP_REG(28, (u32)realFifo->rdPtr & 0xFFFF); + GX_SET_CP_REG(20, (u32)realFifo->hiWatermark & 0xFFFF); + GX_SET_CP_REG(22, (u32)realFifo->loWatermark & 0xFFFF); + GX_SET_CP_REG(17, ((u32)realFifo->base & 0x3FFFFFFF) >> 16); + GX_SET_CP_REG(19, ((u32)realFifo->top & 0x3FFFFFFF) >> 16); + GX_SET_CP_REG(25, realFifo->count >> 16); + GX_SET_CP_REG(27, ((u32)realFifo->wrPtr & 0x3FFFFFFF) >> 16); + GX_SET_CP_REG(29, ((u32)realFifo->rdPtr & 0x3FFFFFFF) >> 16); + GX_SET_CP_REG(21, (u32)realFifo->hiWatermark >> 16); + GX_SET_CP_REG(23, (u32)realFifo->loWatermark >> 16); PPCSync(); if (CPUFifo == GPFifo) { - data_80451954 = 1; + CPGPLinked = GX_TRUE; __GXWriteFifoIntEnable(1, 0); __GXFifoLink(1); } else { - data_80451954 = 0; + CPGPLinked = GX_FALSE; __GXWriteFifoIntEnable(0, 0); __GXFifoLink(0); } - reg = __GXData->cpEnable; - GX_BITFIELD_SET(reg, 0x1e, 1, 0); - GX_BITFIELD_SET(reg, 0x1a, 1, 0); - GX_SET_CP_REG(1, reg); + +#if SDK_REVISION >= 2 + stbtmp = __GXData->cpEnable; + SET_REG_FIELD(0, stbtmp, 1, 1, 0); + SET_REG_FIELD(0, stbtmp, 1, 5, 0); + GX_SET_CP_REG(1, stbtmp); GX_SET_CP_REG(1, __GXData->cpEnable); +#endif __GXWriteFifoIntReset(1, 1); __GXFifoReadEnable(); - OSRestoreInterrupts(interrupts); + OSRestoreInterrupts(enabled); } -/* 8035AA8C-8035AAC0 3553CC 0034+00 0/0 1/1 0/0 .text GXSaveCPUFifo */ +#define SOME_MACRO1(fifo) \ +do { \ + u32 temp = GX_GET_CP_REG(29) << 16; \ + temp |= GX_GET_CP_REG(28); \ + fifo->rdPtr = OSPhysicalToCached(temp); \ +} while (0) + +#define SOME_MACRO2(fifo) \ +do { \ + u32 temp = GX_GET_CP_REG(25) << 16; \ + temp |= GX_GET_CP_REG(24); \ + fifo->count = temp; \ +} while (0) + +#if SDK_REVISION >= 2 +static void __GXSaveFifoCPStat(__GXFifoObj* realFifo) { + u32 cpStatus; + u8 readIdle; + +#if DEBUG + if (__gxVerif->verifyLevel != GX_WARN_NONE) { + cpStatus = GX_GET_CP_REG(0); + readIdle = cpStatus & 0x14; + ASSERTMSGLINE(856, readIdle, "GXSaveGPFifo: GP is not idle"); + } +#endif + + SOME_MACRO1(realFifo); + SOME_MACRO2(realFifo); +} + +static void __GXSaveFifoPIStat(__GXFifoObj* realFifo) { + realFifo->base = OSPhysicalToCached(GX_GET_PI_REG(3)); + realFifo->top = OSPhysicalToCached(GX_GET_PI_REG(4)); + realFifo->wrPtr = OSPhysicalToCached(GX_GET_PI_REG(5) & 0xFBFFFFFF); +} +#endif + void GXSaveCPUFifo(GXFifoObj* fifo) { + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + ASSERTMSGLINE(LINE(835, 835, 900), realFifo == CPUFifo, "GXSaveCPUFifo: fifo is not attached to CPU"); GXFlush(); - __GXSaveCPUFifoAux(fifo); + __GXSaveCPUFifoAux(realFifo); } -/* 8035AAC0-8035AB88 355400 00C8+00 1/1 0/0 0/0 .text __GXSaveCPUFifoAux */ -void __GXSaveCPUFifoAux(GXFifoObj* fifo) { - int interrupts = OSDisableInterrupts(); - fifo->base = OSPhysicalToCached(GX_GET_PI_REG(3)); - fifo->end = OSPhysicalToCached(GX_GET_PI_REG(4)); - fifo->write_ptr = OSPhysicalToCached(GX_GET_PI_REG(5) & ~0x4000000); - if (data_80451954 != 0) { - u32 reg2 = GX_GET_CP_REG(28) | (GX_GET_CP_REG(29) << 16); - fifo->read_ptr = (void*)(reg2 + -0x80000000); - fifo->rw_dst = (((u32)GX_GET_CP_REG(24) | (GX_GET_CP_REG(25) << 16))); +void __GXSaveCPUFifoAux(__GXFifoObj* realFifo) { + BOOL enabled = OSDisableInterrupts(); + +#if SDK_REVISION < 2 + realFifo->base = OSPhysicalToCached(GX_GET_PI_REG(3)); + realFifo->top = OSPhysicalToCached(GX_GET_PI_REG(4)); + realFifo->wrPtr = OSPhysicalToCached(GX_GET_PI_REG(5) & 0xFBFFFFFF); +#else + __GXSaveFifoPIStat(realFifo); +#endif + + if (CPGPLinked) { +#if SDK_REVISION < 2 + SOME_MACRO1(realFifo); + SOME_MACRO2(realFifo); +#else + __GXSaveFifoCPStat(realFifo); +#endif } else { - fifo->rw_dst = (u32)fifo->write_ptr - (u32)fifo->read_ptr; - if (fifo->rw_dst < 0) { - fifo->rw_dst += fifo->size; + realFifo->count = (u8*)realFifo->wrPtr - (u8*)realFifo->rdPtr; + if (realFifo->count < 0) + realFifo->count += realFifo->size; + } + OSRestoreInterrupts(enabled); +} + +void GXSaveGPFifo(GXFifoObj* fifo) { + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; +#if SDK_REVISION < 2 + u32 cpStatus; + u8 readIdle; + u32 temp; +#else + BOOL enabled = OSDisableInterrupts(); +#endif + +#if SDK_REVISION < 2 + ASSERTMSGLINE(908, realFifo == GPFifo, "GXSaveGPFifo: fifo is not attached to GP"); + cpStatus = *(u16*)__cpReg; + readIdle = GET_REG_FIELD(cpStatus, 1, 2); + ASSERTMSGLINE(915, readIdle, "GXSaveGPFifo: GP is not idle"); + + SOME_MACRO1(realFifo); + SOME_MACRO2(realFifo); +#else + __GXSaveFifoCPStat(realFifo); + if (CPGPLinked) { + __GXSaveFifoPIStat(realFifo); + } + OSRestoreInterrupts(enabled); +#endif +} + +void GXGetGPStatus(GXBool* overhi, GXBool* underlow, GXBool* readIdle, GXBool* cmdIdle, GXBool* brkpt) { + __GXData->cpStatus = GX_GET_CP_REG(0); + *overhi = GET_REG_FIELD(__GXData->cpStatus, 1, 0); + *underlow = (int)GET_REG_FIELD(__GXData->cpStatus, 1, 1); + *readIdle = (int)GET_REG_FIELD(__GXData->cpStatus, 1, 2); + *cmdIdle = (int)GET_REG_FIELD(__GXData->cpStatus, 1, 3); + *brkpt = (int)GET_REG_FIELD(__GXData->cpStatus, 1, 4); +} + +void GXGetFifoStatus(GXFifoObj* fifo, GXBool* overhi, GXBool* underflow, u32* fifoCount, GXBool* cpuWrite, GXBool* gpRead, GXBool* fifowrap) { + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + + *underflow = GX_FALSE; + *overhi = GX_FALSE; + *fifoCount = 0; + *fifowrap = GX_FALSE; + + if (realFifo == GPFifo) { + SOME_MACRO1(realFifo); + SOME_MACRO2(realFifo); + } + + if (realFifo == CPUFifo) { + GXFlush(); + __GXSaveCPUFifoAux(realFifo); + *fifowrap = (int)GET_REG_FIELD(GX_GET_PI_REG(5), 1, 26); + } + + *overhi = (realFifo->count > realFifo->hiWatermark); + *underflow = (realFifo->count < realFifo->loWatermark); + *fifoCount = (realFifo->count); + *cpuWrite = (CPUFifo == realFifo); + *gpRead = (GPFifo == realFifo); +} + +void GXGetFifoPtrs(GXFifoObj* fifo, void** readPtr, void** writePtr) { + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + + if (realFifo == CPUFifo) { + realFifo->wrPtr = OSPhysicalToCached(GX_GET_PI_REG(5) & 0xFBFFFFFF); + } + + if (realFifo == GPFifo) { + SOME_MACRO1(realFifo); + SOME_MACRO2(realFifo); + } else { + realFifo->count = (u8*)realFifo->wrPtr - (u8*)realFifo->rdPtr; + if (realFifo->count < 0) { + realFifo->count += realFifo->size; } } - OSRestoreInterrupts(interrupts); + + *readPtr = realFifo->rdPtr; + *writePtr = realFifo->wrPtr; } -/* 8035AB88-8035ABD8 3554C8 0050+00 0/0 2/2 0/0 .text GXGetGPStatus */ -void GXGetGPStatus(GXBool* overhi, GXBool* underlow, GXBool* readIdle, GXBool* cmdIdle, - GXBool* brkpt) { - __GXData->cpStatus = GX_GET_CP_REG(0); - *overhi = __GXData->cpStatus & 1; - *underlow = (__GXData->cpStatus >> 1) & 1; - *readIdle = (__GXData->cpStatus >> 2) & 1; - *cmdIdle = (__GXData->cpStatus >> 3) & 1; - *brkpt = (__GXData->cpStatus >> 4) & 1; +void* GXGetFifoBase(const GXFifoObj* fifo) { + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + + return realFifo->base; } -/* 8035ABD8-8035ABE0 355518 0008+00 0/0 1/1 0/0 .text GXGetFifoBase */ -void* GXGetFifoBase(GXFifoObj* fifo) { - return fifo->base; +u32 GXGetFifoSize(const GXFifoObj* fifo) { + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + + return realFifo->size; } -/* 8035ABE0-8035ABE8 355520 0008+00 0/0 1/1 0/0 .text GXGetFifoSize */ -u32 GXGetFifoSize(GXFifoObj* fifo) { - return fifo->size; +void GXGetFifoLimits(const GXFifoObj* fifo, u32* hi, u32* lo) { + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + + *hi = realFifo->hiWatermark; + *lo = realFifo->loWatermark; } -/* 8035ABE8-8035AC2C 355528 0044+00 0/0 1/1 0/0 .text GXSetBreakPtCallback */ GXBreakPtCallback GXSetBreakPtCallback(GXBreakPtCallback cb) { - GXBreakPtCallback oldCallback = BreakPointCB; - int interrupts = OSDisableInterrupts(); + GXBreakPtCallback oldcb = BreakPointCB; + BOOL enabled = OSDisableInterrupts(); + BreakPointCB = cb; - OSRestoreInterrupts(interrupts); - return oldCallback; + OSRestoreInterrupts(enabled); + return oldcb; +} + +void* __GXCurrentBP; + +void GXEnableBreakPt(void* break_pt) { + BOOL enabled = OSDisableInterrupts(); + + __GXFifoReadDisable(); + GX_SET_CP_REG(30, (u32)break_pt); + GX_SET_CP_REG(31, ((u32)break_pt >> 16) & 0x3FFF); +#if SDK_REVISION >= 2 + SOME_SET_REG_MACRO(__GXData->cpEnable, 1, 1, 0); + SOME_SET_REG_MACRO(__GXData->cpEnable, 1, 5, 0); + GX_SET_CP_REG(1, __GXData->cpEnable); +#endif + SOME_SET_REG_MACRO(__GXData->cpEnable, 1, 1, 1); + SOME_SET_REG_MACRO(__GXData->cpEnable, 1, 5, 1); + GX_SET_CP_REG(1, __GXData->cpEnable); + __GXCurrentBP = break_pt; + __GXFifoReadEnable(); + OSRestoreInterrupts(enabled); +} + +void GXDisableBreakPt(void) { + BOOL enabled = OSDisableInterrupts(); + + SOME_SET_REG_MACRO(__GXData->cpEnable, 1, 1, 0); + SOME_SET_REG_MACRO(__GXData->cpEnable, 1, 5, 0); + GX_SET_CP_REG(1, __GXData->cpEnable); + __GXCurrentBP = NULL; + OSRestoreInterrupts(enabled); } -/* 8035AC2C-8035AC78 35556C 004C+00 0/0 1/1 0/0 .text __GXFifoInit */ void __GXFifoInit(void) { __OSSetInterruptHandler(0x11, GXCPInterruptHandler); __OSUnmaskInterrupts(0x4000); __GXCurrentThread = OSGetCurrentThread(); - GXOverflowSuspendInProgress = 0; + GXOverflowSuspendInProgress = FALSE; CPUFifo = NULL; GPFifo = NULL; } -/* 8035AC78-8035AC9C 3555B8 0024+00 1/1 0/0 0/0 .text __GXFifoReadEnable */ -void __GXFifoReadEnable(void) { - FAST_FLAG_SET(__GXData->cpEnable, 1, 0, 1); +static void __GXFifoReadEnable(void) { + SET_REG_FIELD(0, __GXData->cpEnable, 1, 0, 1); GX_SET_CP_REG(1, __GXData->cpEnable); } -/* 8035AC9C-8035ACC0 3555DC 0024+00 1/1 0/0 0/0 .text __GXFifoReadDisable */ -void __GXFifoReadDisable(void) { - FAST_FLAG_SET(__GXData->cpEnable, 0, 0, 1); +static void __GXFifoReadDisable(void) { + SET_REG_FIELD(0, __GXData->cpEnable, 1, 0, 0); GX_SET_CP_REG(1, __GXData->cpEnable); } -/* 8035ACC0-8035ACF4 355600 0034+00 2/2 0/0 0/0 .text __GXFifoLink */ -void __GXFifoLink(u8 link) { - u32 b; - if (link) { - b = 1; - } else { - b = 0; - } - FAST_FLAG_SET(__GXData->cpEnable, b, 4, 1); +static void __GXFifoLink(u8 en) { + SET_REG_FIELD(LINE(1242, 1242, 1299), __GXData->cpEnable, 1, 4, (en != 0) ? 1 : 0); GX_SET_CP_REG(1, __GXData->cpEnable); } -/* 8035ACF4-8035AD24 355634 0030+00 3/3 0/0 0/0 .text __GXWriteFifoIntEnable */ -void __GXWriteFifoIntEnable(u32 p1, u32 p2) { - FAST_FLAG_SET(__GXData->cpEnable, p1, 2, 1); - FAST_FLAG_SET(__GXData->cpEnable, (u8)p2, 3, 1); +static void __GXWriteFifoIntEnable(u8 hiWatermarkEn, u8 loWatermarkEn) { + SET_REG_FIELD(LINE(1264, 1264, 1321), __GXData->cpEnable, 1, 2, hiWatermarkEn); + SET_REG_FIELD(LINE(1265, 1265, 1322), __GXData->cpEnable, 1, 3, loWatermarkEn); GX_SET_CP_REG(1, __GXData->cpEnable); } -/* 8035AD24-8035AD54 355664 0030+00 3/3 0/0 0/0 .text __GXWriteFifoIntReset */ -void __GXWriteFifoIntReset(u32 p1, u32 p2) { - FAST_FLAG_SET(__GXData->cpClr, p1, 0, 1); - FAST_FLAG_SET(__GXData->cpClr, (u8)p2, 1, 1); +static void __GXWriteFifoIntReset(u8 hiWatermarkClr, u8 loWatermarkClr) { + SET_REG_FIELD(LINE(1288, 1288, 1345), __GXData->cpClr, 1, 0, hiWatermarkClr); + SET_REG_FIELD(LINE(1289, 1289, 1346), __GXData->cpClr, 1, 1, loWatermarkClr); GX_SET_CP_REG(2, __GXData->cpClr); } -/* 8035AD54-8035AE54 355694 0100+00 0/0 1/1 0/0 .text __GXCleanGPFifo */ +void __GXInsaneWatermark(void) { + __GXFifoObj* realFifo = GPFifo; + + realFifo->hiWatermark = realFifo->loWatermark + 512; + GX_SET_CP_REG(20, (realFifo->hiWatermark & 0x3FFFFFFF) & 0xFFFF); + GX_SET_CP_REG(21, (realFifo->hiWatermark & 0x3FFFFFFF) >> 16); +} + void __GXCleanGPFifo(void) { - BOOL interrupts; - GXFifoObj tempObj; // 0x14 - u32 i, j, k; // stack alloc - GXFifoObj* gpFifo; // r31 - GXFifoObj* cpuFifo; // r30 - void* tempPtr; // r29 + GXFifoObj dummyFifo; + GXFifoObj* gpFifo; + GXFifoObj* cpuFifo; + void* base; gpFifo = GXGetGPFifo(); - if (!gpFifo) { + if (gpFifo == (GXFifoObj*)NULL) return; - } cpuFifo = GXGetCPUFifo(); - tempPtr = gpFifo->base; - - tempObj = *gpFifo; - - interrupts = OSDisableInterrupts(); - - tempObj.read_ptr = tempPtr; - tempObj.write_ptr = tempPtr; - tempObj.rw_dst = 0; - if (tempObj.rw_dst < 0) { - tempObj.rw_dst += tempObj.size; - } - - OSRestoreInterrupts(interrupts); - - GXSetGPFifo(&tempObj); + base = GXGetFifoBase(gpFifo); + dummyFifo = *gpFifo; + GXInitFifoPtrs(&dummyFifo, base, base); + GXSetGPFifo(&dummyFifo); if (cpuFifo == gpFifo) { - GXSetCPUFifo(&tempObj); + GXSetCPUFifo(&dummyFifo); } - - interrupts = OSDisableInterrupts(); - - gpFifo->read_ptr = tempPtr; - gpFifo->write_ptr = tempPtr; - gpFifo->rw_dst = 0; - - if (gpFifo->rw_dst < 0) { - gpFifo->rw_dst += gpFifo->size; - } - OSRestoreInterrupts(interrupts); - + GXInitFifoPtrs(gpFifo, base, base); GXSetGPFifo(gpFifo); if (cpuFifo == gpFifo) { GXSetCPUFifo(cpuFifo); } } -/* 8035AE54-8035AEA0 355794 004C+00 0/0 1/1 0/0 .text GXSetCurrentGXThread */ OSThread* GXSetCurrentGXThread(void) { - BOOL interrupts = OSDisableInterrupts(); - OSThread* prevThread = __GXCurrentThread; + BOOL enabled; + OSThread* prev; + + enabled = OSDisableInterrupts(); + prev = __GXCurrentThread; + ASSERTMSGLINE(LINE(1377, 1377, 1434), !GXOverflowSuspendInProgress, "GXSetCurrentGXThread: Two threads cannot generate GX commands at the same time!"); __GXCurrentThread = OSGetCurrentThread(); - OSRestoreInterrupts(interrupts); - return prevThread; + OSRestoreInterrupts(enabled); + return prev; } -/* 8035AEA0-8035AEA8 -00001 0008+00 0/0 0/0 0/0 .text GXGetCurrentGXThread */ OSThread* GXGetCurrentGXThread(void) { - return *(OSThread**)(&__GXCurrentThread); + return __GXCurrentThread; } -/* 8035AEA8-8035AEB0 -00001 0008+00 0/0 0/0 0/0 .text GXGetCPUFifo */ GXFifoObj* GXGetCPUFifo(void) { - return *(GXFifoObj**)(&CPUFifo); + return (GXFifoObj*)CPUFifo; } -/* 8035AEB0-8035AEB8 -00001 0008+00 0/0 0/0 0/0 .text GXGetGPFifo */ GXFifoObj* GXGetGPFifo(void) { - return GPFifo; -} \ No newline at end of file + return (GXFifoObj*)GPFifo; +} + +u32 GXGetOverflowCount(void) { + return __GXOverflowCount; +} + +u32 GXResetOverflowCount(void) { + u32 oldcount; + + oldcount = __GXOverflowCount; + __GXOverflowCount = 0; + return oldcount; +} + +// NONMATCHING +volatile void* GXRedirectWriteGatherPipe(void* ptr) { + u32 reg = 0; + BOOL enabled = OSDisableInterrupts(); + + CHECK_GXBEGIN(LINE(1493, 1493, 1550), "GXRedirectWriteGatherPipe"); + ASSERTLINE(LINE(1494, 1494, 1551), OFFSET(ptr, 32) == 0); + ASSERTLINE(LINE(1496, 1496, 1553), !IsWGPipeRedirected); + +#if DEBUG + IsWGPipeRedirected = TRUE; +#endif + + GXFlush(); + while (PPCMfwpar() & 1) {} + PPCMtwpar((u32)OSUncachedToPhysical((void*)GXFIFO_ADDR)); + if (CPGPLinked) { + __GXFifoLink(0); + __GXWriteFifoIntEnable(0, 0); + } + CPUFifo->wrPtr = OSPhysicalToCached(GX_GET_PI_REG(5) & 0xFBFFFFFF); + GX_SET_PI_REG(3, 0); + GX_SET_PI_REG(4, 0x04000000); + SET_REG_FIELD(LINE(1527, 1527, 1584), reg, 21, 5, ((u32)ptr & 0x3FFFFFFF) >> 5); + reg &= 0xFBFFFFFF; + GX_SET_PI_REG(5, reg); + + PPCSync(); + OSRestoreInterrupts(enabled); + return (volatile void *)GXFIFO_ADDR; +} + +// NONMATCHING +void GXRestoreWriteGatherPipe(void) { + u32 reg = 0; + u32 i; + BOOL enabled; + + ASSERTLINE(1552, IsWGPipeRedirected); + +#if DEBUG + IsWGPipeRedirected = FALSE; +#endif + + enabled = OSDisableInterrupts(); + for (i = 0; i < 31; i++) { + GXWGFifo.u8 = 0; + } + + PPCSync(); + while (PPCMfwpar() & 1) {} + PPCMtwpar((u32)OSUncachedToPhysical((void *)GXFIFO_ADDR)); + GX_SET_PI_REG(3, (u32)CPUFifo->base & 0x3FFFFFFF); + GX_SET_PI_REG(4, (u32)CPUFifo->top & 0x3FFFFFFF); + SET_REG_FIELD(1578, reg, 21, 5, ((u32)CPUFifo->wrPtr & 0x3FFFFFFF) >> 5); + reg &= 0xFBFFFFFF; + GX_SET_PI_REG(5, reg); + if (CPGPLinked) { + __GXWriteFifoIntReset(1, 1); + __GXWriteFifoIntEnable(1, 0); + __GXFifoLink(1); + } + + PPCSync(); + OSRestoreInterrupts(enabled); +} diff --git a/src/dolphin/gx/GXFrameBuf.c b/src/dolphin/gx/GXFrameBuf.c index 2524fd10c9..d248566802 100644 --- a/src/dolphin/gx/GXFrameBuf.c +++ b/src/dolphin/gx/GXFrameBuf.c @@ -1,653 +1,603 @@ -#include "dolphin/gx/GXFrameBuf.h" -#include "dolphin/gx.h" +#include +#include + +#include "__gx.h" + +GXRenderModeObj GXNtsc240Ds = { + 1, + 640, 240, 240, + 40, 0, + 640, 480, + 0, + 0, + 0, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, + { 0, 0, 21, 22, 21, 0, 0 } +}; + +GXRenderModeObj GXNtsc240DsAa = { + 1, 640, 240, 240, 40, 0, 640, 480, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } +}; + +GXRenderModeObj GXNtsc240Int = { + 0, 640, 240, 240, 40, 0, 640, 480, 0, 1, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } +}; + +GXRenderModeObj GXNtsc240IntAa = { + 0, 640, 240, 240, 40, 0, 640, 480, 0, 1, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } +}; GXRenderModeObj GXNtsc480IntDf = { - VI_TVMODE_NTSC_INT, - 640, - 480, - 480, - 40, - 0, - 640, - 480, - VI_XFBMODE_DF, - GX_FALSE, - GX_FALSE, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 8, - 8, - 10, - 12, - 10, - 8, - 8, + 0, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 } }; GXRenderModeObj GXNtsc480Int = { - VI_TVMODE_NTSC_INT, - 640, - 480, - 480, - 40, - 0, - 640, - 480, - VI_XFBMODE_DF, - GX_FALSE, - GX_FALSE, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 0, - 0, - 21, - 22, - 21, - 0, - 0, + 0, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; -GXRenderModeObj GXMpal480IntDf = { - VI_TVMODE_MPAL_INT, - 640, - 480, - 480, - 40, - 0, - 640, - 480, - VI_XFBMODE_DF, - GX_FALSE, - GX_FALSE, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 8, - 8, - 10, - 12, - 10, - 8, - 8, +GXRenderModeObj GXNtsc480IntAa = { + 0, 640, 242, 480, 40, 0, 640, 480, 1, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 } }; -GXRenderModeObj GXPal528IntDf = { - VI_TVMODE_PAL_INT, - 640, - 528, - 528, - 40, - 23, - 640, - 528, - VI_XFBMODE_DF, - GX_FALSE, - GX_FALSE, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 8, - 8, - 10, - 12, - 10, - 8, - 8, +GXRenderModeObj GXNtsc480Prog = { + 2, 640, 480, 480, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; -GXRenderModeObj GXEurgb60Hz480IntDf = { - VI_TVMODE_EURGB60_INT, - 640, - 480, - 480, - 40, - 0, - 640, - 480, - VI_XFBMODE_DF, - GX_FALSE, - GX_FALSE, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 6, - 8, - 8, - 10, - 12, - 10, - 8, - 8, +GXRenderModeObj GXNtsc480ProgSoft = { + 2, 640, 480, 480, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 } }; -/* 8035CA04-8035CA80 357344 007C+00 0/0 2/2 0/0 .text GXSetDispCopySrc */ -void GXSetDispCopySrc(u16 left, u16 top, u16 width, u16 height) { - __GXData->cpDispSrc = 0; - GX_BITFIELD_SET(__GXData->cpDispSrc, 22, 10, left); - GX_BITFIELD_SET(__GXData->cpDispSrc, 12, 10, top); - GX_BITFIELD_SET(__GXData->cpDispSrc, 0, 8, 73); +GXRenderModeObj GXNtsc480ProgAa = { + 2, 640, 242, 480, 40, 0, 640, 480, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 } +}; - __GXData->cpDispSize = 0; - GX_BITFIELD_SET(__GXData->cpDispSize, 22, 10, width - 1); - GX_BITFIELD_SET(__GXData->cpDispSize, 12, 10, height - 1); - GX_BITFIELD_SET(__GXData->cpDispSize, 0, 8, 74); -} +GXRenderModeObj GXMpal240Ds = {9, 640, 240, 240, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXMpal240DsAa = {9, 640, 240, 240, 40, 0, 640, 480, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXMpal240Int = {8, 640, 240, 240, 40, 0, 640, 480, 0, 1, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXMpal240IntAa = {8, 640, 240, 240, 40, 0, 640, 480, 0, 1, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXMpal480IntDf = {8, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 } }; +GXRenderModeObj GXMpal480Int = {8, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXMpal480IntAa = {8, 640, 242, 480, 40, 0, 640, 480, 1, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 } }; +GXRenderModeObj GXPal264Ds = {5, 640, 264, 264, 40, 11, 640, 528, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXPal264DsAa = {5, 640, 264, 264, 40, 11, 640, 528, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXPal264Int = {4, 640, 264, 264, 40, 23, 640, 528, 0, 1, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXPal264IntAa = {4, 640, 264, 264, 40, 23, 640, 528, 0, 1, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXPal528IntDf = {4, 640, 528, 528, 40, 23, 640, 528, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 } }; +GXRenderModeObj GXPal528Int = {4, 640, 528, 528, 40, 23, 640, 528, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXPal524IntAa = {4, 640, 264, 524, 40, 23, 640, 524, 1, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 } }; +GXRenderModeObj GXEurgb60Hz240Ds = {21, 640, 240, 240, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXEurgb60Hz240DsAa = {21, 640, 240, 240, 40, 0, 640, 480, 0, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXEurgb60Hz240Int = {20, 640, 240, 240, 40, 0, 640, 480, 0, 1, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXEurgb60Hz240IntAa = {20, 640, 240, 240, 40, 0, 640, 480, 0, 1, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXEurgb60Hz480IntDf = {20, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 8, 8, 10, 12, 10, 8, 8 } }; +GXRenderModeObj GXEurgb60Hz480Int = {20, 640, 480, 480, 40, 0, 640, 480, 1, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; +GXRenderModeObj GXEurgb60Hz480IntAa = {20, 640, 242, 480, 40, 0, 640, 480, 1, 0, 1, { 3, 2, 9, 6, 3, 10, 3, 2, 9, 6, 3, 10, 9, 2, 3, 6, 9, 10, 9, 2, 3, 6, 9, 10 }, { 4, 8, 12, 16, 12, 8, 4 } }; +GXRenderModeObj GXRmHW = {1, 320, 240, 240, 40, 0, 640, 480, 0, 0, 0, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, { 0, 0, 21, 22, 21, 0, 0 } }; -/* 8035CA80-8035CAFC 3573C0 007C+00 0/0 9/9 0/0 .text GXSetTexCopySrc */ -void GXSetTexCopySrc(u16 left, u16 top, u16 width, u16 height) { - __GXData->cpTexSrc = 0; - GX_BITFIELD_SET(__GXData->cpTexSrc, 22, 10, left); - GX_BITFIELD_SET(__GXData->cpTexSrc, 12, 10, top); - GX_BITFIELD_SET(__GXData->cpTexSrc, 0, 8, 0x49); - __GXData->cpTexSize = 0; - GX_BITFIELD_SET(__GXData->cpTexSize, 22, 10, width - 1); - GX_BITFIELD_SET(__GXData->cpTexSize, 12, 10, height - 1); - GX_BITFIELD_SET(__GXData->cpTexSize, 0, 8, 0x4A); -} +void GXAdjustForOverscan(const GXRenderModeObj* rmin, GXRenderModeObj* rmout, u16 hor, u16 ver) { + u16 hor2 = hor * 2; + u16 ver2 = ver * 2; + u32 verf; + u32 mode; -/* 8035CAFC-8035CB30 35743C 0034+00 0/0 2/2 0/0 .text GXSetDispCopyDst */ -void GXSetDispCopyDst(u16 arg0, u16 arg1) { - s32 val = (s32)((arg0 << 1) & 0xFFFE) >> 5; - __GXData->cpDispStride = 0; - GX_BITFIELD_SET(__GXData->cpDispStride, 22, 10, val); - GX_BITFIELD_SET(__GXData->cpDispStride, 0, 8, 0x4D); -} - -/* 8035CB30-8035CC60 357470 0130+00 0/0 9/9 0/0 .text GXSetTexCopyDst */ -void GXSetTexCopyDst(u16 width, u16 height, GXTexFmt format, GXBool useMIPmap) { - u32 sp20, sp1C, sp18; - u32 value; - u8 depthRelated; - - __GXData->cpTexZ = GX_NONE; - - depthRelated = format & 0xf; - if (format == GX_TF_Z16) { - depthRelated = 0xb; + if (rmin != rmout) { + *rmout = *rmin; } - switch (format) { + mode = rmin->viTVmode & 3; + rmout->fbWidth = rmin->fbWidth - hor2; + verf = (ver2 * rmin->efbHeight) / (u32)rmin->xfbHeight; + rmout->efbHeight = rmin->efbHeight - verf; + if (rmin->xFBmode == VI_XFBMODE_SF && mode == 0) { + rmout->xfbHeight = rmin->xfbHeight - ver2 / 2; + } else { + rmout->xfbHeight = rmin->xfbHeight - ver2; + } + + rmout->viWidth = rmin->viWidth - hor2; + + if (mode == 1) { + rmout->viHeight = rmin->viHeight - (ver2 * 2); + } else { + rmout->viHeight = rmin->viHeight - ver2; + } + + rmout->viXOrigin = rmin->viXOrigin + hor; + rmout->viYOrigin = rmin->viYOrigin + ver; +} + +void GXSetDispCopySrc(u16 left, u16 top, u16 wd, u16 ht) { + CHECK_GXBEGIN(1235, "GXSetDispCopySrc"); + + __GXData->cpDispSrc = 0; + SET_REG_FIELD(1238, __GXData->cpDispSrc, 10, 0, left); + SET_REG_FIELD(1239, __GXData->cpDispSrc, 10, 10, top); + SET_REG_FIELD(1239, __GXData->cpDispSrc, 8, 24, 0x49); + + __GXData->cpDispSize = 0; + SET_REG_FIELD(1243, __GXData->cpDispSize, 10, 0, wd - 1); + SET_REG_FIELD(1244, __GXData->cpDispSize, 10, 10, ht - 1); + SET_REG_FIELD(1244, __GXData->cpDispSize, 8, 24, 0x4A); +} + + +void GXSetTexCopySrc(u16 left, u16 top, u16 wd, u16 ht) { + CHECK_GXBEGIN(1263, "GXSetTexCopySrc"); + + __GXData->cpTexSrc = 0; + SET_REG_FIELD(1266, __GXData->cpTexSrc, 10, 0, left); + SET_REG_FIELD(1267, __GXData->cpTexSrc, 10, 10, top); + SET_REG_FIELD(1267, __GXData->cpTexSrc, 8, 24, 0x49); + + __GXData->cpTexSize = 0; + SET_REG_FIELD(1271, __GXData->cpTexSize, 10, 0, wd - 1); + SET_REG_FIELD(1272, __GXData->cpTexSize, 10, 10, ht - 1); + SET_REG_FIELD(1272, __GXData->cpTexSize, 8, 24, 0x4A); +} + +void GXSetDispCopyDst(u16 wd, u16 ht) { + u16 stride; + + ASSERTMSGLINE(1293, (wd & 0xF) == 0, "GXSetDispCopyDst: Width must be a multiple of 16"); + CHECK_GXBEGIN(1294, "GXSetDispCopyDst"); + + stride = (int)wd * 2; + __GXData->cpDispStride = 0; + SET_REG_FIELD(1300, __GXData->cpDispStride, 10, 0, (stride >> 5) ); + SET_REG_FIELD(1300, __GXData->cpDispStride, 8, 24, 0x4D); +} + +void GXSetTexCopyDst(u16 wd, u16 ht, GXTexFmt fmt, GXBool mipmap) { + u32 rowTiles; + u32 colTiles; + u32 cmpTiles; + u32 peTexFmt; + u32 peTexFmtH; + + CHECK_GXBEGIN(1327, "GXSetTexCopyDst"); + + __GXData->cpTexZ = 0; + peTexFmt = fmt & 0xF; + ASSERTMSGLINEV(1358, peTexFmt < 13, "%s: invalid texture format", "GXSetTexCopyDst"); + + if (fmt == GX_TF_Z16) { + peTexFmt = 0xB; + } + + switch (fmt) { case GX_TF_I4: case GX_TF_I8: case GX_TF_IA4: case GX_TF_IA8: - case GX_CTF_A8: - GX_SET_REG(__GXData->cpTex, 3, 15, 16); + case GX_CTF_YUVA8: + SET_REG_FIELD(0, __GXData->cpTex, 2, 15, 3); break; default: - GX_SET_REG(__GXData->cpTex, 2, 15, 16); + SET_REG_FIELD(0, __GXData->cpTex, 2, 15, 2); break; } - __GXData->cpTexZ = (format & 0x10) == 0x10; + __GXData->cpTexZ = (fmt & _GX_TF_ZTF) == _GX_TF_ZTF; + peTexFmtH = (peTexFmt >> 3) & 1; + !peTexFmt; + SET_REG_FIELD(1381, __GXData->cpTex, 1, 3, peTexFmtH); + peTexFmt = peTexFmt & 7; + __GetImageTileCount(fmt, wd, ht, &rowTiles, &colTiles, &cmpTiles); - value = depthRelated >> 3; - - GX_SET_REG(__GXData->cpTex, value, 28, 28); - - depthRelated &= 7; - - __GetImageTileCount(format, width, height, &sp20, &sp1C, &sp18); - - __GXData->cpTexStride = GX_NONE; - GX_SET_REG(__GXData->cpTexStride, sp20 * sp18, 22, 31); - GX_SET_REG(__GXData->cpTexStride, 0x4D, 0, 7); - - GX_SET_REG(__GXData->cpTex, useMIPmap, 22, 22); - GX_SET_REG(__GXData->cpTex, depthRelated, 25, 27); + __GXData->cpTexStride = 0; + SET_REG_FIELD(1390, __GXData->cpTexStride, 10, 0, rowTiles * cmpTiles); + SET_REG_FIELD(1392, __GXData->cpTexStride, 8, 24, 0x4D); + SET_REG_FIELD(1392, __GXData->cpTex, 1, 9, mipmap); + SET_REG_FIELD(1393, __GXData->cpTex, 3, 4, peTexFmt); } -/* 8035CC60-8035CC84 3575A0 0024+00 0/0 1/1 0/0 .text GXSetDispCopyFrame2Field */ -void GXSetDispCopyFrame2Field(GXCopyMode arg0) { - GX_BITFIELD_SET(__GXData->cpDisp, 18, 2, arg0); - GX_BITFIELD_SET(__GXData->cpTex, 18, 2, 0); +void GXSetDispCopyFrame2Field(GXCopyMode mode) { + CHECK_GXBEGIN(1410, "GXSetDispCopyFrame2Field"); + SET_REG_FIELD(1411, __GXData->cpDisp, 2, 12, mode); + SET_REG_FIELD(1411, __GXData->cpTex, 2, 12, 0); } -// clang-format off -#define INSERT_FIELD(reg, value, nbits, shift) \ - (reg) = ((u32) (reg) & ~(((1 << (nbits)) - 1) << (shift))) | \ - ((u32) (value) << (shift)); -// clang-format on - -/* 8035CC84-8035CCDC 3575C4 0058+00 0/0 2/2 0/0 .text GXSetCopyClamp */ void GXSetCopyClamp(GXFBClamp clamp) { - u8 isTop = (clamp & GX_CLAMP_TOP) == GX_CLAMP_TOP; - u8 isBottom = (clamp & GX_CLAMP_BOTTOM) == GX_CLAMP_BOTTOM; - __GXData->cpDisp = __rlwimi(__GXData->cpDisp, isTop, 0, 31, 31); - __GXData->cpDisp = __rlwimi(__GXData->cpDisp, isBottom, 1, 30, 30); - __GXData->cpTex = __rlwimi(__GXData->cpTex, isTop, 0, 31, 31); - __GXData->cpTex = __rlwimi(__GXData->cpTex, isBottom, 1, 30, 30); + u8 clmpB; + u8 clmpT; + + CHECK_GXBEGIN(1431, "GXSetCopyClamp"); + + clmpT = (clamp & GX_CLAMP_TOP) == 1; + clmpB = (clamp & GX_CLAMP_BOTTOM) == 2; + + SET_REG_FIELD(1435, __GXData->cpDisp, 1, 0, clmpT); + SET_REG_FIELD(1436, __GXData->cpDisp, 1, 1, clmpB); + + SET_REG_FIELD(1438, __GXData->cpTex, 1, 0, clmpT); + SET_REG_FIELD(1439, __GXData->cpTex, 1, 1, clmpB); } -static u32 __GXGetNumXfbLines(u32 height, u32 scale) { - u32 numLines; - u32 actualHeight; - u32 newScale; +static u32 __GXGetNumXfbLines(u32 efbHt, u32 iScale) { + u32 count; + u32 realHt; + u32 iScaleD; - numLines = (height - 1) * 0x100; - actualHeight = (numLines / scale) + 1; + count = (efbHt - 1) * 0x100; + realHt = (count / iScale) + 1; - newScale = scale; + iScaleD = iScale; - if (newScale > 0x80 && newScale < 0x100) { - while (newScale % 2 == 0) { - newScale /= 2; + if (iScaleD > 0x80 && iScaleD < 0x100) { + while (iScaleD % 2 == 0) { + iScaleD /= 2; } - if (height % newScale == 0) { - actualHeight++; + if (efbHt % iScaleD == 0) { + realHt++; } } - if (actualHeight > 0x400) { - actualHeight = 0x400; + if (realHt > 0x400) { + realHt = 0x400; } - return actualHeight; + return realHt; } -/* 8035CCDC-8035CD6C 35761C 0090+00 0/0 2/2 0/0 .text GXGetNumXfbLines */ u16 GXGetNumXfbLines(u16 efbHeight, f32 yScale) { - u32 scale = (u32)(256.0f / yScale) & 0x1FF; + u32 iScale; + ASSERTMSGLINE(1486, yScale >= 1.0f, "GXGetNumXfbLines: Vertical scale must be >= 1.0"); - return __GXGetNumXfbLines(efbHeight, scale); + iScale = (u32)(256.0f / yScale) & 0x1FF; + return __GXGetNumXfbLines(efbHeight, iScale); } -/* 8035CD6C-8035CFA4 3576AC 0238+00 0/0 2/2 0/0 .text GXGetYScaleFactor */ f32 GXGetYScaleFactor(u16 efbHeight, u16 xfbHeight) { - u32 scale; - u32 height1; - u32 height2; - f32 scale2; - f32 scale1; + f32 fScale; + f32 yScale; + u32 iScale; + u32 tgtHt; + u32 realHt; - height1 = xfbHeight; - scale1 = (f32)xfbHeight / (f32)efbHeight; - scale = (u32)(256.0f / scale1) & 0x1FF; - height2 = __GXGetNumXfbLines(efbHeight, scale); + ASSERTMSGLINE(1510, xfbHeight <= 1024, "GXGetYScaleFactor: Display copy only supports up to 1024 lines.\n"); + ASSERTMSGLINE(1512, efbHeight <= xfbHeight, "GXGetYScaleFactor: EFB height should not be greater than XFB height.\n"); - while (height2 > xfbHeight) { - height1--; - scale1 = (f32)height1 / (f32)efbHeight; - scale = (u32)(256.0f / scale1) & 0x1FF; - height2 = __GXGetNumXfbLines(efbHeight, scale); + tgtHt = xfbHeight; + yScale = (f32)xfbHeight / (f32)efbHeight; + iScale = (u32)(256.0f / yScale) & 0x1FF; + realHt = __GXGetNumXfbLines(efbHeight, iScale); + + while (realHt > xfbHeight) { + tgtHt--; + yScale = (f32)tgtHt / (f32)efbHeight; + iScale = (u32)(256.0f / yScale) & 0x1FF; + realHt = __GXGetNumXfbLines(efbHeight, iScale); } - scale2 = scale1; - while (height2 < xfbHeight) { - scale2 = scale1; - height1++; - scale1 = (f32)height1 / (f32)efbHeight; - scale = (u32)(256.0f / scale1) & 0x1FF; - height2 = __GXGetNumXfbLines(efbHeight, scale); + fScale = yScale; + while (realHt < xfbHeight) { + fScale = yScale; + tgtHt++; + yScale = (f32)tgtHt / (f32)efbHeight; + iScale = (u32)(256.0f / yScale) & 0x1FF; + realHt = __GXGetNumXfbLines(efbHeight, iScale); } - return scale2; + return fScale; } -/* 8035CFA4-8035D070 3578E4 00CC+00 0/0 2/2 0/0 .text GXSetDispCopyYScale */ -u32 GXSetDispCopyYScale(f32 vertScale) { - u32 scale; - GXBool check; - u32 height; +u32 GXSetDispCopyYScale(f32 vscale) { + u8 enable; + u32 iScale; + u32 ht; u32 reg; - scale = (u32)(256.0f / vertScale) & 0x1FF; - check = (scale != 0x100); + CHECK_GXBEGIN(1557, "GXSetDispCopyYScale"); + + ASSERTMSGLINE(1559, vscale >= 1.0f, "GXSetDispCopyYScale: Vertical scale must be >= 1.0"); + + iScale = (u32) (256.0f / vscale) & 0x1FF; + enable = (iScale != 256); reg = 0; - GX_SET_REG(reg, scale, 23, 31); - GX_SET_REG(reg, 0x4E, 0, 7); - GX_BP_LOAD_REG(reg); - __GXData->bpSentNot = GX_FALSE; - - GX_SET_REG(__GXData->cpDisp, check, 21, 21); - - height = (__GXData->cpDispSize >> 10 & 0x3FF) + 1; - - return __GXGetNumXfbLines(height, scale); + SET_REG_FIELD(1566, reg, 9, 0, iScale); + SET_REG_FIELD(1566, reg, 8, 24, 0x4E); + GX_WRITE_RAS_REG(reg); + __GXData->bpSentNot = 0; + SET_REG_FIELD(1571, __GXData->cpDisp, 1, 10, enable); + ht = (u32)GET_REG_FIELD(__GXData->cpDispSize, 10, 10) + 1; + return __GXGetNumXfbLines(ht, iScale); } -/* 8035D070-8035D0E8 3579B0 0078+00 0/0 2/2 0/0 .text GXSetCopyClear */ -void GXSetCopyClear(GXColor color, u32 clear_z) { - u32 r6 = 0; - GX_BITFIELD_SET(r6, 24, 8, color.r); - GX_BITFIELD_SET(r6, 16, 8, color.a); - GX_BITFIELD_SET(r6, 0, 8, 0x4f); - GXWGFifo.u8 = 0x61; - GXWGFifo.u32 = r6; +void GXSetCopyClear(GXColor clear_clr, u32 clear_z) { + u32 reg; - r6 = 0; - GX_BITFIELD_SET(r6, 24, 8, color.b); - GX_BITFIELD_SET(r6, 16, 8, color.g); - GX_BITFIELD_SET(r6, 0, 8, 0x50); - GXWGFifo.u8 = 0x61; - GXWGFifo.u32 = r6; + CHECK_GXBEGIN(1596, "GXSetCopyClear"); + ASSERTMSGLINE(1598, clear_z <= 0xFFFFFF, "GXSetCopyClear: Z clear value is out of range"); - r6 = 0; - GX_BITFIELD_SET(r6, 8, 24, clear_z); - GX_BITFIELD_SET(r6, 0, 8, 0x51); - GXWGFifo.u8 = 0x61; - GXWGFifo.u32 = r6; + reg = 0; + SET_REG_FIELD(1601, reg, 8, 0, clear_clr.r); + SET_REG_FIELD(1602, reg, 8, 8, clear_clr.a); + SET_REG_FIELD(1602, reg, 8, 24, 0x4F); + GX_WRITE_RAS_REG(reg); + + reg = 0; + SET_REG_FIELD(1607, reg, 8, 0, clear_clr.b); + SET_REG_FIELD(1608, reg, 8, 8, clear_clr.g); + SET_REG_FIELD(1608, reg, 8, 24, 0x50); + GX_WRITE_RAS_REG(reg); + + reg = 0; + SET_REG_FIELD(1613, reg, 24, 0, clear_z); + SET_REG_FIELD(1613, reg, 8, 24, 0x51); + GX_WRITE_RAS_REG(reg); + __GXData->bpSentNot = 0; +} + +void GXSetCopyFilter(GXBool aa, const u8 sample_pattern[12][2], GXBool vf, const u8 vfilter[7]) { + u32 msLoc[4]; + u32 coeff0; + u32 coeff1; + + CHECK_GXBEGIN(1641, "GXSetCopyFilter"); + + if (aa != 0) { + msLoc[0] = 0; + SET_REG_FIELD(1645, msLoc[0], 4, 0, sample_pattern[0][0]); + SET_REG_FIELD(1646, msLoc[0], 4, 4, sample_pattern[0][1]); + SET_REG_FIELD(1647, msLoc[0], 4, 8, sample_pattern[1][0]); + SET_REG_FIELD(1648, msLoc[0], 4, 12, sample_pattern[1][1]); + SET_REG_FIELD(1649, msLoc[0], 4, 16, sample_pattern[2][0]); + SET_REG_FIELD(1650, msLoc[0], 4, 20, sample_pattern[2][1]); + SET_REG_FIELD(1651, msLoc[0], 8, 24, 1); + + msLoc[1] = 0; + SET_REG_FIELD(1654, msLoc[1], 4, 0, sample_pattern[3][0]); + SET_REG_FIELD(1655, msLoc[1], 4, 4, sample_pattern[3][1]); + SET_REG_FIELD(1656, msLoc[1], 4, 8, sample_pattern[4][0]); + SET_REG_FIELD(1657, msLoc[1], 4, 12, sample_pattern[4][1]); + SET_REG_FIELD(1658, msLoc[1], 4, 16, sample_pattern[5][0]); + SET_REG_FIELD(1659, msLoc[1], 4, 20, sample_pattern[5][1]); + SET_REG_FIELD(1660, msLoc[1], 8, 24, 2); + + msLoc[2] = 0; + SET_REG_FIELD(1663, msLoc[2], 4, 0, sample_pattern[6][0]); + SET_REG_FIELD(1664, msLoc[2], 4, 4, sample_pattern[6][1]); + SET_REG_FIELD(1665, msLoc[2], 4, 8, sample_pattern[7][0]); + SET_REG_FIELD(1666, msLoc[2], 4, 12, sample_pattern[7][1]); + SET_REG_FIELD(1667, msLoc[2], 4, 16, sample_pattern[8][0]); + SET_REG_FIELD(1668, msLoc[2], 4, 20, sample_pattern[8][1]); + SET_REG_FIELD(1669, msLoc[2], 8, 24, 3); + + msLoc[3] = 0; + SET_REG_FIELD(1672, msLoc[3], 4, 0, sample_pattern[9][0]); + SET_REG_FIELD(1673, msLoc[3], 4, 4, sample_pattern[9][1]); + SET_REG_FIELD(1674, msLoc[3], 4, 8, sample_pattern[10][0]); + SET_REG_FIELD(1675, msLoc[3], 4, 12, sample_pattern[10][1]); + SET_REG_FIELD(1676, msLoc[3], 4, 16, sample_pattern[11][0]); + SET_REG_FIELD(1677, msLoc[3], 4, 20, sample_pattern[11][1]); + SET_REG_FIELD(1678, msLoc[3], 8, 24, 4); + } else { + msLoc[0] = 0x01666666; + msLoc[1] = 0x02666666; + msLoc[2] = 0x03666666; + msLoc[3] = 0x04666666; + } + + GX_WRITE_RAS_REG(msLoc[0]); + GX_WRITE_RAS_REG(msLoc[1]); + GX_WRITE_RAS_REG(msLoc[2]); + GX_WRITE_RAS_REG(msLoc[3]); + + coeff0 = 0; + SET_REG_FIELD(0, coeff0, 8, 24, 0x53); + coeff1 = 0; + SET_REG_FIELD(0, coeff1, 8, 24, 0x54); + + if (vf != 0) { + SET_REG_FIELD(1702, coeff0, 6, 0, vfilter[0]); + SET_REG_FIELD(1703, coeff0, 6, 6, vfilter[1]); + SET_REG_FIELD(1704, coeff0, 6, 12, vfilter[2]); + SET_REG_FIELD(1705, coeff0, 6, 18, vfilter[3]); + SET_REG_FIELD(1706, coeff1, 6, 0, vfilter[4]); + SET_REG_FIELD(1707, coeff1, 6, 6, vfilter[5]); + SET_REG_FIELD(1708, coeff1, 6, 12, vfilter[6]); + } else { + SET_REG_FIELD(0, coeff0, 6, 0, 0); + SET_REG_FIELD(0, coeff0, 6, 6, 0); + SET_REG_FIELD(0, coeff0, 6, 12, 21); + SET_REG_FIELD(0, coeff0, 6, 18, 22); + SET_REG_FIELD(0, coeff1, 6, 0, 21); + SET_REG_FIELD(0, coeff1, 6, 6, 0); + SET_REG_FIELD(0, coeff1, 6, 12, 0); + } + + GX_WRITE_RAS_REG(coeff0); + GX_WRITE_RAS_REG(coeff1); + __GXData->bpSentNot = 0; +} + +void GXSetDispCopyGamma(GXGamma gamma) { + CHECK_GXBEGIN(1741, "GXSetDispCopyGamma"); + SET_REG_FIELD(1742, __GXData->cpDisp, 2, 7, gamma); +} + +#if DEBUG +static void __GXVerifCopy(void* dest, u8 clear) { + u8 clmpT; + u8 clmpB; + u32 x0; + u32 y0; + u32 dx; + u32 dy; + + CHECK_GXBEGIN(1762, "GXCopyDisp"); + + clmpT = GET_REG_FIELD(__GXData->cpDisp, 1, 0); + clmpB = (u32)GET_REG_FIELD(__GXData->cpDisp, 1, 1); + x0 = GET_REG_FIELD(__GXData->cpDispSrc, 10, 0); + dx = GET_REG_FIELD(__GXData->cpDispSize, 10, 0) + 1; + y0 = GET_REG_FIELD(__GXData->cpDispSrc, 10, 10); + dy = GET_REG_FIELD(__GXData->cpDispSize, 10, 10) + 1; + + ASSERTMSGLINE(1772, clmpT || y0 != 0, "GXCopy: Have to set GX_CLAMP_TOP if source top == 0"); + ASSERTMSGLINE(1774, clmpB || y0 + dy <= 528, "GXCopy: Have to set GX_CLAMP_BOTTOM if source bottom > 528"); + ASSERTMSGLINE(1779, (__GXData->peCtrl & 7) != 3 || clear == 0, "GXCopy: Can not do clear while pixel type is Z"); + + if ((u32) (__GXData->peCtrl & 7) == 5) { + ASSERTMSGLINE(1785, clear == 0, "GXCopy: Can not clear YUV framebuffer"); + ASSERTMSGLINE(1787, (x0 & 3) == 0, "GXCopy: Source x is not multiple of 4 for YUV copy"); + ASSERTMSGLINE(1789, (y0 & 3) == 0, "GXCopy: Source y is not multiple of 4 for YUV copy"); + ASSERTMSGLINE(1791, (dx & 3) == 0, "GXCopy: Source width is not multiple of 4 for YUV copy"); + ASSERTMSGLINE(1793, (dy & 3) == 0, "GXCopy: Source height is not multiple of 4 for YUV copy"); + } else { + ASSERTMSGLINE(1797, (x0 & 1) == 0, "GXCopy: Source x is not multiple of 2 for RGB copy"); + ASSERTMSGLINE(1799, (y0 & 1) == 0, "GXCopy: Source y is not multiple of 2 for RGB copy"); + ASSERTMSGLINE(1801, (dx & 1) == 0, "GXCopy: Source width is not multiple of 2 for RGB copy"); + ASSERTMSGLINE(1803, (dy & 1) == 0, "GXCopy: Source height is not multiple of 2 for RGB copy"); + } + + ASSERTMSGLINE(1807, ((u32)dest & 0x1F) == 0, "GXCopy: Display destination address not 32B aligned"); +} +#endif + +void GXCopyDisp(void* dest, GXBool clear) { + u32 reg; + u32 tempPeCtrl; + u32 phyAddr; + u8 changePeCtrl; + + CHECK_GXBEGIN(1833, "GXCopyDisp"); + +#if DEBUG + __GXVerifCopy(dest, clear); +#endif + + if (clear) { + reg = __GXData->zmode; + SET_REG_FIELD(0, reg, 1, 0, 1); + SET_REG_FIELD(0, reg, 3, 1, 7); + GX_WRITE_RAS_REG(reg); + + reg = __GXData->cmode0; + SET_REG_FIELD(0, reg, 1, 0, 0); + SET_REG_FIELD(0, reg, 1, 1, 0); + GX_WRITE_RAS_REG(reg); + } + + changePeCtrl = FALSE; + + if ((clear || (u32)GET_REG_FIELD(__GXData->peCtrl, 3, 0) == 3) && (u32)GET_REG_FIELD(__GXData->peCtrl, 1, 6) == 1) { + changePeCtrl = TRUE; + tempPeCtrl = __GXData->peCtrl; + SET_REG_FIELD(0, tempPeCtrl, 1, 6, 0); + GX_WRITE_RAS_REG(tempPeCtrl); + } + + GX_WRITE_RAS_REG(__GXData->cpDispSrc); + GX_WRITE_RAS_REG(__GXData->cpDispSize); + GX_WRITE_RAS_REG(__GXData->cpDispStride); + + phyAddr = (u32)dest & 0x3FFFFFFF; + reg = 0; + SET_REG_FIELD(1872, reg, 21, 0, phyAddr >> 5); + SET_REG_FIELD(1876, reg, 8, 24, 0x4B); + GX_WRITE_RAS_REG(reg); + + SET_REG_FIELD(1876, __GXData->cpDisp, 1, 11, clear); + SET_REG_FIELD(1876, __GXData->cpDisp, 1, 14, 1); + SET_REG_FIELD(1876, __GXData->cpDisp, 8, 24, 0x52); + GX_WRITE_RAS_REG(__GXData->cpDisp); + + if (clear) { + GX_WRITE_RAS_REG(__GXData->zmode); + GX_WRITE_RAS_REG(__GXData->cmode0); + } + + if (changePeCtrl) { + GX_WRITE_RAS_REG(__GXData->peCtrl); + } __GXData->bpSentNot = 0; } -/* 8035D0E8-8035D2F0 357A28 0208+00 0/0 4/4 0/0 .text GXSetCopyFilter */ -void GXSetCopyFilter(GXBool useAA, u8 samplePattern[12][2], GXBool doVertFilt, u8 vFilt[7]) { - u32 vals[4]; - u32 unk1; - u32 unk2; - - if (useAA) { - vals[0] = 0; - GX_SET_REG(vals[0], samplePattern[0][0], 28, 31); - GX_SET_REG(vals[0], samplePattern[0][1], 24, 27); - GX_SET_REG(vals[0], samplePattern[1][0], 20, 23); - GX_SET_REG(vals[0], samplePattern[1][1], 16, 19); - GX_SET_REG(vals[0], samplePattern[2][0], 12, 15); - GX_SET_REG(vals[0], samplePattern[2][1], 8, 11); - GX_SET_REG(vals[0], 1, 0, 7); - - vals[1] = 0; - GX_SET_REG(vals[1], samplePattern[3][0], 28, 31); - GX_SET_REG(vals[1], samplePattern[3][1], 24, 27); - GX_SET_REG(vals[1], samplePattern[4][0], 20, 23); - GX_SET_REG(vals[1], samplePattern[4][1], 16, 19); - GX_SET_REG(vals[1], samplePattern[5][0], 12, 15); - GX_SET_REG(vals[1], samplePattern[5][1], 8, 11); - GX_SET_REG(vals[1], 2, 0, 7); - - vals[2] = 0; - GX_SET_REG(vals[2], samplePattern[6][0], 28, 31); - GX_SET_REG(vals[2], samplePattern[6][1], 24, 27); - GX_SET_REG(vals[2], samplePattern[7][0], 20, 23); - GX_SET_REG(vals[2], samplePattern[7][1], 16, 19); - GX_SET_REG(vals[2], samplePattern[8][0], 12, 15); - GX_SET_REG(vals[2], samplePattern[8][1], 8, 11); - GX_SET_REG(vals[2], 3, 0, 7); - - vals[3] = 0; - GX_SET_REG(vals[3], samplePattern[9][0], 28, 31); - GX_SET_REG(vals[3], samplePattern[9][1], 24, 27); - GX_SET_REG(vals[3], samplePattern[10][0], 20, 23); - GX_SET_REG(vals[3], samplePattern[10][1], 16, 19); - GX_SET_REG(vals[3], samplePattern[11][0], 12, 15); - GX_SET_REG(vals[3], samplePattern[11][1], 8, 11); - GX_SET_REG(vals[3], 4, 0, 7); - } else { - vals[0] = 0x01666666; - vals[1] = 0x02666666; - vals[2] = 0x03666666; - vals[3] = 0x04666666; - } - - GX_BP_LOAD_REG(vals[0]); - GX_BP_LOAD_REG(vals[1]); - GX_BP_LOAD_REG(vals[2]); - GX_BP_LOAD_REG(vals[3]); - - unk1 = 0; - GX_SET_REG(unk1, 0x53, 0, 7); - unk2 = 0; - GX_SET_REG(unk2, 0x54, 0, 7); - - if (doVertFilt) { - GX_SET_REG(unk1, vFilt[0], 26, 31); - GX_SET_REG(unk1, vFilt[1], 20, 25); - GX_SET_REG(unk1, vFilt[2], 14, 19); - GX_SET_REG(unk1, vFilt[3], 8, 13); - GX_SET_REG(unk2, vFilt[4], 26, 31); - GX_SET_REG(unk2, vFilt[5], 20, 25); - GX_SET_REG(unk2, vFilt[6], 14, 19); - - } else { - GX_SET_REG(unk1, 0, 26, 31); - GX_SET_REG(unk1, 0, 20, 25); - GX_SET_REG(unk1, 21, 14, 19); - GX_SET_REG(unk1, 22, 8, 13); - GX_SET_REG(unk2, 21, 26, 31); - GX_SET_REG(unk2, 0, 20, 25); - GX_SET_REG(unk2, 0, 14, 19); - } - - GX_BP_LOAD_REG(unk1); - GX_BP_LOAD_REG(unk2); - - __GXData->bpSentNot = GX_FALSE; -} - -/* 8035D2F0-8035D304 357C30 0014+00 0/0 2/2 0/0 .text GXSetDispCopyGamma */ -void GXSetDispCopyGamma(GXGamma gamma) { - GX_BITFIELD_SET(__GXData->cpDisp, 23, 2, gamma); -} - -/* 8035D304-8035D46C 357C44 0168+00 0/0 3/3 0/0 .text GXCopyDisp */ -void GXCopyDisp(void* dest, GXBool doClear) { +void GXCopyTex(void* dest, GXBool clear) { u32 reg; - u32 newDest; - GXBool check; + u32 tempPeCtrl; + u32 phyAddr; + u8 changePeCtrl; - if (doClear) { + CHECK_GXBEGIN(1916, "GXCopyTex"); + +#if DEBUG + __GXVerifCopy(dest, clear); +#endif + if (clear) { reg = __GXData->zmode; - GX_SET_REG(reg, 1, 31, 31); - GX_SET_REG(reg, 7, 28, 30); - GX_BP_LOAD_REG(reg); + SET_REG_FIELD(0, reg, 1, 0, 1); + SET_REG_FIELD(0, reg, 3, 1, 7); + GX_WRITE_RAS_REG(reg); reg = __GXData->cmode0; - GX_SET_REG(reg, 0, 31, 31); - GX_SET_REG(reg, 0, 30, 30); - GX_BP_LOAD_REG(reg); + SET_REG_FIELD(0, reg, 1, 0, 0); + SET_REG_FIELD(0, reg, 1, 1, 0); + GX_WRITE_RAS_REG(reg); } - check = GX_FALSE; - if ((doClear || (__GXData->peCtrl & 0x7) == 3) && (__GXData->peCtrl >> 6 & 0x1) == 1) { - check = GX_TRUE; - reg = __GXData->peCtrl; - GX_SET_REG(reg, 0, 25, 25); - GX_BP_LOAD_REG(reg); + changePeCtrl = 0; + tempPeCtrl = __GXData->peCtrl; + + if (__GXData->cpTexZ && ((tempPeCtrl & 7) != 3)) { + changePeCtrl = 1; + SET_REG_FIELD(0, tempPeCtrl, 3, 0, 3); } - GX_BP_LOAD_REG(__GXData->cpDispSrc); - GX_BP_LOAD_REG(__GXData->cpDispSize); - GX_BP_LOAD_REG(__GXData->cpDispStride); + if ((clear || ((u32) (tempPeCtrl & 7) == 3)) && ((u32) ((tempPeCtrl >> 6) & 1) == 1)) { + changePeCtrl = 1; + SET_REG_FIELD(0, tempPeCtrl, 1, 6, 0); + } - newDest = (u32)dest & 0x3FFFFFFF; + if (changePeCtrl) { + GX_WRITE_RAS_REG(tempPeCtrl); + } + + GX_WRITE_RAS_REG(__GXData->cpTexSrc); + GX_WRITE_RAS_REG(__GXData->cpTexSize); + GX_WRITE_RAS_REG(__GXData->cpTexStride); + + phyAddr = (u32)dest & 0x3FFFFFFF; reg = 0; - GX_SET_REG(reg, newDest >> 5, 11, 31); - GX_SET_REG(reg, 0x4B, 0, 7); - GX_BP_LOAD_REG(reg); + SET_REG_FIELD(1965, reg, 21, 0, phyAddr >> 5); + SET_REG_FIELD(1965, reg, 8, 24, 0x4B); + GX_WRITE_RAS_REG(reg); - GX_SET_REG(__GXData->cpDisp, doClear, 20, 20); - GX_SET_REG(__GXData->cpDisp, 1, 17, 17); - GX_SET_REG(__GXData->cpDisp, 0x52, 0, 7); - GX_BP_LOAD_REG(__GXData->cpDisp); + SET_REG_FIELD(1969, __GXData->cpTex, 1, 11, clear); + SET_REG_FIELD(1969, __GXData->cpTex, 1, 14, 0); + SET_REG_FIELD(1969, __GXData->cpTex, 8, 24, 0x52); + GX_WRITE_RAS_REG(__GXData->cpTex); - if (doClear) { - GX_BP_LOAD_REG(__GXData->zmode); - GX_BP_LOAD_REG(__GXData->cmode0); + if (clear) { + GX_WRITE_RAS_REG(__GXData->zmode); + GX_WRITE_RAS_REG(__GXData->cmode0); } - if (check) { - GX_BP_LOAD_REG(__GXData->peCtrl); + if (changePeCtrl) { + GX_WRITE_RAS_REG(__GXData->peCtrl); } - __GXData->bpSentNot = GX_FALSE; + __GXData->bpSentNot = 0; } -/* 8035D46C-8035D5F8 357DAC 018C+00 0/0 9/9 0/0 .text GXCopyTex */ -void GXCopyTex(void* dest, GXBool doClear) { - u32 reg; - u32 reg2; - u32 newDest; - GXBool check; - - if (doClear) { - reg = __GXData->zmode; - GX_SET_REG(reg, 1, 31, 31); - GX_SET_REG(reg, 7, 28, 30); - GX_BP_LOAD_REG(reg); - - reg = __GXData->cmode0; - GX_SET_REG(reg, 0, 31, 31); - GX_SET_REG(reg, 0, 30, 30); - GX_BP_LOAD_REG(reg); - } - - check = GX_FALSE; - reg2 = __GXData->peCtrl; - if (__GXData->cpTexZ && (reg2 & 0x7) != 3) { - check = GX_TRUE; - GX_SET_REG(reg2, 3, 29, 31); - } - - if ((doClear || (reg2 & 0x7) == 3) && (reg2 >> 6 & 0x1) == 1) { - check = GX_TRUE; - GX_SET_REG(reg2, 0, 25, 25); - } - - if (check) { - GX_BP_LOAD_REG(reg2); - } - - GX_BP_LOAD_REG(__GXData->cpTexSrc); - GX_BP_LOAD_REG(__GXData->cpTexSize); - GX_BP_LOAD_REG(__GXData->cpTexStride); - - newDest = (u32)dest & 0x3FFFFFFF; - reg = 0; - GX_SET_REG(reg, newDest >> 5, 11, 31); - GX_SET_REG(reg, 0x4B, 0, 7); - GX_BP_LOAD_REG(reg); - - GX_SET_REG(__GXData->cpTex, doClear, 20, 20); - GX_SET_REG(__GXData->cpTex, 0, 17, 17); - GX_SET_REG(__GXData->cpTex, 0x52, 0, 7); - GX_BP_LOAD_REG(__GXData->cpTex); - - if (doClear) { - GX_BP_LOAD_REG(__GXData->zmode); - GX_BP_LOAD_REG(__GXData->cmode0); - } - - if (check) { - GX_BP_LOAD_REG(__GXData->peCtrl); - } - - __GXData->bpSentNot = GX_FALSE; -} - -/* 8035D5F8-8035D630 357F38 0038+00 0/0 1/1 0/0 .text GXClearBoundingBox */ void GXClearBoundingBox(void) { - GXWGFifo.u8 = GX_LOAD_BP_REG; - GXWGFifo.u32 = 0x550003FF; - GXWGFifo.u8 = GX_LOAD_BP_REG; - GXWGFifo.u32 = 0x560003FF; - set_x2(GX_FALSE); + u32 reg; + + CHECK_GXBEGIN(2003, "GXClearBoundingBox"); + reg = 0x550003FF; + GX_WRITE_RAS_REG(reg); + reg = 0x560003FF; + GX_WRITE_RAS_REG(reg); + __GXData->bpSentNot = 0; +} + +void GXReadBoundingBox(u16* left, u16* top, u16* right, u16* bottom) { + *left = GX_GET_PE_REG(8); + *top = GX_GET_PE_REG(10); + *right = GX_GET_PE_REG(9); + *bottom = GX_GET_PE_REG(11); } diff --git a/src/dolphin/gx/GXGeometry.c b/src/dolphin/gx/GXGeometry.c index 97a396ea3b..b41b70be23 100644 --- a/src/dolphin/gx/GXGeometry.c +++ b/src/dolphin/gx/GXGeometry.c @@ -1,158 +1,156 @@ -/** - * GXGeometry.c - * Description: - */ +#include +#include +#include -#include "dolphin/gx/GXGeometry.h" -#include "dolphin/gx.h" +#include "__gx.h" -/* 8035C6E4-8035C764 357024 0080+00 0/0 4/4 0/0 .text __GXSetDirtyState */ void __GXSetDirtyState(void) { - u32 dirtyFlags = __GXData->dirtyState; + u32 dState = __GXData->dirtyState; - if (dirtyFlags & GX_DIRTY_SU_TEX) { + if (dState & 1) { __GXSetSUTexRegs(); } - - if (dirtyFlags & GX_DIRTY_BP_MASK) { + if (dState & 2) { __GXUpdateBPMask(); } - - if (dirtyFlags & GX_DIRTY_GEN_MODE) { + if (dState & 4) { __GXSetGenMode(); } - - if (dirtyFlags & GX_DIRTY_VCD) { + if (dState & 8) { __GXSetVCD(); } - - if (dirtyFlags & GX_DIRTY_VAT) { + if (dState & 0x10) { __GXSetVAT(); } - - if (dirtyFlags & GX_DIRTY_VLIM) { + if (dState & 0x18) { __GXCalculateVLim(); } __GXData->dirtyState = 0; } -/* 8035C764-8035C834 3570A4 00D0+00 0/0 66/66 3/3 .text GXBegin */ -void GXBegin(GXPrimitive type, GXVtxFmt fmt, u16 vert_num) { - GXData* data = __GXData; - u32 dirtyFlags = data->dirtyState; +void GXBegin(GXPrimitive type, GXVtxFmt vtxfmt, u16 nverts) { + ASSERTMSGLINE(359, vtxfmt < GX_MAX_VTXFMT, "GXBegin: Format Index is out of range"); + ASSERTMSGLINE(360, !__GXinBegin, "GXBegin: called inside another GXBegin/GXEnd"); - if (data->dirtyState != 0) { - if (dirtyFlags & GX_DIRTY_SU_TEX) { - __GXSetSUTexRegs(); - } - - if (dirtyFlags & GX_DIRTY_BP_MASK) { - __GXUpdateBPMask(); - } - - if (dirtyFlags & GX_DIRTY_GEN_MODE) { - __GXSetGenMode(); - } - - if (dirtyFlags & GX_DIRTY_VCD) { - __GXSetVCD(); - } - - if (dirtyFlags & GX_DIRTY_VAT) { - __GXSetVAT(); - } - - if (dirtyFlags & GX_DIRTY_VLIM) { - __GXCalculateVLim(); - } - - __GXData->dirtyState = 0; + if (__GXData->dirtyState != 0) { + __GXSetDirtyState(); } - if (*(u32*)__GXData == 0) { +#if DEBUG + if (!__GXData->inDispList) { + __GXVerifyState(vtxfmt); + } + __GXinBegin = 1; +#endif + + if (*(u32*)&__GXData->vNumNot == 0) { // checks both vNum and bpSentNot __GXSendFlushPrim(); } - - GXWGFifo.u8 = fmt | type; - GXWGFifo.u16 = vert_num; + GX_WRITE_U8(vtxfmt | type); + GX_WRITE_U16(nverts); } -/* 8035C834-8035C8BC 357174 0088+00 1/1 1/1 0/0 .text __GXSendFlushPrim */ void __GXSendFlushPrim(void) { u32 i; - u32 sz = __GXData->vNum * __GXData->vLim; + u32 numD = __GXData->vNum * __GXData->vLim; - GXWGFifo.u8 = 0x98; - GXWGFifo.u16 = __GXData->vNum; - - for (i = 0; i < sz; i += 4) { - GXWGFifo.s32 = 0; + GX_WRITE_U8(0x98); + GX_WRITE_U16(__GXData->vNum); + for (i = 0; i < numD; i += 4) { + GX_WRITE_U32(0); } - __GXData->bpSentNot = 1; } -/* 8035C8BC-8035C8FC 3571FC 0040+00 0/0 8/8 0/0 .text GXSetLineWidth */ -void GXSetLineWidth(u8 width, GXTexOffset offsets) { - GXData* data = __GXData; - - GX_BITFIELD_SET(data->lpSize, 24, 8, width); - GX_BITFIELD_SET(data->lpSize, 13, 3, offsets); - GXWGFifo.u8 = 0x61; - GXWGFifo.u32 = data->lpSize; - data->bpSentNot = 0; -} - -/* 8035C8FC-8035C93C 35723C 0040+00 0/0 5/5 0/0 .text GXSetPointSize */ -void GXSetPointSize(u8 size, GXTexOffset offsets) { - GXData* data = __GXData; - - GX_BITFIELD_SET(data->lpSize, 16, 8, size); - GX_BITFIELD_SET(data->lpSize, 10, 3, offsets); - GXWGFifo.u8 = 0x61; - GXWGFifo.u32 = data->lpSize; - data->bpSentNot = 0; -} - -/* 8035C93C-8035C984 35727C 0048+00 0/0 3/3 0/0 .text GXEnableTexOffsets */ -void GXEnableTexOffsets(GXTexCoordID coord, GXBool line, GXBool point) { - GXData* data = __GXData; - - GX_BITFIELD_SET(data->suTs0[coord], 13, 1, line); - GX_BITFIELD_SET(data->suTs0[coord], 12, 1, point); - GXWGFifo.u8 = 0x61; - GXWGFifo.u32 = data->suTs0[coord]; - data->bpSentNot = 0; -} - -/* 8035C984-8035C9AC 3572C4 0028+00 0/0 33/33 5/5 .text GXSetCullMode */ -void GXSetCullMode(GXCullMode mode) { - GXData* data; - GXCullMode mode2; - data = __GXData; - - mode2 = (mode >> 1) & 1; - GX_BITFIELD_SET(mode2, 30, 1, mode); - - GX_BITFIELD_SET(data->genMode, 16, 2, mode2); - data->dirtyState |= GX_DIRTY_GEN_MODE; -} - -/* 8035C9AC-8035C9E0 3572EC 0034+00 0/0 6/6 0/0 .text GXSetCoPlanar */ -void GXSetCoPlanar(GXBool enable) { - GXData* data = __GXData; - - GX_BITFIELD_SET(data->genMode, 12, 1, enable); - GXWGFifo.u8 = 0x61; - GXWGFifo.u32 = 0xFE080000; - GXWGFifo.u8 = 0x61; - GXWGFifo.u32 = data->genMode; -} - -/* 8035C9E0-8035CA04 357320 0024+00 2/2 0/0 0/0 .text __GXSetGenMode */ -void __GXSetGenMode(void) { - GXWGFifo.u8 = 0x61; - GXWGFifo.u32 = __GXData->genMode; +void GXSetLineWidth(u8 width, GXTexOffset texOffsets) { + CHECK_GXBEGIN(440, "GXSetLineWidth"); + SET_REG_FIELD(441, __GXData->lpSize, 8, 0, width); + SET_REG_FIELD(442, __GXData->lpSize, 3, 16, texOffsets); + GX_WRITE_RAS_REG(__GXData->lpSize); __GXData->bpSentNot = 0; -} \ No newline at end of file +} + +void GXGetLineWidth(u8* width, GXTexOffset* texOffsets) { + ASSERTMSGLINE(463, width != NULL && texOffsets != NULL, "GXGet*: invalid null pointer"); + + *width = GET_REG_FIELD(__GXData->lpSize, 8, 0); + *texOffsets = GET_REG_FIELD(__GXData->lpSize, 3, 16); +} + +void GXSetPointSize(u8 pointSize, GXTexOffset texOffsets) { + CHECK_GXBEGIN(484, "GXSetPointSize"); + SET_REG_FIELD(485, __GXData->lpSize, 8, 8, pointSize); + SET_REG_FIELD(486, __GXData->lpSize, 3, 19, texOffsets); + GX_WRITE_RAS_REG(__GXData->lpSize); + __GXData->bpSentNot = 0; +} + +void GXGetPointSize(u8* pointSize, GXTexOffset* texOffsets) { + ASSERTMSGLINE(507, pointSize != NULL && texOffsets != NULL, "GXGet*: invalid null pointer"); + + *pointSize = (int)GET_REG_FIELD(__GXData->lpSize, 8, 8); + *texOffsets = GET_REG_FIELD(__GXData->lpSize, 3, 19); +} + +void GXEnableTexOffsets(GXTexCoordID coord, u8 line_enable, u8 point_enable) { + CHECK_GXBEGIN(529, "GXEnableTexOffsets"); + + ASSERTMSGLINE(531, coord < GX_MAX_TEXCOORD, "GXEnableTexOffsets: Invalid coordinate Id"); + + SET_REG_FIELD(533, __GXData->suTs0[coord], 1, 18, line_enable); + SET_REG_FIELD(534, __GXData->suTs0[coord], 1, 19, point_enable); + GX_WRITE_RAS_REG(__GXData->suTs0[coord]); + __GXData->bpSentNot = 0; +} + +void GXSetCullMode(GXCullMode mode) { + GXCullMode hwMode; + + CHECK_GXBEGIN(557, "GXSetCullMode"); +#if DEBUG + switch (mode) { + case GX_CULL_FRONT: hwMode = GX_CULL_BACK; break; + case GX_CULL_BACK: hwMode = GX_CULL_FRONT; break; + default: hwMode = mode; break; + } +#else + hwMode = (mode >> 1) & 1; + __rlwimi(hwMode, mode, 1, 30, 30); +#endif + + SET_REG_FIELD(570, __GXData->genMode, 2, 14, hwMode); + __GXData->dirtyState |= 4; +} + +void GXGetCullMode(GXCullMode* mode) { +#if DEBUG + GXCullMode hwMode = GET_REG_FIELD(__GXData->genMode, 2, 14); + + switch (hwMode) { + case GX_CULL_FRONT: *mode = GX_CULL_BACK; break; + case GX_CULL_BACK: *mode = GX_CULL_FRONT; break; + default: *mode = hwMode; break; + } +#else + // fake match? + GXCullMode hwMode = __GXData->genMode; + *mode = ((hwMode >> 0xD) & 0x2) | (((((int)hwMode >> 0xE) & 0x2) >> 0x1)); +#endif +} + +void GXSetCoPlanar(GXBool enable) { + u32 reg; + + CHECK_GXBEGIN(613, "GXSetCoPlanar"); + + SET_REG_FIELD(615, __GXData->genMode, 1, 19, enable); + reg = 0xFE080000; + GX_WRITE_RAS_REG(reg); + GX_WRITE_RAS_REG(__GXData->genMode); +} + +void __GXSetGenMode(void) { + GX_WRITE_RAS_REG(__GXData->genMode); + __GXData->bpSentNot = 0; +} diff --git a/src/dolphin/gx/GXInit.c b/src/dolphin/gx/GXInit.c index e0deaf9612..02fba28223 100644 --- a/src/dolphin/gx/GXInit.c +++ b/src/dolphin/gx/GXInit.c @@ -1,106 +1,168 @@ -#include "dolphin/gx.h" -#include "dolphin/os.h" -#include "dolphin/vi.h" +#include -char* __GXVersion = "<< Dolphin SDK - GX release build: Nov 10 2004 06:27:12 (0x2301) >>"; +#include +#include +#include +#include + +#include "__gx.h" + +#if SDK_REVISION < 2 +#define BUILD_DATE "Apr 5 2004" +#define DBUILD_TIME "03:55:13" +#define RBUILD_TIME "04:13:58" +#else +#define BUILD_DATE "Nov 10 2004" +#define DBUILD_TIME "06:08:50" +#define RBUILD_TIME "06:27:12" +#endif + +#ifdef DEBUG +const char* __GXVersion = "<< Dolphin SDK - GX\tdebug build: "BUILD_DATE" "DBUILD_TIME" (0x2301) >>"; +#else +const char* __GXVersion = "<< Dolphin SDK - GX\trelease build: "BUILD_DATE" "RBUILD_TIME" (0x2301) >>"; +#endif -/* 8044CE00-8044CE80 079B20 0080+00 1/1 0/0 0/0 .bss FifoObj */ static GXFifoObj FifoObj; -/* 8044CE80-8044D430 079BA0 05B0+00 1/0 0/0 0/0 .bss gxData */ static GXData gxData; - -/* 80456580-80456584 -00001 0004+00 6/6 108/108 0/0 .sdata2 __GXData */ GXData* const __GXData = &gxData; -/* 8035921C-80359318 353B5C 00FC+00 1/1 0/0 0/0 .text __GXDefaultTexRegionCallback */ -GXTexRegion* __GXDefaultTexRegionCallback(const GXTexObj* obj, GXTexMapID id) { - GXTexFmt format; // r31 - GXBool isMipMap; // r3 +// these are supposed to be in-function static, but it messed up sbss order +u32 resetFuncRegistered; +u32 calledOnce; +OSTime time; +u32 peCount; - format = GXGetTexObjFmt(obj); - isMipMap = GXGetTexObjMipMap(obj); +void* __memReg; +void* __peReg; +void* __cpReg; +void* __piReg; + +#if DEBUG +GXBool __GXinBegin; +#endif + +static u16 DefaultTexData[] __attribute__((aligned(32))) = { + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, +}; + +static GXVtxAttrFmtList GXDefaultVATList[] = { + {GX_VA_POS, GX_POS_XYZ, GX_F32, 0}, + {GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0}, + {GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0}, + {GX_VA_CLR1, GX_CLR_RGBA, GX_RGBA8, 0}, + {GX_VA_TEX0, GX_TEX_ST, GX_F32, 0}, + {GX_VA_TEX1, GX_TEX_ST, GX_F32, 0}, + {GX_VA_TEX2, GX_TEX_ST, GX_F32, 0}, + {GX_VA_TEX3, GX_TEX_ST, GX_F32, 0}, + {GX_VA_TEX4, GX_TEX_ST, GX_F32, 0}, + {GX_VA_TEX5, GX_TEX_ST, GX_F32, 0}, + {GX_VA_TEX6, GX_TEX_ST, GX_F32, 0}, + {GX_VA_TEX7, GX_TEX_ST, GX_F32, 0}, + {GX_VA_NULL, 0, 0, 0}, +}; + +static f32 GXDefaultProjData[] = {1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -2.0f, 0.0f}; + +static u32 GXTexRegionAddrTable[] = { + 0x00000, 0x10000, 0x20000, 0x30000, 0x40000, 0x50000, 0x60000, 0x70000, 0x08000, 0x18000, + 0x28000, 0x38000, 0x48000, 0x58000, 0x68000, 0x78000, 0x00000, 0x90000, 0x20000, 0xB0000, + 0x40000, 0x98000, 0x60000, 0xB8000, 0x80000, 0x10000, 0xA0000, 0x30000, 0x88000, 0x50000, + 0xA8000, 0x70000, 0x00000, 0x90000, 0x20000, 0xB0000, 0x40000, 0x90000, 0x60000, 0xB0000, + 0x80000, 0x10000, 0xA0000, 0x30000, 0x80000, 0x50000, 0xA0000, 0x70000, +}; + +// prototypes +static int __GXShutdown(int final); + +static OSResetFunctionInfo GXResetFuncInfo = {__GXShutdown, 0x7F, NULL, NULL}; + +asm BOOL IsWriteGatherBufferEmpty(void) { + sync + mfspr r3, WPAR + andi. r3, r3, 1 +} + +static void EnableWriteGatherPipe(void) { + u32 hid2 = PPCMfhid2(); + + PPCMtwpar(OSUncachedToPhysical((void*)GXFIFO_ADDR)); + hid2 |= 0x40000000; + PPCMthid2(hid2); +} + +static void DisableWriteGatherPipe(void) { + u32 hid2 = PPCMfhid2(); + + hid2 &= ~0x40000000; + PPCMthid2(hid2); +} + +static GXTexRegion*__GXDefaultTexRegionCallback(const GXTexObj* t_obj, GXTexMapID id) { + GXTexFmt fmt; + u8 mm; + + fmt = GXGetTexObjFmt(t_obj); + mm = GXGetTexObjMipMap(t_obj); id = (GXTexMapID)(id % GX_MAX_TEXMAP); - switch (format) { + switch (fmt) { case GX_TF_RGBA8: - if (isMipMap) { + if (mm) { return &__GXData->TexRegions2[id]; } return &__GXData->TexRegions1[id]; - case GX_TF_C4: case GX_TF_C8: case GX_TF_C14X2: return &__GXData->TexRegions0[id]; - default: - if (isMipMap) { + if (mm) { return &__GXData->TexRegions1[id]; } return &__GXData->TexRegions0[id]; } } -/* 80359318-8035933C 353C58 0024+00 1/1 0/0 0/0 .text __GXDefaultTlutRegionCallback */ -GXTlutRegion* __GXDefaultTlutRegionCallback(u32 tlut) { - if (tlut >= 0x14) { +static GXTlutRegion* __GXDefaultTlutRegionCallback(u32 idx) { + if (idx >= 20) { return NULL; - } else { - return &__GXData->TlutRegions[tlut]; } + return &__GXData->TlutRegions[idx]; } -/* 80451944-80451948 000E44 0004+00 1/1 0/0 0/0 .sbss resetFuncRegistered$145 */ -u32 resetFuncRegistered; +#if DEBUG +static void __GXDefaultVerifyCallback(GXWarningLevel level, u32 id, const char* msg) { + OSReport("Level %1d, Warning %3d: %s\n", level, id, msg); +} +#endif -/* 80451940-80451944 000E40 0004+00 1/1 0/0 0/0 .sbss calledOnce$37 */ -u32 calledOnce; - -/* 80451938-8045193C 000E38 0004+00 1/1 0/0 0/0 .sbss time$36 */ -OSTime time; - -/* 80451930-80451938 000E30 0004+04 1/1 0/0 0/0 .sbss peCount$35 */ -u32 peCount; - -/* 8045192C-80451930 000E2C 0004+00 2/2 2/2 0/0 .sbss __memReg */ -vu16* __memReg; - -/* 80451928-8045192C 000E28 0004+00 1/1 11/11 0/0 .sbss __peReg */ -u16* __peReg; - -/* 80451924-80451928 000E24 0004+00 2/2 12/12 0/0 .sbss __cpReg */ -u16* __cpReg; - -/* ############################################################################################## */ -/* 80451920-80451924 000E20 0004+00 1/1 2/2 0/0 .sbss __piReg */ -u32* __piReg; - -/* 8035933C-803594CC 353C7C 0190+00 1/0 0/0 0/0 .text __GXShutdown */ -BOOL __GXShutdown(BOOL final) { - u32 val; - u32 newPeCount; - OSTime newTime; +static int __GXShutdown(BOOL final) { + u32 reg; + u32 peCountNew; + OSTime timeNew; if (!final) { if (!calledOnce) { - peCount = GXReadMEMReg(0x28, 0x27); + peCount = __GXReadMEMCounterU32(0x28, 0x27); time = OSGetTime(); calledOnce = 1; - return FALSE; + return 0; } - newTime = OSGetTime(); - newPeCount = GXReadMEMReg(0x28, 0x27); + timeNew = OSGetTime(); + peCountNew = __GXReadMEMCounterU32(0x28, 0x27); - if (newTime - time < 10) { - return FALSE; + if (timeNew - time < 10) { + return 0; } - if (newPeCount != peCount) { - peCount = newPeCount; - time = newTime; - return FALSE; + if (peCountNew != peCount) { + peCount = peCountNew; + time = timeNew; + return 0; } } else { @@ -119,129 +181,92 @@ BOOL __GXShutdown(BOOL final) { PPCSync(); - GX_SET_CP_REG(1, 0); - GX_SET_CP_REG(2, 3); + reg = 0; + GX_SET_CP_REG(1, reg); - __GXData->abtWaitPECopy = GX_TRUE; + reg = 3; + GX_SET_CP_REG(2, reg); + + __GXData->abtWaitPECopy = 1; __GXAbort(); } - return TRUE; + return 1; } -/* 803594CC-80359670 353E0C 01A4+00 1/1 1/1 0/0 .text __GXInitRevisionBits */ +#define SOME_SET_REG_MACRO(reg, size, shift, val) \ + do { \ + (reg) = (u32)__rlwimi((u32)(reg), (val), (shift), (32 - (shift) - (size)), (31 - (shift))); \ + } while (0); + void __GXInitRevisionBits(void) { u32 i; + for (i = 0; i < 8; i++) { - FAST_FLAG_SET(__GXData->vatA[i], 1, 30, 33); - FAST_FLAG_SET(__GXData->vatB[i], 1, 31, 33); + s32 regAddr; + SOME_SET_REG_MACRO(__GXData->vatA[i], 1, 30, 1); + SOME_SET_REG_MACRO(__GXData->vatB[i], 1, 31, 1); GX_WRITE_U8(0x8); GX_WRITE_U8(i | 0x80); GX_WRITE_U32(__GXData->vatB[i]); + regAddr = i - 12; } { u32 reg1 = 0; u32 reg2 = 0; - FAST_FLAG_SET(reg1, 1, 0, 1); - FAST_FLAG_SET(reg1, 1, 1, 1); - FAST_FLAG_SET(reg1, 1, 2, 1); - FAST_FLAG_SET(reg1, 1, 3, 1); - FAST_FLAG_SET(reg1, 1, 4, 1); - FAST_FLAG_SET(reg1, 1, 5, 1); - GX_WRITE_U8(0x10); - GX_WRITE_U32(0x1000); - GX_WRITE_U32(reg1); + SOME_SET_REG_MACRO(reg1, 1, 0, 1); + SOME_SET_REG_MACRO(reg1, 1, 1, 1); + SOME_SET_REG_MACRO(reg1, 1, 2, 1); + SOME_SET_REG_MACRO(reg1, 1, 3, 1); + SOME_SET_REG_MACRO(reg1, 1, 4, 1); + SOME_SET_REG_MACRO(reg1, 1, 5, 1); + GX_WRITE_XF_REG(0, reg1); - FAST_FLAG_SET(reg2, 1, 0, 1); - GX_WRITE_U8(0x10); - GX_WRITE_U32(0x1012); - GX_WRITE_U32(reg2); + SOME_SET_REG_MACRO(reg2, 1, 0, 1); + GX_WRITE_XF_REG(0x12, reg2); +#if DEBUG + __gxVerif->xfRegsDirty[0] = 0; +#endif } { u32 reg = 0; - FAST_FLAG_SET(reg, 1, 0, 1); - FAST_FLAG_SET(reg, 1, 1, 1); - FAST_FLAG_SET(reg, 1, 2, 1); - FAST_FLAG_SET(reg, 1, 3, 1); - FAST_FLAG_SET(reg, 0x58, 24, 8); - GX_WRITE_U8(0x61); - GX_WRITE_U32(reg); + SOME_SET_REG_MACRO(reg, 1, 0, 1); + SOME_SET_REG_MACRO(reg, 1, 1, 1); + SOME_SET_REG_MACRO(reg, 1, 2, 1); + SOME_SET_REG_MACRO(reg, 1, 3, 1); + SOME_SET_REG_MACRO(reg, 8, 24, 0x58); + GX_WRITE_RAS_REG(reg); } } -/* 803D20A0-803D20C0 02F1C0 0020+00 0/1 0/0 0/0 .data DefaultTexData */ -static u16 DefaultTexData[] ALIGN_DECL(32) = { - 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, - 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, -}; - -/* 803D20C0-803D2190 02F1E0 00D0+00 0/1 0/0 0/0 .data GXDefaultVATList */ -static GXVtxAttrFmtList GXDefaultVATList[] = { - {GX_VA_POS, GX_POS_XYZ, GX_F32, 0}, - {GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0}, - {GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0}, - {GX_VA_CLR1, GX_CLR_RGBA, GX_RGBA8, 0}, - {GX_VA_TEX0, GX_TEX_ST, GX_F32, 0}, - {GX_VA_TEX1, GX_TEX_ST, GX_F32, 0}, - {GX_VA_TEX2, GX_TEX_ST, GX_F32, 0}, - {GX_VA_TEX3, GX_TEX_ST, GX_F32, 0}, - {GX_VA_TEX4, GX_TEX_ST, GX_F32, 0}, - {GX_VA_TEX5, GX_TEX_ST, GX_F32, 0}, - {GX_VA_TEX6, GX_TEX_ST, GX_F32, 0}, - {GX_VA_TEX7, GX_TEX_ST, GX_F32, 0}, - {GX_VA_NULL, GX_COMPCNT_NULL, GX_COMP_NULL, 0}, -}; - -/* 803D2190-803D21AC 02F2B0 001C+00 0/1 0/0 0/0 .data GXDefaultProjData */ -static f32 GXDefaultProjData[] = {1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -2.0f, 0.0f}; - -/* 803D21AC-803D226C 02F2CC 00C0+00 1/1 0/0 0/0 .data GXTexRegionAddrTable */ -static u32 GXTexRegionAddrTable[] = { - 0x00000, 0x10000, 0x20000, 0x30000, 0x40000, 0x50000, 0x60000, 0x70000, 0x08000, 0x18000, - 0x28000, 0x38000, 0x48000, 0x58000, 0x68000, 0x78000, 0x00000, 0x90000, 0x20000, 0xB0000, - 0x40000, 0x98000, 0x60000, 0xB8000, 0x80000, 0x10000, 0xA0000, 0x30000, 0x88000, 0x50000, - 0xA8000, 0x70000, 0x00000, 0x90000, 0x20000, 0xB0000, 0x40000, 0x90000, 0x60000, 0xB0000, - 0x80000, 0x10000, 0xA0000, 0x30000, 0x80000, 0x50000, 0xA0000, 0x70000, -}; - -/* 803D226C-803D2280 -00001 0010+04 1/1 0/0 0/0 .data GXResetFuncInfo */ -static OSResetFunctionInfo GXResetFuncInfo = {__GXShutdown, OS_RESET_PRIO_GX}; - -/* 80359670-80359C70 353FB0 0600+00 0/0 2/2 0/0 .text GXInit */ -static void EnableWriteGatherPipe() { - u32 hid2; // r31 - hid2 = PPCMfhid2(); - PPCMtwpar(OSUncachedToPhysical((void*)GXFIFO_ADDR)); - hid2 |= 0x40000000; - PPCMthid2(hid2); -} - GXFifoObj* GXInit(void* base, u32 size) { u32 i; - u32 pad2; // for stack matching + u32 reg; + u32 freqBase; OSRegisterVersion(__GXVersion); - __GXData->inDispList = GX_FALSE; - __GXData->dlSaveContext = GX_TRUE; - __GXData->abtWaitPECopy = GX_TRUE; - - __GXData->tcsManEnab = 0; - __GXData->tevTcEnab = 0; + __GXData->inDispList = FALSE; + __GXData->dlSaveContext = TRUE; + __GXData->abtWaitPECopy = 1; +#if DEBUG + __GXinBegin = FALSE; +#endif + __GXData->tcsManEnab = FALSE; + __GXData->tevTcEnab = FALSE; + GXSetMisc(GX_MT_XF_FLUSH, 0); - __piReg = (void*)OSPhysicalToUncached(GX_PI_ADDR); - __cpReg = (void*)OSPhysicalToUncached(GX_CP_ADDR); - __peReg = (void*)OSPhysicalToUncached(GX_PE_ADDR); - __memReg = (void*)OSPhysicalToUncached(GX_MEM_ADDR); - + __piReg = OSPhysicalToUncached(0xC003000); + __cpReg = OSPhysicalToUncached(0xC000000); + __peReg = OSPhysicalToUncached(0xC001000); + __memReg = OSPhysicalToUncached(0xC004000); __GXFifoInit(); - GXInitFifoBase(&FifoObj, base, size); GXSetCPUFifo(&FifoObj); GXSetGPFifo(&FifoObj); @@ -255,77 +280,70 @@ GXFifoObj* GXInit(void* base, u32 size) { EnableWriteGatherPipe(); __GXData->genMode = 0; - FAST_FLAG_SET(__GXData->genMode, 0, 24, 8); - + SET_REG_FIELD(0, __GXData->genMode, 8, 24, 0); __GXData->bpMask = 255; - FAST_FLAG_SET(__GXData->bpMask, 0xF, 24, 8); - + SET_REG_FIELD(0, __GXData->bpMask, 8, 24, 0x0F); __GXData->lpSize = 0; - FAST_FLAG_SET(__GXData->lpSize, 34, 24, 8); + SET_REG_FIELD(0, __GXData->lpSize, 8, 24, 0x22); - for (i = 0; i < GX_MAX_TEVSTAGE; i++) { + for (i = 0; i < 16; ++i) { __GXData->tevc[i] = 0; __GXData->teva[i] = 0; __GXData->tref[i / 2] = 0; __GXData->texmapId[i] = GX_TEXMAP_NULL; - - FAST_FLAG_SET(__GXData->tevc[i], 0xC0 + i * 2, 24, 8); - FAST_FLAG_SET(__GXData->teva[i], 0xC1 + i * 2, 24, 8); - FAST_FLAG_SET(__GXData->tevKsel[i / 2], 0xF6 + i / 2, 24, 8); - FAST_FLAG_SET(__GXData->tref[i / 2], 0x28 + i / 2, 24, 8); + SET_REG_FIELD(1130, __GXData->tevc[i], 8, 24, 0xC0 + i * 2); + SET_REG_FIELD(1131, __GXData->teva[i], 8, 24, 0xC1 + i * 2); + SET_REG_FIELD(1133, __GXData->tevKsel[i / 2], 8, 24, 0xF6 + i / 2); + SET_REG_FIELD(1135, __GXData->tref[i / 2], 8, 24, 0x28 + i / 2); } __GXData->iref = 0; - FAST_FLAG_SET(__GXData->iref, 0x27, 24, 8); + SET_REG_FIELD(0, __GXData->iref, 8, 24, 0x27); - for (i = 0; i < GX_MAXCOORD; i++) { + for (i = 0; i < 8; ++i) { __GXData->suTs0[i] = 0; __GXData->suTs1[i] = 0; - - FAST_FLAG_SET(__GXData->suTs0[i], 0x30 + i * 2, 24, 8); - FAST_FLAG_SET(__GXData->suTs1[i], 0x31 + i * 2, 24, 8); + SET_REG_FIELD(1144, __GXData->suTs0[i], 8, 24, 0x30 + i * 2); + SET_REG_FIELD(1145, __GXData->suTs1[i], 8, 24, 0x31 + i * 2); } - FAST_FLAG_SET(__GXData->suScis0, 0x20, 24, 8); - FAST_FLAG_SET(__GXData->suScis1, 0x21, 24, 8); - - FAST_FLAG_SET(__GXData->cmode0, 0x41, 24, 8); - FAST_FLAG_SET(__GXData->cmode1, 0x42, 24, 8); - - FAST_FLAG_SET(__GXData->zmode, 0x40, 24, 8); - FAST_FLAG_SET(__GXData->peCtrl, 0x43, 24, 8); - - FAST_FLAG_SET(__GXData->cpTex, 0, 7, 2); + SET_REG_FIELD(0, __GXData->suScis0, 8, 24, 0x20); + SET_REG_FIELD(0, __GXData->suScis1, 8, 24, 0x21); + SET_REG_FIELD(0, __GXData->cmode0, 8, 24, 0x41); + SET_REG_FIELD(0, __GXData->cmode1, 8, 24, 0x42); + SET_REG_FIELD(0, __GXData->zmode, 8, 24, 0x40); + SET_REG_FIELD(0, __GXData->peCtrl, 8, 24, 0x43); + SET_REG_FIELD(0, __GXData->cpTex, 2, 7, 0); __GXData->zScale = 1.6777216E7f; __GXData->zOffset = 0.0f; - __GXData->dirtyState = 0; - __GXData->dirtyVAT = 0; + __GXData->dirtyVAT = FALSE; - { - u32 val1; - u32 val2; - - val2 = OS_BUS_CLOCK / 500; - - __GXFlushTextureState(); - - val1 = (val2 / 2048) | 0x69000400; - - GX_WRITE_U8(0x61); - GX_WRITE_U32(val1); - - __GXFlushTextureState(); - - val1 = (val2 / 4224) | 0x46000200; - GX_WRITE_U8(0x61); - GX_WRITE_U32(val1); +#if DEBUG + __gxVerif->verifyLevel = GX_WARN_NONE; + GXSetVerifyCallback((GXVerifyCallback)__GXDefaultVerifyCallback); + for (i = 0; i < 256; i++) { + SET_REG_FIELD(0, __gxVerif->rasRegs[i], 8, 24, 0xFF); } + memset(__gxVerif->xfRegsDirty, 0, 0x50); + memset(__gxVerif->xfMtxDirty, 0, 0x100); + memset(__gxVerif->xfNrmDirty, 0, 0x60); + memset(__gxVerif->xfLightDirty, 0, 0x80); +#endif + + freqBase = __OSBusClock / 500; + __GXFlushTextureState(); + reg = (freqBase >> 11) | 0x400 | 0x69000000; + GX_WRITE_RAS_REG(reg); + + __GXFlushTextureState(); + reg = (freqBase / 0x1080) | 0x200 | 0x46000000; + GX_WRITE_RAS_REG(reg); __GXInitRevisionBits(); - for (i = 0; i < GX_MAX_TEXMAP; i++) { + for (i = 0; i < 8; i++) { GXInitTexCacheRegion(&__GXData->TexRegions0[i], GX_FALSE, GXTexRegionAddrTable[i], GX_TEXCACHE_32K, GXTexRegionAddrTable[i + 8], GX_TEXCACHE_32K); GXInitTexCacheRegion(&__GXData->TexRegions1[i], GX_FALSE, GXTexRegionAddrTable[i + 16], @@ -334,34 +352,41 @@ GXFifoObj* GXInit(void* base, u32 size) { GX_TEXCACHE_32K, GXTexRegionAddrTable[i + 40], GX_TEXCACHE_32K); } - for (i = 0; i < GX_MAX_TLUT; i++) { + for (i = 0; i < 16; i++) { GXInitTlutRegion(&__GXData->TlutRegions[i], 0xC0000 + 0x2000 * i, GX_TLUT_256); } - for (i = 0; i < GX_MAX_BIGTLUT; i++) { + for (i = 0; i < 4; i++) { GXInitTlutRegion(&__GXData->TlutRegions[i + 16], 0xE0000 + 0x8000 * i, GX_TLUT_1K); } - GX_SET_CP_REG(3, 0); + { + u32 reg = 0; +#if DEBUG + s32 regAddr; +#endif + GX_SET_CP_REG(3, reg); - FAST_FLAG_SET(__GXData->perfSel, 0, 4, 4); + SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 0); + GX_WRITE_U8(0x8); + GX_WRITE_U8(0x20); + GX_WRITE_U32(__GXData->perfSel); +#if DEBUG + regAddr = -12; +#endif + + reg = 0; + GX_WRITE_XF_REG(6, reg); + + reg = 0x23000000; + GX_WRITE_RAS_REG(reg); - GX_WRITE_U8(0x8); - GX_WRITE_U8(0x20); - GX_WRITE_U32(__GXData->perfSel); + reg = 0x24000000; + GX_WRITE_RAS_REG(reg); - GX_WRITE_U8(0x10); - GX_WRITE_U32(0x1006); - GX_WRITE_U32(0); - - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x23000000); - - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x24000000); - - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x67000000); + reg = 0x67000000; + GX_WRITE_RAS_REG(reg); + } __GXSetIndirectMask(0); __GXSetTmemConfig(2); @@ -370,127 +395,101 @@ GXFifoObj* GXInit(void* base, u32 size) { return &FifoObj; } -/* 80359C70-8035A5A8 3545B0 0938+00 1/1 0/0 0/0 .text __GXInitGX */ void __GXInitGX(void) { - GXRenderModeObj* renderObj; - GXTexObj texObj; - Mtx ident; - GXColor clearColor = {64, 64, 64, 255}; - GXColor ambColor = {0, 0, 0, 0}; - GXColor matColor = {255, 255, 255, 255}; + GXRenderModeObj* rmode; + GXTexObj tex_obj; + float identity_mtx[3][4]; + GXColor clear = {64, 64, 64, 255}; + GXColor black = {0, 0, 0, 0}; + GXColor white = {255, 255, 255, 255}; u32 i; switch (VIGetTvFormat()) { - case VI_NTSC: - renderObj = &GXNtsc480IntDf; - break; - - case VI_PAL: - renderObj = &GXPal528IntDf; - break; - - case VI_EURGB60: - renderObj = &GXEurgb60Hz480IntDf; - break; - - case VI_MPAL: - renderObj = &GXMpal480IntDf; - break; - + case VI_NTSC: rmode = &GXNtsc480IntDf; break; + case VI_PAL: rmode = &GXPal528IntDf; break; + case VI_EURGB60: rmode = &GXEurgb60Hz480IntDf; break; + case VI_MPAL: rmode = &GXMpal480IntDf; break; default: - renderObj = &GXNtsc480IntDf; + ASSERTMSGLINE(1342, 0, "GXInit: invalid TV format"); + rmode = &GXNtsc480IntDf; break; } - GXSetCopyClear(clearColor, 0xFFFFFF); - - GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); - GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); - GXSetTexCoordGen2(GX_TEXCOORD2, GX_TG_MTX2x4, GX_TG_TEX2, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); - GXSetTexCoordGen2(GX_TEXCOORD3, GX_TG_MTX2x4, GX_TG_TEX3, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); - GXSetTexCoordGen2(GX_TEXCOORD4, GX_TG_MTX2x4, GX_TG_TEX4, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); - GXSetTexCoordGen2(GX_TEXCOORD5, GX_TG_MTX2x4, GX_TG_TEX5, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); - GXSetTexCoordGen2(GX_TEXCOORD6, GX_TG_MTX2x4, GX_TG_TEX6, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); - GXSetTexCoordGen2(GX_TEXCOORD7, GX_TG_MTX2x4, GX_TG_TEX7, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); - + GXSetCopyClear(clear, 0xFFFFFF); + GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3C); + GXSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, 0x3C); + GXSetTexCoordGen(GX_TEXCOORD2, GX_TG_MTX2x4, GX_TG_TEX2, 0x3C); + GXSetTexCoordGen(GX_TEXCOORD3, GX_TG_MTX2x4, GX_TG_TEX3, 0x3C); + GXSetTexCoordGen(GX_TEXCOORD4, GX_TG_MTX2x4, GX_TG_TEX4, 0x3C); + GXSetTexCoordGen(GX_TEXCOORD5, GX_TG_MTX2x4, GX_TG_TEX5, 0x3C); + GXSetTexCoordGen(GX_TEXCOORD6, GX_TG_MTX2x4, GX_TG_TEX6, 0x3C); + GXSetTexCoordGen(GX_TEXCOORD7, GX_TG_MTX2x4, GX_TG_TEX7, 0x3C); GXSetNumTexGens(1); GXClearVtxDesc(); GXInvalidateVtxCache(); for (i = GX_VA_POS; i <= GX_LIGHT_ARRAY; i++) { - GXSetArray((GXAttr)i, __GXData, 0); + GXSetArray(i, __GXData, 0); } - for (i = 0; i < GX_MAX_VTXFMT; i++) { - GXSetVtxAttrFmtv((GXVtxFmt)i, GXDefaultVATList); + for (i = GX_VTXFMT0; i < GX_MAX_VTXFMT; i++) { + GXSetVtxAttrFmtv(i, GXDefaultVATList); } GXSetLineWidth(6, GX_TO_ZERO); GXSetPointSize(6, GX_TO_ZERO); - GXEnableTexOffsets(GX_TEXCOORD0, GX_FALSE, GX_FALSE); - GXEnableTexOffsets(GX_TEXCOORD1, GX_FALSE, GX_FALSE); - GXEnableTexOffsets(GX_TEXCOORD2, GX_FALSE, GX_FALSE); - GXEnableTexOffsets(GX_TEXCOORD3, GX_FALSE, GX_FALSE); - GXEnableTexOffsets(GX_TEXCOORD4, GX_FALSE, GX_FALSE); - GXEnableTexOffsets(GX_TEXCOORD5, GX_FALSE, GX_FALSE); - GXEnableTexOffsets(GX_TEXCOORD6, GX_FALSE, GX_FALSE); - GXEnableTexOffsets(GX_TEXCOORD7, GX_FALSE, GX_FALSE); - - ident[0][0] = 1.0f; - ident[0][1] = 0.0f; - ident[0][2] = 0.0f; - ident[0][3] = 0.0f; - - ident[1][0] = 0.0f; - ident[1][1] = 1.0f; - ident[1][2] = 0.0f; - ident[1][3] = 0.0f; - - ident[2][0] = 0.0f; - ident[2][1] = 0.0f; - ident[2][2] = 1.0f; - ident[2][3] = 0.0f; - - GXLoadPosMtxImm(ident, GX_PNMTX0); - GXLoadNrmMtxImm(ident, GX_PNMTX0); + GXEnableTexOffsets(GX_TEXCOORD0, 0, 0); + GXEnableTexOffsets(GX_TEXCOORD1, 0, 0); + GXEnableTexOffsets(GX_TEXCOORD2, 0, 0); + GXEnableTexOffsets(GX_TEXCOORD3, 0, 0); + GXEnableTexOffsets(GX_TEXCOORD4, 0, 0); + GXEnableTexOffsets(GX_TEXCOORD5, 0, 0); + GXEnableTexOffsets(GX_TEXCOORD6, 0, 0); + GXEnableTexOffsets(GX_TEXCOORD7, 0, 0); + identity_mtx[0][0] = 1.0f; + identity_mtx[0][1] = 0.0f; + identity_mtx[0][2] = 0.0f; + identity_mtx[0][3] = 0.0f; + identity_mtx[1][0] = 0.0f; + identity_mtx[1][1] = 1.0f; + identity_mtx[1][2] = 0.0f; + identity_mtx[1][3] = 0.0f; + identity_mtx[2][0] = 0.0f; + identity_mtx[2][1] = 0.0f; + identity_mtx[2][2] = 1.0f; + identity_mtx[2][3] = 0.0f; + GXLoadPosMtxImm(identity_mtx, GX_PNMTX0); + GXLoadNrmMtxImm(identity_mtx, GX_PNMTX0); GXSetCurrentMtx(GX_PNMTX0); - - GXLoadTexMtxImm(ident, GX_IDENTITY, GX_MTX3x4); - GXLoadTexMtxImm(ident, GX_PTIDENTITY, GX_MTX3x4); - - GXSetViewport(0.0f, 0.0f, renderObj->fb_width, renderObj->xfb_height, 0.0f, 1.0f); - + GXLoadTexMtxImm(identity_mtx, GX_IDENTITY, GX_MTX3x4); + GXLoadTexMtxImm(identity_mtx, GX_PTIDENTITY, GX_MTX3x4); + GXSetViewport(0.0f, 0.0f, rmode->fbWidth, rmode->xfbHeight, 0.0f, 1.0f); GXSetProjectionv(GXDefaultProjData); - - GXSetCoPlanar(GX_FALSE); + GXSetCoPlanar(GX_DISABLE); GXSetCullMode(GX_CULL_BACK); GXSetClipMode(GX_CLIP_ENABLE); - - GXSetScissor(0, 0, renderObj->fb_width, renderObj->efb_height); + GXSetScissor(0, 0, rmode->fbWidth, rmode->efbHeight); GXSetScissorBoxOffset(0, 0); - GXSetNumChans(0); - GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, 0, GX_DF_NONE, GX_AF_NONE); - GXSetChanAmbColor(GX_COLOR0A0, ambColor); - GXSetChanMatColor(GX_COLOR0A0, matColor); - - GXSetChanCtrl(GX_COLOR1A1, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, 0, GX_DF_NONE, GX_AF_NONE); - GXSetChanAmbColor(GX_COLOR1A1, ambColor); - GXSetChanMatColor(GX_COLOR1A1, matColor); - + GXSetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + GXSetChanAmbColor(GX_COLOR0A0, black); + GXSetChanMatColor(GX_COLOR0A0, white); + GXSetChanCtrl(GX_COLOR1A1, GX_DISABLE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + GXSetChanAmbColor(GX_COLOR1A1, black); + GXSetChanMatColor(GX_COLOR1A1, white); GXInvalidateTexAll(); - GXSetTexRegionCallback(__GXDefaultTexRegionCallback); + GXSetTexRegionCallback((GXTexRegionCallback)__GXDefaultTexRegionCallback); GXSetTlutRegionCallback(__GXDefaultTlutRegionCallback); - GXInitTexObj(&texObj, DefaultTexData, 4, 4, GX_TF_IA8, GX_CLAMP, GX_CLAMP, GX_FALSE); - GXLoadTexObj(&texObj, GX_TEXMAP0); - GXLoadTexObj(&texObj, GX_TEXMAP1); - GXLoadTexObj(&texObj, GX_TEXMAP2); - GXLoadTexObj(&texObj, GX_TEXMAP3); - GXLoadTexObj(&texObj, GX_TEXMAP4); - GXLoadTexObj(&texObj, GX_TEXMAP5); - GXLoadTexObj(&texObj, GX_TEXMAP6); - GXLoadTexObj(&texObj, GX_TEXMAP7); + GXInitTexObj(&tex_obj, DefaultTexData, 4, 4, GX_TF_IA8, GX_CLAMP, GX_CLAMP, 0); + GXLoadTexObj(&tex_obj, GX_TEXMAP0); + GXLoadTexObj(&tex_obj, GX_TEXMAP1); + GXLoadTexObj(&tex_obj, GX_TEXMAP2); + GXLoadTexObj(&tex_obj, GX_TEXMAP3); + GXLoadTexObj(&tex_obj, GX_TEXMAP4); + GXLoadTexObj(&tex_obj, GX_TEXMAP5); + GXLoadTexObj(&tex_obj, GX_TEXMAP6); + GXLoadTexObj(&tex_obj, GX_TEXMAP7); GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR0A0); @@ -500,7 +499,6 @@ void __GXInitGX(void) { GXSetTevOrder(GX_TEVSTAGE5, GX_TEXCOORD5, GX_TEXMAP5, GX_COLOR0A0); GXSetTevOrder(GX_TEVSTAGE6, GX_TEXCOORD6, GX_TEXMAP6, GX_COLOR0A0); GXSetTevOrder(GX_TEVSTAGE7, GX_TEXCOORD7, GX_TEXMAP7, GX_COLOR0A0); - GXSetTevOrder(GX_TEVSTAGE8, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); GXSetTevOrder(GX_TEVSTAGE9, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); GXSetTevOrder(GX_TEVSTAGE10, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); @@ -512,12 +510,10 @@ void __GXInitGX(void) { GXSetNumTevStages(1); GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE); - GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); - GXSetZTexture(GX_ZT_DISABLE, GX_TF_Z8, 0); - for (i = 0; i < GX_MAX_TEVSTAGE; i++) { + for (i = GX_TEVSTAGE0; i < GX_MAX_TEVSTAGE; i++) { GXSetTevKColorSel((GXTevStageID)i, GX_TEV_KCSEL_1_4); GXSetTevKAlphaSel((GXTevStageID)i, GX_TEV_KASEL_1); GXSetTevSwapMode((GXTevStageID)i, GX_TEV_SWAP0, GX_TEV_SWAP0); @@ -528,9 +524,8 @@ void __GXInitGX(void) { GXSetTevSwapModeTable(GX_TEV_SWAP2, GX_CH_GREEN, GX_CH_GREEN, GX_CH_GREEN, GX_CH_ALPHA); GXSetTevSwapModeTable(GX_TEV_SWAP3, GX_CH_BLUE, GX_CH_BLUE, GX_CH_BLUE, GX_CH_ALPHA); - for (i = 0; i < GX_MAX_TEVSTAGE; i++) { + for (i = GX_TEVSTAGE0; i < GX_MAX_TEVSTAGE; i++) GXSetTevDirect((GXTevStageID)i); - } GXSetNumIndStages(0); GXSetIndTexCoordScale(GX_INDTEXSTAGE0, GX_ITS_1, GX_ITS_1); @@ -538,34 +533,25 @@ void __GXInitGX(void) { GXSetIndTexCoordScale(GX_INDTEXSTAGE2, GX_ITS_1, GX_ITS_1); GXSetIndTexCoordScale(GX_INDTEXSTAGE3, GX_ITS_1, GX_ITS_1); - GXSetFog(GX_FOG_NONE, 0.0f, 1.0f, 0.1f, 1.0f, ambColor); - GXSetFogRangeAdj(GX_FALSE, 0, NULL); - - GXSetBlendMode(GX_BM_NONE, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); - - GXSetColorUpdate(GX_TRUE); - GXSetAlphaUpdate(GX_TRUE); - + GXSetFog(GX_FOG_NONE, 0.0f, 1.0f, 0.1f, 1.0f, black); + GXSetFogRangeAdj(GX_DISABLE, 0, NULL); + GXSetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); + GXSetColorUpdate(GX_ENABLE); + GXSetAlphaUpdate(GX_ENABLE); GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); GXSetZCompLoc(GX_TRUE); - - GXSetDither(GX_TRUE); - - GXSetDstAlpha(GX_FALSE, 0); + GXSetDither(GX_ENABLE); + GXSetDstAlpha(GX_DISABLE, 0); GXSetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR); + GXSetFieldMask(GX_ENABLE, GX_ENABLE); + GXSetFieldMode(rmode->field_rendering, + ((rmode->viHeight == 2 * rmode->xfbHeight) ? GX_ENABLE : GX_DISABLE)); - GXSetFieldMask(GX_TRUE, GX_TRUE); - GXSetFieldMode( - (GXBool)renderObj->field_rendering, - (GXBool)((renderObj->vi_height == 2 * renderObj->xfb_height) ? GX_TRUE : GX_FALSE)); - - GXSetDispCopySrc(0, 0, renderObj->fb_width, renderObj->efb_height); - GXSetDispCopyDst(renderObj->fb_width, renderObj->efb_height); - GXSetDispCopyYScale((f32)renderObj->xfb_height / (f32)renderObj->efb_height); - GXSetCopyClamp(GX_CLAMP_BOTH); - - GXSetCopyFilter(renderObj->antialiasing, renderObj->sample_pattern, GX_TRUE, - renderObj->vfilter); + GXSetDispCopySrc(0, 0, rmode->fbWidth, rmode->efbHeight); + GXSetDispCopyDst(rmode->fbWidth, rmode->efbHeight); + GXSetDispCopyYScale((f32)(rmode->xfbHeight) / (f32)(rmode->efbHeight)); + GXSetCopyClamp((GXFBClamp)(GX_CLAMP_TOP | GX_CLAMP_BOTTOM)); + GXSetCopyFilter(rmode->aa, rmode->sample_pattern, GX_TRUE, rmode->vfilter); GXSetDispCopyGamma(GX_GM_1_0); GXSetDispCopyFrame2Field(GX_COPY_PROGRESSIVE); GXClearBoundingBox(); @@ -576,8 +562,9 @@ void __GXInitGX(void) { GXPokeBlendMode(GX_BM_NONE, GX_BL_ZERO, GX_BL_ONE, GX_LO_SET); GXPokeAlphaMode(GX_ALWAYS, 0); GXPokeAlphaRead(GX_READ_FF); - GXPokeDstAlpha(GX_FALSE, 0); + GXPokeDstAlpha(GX_DISABLE, 0); GXPokeZMode(GX_TRUE, GX_ALWAYS, GX_TRUE); + GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE); GXClearGPMetric(); -} \ No newline at end of file +} diff --git a/src/dolphin/gx/GXLight.c b/src/dolphin/gx/GXLight.c index 5b86a7da69..d1b005d23f 100644 --- a/src/dolphin/gx/GXLight.c +++ b/src/dolphin/gx/GXLight.c @@ -1,138 +1,322 @@ -/** - * GXLight.c - * Description: - */ +#include +#include +#include -#include "dolphin/gx/GXLight.h" -#include "dolphin/gx.h" -#include "math.h" +#include "__gx.h" -/* 8035D630-8035D64C 357F70 001C+00 0/0 1/1 0/0 .text GXInitLightAttn */ -void GXInitLightAttn(GXLightObj* obj, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2) { - obj->a0 = a0; - obj->a1 = a1; - obj->a2 = a2; - obj->k0 = k0; - obj->k1 = k1; - obj->k2 = k2; +// GXLightObj private data +typedef struct { + u32 reserved[3]; + u32 Color; + f32 a[3]; + f32 k[3]; + f32 lpos[3]; + f32 ldir[3]; +} __GXLightObjInt_struct; + +void GXInitLightAttn(GXLightObj* lt_obj, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(129, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(130, "GXInitLightAttn"); + obj->a[0] = a0; + obj->a[1] = a1; + obj->a[2] = a2; + obj->k[0] = k0; + obj->k[1] = k1; + obj->k[2] = k2; } -/* 8035D64C-8035D7DC 357F8C 0190+00 1/0 2/2 0/0 .text GXInitLightSpot */ -void GXInitLightSpot(GXLightObj* obj, f32 cutoff, GXSpotFn spot_fn) { - f32 rad; - f32 a, b, c, d; +void GXInitLightAttnA(GXLightObj* lt_obj, f32 a0, f32 a1, f32 a2) { + __GXLightObjInt_struct* obj; - if (cutoff <= 0.0f || cutoff > 90.0f) { - spot_fn = GX_SP_OFF; - } + ASSERTMSGLINE(143, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(144, "GXInitLightAttnA"); + obj->a[0] = a0; + obj->a[1] = a1; + obj->a[2] = a2; +} - rad = cosf((3.1415927f * cutoff) / 180.0f); +void GXGetLightAttnA(const GXLightObj* lt_obj, f32* a0, f32* a1, f32* a2) { + __GXLightObjInt_struct* obj; - switch (spot_fn) { + ASSERTMSGLINE(153, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(154, "GXGetLightAttnA"); + *a0 = obj->a[0]; + *a1 = obj->a[1]; + *a2 = obj->a[2]; +} + +void GXInitLightAttnK(GXLightObj* lt_obj, f32 k0, f32 k1, f32 k2) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(163, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(164, "GXInitLightAttnK"); + obj->k[0] = k0; + obj->k[1] = k1; + obj->k[2] = k2; +} + +void GXGetLightAttnK(const GXLightObj* lt_obj, f32* k0, f32* k1, f32* k2) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(173, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(174, "GXGetLightAttnK"); + *k0 = obj->k[0]; + *k1 = obj->k[1]; + *k2 = obj->k[2]; +} + +void GXInitLightSpot(GXLightObj* lt_obj, f32 cutoff, GXSpotFn spot_func) { + f32 a0, a1, a2; + f32 r; + f32 d; + f32 cr; + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(198, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(200, "GXInitLightSpot"); + + if (cutoff <= 0.0f || cutoff > 90.0f) + spot_func = GX_SP_OFF; + + r = (3.1415927f * cutoff) / 180.0f; + cr = cosf(r); + + switch (spot_func) { case GX_SP_FLAT: - a = -1000.0f * rad; - b = 1000.0f; - c = 0.0f; + a0 = -1000.0f * cr; + a1 = 1000.0f; + a2 = 0.0f; break; case GX_SP_COS: - b = 1.0f / (1.0f - rad); - a = -rad * b; - c = 0.0f; + a1 = 1.0f / (1.0f - cr); + a0 = -cr * a1; + a2 = 0.0f; break; case GX_SP_COS2: - c = 1.0f / (1.0f - rad); - a = 0.0f; - b = -rad * c; + a2 = 1.0f / (1.0f - cr); + a0 = 0.0f; + a1 = -cr * a2; break; case GX_SP_SHARP: - d = 1.0f / ((1.0f - rad) * (1.0f - rad)); - a = (rad * (rad - 2.0f)) * d; - b = 2.0f * d; - c = -d; + d = 1.0f / ((1.0f - cr) * (1.0f - cr)); + a0 = (cr * (cr - 2.0f)) * d; + a1 = 2.0f * d; + a2 = -d; break; case GX_SP_RING1: - d = 1.0f / ((1.0f - rad) * (1.0f - rad)); - c = -4.0f * d; - a = c * rad; - b = 4.0f * (1.0f + rad) * d; + d = 1.0f / ((1.0f - cr) * (1.0f - cr)); + a2 = -4.0f * d; + a0 = a2 * cr; + a1 = (4.0f * (1.0f + cr)) * d; break; case GX_SP_RING2: - d = 1.0f / ((1.0f - rad) * (1.0f - rad)); - a = 1.0f - 2.0f * rad * rad * d; - b = 4.0f * rad * d; - c = -2.0f * d; + d = 1.0f / ((1.0f - cr) * (1.0f - cr)); + a0 = 1.0f - ((2.0f * cr * cr) * d); + a1 = (4.0f * cr) * d; + a2 = -2.0f * d; break; case GX_SP_OFF: default: - a = 1.0f; - b = 0.0f; - c = 0.0f; + a0 = 1.0f; + a1 = 0.0f; + a2 = 0.0f; break; } - - obj->a0 = a; - obj->a1 = b; - obj->a2 = c; + obj->a[0] = a0; + obj->a[1] = a1; + obj->a[2] = a2; } -/* 8035D7DC-8035D8AC 35811C 00D0+00 0/0 2/2 0/0 .text GXInitLightDistAttn */ -void GXInitLightDistAttn(GXLightObj* obj, f32 dist, f32 brightness, GXDistAttnFn dist_fn) { - f32 a, b, c; +void GXInitLightDistAttn(GXLightObj* lt_obj, f32 ref_dist, f32 ref_br, GXDistAttnFn dist_func) { + f32 k0, k1, k2; + __GXLightObjInt_struct* obj; - if (dist < 0.0f) { - dist_fn = GX_DA_OFF; - } + ASSERTMSGLINE(273, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(275, "GXInitLightDistAttn"); - if (brightness <= 0.0f || brightness >= 1.0f) { - dist_fn = GX_DA_OFF; - } + if (ref_dist < 0.0f) + dist_func = GX_DA_OFF; + if (ref_br <= 0.0f || ref_br >= 1.0f) + dist_func = GX_DA_OFF; - switch (dist_fn) { + switch (dist_func) { case GX_DA_GENTLE: - a = 1.0f; - b = (1.0f - brightness) / (brightness * dist); - c = 0.0f; + k0 = 1.0f; + k1 = (1.0f - ref_br) / (ref_br * ref_dist); + k2 = 0.0f; break; case GX_DA_MEDIUM: - a = 1.0f; - b = (0.5f * (1.0f - brightness)) / (brightness * dist); - c = (0.5f * (1.0f - brightness)) / (dist * (brightness * dist)); + k0 = 1.0f; + k1 = (0.5f * (1.0f - ref_br)) / (ref_br * ref_dist); + k2 = (0.5f * (1.0f - ref_br)) / (ref_br * ref_dist * ref_dist); break; case GX_DA_STEEP: - a = 1.0f; - b = 0.0f; - c = (1.0f - brightness) / (dist * (brightness * dist)); + k0 = 1.0f; + k1 = 0.0f; + k2 = (1.0f - ref_br) / (ref_br * ref_dist * ref_dist); break; case GX_DA_OFF: default: - a = 1.0f; - b = 0.0f; - c = 0.0f; + k0 = 1.0f; + k1 = 0.0f; + k2 = 0.0f; break; } - obj->k0 = a; - obj->k1 = b; - obj->k2 = c; + obj->k[0] = k0; + obj->k[1] = k1; + obj->k[2] = k2; } -/* 8035D8AC-8035D8BC 3581EC 0010+00 0/0 3/3 0/0 .text GXInitLightPos */ -void GXInitLightPos(GXLightObj* obj, f32 x, f32 y, f32 z) { - obj->posX = x; - obj->posY = y; - obj->posZ = z; +void GXInitLightPos(GXLightObj* lt_obj, f32 x, f32 y, f32 z) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(328, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(330, "GXInitLightPos"); + + obj->lpos[0] = x; + obj->lpos[1] = y; + obj->lpos[2] = z; } -/* 8035D8BC-8035D8D8 3581FC 001C+00 0/0 3/3 0/0 .text GXInitLightDir */ -void GXInitLightDir(GXLightObj* obj, f32 x, f32 y, f32 z) { - obj->dirX = -x; - obj->dirY = -y; - obj->dirZ = -z; +void GXGetLightPos(const GXLightObj* lt_obj, f32* x, f32* y, f32* z) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(339, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(341, "GXGetLightPos"); + + *x = obj->lpos[0]; + *y = obj->lpos[1]; + *z = obj->lpos[2]; } -/* 8035D8D8-8035D8E4 358218 000C+00 0/0 3/3 0/0 .text GXInitLightColor */ -void GXInitLightColor(GXLightObj* obj, GXColor color) { - *(u32*)&obj->color = *(u32*)&color; +void GXInitLightDir(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(360, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + + obj->ldir[0] = -nx; + obj->ldir[1] = -ny; + obj->ldir[2] = -nz; +} + +void GXGetLightDir(const GXLightObj* lt_obj, f32* nx, f32* ny, f32* nz) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(372, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + + *nx = -obj->ldir[0]; + *ny = -obj->ldir[1]; + *nz = -obj->ldir[2]; +} + +void GXInitSpecularDir(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz) { + f32 mag; + f32 vx; + f32 vy; + f32 vz; + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(398, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(399, "GXInitSpecularDir"); + + vx = -nx; + vy = -ny; + vz = -nz + 1.0f; + + mag = (vx * vx) + (vy * vy) + (vz * vz); + if (mag != 0.0f) { + mag = 1.0f / sqrtf(mag); + } + + obj->ldir[0] = vx * mag; + obj->ldir[1] = vy * mag; + obj->ldir[2] = vz * mag; + obj->lpos[0] = nx * -1000000000000000000.0f; + obj->lpos[1] = ny * -1000000000000000000.0f; + obj->lpos[2] = nz * -1000000000000000000.0f; +} + +void GXInitSpecularDirHA(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz, f32 hx, f32 hy, f32 hz) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(436, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(437, "GXInitSpecularHA"); + + obj->ldir[0] = hx; + obj->ldir[1] = hy; + obj->ldir[2] = hz; + obj->lpos[0] = nx * -1000000000000000000.0f; + obj->lpos[1] = ny * -1000000000000000000.0f; + obj->lpos[2] = nz * -1000000000000000000.0f; +} + +void GXInitLightColor(GXLightObj* lt_obj, GXColor color) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(462, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(463, "GXInitLightColor"); + + *(u32*)&obj->Color = *(u32*)&color; +} + +void GXGetLightColor(const GXLightObj* lt_obj, GXColor* color) { + __GXLightObjInt_struct* obj; + + ASSERTMSGLINE(476, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(477, "GXGetLightColor"); + + *(u32*)color = *(u32*)&obj->Color; +} + +#if DEBUG +#define WRITE_SOME_LIGHT_REG1(val, addr) \ +do { \ + u32 xfData = val; \ + GX_WRITE_U32(val); \ + VERIF_MTXLIGHT(addr, xfData); \ +} while (0) + +#define WRITE_SOME_LIGHT_REG2(val, addr) \ +do { \ + f32 xfData = val; \ + GX_WRITE_F32(val); \ + VERIF_MTXLIGHT(addr, *(u32 *)&xfData); \ +} while (0) +#else +#define WRITE_SOME_LIGHT_REG1(val, addr) GX_WRITE_U32(val) +#define WRITE_SOME_LIGHT_REG2(val, addr) GX_WRITE_F32(val) +#endif + +static inline u32 ConvLightID2Num(GXLightID id) { + switch (id) { + case GX_LIGHT0: return 0; + case GX_LIGHT1: return 1; + case GX_LIGHT2: return 2; + case GX_LIGHT3: return 3; + case GX_LIGHT4: return 4; + case GX_LIGHT5: return 5; + case GX_LIGHT6: return 6; + case GX_LIGHT7: return 7; + default: return 8; + } } static inline void PushLight(const register GXLightObj* lt_obj, register void* dest) { @@ -164,142 +348,226 @@ static inline void PushLight(const register GXLightObj* lt_obj, register void* d #endif // clang-format on } -/* 8035D8E4-8035D960 358224 007C+00 0/0 4/4 2/2 .text GXLoadLightObjImm */ -void GXLoadLightObjImm(GXLightObj* obj, GXLightID light) { +void GXLoadLightObjImm(const GXLightObj* lt_obj, GXLightID light) { u32 addr; u32 idx; - GXLightObj* pObj = (GXLightObj*)obj; + __GXLightObjInt_struct* obj; + ASSERTMSGLINE(568, lt_obj != NULL, "Light Object Pointer is null"); + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(569, "GXLoadLightObjImm"); + +#if DEBUG + idx = ConvLightID2Num(light); +#else idx = 31 - __cntlzw(light); +#endif + + ASSERTMSGLINE(575, idx < 8, "GXLoadLightObjImm: Invalid Light Id"); idx &= 7; - addr = 0x600 + idx * 0x10; + addr = idx * 0x10 + 0x600; + GX_WRITE_U8(0x10); + GX_WRITE_U32(addr | 0xF0000); - GX_XF_LOAD_REG_HDR(addr | (0x10 - 1) << 16); +#if DEBUG + WRITE_SOME_LIGHT_REG1(0, addr); + WRITE_SOME_LIGHT_REG1(0, addr + 1); + WRITE_SOME_LIGHT_REG1(0, addr + 2); + WRITE_SOME_LIGHT_REG1(obj->Color, addr + 3); + WRITE_SOME_LIGHT_REG2(obj->a[0], addr + 4); + WRITE_SOME_LIGHT_REG2(obj->a[1], addr + 5); + WRITE_SOME_LIGHT_REG2(obj->a[2], addr + 6); + WRITE_SOME_LIGHT_REG2(obj->k[0], addr + 7); + WRITE_SOME_LIGHT_REG2(obj->k[1], addr + 8); + WRITE_SOME_LIGHT_REG2(obj->k[2], addr + 9); + WRITE_SOME_LIGHT_REG2(obj->lpos[0], addr + 10); + WRITE_SOME_LIGHT_REG2(obj->lpos[1], addr + 11); + WRITE_SOME_LIGHT_REG2(obj->lpos[2], addr + 12); + WRITE_SOME_LIGHT_REG2(obj->ldir[0], addr + 13); + WRITE_SOME_LIGHT_REG2(obj->ldir[1], addr + 14); + WRITE_SOME_LIGHT_REG2(obj->ldir[2], addr + 15); +#else + PushLight(lt_obj, (void*)GXFIFO_ADDR); +#endif - PushLight(pObj, (void*)GXFIFO_ADDR); __GXData->bpSentNot = 1; } -/* 8035D960-8035DA48 3582A0 00E8+00 0/0 7/7 4/4 .text GXSetChanAmbColor */ -void GXSetChanAmbColor(GXChannelID channel, GXColor color) { +void GXLoadLightObjIndx(u32 lt_obj_indx, GXLightID light) { u32 reg; - u32 colorID; - u8 alpha; + u32 addr; + u32 idx; - switch (channel) { + CHECK_GXBEGIN(624, "GXLoadLightObjIndx"); + +#if DEBUG + idx = ConvLightID2Num(light); +#else + idx = 31 - __cntlzw(light); +#endif + + ASSERTMSGLINE(627, idx < 8, "GXLoadLightObjIndx: Invalid Light Id"); + idx &= 7; + + addr = idx * 0x10 + 0x600; + reg = 0; + SET_REG_FIELD(632, reg, 12, 0, addr); + SET_REG_FIELD(634, reg, 4, 12, 0xF); + SET_REG_FIELD(634, reg, 16, 16, lt_obj_indx); + GX_WRITE_U8(0x38); + GX_WRITE_U32(reg); +#if DEBUG + __GXShadowIndexState(7, reg); +#endif + __GXData->bpSentNot = 1; +} + +#define GXCOLOR_AS_U32(color) (*((u32*)&(color))) + +void GXSetChanAmbColor(GXChannelID chan, GXColor amb_color) { + u32 reg; + u32 rgb; + u32 colIdx; + + CHECK_GXBEGIN(661, "GXSetChanAmbColor"); + + switch (chan) { case GX_COLOR0: reg = __GXData->ambColor[GX_COLOR0]; - reg = GX_SET_TRUNC(reg, GXCOLOR_AS_U32(color), 0, 23); - colorID = GX_COLOR0; + rgb = GXCOLOR_AS_U32(amb_color) >> 8; + SET_REG_FIELD(675, reg, 24, 8, rgb); + colIdx = 0; break; case GX_COLOR1: reg = __GXData->ambColor[GX_COLOR1]; - reg = GX_SET_TRUNC(reg, GXCOLOR_AS_U32(color), 0, 23); - colorID = GX_COLOR1; + rgb = GXCOLOR_AS_U32(amb_color) >> 8; + SET_REG_FIELD(690, reg, 24, 8, rgb); + colIdx = 1; break; case GX_ALPHA0: reg = __GXData->ambColor[GX_COLOR0]; - reg = GX_SET_TRUNC(reg, color.a, 24, 31); - colorID = GX_COLOR0; + SET_REG_FIELD(696, reg, 8, 0, amb_color.a); + colIdx = 0; break; case GX_ALPHA1: reg = __GXData->ambColor[GX_COLOR1]; - reg = GX_SET_TRUNC(reg, color.a, 24, 31); - colorID = GX_COLOR1; + SET_REG_FIELD(702, reg, 8, 0, amb_color.a); + colIdx = 1; break; case GX_COLOR0A0: - reg = GXCOLOR_AS_U32(color); - colorID = GX_COLOR0; + reg = GXCOLOR_AS_U32(amb_color); + colIdx = 0; break; case GX_COLOR1A1: - reg = GXCOLOR_AS_U32(color); - colorID = GX_COLOR1; + reg = GXCOLOR_AS_U32(amb_color); + colIdx = 1; break; default: + ASSERTMSGLINE(731, 0, "GXSetChanAmbColor: Invalid Channel Id"); return; } - GX_XF_LOAD_REG(GX_XF_REG_AMBIENT0 + colorID, reg); - __GXData->bpSentNot = GX_TRUE; - __GXData->ambColor[colorID] = reg; + GX_WRITE_XF_REG(colIdx + 10, reg); + __GXData->bpSentNot = 1; + __GXData->ambColor[colIdx] = reg; } -/* 8035DA48-8035DB30 358388 00E8+00 0/0 20/20 2/2 .text GXSetChanMatColor */ -void GXSetChanMatColor(GXChannelID channel, GXColor color) { - u32 reg = 0; - GXChannelID colorID; +void GXSetChanMatColor(GXChannelID chan, GXColor mat_color) { + u32 reg; + u32 rgb; + u32 colIdx; - switch (channel) { + CHECK_GXBEGIN(762, "GXSetChanMatColor"); + + switch (chan) { case GX_COLOR0: reg = __GXData->matColor[GX_COLOR0]; - reg = GX_SET_TRUNC(reg, GXCOLOR_AS_U32(color), 0, 23); - colorID = GX_COLOR0; + rgb = GXCOLOR_AS_U32(mat_color) >> 8; + SET_REG_FIELD(776, reg, 24, 8, rgb); + colIdx = 0; break; case GX_COLOR1: reg = __GXData->matColor[GX_COLOR1]; - reg = GX_SET_TRUNC(reg, GXCOLOR_AS_U32(color), 0, 23); - colorID = GX_COLOR1; + rgb = GXCOLOR_AS_U32(mat_color) >> 8; + SET_REG_FIELD(791, reg, 24, 8, rgb); + colIdx = 1; break; case GX_ALPHA0: reg = __GXData->matColor[GX_COLOR0]; - reg = GX_SET_TRUNC(reg, color.a, 24, 31); - colorID = GX_COLOR0; + SET_REG_FIELD(797, reg, 8, 0, mat_color.a); + colIdx = 0; break; case GX_ALPHA1: reg = __GXData->matColor[GX_COLOR1]; - reg = GX_SET_TRUNC(reg, color.a, 24, 31); - colorID = GX_COLOR1; + SET_REG_FIELD(803, reg, 8, 0, mat_color.a); + colIdx = 1; break; case GX_COLOR0A0: - reg = GXCOLOR_AS_U32(color); - colorID = GX_COLOR0; + reg = GXCOLOR_AS_U32(mat_color); + colIdx = 0; break; case GX_COLOR1A1: - reg = GXCOLOR_AS_U32(color); - colorID = GX_COLOR1; + reg = GXCOLOR_AS_U32(mat_color); + colIdx = 1; break; default: + ASSERTMSGLINE(832, 0, "GXSetChanMatColor: Invalid Channel Id"); return; } - GX_XF_LOAD_REG(GX_XF_REG_MATERIAL0 + colorID, reg); - __GXData->bpSentNot = GX_TRUE; - __GXData->matColor[colorID] = reg; + GX_WRITE_XF_REG(colIdx + 12, reg); + __GXData->bpSentNot = 1; + __GXData->matColor[colIdx] = reg; } -/* 8035DB30-8035DB6C 358470 003C+00 0/0 51/51 6/6 .text GXSetNumChans */ -void GXSetNumChans(u8 count) { - GX_SET_REG(__GXData->genMode, count, 25, 27); - GX_XF_LOAD_REG(GX_XF_REG_NUMCOLORS, count); - __GXData->dirtyState |= GX_DIRTY_GEN_MODE; +void GXSetNumChans(u8 nChans) { + CHECK_GXBEGIN(857, "GXSetNumChans"); + ASSERTMSGLINE(858, nChans <= 2, "GXSetNumChans: nChans > 2"); + + SET_REG_FIELD(860, __GXData->genMode, 3, 4, nChans); + GX_WRITE_XF_REG(9, nChans); + __GXData->dirtyState |= 4; } -/* 8035DB6C-8035DC1C 3584AC 00B0+00 0/0 34/34 4/4 .text GXSetChanCtrl */ -void GXSetChanCtrl(GXChannelID channel, GXBool doEnable, GXColorSrc ambSrc, GXColorSrc matSrc, - u32 mask, GXDiffuseFn diffFunc, GXAttnFn attnFunc) { - const u32 colorID = (u32)channel & 0x3; - u32 reg = 0; +void GXSetChanCtrl(GXChannelID chan, GXBool enable, GXColorSrc amb_src, GXColorSrc mat_src, u32 light_mask, GXDiffuseFn diff_fn, GXAttnFn attn_fn) { + u32 reg; + u32 idx; - GX_SET_REG(reg, doEnable, GX_XF_CLR0CTRL_LIGHT_ST, GX_XF_CLR0CTRL_LIGHT_END); - GX_SET_REG(reg, matSrc, GX_XF_CLR0CTRL_MTXSRC_ST, GX_XF_CLR0CTRL_MTXSRC_END); - GX_SET_REG(reg, ambSrc, GX_XF_CLR0CTRL_AMBSRC_ST, GX_XF_CLR0CTRL_AMBSRC_END); - GX_SET_REG(reg, (attnFunc == GX_AF_SPEC ? GX_DF_NONE : diffFunc), GX_XF_CLR0CTRL_DIFATTN_ST, - GX_XF_CLR0CTRL_DIFATTN_END); - GX_SET_REG(reg, (attnFunc != GX_AF_NONE), GX_XF_CLR0CTRL_ATTNENABLE_ST, - GX_XF_CLR0CTRL_ATTNENABLE_END); - GX_SET_REG(reg, (attnFunc != GX_AF_SPEC), GX_XF_CLR0CTRL_ATTNSEL_ST, - GX_XF_CLR0CTRL_ATTNSEL_END); - GX_BITFIELD_SET(reg, 26, 4, (u32)mask); - reg = __rlwimi(reg, (u32)mask, 7, 0x11, 0x14); + CHECK_GXBEGIN(892, "GXSetChanCtrl"); - GX_XF_LOAD_REG(GX_XF_REG_COLOR0CNTRL + colorID, reg); + ASSERTMSGLINE(895, chan >= GX_COLOR0 && chan <= GX_COLOR1A1, "GXSetChanCtrl: Invalid Channel Id"); - if (channel == GX_COLOR0A0) { - GX_XF_LOAD_REG(GX_XF_REG_ALPHA0CNTRL, reg); - } else if (channel == GX_COLOR1A1) { - GX_XF_LOAD_REG(GX_XF_REG_ALPHA1CNTRL, reg); +#if DEBUG + if (chan == GX_COLOR0A0) + idx = 0; + else if (chan == GX_COLOR1A1) + idx = 1; + else + idx = chan; +#else + idx = chan & 0x3; +#endif + + reg = 0; + SET_REG_FIELD(907, reg, 1, 1, enable); + SET_REG_FIELD(908, reg, 1, 0, mat_src); + SET_REG_FIELD(909, reg, 1, 6, amb_src); + + SET_REG_FIELD(911, reg, 2, 7, (attn_fn == 0) ? 0 : diff_fn); + SET_REG_FIELD(912, reg, 1, 9, (attn_fn != 2)); + SET_REG_FIELD(913, reg, 1, 10, (attn_fn != 0)); + + SET_REG_FIELD(925, reg, 4, 2, light_mask & 0xF); + SET_REG_FIELD(926, reg, 4, 11, (light_mask >> 4) & 0xF); + + GX_WRITE_XF_REG(idx + 14, reg); + + if (chan == GX_COLOR0A0) { + GX_WRITE_XF_REG(16, reg); + } else if (chan == GX_COLOR1A1) { + GX_WRITE_XF_REG(17, reg); } - __GXData->bpSentNot = GX_TRUE; -} \ No newline at end of file + __GXData->bpSentNot = 1; +} diff --git a/src/dolphin/gx/GXMisc.c b/src/dolphin/gx/GXMisc.c index 8ede75e528..3c30698560 100644 --- a/src/dolphin/gx/GXMisc.c +++ b/src/dolphin/gx/GXMisc.c @@ -1,80 +1,92 @@ -#include "dolphin/gx/GXMisc.h" -#include "dolphin/gx.h" -#include "dolphin/os/OSInterrupt.h" -#include "dolphin/os/OSReset.h" -#include "dolphin/os/OSTime.h" +#include +#include +#include +#include -static void GXTokenInterruptHandler(__OSInterrupt interrupt, OSContext* context); -static void GXFinishInterruptHandler(__OSInterrupt interrupt, OSContext* pContext); +#include "__gx.h" + +static GXDrawSyncCallback TokenCB; +static GXDrawDoneCallback DrawDoneCB; +static u8 DrawDone; +static OSThreadQueue FinishQueue; -/* 8035BE38-8035BECC 356778 0094+00 0/0 9/9 0/0 .text GXSetMisc */ void GXSetMisc(GXMiscToken token, u32 val) { switch (token) { - case GX_MT_NULL: - break; - case GX_MT_XF_FLUSH: __GXData->vNum = val; __GXData->vNumNot = !__GXData->vNum; - __GXData->bpSentNot = GX_TRUE; + __GXData->bpSentNot = 1; - if (__GXData->vNum) { - __GXData->dirtyState |= GX_DIRTY_VCD; + if (__GXData->vNum != 0) { + __GXData->dirtyState |= 8; } break; - case GX_MT_DL_SAVE_CONTEXT: + ASSERTMSGLINE(223, !__GXData->inDispList, "GXSetMisc: Cannot change DL context setting while making a display list"); __GXData->dlSaveContext = (val != 0); break; - case GX_MT_ABORT_WAIT_COPYOUT: __GXData->abtWaitPECopy = (val != 0); break; + case GX_MT_NULL: + break; + default: +#if DEBUG + OSReport("GXSetMisc: bad token %d (val %d)\n", token, val); +#endif + break; } } -/* 8035BECC-8035BF28 35680C 005C+00 1/1 10/10 0/0 .text GXFlush */ void GXFlush(void) { + CHECK_GXBEGIN(270, "GXFlush"); if (__GXData->dirtyState) { __GXSetDirtyState(); } - - GXWGFifo.u32 = 0; - GXWGFifo.u32 = 0; - GXWGFifo.u32 = 0; - GXWGFifo.u32 = 0; - GXWGFifo.u32 = 0; - GXWGFifo.u32 = 0; - GXWGFifo.u32 = 0; - GXWGFifo.u32 = 0; + + GX_WRITE_U32(0); + GX_WRITE_U32(0); + GX_WRITE_U32(0); + GX_WRITE_U32(0); + GX_WRITE_U32(0); + GX_WRITE_U32(0); + GX_WRITE_U32(0); + GX_WRITE_U32(0); PPCSync(); } -static void __GXAbortWait(u32 clocks) { - OSTime time0, time1; - time0 = OSGetTime(); +void GXResetWriteGatherPipe(void) { + while (PPCMfwpar() & 1) { + } + PPCMtwpar(OSUncachedToPhysical((void *)GXFIFO_ADDR)); +} +static void __GXAbortWait(u32 clocks) { + OSTime time0; + OSTime time1; + + time0 = OSGetTime(); do { time1 = OSGetTime(); - } while (time1 - time0 <= clocks / 4); + } while (time1 - time0 <= (clocks / 4)); } static void __GXAbortWaitPECopyDone(void) { - u32 peCnt0, peCnt1; + u32 peCnt0; + u32 peCnt1; - peCnt0 = GXReadMEMReg(0x28, 0x27); + peCnt0 = __GXReadMEMCounterU32(0x28, 0x27); do { peCnt1 = peCnt0; __GXAbortWait(32); - peCnt0 = GXReadMEMReg(0x28, 0x27); + peCnt0 = __GXReadMEMCounterU32(0x28, 0x27); } while (peCnt0 != peCnt1); } -/* 8035BF28-8035C094 356868 016C+00 0/0 1/1 0/0 .text __GXAbort */ void __GXAbort(void) { - if (__GXData->abtWaitPECopy && GXGetGPFifo()) { + if (__GXData->abtWaitPECopy && GXGetGPFifo() != (GXFifoObj*)NULL) { __GXAbortWaitPECopyDone(); } @@ -84,10 +96,10 @@ void __GXAbort(void) { __GXAbortWait(20); } -/* 8035C094-8035C25C 3569D4 01C8+00 0/0 2/2 0/0 .text GXAbortFrame */ void GXAbortFrame(void) { __GXAbort(); - if (GXGetGPFifo()) { + + if (GXGetGPFifo() != (GXFifoObj*)NULL) { __GXCleanGPFifo(); __GXInitRevisionBits(); __GXData->dirtyState = 0; @@ -95,197 +107,375 @@ void GXAbortFrame(void) { } } -/* ############################################################################################## */ -/* 80451968-8045196C 000E68 0004+00 2/2 0/0 0/0 .sbss TokenCB */ -static GXDrawSyncCallback TokenCB; +void GXSetDrawSync(u16 token) { + BOOL enabled; + u32 reg; -/* 8045196C-80451970 000E6C 0004+00 2/2 0/0 0/0 .sbss DrawDoneCB */ -static GXDrawDoneCallback DrawDoneCB; + CHECK_GXBEGIN(430, "GXSetDrawSync"); -/* 80451970-80451974 000E70 0004+00 3/3 0/0 0/0 .sbss None */ -static GXBool DrawDone; + enabled = OSDisableInterrupts(); + reg = token | 0x48000000; + GX_WRITE_RAS_REG(reg); + SET_REG_FIELD(443, reg, 16, 0, token); + SET_REG_FIELD(443, reg, 8, 24, 0x47); + GX_WRITE_RAS_REG(reg); + GXFlush(); + OSRestoreInterrupts(enabled); + __GXData->bpSentNot = 0; +} + +u16 GXReadDrawSync(void) { + u16 token = GX_GET_PE_REG(7); + return token; +} -/* 8035C25C-8035C2F4 356B9C 0098+00 0/0 2/2 0/0 .text GXSetDrawDone */ void GXSetDrawDone(void) { - u8 padding[8]; - BOOL restore = OSDisableInterrupts(); - GFWriteBPCmd(0x45000002); + u32 reg; + BOOL enabled; + + CHECK_GXBEGIN(488, "GXSetDrawDone"); + enabled = OSDisableInterrupts(); + reg = 0x45000002; + GX_WRITE_RAS_REG(reg); GXFlush(); DrawDone = 0; - OSRestoreInterrupts(restore); + OSRestoreInterrupts(enabled); } -/* ############################################################################################## */ -/* 80451974-8045197C 000E74 0008+00 3/3 0/0 0/0 .sbss FinishQueue */ -static OSThreadQueue FinishQueue; +void GXWaitDrawDone(void) { + BOOL enabled; -static void GXWaitDrawDone(void) { - BOOL restore = OSDisableInterrupts(); - while (DrawDone == 0) { + CHECK_GXBEGIN(534, "GXWaitDrawDone"); + + enabled = OSDisableInterrupts(); + while (!DrawDone) { OSSleepThread(&FinishQueue); } - OSRestoreInterrupts(restore); + OSRestoreInterrupts(enabled); } -/* 8035C2F4-8035C374 356C34 0080+00 0/0 3/3 1/1 .text GXDrawDone */ void GXDrawDone(void) { - u8 padding[8]; + CHECK_GXBEGIN(566, "GXDrawDone"); GXSetDrawDone(); GXWaitDrawDone(); } -/* 8035C374-8035C398 356CB4 0024+00 0/0 9/9 0/0 .text GXPixModeSync */ void GXPixModeSync(void) { - GXWGFifo.u8 = 0x61; - GXWGFifo.u32 = __GXData->peCtrl; + CHECK_GXBEGIN(601, "GXPixModeSync"); + GX_WRITE_RAS_REG(__GXData->peCtrl); __GXData->bpSentNot = 0; } -/* 8035C398-8035C3AC 356CD8 0014+00 0/0 1/1 0/0 .text GXPokeAlphaMode */ -void GXPokeAlphaMode(GXCompare comp, u8 threshold) { - __peReg[3] = (comp << 8) | threshold; +void GXTexModeSync(void) { + u32 reg; + + CHECK_GXBEGIN(625, "GXTexModeSync"); + reg = 0x63000000; + GX_WRITE_RAS_REG(reg); + __GXData->bpSentNot = 0; +} + +#if DEBUG +void __GXBypass(u32 reg) { + CHECK_GXBEGIN(647, "__GXBypass"); + GX_WRITE_RAS_REG(reg); + __GXData->bpSentNot = 0; +} + +u16 __GXReadPEReg(u32 reg) { + return GX_GET_PE_REG(reg); +} +#endif + +void GXPokeAlphaMode(GXCompare func, u8 threshold) { + u32 reg; + + reg = (func << 8) | threshold; + GX_SET_PE_REG(3, reg); } -/* 8035C3AC-8035C3CC 356CEC 0020+00 0/0 1/1 0/0 .text GXPokeAlphaRead */ void GXPokeAlphaRead(GXAlphaReadMode mode) { - u32 val = 0; - GX_BITFIELD_SET(val, 0x1e, 2, mode); - GX_BITFIELD_SET(val, 0x1d, 1, 1); - __peReg[4] = val; + u32 reg; + + reg = 0; + SET_REG_FIELD(693, reg, 2, 0, mode); + SET_REG_FIELD(693, reg, 1, 2, 1); + GX_SET_PE_REG(4, reg); } -/* 8035C3CC-8035C3E4 356D0C 0018+00 0/0 1/1 0/0 .text GXPokeAlphaUpdate */ -void GXPokeAlphaUpdate(GXBool enable_update) { - GX_BITFIELD_SET(__peReg[1], 0x1b, 1, enable_update); -} - -/* 8035C3E4-8035C448 356D24 0064+00 0/0 1/1 0/0 .text GXPokeBlendMode */ -void GXPokeBlendMode(GXBlendMode mode, GXBlendFactor srcFactor, GXBlendFactor destFactor, - GXLogicOp op) { +void GXPokeAlphaUpdate(GXBool update_enable) { u32 reg; reg = GX_GET_PE_REG(1); - GX_SET_REG(reg, (mode == GX_BM_BLEND) || (mode == GX_BM_SUBTRACT), 31, 31); - GX_SET_REG(reg, (mode == GX_BM_SUBTRACT), 20, 20); - GX_SET_REG(reg, (mode == GX_BM_LOGIC), 30, 30); - GX_SET_REG(reg, op, 16, 19); - GX_SET_REG(reg, srcFactor, 21, 23); - GX_SET_REG(reg, destFactor, 24, 26); - GX_SET_REG(reg, 0x41, 0, 7); + SET_REG_FIELD(704, reg, 1, 4, update_enable); GX_SET_PE_REG(1, reg); } -/* 8035C448-8035C460 356D88 0018+00 0/0 1/1 0/0 .text GXPokeColorUpdate */ -void GXPokeColorUpdate(GXBool enable_update) { - GX_BITFIELD_SET(__peReg[1], 0x1c, 1, enable_update); +void GXPokeBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor, GXLogicOp op) { + u32 reg; + + reg = GX_GET_PE_REG(1); + SET_REG_FIELD(720, reg, 1, 0, (type == GX_BM_BLEND) || (type == GX_BM_SUBTRACT)); + SET_REG_FIELD(721, reg, 1, 11, (type == GX_BM_SUBTRACT)); + SET_REG_FIELD(723, reg, 1, 1, (type == GX_BM_LOGIC)); + SET_REG_FIELD(724, reg, 4, 12, op); + SET_REG_FIELD(725, reg, 3, 8, src_factor); + SET_REG_FIELD(726, reg, 3, 5, dst_factor); + SET_REG_FIELD(726, reg, 8, 24, 0x41); + GX_SET_PE_REG(1, reg); +} + +void GXPokeColorUpdate(GXBool update_enable) { + u32 reg; + + reg = GX_GET_PE_REG(1); + SET_REG_FIELD(738, reg, 1, 3, update_enable); + GX_SET_PE_REG(1, reg); } -/* 8035C460-8035C484 356DA0 0024+00 0/0 1/1 0/0 .text GXPokeDstAlpha */ void GXPokeDstAlpha(GXBool enable, u8 alpha) { - u32 val = 0; - GX_BITFIELD_SET(val, 0x18, 8, alpha); - GX_BITFIELD_SET(val, 0x17, 1, enable); - __peReg[2] = val; + u32 reg = 0; + + SET_REG_FIELD(747, reg, 8, 0, alpha); + SET_REG_FIELD(748, reg, 1, 8, enable); + GX_SET_PE_REG(2, reg); } -/* 8035C484-8035C49C 356DC4 0018+00 0/0 1/1 0/0 .text GXPokeDither */ -void GXPokeDither(GXBool enable) { - GX_BITFIELD_SET(__peReg[1], 0x1d, 1, enable); +void GXPokeDither(GXBool dither) { + u32 reg; + + reg = GX_GET_PE_REG(1); + SET_REG_FIELD(758, reg, 1, 2, dither); + GX_SET_PE_REG(1, reg); } -/* 8035C49C-8035C4BC 356DDC 0020+00 0/0 1/1 0/0 .text GXPokeZMode */ -void GXPokeZMode(GXBool enable_compare, GXCompare comp, GXBool update_enable) { - u32 val = 0; - GX_BITFIELD_SET(val, 0x1f, 1, enable_compare); - GX_BITFIELD_SET(val, 0x1c, 3, comp); - GX_BITFIELD_SET(val, 0x1b, 1, update_enable); - __peReg[0] = val; +void GXPokeZMode(GXBool compare_enable, GXCompare func, GXBool update_enable) { + u32 reg = 0; + + SET_REG_FIELD(767, reg, 1, 0, compare_enable); + SET_REG_FIELD(768, reg, 3, 1, func); + SET_REG_FIELD(769, reg, 1, 4, update_enable); + GX_SET_PE_REG(0, reg); +} + +void GXPeekARGB(u16 x, u16 y, u32* color) { + u32 addr = (u32)OSPhysicalToUncached(0x08000000); + + SET_REG_FIELD(792, addr, 10, 2, x); + SET_REG_FIELD(793, addr, 10, 12, y); + SET_REG_FIELD(793, addr, 2, 22, 0); + *color = *(u32*)addr; +} + +void GXPokeARGB(u16 x, u16 y, u32 color) { + u32 addr = (u32)OSPhysicalToUncached(0x08000000); + + SET_REG_FIELD(0x322, addr, 10, 2, x); + SET_REG_FIELD(0x323, addr, 10, 12, y); + SET_REG_FIELD(0x323, addr, 2, 22, 0); + *(u32*)addr = color; } -/* 8035C4BC-8035C4E0 356DFC 0024+00 0/0 1/1 0/0 .text GXPeekZ */ void GXPeekZ(u16 x, u16 y, u32* z) { - u32 addr = 0xc8000000; - GX_BITFIELD_SET(addr, 0x14, 10, x); - GX_BITFIELD_SET(addr, 0xa, 10, y); - GX_BITFIELD_SET(addr, 8, 2, 1); + u32 addr = (u32)OSPhysicalToUncached(0x08000000); + + SET_REG_FIELD(812, addr, 10, 2, x); + SET_REG_FIELD(813, addr, 10, 12, y); + SET_REG_FIELD(813, addr, 2, 22, 1); *z = *(u32*)addr; } -/* 8035C4E0-8035C524 356E20 0044+00 0/0 1/1 0/0 .text GXSetDrawSyncCallback */ -GXDrawSyncCallback GXSetDrawSyncCallback(GXDrawSyncCallback callback) { - BOOL restore; - GXDrawSyncCallback prevCb = TokenCB; - restore = OSDisableInterrupts(); - TokenCB = callback; - OSRestoreInterrupts(restore); - return prevCb; +void GXPokeZ(u16 x, u16 y, u32 z) { + u32 addr = (u32)OSPhysicalToUncached(0x08000000); + + SET_REG_FIELD(822, addr, 10, 2, x); + SET_REG_FIELD(823, addr, 10, 12, y); + SET_REG_FIELD(823, addr, 2, 22, 1); + *(u32*)addr = z; +} + +GXDrawSyncCallback GXSetDrawSyncCallback(GXDrawSyncCallback cb) { + GXDrawSyncCallback oldcb; + BOOL enabled; + + oldcb = TokenCB; + enabled = OSDisableInterrupts(); + TokenCB = cb; + OSRestoreInterrupts(enabled); + return oldcb; } -/* 8035C524-8035C5AC 356E64 0088+00 1/1 0/0 0/0 .text GXTokenInterruptHandler */ static void GXTokenInterruptHandler(__OSInterrupt interrupt, OSContext* context) { u16 token; - OSContext exceptContext; + OSContext exceptionContext; u32 reg; token = GX_GET_PE_REG(7); - - if (TokenCB) { - OSClearContext(&exceptContext); - OSSetCurrentContext(&exceptContext); + if (TokenCB != NULL) { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); TokenCB(token); - OSClearContext(&exceptContext); + OSClearContext(&exceptionContext); OSSetCurrentContext(context); } - reg = GX_GET_PE_REG(5); - GX_SET_REG(reg, 1, 29, 29); + SET_REG_FIELD(0, reg, 1, 2, 1); GX_SET_PE_REG(5, reg); } -/* 8035C5AC-8035C5F0 356EEC 0044+00 0/0 4/4 0/0 .text GXSetDrawDoneCallback */ -GXDrawDoneCallback GXSetDrawDoneCallback(GXDrawDoneCallback callback) { - BOOL restore; - GXDrawDoneCallback prevCb = DrawDoneCB; - restore = OSDisableInterrupts(); - DrawDoneCB = callback; - OSRestoreInterrupts(restore); - return prevCb; +GXDrawDoneCallback GXSetDrawDoneCallback(GXDrawDoneCallback cb) { + GXDrawDoneCallback oldcb; + BOOL enabled; + + oldcb = DrawDoneCB; + enabled = OSDisableInterrupts(); + DrawDoneCB = cb; + OSRestoreInterrupts(enabled); + return oldcb; } -/* 8035C5F0-8035C670 356F30 0080+00 1/1 0/0 0/0 .text GXFinishInterruptHandler */ static void GXFinishInterruptHandler(__OSInterrupt interrupt, OSContext* context) { - OSContext exceptContext; + OSContext exceptionContext; u32 reg; reg = GX_GET_PE_REG(5); - GX_SET_REG(reg, 1, 28, 28); + SET_REG_FIELD(0, reg, 1, 3, 1); GX_SET_PE_REG(5, reg); - - DrawDone = GX_TRUE; - - if (DrawDoneCB) { - OSClearContext(&exceptContext); - OSSetCurrentContext(&exceptContext); + DrawDone = 1; + if (DrawDoneCB != NULL) { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); DrawDoneCB(); - OSClearContext(&exceptContext); + OSClearContext(&exceptionContext); OSSetCurrentContext(context); } - OSWakeupThread(&FinishQueue); } -/* 8035C670-8035C6E4 356FB0 0074+00 0/0 1/1 0/0 .text __GXPEInit */ void __GXPEInit(void) { - u32 val; - __OSSetInterruptHandler(OS_INTR_PI_PE_TOKEN, GXTokenInterruptHandler); - __OSSetInterruptHandler(OS_INTR_PI_PE_FINISH, GXFinishInterruptHandler); + u32 reg; + __OSSetInterruptHandler(0x12, GXTokenInterruptHandler); + __OSSetInterruptHandler(0x13, GXFinishInterruptHandler); OSInitThreadQueue(&FinishQueue); - __OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_PE_TOKEN); - __OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_PE_FINISH); - val = __peReg[5]; - GX_BITFIELD_SET(val, 0x1d, 1, 1); - GX_BITFIELD_SET(val, 0x1c, 1, 1); - GX_BITFIELD_SET(val, 0x1f, 1, 1); - GX_BITFIELD_SET(val, 0x1e, 1, 1); - __peReg[5] = val; -} \ No newline at end of file + __OSUnmaskInterrupts(0x2000); + __OSUnmaskInterrupts(0x1000); + reg = GX_GET_PE_REG(5); + SET_REG_FIELD(0, reg, 1, 2, 1); + SET_REG_FIELD(0, reg, 1, 3, 1); + SET_REG_FIELD(0, reg, 1, 0, 1); + SET_REG_FIELD(0, reg, 1, 1, 1); + GX_SET_PE_REG(5, reg); +} + +u32 GXCompressZ16(u32 z24, GXZFmt16 zfmt) { + u32 z16; + u32 z24n; + s32 exp; + s32 shift; +#if DEBUG +#define temp exp +#else + s32 temp; + u8 unused[4]; +#endif + + z24n = ~(z24 << 8); + temp = __cntlzw(z24n); + switch (zfmt) { + case GX_ZC_LINEAR: + z16 = (z24 >> 8) & 0xFFFF; + break; + case GX_ZC_NEAR: + if (temp > 3) { + exp = 3; + } else { + exp = temp; + } + if (exp == 3) { + shift = 7; + } else { + shift = 9 - exp; + } + z16 = ((z24 >> shift) & 0x3FFF & ~0xFFFFC000) | (exp << 14); + break; + case GX_ZC_MID: + if (temp > 7) { + exp = 7; + } else { + exp = temp; + } + if (exp == 7) { + shift = 4; + } else { + shift = 10 - exp; + } + z16 = ((z24 >> shift) & 0x1FFF & ~0xFFFFE000) | (exp << 13); + break; + case GX_ZC_FAR: + if (temp > 12) { + exp = 12; + } else { + exp = temp; + } + if (exp == 12) { + shift = 0; + } else { + shift = 11 - exp; + } + z16 = ((z24 >> shift) & 0xFFF & ~0xFFFFF000) | (exp << 12); + break; + default: + OSPanic(__FILE__, 1004, "GXCompressZ16: Invalid Z format\n"); + break; + } + return z16; +} + +u32 GXDecompressZ16(u32 z16, GXZFmt16 zfmt) { + u32 z24; + u32 cb1; + s32 exp; + s32 shift; + + cb1; cb1; cb1; z16; z16; z16; // needed to match + + switch (zfmt) { + case GX_ZC_LINEAR: + z24 = (z16 << 8) & 0xFFFF00; + break; + case GX_ZC_NEAR: + exp = (z16 >> 14) & 3; + if (exp == 3) { + shift = 7; + } else { + shift = 9 - exp; + } + cb1 = -1 << (24 - exp); + z24 = (cb1 | ((z16 & 0x3FFF) << shift)) & 0xFFFFFF; + break; + case GX_ZC_MID: + exp = (z16 >> 13) & 7; + if (exp == 7) { + shift = 4; + } else { + shift = 10 - exp; + } + cb1 = -1 << (24 - exp); + z24 = (cb1 | ((z16 & 0x1FFF) << shift)) & 0xFFFFFF; + break; + case GX_ZC_FAR: + exp = (z16 >> 12) & 0xF; + if (exp == 12) { + shift = 0; + } else { + shift = 11 - exp; + } + cb1 = -1 << (24 - exp); + z24 = (cb1 | ((z16 & 0xFFF) << shift)) & 0xFFFFFF; + break; + default: + OSPanic(__FILE__, 1054, "GXDecompressZ16: Invalid Z format\n"); + break; + } + return z24; +} diff --git a/src/dolphin/gx/GXPerf.c b/src/dolphin/gx/GXPerf.c index 1710d20ddd..9a850eedcc 100644 --- a/src/dolphin/gx/GXPerf.c +++ b/src/dolphin/gx/GXPerf.c @@ -1,8 +1,13 @@ -#include "dolphin/gx/GXPerf.h" -#include "dolphin/gx.h" +#include +#include + +#include "__gx.h" -/* 8036067C-80360EC4 35AFBC 0848+00 2/0 1/1 0/0 .text GXSetGPMetric */ void GXSetGPMetric(GXPerf0 perf0, GXPerf1 perf1) { + u32 reg; + + CHECK_GXBEGIN(134, "GXSetGPMetric"); + switch (__GXData->perf0) { case GX_PERF0_VERTICES: case GX_PERF0_CLIP_VTX: @@ -16,11 +21,9 @@ void GXSetGPMetric(GXPerf0 perf0, GXPerf1 perf1) { case GX_PERF0_XF_REGRD_CLKS: case GX_PERF0_CLIP_RATIO: case GX_PERF0_CLOCKS: - GX_WRITE_U8(0x10); - GX_WRITE_U32(0x1006); - GX_WRITE_U32(0); + reg = 0; + GX_WRITE_XF_REG(6, reg); break; - case GX_PERF0_TRIANGLES: case GX_PERF0_TRIANGLES_CULLED: case GX_PERF0_TRIANGLES_PASSED: @@ -37,10 +40,9 @@ void GXSetGPMetric(GXPerf0 perf0, GXPerf1 perf1) { case GX_PERF0_TRIANGLES_0CLR: case GX_PERF0_TRIANGLES_1CLR: case GX_PERF0_TRIANGLES_2CLR: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x23000000); + reg = 0x23000000; + GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_QUAD_0CVG: case GX_PERF0_QUAD_NON0CVG: case GX_PERF0_QUAD_1CVG: @@ -48,12 +50,14 @@ void GXSetGPMetric(GXPerf0 perf0, GXPerf1 perf1) { case GX_PERF0_QUAD_3CVG: case GX_PERF0_QUAD_4CVG: case GX_PERF0_AVG_QUAD_CNT: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x24000000); + reg = 0x24000000; + GX_WRITE_RAS_REG(reg); break; - case GX_PERF0_NONE: break; + default: + ASSERTMSGLINE(194, 0, "GXSetGPMetric: Invalid GXPerf0 metric name"); + break; } switch (__GXData->perf1) { @@ -67,10 +71,9 @@ void GXSetGPMetric(GXPerf0 perf0, GXPerf1 perf1) { case GX_PERF1_TC_CHECK7_8: case GX_PERF1_TC_MISS: case GX_PERF1_CLOCKS: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x67000000); + reg = 0x67000000; + GX_WRITE_RAS_REG(reg); break; - case GX_PERF1_VC_ELEMQ_FULL: case GX_PERF1_VC_MISSQ_FULL: case GX_PERF1_VC_MEMREQ_FULL: @@ -79,309 +82,350 @@ void GXSetGPMetric(GXPerf0 perf0, GXPerf1 perf1) { case GX_PERF1_VC_STREAMBUF_LOW: case GX_PERF1_VC_ALL_STALLS: case GX_PERF1_VERTICES: - FAST_FLAG_SET(__GXData->perfSel, 0, 4, 4); - GX_WRITE_U8(8); - GX_WRITE_U8(32); - GX_WRITE_U32(__GXData->perfSel); + SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 0); + GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; - case GX_PERF1_FIFO_REQ: case GX_PERF1_CALL_REQ: case GX_PERF1_VC_MISS_REQ: case GX_PERF1_CP_ALL_REQ: - GX_SET_CP_REG(3, 0); + reg = 0; + GX_SET_CP_REG(3, reg); break; - case GX_PERF1_NONE: break; + default: + ASSERTMSGLINE(244, 0, "GXSetGPMetric: Invalid GXPerf1 metric name"); + break; } __GXData->perf0 = perf0; - switch (__GXData->perf0) { case GX_PERF0_VERTICES: - GX_WRITE_U8(0x10); - GX_WRITE_U32(0x1006); - GX_WRITE_U32(0x273); + ASSERTMSGLINE(258, 0, "The use of GX_PERF0_VERTICES is prohibited. Use GX_PERF1_VERTICES instead.\n"); + reg = 0x273; + GX_WRITE_XF_REG(6, reg); break; - case GX_PERF0_CLIP_VTX: - GX_WRITE_U8(0x10); - GX_WRITE_U32(0x1006); - GX_WRITE_U32(0x14A); - break; - case GX_PERF0_CLIP_CLKS: - GX_WRITE_U8(0x10); - GX_WRITE_U32(0x1006); - GX_WRITE_U32(0x16B); - break; - case GX_PERF0_XF_WAIT_IN: - GX_WRITE_U8(0x10); - GX_WRITE_U32(0x1006); - GX_WRITE_U32(0x84); - break; - case GX_PERF0_XF_WAIT_OUT: - GX_WRITE_U8(0x10); - GX_WRITE_U32(0x1006); - GX_WRITE_U32(0xC6); - break; - case GX_PERF0_XF_XFRM_CLKS: - GX_WRITE_U8(0x10); - GX_WRITE_U32(0x1006); - GX_WRITE_U32(0x210); - break; - case GX_PERF0_XF_LIT_CLKS: - GX_WRITE_U8(0x10); - GX_WRITE_U32(0x1006); - GX_WRITE_U32(0x252); - break; - case GX_PERF0_XF_BOT_CLKS: - GX_WRITE_U8(0x10); - GX_WRITE_U32(0x1006); - GX_WRITE_U32(0x231); - break; - case GX_PERF0_XF_REGLD_CLKS: - GX_WRITE_U8(0x10); - GX_WRITE_U32(0x1006); - GX_WRITE_U32(0x1AD); - break; - case GX_PERF0_XF_REGRD_CLKS: - GX_WRITE_U8(0x10); - GX_WRITE_U32(0x1006); - GX_WRITE_U32(0x1CE); - break; - case GX_PERF0_CLOCKS: - GX_WRITE_U8(0x10); - GX_WRITE_U32(0x1006); - GX_WRITE_U32(0x21); - break; - case GX_PERF0_CLIP_RATIO: - GX_WRITE_U8(0x10); - GX_WRITE_U32(0x1006); - GX_WRITE_U32(0x153); - break; - - case GX_PERF0_TRIANGLES: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2300AE7F); - break; - case GX_PERF0_TRIANGLES_CULLED: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x23008E7F); - break; - case GX_PERF0_TRIANGLES_PASSED: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x23009E7F); - break; - case GX_PERF0_TRIANGLES_SCISSORED: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x23001E7F); - break; - case GX_PERF0_TRIANGLES_0TEX: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2300AC3F); - break; - case GX_PERF0_TRIANGLES_1TEX: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2300AC7F); - break; - case GX_PERF0_TRIANGLES_2TEX: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2300ACBF); - break; - case GX_PERF0_TRIANGLES_3TEX: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2300ACFF); - break; - case GX_PERF0_TRIANGLES_4TEX: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2300AD3F); - break; - case GX_PERF0_TRIANGLES_5TEX: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2300AD7F); - break; - case GX_PERF0_TRIANGLES_6TEX: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2300ADBF); - break; - case GX_PERF0_TRIANGLES_7TEX: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2300ADFF); - break; - case GX_PERF0_TRIANGLES_8TEX: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2300AE3F); - break; - case GX_PERF0_TRIANGLES_0CLR: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2300A27F); - break; - case GX_PERF0_TRIANGLES_1CLR: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2300A67F); - break; - case GX_PERF0_TRIANGLES_2CLR: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2300AA7F); - break; - - case GX_PERF0_QUAD_0CVG: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2402C0C6); - break; - case GX_PERF0_QUAD_NON0CVG: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2402C16B); - break; - case GX_PERF0_QUAD_1CVG: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2402C0E7); - break; - case GX_PERF0_QUAD_2CVG: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2402C108); - break; - case GX_PERF0_QUAD_3CVG: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2402C129); - break; - case GX_PERF0_QUAD_4CVG: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2402C14A); - break; - case GX_PERF0_AVG_QUAD_CNT: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x2402C1AD); - break; - - case GX_PERF0_NONE: + case GX_PERF0_CLIP_VTX: reg = 0x14A; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_CLIP_CLKS: reg = 0x16B; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_XF_WAIT_IN: reg = 0x84; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_XF_WAIT_OUT: reg = 0xC6; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_XF_XFRM_CLKS: reg = 0x210; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_XF_LIT_CLKS: reg = 0x252; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_XF_BOT_CLKS: reg = 0x231; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_XF_REGLD_CLKS: reg = 0x1AD; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_XF_REGRD_CLKS: reg = 0x1CE; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_CLOCKS: reg = 0x21; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_CLIP_RATIO: reg = 0x153; GX_WRITE_XF_REG(6, reg); break; + case GX_PERF0_TRIANGLES: reg = 0x2300AE7F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_CULLED: reg = 0x23008E7F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_PASSED: reg = 0x23009E7F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_SCISSORED: reg = 0x23001E7F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_0TEX: reg = 0x2300AC3F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_1TEX: reg = 0x2300AC7F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_2TEX: reg = 0x2300ACBF; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_3TEX: reg = 0x2300ACFF; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_4TEX: reg = 0x2300AD3F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_5TEX: reg = 0x2300AD7F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_6TEX: reg = 0x2300ADBF; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_7TEX: reg = 0x2300ADFF; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_8TEX: reg = 0x2300AE3F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_0CLR: reg = 0x2300A27F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_1CLR: reg = 0x2300A67F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_TRIANGLES_2CLR: reg = 0x2300AA7F; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_QUAD_0CVG: reg = 0x2402C0C6; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_QUAD_NON0CVG: reg = 0x2402C16B; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_QUAD_1CVG: reg = 0x2402C0E7; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_QUAD_2CVG: reg = 0x2402C108; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_QUAD_3CVG: reg = 0x2402C129; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_QUAD_4CVG: reg = 0x2402C14A; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_AVG_QUAD_CNT: reg = 0x2402C1AD; GX_WRITE_RAS_REG(reg); break; + case GX_PERF0_NONE: break; + default: + ASSERTMSGLINE(504, 0, "GXSetGPMetric: Invalid GXPerf0 metric name"); break; } __GXData->perf1 = perf1; - switch (__GXData->perf1) { - case GX_PERF1_TEXELS: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x67000042); - break; - case GX_PERF1_TX_IDLE: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x67000084); - break; - case GX_PERF1_TX_REGS: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x67000063); - break; - case GX_PERF1_TX_MEMSTALL: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x67000129); - break; - case GX_PERF1_TC_MISS: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x67000252); - break; - case GX_PERF1_CLOCKS: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x67000021); - break; - case GX_PERF1_TC_CHECK1_2: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x6700014B); - break; - case GX_PERF1_TC_CHECK3_4: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x6700018D); - break; - case GX_PERF1_TC_CHECK5_6: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x670001CF); - break; - case GX_PERF1_TC_CHECK7_8: - GX_WRITE_U8(0x61); - GX_WRITE_U32(0x67000211); - break; - - case GX_PERF1_VC_ELEMQ_FULL: - FAST_FLAG_SET(__GXData->perfSel, 2, 4, 4); - GX_WRITE_U8(8); - GX_WRITE_U8(32); - GX_WRITE_U32(__GXData->perfSel); - break; - case GX_PERF1_VC_MISSQ_FULL: - FAST_FLAG_SET(__GXData->perfSel, 3, 4, 4); - GX_WRITE_U8(8); - GX_WRITE_U8(32); - GX_WRITE_U32(__GXData->perfSel); - break; - case GX_PERF1_VC_MEMREQ_FULL: - FAST_FLAG_SET(__GXData->perfSel, 4, 4, 4); - GX_WRITE_U8(8); - GX_WRITE_U8(32); - GX_WRITE_U32(__GXData->perfSel); - break; - case GX_PERF1_VC_STATUS7: - FAST_FLAG_SET(__GXData->perfSel, 5, 4, 4); - GX_WRITE_U8(8); - GX_WRITE_U8(32); - GX_WRITE_U32(__GXData->perfSel); - break; - case GX_PERF1_VC_MISSREP_FULL: - FAST_FLAG_SET(__GXData->perfSel, 6, 4, 4); - GX_WRITE_U8(8); - GX_WRITE_U8(32); - GX_WRITE_U32(__GXData->perfSel); - break; - case GX_PERF1_VC_STREAMBUF_LOW: - FAST_FLAG_SET(__GXData->perfSel, 7, 4, 4); - GX_WRITE_U8(8); - GX_WRITE_U8(32); - GX_WRITE_U32(__GXData->perfSel); - break; - case GX_PERF1_VC_ALL_STALLS: - FAST_FLAG_SET(__GXData->perfSel, 9, 4, 4); - GX_WRITE_U8(8); - GX_WRITE_U8(32); - GX_WRITE_U32(__GXData->perfSel); - break; - case GX_PERF1_VERTICES: - FAST_FLAG_SET(__GXData->perfSel, 8, 4, 4); - GX_WRITE_U8(8); - GX_WRITE_U8(32); - GX_WRITE_U32(__GXData->perfSel); - break; - - case GX_PERF1_FIFO_REQ: - GX_SET_CP_REG(3, 2); - break; - case GX_PERF1_CALL_REQ: - GX_SET_CP_REG(3, 3); - break; - case GX_PERF1_VC_MISS_REQ: - GX_SET_CP_REG(3, 4); - break; - case GX_PERF1_CP_ALL_REQ: - GX_SET_CP_REG(3, 5); - break; - - case GX_PERF1_NONE: + case GX_PERF1_TEXELS: reg = 0x67000042; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_TX_IDLE: reg = 0x67000084; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_TX_REGS: reg = 0x67000063; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_TX_MEMSTALL: reg = 0x67000129; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_TC_MISS: reg = 0x67000252; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_CLOCKS: reg = 0x67000021; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_TC_CHECK1_2: reg = 0x6700014B; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_TC_CHECK3_4: reg = 0x6700018D; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_TC_CHECK5_6: reg = 0x670001CF; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_TC_CHECK7_8: reg = 0x67000211; GX_WRITE_RAS_REG(reg); break; + case GX_PERF1_VC_ELEMQ_FULL: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 2); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; + case GX_PERF1_VC_MISSQ_FULL: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 3); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; + case GX_PERF1_VC_MEMREQ_FULL: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 4); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; + case GX_PERF1_VC_STATUS7: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 5); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; + case GX_PERF1_VC_MISSREP_FULL: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 6); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; + case GX_PERF1_VC_STREAMBUF_LOW: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 7); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; + case GX_PERF1_VC_ALL_STALLS: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 9); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; + case GX_PERF1_VERTICES: SET_REG_FIELD(0, __GXData->perfSel, 4, 4, 8); GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); break; + case GX_PERF1_FIFO_REQ: reg = 2; GX_SET_CP_REG(3, reg); break; + case GX_PERF1_CALL_REQ: reg = 3; GX_SET_CP_REG(3, reg); break; + case GX_PERF1_VC_MISS_REQ: reg = 4; GX_SET_CP_REG(3, reg); break; + case GX_PERF1_CP_ALL_REQ: reg = 5; GX_SET_CP_REG(3, reg); break; + case GX_PERF1_NONE: break; + default: + ASSERTMSGLINE(649, 0, "GXSetGPMetric: Invalid GXPerf1 metric name"); break; } - __GXData->bpSentNot = GX_FALSE; + __GXData->bpSentNot = 0; } -/* 80360EC4-80360ED4 35B804 0010+00 0/0 1/1 0/0 .text GXClearGPMetric */ -void GXClearGPMetric(void) { - GX_SET_CP_REG(2, 4); -} - -/* 80360ED4-80360F98 35B814 00C4+00 0/0 1/1 0/0 .text GXReadXfRasMetric */ #pragma scheduling off -void GXReadXfRasMetric(u32* xfWaitIn, u32* xfWaitOut, u32* rasBusy, u32* clocks) { - *rasBusy = GXReadCPReg(32, 33); - *clocks = GXReadCPReg(34, 35); - *xfWaitIn = GXReadCPReg(36, 37); - *xfWaitOut = GXReadCPReg(38, 39); +void GXReadGPMetric(u32* cnt0, u32* cnt1) { + u32 cpCtr0, cpCtr1, cpCtr2, cpCtr3; + + cpCtr0 = __GXReadCPCounterU32(32, 33); + cpCtr1 = __GXReadCPCounterU32(34, 35); + cpCtr2 = __GXReadCPCounterU32(36, 37); + cpCtr3 = __GXReadCPCounterU32(38, 39); + + switch (__GXData->perf0) { + case GX_PERF0_CLIP_RATIO: + *cnt0 = cpCtr1 * 1000 / cpCtr0; + break; + case GX_PERF0_VERTICES: + case GX_PERF0_CLIP_VTX: + case GX_PERF0_CLIP_CLKS: + case GX_PERF0_XF_WAIT_IN: + case GX_PERF0_XF_WAIT_OUT: + case GX_PERF0_XF_XFRM_CLKS: + case GX_PERF0_XF_LIT_CLKS: + case GX_PERF0_XF_BOT_CLKS: + case GX_PERF0_XF_REGLD_CLKS: + case GX_PERF0_XF_REGRD_CLKS: + case GX_PERF0_TRIANGLES: + case GX_PERF0_TRIANGLES_CULLED: + case GX_PERF0_TRIANGLES_PASSED: + case GX_PERF0_TRIANGLES_SCISSORED: + case GX_PERF0_TRIANGLES_0TEX: + case GX_PERF0_TRIANGLES_1TEX: + case GX_PERF0_TRIANGLES_2TEX: + case GX_PERF0_TRIANGLES_3TEX: + case GX_PERF0_TRIANGLES_4TEX: + case GX_PERF0_TRIANGLES_5TEX: + case GX_PERF0_TRIANGLES_6TEX: + case GX_PERF0_TRIANGLES_7TEX: + case GX_PERF0_TRIANGLES_8TEX: + case GX_PERF0_TRIANGLES_0CLR: + case GX_PERF0_TRIANGLES_1CLR: + case GX_PERF0_TRIANGLES_2CLR: + case GX_PERF0_QUAD_0CVG: + case GX_PERF0_QUAD_NON0CVG: + case GX_PERF0_QUAD_1CVG: + case GX_PERF0_QUAD_2CVG: + case GX_PERF0_QUAD_3CVG: + case GX_PERF0_QUAD_4CVG: + case GX_PERF0_AVG_QUAD_CNT: + case GX_PERF0_CLOCKS: + *cnt0 = cpCtr0; + break; + case GX_PERF0_NONE: + *cnt0 = 0; + break; + default: + ASSERTMSGLINE(765, 0, "GXReadGPMetric: Invalid GXPerf0 metric name"); + *cnt0 = 0; + break; + } + + switch (__GXData->perf1) { + case GX_PERF1_TEXELS: + *cnt1 = cpCtr3 * 4; + break; + case GX_PERF1_TC_CHECK1_2: + *cnt1 = cpCtr2 + (cpCtr3 * 2); + break; + case GX_PERF1_TC_CHECK3_4: + *cnt1 = (cpCtr2 * 3) + (cpCtr3 * 4); + break; + case GX_PERF1_TC_CHECK5_6: + *cnt1 = (cpCtr2 * 5) + (cpCtr3 * 6); + break; + case GX_PERF1_TC_CHECK7_8: + *cnt1 = (cpCtr2 * 7) + (cpCtr3 * 8); + break; + case GX_PERF1_TX_IDLE: + case GX_PERF1_TX_REGS: + case GX_PERF1_TX_MEMSTALL: + case GX_PERF1_TC_MISS: + case GX_PERF1_VC_ELEMQ_FULL: + case GX_PERF1_VC_MISSQ_FULL: + case GX_PERF1_VC_MEMREQ_FULL: + case GX_PERF1_VC_STATUS7: + case GX_PERF1_VC_MISSREP_FULL: + case GX_PERF1_VC_STREAMBUF_LOW: + case GX_PERF1_VC_ALL_STALLS: + case GX_PERF1_VERTICES: + case GX_PERF1_CLOCKS: + *cnt1 = cpCtr3; + break; + case GX_PERF1_FIFO_REQ: + case GX_PERF1_CALL_REQ: + case GX_PERF1_VC_MISS_REQ: + case GX_PERF1_CP_ALL_REQ: + *cnt1 = cpCtr2; + break; + case GX_PERF1_NONE: + *cnt1 = 0; + break; + default: + ASSERTMSGLINE(824, 0, "GXReadGPMetric: Invalid GXPerf1 metric name"); + *cnt1 = 0; + break; + } } #pragma scheduling reset + +void GXClearGPMetric(void) { + u32 reg; + + reg = 4; + GX_SET_CP_REG(2, reg); +} + +u32 GXReadGP0Metric(void) { + u32 cnt0, cnt1; + + GXReadGPMetric(&cnt0, &cnt1); + return cnt0; +} + +u32 GXReadGP1Metric(void) { + u32 cnt0, cnt1; + + GXReadGPMetric(&cnt0, &cnt1); + return cnt1; +} + +#pragma scheduling off +void GXReadMemMetric(u32* cp_req, u32* tc_req, u32* cpu_rd_req, u32* cpu_wr_req, u32* dsp_req, u32* io_req, u32* vi_req, u32* pe_req, u32* rf_req, u32* fi_req) { + *cp_req = __GXReadMEMCounterU32(26, 25); + *tc_req = __GXReadMEMCounterU32(28, 27); + *cpu_rd_req = __GXReadMEMCounterU32(30, 29); + *cpu_wr_req = __GXReadMEMCounterU32(32, 31); + *dsp_req = __GXReadMEMCounterU32(34, 33); + *io_req = __GXReadMEMCounterU32(36, 35); + *vi_req = __GXReadMEMCounterU32(38, 37); + *pe_req = __GXReadMEMCounterU32(40, 39); + *rf_req = __GXReadMEMCounterU32(42, 41); + *fi_req = __GXReadMEMCounterU32(44, 43); +} +#pragma scheduling reset + +void GXClearMemMetric(void) { + GX_SET_MEM_REG(25, 0); + GX_SET_MEM_REG(26, 0); + GX_SET_MEM_REG(27, 0); + GX_SET_MEM_REG(28, 0); + GX_SET_MEM_REG(30, 0); + GX_SET_MEM_REG(29, 0); + GX_SET_MEM_REG(32, 0); + GX_SET_MEM_REG(31, 0); + GX_SET_MEM_REG(34, 0); + GX_SET_MEM_REG(33, 0); + GX_SET_MEM_REG(36, 0); + GX_SET_MEM_REG(35, 0); + GX_SET_MEM_REG(38, 0); + GX_SET_MEM_REG(37, 0); + GX_SET_MEM_REG(40, 0); + GX_SET_MEM_REG(39, 0); + GX_SET_MEM_REG(42, 0); + GX_SET_MEM_REG(41, 0); + GX_SET_MEM_REG(44, 0); + GX_SET_MEM_REG(43, 0); +} + +#pragma scheduling off +void GXReadPixMetric(u32* top_pixels_in, u32* top_pixels_out, u32* bot_pixels_in, u32* bot_pixels_out, u32* clr_pixels_in, u32* copy_clks) { + *top_pixels_in = __GXReadPECounterU32(12, 13) * 4; + *top_pixels_out = __GXReadPECounterU32(14, 15) * 4; + *bot_pixels_in = __GXReadPECounterU32(16, 17) * 4; + *bot_pixels_out = __GXReadPECounterU32(18, 19) * 4; + *clr_pixels_in = __GXReadPECounterU32(20, 21) * 4; + *copy_clks = __GXReadPECounterU32(22, 23); +} +#pragma scheduling reset + +void GXClearPixMetric(void) { + u32 reg; + + CHECK_GXBEGIN(1163, "GXClearPixMetric"); + + reg = 0x57000000; + GX_WRITE_RAS_REG(reg); + reg = 0x57000AAA; + GX_WRITE_RAS_REG(reg); + __GXData->bpSentNot = 0; +} + +void GXSetVCacheMetric(GXVCachePerf attr) { + u32 reg; + + SET_REG_FIELD(1194, __GXData->perfSel, 4, 0, attr); + GX_WRITE_SOME_REG4(8, 0x20, __GXData->perfSel, -12); + reg = 1; + GX_WRITE_SOME_REG4(8, 0x10, reg, -12); +} + +#pragma scheduling off +void GXReadVCacheMetric(u32* check, u32* miss, u32* stall) { + *check = __GXReadCPCounterU32(40, 41); + *miss = __GXReadCPCounterU32(42, 43); + *stall = __GXReadCPCounterU32(44, 45); +} +#pragma scheduling reset + +void GXClearVCacheMetric(void) { + GX_WRITE_SOME_REG4(8, 0, 0, -12); +} + +void GXInitXfRasMetric(void) { + u32 reg; + + CHECK_GXBEGIN(1293, "GXInitXfRasMetric"); + + reg = 0x2402C022; + GX_WRITE_RAS_REG(reg); + reg = 0x31000; + GX_WRITE_XF_REG(6, reg); + __GXData->bpSentNot = 1; +} + +#pragma scheduling off +void GXReadXfRasMetric(u32* xf_wait_in, u32* xf_wait_out, u32* ras_busy, u32* clocks) { + *ras_busy = __GXReadCPCounterU32(32, 33); + *clocks = __GXReadCPCounterU32(34, 35); + *xf_wait_in = __GXReadCPCounterU32(36, 37); + *xf_wait_out = __GXReadCPCounterU32(38, 39); +} +#pragma scheduling reset + +u32 GXReadClksPerVtx(void) { + u32 perfCnt; + u32 ctrh; + + GXDrawDone(); + GX_SET_CP_REG(49, 0x1007); + GX_SET_CP_REG(48, 0x1007); + + ctrh = GX_GET_CP_REG(50); + perfCnt = ctrh >> 8; + return perfCnt; +} + +void __GXSetBWDials(u16 cpDial, u16 tcDial, u16 peDial, u16 cpuRdDial, u16 cpuWrDial) { + __MEMRegs[9] = cpDial; + __MEMRegs[10] = tcDial; + __MEMRegs[11] = peDial; + __MEMRegs[12] = cpuRdDial; + __MEMRegs[13] = cpuWrDial; +} diff --git a/src/dolphin/gx/GXPixel.c b/src/dolphin/gx/GXPixel.c index 4fa79b15de..027276cf0a 100644 --- a/src/dolphin/gx/GXPixel.c +++ b/src/dolphin/gx/GXPixel.c @@ -1,247 +1,334 @@ -#include "dolphin/gx/GXPixel.h" -#include "dolphin/gx.h" +#include +#include +#include + +#include "__gx.h" -/* 8035F8B8-8035FACC 35A1F8 0214+00 0/0 20/20 2/2 .text GXSetFog */ void GXSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color) { - f32 a, c; - u32 a_bits, c_bits; + u32 fogclr; + u32 fog0; + u32 fog1; + u32 fog2; + u32 fog3; + f32 A; + f32 B; + f32 B_mant; + f32 C; + f32 a; + f32 c; + u32 B_expn; + u32 b_m; + u32 b_s; + u32 a_hex; + u32 c_hex; + u32 fsel; + u32 proj; + u32 rgba; - u32 fogColorReg = 0; - u32 fogParamReg0 = 0; - u32 fogParamReg1 = 0; - u32 fogParamReg2 = 0; - u32 fogParamReg3 = 0; + fogclr = 0; + fog0 = 0; + fog1 = 0; + fog2 = 0; + fog3 = 0; - u32 fsel = type & 7; - BOOL isOrtho = (type >> 3) & 1; - u32 col; + CHECK_GXBEGIN(138, "GXSetFog"); - if (isOrtho) { + ASSERTMSGLINE(140, farz >= 0.0f, "GXSetFog: The farz should be positive value"); + ASSERTMSGLINE(141, farz >= nearz, "GXSetFog: The farz should be larger than nearz"); + + fsel = type & 7; + proj = (type >> 3) & 1; + + if (proj) { if (farz == nearz || endz == startz) { a = 0.0f; c = 0.0f; } else { - a = (1.0f / (endz - startz)) * (farz - nearz); - c = (1.0f / (endz - startz)) * (startz - nearz); + A = (1.0f / (endz - startz)); + a = A * (farz - nearz); + c = A * (startz - nearz); } } else { - f32 tmpA, tmpB, tmpC; - u32 expB, magB, shiftB; - if (farz == nearz || endz == startz) { - tmpA = 0.0f; - tmpB = 0.5f; - tmpC = 0.0f; + A = 0.0f; + B = 0.5f; + C = 0.0f; } else { - tmpA = (farz * nearz) / ((farz - nearz) * (endz - startz)); - tmpB = farz / (farz - nearz); - tmpC = startz / (endz - startz); + A = (farz * nearz) / ((farz - nearz) * (endz - startz)); + B = farz / (farz - nearz); + C = startz / (endz - startz); } - expB = 0; - while (tmpB > 1.0) { - tmpB /= 2.0f; - expB++; + B_mant = B; + B_expn = 0; + while (B_mant > 1.0) { + B_mant /= 2.0f; + B_expn++; } - while (tmpB > 0.0f && tmpB < 0.5) { - tmpB *= 2.0f; - expB--; + while (B_mant > 0.0f && B_mant < 0.5) { + B_mant *= 2.0f; + B_expn--; } - a = tmpA / (1 << expB + 1); - magB = 8388638.0f * tmpB; - shiftB = expB + 1; - c = tmpC; + a = A / (f32) (1 << (B_expn + 1)); + b_m = 8.388638e6f * B_mant; + b_s = B_expn + 1; + c = C; - GX_SET_REG(fogParamReg1, magB, GX_BP_FOGPARAM1_B_MAG_ST, GX_BP_FOGPARAM1_B_MAG_END); - GX_SET_REG(fogParamReg2, shiftB, GX_BP_FOGPARAM2_B_SHIFT_ST, GX_BP_FOGPARAM2_B_SHIFT_END); + SET_REG_FIELD(198, fog1, 24, 0, b_m); + SET_REG_FIELD(198, fog1, 8, 24, 0xEF); - GX_SET_REG(fogParamReg1, GX_BP_REG_FOGPARAM1, 0, 7); - GX_SET_REG(fogParamReg2, GX_BP_REG_FOGPARAM2, 0, 7); + SET_REG_FIELD(201, fog2, 5, 0, b_s); + SET_REG_FIELD(201, fog2, 8, 24, 0xF0); } - a_bits = *(u32*)&a; - c_bits = *(u32*)&c; + a_hex = *(u32 *)&a; + c_hex = *(u32 *)&c; - GX_SET_REG(fogParamReg0, a_bits >> 12, GX_BP_FOGPARAM0_A_MANT_ST, GX_BP_FOGPARAM0_A_MANT_END); - GX_SET_REG(fogParamReg0, a_bits >> 23, GX_BP_FOGPARAM0_A_EXP_ST, GX_BP_FOGPARAM0_A_EXP_END); - GX_SET_REG(fogParamReg0, a_bits >> 31, GX_BP_FOGPARAM0_A_SIGN_ST, GX_BP_FOGPARAM0_A_SIGN_END); - GX_SET_REG(fogParamReg0, GX_BP_REG_FOGPARAM0, 0, 7); + SET_REG_FIELD(209, fog0, 11, 0, (a_hex >> 12) & 0x7FF); + SET_REG_FIELD(210, fog0, 8, 11, (a_hex >> 23) & 0xFF); + SET_REG_FIELD(211, fog0, 1, 19, (a_hex >> 31)); + SET_REG_FIELD(211, fog0, 8, 24, 0xEE); - GX_SET_REG(fogParamReg3, c_bits >> 12, GX_BP_FOGPARAM3_C_MANT_ST, GX_BP_FOGPARAM3_C_MANT_END); - GX_SET_REG(fogParamReg3, c_bits >> 23, GX_BP_FOGPARAM3_C_EXP_ST, GX_BP_FOGPARAM3_C_EXP_END); - GX_SET_REG(fogParamReg3, c_bits >> 31, GX_BP_FOGPARAM3_C_SIGN_ST, GX_BP_FOGPARAM3_C_SIGN_END); - GX_SET_REG(fogParamReg3, isOrtho, GX_BP_FOGPARAM3_PROJ_ST, GX_BP_FOGPARAM3_PROJ_END); - GX_SET_REG(fogParamReg3, fsel, GX_BP_FOGPARAM3_FSEL_ST, GX_BP_FOGPARAM3_FSEL_END); - GX_SET_REG(fogParamReg3, GX_BP_REG_FOGPARAM3, 0, 7); + SET_REG_FIELD(214, fog3, 11, 0, (c_hex >> 12) & 0x7FF); + SET_REG_FIELD(215, fog3, 8, 11, (c_hex >> 23) & 0xFF); + SET_REG_FIELD(216, fog3, 1, 19, (c_hex >> 31)); - col = *(u32*)&color; - GX_SET_REG(fogColorReg, col >> 8, GX_BP_FOGCOLOR_RGB_ST, GX_BP_FOGCOLOR_RGB_END); - GX_SET_REG(fogColorReg, GX_BP_REG_FOGCOLOR, 0, 7); + SET_REG_FIELD(217, fog3, 1, 20, proj); + SET_REG_FIELD(218, fog3, 3, 21, fsel); + SET_REG_FIELD(218, fog3, 8, 24, 0xF1); - GX_BP_LOAD_REG(fogParamReg0); - GX_BP_LOAD_REG(fogParamReg1); - GX_BP_LOAD_REG(fogParamReg2); - GX_BP_LOAD_REG(fogParamReg3); - GX_BP_LOAD_REG(fogColorReg); + rgba = *(u32*)&color; + SET_REG_FIELD(222, fogclr, 24, 0, rgba >> 8); + SET_REG_FIELD(222, fogclr, 8, 24, 0xF2); - __GXData->bpSentNot = GX_FALSE; + GX_WRITE_RAS_REG(fog0); + GX_WRITE_RAS_REG(fog1); + GX_WRITE_RAS_REG(fog2); + GX_WRITE_RAS_REG(fog3); + GX_WRITE_RAS_REG(fogclr); + + __GXData->bpSentNot = 0; } -/* 8035FACC-8035FBF0 35A40C 0124+00 0/0 9/9 2/2 .text GXSetFogRangeAdj */ -void GXSetFogRangeAdj(GXBool enable, u16 center, GXFogAdjTable* table) { - u32 fogRangeReg; - u32 fogRangeRegK; +void GXSetFogColor(GXColor color) { + u32 rgba; + u32 fogclr = 0xF2000000; + + rgba = *(u32*)&color; + SET_REG_FIELD(250, fogclr, 24, 0, rgba >> 8); + GX_WRITE_RAS_REG(fogclr); + __GXData->bpSentNot = 0; +} + +void GXInitFogAdjTable(GXFogAdjTable *table, u16 width, const f32 projmtx[4][4]) { + f32 xi; + f32 iw; + f32 rangeVal; + f32 nearZ; + f32 sideX; u32 i; + CHECK_GXBEGIN(275, "GXInitFogAdjTable"); + ASSERTMSGLINE(276, table != NULL, "GXInitFogAdjTable: table pointer is null"); + ASSERTMSGLINE(277, width <= 640, "GXInitFogAdjTable: invalid width value"); + + if (0.0 == projmtx[3][3]) { + nearZ = projmtx[2][3] / (projmtx[2][2] - 1.0f); + sideX = nearZ / projmtx[0][0]; + } else { + sideX = 1.0f / projmtx[0][0]; + nearZ = 1.73205f * sideX; + } + + iw = 2.0f / width; + for (i = 0; i < 10; i++) { + xi = (i + 1) << 5; + xi *= iw; + xi *= sideX; + rangeVal = sqrtf(1.0f + ((xi * xi) / (nearZ * nearZ))); + table->r[i] = (u32)(256.0f * rangeVal) & 0xFFF; + } +} + +void GXSetFogRangeAdj(GXBool enable, u16 center, const GXFogAdjTable *table) { + u32 i; + u32 range_adj; + u32 range_c; + + CHECK_GXBEGIN(331, "GXSetFogRangeAdj"); + if (enable) { + ASSERTMSGLINE(334, table != NULL, "GXSetFogRangeAdj: table pointer is null"); for (i = 0; i < 10; i += 2) { - fogRangeRegK = 0; - GX_SET_REG(fogRangeRegK, table->fogVals[i], GX_BP_FOGRANGEK_HI_ST, - GX_BP_FOGRANGEK_HI_END); - GX_SET_REG(fogRangeRegK, table->fogVals[i + 1], GX_BP_FOGRANGEK_LO_ST, - GX_BP_FOGRANGEK_LO_END); - GX_SET_REG(fogRangeRegK, GX_BP_REG_FOGRANGEK0 + (i / 2), 0, 7); - GX_BP_LOAD_REG(fogRangeRegK); + range_adj = 0; + SET_REG_FIELD(338, range_adj, 12, 0, table->r[i]); + SET_REG_FIELD(339, range_adj, 12, 12, table->r[i + 1]); + SET_REG_FIELD(340, range_adj, 8, 24, (i >> 1) + 0xE9); + GX_WRITE_RAS_REG(range_adj); } } - - fogRangeReg = 0; - GX_SET_REG(fogRangeReg, center + 342, GX_BP_FOGRANGE_CENTER_ST, GX_BP_FOGRANGE_CENTER_END); - GX_SET_REG(fogRangeReg, enable, GX_BP_FOGRANGE_ENABLED_ST, GX_BP_FOGRANGE_ENABLED_END); - GX_SET_REG(fogRangeReg, GX_BP_REG_FOGRANGE, 0, 7); - GX_BP_LOAD_REG(fogRangeReg); - - __GXData->bpSentNot = GX_FALSE; + range_c = 0; + SET_REG_FIELD(346, range_c, 10, 0, center + 342); + SET_REG_FIELD(347, range_c, 1, 10, enable); + SET_REG_FIELD(348, range_c, 8, 24, 0xE8); + GX_WRITE_RAS_REG(range_c); + __GXData->bpSentNot = 0; } -/* 8035FBF0-8035FC44 35A530 0054+00 0/0 53/53 3/3 .text GXSetBlendMode */ -void GXSetBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor, - GXLogicOp op) { - u32 blendModeReg = __GXData->cmode0; - GX_SET_REG(blendModeReg, type == GX_BM_SUBTRACT, GX_BP_BLENDMODE_SUBTRACT_ST, - GX_BP_BLENDMODE_SUBTRACT_END); - GX_SET_REG(blendModeReg, type, GX_BP_BLENDMODE_ENABLE_ST, GX_BP_BLENDMODE_ENABLE_END); - GX_SET_REG(blendModeReg, type == GX_BM_LOGIC, GX_BP_BLENDMODE_LOGIC_OP_ST, - GX_BP_BLENDMODE_LOGIC_OP_END); - GX_SET_REG(blendModeReg, op, GX_BP_BLENDMODE_LOGICMODE_ST, GX_BP_BLENDMODE_LOGICMODE_END); - GX_SET_REG(blendModeReg, src_factor, GX_BP_BLENDMODE_SRCFACTOR_ST, - GX_BP_BLENDMODE_SRCFACTOR_END); - GX_SET_REG(blendModeReg, dst_factor, GX_BP_BLENDMODE_DSTFACTOR_ST, - GX_BP_BLENDMODE_DSTFACTOR_END); +void GXSetBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor, GXLogicOp op) { + u32 reg; + u32 blend_en; - GX_BP_LOAD_REG(blendModeReg); - __GXData->cmode0 = blendModeReg; + CHECK_GXBEGIN(375, "GXSetBlendMode"); - __GXData->bpSentNot = FALSE; + reg = __GXData->cmode0; + +#if DEBUG + blend_en = type == GX_BM_BLEND || type == GX_BM_SUBTRACT; +#endif + + SET_REG_FIELD(389, reg, 1, 11, (type == GX_BM_SUBTRACT)); +#if DEBUG + SET_REG_FIELD(392, reg, 1, 0, blend_en); +#else + SET_REG_FIELD(392, reg, 1, 0, type); +#endif + SET_REG_FIELD(393, reg, 1, 1, (type == GX_BM_LOGIC)); + SET_REG_FIELD(394, reg, 4, 12, op); + SET_REG_FIELD(395, reg, 3, 8, src_factor); + SET_REG_FIELD(396, reg, 3, 5, dst_factor); + GX_WRITE_RAS_REG(reg); + + __GXData->cmode0 = reg; + __GXData->bpSentNot = 0; } -/* 8035FC44-8035FC70 35A584 002C+00 0/0 10/10 2/2 .text GXSetColorUpdate */ -void GXSetColorUpdate(GXBool updateEnable) { - u32 blendModeReg = __GXData->cmode0; - GX_SET_REG(blendModeReg, updateEnable, GX_BP_BLENDMODE_COLOR_UPDATE_ST, - GX_BP_BLENDMODE_COLOR_UPDATE_END); - GX_BP_LOAD_REG(blendModeReg); - __GXData->cmode0 = blendModeReg; - __GXData->bpSentNot = GX_FALSE; +void GXSetColorUpdate(GXBool update_enable) { + u32 reg; + CHECK_GXBEGIN(419, "GXSetColorUpdate"); + + reg = __GXData->cmode0; + + SET_REG_FIELD(421, reg, 1, 3, update_enable); + GX_WRITE_RAS_REG(reg); + + __GXData->cmode0 = reg; + __GXData->bpSentNot = 0; } -/* 8035FC70-8035FC9C 35A5B0 002C+00 0/0 10/10 2/2 .text GXSetAlphaUpdate */ -void GXSetAlphaUpdate(GXBool updateEnable) { - u32 blendModeReg = __GXData->cmode0; - GX_SET_REG(blendModeReg, updateEnable, GX_BP_BLENDMODE_ALPHA_UPDATE_ST, - GX_BP_BLENDMODE_ALPHA_UPDATE_END); - GX_BP_LOAD_REG(blendModeReg); - __GXData->cmode0 = blendModeReg; - __GXData->bpSentNot = GX_FALSE; +void GXSetAlphaUpdate(GXBool update_enable) { + u32 reg; + CHECK_GXBEGIN(432, "GXSetAlphaUpdate"); + + reg = __GXData->cmode0; + + SET_REG_FIELD(434, reg, 1, 4, update_enable); + GX_WRITE_RAS_REG(reg); + + __GXData->cmode0 = reg; + __GXData->bpSentNot = 0; } -/* 8035FC9C-8035FCD0 35A5DC 0034+00 0/0 40/40 6/6 .text GXSetZMode */ -void GXSetZMode(GXBool compareEnable, GXCompare func, GXBool updateEnable) { - u32 zModeReg = __GXData->zmode; - GX_SET_REG(zModeReg, compareEnable, GX_BP_ZMODE_TEST_ENABLE_ST, GX_BP_ZMODE_TEST_ENABLE_END); - GX_SET_REG(zModeReg, func, GX_BP_ZMODE_COMPARE_ST, GX_BP_ZMODE_COMPARE_END); - GX_SET_REG(zModeReg, updateEnable, GX_BP_ZMODE_UPDATE_ENABLE_ST, GX_BP_ZMODE_UPDATE_ENABLE_END); - GX_BP_LOAD_REG(zModeReg); - __GXData->zmode = zModeReg; - __GXData->bpSentNot = GX_FALSE; +void GXSetZMode(GXBool compare_enable, GXCompare func, GXBool update_enable) { + u32 reg; + CHECK_GXBEGIN(459, "GXSetZMode"); + + reg = __GXData->zmode; + + SET_REG_FIELD(462, reg, 1, 0, compare_enable); + SET_REG_FIELD(463, reg, 3, 1, func); + SET_REG_FIELD(464, reg, 1, 4, update_enable); + GX_WRITE_RAS_REG(reg); + + __GXData->zmode = reg; + __GXData->bpSentNot = 0; } -/* 8035FCD0-8035FD04 35A610 0034+00 0/0 29/29 5/5 .text GXSetZCompLoc */ -void GXSetZCompLoc(GXBool beforeTex) { - GX_SET_REG(__GXData->peCtrl, beforeTex, GX_BP_ZCONTROL_BEFORE_TEX_ST, - GX_BP_ZCONTROL_BEFORE_TEX_END); - GX_BP_LOAD_REG(__GXData->peCtrl); - __GXData->bpSentNot = GX_FALSE; +void GXSetZCompLoc(GXBool before_tex) { + CHECK_GXBEGIN(474, "GXSetZCompLoc"); + SET_REG_FIELD(475, __GXData->peCtrl, 1, 6, before_tex); + GX_WRITE_RAS_REG(__GXData->peCtrl); + __GXData->bpSentNot = 0; } -/* 8035FD04-8035FDD8 35A644 00D4+00 0/0 2/2 1/1 .text GXSetPixelFmt */ -void GXSetPixelFmt(GXPixelFmt pixelFmt, GXZFmt16 zFmt) { - GXBool isZ16; - static u32 p2f[GX_PF_MAX] = {GX_PF_RGB8_Z24, GX_PF_RGBA6_Z24, GX_PF_RGB565_Z16, GX_PF_Z24, - GX_PF_Y8, GX_PF_Y8, GX_PF_Y8, GX_PF_U8}; +void GXSetPixelFmt(GXPixelFmt pix_fmt, GXZFmt16 z_fmt) { + u32 oldPeCtrl; + u8 aa; + static u32 p2f[8] = { 0, 1, 2, 3, 4, 4, 4, 5 }; - const u32 zControlRegOld = __GXData->peCtrl; + CHECK_GXBEGIN(511, "GXSetPixelFmt"); + oldPeCtrl = __GXData->peCtrl; + ASSERTMSGLINE(515, pix_fmt >= GX_PF_RGB8_Z24 && pix_fmt <= GX_PF_YUV420, "Invalid Pixel format"); + SET_REG_FIELD(517, __GXData->peCtrl, 3, 0, p2f[pix_fmt]); + SET_REG_FIELD(518, __GXData->peCtrl, 3, 3, z_fmt); - GX_SET_REG(__GXData->peCtrl, p2f[pixelFmt], GX_BP_ZCONTROL_PIXEL_FMT_ST, - GX_BP_ZCONTROL_PIXEL_FMT_END); - GX_SET_REG(__GXData->peCtrl, zFmt, GX_BP_ZCONTROL_Z_FMT_ST, GX_BP_ZCONTROL_Z_FMT_END); - - if (zControlRegOld != __GXData->peCtrl) { - GX_BP_LOAD_REG(__GXData->peCtrl); - isZ16 = (pixelFmt == GX_PF_RGB565_Z16) ? GX_TRUE : GX_FALSE; - GX_SET_REG(__GXData->genMode, isZ16, GX_BP_GENMODE_MULTISAMPLE_ST, - GX_BP_GENMODE_MULTISAMPLE_END); - __GXData->dirtyState |= GX_DIRTY_GEN_MODE; + if (oldPeCtrl != __GXData->peCtrl) { + GX_WRITE_RAS_REG(__GXData->peCtrl); + if (pix_fmt == GX_PF_RGB565_Z16) + aa = 1; + else + aa = 0; + SET_REG_FIELD(527, __GXData->genMode, 1, 9, aa); + __GXData->dirtyState |= 4; } - if (p2f[pixelFmt] == GX_PF_Y8) { - GX_SET_REG(__GXData->cmode1, pixelFmt - GX_PF_Y8, GX_BP_DSTALPHA_YUV_FMT_ST, - GX_BP_DSTALPHA_YUV_FMT_END); - GX_SET_REG(__GXData->cmode1, GX_BP_REG_DSTALPHA, 0, 7); - GX_BP_LOAD_REG(__GXData->cmode1); + if (p2f[pix_fmt] == 4) { + SET_REG_FIELD(534, __GXData->cmode1, 2, 9, (pix_fmt - 4) & 0x3); + SET_REG_FIELD(534, __GXData->cmode1, 8, 24, 0x42); + GX_WRITE_RAS_REG(__GXData->cmode1); } - __GXData->bpSentNot = FALSE; + __GXData->bpSentNot = 0; } -/* 8035FDD8-8035FE04 35A718 002C+00 0/0 22/22 1/1 .text GXSetDither */ void GXSetDither(GXBool dither) { - u32 blendModeReg = __GXData->cmode0; - GX_SET_REG(blendModeReg, dither, GX_BP_BLENDMODE_DITHER_ST, GX_BP_BLENDMODE_DITHER_END); - GX_BP_LOAD_REG(blendModeReg); - __GXData->cmode0 = blendModeReg; - __GXData->bpSentNot = GX_FALSE; + u32 reg; + CHECK_GXBEGIN(556, "GXSetDither"); + + reg = __GXData->cmode0; + + SET_REG_FIELD(559, reg, 1, 2, dither); + GX_WRITE_RAS_REG(reg); + + __GXData->cmode0 = reg; + __GXData->bpSentNot = 0; } -/* 8035FE04-8035FE40 35A744 003C+00 0/0 2/2 0/0 .text GXSetDstAlpha */ void GXSetDstAlpha(GXBool enable, u8 alpha) { - u32 dstAlpha = __GXData->cmode1; - GX_SET_REG(dstAlpha, alpha, GX_BP_DSTALPHA_ALPHA_ST, GX_BP_DSTALPHA_ALPHA_END); - GX_SET_REG(dstAlpha, enable, GX_BP_DSTALPHA_ENABLE_ST, GX_BP_DSTALPHA_ENABLE_END); - GX_BP_LOAD_REG(dstAlpha); - __GXData->cmode1 = dstAlpha; - __GXData->bpSentNot = GX_FALSE; + u32 reg; + CHECK_GXBEGIN(581, "GXSetDstAlpha"); + + reg = __GXData->cmode1; + + SET_REG_FIELD(584, reg, 8, 0, alpha); + SET_REG_FIELD(585, reg, 1, 8, enable); + GX_WRITE_RAS_REG(reg); + + __GXData->cmode1 = reg; + __GXData->bpSentNot = 0; } -/* 8035FE40-8035FE78 35A780 0038+00 0/0 1/1 0/0 .text GXSetFieldMask */ -void GXSetFieldMask(GXBool enableEven, GXBool enableOdd) { - u32 fieldMaskReg = 0; - GX_SET_REG(fieldMaskReg, enableOdd, GX_BP_FIELDMASK_ODD_ST, GX_BP_FIELDMASK_ODD_END); - GX_SET_REG(fieldMaskReg, enableEven, GX_BP_FIELDMASK_EVEN_ST, GX_BP_FIELDMASK_EVEN_END); - GX_SET_REG(fieldMaskReg, GX_BP_REG_FIELDMASK, 0, 7); +void GXSetFieldMask(GXBool odd_mask, GXBool even_mask) { + u32 reg; - GX_BP_LOAD_REG(fieldMaskReg); - __GXData->bpSentNot = GX_FALSE; + CHECK_GXBEGIN(608, "GXSetFieldMask"); + reg = 0; + SET_REG_FIELD(610, reg, 1, 0, even_mask); + SET_REG_FIELD(611, reg, 1, 1, odd_mask); + SET_REG_FIELD(611, reg, 8, 24, 0x44); + GX_WRITE_RAS_REG(reg); + __GXData->bpSentNot = 0; } -/* 8035FE78-8035FEF0 35A7B8 0078+00 0/0 1/1 0/0 .text GXSetFieldMode */ -void GXSetFieldMode(GXBool texLOD, GXBool adjustAR) { - GX_SET_REG(__GXData->lpSize, adjustAR, GX_BP_LINEPTWIDTH_ADJUST_ST, - GX_BP_LINEPTWIDTH_ADJUST_END); - GX_BP_LOAD_REG(__GXData->lpSize); +void GXSetFieldMode(GXBool field_mode, GXBool half_aspect_ratio) { + u32 reg; + CHECK_GXBEGIN(637, "GXSetFieldMode"); + SET_REG_FIELD(641, __GXData->lpSize, 1, 22, half_aspect_ratio); + GX_WRITE_RAS_REG(__GXData->lpSize); __GXFlushTextureState(); - GX_BP_LOAD_REG(GX_BP_REG_FIELDMODE << 24 | texLOD); + reg = field_mode | 0x68000000; + GX_WRITE_RAS_REG(reg); __GXFlushTextureState(); -} \ No newline at end of file +} diff --git a/src/dolphin/gx/GXSave.c b/src/dolphin/gx/GXSave.c new file mode 100644 index 0000000000..90b9a828a8 --- /dev/null +++ b/src/dolphin/gx/GXSave.c @@ -0,0 +1,528 @@ +#if DEBUG + +#include +#include + +#include "__gx.h" + +static const u8* dlist; +static u32 dlistSize; +static u32 bytesRead; + +// prototypes +void __GXShadowIndexState(u32 idx_reg, u32 reg_data); + +static u8 __ReadMem(void* ptr, u32 sz) { + const u8* src; + u8* dst; + u32 i; + + if (sz > dlistSize - bytesRead) { + return FALSE; + } + + src = dlist; + dst = ptr; + for (i = 0; i < sz; i++) { + *dst++ = *src++; + } + bytesRead += sz; + dlist += sz; + return TRUE; +} + +inline void DPF(char*, ...) { + u8 unused[4]; +} + +static void __SaveCPRegs(u8 reg, u8 vatIdx, u32 data) { + s32 idx; + + DPF("\tCP Stream Reg[0x%x] = 0x%x\n", reg, data); + + switch (reg) { + case 0: + case 1: + case 2: + case 3: + case 4: + break; + case 5: + __GXData->vcdLo = data; + break; + case 6: + __GXData->vcdHi = data; + break; + case 7: + __GXData->vatA[vatIdx & 0xFF] = data; + break; + case 8: + __GXData->vatB[vatIdx & 0xFF] = data; + break; + case 9: + __GXData->vatC[vatIdx & 0xFF] = data; + break; + case 10: + idx = vatIdx - 0x15; + if ((idx >= 0) && (idx < 4)) { + __GXData->indexBase[idx] = data; + } + break; + case 11: + idx = vatIdx - 0x15; + if ((idx >= 0) && (idx < 4)) { + __GXData->indexStride[idx] = data; + } + break; + default: + if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_DL_INV_CMD]) { + __GX_WARN(GXWARN_DL_INV_CMD); + } + OSReport("[Invalid CP Stream Register Address 0x%x\n]", reg); + break; + } +} + +static void __ReconstVtxStatus(u8 vatIdx) { + u32 vat; + + if (GET_REG_FIELD(__GXData->vcdLo, 2, 11) & 3) { + vat = __GXData->vatA[vatIdx]; + if ((vat >> 9) & 1) { + __GXData->hasNrms = 0; + __GXData->hasBiNrms = 1; + } else { + __GXData->hasNrms = 1; + __GXData->hasBiNrms = 0; + } + } +} + +static u32 vtxCompSize[5] = { 1, 1, 2, 2, 4 }; +static int clrCompSize[6] = { 2, 3, 4, 2, 3, 4 }; + +static u32 GetAttrSize(u8 vatIdx, u32 attrIdx) { + u32 vcd; + u32 vat; + u32 nc; + + switch (attrIdx) { + case 0: + return GET_REG_FIELD(__GXData->vcdLo, 1, 0) ? 1 : 0; + case 1: + return GET_REG_FIELD(__GXData->vcdLo, 1, 1) ? 1 : 0; + case 2: + return GET_REG_FIELD(__GXData->vcdLo, 1, 2) ? 1 : 0; + case 3: + return GET_REG_FIELD(__GXData->vcdLo, 1, 3) ? 1 : 0; + case 4: + return GET_REG_FIELD(__GXData->vcdLo, 1, 4) ? 1 : 0; + case 5: + return GET_REG_FIELD(__GXData->vcdLo, 1, 5) ? 1 : 0; + case 6: + return GET_REG_FIELD(__GXData->vcdLo, 1, 6) ? 1 : 0; + case 7: + return GET_REG_FIELD(__GXData->vcdLo, 1, 7) ? 1 : 0; + case 8: + return GET_REG_FIELD(__GXData->vcdLo, 1, 8) ? 1 : 0; + case 9: + vcd = __GXData->vcdLo; + vat = __GXData->vatA[vatIdx & 0xFF]; + switch (GET_REG_FIELD(vcd, 2, 9)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + return ((vat & 1) + 2) * vtxCompSize[(vat >> 1) & 7]; + } + break; + case 10: + vcd = __GXData->vcdLo; + vat = __GXData->vatA[vatIdx & 0xFF]; + + switch (GET_REG_FIELD(vcd, 2, 11)) { + case 0: + return 0; + case 2: + if ((vat >> 9) & 1 && vat >> 31) { + nc = 3; + } else { + nc = 1; + } + return nc; + case 3: + if ((vat >> 9) & 1 && vat >> 31) { + nc = 6; + } else { + nc = 2; + } + return nc; + case 1: + if ((vat >> 9) & 1) { + nc = 9; + } else { + nc = 3; + } + return nc * vtxCompSize[(vat >> 10) & 7]; + } + break; + case 11: + switch (GET_REG_FIELD(__GXData->vcdLo, 2, 13)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + vat = __GXData->vatA[vatIdx]; + return clrCompSize[(vat >> 14) & 7]; + } + break; + case 12: + switch (GET_REG_FIELD(__GXData->vcdLo, 2, 15)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + vat = __GXData->vatA[vatIdx]; + return clrCompSize[(vat >> 18) & 7]; + } + break; + case 13: + vcd = __GXData->vcdHi; + vat = __GXData->vatA[vatIdx & 0xFF]; + switch (GET_REG_FIELD(vcd, 2, 0)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + return (((vat >> 21) & 1) + 1) * vtxCompSize[(vat >> 22) & 7]; + } + break; + case 14: + vcd = __GXData->vcdHi; + vat = __GXData->vatB[vatIdx & 0xFF]; + switch (GET_REG_FIELD(vcd, 2, 2)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + return (((vat >> 0) & 1) + 1) * vtxCompSize[(vat >> 1) & 7]; + } + break; + case 15: + vcd = __GXData->vcdHi; + vat = __GXData->vatB[vatIdx & 0xFF]; + switch (GET_REG_FIELD(vcd, 2, 4)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + return (((vat >> 9) & 1) + 1) * vtxCompSize[(vat >> 10) & 7]; + } + break; + case 16: + vcd = __GXData->vcdHi; + vat = __GXData->vatB[vatIdx & 0xFF]; + switch (GET_REG_FIELD(vcd, 2, 6)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + return (((vat >> 18) & 1) + 1) * vtxCompSize[(vat >> 19) & 7]; + } + break; + case 17: + vcd = __GXData->vcdHi; + vat = __GXData->vatB[vatIdx & 0xFF]; + switch (GET_REG_FIELD(vcd, 2, 8)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + return (((vat >> 27) & 1) + 1) * vtxCompSize[(vat >> 28) & 7]; + } + break; + case 18: + vcd = __GXData->vcdHi; + vat = __GXData->vatC[vatIdx & 0xFF]; + switch (GET_REG_FIELD(vcd, 2, 10)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + return (((vat >> 5) & 1) + 1) * vtxCompSize[(vat >> 6) & 7]; + } + break; + case 19: + vcd = __GXData->vcdHi; + vat = __GXData->vatC[vatIdx & 0xFF]; + switch (GET_REG_FIELD(vcd, 2, 12)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + return (((vat >> 14) & 1) + 1) * vtxCompSize[(vat >> 15) & 7]; + } + break; + case 20: + vcd = __GXData->vcdHi; + vat = __GXData->vatC[vatIdx & 0xFF]; + switch (GET_REG_FIELD(vcd, 2, 14)) { + case 0: + return 0; + case 2: + return 1; + case 3: + return 2; + case 1: + return (((vat >> 23) & 1) + 1) * vtxCompSize[(vat >> 24) & 7]; + } + break; + } + return 0; +} + +static void __ParseVertexData(u8 vatIdx) { + u16 vcnt; + GXAttr attrIdx; + u32 vsize; + + if (__ReadMem(&vcnt, 2)) { + vsize = 0; + for (attrIdx = 0; attrIdx < GX_VA_MAX_ATTR; attrIdx++) { + if (attrIdx != GX_VA_NBT) { + vsize += GetAttrSize(vatIdx, attrIdx); + } + } + vsize *= vcnt; + dlist += vsize; + bytesRead += vsize; + } +} + +void __GXShadowDispList(void* list, u32 nbytes) { + u8 cmd; + u8 cmdOp; + u8 vatIdx; + u32 reg32; + u32 d32; + u8 reg8; + u8 cpAddr; + u32 i; + u32 addr; + u32 cnt; + + if (__gxVerif->verifyLevel == GX_WARN_NONE) { + return; + } + + dlist = list; + dlistSize = nbytes; + bytesRead = 0; + + DPF("Displaylist IN\n"); + + while (dlistSize > bytesRead) { + if (!__ReadMem(&cmd, 1)) { + break; + } + cmdOp = (u32)GET_REG_FIELD((u32)cmd, 5, 3); + vatIdx = cmd & 7; + switch (cmdOp) { + case 0: + case 9: + break; + case 16: + case 18: + case 19: + case 20: + case 21: + case 22: + case 23: + __ReconstVtxStatus(vatIdx); + __GXVerifyState(vatIdx); + __ParseVertexData(vatIdx); + break; + case 1: + if (__ReadMem(®8, 1) && __ReadMem(&d32, 4)) { + vatIdx = reg8 & 0xF; + cpAddr = (reg8& 0xF0) >> 4; + __SaveCPRegs(cpAddr, vatIdx, d32); + } + break; + case 2: + if (__ReadMem(®32, 4)) { + cnt = GET_REG_FIELD(reg32, 4, 16) + 1; + addr = (u16)reg32; + DPF("\tXFReg = 0x%x, Cnt = %d\n", addr, cnt); + for (i = 0; i < cnt; i++) { + if (__ReadMem(&d32, 4)) { + DPF("\tXFData = 0x%x\n", d32); + VERIF_MTXLIGHT(addr, d32); + addr++; + } + } + } + break; + case 4: + case 5: + case 6: + case 7: + if (__ReadMem(®32, 4)) { + DPF("\tXF_INDEX_LOAD: = 0x%x\n", reg32); + __GXShadowIndexState(cmdOp, reg32); + } + break; + case 8: + if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_DL_NESTED]) { + __GX_WARN(GXWARN_DL_NESTED); + } + return; + case 12: + case 13: + if (__ReadMem(®32, 4)) { + DPF("\tSU Bypass = 0x%x\n", reg32); + __gxVerif->rasRegs[(reg32 >> 24) & 0xFF] = reg32; + } + break; + default: + if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_DL_INV_CMD]) { + __GX_WARN(GXWARN_DL_INV_CMD); + } + OSReport("[Bad Display List Command: 0x%02X\n]", cmdOp); + break; + } + } + + DPF("Displaylist OUT\n"); +} + +void __GXShadowIndexState(u32 idx_reg, u32 reg_data) { + u32* basePtr; + u32* memAddr; + u32 cnt; + u32 stride; + u32 addr; + u32 data; + u32 index; + u32 i; + + i = idx_reg - 4; + basePtr = OSPhysicalToCached(__GXData->indexBase[i]); + stride = __GXData->indexStride[i]; + addr = reg_data & 0xFFF; + cnt = (reg_data >> 12) & 0xF; + index = reg_data >> 16; + memAddr = (u32*)((u8*)basePtr + (index * stride)); + cnt++; + + while (cnt-- != 0) { + data = *memAddr; + VERIF_MTXLIGHT(addr, data); + memAddr = (u32*)((u8*)memAddr + stride); + addr++; + } + + &data; // needed to match +} + +void __GXPrintShadowState(void) { + u32 i; + u32 j; + + OSReport("CP State:\n"); + OSReport("\tvcdLo = 0x%x\n", __GXData->vcdLo); + OSReport("\tvcdHi = 0x%x\n", __GXData->vcdHi); + OSReport("\thasBiNrms = 0x%x\n", __GXData->hasBiNrms); + + for (i = 0; i < 8; i++) { + OSReport("\tVertex Format %d:\n", i); + OSReport("\t\tvatA = 0x%x\n", __GXData->vatA[i]); + OSReport("\t\tvatB = 0x%x\n", __GXData->vatB[i]); + OSReport("\t\tvatC = 0x%x\n", __GXData->vatC[i]); + } + + OSReport("\n-------------------------------------\n"); + OSReport("XF Pos/Tex Matrix State:\n"); + + for (i = 0; i < 256; i += 4) { + if (__gxVerif->xfMtxDirty[i]) { + OSReport("\tXF_MATRIX[%d] = ", i); + OSReport("%f, %f, %f, %f\n", *(f32*)&__gxVerif->xfMtx[i], *(f32*)&__gxVerif->xfMtx[i + 1], *(f32*)&__gxVerif->xfMtx[i + 2], *(f32*)&__gxVerif->xfMtx[i + 3]); + } + } + + OSReport("\n-------------------------------------\n"); + OSReport("XF Normal Matrix State:\n"); + + for (i = 0; i < 96; i += 3) { + if (__gxVerif->xfNrmDirty[i]) { + OSReport("\tXF_NRM_MTX[%d] = ", i); + OSReport("%f, %f, %f\n", *(f32*)&__gxVerif->xfMtx[i], *(f32*)&__gxVerif->xfMtx[i + 1], *(f32*)&__gxVerif->xfMtx[i + 2]); + } + } + + OSReport("\n-------------------------------------\n"); + OSReport("XF Light State:\n"); + + for (i = 0; i < 128; i += 16) { + if (__gxVerif->xfLightDirty[i]) { + OSReport("\tXF_LIGHT[%d]:\n", i >> 4); + for (j = 0; j < 4; j++) { + OSReport("\t\tparam[%d] = 0x%x\n", j, __gxVerif->xfLight[i + j]); + } + for (j = 4; j < 16; j++) { + OSReport("\t\tparam[%d] = %Lg\n", j, *(f32*)&__gxVerif->xfLight[i + j]); + } + } + } + + OSReport("\n-------------------------------------\n"); + OSReport("XF Register State:\n"); + + for (i = 0; i < 80; i++) { + if (__gxVerif->xfRegsDirty[i]) { + OSReport("\tXF_REG[0x%x] = 0x%x (%f)\n", i, __gxVerif->xfRegs[i], *(f32*)&__gxVerif->xfRegs[i]); + } + } + + OSReport("\n-------------------------------------\n"); + OSReport("Raster Registers State:\n"); + + for (i = 0; i < 256; i++) { + OSReport("\tRAS_REG[0x%x] = 0x%x\n", i, __gxVerif->rasRegs[i]); + } + + OSReport("\n-------------------------------------\n"); +} + +#endif diff --git a/src/dolphin/gx/GXStubs.c b/src/dolphin/gx/GXStubs.c new file mode 100644 index 0000000000..c5e36bb455 --- /dev/null +++ b/src/dolphin/gx/GXStubs.c @@ -0,0 +1,5 @@ +#include + +#include "__gx.h" + +void __GXSetRange(f32 nearz, f32 fgSideX) {} diff --git a/src/dolphin/gx/GXTev.c b/src/dolphin/gx/GXTev.c index 3577ab673d..195e605a27 100644 --- a/src/dolphin/gx/GXTev.c +++ b/src/dolphin/gx/GXTev.c @@ -1,386 +1,470 @@ -#include "dolphin/gx/GXTev.h" -#include "dolphin/gx.h" +#include +#include -/* ############################################################################################## */ -/* 803D27C0-803D27D4 02F8E0 0014+00 1/1 0/0 0/0 .data TEVCOpTableST0 */ -static u32 TEVCOpTableST0[] = { - 0xC008F8AF, // modulate - 0xC008A89F, // decal - 0xC008AC8F, // blend - 0xC008FFF8, // replace - 0xC008FFFA, // passclr +#include "__gx.h" + +static struct { + u32 rid : 8; + u32 dest : 2; + u32 shift : 2; + u32 clamp : 1; + u32 sub : 1; + u32 bias : 2; + u32 sela : 4; + u32 selb : 4; + u32 selc : 4; + u32 seld : 4; +} TEVCOpTableST0[5] = { + {192, 0, 0, 1, 0, 0, 15, 8, 10, 15}, // modulate + {192, 0, 0, 1, 0, 0, 10, 8, 9, 15}, // decal + {192, 0, 0, 1, 0, 0, 10, 12, 8, 15}, // blend + {192, 0, 0, 1, 0, 0, 15, 15, 15, 8}, // replace + {192, 0, 0, 1, 0, 0, 15, 15, 15, 10}, // passclr }; -/* 803D27D4-803D27E8 02F8F4 0014+00 0/0 0/0 0/0 .data TEVCOpTableST1 */ -static u32 TEVCOpTableST1[] = { - 0xC008F80F, // modulate - 0xC008089F, // decal - 0xC0080C8F, // blend - 0xC008FFF8, // replace - 0xC008FFF0, // passclr +static struct { + u32 rid : 8; + u32 dest : 2; + u32 shift : 2; + u32 clamp : 1; + u32 sub : 1; + u32 bias : 2; + u32 sela : 4; + u32 selb : 4; + u32 selc : 4; + u32 seld : 4; +} TEVCOpTableST1[5] = { + {192, 0, 0, 1, 0, 0, 15, 8, 0, 15}, // modulate + {192, 0, 0, 1, 0, 0, 0, 8, 9, 15}, // decal + {192, 0, 0, 1, 0, 0, 0, 12, 8, 15}, // blend + {192, 0, 0, 1, 0, 0, 15, 15, 15, 8}, // replace + {192, 0, 0, 1, 0, 0, 15, 15, 15, 0}, // passclr }; -/* 803D27E8-803D27FC 02F908 0014+00 0/0 0/0 0/0 .data TEVAOpTableST0 */ -static u32 TEVAOpTableST0[] = { - 0xC108F2F0, // modulate - 0xC108FFD0, // decal - 0xC108F2F0, // blend - 0xC108FFC0, // replace - 0xC108FFD0, // passclr +static struct { + u32 rid : 8; + u32 dest : 2; + u32 shift : 2; + u32 clamp : 1; + u32 sub : 1; + u32 bias : 2; + u32 sela : 3; + u32 selb : 3; + u32 selc : 3; + u32 seld : 3; + u32 swap : 2; + u32 mode : 2; +} TEVAOpTableST0[5] = { + {193, 0, 0, 1, 0, 0, 7, 4, 5, 7, 0, 0}, // modulate + {193, 0, 0, 1, 0, 0, 7, 7, 7, 5, 0, 0}, // decal + {193, 0, 0, 1, 0, 0, 7, 4, 5, 7, 0, 0}, // blend + {193, 0, 0, 1, 0, 0, 7, 7, 7, 4, 0, 0}, // replace + {193, 0, 0, 1, 0, 0, 7, 7, 7, 5, 0, 0}, // passclr }; -/* 803D27FC-803D2810 02F91C 0014+00 0/0 0/0 0/0 .data TEVAOpTableST1 */ -static u32 TEVAOpTableST1[] = { - 0xC108F070, // modulate - 0xC108FF80, // decal - 0xC108F070, // blend - 0xC108FFC0, // replace - 0xC108FF80, // passclr +static struct { + u32 rid : 8; + u32 dest : 2; + u32 shift : 2; + u32 clamp : 1; + u32 sub : 1; + u32 bias : 2; + u32 sela : 3; + u32 selb : 3; + u32 selc : 3; + u32 seld : 3; + u32 swap : 2; + u32 mode : 2; +} TEVAOpTableST1[5] = { + {193, 0, 0, 1, 0, 0, 7, 4, 0, 7, 0, 0}, // modulate + {193, 0, 0, 1, 0, 0, 7, 7, 7, 0, 0, 0}, // decal + {193, 0, 0, 1, 0, 0, 7, 4, 0, 7, 0, 0}, // blend + {193, 0, 0, 1, 0, 0, 7, 7, 7, 4, 0, 0}, // replace + {193, 0, 0, 1, 0, 0, 7, 7, 7, 0, 0, 0}, // passclr }; -/* 8035F198-8035F224 359AD8 008C+00 0/0 15/15 1/1 .text GXSetTevOp */ -void GXSetTevOp(GXTevStageID stage, GXTevMode mode) { - u32* color; - u32* alpha; +#define SOME_SET_REG_MACRO(reg, size, shift, val) \ + do { \ + (reg) = (u32)__rlwimi((u32)(reg), (val), (shift), (32 - (shift) - (size)), (31 - (shift))); \ + } while (0); + +void GXSetTevOp(GXTevStageID id, GXTevMode mode) { + u32* ctmp; + u32* atmp; u32 tevReg; - if (stage == GX_TEVSTAGE0) { - color = &TEVCOpTableST0[mode]; - alpha = &TEVAOpTableST0[mode]; + CHECK_GXBEGIN(420, "GXSetTevOp"); + ASSERTMSGLINE(421, id < GX_MAX_TEVSTAGE, "GXSetTevColor*: Invalid Tev Stage Index"); + ASSERTMSGLINE(422, mode <= GX_PASSCLR, "GXSetTevOp: Invalid Tev Mode"); + + if (id == GX_TEVSTAGE0) { + ctmp = (u32*)TEVCOpTableST0 + mode; + atmp = (u32*)TEVAOpTableST0 + mode; } else { - color = &TEVCOpTableST1[mode]; - alpha = &TEVAOpTableST1[mode]; + ctmp = (u32*)TEVCOpTableST1 + mode; + atmp = (u32*)TEVAOpTableST1 + mode; } + tevReg = __GXData->tevc[id]; + tevReg = (*ctmp & ~0xFF000000) | (tevReg & 0xFF000000); + GX_WRITE_RAS_REG(tevReg); + __GXData->tevc[id] = tevReg; + + tevReg = __GXData->teva[id]; + tevReg = (*atmp & ~0xFF00000F) | (tevReg & 0xFF00000F); + GX_WRITE_RAS_REG(tevReg); + __GXData->teva[id] = tevReg; + + __GXData->bpSentNot = 0; +} + +void GXSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, GXTevColorArg d) { + u32 tevReg; + + CHECK_GXBEGIN(578, "GXSetTevColorIn"); + ASSERTMSGLINE(579, stage < GX_MAX_TEVSTAGE, "GXSetTevColor*: Invalid Tev Stage Index"); + ASSERTMSGLINE(580, a <= GX_CC_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); + ASSERTMSGLINE(581, b <= GX_CC_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); + ASSERTMSGLINE(582, c <= GX_CC_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); + ASSERTMSGLINE(583, d <= GX_CC_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); + tevReg = __GXData->tevc[stage]; - tevReg = (*color & ~0xFF000000) | (tevReg & 0xFF000000); - - GX_WRITE_U8(0x61); - GX_WRITE_U32(tevReg); + SET_REG_FIELD(586, tevReg, 4, 12, a); + SET_REG_FIELD(587, tevReg, 4, 8, b); + SET_REG_FIELD(588, tevReg, 4, 4, c); + SET_REG_FIELD(589, tevReg, 4, 0, d); + GX_WRITE_RAS_REG(tevReg); __GXData->tevc[stage] = tevReg; + __GXData->bpSentNot = 0; +} + +void GXSetTevAlphaIn(GXTevStageID stage, GXTevAlphaArg a, GXTevAlphaArg b, GXTevAlphaArg c, GXTevAlphaArg d) { + u32 tevReg; + + CHECK_GXBEGIN(614, "GXSetTevAlphaIn"); + ASSERTMSGLINE(615, stage < GX_MAX_TEVSTAGE, "GXSetTevAlpha*: Invalid Tev Stage Index"); + ASSERTMSGLINE(616, a <= GX_CA_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); + ASSERTMSGLINE(617, b <= GX_CA_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); + ASSERTMSGLINE(618, c <= GX_CA_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); + ASSERTMSGLINE(619, d <= GX_CA_ZERO, "GXSetTev*In: A/B/C/D argument out of range"); tevReg = __GXData->teva[stage]; - tevReg = (*alpha & ~0xFF00000F) | (tevReg & 0xFF00000F); - - GX_WRITE_U8(0x61); - GX_WRITE_U32(tevReg); + SET_REG_FIELD(622, tevReg, 3, 13, a); + SET_REG_FIELD(623, tevReg, 3, 10, b); + SET_REG_FIELD(624, tevReg, 3, 7, c); + SET_REG_FIELD(625, tevReg, 3, 4, d); + GX_WRITE_RAS_REG(tevReg); __GXData->teva[stage] = tevReg; - - __GXData->bpSentNot = GX_FALSE; + __GXData->bpSentNot = 0; } -/* 8035F224-8035F268 359B64 0044+00 0/0 49/49 5/5 .text GXSetTevColorIn */ -void GXSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, - GXTevColorArg d) { +void GXSetTevColorOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, GXTevRegID out_reg) { u32 tevReg; + CHECK_GXBEGIN(653, "GXSetTevColorOp"); + ASSERTMSGLINE(654, stage < GX_MAX_TEVSTAGE, "GXSetTevColor*: Invalid Tev Stage Index"); + tevReg = __GXData->tevc[stage]; - - FAST_FLAG_SET(tevReg, a, 12, 4); - FAST_FLAG_SET(tevReg, b, 8, 4); - FAST_FLAG_SET(tevReg, c, 4, 4); - FAST_FLAG_SET(tevReg, d, 0, 4); - - GX_WRITE_U8(0x61); - GX_WRITE_U32(tevReg); - - __GXData->tevc[stage] = tevReg; - __GXData->bpSentNot = GX_FALSE; -} - -/* 8035F268-8035F2AC 359BA8 0044+00 0/0 49/49 6/6 .text GXSetTevAlphaIn */ -void GXSetTevAlphaIn(GXTevStageID stage, GXTevAlphaArg a, GXTevAlphaArg b, GXTevAlphaArg c, - GXTevAlphaArg d) { - u32 tevReg; - - tevReg = __GXData->teva[stage]; - - FAST_FLAG_SET(tevReg, a, 13, 3); - FAST_FLAG_SET(tevReg, b, 10, 3); - FAST_FLAG_SET(tevReg, c, 7, 3); - FAST_FLAG_SET(tevReg, d, 4, 3); - - GX_WRITE_U8(0x61); - GX_WRITE_U32(tevReg); - - __GXData->teva[stage] = tevReg; - __GXData->bpSentNot = GX_FALSE; -} - -/* 8035F2AC-8035F314 359BEC 0068+00 0/0 50/50 5/5 .text GXSetTevColorOp */ -void GXSetTevColorOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, - GXBool doClamp, GXTevRegID outReg) { - u32 tevReg; - - tevReg = __GXData->tevc[stage]; - FAST_FLAG_SET(tevReg, op & 1, 18, 1); - + SET_REG_FIELD(663, tevReg, 1, 18, op & 1); if (op <= 1) { - FAST_FLAG_SET(tevReg, scale, 20, 2); - FAST_FLAG_SET(tevReg, bias, 16, 2); + SET_REG_FIELD(665, tevReg, 2, 20, scale); + SET_REG_FIELD(666, tevReg, 2, 16, bias); } else { - FAST_FLAG_SET(tevReg, (op >> 1) & 3, 20, 2); - FAST_FLAG_SET(tevReg, 3, 16, 2); + SET_REG_FIELD(668, tevReg, 2, 20, (op >> 1) & 3); + SET_REG_FIELD(672, tevReg, 2, 16, 3); } + SET_REG_FIELD(672, tevReg, 1, 19, clamp & 0xFF); + SET_REG_FIELD(673, tevReg, 2, 22, out_reg); - FAST_FLAG_SET(tevReg, doClamp, 19, 1); - FAST_FLAG_SET(tevReg, outReg, 22, 2); - - GX_WRITE_U8(0x61); - GX_WRITE_U32(tevReg); + GX_WRITE_RAS_REG(tevReg); __GXData->tevc[stage] = tevReg; - __GXData->bpSentNot = GX_FALSE; + __GXData->bpSentNot = 0; } -/* 8035F314-8035F37C 359C54 0068+00 0/0 50/50 5/5 .text GXSetTevAlphaOp */ -void GXSetTevAlphaOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, - GXBool doClamp, GXTevRegID outReg) { +void GXSetTevAlphaOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, GXTevRegID out_reg) { u32 tevReg; + CHECK_GXBEGIN(699, "GXSetTevAlphaOp"); + ASSERTMSGLINE(700, stage < GX_MAX_TEVSTAGE, "GXSetTevAlpha*: Invalid Tev Stage Index"); + tevReg = __GXData->teva[stage]; - FAST_FLAG_SET(tevReg, op & 1, 18, 1); - + SET_REG_FIELD(708, tevReg, 1, 18, op & 1); if (op <= 1) { - FAST_FLAG_SET(tevReg, scale, 20, 2); - FAST_FLAG_SET(tevReg, bias, 16, 2); + SET_REG_FIELD(710, tevReg, 2, 20, scale); + SET_REG_FIELD(711, tevReg, 2, 16, bias); } else { - FAST_FLAG_SET(tevReg, (op >> 1) & 3, 20, 2); - FAST_FLAG_SET(tevReg, 3, 16, 2); + SET_REG_FIELD(713, tevReg, 2, 20, (op >> 1) & 3); + SET_REG_FIELD(717, tevReg, 2, 16, 3); } + SET_REG_FIELD(717, tevReg, 1, 19, clamp & 0xFF); + SET_REG_FIELD(718, tevReg, 2, 22, out_reg); - FAST_FLAG_SET(tevReg, doClamp, 19, 1); - FAST_FLAG_SET(tevReg, outReg, 22, 2); - - GX_WRITE_U8(0x61); - GX_WRITE_U32(tevReg); + GX_WRITE_RAS_REG(tevReg); __GXData->teva[stage] = tevReg; - __GXData->bpSentNot = GX_FALSE; + __GXData->bpSentNot = 0; } -/* 8035F37C-8035F3DC 359CBC 0060+00 0/0 54/54 4/4 .text GXSetTevColor */ -void GXSetTevColor(GXTevRegID reg, GXColor color) { - u32 col = *(u32*)&color; - u32 ra = (0xE0 + reg * 2) << 24; - u32 bg = (0xE1 + reg * 2) << 24; +void GXSetTevColor(GXTevRegID id, GXColor color) { + u32 rgba; + u32 regRA; + u32 regBG; - GX_SET_REG(ra, col >> 24, 24, 31); - GX_SET_REG(bg, col >> 8, 24, 31); - GX_SET_REG(bg, col >> 16, 12, 19); - GX_SET_REG(ra, col & 0xFF, 12, 19); + CHECK_GXBEGIN(740, "GXSetTevColor"); + rgba = *(u32*)&color; - GX_BP_LOAD_REG(ra); - GX_BP_LOAD_REG(bg); - GX_BP_LOAD_REG(bg); - GX_BP_LOAD_REG(bg); + regRA = (0xE0 + id * 2) << 24; + SET_REG_FIELD(745, regRA, 8, 0, rgba >> 24); + SET_REG_FIELD(746, regRA, 8, 12, rgba & 0xFF); - __GXData->bpSentNot = GX_FALSE; + regBG = (0xE1 + id * 2) << 24; + SET_REG_FIELD(749, regBG, 8, 0, (rgba >> 8) & 0xFF); + SET_REG_FIELD(750, regBG, 8, 12, (rgba >> 16) & 0xFF); + + GX_WRITE_RAS_REG(regRA); + GX_WRITE_RAS_REG(regBG); + GX_WRITE_RAS_REG(regBG); + GX_WRITE_RAS_REG(regBG); + + __GXData->bpSentNot = 0; } -/* 8035F3DC-8035F440 359D1C 0064+00 0/0 8/8 2/2 .text GXSetTevColorS10 */ -void GXSetTevColorS10(GXTevRegID reg, GXColorS10 color) { - u32 col = *(u32*)&color; - u32 col1 = ((u32*)&color)[1]; - u32 ra = (0xE0 + reg * 2) << 24; - u32 bg = (0xE1 + reg * 2) << 24; +void GXSetTevColorS10(GXTevRegID id, GXColorS10 color) { + u32 sRG; + u32 sBA; + u32 regRA; + u32 regBG; - GX_SET_REG(ra, col >> 16, 21, 31); - GX_SET_REG(bg, col1 >> 16, 21, 31); - GX_SET_REG(bg, col & 0x7FF, 9, 19); - GX_SET_REG(ra, col1 & 0x7FF, 9, 19); + ASSERTMSGLINE(777, color.r >= -1024 && color.r < 1024, "GXSetTevColorS10: Color not in range -1024 to +1023"); + ASSERTMSGLINE(778, color.g >= -1024 && color.g < 1024, "GXSetTevColorS10: Color not in range -1024 to +1023"); + ASSERTMSGLINE(779, color.b >= -1024 && color.b < 1024, "GXSetTevColorS10: Color not in range -1024 to +1023"); + ASSERTMSGLINE(780, color.a >= -1024 && color.a < 1024, "GXSetTevColorS10: Color not in range -1024 to +1023"); - GX_BP_LOAD_REG(ra); - GX_BP_LOAD_REG(bg); - GX_BP_LOAD_REG(bg); - GX_BP_LOAD_REG(bg); + CHECK_GXBEGIN(782, "GXSetTevColorS10"); + sRG = *(u32*)&color; + sBA = *((u32*)&color + 1); - __GXData->bpSentNot = GX_FALSE; + regRA = (0xE0 + id * 2) << 24; + SET_REG_FIELD(789, regRA, 11, 0, (sRG >> 16) & 0x7FF); + SET_REG_FIELD(790, regRA, 11, 12, sBA & 0x7FF); + + regBG = (0xE1 + id * 2) << 24; + SET_REG_FIELD(793, regBG, 11, 0, (sBA >> 16) & 0x7FF); + SET_REG_FIELD(794, regBG, 11, 12, sRG & 0x7FF); + + GX_WRITE_RAS_REG(regRA); + GX_WRITE_RAS_REG(regBG); + GX_WRITE_RAS_REG(regBG); + GX_WRITE_RAS_REG(regBG); + + __GXData->bpSentNot = 0; } -/* 8035F440-8035F4A4 359D80 0064+00 0/0 8/8 4/4 .text GXSetTevKColor */ void GXSetTevKColor(GXTevKColorID id, GXColor color) { - u32 col = *(u32*)&color; - u32 ra; - u32 bg; + u32 rgba; + u32 regRA; + u32 regBG; - ra = (0xE0 + id * 2) << 24; - GX_SET_REG(ra, col >> 24, 24, 31); - GX_SET_REG(ra, col & 0xFF, 12, 19); - GX_SET_REG(ra, 8, 8, 11); + CHECK_GXBEGIN(833, "GXSetTevKColor"); + rgba = *(u32*)&color; - bg = (0xE1 + id * 2) << 24; - GX_SET_REG(bg, col >> 8, 24, 31); - GX_SET_REG(bg, col >> 16, 12, 19); - GX_SET_REG(bg, 8, 8, 11); + regRA = (0xE0 + id * 2) << 24; + SET_REG_FIELD(838, regRA, 8, 0, rgba >> 24); + SET_REG_FIELD(839, regRA, 8, 12, rgba & 0xFF); + SET_REG_FIELD(839, regRA, 4, 20, 8); - GX_BP_LOAD_REG(ra); - GX_BP_LOAD_REG(bg); + regBG = (0xE1 + id * 2) << 24; + SET_REG_FIELD(843, regBG, 8, 0, (rgba >> 8) & 0xFF); + SET_REG_FIELD(844, regBG, 8, 12, (rgba >> 16) & 0xFF); + SET_REG_FIELD(845, regBG, 4, 20, 8); - __GXData->bpSentNot = GX_FALSE; + GX_WRITE_RAS_REG(regRA); + GX_WRITE_RAS_REG(regBG); + + __GXData->bpSentNot = 0; } -/* 8035F4A4-8035F500 359DE4 005C+00 0/0 9/9 4/4 .text GXSetTevKColorSel */ void GXSetTevKColorSel(GXTevStageID stage, GXTevKColorSel sel) { - u32* reg; + u32* Kreg; - reg = &__GXData->tevKsel[stage >> 1]; + CHECK_GXBEGIN(872, "GXSetTevKColorSel"); + ASSERTMSGLINE(873, stage < GX_MAX_TEVSTAGE, "GXSetTevKColor*: Invalid Tev Stage Index"); + Kreg = &__GXData->tevKsel[stage >> 1]; if (stage & 1) { - GX_SET_REG(*reg, sel, 13, 17); + SET_REG_FIELD(0x36E, *Kreg, 5, 14, sel); } else { - GX_SET_REG(*reg, sel, 23, 27); + SET_REG_FIELD(0x370, *Kreg, 5, 4, sel); } - GX_BP_LOAD_REG(*reg); - - __GXData->bpSentNot = GX_FALSE; + GX_WRITE_RAS_REG(*Kreg); + __GXData->bpSentNot = 0; } -/* 8035F500-8035F55C 359E40 005C+00 0/0 9/9 4/4 .text GXSetTevKAlphaSel */ void GXSetTevKAlphaSel(GXTevStageID stage, GXTevKAlphaSel sel) { - u32* reg; + u32* Kreg; - reg = &__GXData->tevKsel[stage >> 1]; + CHECK_GXBEGIN(905, "GXSetTevKAlphaSel"); + ASSERTMSGLINE(906, stage < GX_MAX_TEVSTAGE, "GXSetTevKColor*: Invalid Tev Stage Index"); + Kreg = &__GXData->tevKsel[stage >> 1]; if (stage & 1) { - GX_SET_REG(*reg, sel, 8, 12); + SET_REG_FIELD(911, *Kreg, 5, 19, sel); } else { - GX_SET_REG(*reg, sel, 18, 22); + SET_REG_FIELD(913, *Kreg, 5, 9, sel); } - GX_BP_LOAD_REG(*reg); - - __GXData->bpSentNot = GX_FALSE; + GX_WRITE_RAS_REG(*Kreg); + __GXData->bpSentNot = 0; } -/* 8035F55C-8035F5A4 359E9C 0048+00 0/0 10/10 5/5 .text GXSetTevSwapMode */ -void GXSetTevSwapMode(GXTevStageID stage, GXTevSwapSel rasSel, GXTevSwapSel texSel) { - u32* reg = &__GXData->teva[stage]; - GX_SET_REG(*reg, rasSel, 30, 31); - GX_SET_REG(*reg, texSel, 28, 29); +void GXSetTevSwapMode(GXTevStageID stage, GXTevSwapSel ras_sel, GXTevSwapSel tex_sel) { + u32* pTevReg; - GX_BP_LOAD_REG(*reg); + CHECK_GXBEGIN(942, "GXSetTevSwapMode"); + ASSERTMSGLINE(943, stage < GX_MAX_TEVSTAGE, "GXSetTevSwapMode: Invalid Tev Stage Index"); - __GXData->bpSentNot = GX_FALSE; + pTevReg = &__GXData->teva[stage]; + SET_REG_FIELD(946, *pTevReg, 2, 0, ras_sel); + SET_REG_FIELD(947, *pTevReg, 2, 2, tex_sel); + + GX_WRITE_RAS_REG(*pTevReg); + __GXData->bpSentNot = 0; } -/* 8035F5A4-8035F624 359EE4 0080+00 0/0 17/17 2/2 .text GXSetTevSwapModeTable */ -void GXSetTevSwapModeTable(GXTevSwapSel table, GXTevColor red, GXTevColor green, GXTevColor blue, - GXTevColor alpha) { - u32* reg; +void GXSetTevSwapModeTable(GXTevSwapSel table, GXTevColorChan red, GXTevColorChan green, GXTevColorChan blue, GXTevColorChan alpha) { + u32* Kreg; +#if !DEBUG + // not a real variable, but needed to match release + int index = table * 2; +#endif - reg = &__GXData->tevKsel[table << 1]; - GX_SET_REG(*reg, red, 30, 31); - GX_SET_REG(*reg, green, 28, 29); + CHECK_GXBEGIN(978, "GXSetTevSwapModeTable"); + ASSERTMSGLINE(979, table < GX_MAX_TEVSWAP, "GXSetTevSwapModeTable: Invalid Swap Selection Index"); - GX_BP_LOAD_REG(*reg); +#if DEBUG + Kreg = &__GXData->tevKsel[table * 2]; +#else + Kreg = &__GXData->tevKsel[index]; +#endif + SET_REG_FIELD(982, *Kreg, 2, 0, red); + SET_REG_FIELD(983, *Kreg, 2, 2, green); - reg = &__GXData->tevKsel[(table << 1) + 1]; - GX_SET_REG(*reg, blue, 30, 31); - GX_SET_REG(*reg, alpha, 28, 29); + GX_WRITE_RAS_REG(*Kreg); - GX_BP_LOAD_REG(*reg); + Kreg = &__GXData->tevKsel[table * 2 + 1]; + SET_REG_FIELD(987, *Kreg, 2, 0, blue); + SET_REG_FIELD(988, *Kreg, 2, 2, alpha); - __GXData->bpSentNot = GX_FALSE; + GX_WRITE_RAS_REG(*Kreg); + __GXData->bpSentNot = 0; +} + +void GXSetTevClampMode(void) { + ASSERTMSGLINE(1012, 0, "GXSetTevClampMode: not available on this hardware"); } -/* 8035F624-8035F668 359F64 0044+00 0/0 43/43 5/5 .text GXSetAlphaCompare */ void GXSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1) { - u32 reg = 0xF3000000; + u32 reg; - GX_SET_REG(reg, ref0, 24, 31); - GX_SET_REG(reg, ref1, 16, 23); - GX_SET_REG(reg, comp0, 13, 15); - GX_SET_REG(reg, comp1, 10, 12); - GX_SET_REG(reg, op, 8, 9); + CHECK_GXBEGIN(1046, "GXSetAlphaCompare"); + reg = 0xF3000000; - GX_BP_LOAD_REG(reg); + SET_REG_FIELD(1049, reg, 8, 0, ref0); + SET_REG_FIELD(1050, reg, 8, 8, ref1); + SET_REG_FIELD(1051, reg, 3, 16, comp0); + SET_REG_FIELD(1052, reg, 3, 19, comp1); + SET_REG_FIELD(1053, reg, 2, 22, op); - __GXData->bpSentNot = GX_FALSE; + GX_WRITE_RAS_REG(reg); + __GXData->bpSentNot = 0; } -/* 8035F668-8035F6F4 359FA8 008C+00 0/0 3/3 0/0 .text GXSetZTexture */ -void GXSetZTexture(GXZTexOp op, GXTexFmt format, u32 bias) { - u32 val1; - u32 val2; - u32 val3; +void GXSetZTexture(GXZTexOp op, GXTexFmt fmt, u32 bias) { + u32 zenv0; + u32 zenv1; + u32 type; - val1 = 0; - GX_SET_REG(val1, bias, 8, 31); - GX_SET_REG(val1, 0xF4, 0, 7); + CHECK_GXBEGIN(1077, "GXSetZTexture"); - val2 = 0; - switch (format) { + zenv0 = 0; + SET_REG_FIELD(1080, zenv0, 24, 0, bias); + SET_REG_FIELD(1081, zenv0, 8, 24, 0xF4); + + zenv1 = 0; + switch (fmt) { case GX_TF_Z8: - val3 = 0; + type = 0; break; case GX_TF_Z16: - val3 = 1; + type = 1; break; case GX_TF_Z24X8: - val3 = 2; + type = 2; break; default: - val3 = 2; + ASSERTMSGLINE(1089, 0, "GXSetZTexture: Invalid z-texture format"); + type = 2; break; } - GX_SET_REG(val2, val3, 30, 31); - GX_SET_REG(val2, op, 28, 29); - GX_SET_REG(val2, 0xF5, 0, 7); + SET_REG_FIELD(1092, zenv1, 2, 0, type); + SET_REG_FIELD(1093, zenv1, 2, 2, op); + SET_REG_FIELD(1094, zenv1, 8, 24, 0xF5); - GX_BP_LOAD_REG(val1); - - GX_BP_LOAD_REG(val2); - - __GXData->bpSentNot = GX_FALSE; + GX_WRITE_RAS_REG(zenv0); + GX_WRITE_RAS_REG(zenv1); + __GXData->bpSentNot = 0; } -/* 8035F6F4-8035F890 35A034 019C+00 0/0 65/65 6/6 .text GXSetTevOrder */ void GXSetTevOrder(GXTevStageID stage, GXTexCoordID coord, GXTexMapID map, GXChannelID color) { - static int c2r[] = {0, 1, 0, 1, 0, 1, 7, 5, 6}; + u32* ptref; + u32 tmap; + u32 tcoord; + static int c2r[] = { 0, 1, 0, 1, 0, 1, 7, 5, 6 }; - u32* reg; - u32 tempMap; - u32 tempCoord; + CHECK_GXBEGIN(1131, "GXSetTevOrder"); + ASSERTMSGLINE(1132, stage < GX_MAX_TEVSTAGE, "GXSetTevOrder: Invalid Tev Stage Index"); + ASSERTMSGLINE(1134, coord < GX_MAX_TEXCOORD || coord == GX_TEXCOORD_NULL, "GXSetTevOrder: Invalid Texcoord"); + ASSERTMSGLINE(1136, (map & ~GX_TEX_DISABLE) < GX_MAX_TEXMAP || map == GX_TEXMAP_NULL, "GXSetTevOrder: Invalid Tex Map"); + ASSERTMSGLINE(1138, color >= GX_COLOR0A0 && color <= GX_COLOR_NULL, "GXSetTevOrder: Invalid Color Channel ID"); - reg = &__GXData->tref[stage / 2]; + ptref = &__GXData->tref[stage / 2]; __GXData->texmapId[stage] = map; - tempMap = map & ~0x100; - tempMap = (tempMap >= GX_MAX_TEXMAP) ? GX_TEXMAP0 : tempMap; + tmap = map & ~GX_TEX_DISABLE; + tmap = (tmap >= GX_MAX_TEXMAP) ? GX_TEXMAP0 : tmap; - if (coord >= GX_MAXCOORD) { - tempCoord = GX_TEXCOORD0; + if (coord >= GX_MAX_TEXCOORD) { + tcoord = GX_TEXCOORD0; __GXData->tevTcEnab = __GXData->tevTcEnab & ~(1 << stage); } else { - tempCoord = coord; + tcoord = coord; __GXData->tevTcEnab = __GXData->tevTcEnab | (1 << stage); } if (stage & 1) { - GX_SET_REG(*reg, tempMap, 17, 19); - GX_SET_REG(*reg, tempCoord, 14, 16); - GX_SET_REG(*reg, (color == GX_COLOR_NULL ? 7 : c2r[color]), 10, 12); - GX_SET_REG(*reg, ((map != GX_TEXMAP_NULL) && !(map & 0x100)), 13, 13); - + SET_REG_FIELD(1158, *ptref, 3, 12, tmap); + SET_REG_FIELD(1159, *ptref, 3, 15, tcoord); + SET_REG_FIELD(1161, *ptref, 3, 19, (color == GX_COLOR_NULL) ? 7 : c2r[color]); + SET_REG_FIELD(1163, *ptref, 1, 18, (map != GX_TEXMAP_NULL && !(map & GX_TEX_DISABLE))); } else { - GX_SET_REG(*reg, tempMap, 29, 31); - GX_SET_REG(*reg, tempCoord, 26, 28); - GX_SET_REG(*reg, (color == GX_COLOR_NULL ? 7 : c2r[color]), 22, 24); - GX_SET_REG(*reg, ((map != GX_TEXMAP_NULL) && !(map & 0x100)), 25, 25); + SET_REG_FIELD(1166, *ptref, 3, 0, tmap); + SET_REG_FIELD(1167, *ptref, 3, 3, tcoord); + SET_REG_FIELD(1169, *ptref, 3, 7, (color == GX_COLOR_NULL) ? 7 : c2r[color]); + SET_REG_FIELD(1171, *ptref, 1, 6, (map != GX_TEXMAP_NULL && !(map & GX_TEX_DISABLE))); } - GX_BP_LOAD_REG(*reg); - - __GXData->bpSentNot = GX_FALSE; + GX_WRITE_RAS_REG(*ptref); + __GXData->bpSentNot = 0; __GXData->dirtyState |= 1; } -/* 8035F890-8035F8B8 35A1D0 0028+00 0/0 63/63 6/6 .text GXSetNumTevStages */ -void GXSetNumTevStages(u8 count) { - GX_SET_REG(__GXData->genMode, count - 1, 18, 21); +void GXSetNumTevStages(u8 nStages) { + CHECK_GXBEGIN(1187, "GXSetNumTevStages"); - __GXData->dirtyState |= 0x4; -} \ No newline at end of file + ASSERTMSGLINE(1189, nStages != 0 && nStages <= 16, "GXSetNumTevStages: Exceed max number of tex stages"); + SET_REG_FIELD(1190, __GXData->genMode, 4, 10, nStages - 1); + __GXData->dirtyState |= 4; +} diff --git a/src/dolphin/gx/GXTexture.c b/src/dolphin/gx/GXTexture.c index 00f1d4537b..ad12a7bf53 100644 --- a/src/dolphin/gx/GXTexture.c +++ b/src/dolphin/gx/GXTexture.c @@ -1,635 +1,1314 @@ -#include "dolphin/gx/GXTexture.h" -#include "dolphin/gx.h" +#include +#include -#define GET_TILE_COUNT(a, b) (((a) + (1 << (b)) - 1) >> (b)) +#include "__gx.h" -inline void __GXGetTexTileShift(GXTexFmt format, u32* widthTiles, u32* heightTiles) { - switch (format) { +// GXTexObj internal data +typedef struct __GXTexObjInt_struct { + u32 mode0; + u32 mode1; + u32 image0; + u32 image3; + void* userData; + GXTexFmt fmt; + u32 tlutName; + u16 loadCnt; + u8 loadFmt; + u8 flags; +} __GXTexObjInt; + +// GXTexRegion internal data +typedef struct __GXTexRegionInt_struct { + u32 image1; + u32 image2; + u16 sizeEven; + u16 sizeOdd; + u8 is32bMipmap; + u8 isCached; +} __GXTexRegionInt; + +// GXTlutObj internal data +typedef struct __GXTlutObjInt_struct { + u32 tlut; + u32 loadTlut0; + u16 numEntries; +} __GXTlutObjInt; + +// GXTlutRegion internal data +typedef struct __GXTlutRegionInt_struct { + u32 loadTlut1; + __GXTlutObjInt tlutObj; +} __GXTlutRegionInt; + +u8 GXTexMode0Ids[8] = { 0x80, 0x81, 0x82, 0x83, 0xA0, 0xA1, 0xA2, 0xA3 }; +u8 GXTexMode1Ids[8] = { 0x84, 0x85, 0x86, 0x87, 0xA4, 0xA5, 0xA6, 0xA7 }; +u8 GXTexImage0Ids[8] = { 0x88, 0x89, 0x8A, 0x8B, 0xA8, 0xA9, 0xAA, 0xAB }; +u8 GXTexImage1Ids[8] = { 0x8C, 0x8D, 0x8E, 0x8F, 0xAC, 0xAD, 0xAE, 0xAF }; +u8 GXTexImage2Ids[8] = { 0x90, 0x91, 0x92, 0x93, 0xB0, 0xB1, 0xB2, 0xB3 }; +u8 GXTexImage3Ids[8] = { 0x94, 0x95, 0x96, 0x97, 0xB4, 0xB5, 0xB6, 0xB7 }; +u8 GXTexTlutIds[8] = { 0x98, 0x99, 0x9A, 0x9B, 0xB8, 0xB9, 0xBA, 0xBB }; +static u8 GX2HWFiltConv[6] = { 0x00, 0x04, 0x01, 0x05, 0x02, 0x06 }; +static u8 HW2GXFiltConv[8] = { 0x00, 0x02, 0x04, 0x00, 0x01, 0x03, 0x05, 0x00 }; + +static void __GXGetTexTileShift(GXTexFmt fmt, u32* rowTileS, u32* colTileS) { + switch (fmt) { case GX_TF_I4: - case GX_TF_C4: + case 0x8: case GX_TF_CMPR: case GX_CTF_R4: case GX_CTF_Z4: - *widthTiles = 3; - *heightTiles = 3; + *rowTileS = 3; + *colTileS = 3; break; - case GX_TF_I8: case GX_TF_IA4: - case GX_TF_C8: + case 0x9: case GX_TF_Z8: case GX_CTF_RA4: + case GX_TF_A8: case GX_CTF_R8: case GX_CTF_G8: case GX_CTF_B8: - case GX_CTF_RG8: case GX_CTF_Z8M: case GX_CTF_Z8L: - *widthTiles = 3; - *heightTiles = 2; + *rowTileS = 3; + *colTileS = 2; break; - case GX_TF_IA8: case GX_TF_RGB565: case GX_TF_RGB5A3: case GX_TF_RGBA8: - case GX_TF_C14X2: + case 0xA: case GX_TF_Z16: case GX_TF_Z24X8: case GX_CTF_RA8: + case GX_CTF_RG8: case GX_CTF_GB8: - case 44: case GX_CTF_Z16L: - *widthTiles = 2; - *heightTiles = 2; + *rowTileS = 2; + *colTileS = 2; break; - default: - *heightTiles = 0; - *widthTiles = 0; + *rowTileS = *colTileS = 0; + ASSERTMSGLINEV(444, 0, "%s: invalid texture format", "GX"); break; } } -/* 8035DC1C-8035DD78 35855C 015C+00 1/0 8/8 0/0 .text GXGetTexBufferSize */ u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, GXBool mipmap, u8 max_lod) { - u32 widthTiles, heightTiles, tileSize, bufferSize, numX, numY, i; + u32 tileShiftX; + u32 tileShiftY; + u32 tileBytes; + u32 bufferSize; + u32 nx; + u32 ny; + u32 level; - __GXGetTexTileShift(format, &widthTiles, &heightTiles); + ASSERTMSGLINEV(460, width <= 1024, "%s: width too large", "GXGetTexBufferSize"); + ASSERTMSGLINEV(461, height <= 1024, "%s: height too large", "GXGetTexBufferSize"); + __GXGetTexTileShift(format, &tileShiftX, &tileShiftY); if (format == GX_TF_RGBA8 || format == GX_TF_Z24X8) { - tileSize = 0x40; + tileBytes = 64; } else { - tileSize = 0x20; + tileBytes = 32; } if (mipmap == GX_TRUE) { + nx = 1 << (31 - __cntlzw(width)); + ASSERTMSGLINEV(479, width == nx, "%s: width must be a power of 2", "GXGetTexBufferSize"); + ny = 1 << (31 - __cntlzw(height)); + ASSERTMSGLINEV(482, height == ny, "%s: height must be a power of 2", "GXGetTexBufferSize"); + bufferSize = 0; - - for (i = 0; i < max_lod; i++) { - numX = GET_TILE_COUNT(width, widthTiles); - numY = GET_TILE_COUNT(height, heightTiles); - - bufferSize += numX * numY * tileSize; + for (level = 0; level < max_lod; level++) { + nx = (width + (1 << tileShiftX) - 1) >> tileShiftX; + ny = (height + (1 << tileShiftY) - 1) >> tileShiftY; + bufferSize += tileBytes * (nx * ny); if (width == 1 && height == 1) { break; } - - width = (width > 1) ? (width >> 1) : 1; - height = (height > 1) ? (height >> 1) : 1; + width = (width > 1) ? width >> 1 : 1; + height = (height > 1) ? height >> 1 : 1; } - } else { - numX = GET_TILE_COUNT(width, widthTiles); - numY = GET_TILE_COUNT(height, heightTiles); - bufferSize = numX * numY * tileSize; + nx = (width + (1 << tileShiftX) - 1) >> tileShiftX; + ny = (height + (1 << tileShiftY) - 1) >> tileShiftY; + bufferSize = nx * ny * tileBytes; } return bufferSize; } -/* 8035DD78-8035DE40 3586B8 00C8+00 1/0 1/1 0/0 .text __GetImageTileCount */ -void __GetImageTileCount(GXTexFmt format, u16 width, u16 height, u32* a, u32* b, u32* c) { - u32 widthTiles, heightTiles; +void __GetImageTileCount(GXTexFmt fmt, u16 wd, u16 ht, u32* rowTiles, u32* colTiles, u32* cmpTiles) { + u32 texRowShift; + u32 texColShift; - __GXGetTexTileShift(format, &widthTiles, &heightTiles); - - if (width <= 0) { - width = 1; + __GXGetTexTileShift(fmt, &texRowShift, &texColShift); + if (wd == 0) { + wd = 1; } - - if (height <= 0) { - height = 1; + if (ht == 0) { + ht = 1; } - - *a = GET_TILE_COUNT(width, widthTiles); - *b = GET_TILE_COUNT(height, heightTiles); - *c = (format == GX_TF_RGBA8 || format == GX_TF_Z24X8) ? 2 : 1; + *rowTiles = (wd + (1 << texRowShift) - 1) >> texRowShift; + *colTiles = (ht + (1 << texColShift) - 1) >> texColShift; + *cmpTiles = (fmt == GX_TF_RGBA8 || fmt == GX_TF_Z24X8) ? 2 : 1; } -/* 8035DE40-8035E08C 358780 024C+00 2/1 22/22 3/3 .text GXInitTexObj */ -void GXInitTexObj(GXTexObj* obj, void* imagePtr, u16 width, u16 height, GXTexFmt format, - GXTexWrapMode sWrap, GXTexWrapMode tWrap, GXBool useMIPmap) { +#define SOME_SET_REG_MACRO(reg, size, shift, val) \ + do { \ + (reg) = (u32)__rlwimi((u32)(reg), (val), (shift), (32 - (shift) - (size)), (31 - (shift))); \ + } while (0); + +void GXInitTexObj(GXTexObj* obj, void* image_ptr, u16 width, u16 height, GXTexFmt format, GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, GXBool mipmap) { u32 imageBase; - u16 a, b; - u32 c, d; + u32 maxLOD; + u16 rowT; + u16 colT; + u32 rowC; + u32 colC; + __GXTexObjInt* t = (__GXTexObjInt*)obj; - GXTexObj* internal = (GXTexObj*)obj; - memset(internal, 0, sizeof(*internal)); + ASSERTMSGLINE(565, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(567, "GXInitTexObj"); + ASSERTMSGLINEV(568, width <= 1024, "%s: width too large", "GXInitTexObj"); + ASSERTMSGLINEV(569, height <= 1024, "%s: height too large", "GXInitTexObj"); + ASSERTMSGLINEV(571, !(format & _GX_TF_CTF), "%s: invalid texture format", "GXInitTexObj"); - GX_SET_REG(internal->texture_filter, sWrap, 30, 31); - GX_SET_REG(internal->texture_filter, tWrap, 28, 29); - GX_SET_REG(internal->texture_filter, GX_TRUE, 27, 27); +#if DEBUG + if (wrap_s != GX_CLAMP || mipmap) { + u32 mask = 1 << (31 - __cntlzw(width)); + ASSERTMSGLINEV(581, width == mask, "%s: width must be a power of 2", "GXInitTexObj"); + } + if (wrap_t != GX_CLAMP || mipmap) { + u32 mask = 1 << (31 - __cntlzw(height)); + ASSERTMSGLINEV(586, height == mask, "%s: height must be a power of 2", "GXInitTexObj"); + } +#endif + + memset(t, 0, 0x20); + SET_REG_FIELD(600, t->mode0, 2, 0, wrap_s); + SET_REG_FIELD(601, t->mode0, 2, 2, wrap_t); + SET_REG_FIELD(602, t->mode0, 1, 4, 1); + + if (mipmap) { + u8 lmax; + t->flags |= 1; - if (useMIPmap) { - u32 maxDimSize; - internal->texture_flags |= 1; if (format == 8 || format == 9 || format == 10) { - GX_SET_REG(internal->texture_filter, 5, 24, 26); + SOME_SET_REG_MACRO(t->mode0, 3, 5, 5); } else { - GX_SET_REG(internal->texture_filter, 6, 24, 26); + SOME_SET_REG_MACRO(t->mode0, 3, 5, 6); } - maxDimSize = width > height ? 31 - __cntlzw(width) : 31 - __cntlzw(height); - GX_SET_REG(internal->texture_lod, (maxDimSize) * 16.f, 16, 23); + if (width > height) { + maxLOD = 31 - __cntlzw(width); + } else { + maxLOD = 31 - __cntlzw(height); + } + + lmax = 16.0f * maxLOD; + SET_REG_FIELD(632, t->mode1, 8, 8, lmax); } else { - GX_SET_REG(internal->texture_filter, 4, 24, 26); + SOME_SET_REG_MACRO(t->mode0, 3, 5, 4); } - internal->texture_format = format; - GX_SET_REG(internal->texture_size, width - 1, 22, 31); - GX_SET_REG(internal->texture_size, height - 1, 12, 21); + t->fmt = format; + SET_REG_FIELD(646, t->image0, 10, 0, width - 1); + SET_REG_FIELD(647, t->image0, 10, 10, height - 1); + SET_REG_FIELD(648, t->image0, 4, 20, format & 0xF); + ASSERTMSGLINEV(654, ((u32)image_ptr & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexObj", "image"); + imageBase = (u32)((u32)image_ptr >> 5) & 0x01FFFFFF; + SET_REG_FIELD(656, t->image3, 21, 0, imageBase); - GX_SET_REG(internal->texture_size, format & 0xf, 8, 11); - imageBase = (u32)imagePtr >> 5; - GX_SET_REG(internal->texture_address, imageBase, 11, 31); - - switch (format & 0xf) { - case 0: + switch (format & 0xF) { + case GX_TF_I4: case 8: - internal->texture_tile_type = 1; - a = 3; - b = 3; + t->loadFmt = 1; + rowT = 3; + colT = 3; break; - case 1: - case 2: + case GX_TF_I8: + case GX_TF_IA4: case 9: - internal->texture_tile_type = 2; - a = 3; - b = 2; + t->loadFmt = 2; + rowT = 3; + colT = 2; break; - case 3: - case 4: - case 5: + case GX_TF_IA8: + case GX_TF_RGB565: + case GX_TF_RGB5A3: case 10: - internal->texture_tile_type = 2; - a = 2; - b = 2; + t->loadFmt = 2; + rowT = 2; + colT = 2; break; - case 6: - internal->texture_tile_type = 3; - a = 2; - b = 2; + case GX_TF_RGBA8: + t->loadFmt = 3; + rowT = 2; + colT = 2; break; - case 0xe: - internal->texture_tile_type = 0; - a = 3; - b = 3; + case GX_TF_CMPR: + t->loadFmt = 0; + rowT = 3; + colT = 3; break; default: - internal->texture_tile_type = 2; - a = 2; - b = 2; + ASSERTMSGLINEV(699, 0, "%s: invalid texture format", "GXPreLoadEntireTexture"); + t->loadFmt = 2; + rowT = 2; + colT = 2; break; } - internal->texture_time_count = (GET_TILE_COUNT(width, a) * GET_TILE_COUNT(height, b)) & 0x7fff; - - internal->texture_flags |= 2; + rowC = (width + (1 << rowT) - 1) >> rowT; + colC = (height + (1 << colT) - 1) >> colT; + t->loadCnt = (rowC * colC) & 0x7FFF; + t->flags |= 2; } -/* 8035E08C-8035E0D4 3589CC 0048+00 0/0 3/3 1/1 .text GXInitTexObjCI */ -void GXInitTexObjCI(GXTexObj* obj, void* imagePtr, u16 width, u16 height, GXCITexFmt format, - GXTexWrapMode sWrap, GXTexWrapMode tWrap, GXBool useMIPmap, u32 tlut_name) { - GXTexObj* internal = (GXTexObj*)obj; +void GXInitTexObjCI(GXTexObj* obj, void* image_ptr, u16 width, u16 height, GXCITexFmt format, GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, GXBool mipmap, u32 tlut_name) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; - GXInitTexObj(obj, imagePtr, width, height, format, sWrap, tWrap, useMIPmap); - - internal->texture_flags &= ~2; - internal->tlut_name = tlut_name; + ASSERTMSGLINE(737, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(739, "GXInitTexObjCI"); + GXInitTexObj(obj, image_ptr, width, height, format, wrap_s, wrap_t, mipmap); + t->flags &= 0xFFFFFFFD; + t->tlutName = tlut_name; } -/* 80450A90-80450A98 000510 0008+00 1/1 0/0 0/0 .sdata GXTexMode0Ids */ -u8 GXTexMode0Ids[8] = {0x80, 0x81, 0x82, 0x83, 0xA0, 0xA1, 0xA2, 0xA3}; +void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter min_filt, GXTexFilter mag_filt, f32 min_lod, f32 max_lod, f32 lod_bias, u8 bias_clamp, u8 do_edge_lod, GXAnisotropy max_aniso) { + u8 lbias; + u8 lmin; + u8 lmax; + __GXTexObjInt* t = (__GXTexObjInt*)obj; -/* 80450A98-80450AA0 000518 0008+00 1/1 0/0 0/0 .sdata GXTexMode1Ids */ -u8 GXTexMode1Ids[8] = {0x84, 0x85, 0x86, 0x87, 0xA4, 0xA5, 0xA6, 0xA7}; + ASSERTMSGLINE(776, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(778, "GXInitTexObjLOD"); -/* 80450AA0-80450AA8 000520 0008+00 1/1 0/0 0/0 .sdata GXTexImage0Ids */ -u8 GXTexImage0Ids[8] = {0x88, 0x89, 0x8a, 0x8b, 0xA8, 0xA9, 0xAa, 0xAb}; - -/* 80450AA8-80450AB0 000528 0008+00 1/1 0/0 0/0 .sdata GXTexImage1Ids */ -u8 GXTexImage1Ids[8] = {0x8c, 0x8d, 0x8e, 0x8f, 0xAc, 0xAd, 0xAe, 0xAf}; - -/* 80450AB0-80450AB8 000530 0008+00 1/1 0/0 0/0 .sdata GXTexImage2Ids */ -u8 GXTexImage2Ids[8] = {0x90, 0x91, 0x92, 0x93, 0xB0, 0xB1, 0xB2, 0xB3}; - -/* 80450AB8-80450AC0 000538 0008+00 1/1 0/0 0/0 .sdata GXTexImage3Ids */ -u8 GXTexImage3Ids[8] = {0x94, 0x95, 0x96, 0x97, 0xB4, 0xB5, 0xB6, 0xB7}; - -/* 80450AC0-80450AC8 000540 0008+00 1/1 0/0 0/0 .sdata GXTexTlutIds */ -u8 GXTexTlutIds[8] = {0x98, 0x99, 0x9a, 0x9b, 0xB8, 0xB9, 0xBa, 0xBb}; - -/* 80450AC8-80450AD0 000548 0006+02 1/1 0/0 0/0 .sdata GX2HWFiltConv */ -u8 GX2HWFiltConv[6] = {0x00, 0x04, 0x01, 0x05, 0x02, 0x06}; - -/* 8035E0D4-8035E238 358A14 0164+00 0/0 21/21 4/4 .text GXInitTexObjLOD */ -void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter minFilter, GXTexFilter maxFilter, f32 minLOD, - f32 maxLOD, f32 lodBias, GXBool doBiasClamp, GXBool doEdgeLOD, - GXAnisotropy maxAniso) { - GXTexObj* internal = (GXTexObj*)obj; - u8 reg1, reg2; - if (lodBias < -4.0f) { - lodBias = -4.0f; - } else if (lodBias >= 4.0f) { - lodBias = 3.99f; + if (lod_bias < -4.0f) { + lod_bias = -4.0f; + } else if (lod_bias >= 4.0f) { + lod_bias = 3.99f; } - GX_SET_REG(internal->texture_filter, lodBias * 32.0f, 15, 22); - GX_SET_REG(internal->texture_filter, maxFilter == 1 ? 1 : 0, 27, 27); - GX_SET_REG(internal->texture_filter, GX2HWFiltConv[minFilter], 24, 26); - GX_SET_REG(internal->texture_filter, doEdgeLOD ? 0 : 1, 23, 23); - GX_SET_REG(internal->texture_filter, 0, 14, 14); - GX_SET_REG(internal->texture_filter, 0, 13, 13); - GX_SET_REG(internal->texture_filter, maxAniso, 11, 12); - GX_SET_REG(internal->texture_filter, doBiasClamp, 10, 10); + lbias = 32.0f * lod_bias; + SET_REG_FIELD(788, t->mode0, 8, 9, lbias); + ASSERTMSG1LINE(791, (u32)mag_filt <= 1, "%s: invalid mag_filt value", "GXInitTexObjLOD"); + SET_REG_FIELD(792, t->mode0, 1, 4, (mag_filt == GX_LINEAR) ? 1 : 0); + ASSERTMSG1LINE(795, (u32)min_filt <= 5, "%s: invalid min_filt value", "GXInitTexObjLOD"); + SET_REG_FIELD(796, t->mode0, 3, 5, GX2HWFiltConv[min_filt]); + SET_REG_FIELD(798, t->mode0, 1, 8, do_edge_lod ? 0 : 1); + SET_REG_FIELD(801, t->mode0, 1, 17, 0); + SET_REG_FIELD(801, t->mode0, 1, 18, 0); + SET_REG_FIELD(801, t->mode0, 2, 19, max_aniso); + SET_REG_FIELD(802, t->mode0, 1, 21, bias_clamp); - if (minLOD < 0.0f) { - minLOD = 0.0f; - } else if (minLOD > 10.0f) { - minLOD = 10.0f; + if (min_lod < 0.0f) { + min_lod = 0.0f; + } else if (min_lod > 10.0f) { + min_lod = 10.0f; } - reg1 = minLOD * 16.0f; - - if (maxLOD < 0.0f) { - maxLOD = 0.0f; - } else if (maxLOD > 10.0f) { - maxLOD = 10.0f; + lmin = 16.0f * min_lod; + if (max_lod < 0.0f) { + max_lod = 0.0f; + } else if (max_lod > 10.0f) { + max_lod = 10.0f; } - reg2 = maxLOD * 16.0f; - - GX_SET_REG(internal->texture_lod, reg1, 24, 31); - GX_SET_REG(internal->texture_lod, reg2, 16, 23); + lmax = 16.0f * max_lod; + SET_REG_FIELD(816, t->mode1, 8, 0, lmin); + SET_REG_FIELD(817, t->mode1, 8, 8, lmax); } -/* 8035E238-8035E248 358B78 0010+00 0/0 4/4 1/1 .text GXGetTexObjWidth */ -u16 GXGetTexObjWidth(GXTexObj* obj) { - return (obj->texture_size & 0x3ff) + 1; +void GXInitTexObjData(GXTexObj* obj, void* image_ptr) { + u32 imageBase; + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(835, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(837, "GXInitTexObjData"); + ASSERTMSGLINEV(840, ((u32)image_ptr & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexObjData", "image"); + imageBase = ((u32)image_ptr >> 5) & 0x01FFFFFF; + SET_REG_FIELD(843, t->image3, 21, 0, imageBase); } -/* 8035E248-8035E258 358B88 0010+00 0/0 3/3 0/0 .text GXGetTexObjHeight */ -u16 GXGetTexObjHeight(GXTexObj* obj) { - return ((obj->texture_size >> 10) & 0x3ff) + 1; +void GXInitTexObjWrapMode(GXTexObj* obj, GXTexWrapMode sm, GXTexWrapMode tm) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(860, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(862, "GXInitTexObjWrapMode"); + SET_REG_FIELD(864, t->mode0, 2, 0, sm); + SET_REG_FIELD(865, t->mode0, 2, 2, tm); } -/* 8035E258-8035E260 358B98 0008+00 0/0 1/1 0/0 .text GXGetTexObjFmt */ -GXTexFmt GXGetTexObjFmt(const GXTexObj* obj) { - return obj->texture_format; +void GXInitTexObjTlut(GXTexObj* obj, u32 tlut_name) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(881, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(883, "GXInitTexObjTlut"); + t->tlutName = tlut_name; } -/* 8035E260-8035E26C 358BA0 000C+00 0/0 1/1 0/0 .text GXGetTexObjWrapS */ -GXTexWrapMode GXGetTexObjWrapS(GXTexObj* obj) { - return obj->texture_filter & 0x3; +void GXInitTexObjFilter(GXTexObj* obj, GXTexFilter min_filt, GXTexFilter mag_filt) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(902, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(904, "GXInitTexObjFilter"); + + ASSERTMSG1LINE(907, (u32)mag_filt <= 1, "%s: invalid mag_filt value", "GXInitTexObjFilter"); + SET_REG_FIELD(908, t->mode0, 1, 4, mag_filt == 1 ? 1 : 0); + + ASSERTMSG1LINE(911, (u32)min_filt <= 5, "%s: invalid min_filt value", "GXInitTexObjFilter"); + SET_REG_FIELD(912, t->mode0, 3, 5, GX2HWFiltConv[min_filt]); } -/* 8035E26C-8035E278 358BAC 000C+00 0/0 1/1 0/0 .text GXGetTexObjWrapT */ -GXTexWrapMode GXGetTexObjWrapT(GXTexObj* obj) { - return (obj->texture_filter & 0xc) >> 2; +void GXInitTexObjMaxLOD(GXTexObj* obj, f32 max_lod) { + u8 lmax; + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(930, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(932, "GXInitTexObjMaxLOD"); + + if (max_lod < 0.0f) { + max_lod = 0.0f; + } else if (max_lod > 10.0f) { + max_lod = 10.0f; + } + lmax = 16.0f * max_lod; + SET_REG_FIELD(938, t->mode1, 8, 8, lmax); } -/* 8035E278-8035E290 358BB8 0018+00 0/0 1/1 0/0 .text GXGetTexObjMipMap */ -GXBool GXGetTexObjMipMap(const GXTexObj* obj) { - return (obj->texture_flags & 1) == 1; +void GXInitTexObjMinLOD(GXTexObj* obj, f32 min_lod) { + u8 lmin; + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(956, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(958, "GXInitTexObjMinLOD"); + + if (min_lod < 0.0f) { + min_lod = 0.0f; + } else if (min_lod > 10.0f) { + min_lod = 10.0f; + } + lmin = 16.0f * min_lod; + SET_REG_FIELD(964, t->mode1, 8, 0, lmin); } -/* 8035E290-8035E298 358BD0 0008+00 0/0 1/1 0/0 .text GXGetTexObjTlut */ -u32 GXGetTexObjTlut(GXTexObj* obj) { - return obj->tlut_name; +void GXInitTexObjLODBias(GXTexObj* obj, f32 lod_bias) { + u8 lbias; + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(982, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(984, "GXInitTexObjLODBias"); + + if (lod_bias < -4.0f) { + lod_bias = -4.0f; + } else if (lod_bias >= 4.0f) { + lod_bias = 3.99f; + } + lbias = 32.0f * lod_bias; + SET_REG_FIELD(991, t->mode0, 8, 9, lbias); } -/* 8035E298-8035E414 358BD8 017C+00 1/1 0/0 0/0 .text GXLoadTexObjPreLoaded */ -void GXLoadTexObjPreLoaded(GXTexObj* obj, GXTexRegion* region, GXTexMapID map) { - u8 stackManipulation[0x18]; +void GXInitTexObjBiasClamp(GXTexObj* obj, u8 bias_clamp) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; - GXTexObj* internalObj = (GXTexObj*)obj; - GXTexRegion* internalRegion = (GXTexRegion*)region; + ASSERTMSGLINE(1007, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(1009, "GXInitTexObjBiasClamp"); - GX_SET_REG(internalObj->texture_filter, GXTexMode0Ids[map], 0, 7); - GX_SET_REG(internalObj->texture_lod, GXTexMode1Ids[map], 0, 7); - GX_SET_REG(internalObj->texture_size, GXTexImage0Ids[map], 0, 7); + SET_REG_FIELD(1011, t->mode0, 1, 21, bias_clamp); +} - GX_SET_REG(internalRegion->unk0, GXTexImage1Ids[map], 0, 7); - GX_SET_REG(internalRegion->unk4, GXTexImage2Ids[map], 0, 7); +void GXInitTexObjEdgeLOD(GXTexObj* obj, u8 do_edge_lod) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; - GX_SET_REG(internalObj->texture_address, GXTexImage3Ids[map], 0, 7); + ASSERTMSGLINE(1027, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(1029, "GXInitTexObjEdgeLOD"); - GX_BP_LOAD_REG(internalObj->texture_filter); - GX_BP_LOAD_REG(internalObj->texture_lod); - GX_BP_LOAD_REG(internalObj->texture_size); - GX_BP_LOAD_REG(internalRegion->unk0); - GX_BP_LOAD_REG(internalRegion->unk4); - GX_BP_LOAD_REG(internalObj->texture_address); + SET_REG_FIELD(1031, t->mode0, 1, 8, do_edge_lod ? 0 : 1); +} - if ((internalObj->texture_flags & 2) == 0) { - GXTlutObj* tlut = (GXTlutObj*)__GXData->tlutRegionCallback(internalObj->tlut_name); - GX_SET_REG(tlut->address, GXTexTlutIds[map], 0, 7); +void GXInitTexObjMaxAniso(GXTexObj* obj, GXAnisotropy max_aniso) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; - GX_BP_LOAD_REG(tlut->address); + ASSERTMSGLINE(1047, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(1049, "GXInitTexObjMaxAniso"); + + SET_REG_FIELD(1051, t->mode0, 2, 19, max_aniso); +} + +void GXInitTexObjUserData(GXTexObj* obj, void* user_data) { + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + ASSERTMSGLINE(1068, obj, "Texture Object Pointer is null"); + CHECK_GXBEGIN(1069, "GXInitTexObjUserData"); + t->userData = user_data; +} + +void* GXGetTexObjUserData(const GXTexObj* obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)obj; + + ASSERTMSGLINE(1075, obj, "Texture Object Pointer is null"); + return t->userData; +} + +void GXGetTexObjAll(const GXTexObj* obj, void** image_ptr, u16* width, u16* height, GXTexFmt* format, GXTexWrapMode* wrap_s, GXTexWrapMode* wrap_t, u8* mipmap) { + const __GXTexObjInt* t = (const __GXTexObjInt *)obj; + + ASSERTMSGLINE(1095, obj, "Texture Object Pointer is null"); + *image_ptr = (void *)(GET_REG_FIELD(t->image3, 21, 0) << 5); + *width = (u32)GET_REG_FIELD(t->image0, 10, 0) + 1; + *height = (u32)GET_REG_FIELD(t->image0, 10, 10) + 1; + *format = t->fmt; + *wrap_s = GET_REG_FIELD(t->mode0, 2, 0); + *wrap_t = GET_REG_FIELD(t->mode0, 2, 2); + *mipmap = (t->flags & 1) == 1; +} + +void* GXGetTexObjData(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1108, to, "Texture Object Pointer is null"); + return (void*)(GET_REG_FIELD(t->image3, 21, 0) << 5); +} + +u16 GXGetTexObjWidth(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1114, to, "Texture Object Pointer is null"); + return (u32)GET_REG_FIELD(t->image0, 10, 0) + 1; +} + +u16 GXGetTexObjHeight(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1120, to, "Texture Object Pointer is null"); + return (u32)GET_REG_FIELD(t->image0, 10, 10) + 1; +} + +GXTexFmt GXGetTexObjFmt(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1126, to, "Texture Object Pointer is null"); + return t->fmt; +} + +GXTexWrapMode GXGetTexObjWrapS(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1132, to, "Texture Object Pointer is null"); + return GET_REG_FIELD(t->mode0, 2, 0); +} + +GXTexWrapMode GXGetTexObjWrapT(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1138, to, "Texture Object Pointer is null"); + return GET_REG_FIELD(t->mode0, 2, 2); +} + +GXBool GXGetTexObjMipMap(const GXTexObj* to) { + const __GXTexObjInt* t = (const __GXTexObjInt *)to; + + ASSERTMSGLINE(1144, to, "Texture Object Pointer is null"); + return (t->flags & 1) == 1; +} + +void GXGetTexObjLODAll(const GXTexObj* tex_obj, GXTexFilter* min_filt, GXTexFilter* mag_filt, f32* min_lod, f32* max_lod, f32* lod_bias, u8* bias_clamp, u8* do_edge_lod, GXAnisotropy* max_aniso) { + s16 tmp; + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1166, tex_obj, "Texture Object Pointer is null"); + *min_filt = HW2GXFiltConv[GET_REG_FIELD(t->mode0, 3, 5)]; + *mag_filt = GET_REG_FIELD(t->mode0, 1, 4); + *min_lod = (u8)t->mode1 / 16.0f; + *max_lod = (u32)GET_REG_FIELD(t->mode1, 8, 8) / 16.0f; + tmp = (s32)GET_REG_FIELD(t->mode0, 8, 9); + *lod_bias = (s8)tmp / 32.0f; + *bias_clamp = (u32)GET_REG_FIELD(t->mode0, 1, 21); + *do_edge_lod = !GET_REG_FIELD(t->mode0, 1, 8); + *max_aniso = GET_REG_FIELD(t->mode0, 2, 19); +} + +GXTexFilter GXGetTexObjMinFilt(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1182, tex_obj, "Texture Object Pointer is null"); + return HW2GXFiltConv[GET_REG_FIELD(t->mode0, 3, 5)]; +} + +GXTexFilter GXGetTexObjMagFilt(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1189, tex_obj, "Texture Object Pointer is null"); + return GET_REG_FIELD(t->mode0, 1, 4); +} + +f32 GXGetTexObjMinLOD(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1195, tex_obj, "Texture Object Pointer is null"); + return (u32)GET_REG_FIELD(t->mode1, 8, 0) / 16.0f; +} + +f32 GXGetTexObjMaxLOD(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1201, tex_obj, "Texture Object Pointer is null"); + return (u32)GET_REG_FIELD(t->mode1, 8, 8) / 16.0f; +} + +f32 GXGetTexObjLODBias(const GXTexObj* tex_obj) { + s16 tmp; + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1208, tex_obj, "Texture Object Pointer is null"); + tmp = (s32)GET_REG_FIELD(t->mode0, 8, 9); + return (s8)tmp / 32.0f; +} + +GXBool GXGetTexObjBiasClamp(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1215, tex_obj, "Texture Object Pointer is null"); + return (u32)GET_REG_FIELD(t->mode0, 1, 21); +} + +GXBool GXGetTexObjEdgeLOD(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1221, tex_obj, "Texture Object Pointer is null"); + return !GET_REG_FIELD(t->mode0, 1, 8); +} + +GXAnisotropy GXGetTexObjMaxAniso(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1227, tex_obj, "Texture Object Pointer is null"); + return GET_REG_FIELD(t->mode0, 2, 19); +} + +u32 GXGetTexObjTlut(const GXTexObj* tex_obj) { + const __GXTexObjInt* t = (const __GXTexObjInt *)tex_obj; + + ASSERTMSGLINE(1233, tex_obj, "Texture Object Pointer is null"); + return t->tlutName; +} + +void GXLoadTexObjPreLoaded(GXTexObj* obj, GXTexRegion* region, GXTexMapID id) { + __GXTlutRegionInt* tlr; + u32 m0; + u32 m1; + u32 img0; + u32 img1; + u32 img2; + u32 img3; + __GXTexObjInt* t = (__GXTexObjInt*)obj; + __GXTexRegionInt* r = (__GXTexRegionInt *)region; + + ASSERTMSGLINE(1257, obj, "Texture Object Pointer is null"); + ASSERTMSGLINE(1257, region, "TexRegion Object Pointer is null"); + CHECK_GXBEGIN(1259, "GXLoadTexObjPreLoaded"); + ASSERTMSGLINEV(1260, id < GX_MAX_TEXMAP, "%s: invalid texture map ID", "GXLoadTexObj"); + + m0 = t->mode0; + m1 = t->mode1; + img0 = t->image0; + img1 = r->image1; + img2 = r->image2; + img3 = t->image3; + + SET_REG_FIELD(1271, t->mode0, 8, 24, GXTexMode0Ids[id]); + SET_REG_FIELD(1272, t->mode1, 8, 24, GXTexMode1Ids[id]); + SET_REG_FIELD(1273, t->image0, 8, 24, GXTexImage0Ids[id]); + SET_REG_FIELD(1274, r->image1, 8, 24, GXTexImage1Ids[id]); + SET_REG_FIELD(1275, r->image2, 8, 24, GXTexImage2Ids[id]); + SET_REG_FIELD(1276, t->image3, 8, 24, GXTexImage3Ids[id]); + + GX_WRITE_RAS_REG(t->mode0); + GX_WRITE_RAS_REG(t->mode1); + GX_WRITE_RAS_REG(t->image0); + GX_WRITE_RAS_REG(r->image1); + GX_WRITE_RAS_REG(r->image2); + GX_WRITE_RAS_REG(t->image3); + + if (!(t->flags & 2)) { + ASSERTMSGLINEV(1287, __GXData->tlutRegionCallback, "%s: Tex/Tlut Region Callback not set", "GXLoadTexObj/PreLoaded"); + tlr = (__GXTlutRegionInt*)__GXData->tlutRegionCallback(t->tlutName); + ASSERTMSGLINEV(1289, tlr, "%s: Tex/Tlut Region Callback returns NULL", "GXLoadTexObj/PreLoaded"); + + SET_REG_FIELD(1291, tlr->tlutObj.tlut, 8, 24, GXTexTlutIds[id]); + GX_WRITE_RAS_REG(tlr->tlutObj.tlut); } - __GXData->tImage0[map] = internalObj->texture_size; - __GXData->tMode0[map] = internalObj->texture_filter; - - __GXData->dirtyState |= GX_DIRTY_SU_TEX; - __GXData->bpSentNot = GX_FALSE; -} - -/* 8035E414-8035E468 358D54 0054+00 0/0 33/33 5/5 .text GXLoadTexObj */ -void GXLoadTexObj(GXTexObj* obj, GXTexMapID map) { - GXTexRegion* ret = (GXTexRegion*)__GXData->texRegionCallback(obj, map); - - GXLoadTexObjPreLoaded(obj, ret, map); -} - -/* 8035E468-8035E4A0 358DA8 0038+00 0/0 4/4 1/1 .text GXInitTlutObj */ -void GXInitTlutObj(GXTlutObj* obj, void* table, GXTlutFmt format, u16 numEntries) { - GXTlutObj* internal = (GXTlutObj*)obj; - - internal->format = 0; - - GX_SET_REG(internal->format, format, 20, 21); - GX_SET_REG(internal->address, (u32)table >> 5, 11, 31); - GX_SET_REG(internal->address, 100, 0, 7); - - internal->numEntries = numEntries; -} - -/* 8035E4A0-8035E538 358DE0 0098+00 0/0 4/4 1/1 .text GXLoadTlut */ -void GXLoadTlut(GXTlutObj* obj, u32 tlut_name) { - GXTlutObj* internal = (GXTlutObj*)obj; - GXTlutRegion* ret = (GXTlutRegion*)__GXData->tlutRegionCallback(tlut_name); - u32 reg; - - __GXFlushTextureState(); - - GX_BP_LOAD_REG(internal->address); - GX_BP_LOAD_REG(ret->unk0); - - __GXFlushTextureState(); - - reg = ret->unk0; - GX_SET_REG(internal->format, reg, 22, 31); - - ret->tlutObj = *internal; -} - -/* 8035E538-8035E62C 358E78 00F4+00 0/0 2/2 0/0 .text GXInitTexCacheRegion */ -void GXInitTexCacheRegion(GXTexRegion* region, GXBool is32bMIPmap, u32 memEven, - GXTexCacheSize sizeEven, u32 memOdd, GXTexCacheSize sizeOdd) { - GXTexRegion* internal = (GXTexRegion*)region; - - u32 reg; - switch (sizeEven) { - case 0: - reg = 3; - break; - case 1: - reg = 4; - break; - case 2: - reg = 5; - break; - } - - internal->unk0 = 0; - - GX_SET_REG(internal->unk0, memEven >> 5, 17, 31); - GX_SET_REG(internal->unk0, reg, 14, 16); - GX_SET_REG(internal->unk0, reg, 11, 13); - GX_SET_REG(internal->unk0, 0, 10, 10); - - switch (sizeOdd) { - case 0: - reg = 3; - break; - case 1: - reg = 4; - break; - case 2: - reg = 5; - break; - case 3: - reg = 0; - break; - } - - internal->unk4 = 0; - GX_SET_REG(internal->unk4, memOdd >> 5, 17, 31); - GX_SET_REG(internal->unk4, reg, 14, 16); - GX_SET_REG(internal->unk4, reg, 11, 13); - - internal->unkC = is32bMIPmap; - internal->unkD = 1; -} - -/* 8035E62C-8035E664 358F6C 0038+00 0/0 1/1 0/0 .text GXInitTlutRegion */ -void GXInitTlutRegion(GXTlutRegion* region, u32 memAddr, GXTlutSize tlutSize) { - GXTlutRegion* internal = (GXTlutRegion*)region; - - internal->unk0 = 0; - GX_SET_REG(internal->unk0, (memAddr - 0x80000) >> 9, 22, 31); - GX_SET_REG(internal->unk0, tlutSize, 11, 21); - GX_SET_REG(internal->unk0, 0x65, 0, 7); -} - -/* 8035E664-8035E6AC 358FA4 0048+00 0/0 8/8 1/1 .text GXInvalidateTexAll */ -void GXInvalidateTexAll(void) { - __GXFlushTextureState(); - GXWGFifo.u8 = 0x61; - GXWGFifo.u32 = 0x66001000; - GXWGFifo.u8 = 0x61; - GXWGFifo.u32 = 0x66001100; - __GXFlushTextureState(); -} - -/* 8035E6AC-8035E6C0 358FEC 0014+00 0/0 1/1 0/0 .text GXSetTexRegionCallback */ -GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback callback) { - GXTexRegionCallback prev = __GXData->texRegionCallback; - __GXData->texRegionCallback = callback; - return prev; -} - -/* 8035E6C0-8035E6D4 359000 0014+00 0/0 1/1 0/0 .text GXSetTlutRegionCallback */ -GXTlutRegionCallback GXSetTlutRegionCallback(GXTlutRegionCallback callback) { - GXTlutRegionCallback prev = __GXData->tlutRegionCallback; - __GXData->tlutRegionCallback = callback; - return prev; -} - -/* 8035E6D4-8035E750 359014 007C+00 0/0 1/1 0/0 .text GXSetTexCoordScaleManually */ -void GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 s_scale, u16 t_scale) { - __GXData->tcsManEnab = (__GXData->tcsManEnab & ~(1 << coord)) | (enable << coord); - if (enable == GX_FALSE) { - return; - } - GX_SET_REG(__GXData->suTs0[coord], (u16)(s_scale - 1), 16, 31); - GX_SET_REG(__GXData->suTs1[coord], (u16)(t_scale - 1), 16, 31); - GXWGFifo.u8 = 0x61; - GXWGFifo.u32 = __GXData->suTs0[coord]; - GXWGFifo.u8 = 0x61; - GXWGFifo.u32 = __GXData->suTs1[coord]; + __GXData->tImage0[id] = t->image0; + __GXData->tMode0[id] = t->mode0; + __GXData->dirtyState |= 1; __GXData->bpSentNot = 0; } -/* 8035E750-8035E7F0 359090 00A0+00 1/1 0/0 0/0 .text __SetSURegs */ -void __SetSURegs(u32 texImgIndex, u32 setUpRegIndex) { - u16 a1, a2; - GXBool b, c; +void GXLoadTexObj(GXTexObj* obj, GXTexMapID id) { + GXTexRegion* r; - a1 = GX_GET_REG(__GXData->tImage0[texImgIndex], 22, 31); - a2 = (__GXData->tImage0[texImgIndex] & (0x3ff << 10)) >> 10; - - GX_SET_REG(__GXData->suTs0[setUpRegIndex], a1, 16, 31); - GX_SET_REG(__GXData->suTs1[setUpRegIndex], a2, 16, 31); - - b = GX_GET_REG(__GXData->tMode0[texImgIndex], 30, 31) == 1; - c = GX_GET_REG(__GXData->tMode0[texImgIndex], 28, 29) == 1; - - GX_SET_REG(__GXData->suTs0[setUpRegIndex], b, 15, 15); - GX_SET_REG(__GXData->suTs1[setUpRegIndex], c, 15, 15); - - GX_BP_LOAD_REG(__GXData->suTs0[setUpRegIndex]); - GX_BP_LOAD_REG(__GXData->suTs1[setUpRegIndex]); - - __GXData->bpSentNot = GX_FALSE; + CHECK_GXBEGIN(1318, "GXLoadTexObj"); + ASSERTMSGLINEV(1319, id < 8, "%s: invalid texture map ID", "GXLoadTexObj"); + ASSERTMSGLINEV(1324, __GXData->texRegionCallback, "%s: Tex/Tlut Region Callback not set", "GXLoadTexObj"); + r = __GXData->texRegionCallback(obj, id); + ASSERTMSGLINEV(1326, r, "%s: Tex/Tlut Region Callback returns NULL", "GXLoadTexObj"); + GXLoadTexObjPreLoaded(obj, r, id); } -/* 8035E7F0-8035E96C 359130 017C+00 0/0 2/2 0/0 .text __GXSetSUTexRegs */ -#pragma dont_inline on -void __GXSetSUTexRegs(void) { +void GXInitTlutObj(GXTlutObj* tlut_obj, void* lut, GXTlutFmt fmt, u16 n_entries) { + __GXTlutObjInt* t = (__GXTlutObjInt *)tlut_obj; + + ASSERTMSGLINE(1350, tlut_obj, "TLut Object Pointer is null"); + CHECK_GXBEGIN(1351, "GXInitTlutObj"); + ASSERTMSGLINEV(1354, n_entries <= 0x4000, "%s: number of entries exceeds maximum", "GXInitTlutObj"); + ASSERTMSGLINEV(1356, ((u32)lut & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTlutObj", "Tlut"); + t->tlut = 0; + SET_REG_FIELD(1359, t->tlut, 2, 10, fmt); + SET_REG_FIELD(1360, t->loadTlut0, 21, 0, ((u32)lut & 0x3FFFFFFF) >> 5); + SET_REG_FIELD(1361, t->loadTlut0, 8, 24, 0x64); + t->numEntries = n_entries; +} + +void GXGetTlutObjAll(const GXTlutObj* tlut_obj, void **data, GXTlutFmt* format, u16* numEntries) { + const __GXTlutObjInt* t = (const __GXTlutObjInt *)tlut_obj; + + ASSERTMSGLINE(1382, tlut_obj, "TLut Object Pointer is null"); + *data = (void *)(GET_REG_FIELD(t->loadTlut0, 21, 0) << 5); + *format = GET_REG_FIELD(t->tlut, 2, 10); + *numEntries = t->numEntries; +} + +void* GXGetTlutObjData(const GXTlutObj* tlut_obj) { + const __GXTlutObjInt* t = (const __GXTlutObjInt *)tlut_obj; + + ASSERTMSGLINE(1391, tlut_obj, "TLut Object Pointer is null"); + return (void *)(GET_REG_FIELD(t->loadTlut0, 21, 0) << 5); +} + +GXTlutFmt GXGetTlutObjFmt(const GXTlutObj* tlut_obj) { + const __GXTlutObjInt* t = (const __GXTlutObjInt *)tlut_obj; + + ASSERTMSGLINE(1398, tlut_obj, "TLut Object Pointer is null"); + return GET_REG_FIELD(t->tlut, 2, 10); +} + +u16 GXGetTlutObjNumEntries(const GXTlutObj* tlut_obj) { + const __GXTlutObjInt* t = (const __GXTlutObjInt *)tlut_obj; + + ASSERTMSGLINE(1405, tlut_obj, "TLut Object Pointer is null"); + return t->numEntries; +} + +void GXLoadTlut(GXTlutObj* tlut_obj, u32 tlut_name) { + __GXTlutRegionInt* r; + u32 tlut_offset; + __GXTlutObjInt* t = (__GXTlutObjInt *)tlut_obj; + + ASSERTMSGLINE(1432, tlut_obj, "TLut Object Pointer is null"); + CHECK_GXBEGIN(1434, "GXLoadTlut"); + ASSERTMSGLINEV(1435, __GXData->tlutRegionCallback, "%s: Tex/Tlut Region Callback not set", "GXLoadTlut"); + r = (__GXTlutRegionInt *)__GXData->tlutRegionCallback(tlut_name); + ASSERTMSGLINEV(1437, r, "%s: Tex/Tlut Region Callback returns NULL", "GXLoadTlut"); + + __GXFlushTextureState(); + GX_WRITE_RAS_REG(t->loadTlut0); + GX_WRITE_RAS_REG(r->loadTlut1); + __GXFlushTextureState(); + tlut_offset = r->loadTlut1 & 0x3FF; + SET_REG_FIELD(1453, t->tlut, 10, 0, tlut_offset); + r->tlutObj = *t; +} + +void GXInitTexCacheRegion(GXTexRegion* region, u8 is_32b_mipmap, u32 tmem_even, GXTexCacheSize size_even, u32 tmem_odd, GXTexCacheSize size_odd) { + u32 WidthExp2; + __GXTexRegionInt* t = (__GXTexRegionInt*)region; + + ASSERTMSGLINE(1484, region, "TexRegion Object Pointer is null"); + CHECK_GXBEGIN(1486, "GXInitTexCacheRegion"); + ASSERTMSGLINEV(1488, (tmem_even & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexCacheRegion", "tmem even"); + ASSERTMSGLINEV(1490, (tmem_odd & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexCacheRegion", "tmem odd"); + + switch (size_even) { + case GX_TEXCACHE_32K: + WidthExp2 = 3; + break; + case GX_TEXCACHE_128K: + WidthExp2 = 4; + break; + case GX_TEXCACHE_512K: + WidthExp2 = 5; + break; + default: + ASSERTMSGLINEV(1498, 0, "%s: Invalid %s size", "GXInitTexCacheRegion", "tmem even"); + break; + } + + t->image1 = 0; + SET_REG_FIELD(1503, t->image1, 15, 0, tmem_even >> 5); + SET_REG_FIELD(1504, t->image1, 3, 15, WidthExp2); + SET_REG_FIELD(1505, t->image1, 3, 18, WidthExp2); + SET_REG_FIELD(1506, t->image1, 1, 21, 0); + + switch (size_odd) { + case GX_TEXCACHE_32K: + WidthExp2 = 3; + break; + case GX_TEXCACHE_128K: + WidthExp2 = 4; + break; + case GX_TEXCACHE_512K: + WidthExp2 = 5; + break; + case GX_TEXCACHE_NONE: + WidthExp2 = 0; + break; + default: + ASSERTMSGLINEV(1514, 0, "%s: Invalid %s size", "GXInitTexCacheRegion", "tmem odd"); + break; + } + + t->image2 = 0; + SET_REG_FIELD(1519, t->image2, 15, 0, tmem_odd >> 5); + SET_REG_FIELD(1520, t->image2, 3, 15, WidthExp2); + SET_REG_FIELD(1521, t->image2, 3, 18, WidthExp2); + t->is32bMipmap = is_32b_mipmap; + t->isCached = 1; +} + +void GXInitTexPreLoadRegion(GXTexRegion* region, u32 tmem_even, u32 size_even, u32 tmem_odd, u32 size_odd) { + __GXTexRegionInt* t = (__GXTexRegionInt *)region; + + ASSERTMSGLINE(1550, region, "TexRegion Object Pointer is null"); + CHECK_GXBEGIN(1552, "GXInitTexPreLoadRegion"); + ASSERTMSGLINEV(1554, (tmem_even & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexPreLoadRegion", "tmem even"); + ASSERTMSGLINEV(1556, (tmem_odd & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexPreLoadRegion", "tmem odd"); + ASSERTMSGLINEV(1558, (size_even & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexPreLoadRegion", "size even"); + ASSERTMSGLINEV(1560, (size_odd & 0x1F) == 0, "%s: %s pointer not aligned to 32B", "GXInitTexPreLoadRegion", "size odd"); + + t->image1 = 0; + SET_REG_FIELD(1564, t->image1, 15, 0, tmem_even >> 5); + SET_REG_FIELD(1565, t->image1, 3, 15, 0); + SET_REG_FIELD(1566, t->image1, 3, 18, 0); + SET_REG_FIELD(1567, t->image1, 1, 21, 1); + + t->image2 = 0; + SET_REG_FIELD(1570, t->image2, 15, 0, tmem_odd >> 5); + SET_REG_FIELD(1571, t->image2, 3, 15, 0); + SET_REG_FIELD(1572, t->image2, 3, 18, 0); + t->is32bMipmap = 0; + t->isCached = 0; + t->sizeEven = (u16)(size_even >> 5); + t->sizeOdd = (u16)(size_odd >> 5); +} + +void GXGetTexRegionAll(const GXTexRegion* region, u8* is_cached, u8* is_32b_mipmap, u32* tmem_even, u32* size_even, u32* tmem_odd, u32* size_odd) { + const __GXTexRegionInt* t = (const __GXTexRegionInt *)region; + + ASSERTMSGLINE(1601, region, "TexRegion Object Pointer is null"); + *tmem_even = GET_REG_FIELD(t->image1, 15, 0) << 5; + *tmem_odd = GET_REG_FIELD(t->image2, 15, 0) << 5; + if (t->isCached) { + switch (GET_REG_FIELD(t->image1, 3, 15)) { + case 3: + *size_even = 0x8000; + break; + case 4: + *size_even = 0x20000; + break; + case 5: + *size_even = 0x80000; + break; + default: + *size_even = 0; + break; + } + + switch (GET_REG_FIELD(t->image2, 3, 15)) { + case 3: + *size_odd = 0x8000; + break; + case 4: + *size_odd = 0x20000; + break; + case 5: + *size_odd = 0x80000; + break; + default: + *size_odd = 0; + break; + } + } else { + *size_even = t->sizeEven << 5; + *size_odd = t->sizeOdd << 5; + } + + *is_32b_mipmap = t->is32bMipmap; + *is_cached = t->isCached; +} + +void GXInitTlutRegion(GXTlutRegion* region, u32 tmem_addr, GXTlutSize tlut_size) { + __GXTlutRegionInt* t = (__GXTlutRegionInt *)region; + + ASSERTMSGLINE(1652, region, "TLutRegion Object Pointer is null"); + CHECK_GXBEGIN(1654, "GXInitTlutRegion"); + ASSERTMSGLINEV(1655, (tmem_addr & 0x1FF) == 0, "%s: tmem pointer is not aligned to 512B", "GXInitTlutRegion"); + ASSERTMSGLINEV(1656, tlut_size <= 0x400, "%s: tlut size exceeds 16K", "GXInitTlutRegion"); + t->loadTlut1 = 0; + tmem_addr -= 0x80000; + SET_REG_FIELD(1660, t->loadTlut1, 10, 0, tmem_addr >> 9); + SET_REG_FIELD(1661, t->loadTlut1, 11, 10, tlut_size); + SET_REG_FIELD(1662, t->loadTlut1, 8, 24, 0x65); +} + +void GXGetTlutRegionAll(const GXTlutRegion* region, u32* tmem_addr, GXTlutSize* tlut_size) { + const __GXTlutRegionInt* t = (const __GXTlutRegionInt *)region; + + ASSERTMSGLINE(1682, region, "TLutRegion Object Pointer is null"); + *tmem_addr = (GET_REG_FIELD(t->loadTlut1, 10, 0) << 9) + 0x80000; + *tlut_size = GET_REG_FIELD(t->loadTlut1, 11, 10); +} + +void GXInvalidateTexRegion(GXTexRegion* region) { + s32 wle; + s32 hle; + s32 wlo; + s32 hlo; + s32 count; + u32 reg0; + u32 reg1; + __GXTexRegionInt* r = (__GXTexRegionInt*)region; + + ASSERTMSGLINE(1705, region, "TexRegion Object Pointer is null"); + CHECK_GXBEGIN(1707, "GXInvalidateTexRegion"); + + wle = GET_REG_FIELD(r->image1, 3, 15) - 1; + hle = GET_REG_FIELD(r->image1, 3, 18) - 1; + wlo = GET_REG_FIELD(r->image2, 3, 15) - 1; + hlo = GET_REG_FIELD(r->image2, 3, 18) - 1; + if (wle < 0) { + wle = 0; + } + if (hle < 0) { + hle = 0; + } + if (wlo < 0) { + wlo = 0; + } + if (hlo < 0) { + hlo = 0; + } + count = wle + hle; + if (r->is32bMipmap) { + count = wlo + hlo - 2 + count; + } + + reg0 = 0; + SET_REG_FIELD(1724, reg0, 9, 0, GET_REG_FIELD(r->image1, 9, 6)); + SET_REG_FIELD(1725, reg0, 4, 9, count); + SET_REG_FIELD(1724, reg0, 8, 24, 0x66); + + if (wlo != 0) { + count = wlo + hlo; + if (r->is32bMipmap) { + count = wle + hle - 2 + count; + } + reg1 = 0; + SET_REG_FIELD(1736, reg1, 9, 0, GET_REG_FIELD(r->image2, 9, 6)); + SET_REG_FIELD(1737, reg1, 4, 9, count); + SET_REG_FIELD(1738, reg1, 8, 24, 0x66); + } + + __GXFlushTextureState(); + GX_WRITE_RAS_REG(reg0); + if (wlo != 0) { + GX_WRITE_RAS_REG(reg1); + } + __GXFlushTextureState(); + + reg0; reg1; r; // needed to match +} + +void GXInvalidateTexAll(void) { + u32 reg0; + u32 reg1; + + CHECK_GXBEGIN(1755, "GXInvalidateTexAll"); + reg0 = 0x66001000; + reg1 = 0x66001100; + __GXFlushTextureState(); + GX_WRITE_RAS_REG(reg0); + GX_WRITE_RAS_REG(reg1); + __GXFlushTextureState(); +} + +GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback f) { + GXTexRegionCallback oldcb = __GXData->texRegionCallback; + + __GXData->texRegionCallback = f; + return oldcb; +} + +GXTlutRegionCallback GXSetTlutRegionCallback(GXTlutRegionCallback f) { + GXTlutRegionCallback oldcb = __GXData->tlutRegionCallback; + + __GXData->tlutRegionCallback = f; + return oldcb; +} + +void GXPreLoadEntireTexture(GXTexObj* tex_obj, GXTexRegion* region) { + GXBool isMipMap; + GXBool is32bit; + u32 wd; + u32 ht; + u32 maxLevelIndex; + u32 loadImage0; + u32 loadImage1; + u32 loadImage2; + u32 loadImage3; + u32 base; + u32 tmem1; + u32 tmem2; + u32 tmemAR; + u32 tmemGB; + u32 nTiles; +#if DEBUG + u32 totalOdd; + u32 totalEven; + u32 count; +#endif + u32 rowTiles; + u32 colTiles; + u32 cmpTiles; u32 i; - u32 b; - u32 a; - u32 c; - u32 d; - u32 stackFiller; - if (__GXData->tcsManEnab != 0xff) { - a = GX_GET_REG(__GXData->genMode, 18, 21) + 1; - b = GX_GET_REG(__GXData->genMode, 13, 15); - for (i = 0; i < b; i++) { + __GXTexObjInt* t = (__GXTexObjInt*)tex_obj; + __GXTexRegionInt* r = (__GXTexRegionInt*)region; + + ASSERTMSGLINE(1820, tex_obj, "Texture Object Pointer is null"); + ASSERTMSGLINE(1820, region, "TexRegion Object Pointer is null"); + CHECK_GXBEGIN(1822, "GXPreLoadEntireTexture"); + isMipMap = (t->flags & 1) == 1; + is32bit = GET_REG_FIELD(t->image0, 4, 20) == 6; + + loadImage0 = 0; + SET_REG_FIELD(0, loadImage0, 8, 24, 0x60); + base = t->image3 & 0x1FFFFF; + SET_REG_FIELD(1831, loadImage0, 21, 0, base); + + loadImage1 = 0; + SET_REG_FIELD(0, loadImage1, 8, 24, 0x61); + tmem1 = r->image1 & 0x7FFF; + SET_REG_FIELD(1837, loadImage1, 15, 0, tmem1); + + loadImage2 = 0; + SET_REG_FIELD(0, loadImage2, 8, 24, 0x62); + tmem2 = r->image2 & 0x7FFF; + SET_REG_FIELD(1843, loadImage2, 15, 0, tmem2); + + loadImage3 = 0; + SET_REG_FIELD(0, loadImage3, 8, 24, 0x63); + SET_REG_FIELD(1848, loadImage3, 15, 0, t->loadCnt); + SET_REG_FIELD(1849, loadImage3, 2, 15, t->loadFmt); + maxLevelIndex = 0; + nTiles = t->loadCnt; + + if (isMipMap) { + wd = GET_REG_FIELD(t->image0, 10, 0) + 1; + ht = GET_REG_FIELD(t->image0, 10, 10) + 1; + if (wd > ht) { + maxLevelIndex = (u16)(31 - __cntlzw(wd)); + } else { + maxLevelIndex = (u16)(31 - __cntlzw(ht)); + } + +#if DEBUG + count = nTiles; + totalOdd = totalEven = 0; + + for (i = 0; i < maxLevelIndex; i++) { + if (i & 1) { + if (count == 0) { + count = 1; + } + totalOdd += count; + } else { + if (count == 0) { + count = 1; + } + totalEven += count; + } + __GetImageTileCount(t->fmt, wd >> (i + 1), ht >> (i + 1), &rowTiles, &colTiles, &cmpTiles); + count = rowTiles * colTiles; + } +#endif + } else { +#if DEBUG + totalEven = (nTiles == 0) ? 1 : nTiles; + totalOdd = totalEven; +#endif + } + +#if DEBUG + if (is32bit) { + totalOdd = isMipMap ? totalOdd : 0; + totalEven = totalEven + totalOdd; + ASSERTMSGLINE(1890, totalEven <= r->sizeEven, "GXPreLoadEntireTexture: Even tmem size does not match the texture size"); + ASSERTMSGLINE(1891, totalEven <= r->sizeOdd, "GXPreLoadEntireTexture: Odd tmem size does not match the texture size"); + } else if (isMipMap != 0) { + if (r->sizeEven > r->sizeOdd) { + ASSERTMSGLINE(1896, totalEven <= r->sizeEven, "GXPreLoadEntireTexture: Even tmem size does not match the texture size"); + ASSERTMSGLINE(1897, totalOdd <= r->sizeOdd, "GXPreLoadEntireTexture: Odd tmem size does not match the texture size"); + } else { + ASSERTMSGLINE(1900, totalEven <= r->sizeOdd, "GXPreLoadEntireTexture: Odd tmem size does not match the texture size"); + ASSERTMSGLINE(1901, totalOdd <= r->sizeEven, "GXPreLoadEntireTexture: Even tmem size does not match the texture size"); + } + } else if (r->sizeEven > r->sizeOdd) { + ASSERTMSGLINE(1906, totalEven <= r->sizeEven, "GXPreLoadEntireTexture: Even tmem size does not match the texture size"); + } else { + ASSERTMSGLINE(1908, totalOdd <= r->sizeOdd, "GXPreLoadEntireTexture: Odd tmem size does not match the texture size"); + } +#endif + + __GXFlushTextureState(); + GX_WRITE_RAS_REG(loadImage0); + GX_WRITE_RAS_REG(loadImage1); + GX_WRITE_RAS_REG(loadImage2); + GX_WRITE_RAS_REG(loadImage3); + + if (maxLevelIndex != 0) { + tmemAR = tmem1; + tmemGB = tmem2; + for (i = 0; i < maxLevelIndex; i++) { + if (is32bit) { + base += nTiles * 2; + tmemAR += nTiles; + tmemGB += nTiles; + } else { + base += nTiles; + if (i & 1) { + tmemGB += nTiles; + } else { + tmemAR += nTiles; + } + } + tmem1 = (i & 1) ? tmemAR : tmemGB; + tmem2 = (i & 1) ? tmemGB : tmemAR; + __GetImageTileCount(t->fmt, (u16) (wd >> (i + 1)), (u16) (ht >> (i + 1)), &rowTiles, &colTiles, &cmpTiles); + nTiles = rowTiles * colTiles; + SET_REG_FIELD(1957, loadImage0, 21, 0, base); + SET_REG_FIELD(1958, loadImage1, 15, 0, tmem1); + SET_REG_FIELD(1959, loadImage2, 15, 0, tmem2); + SET_REG_FIELD(1960, loadImage3, 15, 0, nTiles); + GX_WRITE_RAS_REG(loadImage0); + GX_WRITE_RAS_REG(loadImage1); + GX_WRITE_RAS_REG(loadImage2); + GX_WRITE_RAS_REG(loadImage3); + } + } + __GXFlushTextureState(); + + // needed to match debug + maxLevelIndex; maxLevelIndex; base; base; base; tmem1; tmem1; tmem2; tmem2; +} + +void GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 ss, u16 ts) { + CHECK_GXBEGIN(1989, "GXSetTexCoordScaleManually"); + ASSERTMSGLINEV(1991, coord < GX_MAX_TEXCOORD, "%s: bad texcoord specified", "GXSetTexCoordScaleManually"); + __GXData->tcsManEnab = (__GXData->tcsManEnab & ~(1 << coord)) | (enable << coord); + + if (enable) { + SET_REG_FIELD(1997, __GXData->suTs0[coord], 16, 0, (u16)(ss - 1)); + SET_REG_FIELD(1998, __GXData->suTs1[coord], 16, 0, (u16)(ts - 1)); + GX_WRITE_RAS_REG(__GXData->suTs0[coord]); + GX_WRITE_RAS_REG(__GXData->suTs1[coord]); + __GXData->bpSentNot = 0; + } +} + +void GXSetTexCoordCylWrap(GXTexCoordID coord, u8 s_enable, u8 t_enable) { + CHECK_GXBEGIN(2023, "GXSetTexCoordCylWrap"); + ASSERTMSGLINEV(2025, coord < GX_MAX_TEXCOORD, "%s: bad texcoord specified", "GXSetTexCoordCylWrap"); + SET_REG_FIELD(2027, __GXData->suTs0[coord], 1, 17, s_enable); + SET_REG_FIELD(2028, __GXData->suTs1[coord], 1, 17, t_enable); + + if (__GXData->tcsManEnab & (1 << coord)) { + GX_WRITE_RAS_REG(__GXData->suTs0[coord]); + GX_WRITE_RAS_REG(__GXData->suTs1[coord]); + __GXData->bpSentNot = 0; + } +} + +void GXSetTexCoordBias(GXTexCoordID coord, u8 s_enable, u8 t_enable) { + CHECK_GXBEGIN(2054, "GXSetTexCoordBias"); + ASSERTMSGLINEV(2056, coord < GX_MAX_TEXCOORD, "%s: bad texcoord specified", "GXSetTexCoordBias"); + SET_REG_FIELD(2058, __GXData->suTs0[coord], 1, 16, s_enable); + SET_REG_FIELD(2059, __GXData->suTs1[coord], 1, 16, t_enable); + + if (__GXData->tcsManEnab & (1 << coord)) { + GX_WRITE_RAS_REG(__GXData->suTs0[coord]); + GX_WRITE_RAS_REG(__GXData->suTs1[coord]); + __GXData->bpSentNot = 0; + } +} + +static void __SetSURegs(u32 tmap, u32 tcoord) { + u32 w; + u32 h; + u8 s_bias; + u8 t_bias; + + w = GET_REG_FIELD(__GXData->tImage0[tmap], 10, 0); + h = GET_REG_FIELD(__GXData->tImage0[tmap], 10, 10); + SET_REG_FIELD(2089, __GXData->suTs0[tcoord], 16, 0, w); + SET_REG_FIELD(2090, __GXData->suTs1[tcoord], 16, 0, h); + s_bias = GET_REG_FIELD(__GXData->tMode0[tmap], 2, 0) == 1; + t_bias = GET_REG_FIELD(__GXData->tMode0[tmap], 2, 2) == 1; + SET_REG_FIELD(2096, __GXData->suTs0[tcoord], 1, 16, s_bias); + SET_REG_FIELD(2097, __GXData->suTs1[tcoord], 1, 16, t_bias); + GX_WRITE_RAS_REG(__GXData->suTs0[tcoord]); + GX_WRITE_RAS_REG(__GXData->suTs1[tcoord]); + __GXData->bpSentNot = 0; +} + +void __GXSetSUTexRegs(void) { + u32 nStages; + u32 nIndStages; + u32 i; + u32 map; + u32 tmap; + u32 coord; + u32* ptref; + + if (__GXData->tcsManEnab != 0xFF) { + nStages = GET_REG_FIELD(__GXData->genMode, 4, 10) + 1; + nIndStages = GET_REG_FIELD(__GXData->genMode, 3, 16); + for (i = 0; i < nIndStages; i++) { switch (i) { case 0: - c = GX_GET_REG(__GXData->iref, 29, 31); - d = GX_GET_REG(__GXData->iref, 26, 28); + tmap = GET_REG_FIELD(__GXData->iref, 3, 0); + coord = GET_REG_FIELD(__GXData->iref, 3, 3); break; case 1: - c = GX_GET_REG(__GXData->iref, 23, 25); - d = GX_GET_REG(__GXData->iref, 20, 22); + tmap = GET_REG_FIELD(__GXData->iref, 3, 6); + coord = GET_REG_FIELD(__GXData->iref, 3, 9); break; case 2: - c = GX_GET_REG(__GXData->iref, 17, 19); - d = GX_GET_REG(__GXData->iref, 14, 16); + tmap = GET_REG_FIELD(__GXData->iref, 3, 12); + coord = GET_REG_FIELD(__GXData->iref, 3, 15); break; case 3: - c = GX_GET_REG(__GXData->iref, 11, 13); - d = GX_GET_REG(__GXData->iref, 8, 10); + tmap = GET_REG_FIELD(__GXData->iref, 3, 18); + coord = GET_REG_FIELD(__GXData->iref, 3, 21); break; } - - if (!(__GXData->tcsManEnab & (1 << d))) { - __SetSURegs(c, d); + if (!(__GXData->tcsManEnab & (1 << coord))) { + __SetSURegs(tmap, coord); } } - for (i = 0; i < a; i++) { - u32* g = &__GXData->tref[i / 2]; - - c = __GXData->texmapId[i] & ~0x100; - + i = 0; + for (i = 0; i < nStages; i++) { + ptref = &__GXData->tref[i / 2]; + map = __GXData->texmapId[i]; + tmap = map & 0xFFFFFEFF; if (i & 1) { - d = GX_GET_REG(*g, 14, 16); + coord = GET_REG_FIELD(*ptref, 3, 15); } else { - d = GX_GET_REG(*g, 26, 28); + coord = GET_REG_FIELD(*ptref, 3, 3); } - - if (c != 0xff && !(__GXData->tcsManEnab & (1 << d)) && __GXData->tevTcEnab & (1 << i)) { - __SetSURegs(c, d); + if ((tmap != 0xFF) && !(__GXData->tcsManEnab & (1 << coord)) && (__GXData->tevTcEnab & (1 << i))) { + __SetSURegs(tmap, coord); } } } } -#pragma dont_inline reset -/* 8035E96C-8035ECC0 3592AC 0354+00 0/0 1/1 0/0 .text __GXSetTmemConfig */ +void __GXGetSUTexSize(GXTexCoordID coord, u16* width, u16* height) { + *width = (u16)__GXData->suTs0[coord] + 1; + *height = (u16)__GXData->suTs1[coord] + 1; +} + void __GXSetTmemConfig(u32 config) { switch (config) { case 2: - GX_BP_LOAD_REG(0x8c0d8000); - GX_BP_LOAD_REG(0x900dc000); + GX_WRITE_RAS_REG(0x8c0d8000); + GX_WRITE_RAS_REG(0x900dc000); - GX_BP_LOAD_REG(0x8d0d8800); - GX_BP_LOAD_REG(0x910dc800); + GX_WRITE_RAS_REG(0x8d0d8800); + GX_WRITE_RAS_REG(0x910dc800); - GX_BP_LOAD_REG(0x8e0d9000); - GX_BP_LOAD_REG(0x920dd000); + GX_WRITE_RAS_REG(0x8e0d9000); + GX_WRITE_RAS_REG(0x920dd000); - GX_BP_LOAD_REG(0x8f0d9800); - GX_BP_LOAD_REG(0x930dd800); + GX_WRITE_RAS_REG(0x8f0d9800); + GX_WRITE_RAS_REG(0x930dd800); - GX_BP_LOAD_REG(0xac0da000); - GX_BP_LOAD_REG(0xb00dc400); + GX_WRITE_RAS_REG(0xac0da000); + GX_WRITE_RAS_REG(0xb00dc400); - GX_BP_LOAD_REG(0xad0da800); - GX_BP_LOAD_REG(0xb10dcc00); + GX_WRITE_RAS_REG(0xad0da800); + GX_WRITE_RAS_REG(0xb10dcc00); - GX_BP_LOAD_REG(0xae0db000); - GX_BP_LOAD_REG(0xb20dd400); + GX_WRITE_RAS_REG(0xae0db000); + GX_WRITE_RAS_REG(0xb20dd400); - GX_BP_LOAD_REG(0xaf0db800); - GX_BP_LOAD_REG(0xb30ddc00); + GX_WRITE_RAS_REG(0xaf0db800); + GX_WRITE_RAS_REG(0xb30ddc00); break; case 1: - GX_BP_LOAD_REG(0x8c0d8000); - GX_BP_LOAD_REG(0x900dc000); + GX_WRITE_RAS_REG(0x8c0d8000); + GX_WRITE_RAS_REG(0x900dc000); - GX_BP_LOAD_REG(0x8d0d8800); - GX_BP_LOAD_REG(0x910dc800); + GX_WRITE_RAS_REG(0x8d0d8800); + GX_WRITE_RAS_REG(0x910dc800); - GX_BP_LOAD_REG(0x8e0d9000); - GX_BP_LOAD_REG(0x920dd000); + GX_WRITE_RAS_REG(0x8e0d9000); + GX_WRITE_RAS_REG(0x920dd000); - GX_BP_LOAD_REG(0x8f0d9800); - GX_BP_LOAD_REG(0x930dd800); + GX_WRITE_RAS_REG(0x8f0d9800); + GX_WRITE_RAS_REG(0x930dd800); - GX_BP_LOAD_REG(0xac0da000); - GX_BP_LOAD_REG(0xb00de000); + GX_WRITE_RAS_REG(0xac0da000); + GX_WRITE_RAS_REG(0xb00de000); - GX_BP_LOAD_REG(0xad0da800); - GX_BP_LOAD_REG(0xb10de800); + GX_WRITE_RAS_REG(0xad0da800); + GX_WRITE_RAS_REG(0xb10de800); - GX_BP_LOAD_REG(0xae0db000); - GX_BP_LOAD_REG(0xb20df000); + GX_WRITE_RAS_REG(0xae0db000); + GX_WRITE_RAS_REG(0xb20df000); - GX_BP_LOAD_REG(0xaf0db800); - GX_BP_LOAD_REG(0xb30df800); + GX_WRITE_RAS_REG(0xaf0db800); + GX_WRITE_RAS_REG(0xb30df800); break; case 0: default: - GX_BP_LOAD_REG(0x8c0d8000); - GX_BP_LOAD_REG(0x900dc000); + GX_WRITE_RAS_REG(0x8c0d8000); + GX_WRITE_RAS_REG(0x900dc000); - GX_BP_LOAD_REG(0x8d0d8400); - GX_BP_LOAD_REG(0x910dc400); + GX_WRITE_RAS_REG(0x8d0d8400); + GX_WRITE_RAS_REG(0x910dc400); - GX_BP_LOAD_REG(0x8e0d8800); - GX_BP_LOAD_REG(0x920dc800); + GX_WRITE_RAS_REG(0x8e0d8800); + GX_WRITE_RAS_REG(0x920dc800); - GX_BP_LOAD_REG(0x8f0d8c00); - GX_BP_LOAD_REG(0x930dcc00); + GX_WRITE_RAS_REG(0x8f0d8c00); + GX_WRITE_RAS_REG(0x930dcc00); - GX_BP_LOAD_REG(0xac0d9000); - GX_BP_LOAD_REG(0xb00dd000); + GX_WRITE_RAS_REG(0xac0d9000); + GX_WRITE_RAS_REG(0xb00dd000); - GX_BP_LOAD_REG(0xad0d9400); - GX_BP_LOAD_REG(0xb10dd400); + GX_WRITE_RAS_REG(0xad0d9400); + GX_WRITE_RAS_REG(0xb10dd400); - GX_BP_LOAD_REG(0xae0d9800); - GX_BP_LOAD_REG(0xb20dd800); + GX_WRITE_RAS_REG(0xae0d9800); + GX_WRITE_RAS_REG(0xb20dd800); - GX_BP_LOAD_REG(0xaf0d9c00); - GX_BP_LOAD_REG(0xb30ddc00); + GX_WRITE_RAS_REG(0xaf0d9c00); + GX_WRITE_RAS_REG(0xb30ddc00); break; } diff --git a/src/dolphin/gx/GXTransform.c b/src/dolphin/gx/GXTransform.c index 389c92e867..e454017a62 100644 --- a/src/dolphin/gx/GXTransform.c +++ b/src/dolphin/gx/GXTransform.c @@ -1,332 +1,608 @@ -#include "dolphin/gx/GXTransform.h" -#include "dolphin/gx.h" -#include "dolphin/os.h" +#include +#include +#include -void __GXSetMatrixIndex(); +#include "__gx.h" -static void Copy6Floats(register f32 src[6], register f32 dst[6]) { - register f32 ps_0, ps_1, ps_2; +void GXProject(f32 x, f32 y, f32 z, const Mtx mtx, const f32* pm, const f32* vp, f32* sx, f32* sy, f32* sz) { + Vec peye; + f32 xc; + f32 yc; + f32 zc; + f32 wc; - // clang-format off - asm { - psq_l ps_0, 0(src), 0, 0 - psq_l ps_1, 8(src), 0, 0 - psq_l ps_2, 16(src), 0, 0 - psq_st ps_0, 0(dst), 0, 0 - psq_st ps_1, 8(dst), 0, 0 - psq_st ps_2, 16(dst), 0, 0 - } - // clang-format on -} + ASSERTMSGLINE(168, pm && vp && sx && sy && sz, "GXGet*: invalid null pointer"); -static void WriteProjPS(const register f32 src[6], register volatile void* dst) { - register f32 ps_0, ps_1, ps_2; - - // clang-format off - asm { - psq_l ps_0, 0(src), 0, 0 - psq_l ps_1, 8(src), 0, 0 - psq_l ps_2, 16(src), 0, 0 - psq_st ps_0, 0(dst), 0, 0 - psq_st ps_1, 0(dst), 0, 0 - psq_st ps_2, 0(dst), 0, 0 - } - // clang-format on -} - -/* 8035FF60-803600D4 35A8A0 0174+00 0/0 1/1 0/0 .text GXProject */ -void GXProject(f32 model_x, f32 model_y, f32 model_z, Mtx model_mtx, f32* proj_mtx, f32* viewpoint, - f32* screen_x, f32* screen_y, f32* screen_z) { - f32 sp10[3]; - f32 var_f30; - f32 var_f29; - f32 var_f28; - f32 var_f31; - - ASSERTMSG(proj_mtx != NULL && viewpoint != NULL && screen_x != NULL && screen_y != NULL && screen_z != NULL, "GXGet*: invalid null pointer"); - - sp10[0] = (model_mtx[0][0] * model_x) + (model_mtx[0][1] * model_y) + - (model_mtx[0][2] * model_z) + model_mtx[0][3]; - sp10[1] = (model_mtx[1][0] * model_x) + (model_mtx[1][1] * model_y) + - (model_mtx[1][2] * model_z) + model_mtx[1][3]; - sp10[2] = (model_mtx[2][0] * model_x) + (model_mtx[2][1] * model_y) + - (model_mtx[2][2] * model_z) + model_mtx[2][3]; - - if (proj_mtx[0] == 0.0f) { - var_f30 = (sp10[0] * proj_mtx[1]) + (sp10[2] * proj_mtx[2]); - var_f29 = (sp10[1] * proj_mtx[3]) + (sp10[2] * proj_mtx[4]); - var_f28 = proj_mtx[6] + (sp10[2] * proj_mtx[5]); - var_f31 = 1.0f / -sp10[2]; + peye.x = mtx[0][3] + ((mtx[0][2] * z) + ((mtx[0][0] * x) + (mtx[0][1] * y))); + peye.y = mtx[1][3] + ((mtx[1][2] * z) + ((mtx[1][0] * x) + (mtx[1][1] * y))); + peye.z = mtx[2][3] + ((mtx[2][2] * z) + ((mtx[2][0] * x) + (mtx[2][1] * y))); + if (pm[0] == 0.0f) { + xc = (peye.x * pm[1]) + (peye.z * pm[2]); + yc = (peye.y * pm[3]) + (peye.z * pm[4]); + zc = pm[6] + (peye.z * pm[5]); + wc = 1.0f / -peye.z; } else { - var_f30 = proj_mtx[2] + (sp10[0] * proj_mtx[1]); - var_f29 = proj_mtx[4] + (sp10[1] * proj_mtx[3]); - var_f28 = proj_mtx[6] + (sp10[2] * proj_mtx[5]); - var_f31 = 1.0f; + xc = pm[2] + (peye.x * pm[1]); + yc = pm[4] + (peye.y * pm[3]); + zc = pm[6] + (peye.z * pm[5]); + wc = 1.0f; } + *sx = (vp[2] / 2.0f) + (vp[0] + (wc * (xc * vp[2] / 2.0f))); + *sy = (vp[3] / 2.0f) + (vp[1] + (wc * (-yc * vp[3] / 2.0f))); + *sz = vp[5] + (wc * (zc * (vp[5] - vp[4]))); +} - *screen_x = (viewpoint[2] / 2) + (viewpoint[0] + (var_f31 * (var_f30 * viewpoint[2] / 2))); - *screen_y = (viewpoint[3] / 2) + (viewpoint[1] + (var_f31 * (-var_f29 * viewpoint[3] / 2))); - *screen_z = viewpoint[5] + (var_f31 * (var_f28 * (viewpoint[5] - viewpoint[4]))); +static void WriteProjPS(const register f32 proj[6], register volatile void* dest) { + register f32 p01, p23, p45; + + asm { + psq_l p01, 0(proj), 0, 0 + psq_l p23, 8(proj), 0, 0 + psq_l p45, 16(proj), 0, 0 + psq_st p01, 0(dest), 0, 0 + psq_st p23, 0(dest), 0, 0 + psq_st p45, 0(dest), 0, 0 + } +} + +static void Copy6Floats(const register f32 src[6], register volatile f32* dest) { + register f32 ps01, ps23, ps45; + + asm { + psq_l ps01, 0(src), 0, 0 + psq_l ps23, 8(src), 0, 0 + psq_l ps45, 16(src), 0, 0 + psq_st ps01, 0(dest), 0, 0 + psq_st ps23, 8(dest), 0, 0 + psq_st ps45, 16(dest), 0, 0 + } } void __GXSetProjection(void) { - GX_XF_LOAD_REGS(6, GX_XF_REG_PROJECTIONA); + u32 reg = 0x00061020; + GX_WRITE_U8(0x10); + GX_WRITE_U32(reg); +#if DEBUG + GX_WRITE_XF_REG_F(32, __GXData->projMtx[0]); + GX_WRITE_XF_REG_F(33, __GXData->projMtx[1]); + GX_WRITE_XF_REG_F(34, __GXData->projMtx[2]); + GX_WRITE_XF_REG_F(35, __GXData->projMtx[3]); + GX_WRITE_XF_REG_F(36, __GXData->projMtx[4]); + GX_WRITE_XF_REG_F(37, __GXData->projMtx[5]); + GX_WRITE_XF_REG_2(38, __GXData->projType); +#else WriteProjPS(__GXData->projMtx, (volatile void*)GXFIFO_ADDR); GX_WRITE_U32(__GXData->projType); +#endif } -/* 803600D4-80360178 35AA14 00A4+00 0/0 15/15 2/2 .text GXSetProjection */ -void GXSetProjection(const Mtx44 proj, GXProjectionType type) { - volatile void* fifo; +void GXSetProjection(const Mtx44 mtx, GXProjectionType type) { + CHECK_GXBEGIN(295, "GXSetProjection"); + __GXData->projType = type; - - __GXData->projMtx[0] = proj[0][0]; - __GXData->projMtx[2] = proj[1][1]; - __GXData->projMtx[4] = proj[2][2]; - __GXData->projMtx[5] = proj[2][3]; - + __GXData->projMtx[0] = mtx[0][0]; + __GXData->projMtx[2] = mtx[1][1]; + __GXData->projMtx[4] = mtx[2][2]; + __GXData->projMtx[5] = mtx[2][3]; if (type == GX_ORTHOGRAPHIC) { - __GXData->projMtx[1] = proj[0][3]; - __GXData->projMtx[3] = proj[1][3]; + __GXData->projMtx[1] = mtx[0][3]; + __GXData->projMtx[3] = mtx[1][3]; } else { - __GXData->projMtx[1] = proj[0][2]; - __GXData->projMtx[3] = proj[1][2]; + __GXData->projMtx[1] = mtx[0][2]; + __GXData->projMtx[3] = mtx[1][2]; } __GXSetProjection(); - - __GXData->bpSentNot = GX_TRUE; + __GXData->bpSentNot = 1; } -/* 80360178-80360204 35AAB8 008C+00 0/0 1/1 1/1 .text GXSetProjectionv */ -void GXSetProjectionv(f32* proj) { - __GXData->projType = proj[0] == 0.0f ? GX_PERSPECTIVE : GX_ORTHOGRAPHIC; - Copy6Floats(&proj[1], __GXData->projMtx); +void GXSetProjectionv(const f32* ptr) { + CHECK_GXBEGIN(339, "GXSetProjectionv"); + + __GXData->projType = ptr[0] == 0.0f ? GX_PERSPECTIVE : GX_ORTHOGRAPHIC; + +#if DEBUG + __GXData->projMtx[0] = ptr[1]; + __GXData->projMtx[1] = ptr[2]; + __GXData->projMtx[2] = ptr[3]; + __GXData->projMtx[3] = ptr[4]; + __GXData->projMtx[4] = ptr[5]; + __GXData->projMtx[5] = ptr[6]; +#else + Copy6Floats(&ptr[1], __GXData->projMtx); +#endif __GXSetProjection(); - __GXData->bpSentNot = GX_TRUE; + __GXData->bpSentNot = 1; } -/* 80360204-8036024C 35AB44 0048+00 0/0 1/1 1/1 .text GXGetProjectionv */ -void GXGetProjectionv(f32* proj) { - *proj = (u32)__GXData->projType != GX_PERSPECTIVE ? 1.0f : 0.0f; - Copy6Floats(__GXData->projMtx, &proj[1]); +#define qr0 0 + +void GXGetProjectionv(f32* ptr) { + ASSERTMSGLINE(370, ptr, "GXGet*: invalid null pointer"); + + ptr[0] = (u32)__GXData->projType != GX_PERSPECTIVE ? 1.0f : 0.0f; + +#if DEBUG + ptr[1] = __GXData->projMtx[0]; + ptr[2] = __GXData->projMtx[1]; + ptr[3] = __GXData->projMtx[2]; + ptr[4] = __GXData->projMtx[3]; + ptr[5] = __GXData->projMtx[4]; + ptr[6] = __GXData->projMtx[5]; +#else + Copy6Floats(__GXData->projMtx, &ptr[1]); +#endif } -static void WriteMTXPS4x3(register volatile void* dst, register const Mtx src) { - register f32 ps_0, ps_1, ps_2, ps_3, ps_4, ps_5; +static void WriteMTXPS4x3(const register f32 mtx[3][4], register volatile f32* dest) { + register f32 a00_a01; + register f32 a02_a03; + register f32 a10_a11; + register f32 a12_a13; + register f32 a20_a21; + register f32 a22_a23; - // clang-format off asm { - psq_l ps_0, 0(src), 0, 0 - psq_l ps_1, 8(src), 0, 0 - psq_l ps_2, 16(src), 0, 0 - psq_l ps_3, 24(src), 0, 0 - psq_l ps_4, 32(src), 0, 0 - psq_l ps_5, 40(src), 0, 0 - - psq_st ps_0, 0(dst), 0, 0 - psq_st ps_1, 0(dst), 0, 0 - psq_st ps_2, 0(dst), 0, 0 - psq_st ps_3, 0(dst), 0, 0 - psq_st ps_4, 0(dst), 0, 0 - psq_st ps_5, 0(dst), 0, 0 + psq_l a00_a01, 0x00(mtx), 0, qr0 + psq_l a02_a03, 0x08(mtx), 0, qr0 + psq_l a10_a11, 0x10(mtx), 0, qr0 + psq_l a12_a13, 0x18(mtx), 0, qr0 + psq_l a20_a21, 0x20(mtx), 0, qr0 + psq_l a22_a23, 0x28(mtx), 0, qr0 + psq_st a00_a01, 0(dest), 0, qr0 + psq_st a02_a03, 0(dest), 0, qr0 + psq_st a10_a11, 0(dest), 0, qr0 + psq_st a12_a13, 0(dest), 0, qr0 + psq_st a20_a21, 0(dest), 0, qr0 + psq_st a22_a23, 0(dest), 0, qr0 } - // clang-format on } -/* 8036024C-8036029C 35AB8C 0050+00 0/0 83/83 9/9 .text GXLoadPosMtxImm */ -void GXLoadPosMtxImm(Mtx mtx, u32 id) { - GX_XF_LOAD_REGS(4 * 3 - 1, id * 4 + GX_XF_MEM_POSMTX); - WriteMTXPS4x3(&GXWGFifo, mtx); -} +static void WriteMTXPS3x3from3x4(register f32 mtx[3][4], register volatile f32* dest) { + register f32 a00_a01; + register f32 a02_a03; + register f32 a10_a11; + register f32 a12_a13; + register f32 a20_a21; + register f32 a22_a23; -static void WriteMTXPS3x3(register volatile void* dst, register const Mtx src) { - register f32 ps_0, ps_1, ps_2, ps_3, ps_4, ps_5; - - // clang-format off asm { - psq_l ps_0, 0(src), 0, 0 - lfs ps_1, 8(src) - psq_l ps_2, 16(src), 0, 0 - lfs ps_3, 24(src) - psq_l ps_4, 32(src), 0, 0 - lfs ps_5, 40(src) - - psq_st ps_0, 0(dst), 0, 0 - stfs ps_1, 0(dst) - psq_st ps_2, 0(dst), 0, 0 - stfs ps_3, 0(dst) - psq_st ps_4, 0(dst), 0, 0 - stfs ps_5, 0(dst) + psq_l a00_a01, 0x00(mtx), 0, qr0 + lfs a02_a03, 0x08(mtx) + psq_l a10_a11, 0x10(mtx), 0, qr0 + lfs a12_a13, 0x18(mtx) + psq_l a20_a21, 0x20(mtx), 0, qr0 + lfs a22_a23, 0x28(mtx) + psq_st a00_a01, 0(dest), 0, qr0 + stfs a02_a03, 0(dest) + psq_st a10_a11, 0(dest), 0, qr0 + stfs a12_a13, 0(dest) + psq_st a20_a21, 0(dest), 0, qr0 + stfs a22_a23, 0(dest) } - // clang-format on } -/* 8036029C-803602EC 35ABDC 0050+00 0/0 11/11 7/7 .text GXLoadNrmMtxImm */ -void GXLoadNrmMtxImm(Mtx mtx, u32 id) { - GX_XF_LOAD_REGS(3 * 3 - 1, id * 3 + GX_XF_MEM_NRMMTX); - WriteMTXPS3x3(&GXWGFifo, mtx); +static void WriteMTXPS3x3(register f32 mtx[3][3], register volatile f32* dest) { + register f32 a00_a01; + register f32 a02_a10; + register f32 a11_a12; + register f32 a20_a21; + register f32 a22_nnn; + + asm { + psq_l a00_a01, 0x00(mtx), 0, qr0 + psq_l a02_a10, 0x08(mtx), 0, qr0 + psq_l a11_a12, 0x10(mtx), 0, qr0 + psq_l a20_a21, 0x18(mtx), 0, qr0 + lfs a22_nnn, 0x20(mtx) + psq_st a00_a01, 0(dest), 0, qr0 + psq_st a02_a10, 0(dest), 0, qr0 + psq_st a11_a12, 0(dest), 0, qr0 + psq_st a20_a21, 0(dest), 0, qr0 + stfs a22_nnn, 0(dest) + } +} + +static void WriteMTXPS4x2(const register f32 mtx[2][4], register volatile f32* dest) { + register f32 a00_a01; + register f32 a02_a03; + register f32 a10_a11; + register f32 a12_a13; + + asm { + psq_l a00_a01, 0x00(mtx), 0, qr0 + psq_l a02_a03, 0x08(mtx), 0, qr0 + psq_l a10_a11, 0x10(mtx), 0, qr0 + psq_l a12_a13, 0x18(mtx), 0, qr0 + psq_st a00_a01, 0(dest), 0, qr0 + psq_st a02_a03, 0(dest), 0, qr0 + psq_st a10_a11, 0(dest), 0, qr0 + psq_st a12_a13, 0(dest), 0, qr0 + } +} + +#define GX_WRITE_MTX_ELEM(addr, value) \ +do { \ + f32 xfData = (value); \ + GX_WRITE_F32(value); \ + VERIF_MTXLIGHT((addr), *(u32 *)&xfData); \ +} while (0) + +void GXLoadPosMtxImm(const Mtx mtx, u32 id) { + u32 reg; + u32 addr; + + CHECK_GXBEGIN(507, "GXLoadPosMtxImm"); + + addr = id * 4; + reg = addr | 0xB0000; + + GX_WRITE_U8(0x10); + GX_WRITE_U32(reg); +#if DEBUG + GX_WRITE_MTX_ELEM(addr + 0, mtx[0][0]); + GX_WRITE_MTX_ELEM(addr + 1, mtx[0][1]); + GX_WRITE_MTX_ELEM(addr + 2, mtx[0][2]); + GX_WRITE_MTX_ELEM(addr + 3, mtx[0][3]); + GX_WRITE_MTX_ELEM(addr + 4, mtx[1][0]); + GX_WRITE_MTX_ELEM(addr + 5, mtx[1][1]); + GX_WRITE_MTX_ELEM(addr + 6, mtx[1][2]); + GX_WRITE_MTX_ELEM(addr + 7, mtx[1][3]); + GX_WRITE_MTX_ELEM(addr + 8, mtx[2][0]); + GX_WRITE_MTX_ELEM(addr + 9, mtx[2][1]); + GX_WRITE_MTX_ELEM(addr + 10, mtx[2][2]); + GX_WRITE_MTX_ELEM(addr + 11, mtx[2][3]); +#else + WriteMTXPS4x3(mtx, &GXWGFifo.f32); +#endif +} + +void GXLoadPosMtxIndx(u16 mtx_indx, u32 id) { + u32 offset; + u32 reg; + + CHECK_GXBEGIN(555, "GXLoadPosMtxIndx"); + offset = id * 4; + reg = 0; + SET_REG_FIELD(561, reg, 12, 0, offset); + SET_REG_FIELD(563, reg, 4, 12, 11); + SET_REG_FIELD(563, reg, 16, 16, mtx_indx); + GX_WRITE_U8(0x20); + GX_WRITE_U32(reg); +#if DEBUG + __GXShadowIndexState(4, reg); +#endif +} + +void GXLoadNrmMtxImm(const Mtx mtx, u32 id) { + u32 reg; + u32 addr; + + CHECK_GXBEGIN(588, "GXLoadNrmMtxImm"); + + addr = id * 3 + 0x400; + reg = addr | 0x80000; + + GX_WRITE_U8(0x10); + GX_WRITE_U32(reg); +#if DEBUG + GX_WRITE_MTX_ELEM(addr + 0, mtx[0][0]); + GX_WRITE_MTX_ELEM(addr + 1, mtx[0][1]); + GX_WRITE_MTX_ELEM(addr + 2, mtx[0][2]); + GX_WRITE_MTX_ELEM(addr + 3, mtx[1][0]); + GX_WRITE_MTX_ELEM(addr + 4, mtx[1][1]); + GX_WRITE_MTX_ELEM(addr + 5, mtx[1][2]); + GX_WRITE_MTX_ELEM(addr + 6, mtx[2][0]); + GX_WRITE_MTX_ELEM(addr + 7, mtx[2][1]); + GX_WRITE_MTX_ELEM(addr + 8, mtx[2][2]); +#else + WriteMTXPS3x3from3x4((void*)mtx, &GXWGFifo.f32); +#endif +} + +void GXLoadNrmMtxImm3x3(const f32 mtx[3][3], u32 id) { + u32 reg; + u32 addr; + + CHECK_GXBEGIN(633, "GXLoadNrmMtxImm3x3"); + + addr = id * 3 + 0x400; + reg = addr | 0x80000; + + GX_WRITE_U8(0x10); + GX_WRITE_U32(reg); +#if DEBUG + GX_WRITE_MTX_ELEM(addr + 0, mtx[0][0]); + GX_WRITE_MTX_ELEM(addr + 1, mtx[0][1]); + GX_WRITE_MTX_ELEM(addr + 2, mtx[0][2]); + GX_WRITE_MTX_ELEM(addr + 3, mtx[1][0]); + GX_WRITE_MTX_ELEM(addr + 4, mtx[1][1]); + GX_WRITE_MTX_ELEM(addr + 5, mtx[1][2]); + GX_WRITE_MTX_ELEM(addr + 6, mtx[2][0]); + GX_WRITE_MTX_ELEM(addr + 7, mtx[2][1]); + GX_WRITE_MTX_ELEM(addr + 8, mtx[2][2]); +#else + WriteMTXPS3x3((void*)mtx, &GXWGFifo.f32); +#endif +} + +void GXLoadNrmMtxIndx3x3(u16 mtx_indx, u32 id) { + u32 offset; + u32 reg; + + CHECK_GXBEGIN(679, "GXLoadNrmMtxIndx3x3"); + offset = id * 3 + 0x400; + reg = 0; + SET_REG_FIELD(685, reg, 12, 0, offset); + SET_REG_FIELD(687, reg, 4, 12, 8); + SET_REG_FIELD(687, reg, 16, 16, mtx_indx); + GX_WRITE_U8(0x28); + GX_WRITE_U32(reg); +#if DEBUG + __GXShadowIndexState(5, reg); +#endif } -/* 803602EC-80360320 35AC2C 0034+00 0/0 51/51 2/2 .text GXSetCurrentMtx */ void GXSetCurrentMtx(u32 id) { - GX_SET_REG(__GXData->matIdxA, id, GX_XF_MTXIDX0_GEOM_ST, GX_XF_MTXIDX0_GEOM_END); + CHECK_GXBEGIN(708, "GXSetCurrentMtx"); + SET_REG_FIELD(712, __GXData->matIdxA, 6, 0, id); __GXSetMatrixIndex(GX_VA_PNMTXIDX); } -static void WriteMTXPS4x2(register volatile void* dst, register const Mtx src) { - register f32 ps_0, ps_1, ps_2, ps_3; +void GXLoadTexMtxImm(const f32 mtx[][4], u32 id, GXTexMtxType type) { + u32 reg; + u32 addr; + u32 count; - // clang-format off - asm { - psq_l ps_0, 0(src), 0, 0 - psq_l ps_1, 8(src), 0, 0 - psq_l ps_2, 16(src), 0, 0 - psq_l ps_3, 24(src), 0, 0 + CHECK_GXBEGIN(741, "GXLoadTexMtxImm"); - psq_st ps_0, 0(dst), 0, 0 - psq_st ps_1, 0(dst), 0, 0 - psq_st ps_2, 0(dst), 0, 0 - psq_st ps_3, 0(dst), 0, 0 + if (id >= GX_PTTEXMTX0) { + addr = (id - GX_PTTEXMTX0) * 4 + 0x500; + ASSERTMSGLINE(751, type == GX_MTX3x4, "GXLoadTexMtx: Invalid matrix type"); + } else { + addr = id * 4; } - // clang-format on + count = (type == GX_MTX2x4) ? 8 : 12; + reg = addr | ((count - 1) << 16); + + GX_WRITE_U8(0x10); + GX_WRITE_U32(reg); +#if DEBUG + GX_WRITE_MTX_ELEM(addr + 0, mtx[0][0]); + GX_WRITE_MTX_ELEM(addr + 1, mtx[0][1]); + GX_WRITE_MTX_ELEM(addr + 2, mtx[0][2]); + GX_WRITE_MTX_ELEM(addr + 3, mtx[0][3]); + GX_WRITE_MTX_ELEM(addr + 4, mtx[1][0]); + GX_WRITE_MTX_ELEM(addr + 5, mtx[1][1]); + GX_WRITE_MTX_ELEM(addr + 6, mtx[1][2]); + GX_WRITE_MTX_ELEM(addr + 7, mtx[1][3]); + if (type == GX_MTX3x4) { + GX_WRITE_MTX_ELEM(addr + 8, mtx[2][0]); + GX_WRITE_MTX_ELEM(addr + 9, mtx[2][1]); + GX_WRITE_MTX_ELEM(addr + 10, mtx[2][2]); + GX_WRITE_MTX_ELEM(addr + 11, mtx[2][3]); + } +#else + if (type == GX_MTX3x4) { + WriteMTXPS4x3(mtx, &GXWGFifo.f32); + } else { + WriteMTXPS4x2(mtx, &GXWGFifo.f32); + } +#endif } -/* 80360320-803603D4 35AC60 00B4+00 0/0 15/15 0/0 .text GXLoadTexMtxImm */ -void GXLoadTexMtxImm(const Mtx mtx, u32 id, GXTexMtxType type) { - u32 addr; - u32 num; +void GXLoadTexMtxIndx(u16 mtx_indx, u32 id, GXTexMtxType type) { + u32 offset; + u32 reg; + u32 count; + + CHECK_GXBEGIN(813, "GXLoadTexMtxIndx"); + + if (id >= GX_PTTEXMTX0) { + offset = (id - GX_PTTEXMTX0) * 4 + 0x500; + ASSERTMSGLINE(0x337, type == GX_MTX3x4, "GXLoadTexMtx: Invalid matrix type"); + } else { + offset = id * 4; + } + count = (type == GX_MTX2x4) ? 8 : 12; + + reg = 0; + SET_REG_FIELD(830, reg, 12, 0, offset); + SET_REG_FIELD(831, reg, 4, 12, (count - 1)); + SET_REG_FIELD(832, reg, 16, 16, mtx_indx); + GX_WRITE_U8(0x30); + GX_WRITE_U32(reg); +#if DEBUG + __GXShadowIndexState(6, reg); +#endif +} + +void __GXSetViewport(void) { + f32 sx; + f32 sy; + f32 sz; + f32 ox; + f32 oy; + f32 oz; + f32 zmin; + f32 zmax; u32 reg; - // Matrix address in XF memory - addr = id >= GX_PTTEXMTX0 ? (id - GX_PTTEXMTX0) * 4 + GX_XF_MEM_DUALTEXMTX : - id * 4 + (u64)GX_XF_MEM_POSMTX; + sx = __GXData->vpWd / 2.0f; + sy = -__GXData->vpHt / 2.0f; + ox = 342.0f + (__GXData->vpLeft + (__GXData->vpWd / 2.0f)); + oy = 342.0f + (__GXData->vpTop + (__GXData->vpHt / 2.0f)); - // Number of elements in matrix - num = type == GX_MTX2x4 ? (u64)(2 * 4) : 3 * 4; + zmin = __GXData->vpNearz * __GXData->zScale; + zmax = __GXData->vpFarz * __GXData->zScale; - reg = addr | (num - 1) << 16; + sz = zmax - zmin; + oz = zmax + __GXData->zOffset; - GX_XF_LOAD_REG_HDR(reg); + reg = 0x5101A; + GX_WRITE_U8(0x10); + GX_WRITE_U32(reg); + GX_WRITE_XF_REG_F(26, sx); + GX_WRITE_XF_REG_F(27, sy); + GX_WRITE_XF_REG_F(28, sz); + GX_WRITE_XF_REG_F(29, ox); + GX_WRITE_XF_REG_F(30, oy); + GX_WRITE_XF_REG_F(31, oz); +} - if (type == GX_MTX3x4) { - WriteMTXPS4x3(&GXWGFifo, mtx); - } else { - WriteMTXPS4x2(&GXWGFifo, mtx); +void GXSetViewportJitter(f32 left, f32 top, f32 wd, f32 ht, f32 nearz, f32 farz, u32 field) { + CHECK_GXBEGIN(903, "GXSetViewport"); // not the correct function name + + if (field == 0) { + top -= 0.5f; } -} -/* 803603D4-80360464 35AD14 0090+00 1/1 0/0 0/0 .text __GXSetViewport */ -void __GXSetViewport(void) { - f32 a, b, c, d, e, f; - f32 near, far; - - a = __GXData->vpWd / 2; - b = -__GXData->vpHt / 2; - d = __GXData->vpLeft + (__GXData->vpWd / 2) + 342.0f; - e = __GXData->vpTop + (__GXData->vpHt / 2) + 342.0f; - - near = __GXData->vpNearz * __GXData->zScale; - far = __GXData->vpFarz * __GXData->zScale; - - c = far - near; - f = far + __GXData->zOffset; - - GX_XF_LOAD_REGS(5, GX_XF_REG_SCALEX); - GX_WRITE_F32(a); - GX_WRITE_F32(b); - GX_WRITE_F32(c); - GX_WRITE_F32(d); - GX_WRITE_F32(e); - GX_WRITE_F32(f); -} - -/* 80360464-803604AC 35ADA4 0048+00 0/0 10/10 1/1 .text GXSetViewport */ -void GXSetViewport(f32 left, f32 top, f32 width, f32 height, f32 nearZ, f32 farZ) { __GXData->vpLeft = left; __GXData->vpTop = top; - __GXData->vpWd = width; - __GXData->vpHt = height; - __GXData->vpNearz = nearZ; - __GXData->vpFarz = farZ; + __GXData->vpWd = wd; + __GXData->vpHt = ht; + __GXData->vpNearz = nearz; + __GXData->vpFarz = farz; + __GXSetViewport(); - __GXData->bpSentNot = GX_TRUE; + __GXData->bpSentNot = 1; } -/* 803604AC-803604D0 35ADEC 0024+00 0/0 1/1 1/1 .text GXGetViewportv */ -void GXGetViewportv(f32* p) { - Copy6Floats(&__GXData->vpLeft, p); +void GXSetViewport(f32 left, f32 top, f32 wd, f32 ht, f32 nearz, f32 farz) { + GXSetViewportJitter(left, top, wd, ht, nearz, farz, 1); } -/* 803604D0-80360548 35AE10 0078+00 0/0 11/11 4/4 .text GXSetScissor */ -void GXSetScissor(u32 left, u32 top, u32 width, u32 height) { - u32 y1, x1, y2, x2; - u32 reg; +void GXGetViewportv(f32* vp) { + ASSERTMSGLINE(968, vp, "GXGet*: invalid null pointer"); - y1 = top + 342; - x1 = left + 342; - - GX_SET_REG(__GXData->suScis0, y1, GX_BP_SCISSORTL_TOP_ST, GX_BP_SCISSORTL_TOP_END); - GX_SET_REG(__GXData->suScis0, x1, GX_BP_SCISSORTL_LEFT_ST, GX_BP_SCISSORTL_LEFT_END); - - y2 = y1 + height - 1; - x2 = (x1 + width) - 1; - - GX_SET_REG(__GXData->suScis1, y2, GX_BP_SCISSORBR_BOT_ST, GX_BP_SCISSORBR_BOT_END); - GX_SET_REG(__GXData->suScis1, x2, GX_BP_SCISSORBR_RIGHT_ST, GX_BP_SCISSORBR_RIGHT_END); - - GX_BP_LOAD_REG(__GXData->suScis0); - GX_BP_LOAD_REG(__GXData->suScis1); - __GXData->bpSentNot = FALSE; +#if DEBUG + vp[0] = __GXData->vpLeft; + vp[1] = __GXData->vpTop; + vp[2] = __GXData->vpWd; + vp[3] = __GXData->vpHt; + vp[4] = __GXData->vpNearz; + vp[5] = __GXData->vpFarz; +#else + Copy6Floats(&__GXData->vpLeft, vp); +#endif } -/* 80360548-80360590 35AE88 0048+00 0/0 6/6 2/2 .text GXGetScissor */ -void GXGetScissor(u32* left, u32* top, u32* width, u32* height) { - u32 y1 = (__GXData->suScis0 & 0x0007FF) >> 0; - u32 x1 = (__GXData->suScis0 & 0x7FF000) >> 12; - u32 y2 = (__GXData->suScis1 & 0x0007FF) >> 0; - u32 x2 = (__GXData->suScis1 & 0x7FF000) >> 12; +#define GX_WRITE_XF_REG_F_(addr, value) \ +do { \ + GX_WRITE_U8(0x10); \ + GX_WRITE_U32(0x1000 + (addr)); \ + { \ + f32 xfData = (value); \ + GX_WRITE_F32(value); \ + VERIF_XF_REG_alt(addr, *(u32 *)&xfData); \ + } \ +} while (0) - *left = x1 - 0x156; - *top = y1 - 0x156; - *width = (x2 - x1) + 1; - *height = (y2 - y1) + 1; +void GXSetZScaleOffset(f32 scale, f32 offset) { + f32 sz; + f32 oz; + f32 zmin; + f32 zmax; + + CHECK_GXBEGIN(996, "GXSetZScaleOffset"); + + oz = offset * 1.6777215e7f; + __GXData->zOffset = oz; + + sz = (scale * 1.6777215e7f) + 1.0f; + __GXData->zScale = sz; + + zmin = __GXData->vpNearz * sz; + zmax = __GXData->vpFarz * sz; + sz = zmax - zmin; + oz = oz + zmax; + + GX_WRITE_XF_REG_F_(0x1C, sz); + GX_WRITE_XF_REG_F_(0x1F, oz); + + __GXData->bpSentNot = 1; } -/* 80360590-803605D0 35AED0 0040+00 0/0 1/1 0/0 .text GXSetScissorBoxOffset */ -void GXSetScissorBoxOffset(s32 x, s32 y) { - u32 cmd = 0; - u32 x1; - u32 y1; +void GXSetScissor(u32 left, u32 top, u32 wd, u32 ht) { + u32 tp; + u32 lf; + u32 bm; + u32 rt; - x1 = (u32)(x + 342) / 2; - y1 = (u32)(y + 342) / 2; - GX_SET_REG(cmd, x1, GX_BP_SCISSOROFS_OX_ST, GX_BP_SCISSOROFS_OX_END); - GX_SET_REG(cmd, y1, GX_BP_SCISSOROFS_OY_ST, GX_BP_SCISSOROFS_OY_END); + CHECK_GXBEGIN(1048, "GXSetScissor"); + ASSERTMSGLINE(1049, left < 1706, "GXSetScissor: Left origin > 1708"); + ASSERTMSGLINE(1050, top < 1706, "GXSetScissor: top origin > 1708"); + ASSERTMSGLINE(1051, left + wd < 1706, "GXSetScissor: right edge > 1708"); + ASSERTMSGLINE(1052, top + ht < 1706, "GXSetScissor: bottom edge > 1708"); - GX_SET_REG(cmd, GX_BP_REG_SCISSOROFFSET, 0, 7); + tp = top + 342; + lf = left + 342; + bm = tp + ht - 1; + rt = lf + wd - 1; - GX_BP_LOAD_REG(cmd); - __GXData->bpSentNot = GX_FALSE; + SET_REG_FIELD(1059, __GXData->suScis0, 11, 0, tp); + SET_REG_FIELD(1060, __GXData->suScis0, 11, 12, lf); + SET_REG_FIELD(1062, __GXData->suScis1, 11, 0, bm); + SET_REG_FIELD(1063, __GXData->suScis1, 11, 12, rt); + + GX_WRITE_RAS_REG(__GXData->suScis0); + GX_WRITE_RAS_REG(__GXData->suScis1); + __GXData->bpSentNot = 0; +} + +void GXGetScissor(u32* left, u32* top, u32* wd, u32* ht) { + u32 tp; + u32 lf; + u32 bm; + u32 rt; + + ASSERTMSGLINE(1089, left && top && wd && ht, "GXGet*: invalid null pointer"); + + tp = __GXData->suScis0 & 0x7FF; + lf = (__GXData->suScis0 & 0x7FF000) >> 12; + bm = __GXData->suScis1 & 0x7FF; + rt = (__GXData->suScis1 & 0x7FF000) >> 12; + + *left = lf - 342; + *top = tp - 342; + *wd = rt - lf + 1; + *ht = bm - tp + 1; +} + +void GXSetScissorBoxOffset(s32 x_off, s32 y_off) { + u32 reg = 0; + u32 hx; + u32 hy; + + CHECK_GXBEGIN(1119, "GXSetScissorBoxOffset"); + + ASSERTMSGLINE(1122, (u32)(x_off + 342) < 2048, "GXSetScissorBoxOffset: Invalid X offset"); + ASSERTMSGLINE(1124, (u32)(y_off + 342) < 2048, "GXSetScissorBoxOffset: Invalid Y offset"); + + hx = (u32)(x_off + 342) >> 1; + hy = (u32)(y_off + 342) >> 1; + + SET_REG_FIELD(1129, reg, 10, 0, hx); + SET_REG_FIELD(1130, reg, 10, 10, hy); + SET_REG_FIELD(1131, reg, 8, 24, 0x59); + GX_WRITE_RAS_REG(reg); + __GXData->bpSentNot = 0; } -/* 803605D0-803605F8 35AF10 0028+00 0/0 27/27 2/2 .text GXSetClipMode */ void GXSetClipMode(GXClipMode mode) { - GX_XF_LOAD_REG(GX_XF_REG_CLIPDISABLE, mode); - __GXData->bpSentNot = GX_TRUE; + CHECK_GXBEGIN(1151, "GXSetClipMode"); + GX_WRITE_XF_REG(5, mode); + __GXData->bpSentNot = 1; } -/* 803605F8-8036067C 35AF38 0084+00 1/1 1/1 0/0 .text __GXSetMatrixIndex */ -void __GXSetMatrixIndex(GXAttr index) { - // Tex4 and after is stored in XF MatrixIndex1 - if (index < GX_VA_TEX4MTXIDX) { - GX_CP_LOAD_REG(GX_CP_REG_MTXIDXA, __GXData->matIdxA); - GX_XF_LOAD_REG(GX_XF_REG_MATRIXINDEX0, __GXData->matIdxA); +void __GXSetMatrixIndex(GXAttr matIdxAttr) { + if (matIdxAttr < GX_VA_TEX4MTXIDX) { + GX_WRITE_SOME_REG4(8, 0x30, __GXData->matIdxA, -12); + GX_WRITE_XF_REG(24, __GXData->matIdxA); } else { - GX_CP_LOAD_REG(GX_CP_REG_MTXIDXB, __GXData->matIdxB); - GX_XF_LOAD_REG(GX_XF_REG_MATRIXINDEX1, __GXData->matIdxB); + GX_WRITE_SOME_REG4(8, 0x40, __GXData->matIdxB, -12); + GX_WRITE_XF_REG(25, __GXData->matIdxB); } - - __GXData->bpSentNot = GX_TRUE; -} \ No newline at end of file + __GXData->bpSentNot = 1; +} diff --git a/src/dolphin/gx/GXVerifRAS.c b/src/dolphin/gx/GXVerifRAS.c new file mode 100644 index 0000000000..f1aa96678b --- /dev/null +++ b/src/dolphin/gx/GXVerifRAS.c @@ -0,0 +1,640 @@ +#if DEBUG + +#include + +#include + +#include "__gx.h" + +static char __data_0[] = "RGB multisample"; +static char _305[] = "GX_TEVPREV(color)"; +static char _306[] = "GX_TEVPREV(alpha)"; +static char _307[] = "GX_TEVREG0(color)"; +static char _308[] = "GX_TEVREG0(alpha)"; +static char _309[] = "GX_TEVREG1(color)"; +static char _310[] = "GX_TEVREG1(alpha)"; +static char _311[] = "GX_TEVREG2(color)"; +static char _312[] = "GX_TEVREG2(alpha)"; + +static char* TevRegNames[8] = {0}; + +#define SOME_GET_REG_MACRO(reg, size, shift) ((u32)((reg) << (shift)) & ((1 << (size)) - 2)) +#define SOME_GET_REG_MACRO2(reg, size, shift) ((u32)((reg) >> (shift)) & ((1 << (size)) - 2)) + +void __GXVerifySU(void) { + s32 scis_l; + s32 scis_r; + s32 scis_t; + s32 scis_b; + + scis_l = (u32)GET_REG_FIELD(__gxVerif->rasRegs[32], 11, 12); + scis_t = (u32)GET_REG_FIELD(__gxVerif->rasRegs[32], 11, 0); + scis_r = (u32)GET_REG_FIELD(__gxVerif->rasRegs[33], 11, 12); + scis_b = (u32)GET_REG_FIELD(__gxVerif->rasRegs[33], 11, 0); + + scis_l = scis_l - (u32)SOME_GET_REG_MACRO(__gxVerif->rasRegs[89], 11, 1); + scis_r = scis_r - (u32)SOME_GET_REG_MACRO(__gxVerif->rasRegs[89], 11, 1); + scis_t = scis_t - (u32)SOME_GET_REG_MACRO2(__gxVerif->rasRegs[89], 11, 9); + scis_b = scis_b - (u32)SOME_GET_REG_MACRO2(__gxVerif->rasRegs[89], 11, 9); + + if (scis_l < 0 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_LEFT]) { + __GX_WARNF(GXWARN_SCISSOR_RECT_LEFT, 0); + } + + if (scis_t < 0 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_TOP]) { + __GX_WARNF(GXWARN_SCISSOR_RECT_TOP, 0); + } + + switch (__gxVerif->rasRegs[67] & 7) { + case 4: + case 5: + if (scis_r > 719 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_RIGHT]) { + __GX_WARNF(GXWARN_SCISSOR_RECT_RIGHT, 719, "YUV"); + } + + if (scis_b > 575 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_BOT]) { + __GX_WARNF(GXWARN_SCISSOR_RECT_BOT, 575, "YUV"); + } + break; + case 0: + case 1: + case 3: + if (scis_r > 639 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_RIGHT]) { + __GX_WARNF(GXWARN_SCISSOR_RECT_RIGHT, 639, "RGB"); + } + + if (scis_b > 527 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_BOT]) { + __GX_WARNF(GXWARN_SCISSOR_RECT_BOT, 527, "RGB"); + } + break; + case 2: + if (scis_r > 639 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_RIGHT]) { + __GX_WARNF(GXWARN_SCISSOR_RECT_RIGHT, 639, __data_0); + } + + if (scis_b > 263 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_SCISSOR_RECT_BOT]) { + __GX_WARNF(GXWARN_SCISSOR_RECT_BOT, 263, __data_0); + } + break; + } +} + +void __GXVerifyBUMP(void) { + u32 i; + u32 nBmp; + u32 nTev; + u32 nTex; + u32 matrix; + + nBmp = GET_REG_FIELD(__gxVerif->rasRegs[0], 3, 16); + nTex = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 0); + nTev = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 10) + 1; + + for (i = 0; i < nTev; i++) { + matrix = GET_REG_FIELD(__gxVerif->rasRegs[16 + i], 4, 9); + if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) { + if ((u32)(__gxVerif->rasRegs[16 + i] & 0xFF000000) + 0x01000000 == 0U && __gxVerif->verifyLevel >= __gxvWarnLev[7]) { + sprintf(__gxvDummyStr, __gxvWarnings[7], i); + __gxVerif->cb(__gxvWarnLev[7], 7U, __gxvDummyStr); + } + + if ((GET_REG_FIELD(__gxVerif->rasRegs[16 + i], 2, 7) != 0 || matrix != 0) + && GET_REG_FIELD(__gxVerif->rasRegs[16 + i], 2, 0) >= nBmp && __gxVerif->verifyLevel >= __gxvWarnLev[8]) { + sprintf(__gxvDummyStr, __gxvWarnings[8], i); + __gxVerif->cb(__gxvWarnLev[8], 8U, __gxvDummyStr); + } + + if (matrix != 0) { + matrix = (matrix & 3) - 1; + if (((u32)(__gxVerif->rasRegs[(matrix * 3) + 6] & 0xFF000000) + 0x01000000 == 0 + || (u32)(__gxVerif->rasRegs[(matrix * 3) + 7] & 0xFF000000) + 0x01000000 == 0U + || (u32)(__gxVerif->rasRegs[(matrix * 3) + 8] & 0xFF000000) + 0x01000000 == 0U) && __gxVerif->verifyLevel >= __gxvWarnLev[9]) { + sprintf(__gxvDummyStr, __gxvWarnings[9], matrix, i); + __gxVerif->cb(__gxvWarnLev[9], 9U, __gxvDummyStr); + } + } + } + } + + if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) { + if (nBmp != 0 && (u32)(__gxVerif->rasRegs[0x27] & 0xFF000000) + 0x01000000 == 0 && __gxVerif->verifyLevel >= __gxvWarnLev[10]) { + __gxVerif->cb(__gxvWarnLev[10], 0xAU, __gxvWarnings[10]); + } + + if (nBmp != 0 && (u32)(__gxVerif->rasRegs[0x25] & 0xFF000000) + 0x01000000 == 0 && __gxVerif->verifyLevel >= __gxvWarnLev[11]) { + sprintf(__gxvDummyStr, __gxvWarnings[11], 0U, 1); + __gxVerif->cb(__gxvWarnLev[11], 0xBU, __gxvDummyStr); + } + + if (nBmp > 2U && (u32)(__gxVerif->rasRegs[0x26] & 0xFF000000) + 0x01000000 == 0 && __gxVerif->verifyLevel >= __gxvWarnLev[11]) { + sprintf(__gxvDummyStr, __gxvWarnings[11], 2U, 3); + __gxVerif->cb(__gxvWarnLev[11], 0xBU, __gxvDummyStr); + } + + if (nBmp != 0 && GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 3) >= nTex && __gxVerif->verifyLevel >= __gxvWarnLev[12]) { + sprintf(__gxvDummyStr, __gxvWarnings[12], 0U); + __gxVerif->cb(__gxvWarnLev[12], 0xCU, __gxvDummyStr); + } + + if (nBmp > 1U && GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 9) >= nTex && __gxVerif->verifyLevel >= __gxvWarnLev[12]) { + sprintf(__gxvDummyStr, __gxvWarnings[12], 1U); + __gxVerif->cb(__gxvWarnLev[12], 0xCU, __gxvDummyStr); + } + + if (nBmp > 2U && GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 15) >= nTex && __gxVerif->verifyLevel >= __gxvWarnLev[12]) { + sprintf(__gxvDummyStr, __gxvWarnings[12], 2U); + __gxVerif->cb(__gxvWarnLev[12], 0xCU, __gxvDummyStr); + } + + if (nBmp > 3U && GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 21) >= nTex && __gxVerif->verifyLevel >= __gxvWarnLev[12]) { + sprintf(__gxvDummyStr, __gxvWarnings[12], 3U); + __gxVerif->cb(__gxvWarnLev[12], 0xCU, __gxvDummyStr); + } + + if (nBmp != 0 && GET_REG_FIELD(__gxVerif->rasRegs[0x10], 1, 20) && __gxVerif->verifyLevel >= __gxvWarnLev[13]) { + __gxVerif->cb(__gxvWarnLev[13], 0xDU, __gxvWarnings[13]); + } + + if (nBmp != 0 && GET_REG_FIELD(__gxVerif->rasRegs[0x10], 2, 7) != 0 && __gxVerif->verifyLevel >= __gxvWarnLev[14]) { + __gxVerif->cb(__gxvWarnLev[14], 0xEU, __gxvWarnings[14]); + } + + if ((u32)(__gxVerif->rasRegs[0xF] & 0xFF000000) + 0x01000000 == 0 && (nTex != 0 || nBmp != 0) && __gxVerif->verifyLevel >= __gxvWarnLev[15]) { + __gxVerif->cb(__gxvWarnLev[15], 0xFU, __gxvWarnings[15]); + } + } +} + +#define SOMEINDEX(index) (index & 3) + ((index * 8) & ~0x1F) + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +void __GXVerifyTEX(void) { + u32 i; + u32 nBmp; + u32 nTev; + u32 nTex; + u32 enabled; + u32 texId; + u32 direct[8]; + u32 indirect[8]; + u32 h2; + u32 w2; + u32 nlevels; + + nBmp = GET_REG_FIELD(__gxVerif->rasRegs[0], 3, 16); + nTex = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 0); + nTev = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 10) + 1; + + for (i = 0; i < 8; i++) { + direct[i] = 0; + indirect[i] = 0; + } + + for (i = 0; i < nTev + nBmp; i++) { + if (i < nTev) { + if (__gxVerif->verifyLevel >= 1) { + if ((__gxVerif->rasRegs[(i >> 1U) + 0x28] & 0xFF000000) + 0x01000000 == 0U && __gxVerif->verifyLevel >= __gxvWarnLev[16]) { + sprintf(__gxvDummyStr, __gxvWarnings[16], i); + __gxVerif->cb(__gxvWarnLev[16], 16, __gxvDummyStr); + } + + if (i & 1) { + enabled = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 1, 18); + if (enabled && (GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 15) >= nTex) && __gxVerif->verifyLevel >= __gxvWarnLev[17]) { + sprintf(__gxvDummyStr, __gxvWarnings[17], i); + __gxVerif->cb(__gxvWarnLev[17], 17, __gxvDummyStr); + } + texId = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 12); + } else { + enabled = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 1, 6); + if (enabled && (GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 3) >= nTex) && __gxVerif->verifyLevel >= __gxvWarnLev[17]) { + sprintf(__gxvDummyStr, __gxvWarnings[17], i); + __gxVerif->cb(__gxvWarnLev[17], 17, __gxvDummyStr); + } + texId = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 0); + } + + if (enabled) { + direct[texId] = 1; + } + } + } else { + enabled = 1; + if ((i - nTev) == 0) { + texId = GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 0); + } else if ((i - nTev) == 1U) { + texId = GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 6); + } else if ((i - nTev) == 2U) { + texId = GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 12); + } else { + texId = GET_REG_FIELD(__gxVerif->rasRegs[0x27], 3, 18); + } + + if (!indirect[texId] && direct[texId] && __gxVerif->verifyLevel >= __gxvWarnLev[18]) { + sprintf(__gxvDummyStr, __gxvWarnings[18], texId); + __gxVerif->cb(__gxvWarnLev[18], 18, __gxvDummyStr); + } + indirect[texId] = 1; + } + + if (enabled) { + if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) { + if (((u32)(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0 + || (u32)(__gxVerif->rasRegs[0x84 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0 + || (u32)(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0 + || (u32)(__gxVerif->rasRegs[0x8C + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0 + || (u32)(__gxVerif->rasRegs[0x90 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0) && __gxVerif->verifyLevel >= __gxvWarnLev[19]) { + sprintf(__gxvDummyStr, __gxvWarnings[19], texId); + __gxVerif->cb(__gxvWarnLev[19], 19, __gxvDummyStr); + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x8C + SOMEINDEX(texId)], 1, 21) == 0 + && (u32)(__gxVerif->rasRegs[0x94 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0 && __gxVerif->verifyLevel >= __gxvWarnLev[20]) { + sprintf(__gxvDummyStr, __gxvWarnings[20], texId); + __gxVerif->cb(__gxvWarnLev[20], 20, __gxvDummyStr); + } + + if (((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 8 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 9 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 10) + && (__gxVerif->rasRegs[0x98 + SOMEINDEX(texId)] & 0xFF000000) + 0x01000000 == 0U && __gxVerif->verifyLevel >= __gxvWarnLev[21]) { + sprintf(__gxvDummyStr, __gxvWarnings[21], texId); + __gxVerif->cb(__gxvWarnLev[21], 21, __gxvDummyStr); + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 0) + 1 == 0) { + w2 = 1; + } else { + w2 = 1; + while (!(w2 & (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 0) + 1))) { + w2 *= 2; + } + w2 = (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 0) + 1) == w2; + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 10) + 1 == 0) { + h2 = 1; + } else { + h2 = 1; + while (!(h2 & (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 10) + 1))) { + h2 *= 2; + } + h2 = (GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 10) + 1) == h2; + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFFFF, 2, 5) && !w2 && __gxVerif->verifyLevel >= __gxvWarnLev[22]) { + sprintf(__gxvDummyStr, __gxvWarnings[22], "Width", texId); + __gxVerif->cb(__gxvWarnLev[22], 22, __gxvDummyStr); + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFFFF, 2, 5) && !h2 && __gxVerif->verifyLevel >= __gxvWarnLev[22]) { + sprintf(__gxvDummyStr, __gxvWarnings[22], "Height", texId); + __gxVerif->cb(__gxvWarnLev[22], 22, __gxvDummyStr); + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 2, 0) && !w2 && __gxVerif->verifyLevel >= __gxvWarnLev[23]) { + sprintf(__gxvDummyStr, __gxvWarnings[23], "S", texId); + __gxVerif->cb(__gxvWarnLev[23], 23, __gxvDummyStr); + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 2, 2) && !h2 && __gxVerif->verifyLevel >= __gxvWarnLev[23]) { + sprintf(__gxvDummyStr, __gxvWarnings[23], "T", texId); + __gxVerif->cb(__gxvWarnLev[23], 23, __gxvDummyStr); + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFFFF, 2, 5) != 0 + && ((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 8 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 9 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 10) + && (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 3, 5) != 1 + && (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 3, 5) != 5 && __gxVerif->verifyLevel >= __gxvWarnLev[24]) { + sprintf(__gxvDummyStr, __gxvWarnings[24], texId); + __gxVerif->cb(__gxvWarnLev[24], 24, __gxvDummyStr); + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x84 + SOMEINDEX(texId)], 8, 0) > (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x84 + SOMEINDEX(texId)], 8, 8) && __gxVerif->verifyLevel >= __gxvWarnLev[25]) { + sprintf(__gxvDummyStr, __gxvWarnings[25], texId); + __gxVerif->cb(__gxvWarnLev[25], 25, __gxvDummyStr); + } + + for ( + nlevels = 0; + ( + MAX((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 0) + 1, + (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 10, 10) + 1) >> nlevels + ) != 0; + nlevels++) { + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x84 + SOMEINDEX(texId)], 8, 8) > (nlevels - 1) * 16 && __gxVerif->verifyLevel >= __gxvWarnLev[26]) { + sprintf(__gxvDummyStr, __gxvWarnings[26], texId); + __gxVerif->cb(__gxvWarnLev[26], 26, __gxvDummyStr); + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 21) && GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 8) && __gxVerif->verifyLevel >= __gxvWarnLev[27]) { + sprintf(__gxvDummyStr, __gxvWarnings[27], texId); + __gxVerif->cb(__gxvWarnLev[27], 27, __gxvDummyStr); + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 2, 19) + && (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)] & 0xFFFF, 2, 5) == 0 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 3, 5) != 6 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 4) != 1 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 8 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 9 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 10 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 8) != 0 + || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 21)) && __gxVerif->verifyLevel >= __gxvWarnLev[28]) { + sprintf(__gxvDummyStr, __gxvWarnings[28], texId); + __gxVerif->cb(__gxvWarnLev[28], 28, __gxvDummyStr); + } + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 18) != 0) { + if (((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 3, 5) != 4 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 4) != 1) && __gxVerif->verifyLevel >= __gxvWarnLev[29]) { + sprintf(__gxvDummyStr, __gxvWarnings[29], texId); + __gxVerif->cb(__gxvWarnLev[29], 29, __gxvDummyStr); + } + + if ((!GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 17) || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) != 1 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 2, 19) != 0) && __gxVerif->verifyLevel >= __gxvWarnLev[30]) { + sprintf(__gxvDummyStr, __gxvWarnings[30], texId); + __gxVerif->cb(__gxvWarnLev[30], 30, __gxvDummyStr); + } + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 17) != 0) { + if (((u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 9 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x88 + SOMEINDEX(texId)], 4, 20) == 10) && __gxVerif->verifyLevel >= __gxvWarnLev[31]) { + sprintf(__gxvDummyStr, __gxvWarnings[31], texId); + __gxVerif->cb(__gxvWarnLev[31], 31, __gxvDummyStr); + } + + if ((!GET_REG_FIELD(__gxVerif->rasRegs[0x80 + SOMEINDEX(texId)], 1, 18) || 0) && __gxVerif->verifyLevel >= __gxvWarnLev[30]) { + sprintf(__gxvDummyStr, __gxvWarnings[30], texId); + __gxVerif->cb(__gxvWarnLev[30], 30, __gxvDummyStr); + } + } + } + } +} + +#if DEBUG +static char _521[] = "A"; +static char _522[] = "B"; +static char _523[] = "C"; +static char _524[] = "D"; +asm void __GXVerifyTEV(void) { + nofralloc +#include "../../nonmatchings/__GXVerifyTEV.s" +} +#pragma peephole on +#else +void __GXVerifyTEV(void) { + u32 i; // r31 + u32 nTev; // r29 + u32 nCol; // r28 + u32 enabled; // r30 + u32 color; // r27 + u32 Clh[4]; // r1+0x38 + u32 Alh[4]; // r1+0x28 + u32 Cwritten[4]; // r1+0x18 + u32 Awritten[4]; // r1+0x8 + + nTev = GET_REG_FIELD(__gxVerif->rasRegs[0], 4, 10) + 1; + nCol = GET_REG_FIELD(__gxVerif->rasRegs[0], 3, 4); + nCol; + + for (i = 0; i < 4; i++) { + Clh[i] = 0; + Alh[i] = 0; + Cwritten[i] = 0; + Awritten[i] = 0; + } + + for (i = 0; i < nTev; i++) { + if (__gxVerif->verifyLevel >= GX_WARN_SEVERE + && (((u32) ((__gxVerif->rasRegs[(i * 2) + 0xC0] & 0xFF000000) + 0x01000000) == 0U) || ((u32) ((__gxVerif->rasRegs[(i * 2) + 0xC1] & 0xFF000000) + 0x01000000) == 0U))) { + sprintf(__gxvDummyStr, __gxvWarnings[32], i); + __gxVerif->cb(1, 0x20U, __gxvDummyStr); + } + + if (i & 1) { + color = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 19); + } else { + color = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 3, 7); + } + + if (__gxVerif->verifyLevel >= GX_WARN_MEDIUM && ((color == 0 && nCol < 1) || (color == 1 && nCol < 2))) { + sprintf(__gxvDummyStr, __gxvWarnings[33], i); + __gxVerif->cb(1, 0x21U, __gxvDummyStr); + } + + if (i & 1) { + enabled = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 1, 18); + } else { + enabled = GET_REG_FIELD(__gxVerif->rasRegs[(i >> 1U) + 0x28], 1, 6); + } + + if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) { + if (!enabled && ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) == 9)) { + sprintf(__gxvDummyStr, __gxvWarnings[0x22], "A", i); + __gxVerif->cb(1, 0x22U, __gxvDummyStr); + } + + if (!enabled && ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) == 9)) { + sprintf(__gxvDummyStr, __gxvWarnings[0x22], "B", i); + __gxVerif->cb(1, 0x22U, __gxvDummyStr); + } + + if (!enabled && ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) == 9)) { + sprintf(__gxvDummyStr, __gxvWarnings[0x22], "C", i); + __gxVerif->cb(1, 0x22U, __gxvDummyStr); + } + + if (!enabled && ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 0) == 8 || (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 0) == 9)) { + sprintf(__gxvDummyStr, __gxvWarnings[0x22], "D", i); + __gxVerif->cb(1, 0x22U, __gxvDummyStr); + } + + if (!enabled && (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13) == 4) { + sprintf(__gxvDummyStr, __gxvWarnings[0x23], "A", i); + __gxVerif->cb(1, 0x23U, __gxvDummyStr); + } + + if (!enabled && (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10) == 4) { + sprintf(__gxvDummyStr, __gxvWarnings[0x23], "B", i); + __gxVerif->cb(1, 0x23U, __gxvDummyStr); + } + + if (!enabled && (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7) == 4) { + sprintf(__gxvDummyStr, __gxvWarnings[0x23], "C", i); + __gxVerif->cb(1, 0x23U, __gxvDummyStr); + } + + if (!enabled && (u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 4) == 4) { + sprintf(__gxvDummyStr, __gxvWarnings[0x23], "D", i); + __gxVerif->cb(1, 0x23U, __gxvDummyStr); + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) <= 7 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) + 0xE1] & 0xFF000000) + 0x01000000) == 0U) { + if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 12) ? !Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13)] : !Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13)]) { + sprintf(__gxvDummyStr, __gxvWarnings[0x24], "A", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 0xCU) ? "alpha" : "color", (__gxVerif->rasRegs[(i * 2) + 0xC0] >> 0xDU) & 7); + __gxVerif->cb(1, 0x24U, __gxvDummyStr); + } + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) <= 7 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) + 0xE1] & 0xFF000000) + 0x01000000) == 0U) { + if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 8) ? !Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9)] : !Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9)]) { + sprintf(__gxvDummyStr, __gxvWarnings[0x24], "B", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 8U) ? "alpha" : "color", (__gxVerif->rasRegs[(i * 2) + 0xC0] >> 9U) & 7); + __gxVerif->cb(1, 0x24U, __gxvDummyStr); + } + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) <= 7 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) + 0xE1] & 0xFF000000) + 0x01000000) == 0U) { + if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 4) ? !Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5)] : !Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5)]) { + sprintf(__gxvDummyStr, __gxvWarnings[0x24], "C", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 4U) ? "alpha" : "color", (__gxVerif->rasRegs[(i * 2) + 0xC0] >> 5U) & 7); + __gxVerif->cb(1, 0x24U, __gxvDummyStr); + } + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 0) <= 7 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 0) + 0xE1] & 0xFF000000) + 0x01000000) == 0U) { + if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 0) ? !Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 1)] : !Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 1)]) { + sprintf(__gxvDummyStr, __gxvWarnings[0x24], "D", i, (__gxVerif->rasRegs[(i * 2) + 0xC0] & 1) ? "alpha" : "color", (__gxVerif->rasRegs[(i * 2) + 0xC0] >> 1U) & 7); + __gxVerif->cb(1, 0x24U, __gxvDummyStr); + } + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13) <= 3 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 4, 14) + 0xE0] & 0xFF000000) + 0x01000000) == 0U && Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13)] == 0U) { + sprintf(__gxvDummyStr, __gxvWarnings[0x25], "A", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13)); + __gxVerif->cb(1, 0x25U, __gxvDummyStr); + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10) <= 3 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 11) + 0xE0] & 0xFF000000) + 0x01000000) == 0U && Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10)] == 0U) { + sprintf(__gxvDummyStr, __gxvWarnings[0x25], "B", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10)); + __gxVerif->cb(1, 0x25U, __gxvDummyStr); + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7) <= 3 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 8) + 0xE0] & 0xFF000000) + 0x01000000) == 0U && Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7)] == 0U) { + sprintf(__gxvDummyStr, __gxvWarnings[0x25], "C", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7)); + __gxVerif->cb(1, 0x25U, __gxvDummyStr); + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 4) <= 3 && ((__gxVerif->rasRegs[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 3) + 0xE0] & 0xFF000000) + 0x01000000) == 0U && Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 4)] == 0U) { + sprintf(__gxvDummyStr, __gxvWarnings[0x25], "D", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 4)); + __gxVerif->cb(1, 0x25U, __gxvDummyStr); + } + } + + if (__gxVerif->verifyLevel >= GX_WARN_ALL) { + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 12) <= 7) { + if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 12) ? Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13)] : Clh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13)]) { + sprintf(__gxvDummyStr, __gxvWarnings[0x26], "A", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 12) ? "alpha" : "color", GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 13)); + __gxVerif->cb(3, 0x26U, __gxvDummyStr); + } + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 8) <= 7) { + if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 8) ? Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9)] : Clh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9)]) { + sprintf(__gxvDummyStr, __gxvWarnings[0x26], "B", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 8) ? "alpha" : "color", GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 9)); + __gxVerif->cb(3, 0x26U, __gxvDummyStr); + } + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 4, 4) <= 7) { + if (GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 4) ? Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5)] : Clh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5)]) { + sprintf(__gxvDummyStr, __gxvWarnings[0x26], "C", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 4) ? "alpha" : "color", GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 3, 5)); + __gxVerif->cb(3, 0x26U, __gxvDummyStr); + } + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13) <= 3 && (u32)Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 13)] != 0) { + sprintf(__gxvDummyStr, __gxvWarnings[0x27], "A", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 0xDU)); + __gxVerif->cb(3, 0x27U, __gxvDummyStr); + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10) <= 3 && (u32)Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 10)] != 0) { + sprintf(__gxvDummyStr, __gxvWarnings[0x27], "B", i, ((__gxVerif->rasRegs[(i * 2) + 0xC1] >> 0xAU) & 7)); + __gxVerif->cb(3, 0x27U, __gxvDummyStr); + } + + if ((u32)GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7) <= 3 && (u32)Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7)] != 0) { + sprintf(__gxvDummyStr, __gxvWarnings[0x27], "C", i, GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 3, 7U)); + __gxVerif->cb(3, 0x27U, __gxvDummyStr); + } + } + Cwritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 2, 22)] = 1; + Awritten[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 2, 22)] = 1; + Clh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 2, 22)] = (!GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 2, 0) && !GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC0], 1, 19)); + Alh[GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 2, 22)] = (!GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 2, 0) && !GET_REG_FIELD(__gxVerif->rasRegs[(i * 2) + 0xC1], 1, 19)); + } + + for (i = 0; i < 4; i++) { + if (Cwritten[i] != 0U) { + __gxVerif->rasRegs[(i * 2) + 0xE1] = (__gxVerif->rasRegs[(i * 2) + 0xE1] & 0xFFFFFF) | 0xFF000000; + } + if (Awritten[i] != 0U) { + __gxVerif->rasRegs[(i * 2) + 0xE0] = (__gxVerif->rasRegs[(i * 2) + 0xE0] & 0xFFFFFF) | 0xFF000000; + } + } + + if (GET_REG_FIELD(__gxVerif->rasRegs[0xF5], 2, 2) && __gxVerif->verifyLevel >= 1) { + if ((u32) ((__gxVerif->rasRegs[0xF4] & 0xFF000000) + 0x01000000) == 0U) { + __gxVerif->cb(1, 0x28U, __gxvWarnings[0x28]); + } + if (!enabled) { + __gxVerif->cb(1, 0x29U, __gxvWarnings[0x29]); + } + } + + if (__gxVerif->verifyLevel >= GX_WARN_MEDIUM) { + if (GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC0], 2, 22)) { + __gxVerif->cb(2, 0x2AU, __gxvWarnings[0x2A]); + } + if (GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC1], 2, 22)) { + __gxVerif->cb(2, 0x2BU, __gxvWarnings[0x2B]); + } + } + + if (__gxVerif->verifyLevel >= GX_WARN_ALL) { + if (!GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC1], 2, 0) && !GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC0], 1, 19)) { + __gxVerif->cb(3, 0x2CU, __gxvWarnings[0x2C]); + } + if (!GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC1], 2, 0) && !GET_REG_FIELD(__gxVerif->rasRegs[((nTev - 1) * 2) + 0xC1], 1, 19)) { + __gxVerif->cb(3, 0x2DU, __gxvWarnings[0x2D]); + } + } + + if (__gxVerif->verifyLevel >= GX_WARN_MEDIUM && GET_REG_FIELD(__gxVerif->rasRegs[0x43], 1, 6) && (GET_REG_FIELD(__gxVerif->rasRegs[0xF3], 2, 22) || ((u32) GET_REG_FIELD(__gxVerif->rasRegs[0xF3], 3, 16) != 7) || ((u32) GET_REG_FIELD(__gxVerif->rasRegs[0xF3], 3, 19) != 7))) { + __gxVerif->cb(2, 0x2EU, __gxvWarnings[0x2E]); + } +} +#endif + +void __GXVerifyPE(void) { + u32 i; + + if (__gxVerif->verifyLevel >= GX_WARN_SEVERE && GET_REG_FIELD(__gxVerif->rasRegs[0x41], 1, 0) && GET_REG_FIELD(__gxVerif->rasRegs[0x41], 1, 1) && __gxVerif->verifyLevel >= __gxvWarnLev[0x2F]) { + __gxVerif->cb(__gxvWarnLev[0x2F], 0x2FU, __gxvWarnings[0x2F]); + } + + if (__gxVerif->verifyLevel >= GX_WARN_MEDIUM) { + if (GET_REG_FIELD(__gxVerif->rasRegs[0], 1, 9) && (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x43], 3, 0) != 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x31]) { + __gxVerif->cb(__gxvWarnLev[0x31], 0x31U, __gxvWarnings[0x31]); + } + if (!GET_REG_FIELD(__gxVerif->rasRegs[0], 1, 9) && (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x43], 3, 0) == 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x32]) { + __gxVerif->cb(__gxvWarnLev[0x32], 0x32U, __gxvWarnings[0x32]); + } + } + + if (__gxVerif->verifyLevel >= GX_WARN_ALL) { + for (i = 0; i < 4; i++) { + if (((u32)GET_REG_FIELD(__gxVerif->rasRegs[i + 1], 4, 4) > GET_REG_FIELD(__gxVerif->rasRegs[i + 1], 4, 12) || (u32)GET_REG_FIELD(__gxVerif->rasRegs[i + 1], 4, 12) > (u32)GET_REG_FIELD(__gxVerif->rasRegs[i + 1], 4, 20)) + && (u32)GET_REG_FIELD(__gxVerif->rasRegs[0x43], 3, 0) == 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x33]) { + sprintf(__gxvDummyStr, __gxvWarnings[0x33], i); + __gxVerif->cb(__gxvWarnLev[0x33], 0x33U, __gxvDummyStr); + } + } + } +} + +#endif diff --git a/src/dolphin/gx/GXVerifXF.c b/src/dolphin/gx/GXVerifXF.c new file mode 100644 index 0000000000..1e45aabdb8 --- /dev/null +++ b/src/dolphin/gx/GXVerifXF.c @@ -0,0 +1,1002 @@ +#if DEBUG + +#include + +#include + +#include "__gx.h" + +static u8 internalDebug; +static u32 DumpCount; +static s8 XFBuf[128]; +static u32 numRegularTextures; +static u32 numBumpmapTextures; +static u32 numColor0Textures; +static u32 numColor1Textures; +static u32 numColorTextures; +static s32 XFChannel = -1; + +static GXAttr TextureEnums[8] = { + GX_VA_TEX0, + GX_VA_TEX1, + GX_VA_TEX2, + GX_VA_TEX3, + GX_VA_TEX4, + GX_VA_TEX5, + GX_VA_TEX6, + GX_VA_TEX7, +}; + +static GXAttr MtxIdxEnums[9] = { + GX_VA_PNMTXIDX, + GX_VA_TEX0MTXIDX, + GX_VA_TEX1MTXIDX, + GX_VA_TEX2MTXIDX, + GX_VA_TEX3MTXIDX, + GX_VA_TEX4MTXIDX, + GX_VA_TEX5MTXIDX, + GX_VA_TEX6MTXIDX, + GX_VA_TEX7MTXIDX, +}; + +static u8 lightRegisterNames[13][256] = { + "Light Color RGBA", + "Cosine Attenuation A0", + "Cosine Attenuation A1", + "Cosine Attenuation A2", + "Distance Attenuation K0", + "Distance Attenuation K1", + "Distance Attenuation K2", + "X Light Position / Infinite Light X Direction", + "Y Light Position / Infinite Light Y Direction", + "Z Light Position / Infinite Light Z Direction", + "X Light Direction / Half Angle X Component", + "Y Light Direction / Half Angle Y Component", + "Z Light Direction / Half Angle Z Component", +}; + +#define LOWORD(var) (((u16 *)&(var))[0]) +#define HIWORD(var) (((u16 *)&(var))[1]) + +#define BYTE0(var) (((u8 *)&(var))[0]) +#define BYTE1(var) (((u8 *)&(var))[1]) +#define BYTE2(var) (((u8 *)&(var))[2]) +#define BYTE3(var) (((u8 *)&(var))[3]) + +static void CountTextureTypes(void) { + u32 i; + u32 texgen_type; + + numRegularTextures = 0; + numBumpmapTextures = 0; + numColor0Textures = 0; + numColor1Textures = 0; + + for (i = 0; i < __gxVerif->xfRegs[0x3F]; i++) { + texgen_type = BYTE3(__gxVerif->xfRegs[i + 64]); + texgen_type = (texgen_type >> 4) & 7; + if (texgen_type == 0) { + numRegularTextures++; + } else if (texgen_type == 1) { + numBumpmapTextures++; + } else if (texgen_type == 2) { + numColor0Textures++; + } else if (texgen_type == 3) { + numColor1Textures++; + } else { + if (__gxVerif->verifyLevel >= __gxvWarnLev[52]) { + __GX_WARNF(GXWARN_INVALID_TG_TYPE, texgen_type, i); + } + } + } + numColorTextures = numColor0Textures + numColor1Textures; +} + +static void InitializeXFVerifyData(void) { + CountTextureTypes(); +} + +static void CheckDirty(u32 index, const char* name) { + if (!__gxVerif->xfRegsDirty[index - 0x1000] && __gxVerif->verifyLevel >= __gxvWarnLev[53]) { + __GX_WARNF(GXWARN_XF_CTRL_UNINIT, index, name); + } +} + +static void CheckClean(u32 index, const char* name) { + if (__gxVerif->xfRegsDirty[index - 0x1000] && __gxVerif->verifyLevel >= __gxvWarnLev[54]) { + __GX_WARNF(GXWARN_XF_CTRL_INIT, index, name); + } +} + +static void CheckCTGColors(void) { + if ((u32)(BYTE3(__gxVerif->xfRegs[9]) & 3) > 2 && __gxVerif->verifyLevel >= __gxvWarnLev[120]) { + __GX_WARNF(120, (u8)(BYTE3(__gxVerif->xfRegs[9]) & 3)); + } +} + +static GXBool __GXVertexPacketHas(GXAttr attr) { + switch (attr) { + case GX_VA_POS: return GET_REG_FIELD(__GXData->vcdLo, 2, 9) != 0; + case GX_VA_NRM: return __GXData->hasNrms ? GET_REG_FIELD(__GXData->vcdLo, 2, 11) != 0 : GX_FALSE; + case GX_VA_NBT: return __GXData->hasBiNrms ? GET_REG_FIELD(__GXData->vcdLo, 2, 11) != 0 : GX_FALSE; + case GX_VA_CLR0: return GET_REG_FIELD(__GXData->vcdLo, 2, 13) != 0; + case GX_VA_CLR1: return GET_REG_FIELD(__GXData->vcdLo, 2, 15) != 0; + case GX_VA_TEX0: return GET_REG_FIELD(__GXData->vcdHi, 2, 0) != 0; + case GX_VA_TEX1: return GET_REG_FIELD(__GXData->vcdHi, 2, 2) != 0; + case GX_VA_TEX2: return GET_REG_FIELD(__GXData->vcdHi, 2, 4) != 0; + case GX_VA_TEX3: return GET_REG_FIELD(__GXData->vcdHi, 2, 6) != 0; + case GX_VA_TEX4: return GET_REG_FIELD(__GXData->vcdHi, 2, 8) != 0; + case GX_VA_TEX5: return GET_REG_FIELD(__GXData->vcdHi, 2, 10) != 0; + case GX_VA_TEX6: return GET_REG_FIELD(__GXData->vcdHi, 2, 12) != 0; + case GX_VA_TEX7: return GET_REG_FIELD(__GXData->vcdHi, 2, 14) != 0; + case GX_VA_PNMTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 0) != 0; + case GX_VA_TEX0MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 1) != 0; + case GX_VA_TEX1MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 2) != 0; + case GX_VA_TEX2MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 3) != 0; + case GX_VA_TEX3MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 4) != 0; + case GX_VA_TEX4MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 5) != 0; + case GX_VA_TEX5MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 6) != 0; + case GX_VA_TEX6MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 7) != 0; + case GX_VA_TEX7MTXIDX: return GET_REG_FIELD(__GXData->vcdLo, 1, 8) != 0; + default: + return GX_FALSE; + } +} + +static void CheckVertexPacket(void) { + u32 numHostTextures; + u32 numHostTexAbsent; + u32 i; + u32 numMatrixIndices; + + if (!__GXVertexPacketHas(GX_VA_POS) && __gxVerif->verifyLevel >= __gxvWarnLev[57]) { + __GX_WARN(GXWARN_VTX_NO_GEOM); + } + + if (__GXVertexPacketHas(GX_VA_CLR1) && !__GXVertexPacketHas(GX_VA_CLR0) &&__gxVerif->verifyLevel >= __gxvWarnLev[70]) { + __GX_WARN(GXWARN_VCD_CLR_ORDER); + } + + numHostTextures = 0; + numHostTexAbsent = 0; + + for (i = 0; i < 8; i++) { + if (__GXVertexPacketHas(TextureEnums[i])) { + numHostTextures += 1; + numHostTexAbsent = 0; + } else { + numHostTexAbsent += 1; + } + } + + if (numHostTextures + numHostTexAbsent != 8 && __gxVerif->verifyLevel >= __gxvWarnLev[71]) { + __GX_WARN(GXWARN_VCD_TEX_ORDER); + } + + if ((BYTE3(__gxVerif->xfRegs[8]) & 3) == 0 && ((BYTE3(__gxVerif->xfRegs[8]) >> 2) & 3) == 0 && (u32)((BYTE3(__gxVerif->xfRegs[8]) >> 4) & 0xF) == 0) { + numMatrixIndices = 0; + + for (i = 0; i <= 8; i++) { + if (__GXVertexPacketHas(MtxIdxEnums[i])) { + numMatrixIndices += 1; + } + } + + if (numMatrixIndices != 0 && __gxVerif->verifyLevel >= __gxvWarnLev[69]) { + __GX_WARN(GXWARN_VCD_FMT_UNSUP); + } + } +} + +static void CheckSourceRows(void) { + u32 i; + + for (i = 0; i < numRegularTextures; i++) { + switch ((HIWORD(__gxVerif->xfRegs[i + 64]) >> 7) & 0x1F) { + case 0: + if (!__GXVertexPacketHas(GX_VA_POS) && __gxVerif->verifyLevel >= __gxvWarnLev[72]) { + __GX_WARNF(GXWARN_TEX_SRC_NPOS, i); + } + break; + case 1: + if (!__GXVertexPacketHas(GX_VA_NRM) && !__GXVertexPacketHas(GX_VA_NBT)&& __gxVerif->verifyLevel >= __gxvWarnLev[73]) { + __GX_WARNF(GXWARN_TEX_SRC_NNRM, i); + } + break; + case 2: + if (!__GXVertexPacketHas(GX_VA_CLR0) && __gxVerif->verifyLevel >= __gxvWarnLev[74]) { + __GX_WARNF(GXWARN_TEX_SRC_NCLR0, i); + } + if (!__GXVertexPacketHas(GX_VA_CLR1) && __gxVerif->verifyLevel >= __gxvWarnLev[75]) { + __GX_WARNF(GXWARN_TEX_SRC_NCLR1, i); + } + break; + case 3: + case 4: + if (!__GXVertexPacketHas(GX_VA_NBT) && __gxVerif->verifyLevel >= __gxvWarnLev[76]) { + __GX_WARNF(GXWARN_TEX_SRC_NNBT, i); + } + break; + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + if (!__GXVertexPacketHas(TextureEnums[((HIWORD(__gxVerif->xfRegs[i + 64]) >> 7) & 0x1F) - 5]) && __gxVerif->verifyLevel >= __gxvWarnLev[77]) { + __GX_WARNF(GXWARN_TEX_SRC_NTEX, i, ((HIWORD(__gxVerif->xfRegs[i + 64]) >> 7) & 0x1F) - 5); + } + break; + default: + if (__gxVerif->verifyLevel >= __gxvWarnLev[78]) { + __GX_WARNF(GXWARN_INV_TEX_SRC, i, (u8)((HIWORD(__gxVerif->xfRegs[i + 64]) >> 7) & 0x1F)); + } + break; + } + } +} + +static void CheckTextureOrder(void) { + u8 done = 0; + u32 count = 0; + + while (!done) { + if (count == __gxVerif->xfRegs[0x3F] || ((BYTE3(__gxVerif->xfRegs[count + 64]) >> 4) & 7)) { + done = 1; + } else { + count += 1; + } + } + + done = 0; + while (done == 0) { + if (count == __gxVerif->xfRegs[0x3F]) { + done = 1; + } else if ((u32)((BYTE3(__gxVerif->xfRegs[count + 64]) >> 4) & 7) != 1) { + if (!((BYTE3(__gxVerif->xfRegs[count + 64]) >> 4) & 7) && __gxVerif->verifyLevel >= __gxvWarnLev[79]) { + __GX_WARN(GXWARN_INV_TG_ORDER); + } + done = 1; + } else { + count += 1; + } + } + + done = 0; + while (done == 0) { + if (count == __gxVerif->xfRegs[0x3F]) { + done = 1; + } else if (!((BYTE3(__gxVerif->xfRegs[count + 64]) >> 4) & 7) || (u32)((BYTE3(__gxVerif->xfRegs[count + 64]) >> 4) & 7) == 1) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[79]) { + __GX_WARN(GXWARN_INV_TG_ORDER); + } + done = 1; + } else { + count += 1; + } + } +} + +static void CheckRAM(u8 Normal, u32 StartingAddress, u32 Count, GXWarnID WarnID, char* Str) { + u32 i; + u8 printedPreamble; + u8 dirtyBit; + + printedPreamble = 0; + + for (i = StartingAddress; i < StartingAddress + Count; i++) { + dirtyBit = Normal != 0 ? __gxVerif->xfMtxDirty[i - 0x300] : __gxVerif->xfMtxDirty[i]; + + if (dirtyBit == 0) { + if (printedPreamble == 0) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[WarnID]) { + __gxVerif->cb(__gxvWarnLev[WarnID], WarnID, Str); + } + + printedPreamble = 1; + } + } + } +} + +static void CheckBumpmapTextures(void) { + u32 i; + u32 BumpMapSource; + u32 BumpMapLight; + u32 lightRAMOffset; + char Preamble[256]; + + if (!__GXVertexPacketHas(GX_VA_PNMTXIDX)) { + if ((u32)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F) > 30 && __gxVerif->verifyLevel >= __gxvWarnLev[0x50]) { + __GX_WARNF(0x50, (u8)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F)); + } + sprintf(Preamble, __gxvWarnings[0x6A], (u8)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F)); + CheckRAM(1, ((BYTE3(__gxVerif->xfRegs[24]) & 0x3F) * 3) + 0x400, 9U, 0x6A, Preamble); + } + + for (i = 0; i < numBumpmapTextures; i++) { + BumpMapSource = BYTE2(__gxVerif->xfRegs[numRegularTextures + i + 64]); + BumpMapSource = (BumpMapSource >> 4) & 7; + if ((BYTE3(__gxVerif->xfRegs[BumpMapSource + 64]) >> 4) & 7 && __gxVerif->verifyLevel >= __gxvWarnLev[0x51]) { + __GX_WARNF(0x51, i + numRegularTextures, BumpMapSource); + } + + BumpMapLight = __gxVerif->xfRegs[numRegularTextures + i + 0x40]; + BumpMapLight = (BumpMapLight >> 15) & 7; + lightRAMOffset = (BumpMapLight * 0x10) + 0x60A; + if (!__gxVerif->xfLightDirty[lightRAMOffset - 0x600 + 0] && __gxVerif->verifyLevel >= __gxvWarnLev[0x52]) { + __GX_WARNF(0x52, i + numRegularTextures, BumpMapLight, "X"); + } + + if (!__gxVerif->xfLightDirty[lightRAMOffset - 0x600 + 1] && __gxVerif->verifyLevel >= __gxvWarnLev[0x52]) { + __GX_WARNF(0x52, i + numRegularTextures, BumpMapLight, "Y"); + } + + if (!__gxVerif->xfLightDirty[lightRAMOffset - 0x600 + 2] && __gxVerif->verifyLevel >= __gxvWarnLev[0x52]) { + __GX_WARNF(0x52, i + numRegularTextures, BumpMapLight, "Z"); + } + + if (!__GXVertexPacketHas(GX_VA_NBT) && __gxVerif->verifyLevel >= __gxvWarnLev[0x53]) { + __GX_WARNF(0x53, i); + } + } + + lightRAMOffset; lightRAMOffset; // needed to match +} + +static void CheckTextureTransformMatrices(void) { + u32 i; + u32 StartingAddress; + u32 Size; + u8 MtxIndexInVertexPacket; + char Preamble[256]; + u32 Val; + + for (i = 0; i < numRegularTextures; i++) { + MtxIndexInVertexPacket = 0; + switch (i) { + case 0: + StartingAddress = (u8)((HIWORD(__gxVerif->xfRegs[0x18]) >> 4U) & 0xFC); + Val = HIWORD(__gxVerif->xfRegs[0x18]); + Val = (Val >> 6) & 0x3F; + MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX0MTXIDX); + break; + case 1: + StartingAddress = (u8)((__gxVerif->xfRegs[0x18] >> 10) & 0xFC); + Val = __gxVerif->xfRegs[0x18]; + Val = (Val >> 12) & 0x3F; + MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX1MTXIDX); + break; + case 2: + StartingAddress = (u8)(BYTE1(__gxVerif->xfRegs[0x18]) & 0xFC); + Val = BYTE1(__gxVerif->xfRegs[0x18]); + Val = (Val >> 2) & 0x3F; + MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX2MTXIDX); + break; + case 3: + StartingAddress = (BYTE0(__gxVerif->xfRegs[0x18]) * 4) & 0xFC; + Val = BYTE0(__gxVerif->xfRegs[0x18]); + Val = Val & 0x3F; + MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX3MTXIDX); + break; + case 4: + StartingAddress = (BYTE3(__gxVerif->xfRegs[0x19]) * 4) & 0xFC; + Val = BYTE3(__gxVerif->xfRegs[0x19]); + Val = Val & 0x3F; + MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX4MTXIDX); + break; + case 5: + StartingAddress = (u8)((HIWORD(__gxVerif->xfRegs[0x19]) >> 4) & 0xFC); + Val = HIWORD(__gxVerif->xfRegs[0x19]); + Val = (Val >> 6) & 0x3F; + MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX5MTXIDX); + break; + case 6: + StartingAddress = (u8)((__gxVerif->xfRegs[0x19] >> 10) & 0xFC); + Val = __gxVerif->xfRegs[0x19]; + Val = (Val >> 12) & 0x3F; + MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX6MTXIDX); + break; + case 7: + StartingAddress = (u8)(BYTE1(__gxVerif->xfRegs[0x19]) & 0xFC); + Val = BYTE1(__gxVerif->xfRegs[0x19]); + Val = (Val >> 2) & 0x3F; + MtxIndexInVertexPacket = __GXVertexPacketHas(GX_VA_TEX7MTXIDX); + break; + default: + if (__gxVerif->verifyLevel >= __gxvWarnLev[0x54]) { + __GX_WARNF(0x54, i); + } + break; + } + + if (MtxIndexInVertexPacket == 0) { + sprintf(Preamble, __gxvWarnings[0x6B], i, i, Val); + if (!((BYTE3(__gxVerif->xfRegs[i + 64]) >> 1) & 1)) { + Size = 8; + } else { + Size = 0xC; + } + CheckRAM(0U, StartingAddress, Size, 0x6B, Preamble); + } + } + + // needed to match + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + StartingAddress; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; + MtxIndexInVertexPacket; +} + +static void CheckInputForms(void) { + u32 i; + + for (i = 0; i < numRegularTextures; i++) { + switch ((HIWORD(__gxVerif->xfRegs[i + 64]) >> 7) & 0x1F) { + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + if ((BYTE3(__gxVerif->xfRegs[i + 64]) >> 2) & 1 && __gxVerif->verifyLevel >= __gxvWarnLev[0x79]) { + __GX_WARNF(0x79, i, (u8)((HIWORD(__gxVerif->xfRegs[i + 64]) >> 7) & 0x1F)); + } + } + } +} + +static void CheckLight(u32 lightSource) { + u32 lightRAMOffset; + u8 printedPreamble; + u32 i; + + printedPreamble = 0; + lightRAMOffset = (lightSource * 0x10) + 0x603; + for (i = 0; i < 13; i++) { + if (!__gxVerif->xfLightDirty[lightRAMOffset + i - 0x600]) { + if (!printedPreamble) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[0x6C]) { + __GX_WARNF(0x6C, lightSource); + } + + printedPreamble = 1; + } + } + } +} + +// NONMATCHING +static void CheckColor0(void) { + char Preamble[256]; + u8 haveLight; + u32 i; + u8 lightUsed; + + if ((u8)(BYTE3(__gxVerif->xfRegs[9]) & 3) || numColorTextures != 0) { + if (!__gxVerif->xfRegsDirty[14] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7A]) { + __GX_WARNF(0x7A, 0x100E, "Color 0 control register"); + } + + if (!__gxVerif->xfRegsDirty[16] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7A]) { + __GX_WARNF(0x7A, 0x1010, "Alpha 0 control register"); + } + + if (!(BYTE3(__gxVerif->xfRegs[14]) & 1) && !__gxVerif->xfRegsDirty[12] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7B]) { + __GX_WARNF(0x7B, 0, 0, 0x100C); + } + + if (!((BYTE3(__gxVerif->xfRegs[14]) >> 6) & 1) && !__gxVerif->xfRegsDirty[10] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7C]) { + __GX_WARNF(0x7C, 0, 0, 0x100A); + } + + if ((u32)((BYTE3(__gxVerif->xfRegs[14]) >> 1) & 1) == 1 || (u32)((BYTE3(__gxVerif->xfRegs[16]) >> 1) & 1) == 1) { + haveLight = 0; + for (i = 0; i < 8; i++) { + lightUsed = 0; + switch (i) { + case 0: + if ((u8)((BYTE3(__gxVerif->xfRegs[14]) >> 2) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[16]) >> 2) & 1)) { + lightUsed = 1; + } + break; + case 1: + if ((u8)((BYTE3(__gxVerif->xfRegs[14]) >> 3) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[16]) >> 3) & 1)) { + lightUsed = 1; + } + break; + case 2: + if ((u8)((BYTE3(__gxVerif->xfRegs[14]) >> 4) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[16]) >> 4) & 1)) { + lightUsed = 1; + } + break; + case 3: + if ((u8)((BYTE3(__gxVerif->xfRegs[14]) >> 5) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[16]) >> 5) & 1)) { + lightUsed = 1; + } + break; + case 4: + if ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 3) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[16]) >> 3) & 1)) { + lightUsed = 1; + } + break; + case 5: + if ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 4) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[16]) >> 4) & 1)) { + lightUsed = 1; + } + break; + case 6: + if ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 5) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[16]) >> 5) & 1)) { + lightUsed = 1; + } + break; + case 7: + if ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 6) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[16]) >> 6) & 1)) { + lightUsed = 1; + } + break; + } + if (lightUsed != 0) { + CheckLight(i); + haveLight = 1; + } + } + + if (haveLight != 0) { + if (!((BYTE2(__gxVerif->xfRegs[14]) >> 2) & 1) && ((HIWORD(__gxVerif->xfRegs[14]) >> 7) & 3) && __gxVerif->verifyLevel >= __gxvWarnLev[0x59]) { + __GX_WARNF(0x59, "COLOR0", "COLOR0"); + } + + if (!((BYTE2(__gxVerif->xfRegs[16]) >> 2) & 1) && ((HIWORD(__gxVerif->xfRegs[16]) >> 7) & 3) && __gxVerif->verifyLevel >= __gxvWarnLev[0x59]) { + __GX_WARNF(0x59, "ALPHA0", "ALPHA0"); + } + + if (((HIWORD(__gxVerif->xfRegs[14]) >> 7) & 3) + || ((u8)((BYTE2(__gxVerif->xfRegs[14]) >> 1) & 1) && ((u32)((BYTE2(__gxVerif->xfRegs[14]) >> 2) & 1) == 1)) + || ((HIWORD(__gxVerif->xfRegs[16]) >> 7) & 3) + || ((u8)((BYTE2(__gxVerif->xfRegs[16]) >> 1) & 1) && ((u32)((BYTE2(__gxVerif->xfRegs[16]) >> 2) & 1) == 1))) { + if ((__GXVertexPacketHas(GX_VA_NRM) == 0) && (__GXVertexPacketHas(GX_VA_NBT) == 0) && __gxVerif->verifyLevel >= __gxvWarnLev[0x5A]) { + __GX_WARNF(0x5A, 0); + } + if (__GXVertexPacketHas(GX_VA_PNMTXIDX) == 0) { + if ((u32)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F) > 30 && __gxVerif->verifyLevel >= __gxvWarnLev[0x5B]) { + __GX_WARNF(0x5B, 0, (BYTE3(__gxVerif->xfRegs[24]) & 0x3F)); + } + sprintf(Preamble, __gxvWarnings[0x6D], 0, (u8)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F)); + CheckRAM(1, ((BYTE3(__gxVerif->xfRegs[24]) & 0x3F) * 3) + 0x400, 9, 0x6D, Preamble); + } + } + } + } + } +} + +// NONMATCHING +static void CheckColor1(void) { + u8 usingColor1; + char Preamble[256]; + u8 haveLight; + u32 i; + u8 lightUsed; + + if (numColorTextures > 1 && ((u32)((BYTE3(__gxVerif->xfRegs[numRegularTextures + numBumpmapTextures + 1 + 64]) >> 4) & 7) == 3)) { + usingColor1 = 1; + } else { + usingColor1 = 0; + } + + if ((u32)(BYTE3(__gxVerif->xfRegs[9]) & 3) == 2 || usingColor1) { + if (!__gxVerif->xfRegsDirty[15] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7A]) { + __GX_WARNF(0x7A, 0x100F, "Color 1 control register"); + } + + if (!__gxVerif->xfRegsDirty[17] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7A]) { + __GX_WARNF(0x7A, 0x1011, "Alpha 1 control register"); + } + + if (!(BYTE3(__gxVerif->xfRegs[15]) & 1) && !__gxVerif->xfRegsDirty[13] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7B]) { + __GX_WARNF(0x7B, 1, 1, 0x100D); + } + + if (!((BYTE3(__gxVerif->xfRegs[15]) >> 6) & 1) && !__gxVerif->xfRegsDirty[11] && __gxVerif->verifyLevel >= __gxvWarnLev[0x7C]) { + __GX_WARNF(0x7C, 1, 1, 0x100B); + } + + if ((u32)((BYTE3(__gxVerif->xfRegs[15]) >> 1) & 1) == 1 || (u32)((BYTE3(__gxVerif->xfRegs[17]) >> 1) & 1) == 1) { + haveLight = 0; + for (i = 0; i < 8; i++) { + lightUsed = 0; + switch (i) { + case 0: + if ((u8)((BYTE3(__gxVerif->xfRegs[15]) >> 2) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[17]) >> 2) & 1)) { + lightUsed = 1; + } + break; + case 1: + if ((u8)((BYTE3(__gxVerif->xfRegs[15]) >> 3) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[17]) >> 3) & 1)) { + lightUsed = 1; + } + break; + case 2: + if ((u8)((BYTE3(__gxVerif->xfRegs[15]) >> 4) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[17]) >> 4) & 1)) { + lightUsed = 1; + } + break; + case 3: + if ((u8)((BYTE3(__gxVerif->xfRegs[15]) >> 5) & 1) || (u8)((BYTE3(__gxVerif->xfRegs[17]) >> 5) & 1)) { + lightUsed = 1; + } + break; + case 4: + if ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 3) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[17]) >> 3) & 1)) { + lightUsed = 1; + } + break; + case 5: + if ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 4) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[17]) >> 4) & 1)) { + lightUsed = 1; + } + break; + case 6: + if ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 5) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[17]) >> 5) & 1)) { + lightUsed = 1; + } + break; + case 7: + if ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 6) & 1) || (u8)((BYTE2(__gxVerif->xfRegs[17]) >> 6) & 1)) { + lightUsed = 1; + } + break; + } + if (lightUsed != 0) { + CheckLight(i); + haveLight = 1; + } + } + + if (haveLight != 0) { + if (!((BYTE2(__gxVerif->xfRegs[15]) >> 2) & 1) && ((HIWORD(__gxVerif->xfRegs[15]) >> 7) & 3) && __gxVerif->verifyLevel >= __gxvWarnLev[0x59]) { + __GX_WARNF(0x59, "COLOR1", "COLOR1"); + } + + if (!((BYTE2(__gxVerif->xfRegs[17]) >> 2) & 1) && ((HIWORD(__gxVerif->xfRegs[17]) >> 7) & 3) && __gxVerif->verifyLevel >= __gxvWarnLev[0x59]) { + __GX_WARNF(0x59, "ALPHA1", "ALPHA1"); + } + + if (((HIWORD(__gxVerif->xfRegs[15]) >> 7) & 3) + || ((u8)((BYTE2(__gxVerif->xfRegs[15]) >> 1) & 1) && ((u32)((BYTE2(__gxVerif->xfRegs[15]) >> 2) & 1) == 1)) + || ((HIWORD(__gxVerif->xfRegs[17]) >> 7) & 3) + || ((u8)((BYTE2(__gxVerif->xfRegs[17]) >> 1) & 1) && ((u32)((BYTE2(__gxVerif->xfRegs[17]) >> 2) & 1) == 1))) { + if ((__GXVertexPacketHas(GX_VA_NRM) == 0) && (__GXVertexPacketHas(GX_VA_NBT) == 0) && __gxVerif->verifyLevel >= __gxvWarnLev[0x5A]) { + __GX_WARNF(0x5A, 1); + } + if (__GXVertexPacketHas(GX_VA_PNMTXIDX) == 0) { + if ((u32)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F) > 30 && __gxVerif->verifyLevel >= __gxvWarnLev[0x5B]) { + __GX_WARNF(0x5B, 1, (u8)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F)); + } + sprintf(Preamble, __gxvWarnings[0x6D], 1, (u8)(BYTE3(__gxVerif->xfRegs[24]) & 0x3F)); + CheckRAM(1, ((BYTE3(__gxVerif->xfRegs[24]) & 0x3F) * 3) + 0x400, 9, 0x6D, Preamble); + } + } + } + } + } +} + +static void CheckViewport(void) { + f32 vl; + f32 vr; + f32 vt; + f32 vb; + + vl = (*(f32*)&__gxVerif->xfRegs[29] - *(f32*)&__gxVerif->xfRegs[26]) - 342.0f; + vt = (*(f32*)&__gxVerif->xfRegs[30] + *(f32*)&__gxVerif->xfRegs[27]) - 342.0f; + vr = (*(f32*)&__gxVerif->xfRegs[29] + *(f32*)&__gxVerif->xfRegs[26]) - 342.0f; + vb = (*(f32*)&__gxVerif->xfRegs[30] - *(f32*)&__gxVerif->xfRegs[27]) - 342.0f; + + if ((vt < -0.5f || vt > 528.0f) && __gxVerif->verifyLevel >= __gxvWarnLev[0x55]) { + __GX_WARNF(0x55, vt); + } + + if ((vb < 0.0f || vb > 528.0f) && __gxVerif->verifyLevel >= __gxvWarnLev[0x56]) { + __GX_WARNF(0x56, vb); + } + + if ((vl < 0.0f || vl > 640.0f) && __gxVerif->verifyLevel >= __gxvWarnLev[0x57]) { + __GX_WARNF(0x57, vl); + } + + if ((vr < 0.0f || vr > 640.0f) && __gxVerif->verifyLevel >= __gxvWarnLev[0x58]) { + __GX_WARNF(0x58, vr); + } +} + +static void ComputeSignExponentMantissa(f32 floatVal, u32* sign, u32* exponent, u32* mantissa) { + u32 intVal = *(u32*)&floatVal; + + *sign = (intVal >> 31) & 1; + *exponent = (intVal >> 23) & 0xFF; + *mantissa = intVal & 0x7FFFFF; +} + +static void CheckFloatingPointValue(u8 dirtyBit, u32 value, char* label) { + u32 sign; + u32 exponent; + u32 mantissa; + f32 valuef; + + &valuef; + + if ((dirtyBit == 0)) { + return; + } + valuef = *(f32 *)&value; + ComputeSignExponentMantissa(valuef, &sign, &exponent, &mantissa); + + if (exponent == 0 && mantissa == 0) { + return; + } + + if (exponent == 0xFF) { + if (__gxVerif->verifyLevel >= 2) { + if (mantissa == 0) { + if (sign != 0) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5C]) { + __GX_WARNF(0x5C, label, "-", *(u32 *)&valuef); + } + } else { + if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5C]) { + __GX_WARNF(0x5C, label, "+", *(u32 *)&valuef); + } + } + } else { + if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5D]) { + __GX_WARNF(0x5D, label, *(u32 *)&valuef); + } + } + } + } else if (__gxVerif->verifyLevel >= 3) { + if (exponent < 0x6BU) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5E]) { + __GX_WARNF(0x5E, label, valuef, *(u32 *)&valuef); + } + } else if (exponent > 0x96U) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[0x5F]) { + __GX_WARNF(0x5F, label, valuef, *(u32 *)&valuef); + } + } + } +} + +static void CheckMatrixRAMRanges(void) { + u32 i; + char label[256]; + + for (i = 0; i <= 255; i++) { + sprintf(label, "Geometry/Texture Matrix ram address 0x%04x", i); + CheckFloatingPointValue(__gxVerif->xfMtxDirty[i], __gxVerif->xfMtx[i], label); + } +} + +static void CheckNormalRAMRanges(void) { + u32 i; + char label[256]; + + for (i = 1024; i <= 1119; i++) { + sprintf(label, "Normal Matrix ram address 0x%04x", i); + CheckFloatingPointValue(__gxVerif->xfNrmDirty[i - 1024], __gxVerif->xfNrm[i - 1024], label); + } +} + +static void CheckDMatrixRAMRanges(void) { + u32 i; + char label[256]; + + for (i = 1280; i <= 1535; i++) { + sprintf(label, "Dual Texture Matrix ram address 0x%04x", i); + CheckFloatingPointValue(__gxVerif->xfDMtxDirty[i - 1280], __gxVerif->xfDMtx[i - 1280], label); + } +} + +static void CheckLightRAMRanges(void) { + u32 lightSource; + u32 lightRAMOffset; + char label[256]; + u32 i; + + for (lightSource = 0; lightSource < 8; lightSource++) { + for (i = 1; i < 13; i++) { + lightRAMOffset = (lightSource << 4) + i; + lightRAMOffset += 0x603; + sprintf(label, "Light %d %s (address 0x%04x)", lightSource, lightRegisterNames[i], lightRAMOffset); + CheckFloatingPointValue(__gxVerif->xfLightDirty[lightRAMOffset - 0x600], __gxVerif->xfLight[(s32) (lightRAMOffset - 0x600)], label); + } + + } + + i; lightSource; // needed to match +} + +static void CheckControlRAMRanges(void) { + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1A], __gxVerif->xfRegs[0x1A], "Viewport Scale X"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1B], __gxVerif->xfRegs[0x1B], "Viewport Scale Y"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1C], __gxVerif->xfRegs[0x1C], "Viewport Scale Z"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1D], __gxVerif->xfRegs[0x1D], "Viewport Offset X"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1E], __gxVerif->xfRegs[0x1E], "Viewport Offset Y"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x1F], __gxVerif->xfRegs[0x1F], "Viewport Offset Z"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x20], __gxVerif->xfRegs[0x20], "Projection Matrix A Value"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x21], __gxVerif->xfRegs[0x21], "Projection Matrix B Value"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x22], __gxVerif->xfRegs[0x22], "Projection Matrix C Value"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x23], __gxVerif->xfRegs[0x23], "Projection Matrix D Value"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x24], __gxVerif->xfRegs[0x24], "Projection Matrix E Value"); + CheckFloatingPointValue(__gxVerif->xfRegsDirty[0x25], __gxVerif->xfRegs[0x25], "Projection Matrix F Value"); +} + +static void CheckFloatingPointRanges(void) { + CheckMatrixRAMRanges(); + CheckNormalRAMRanges(); + CheckDMatrixRAMRanges(); + CheckLightRAMRanges(); + CheckControlRAMRanges(); +} + +static void CheckMatrixIndices(void) { + if (!__GXVertexPacketHas(GX_VA_PNMTXIDX) + || !__GXVertexPacketHas(GX_VA_TEX0MTXIDX) + || !__GXVertexPacketHas(GX_VA_TEX1MTXIDX) + || !__GXVertexPacketHas(GX_VA_TEX2MTXIDX) + || !__GXVertexPacketHas(GX_VA_TEX3MTXIDX)) + { + CheckDirty(0x1018U, "Geometry & Textures [0-3] transform matrix indices"); + } + + if (__gxVerif->verifyLevel >= 1 && !__GXVertexPacketHas(GX_VA_PNMTXIDX)) { + CheckRAM(0U, (BYTE3(__gxVerif->xfRegs[24]) * 4) & 0xFC, 0xCU, 0x6E, __gxvWarnings[0x6E]); + } + + if ((!__GXVertexPacketHas(GX_VA_TEX4MTXIDX) + || !__GXVertexPacketHas(GX_VA_TEX5MTXIDX) + || !__GXVertexPacketHas(GX_VA_TEX6MTXIDX) + || !__GXVertexPacketHas(GX_VA_TEX7MTXIDX)) + && numRegularTextures > 4 + && __gxVerif->verifyLevel >= 1 + && !__gxVerif->xfRegsDirty[0x19] && __gxVerif->verifyLevel >= __gxvWarnLev[0x60]) { + __GX_WARNF(0x60, numRegularTextures, 0x1019U); + } +} + +static void CheckErrors(void) { + u32 i; + char registerName[80]; + + CheckDirty(0x103FU, "Number of XF output textures"); + CheckDirty(0x1009U, "Number of XF output colors"); + CheckDirty(0x1008U, "InVertexSpec"); + CheckDirty(0x101AU, "Viewport ScaleX"); + CheckDirty(0x101BU, "Viewport ScaleY"); + CheckDirty(0x101CU, "Viewport ScaleZ"); + CheckDirty(0x101DU, "Viewport OffsetX"); + CheckDirty(0x101EU, "Viewport OffsetY"); + CheckDirty(0x101FU, "Viewport OffsetZ"); + CheckDirty(0x1020U, "Projection matrix 'A' value"); + CheckDirty(0x1021U, "Projection matrix 'B' value"); + CheckDirty(0x1022U, "Projection matrix 'C' value"); + CheckDirty(0x1023U, "Projection matrix 'D' value"); + CheckDirty(0x1024U, "Projection matrix 'E' value"); + CheckDirty(0x1025U, "Projection matrix 'F' value"); + CheckDirty(0x1026U, "Projection matrix orthographic/perspective select"); + CheckMatrixIndices(); + + if (__gxVerif->verifyLevel >= 1) { + if (!(u32)(BYTE3(__gxVerif->xfRegs[9]) & 3) && !__gxVerif->xfRegs[0x3F] && __gxVerif->verifyLevel >= __gxvWarnLev[0x38]) { + __GX_WARN(0x38); + } + + CheckCTGColors(); + + if (__gxVerif->xfRegs[0x3F] > 8 && __gxVerif->verifyLevel >= __gxvWarnLev[0x64]) { + __GX_WARNF(0x64, __gxVerif->xfRegs[0x3F], 8); + } + if (numRegularTextures > 8 && __gxVerif->verifyLevel >= __gxvWarnLev[0x65]) { + __GX_WARNF(0x65, numRegularTextures, 8); + } + if (numBumpmapTextures > 3 && __gxVerif->verifyLevel >= __gxvWarnLev[0x66]) { + __GX_WARNF(0x66, numBumpmapTextures, 3); + } + if (numColorTextures > 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x67]) { + __GX_WARNF(0x67, numColorTextures, 2); + } + if (numColor0Textures > 1 && __gxVerif->verifyLevel >= __gxvWarnLev[0x69]) { + __GX_WARNF(0x69, 0); + } + if (numColor1Textures > 1 && __gxVerif->verifyLevel >= __gxvWarnLev[0x69]) { + __GX_WARNF(0x69, 1); + } + + CheckVertexPacket(); + + for (i = 0; i < __gxVerif->xfRegs[0x3F]; i++) { + sprintf(registerName, "Texture %d settings", i); + CheckDirty(i + 0x1040, registerName); + } + + CheckSourceRows(); + CheckTextureOrder(); + if (numBumpmapTextures != 0) { + CheckBumpmapTextures(); + } + + CheckTextureTransformMatrices(); + if (numColorTextures != 0 && (u32)((BYTE3(__gxVerif->xfRegs[numRegularTextures + numBumpmapTextures + 64]) >> 4) & 7) != 2 && __gxVerif->verifyLevel >= __gxvWarnLev[0x68]) { + __GX_WARN(0x68U); + } + + CheckColor0(); + CheckColor1(); + CheckViewport(); + } +} + +static void CheckWarnings(void) { + if (__gxVerif->verifyLevel >= 1) { + CheckInputForms(); + } + + CheckClean(0x1000U, "Internal error register"); + CheckClean(0x1001U, "Internal diagnostic register"); + CheckClean(0x1002U, "Internal state register 0"); + CheckClean(0x1003U, "Internal state register 1"); + CheckClean(0x1004U, "Power savings register"); + + if (__gxVerif->verifyLevel >= 2) { + CheckFloatingPointRanges(); + } +} + +static void DumpXFRegisters(void) { + static u8 firstTime = 1; +} + +void __GXVerifyXF(void) { + if (internalDebug) { + DumpXFRegisters(); + } + InitializeXFVerifyData(); + CheckErrors(); + CheckWarnings(); + DumpCount++; +} + +#endif diff --git a/src/dolphin/gx/GXVerify.c b/src/dolphin/gx/GXVerify.c new file mode 100644 index 0000000000..7f07b8f6f4 --- /dev/null +++ b/src/dolphin/gx/GXVerify.c @@ -0,0 +1,368 @@ +#if DEBUG + +#include + +#include "__gx.h" + +static __GXVerifyData __gxVerifData; +struct __GXVerifyData* __gxVerif = &__gxVerifData; + +char* __gxvWarnings[125] = { + "Invalid Vertex Format. Normal count must be set to %s.", + "Texture size %ld not initialized.", + "Left edge of scissor rectangle is less than %d.", + "Top edge of scissor rectangle is less than %d.", + "Right edge of scissor rectangle is greater than %d in %s mode.", + "Bottom edge of scissor rectangle is greater than %d in %s mode.", + "%s value for subsample %d in pixel %ld is not 6 when single-sampling.", + "Indirect texture command for stage %ld is not set.", + "Invalid indirect texture request in TEV stage %ld.", + "Indirect matrix %ld requested in stage %d not set.", + "Requested indirect textures never initialized.", + "Indirect texture coordinate scales %d and %d not set.", + "Invalid texture coordinate specified for indirect stage %d.", + "Indirect texture feedback accumulation is on in TEV stage 0.", + "Indirect bump alpha is enabled in TEV stage 0.", + "Indirect vs. direct mask byte never set.", + "Texture reference never written for TEV stage %ld.", + "Invalid texture coordinate specified for TEV stage %ld.", + "Texture %ld is used as both indirect and direct.", + "Texture %ld not configured.", + "Base pointer for cached texture %ld is not specified.", + "TLUT for indexed texture %ld was never set up.", + "%s is not a power of 2 for mipmapped texture %ld.", + "%s is not GX_CLAMP for non-power-of-2 width in texture %ld.", + "Minification filter for texture %ld is not compatible with color index texture format.", + "Minimum LOD is greater than maximum LOD in texture %ld.", + "Maximum LOD is greater than image's maximum LOD for texture %ld.", + "LOD bias clamp shold be used with edge LOD for texture %ld.", + "Texture %ld does not meet requirements for anisotropic mipmapping.", + "Filters are not linear for field prediction in texture %ld.", + "Incomplete rounding mode configuration for texture %ld.", + "Rounding color indexed texture %ld.", + "Environment for TEV stage %ld not fully set up.", + "Invalid color channel selected in TEV stage %ld.", + "Argument %s selects null texture in TEV color stage %ld.", + "Argument %s selects null texture in TEV alpha stage %ld.", + "Color arg %s in TEV stage %ld accesses register %s, which may be dirty.", + "Alpha arg %s in TEV stage %ld accesses register %s, which may be dirty.", + "Color arg %s in TEV stage %ld accesses register %s, which was last unclamped. Possible wrap-around effect.", + "Alpha arg %s in TEV stage %ld accesses register %s, which was last unclamped. Possible wrap-around effect.", + "Z texturing enabled, but no Z offset specified.", + "Z texturing enabled, but no texture specified for final TEV stage.", + "Final TEV stage doesn't write color to register GX_TEVPREV.", + "Final TEV stage doesn't write alpha to register GX_TEVPREV.", + "Final TEV color stage has no clamping. Possible color wrap-around effect.", + "Final TEV alpha stage has no clamping. Possible alpha wrap-around effect.", + "Z buffering is before texture, but alpha compare operation is active.", + "PE blend and logicop are both on.", + "Selected pixel format does not support dithering.", + "Multisample enabled but pixel type is not RGB565.", + "Pixel type is RGB565 but multisample is not enabled.", + "Multisample locations for pixel %ld are not ordered correctly for antialias filter.", + "Invalid texgen_type %d for texture %d.", + "Register address 0x%04x uninitialized (%s).", + "Register address 0x%04x modified (%s), probably should not be.", + "Invalid combination of %d output color channels and %d color texgen textures.", + "Number of color channels and number of texgens are both zero.", + "Vertex packet does not contain position values.", + "Mismatched argument setting in vertex attribute. %s should be used with %s.", + "GXSetVtxAttrFmt: Normals only support signed types.", + "GXSetVtxAttrFmt: Number of fractional bits is fixed for normals. %s uses %d. Your setting will be ignored.", + "GXSetVtxAttrFmt: GX_F32 type doesn't refer the frac argument. Your setting will be ignored.", + "GXSetVtxAttrFmt: Colors don't refer the frac argument. Your setting will be ignored.", + "Invalid value (%d) for INVERTEXSPEC_REG.host_colors.", + "XF is not expecting host normals but cp is sending them.", + "XF is not expecting host normals, binormals and tangents but cp is sending them.", + "XF is expecting host normals but cp is not sending them.", + "XF is expecting host normals but cp is sending normals, binormals, and tangents.", + "XF is expecting host normals, binormals and tangents but cp is only sending normals.", + "This vertex format (Position + Matrix Indices only) is not supported.", + "VCD for GX_VA_CLR1 is activated though GX_VA_CLR0 is set to GX_NONE. GX_VA_CLR0 should be used first.", + "VCDs for input texture coordinates are not used sequentially from smaller IDs.", + "GX_TEXCOORD%d specifies source row of position, but this is not getting sent.", + "GX_TEXCOORD%d specifies source row of normal, but this is not getting sent.", + "GX_TEXCOORD%d specifies source row of color0, but color0 is not getting sent.", + "GX_TEXCOORD%d specifies source row of color1, but color1 is not getting sent.", + "GX_TEXCOORD%d specifies source row of binormal or tangent, but this is not getting sent.", + "GX_TEXCOORD%d specifies source row of input texture coordinate %d, but this is not getting sent.", + "GX_TEXCOORD%d is specifying an invalid source row of %d.", + "TexCoordGen types are out of order. GX_TG_MTX2x4/3x4 should come first (if any), followed by GX_TG_BUMP (if any), then GX_TG_SRTG (if any).", + "Bumpmap texgen is defined, which requires that binormals and tangents be transformed by a normal matrix, but current matrix index is set to an invalid value (%d) for normal transform.", + "GX_TEXCOORD%d (texgen type bumpmap) is referencing texture %d as a source texture, which is not of texgen type regular.", + "GX_TEXCOORD%d (texgen type bumpmap) using light source %d, but light's %c position is not defined.", + "GX_TEXCOORD%d is defined as texgen type bumpmap, but binormals and tangents are not getting sent.", + "Invalid regular texture number (%d)", + "Top edge of viewport (%f) is out of recommended range. It may cause incorrect clipping.", + "Bottom edge of viewport (%f) is out of recommended range. It may cause incorrect clipping.", + "Left edge of viewport (%f) is out of recommended range. It may cause incorrect clipping.", + "Right edge of viewport (%f) is out of recommended range. It may cause incorrect clipping.", + "Channel %s uses specular function (GX_AF_SPEC), but diffuse function is not GX_DF_NONE.", + "Channel %d performs lighting which requires a normal, but this is not getting sent.", + "Channel %d performs lighting which requires the normal to be transformed by a normal matrix, but current matrix index is (%d), which may be invalid.", + "%s has a value of %sinfinity (%08x), which is probably not intended.", + "%s has a value of NaN (%08x), which is probably not intended.", + "%s has a value of (%f 0x%08x), which might be unintentionally small.", + "%s has a value of (%f 0x%08x), which might be unintentionally large.", + "%d regular textures active, but MatrixIndex1 register (0x%04x) uninitialized.", + "gen_mode register not initialized.", + "Number of XF output textures does not match what downstream units are expecting.", + "Number of XF output colors does not match what downstream units are expecting.", + "Number of all texgens (%d) > max allowed %d.", + "Number of regular(2x4/3x4) type texgens (%d) > max allowed %d.", + "Number of bumpmap type texgens (%d) > max allowed %d.", + "Number of color texgens (%d) > max allowed %d.", + "First color texgen is not referencing COLOR0.", + "Color texgen from COLOR%d is used more than once.", + "Bumpmap texgen is defined, which requires the normal matrix values pointed by current matrix index (%d) to be loaded, however it may not be loaded yet.", + "GX_TEXCOORD%d requires the matrix values pointed by current texture matrix index %d (%d), however it may not be loaded yet.", + "GX_LIGHT%d is being referenced, however it may not be loaded yet.", + "Channel %d performs lighting which requires the normal matrix values pointed to by the current matrix index (%d), however these values may not be loaded yet.", + "Position matrix values pointed to by the current matrix index must be loaded, however they may not be loaded yet.", + "Address 0x%04x is uninitialized.", + "Register (0x%04x) (%s) is not initialized.", + "Display list contains invalid command.", + "Nested display list.", + "XF is not expecting host colors but cp is sending some.", + "XF is expecting a host color but cp is not sending one.", + "XF is expecting a single host color but cp is sending two.", + "XF is expecting two host colors but cp is not sending first color.", + "XF is expecting two host colors but cp is not sending second color.", + "Invalid number of output colors, %d.", + "Regular texture %d specifying a source row of %d which only has 2 elements, but an input form of ABC1.", + "Output XF colors or color textures enabled, but register address 0x%04x uninitialized (%s).", + "Output XF colors or color textures enabled, COLOR%dCNTRL_REG.material_src == REGISTER, but Material %d register (0x%04x) is not initialized.", + "Output XF colors or color textures enabled, COLOR%dCNTRL_REG.ambient_src == REGISTER, but Ambient %d register (0x%04x) is not initialized." +}; + +GXWarningLevel __gxvWarnLev[125] = { + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + 4, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + 4, + 4, + GX_WARN_SEVERE, + GX_WARN_ALL, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + 4, + 4, + 4, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_ALL, + GX_WARN_ALL, + 4, + GX_WARN_SEVERE, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_ALL, + GX_WARN_ALL, + GX_WARN_MEDIUM, + 4, + 4, + 4, + 4, + GX_WARN_ALL, + 4, + 4, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_ALL, + GX_WARN_ALL, + GX_WARN_ALL, + 4, + 4, + 4, + 4, + 4, + 4, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + 4, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + 4, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_ALL, + GX_WARN_ALL, + GX_WARN_SEVERE, + 4, + 4, + 4, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_MEDIUM, + GX_WARN_SEVERE, + GX_WARN_SEVERE, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, +}; + +char __gxvDummyStr[256]; + +static void __GXVerifyGlobal(void) {} + +static void __GXVerifyCP(GXVtxFmt fmt) { + u32 nrmCnt = GET_REG_FIELD(__GXData->vatA[fmt], 1, 9); + + if (__gxVerif->verifyLevel >= GX_WARN_SEVERE) { + if (__GXData->hasNrms && nrmCnt != 0) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_INVALID_VTX_FMT]) { + __GX_WARNF(GXWARN_INVALID_VTX_FMT, "GX_NRM_XYZ"); + } + } + else if (__GXData->hasBiNrms && nrmCnt != 1) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_INVALID_VTX_FMT]) { + __GX_WARNF(GXWARN_INVALID_VTX_FMT, "GX_NRM_NBT or GX_NRM_NBT3"); + } + } + } +} + +void __GXVerifyState(GXVtxFmt vtxfmt) { + if (__gxVerif->verifyLevel != GX_WARN_NONE) { + __GXVerifyGlobal(); + __GXVerifyCP(vtxfmt); + __GXVerifyXF(); + __GXVerifySU(); + __GXVerifyBUMP(); + __GXVerifyTEX(); + __GXVerifyTEV(); + __GXVerifyPE(); + } +} + +void __GXVerifyVATImm(GXAttr attr, GXCompCnt cnt, GXCompType type, u8 frac) { + if (__gxVerif->verifyLevel != GX_WARN_NONE) { + if (attr == GX_VA_CLR0 || attr == GX_VA_CLR1) { + switch (type) { + case GX_RGB565: + case GX_RGB8: + case GX_RGBX8: + if (cnt != GX_CLR_RGB && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_MISMATCH]) { + __GX_WARNF(GXWARN_VAT_MISMATCH, "RGB format type", "GX_CLR_RGB"); + } + break; + case GX_RGBA4: + case GX_RGBA6: + case GX_RGBA8: + if (cnt != GX_CLR_RGBA && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_MISMATCH]) { + __GX_WARNF(GXWARN_VAT_MISMATCH, "RGBA format type", "GX_CLR_RGBA"); + } + break; + } + } + + if (frac != 0) { + if (attr == GX_VA_CLR0 || attr == GX_VA_CLR1) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_CLR_FRAC]) { + __GX_WARN(GXWARN_VAT_CLR_FRAC); + } + } else if (type == GX_F32) { + if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_F32_FRAC]) { + __GX_WARN(GXWARN_VAT_F32_FRAC); + } + } + } + + if (attr == GX_VA_NRM || attr == GX_VA_NBT) { + switch (type) { + case GX_S8: + if (frac != 6 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_NRM_FRAC]) { + __GX_WARNF(GXWARN_VAT_NRM_FRAC, "GX_S8", 6); + } + break; + case GX_S16: + if (frac != 14 && __gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_NRM_FRAC]) { + __GX_WARNF(GXWARN_VAT_NRM_FRAC, "GX_S16", 14); + } + break; + case GX_F32: + break; + default: + if (__gxVerif->verifyLevel >= __gxvWarnLev[GXWARN_VAT_NRM_TYPE]) { + __GX_WARN(GXWARN_VAT_NRM_TYPE); + } + break; + } + } + } +} + +void GXSetVerifyLevel(GXWarningLevel level) { + __gxVerif->verifyLevel = level; +} + +GXVerifyCallback GXSetVerifyCallback(GXVerifyCallback cb) { + GXVerifyCallback old_cb = __gxVerif->cb; + + __gxVerif->cb = cb; + return old_cb; +} + +#endif // DEBUG diff --git a/src/dolphin/gx/GXVert.c b/src/dolphin/gx/GXVert.c new file mode 100644 index 0000000000..df50141521 --- /dev/null +++ b/src/dolphin/gx/GXVert.c @@ -0,0 +1,86 @@ +#if DEBUG +#include + +#include "__gx.h" + +#define FUNC_1PARAM(name, T) \ +void name##1##T(T x) { GXWGFifo.T = x; } + +#define FUNC_2PARAM(name, T) \ +void name##2##T(T x, T y) { GXWGFifo.T = x; GXWGFifo.T = y; } + +#define FUNC_3PARAM(name, T) \ +void name##3##T(T x, T y, T z) { GXWGFifo.T = x; GXWGFifo.T = y; GXWGFifo.T = z; } + +#define FUNC_4PARAM(name, T) \ +void name##4##T(T x, T y, T z, T w) { GXWGFifo.T = x; GXWGFifo.T = y; GXWGFifo.T = z; GXWGFifo.T = w; } + +#define FUNC_INDEX8(name) \ +void name##1x8(u8 x) { GXWGFifo.u8 = x; } + +#define FUNC_INDEX16(name) \ +void name##1x16(u16 x) { GXWGFifo.u16 = x; } + +// GXCmd +FUNC_1PARAM(GXCmd, u8) +FUNC_1PARAM(GXCmd, u16) +FUNC_1PARAM(GXCmd, u32) + +// GXParam +FUNC_1PARAM(GXParam, u8) +FUNC_1PARAM(GXParam, u16) +FUNC_1PARAM(GXParam, u32) +FUNC_1PARAM(GXParam, s8) +FUNC_1PARAM(GXParam, s16) +FUNC_1PARAM(GXParam, s32) +FUNC_1PARAM(GXParam, f32) +FUNC_3PARAM(GXParam, f32) +FUNC_4PARAM(GXParam, f32) + +// GXPosition +FUNC_3PARAM(GXPosition, f32) +FUNC_3PARAM(GXPosition, u8) +FUNC_3PARAM(GXPosition, s8) +FUNC_3PARAM(GXPosition, u16) +FUNC_3PARAM(GXPosition, s16) +FUNC_2PARAM(GXPosition, f32) +FUNC_2PARAM(GXPosition, u8) +FUNC_2PARAM(GXPosition, s8) +FUNC_2PARAM(GXPosition, u16) +FUNC_2PARAM(GXPosition, s16) +FUNC_INDEX16(GXPosition) +FUNC_INDEX8(GXPosition) + +// GXNormal +FUNC_3PARAM(GXNormal, f32) +FUNC_3PARAM(GXNormal, s16) +FUNC_3PARAM(GXNormal, s8) +FUNC_INDEX16(GXNormal) +FUNC_INDEX8(GXNormal) + +// GXColor +FUNC_4PARAM(GXColor, u8) +FUNC_1PARAM(GXColor, u32) +FUNC_3PARAM(GXColor, u8) +FUNC_1PARAM(GXColor, u16) +FUNC_INDEX16(GXColor) +FUNC_INDEX8(GXColor) + +// GXTexCoord +FUNC_2PARAM(GXTexCoord, f32) +FUNC_2PARAM(GXTexCoord, s16) +FUNC_2PARAM(GXTexCoord, u16) +FUNC_2PARAM(GXTexCoord, s8) +FUNC_2PARAM(GXTexCoord, u8) +FUNC_1PARAM(GXTexCoord, f32) +FUNC_1PARAM(GXTexCoord, s16) +FUNC_1PARAM(GXTexCoord, u16) +FUNC_1PARAM(GXTexCoord, s8) +FUNC_1PARAM(GXTexCoord, u8) +FUNC_INDEX16(GXTexCoord) +FUNC_INDEX8(GXTexCoord) + +// GXMatrixIndex +FUNC_1PARAM(GXMatrixIndex, u8) + +#endif // DEBUG diff --git a/src/dolphin/gx/__gx.h b/src/dolphin/gx/__gx.h new file mode 100644 index 0000000000..1e065bbb2f --- /dev/null +++ b/src/dolphin/gx/__gx.h @@ -0,0 +1,592 @@ +#ifndef _DOLPHIN_GX_INTERNAL_H_ +#define _DOLPHIN_GX_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// FIFO WRITE + +#define GX_WRITE_U8(ub) \ + GXWGFifo.u8 = (u8)(ub) + +#define GX_WRITE_U16(us) \ + GXWGFifo.u16 = (u16)(us) + +#define GX_WRITE_U32(ui) \ + GXWGFifo.u32 = (u32)(ui) + +#define GX_WRITE_F32(f) \ + GXWGFifo.f32 = (f32)(f); + + +// REG VERIF + +#if DEBUG +#define VERIF_XF_REG(addr, value) \ +do { \ + s32 regAddr = (addr); \ + if (regAddr >= 0 && regAddr < 0x50) { \ + __gxVerif->xfRegs[regAddr] = (value); \ + __gxVerif->xfRegsDirty[regAddr] = 1; \ + } \ +} while (0) + +#define VERIF_XF_REG_alt(addr, value) \ +do { \ + s32 xfAddr = (addr); \ + if (xfAddr >= 0 && xfAddr < 0x50) { \ + __gxVerif->xfRegs[xfAddr] = (value); \ + __gxVerif->xfRegsDirty[xfAddr] = 1; \ + } \ +} while (0) + +#define VERIF_RAS_REG(value) (__gxVerif->rasRegs[((value) & 0xFF000000) >> 24] = value) + +#define VERIF_MTXLIGHT(addr, data) \ +do { \ + s32 xfAddr; \ + if (addr < 0x400U) { \ + __gxVerif->xfMtx[addr] = data; \ + __gxVerif->xfMtxDirty[addr] = 1; \ + } else if (addr < 0x500U) { \ + xfAddr = addr - 0x400; \ + __gxVerif->xfNrm[xfAddr] = data; \ + __gxVerif->xfNrmDirty[xfAddr] = 1; \ + } else if (addr < 0x600U) { \ + xfAddr = addr - 0x500; \ + __gxVerif->xfDMtx[xfAddr] = data; \ + __gxVerif->xfDMtxDirty[xfAddr] = 1; \ + } else if (addr < 0x680U) { \ + xfAddr = addr - 0x600; \ + __gxVerif->xfLight[xfAddr] = data; \ + __gxVerif->xfLightDirty[xfAddr] = 1; \ + } else { \ + xfAddr = addr - 0x1000; \ + if ((xfAddr >= 0) && (xfAddr < 0x50)) { \ + __gxVerif->xfRegs[xfAddr] = data; \ + __gxVerif->xfRegsDirty[xfAddr] = 1; \ + } \ + } \ +} while (0) +#else +#define VERIF_XF_REG(addr, value) ((void)0) +#define VERIF_XF_REG_alt(addr, value) ((void)0) +#define VERIF_RAS_REG(value) ((void)0) +#endif + +// WRITE REG + +#define GX_WRITE_XF_REG(addr, value) \ +do { \ + GX_WRITE_U8(0x10); \ + GX_WRITE_U32(0x1000 + (addr)); \ + GX_WRITE_U32(value); \ + VERIF_XF_REG(addr, value); \ +} while (0) + +#if DEBUG +#define GX_WRITE_XF_REG_2(addr, value) \ +do { \ + u32 xfData = (value); &xfData; \ + GX_WRITE_U32(value); \ + VERIF_XF_REG_alt(addr, xfData); \ +} while (0) + +#define GX_WRITE_XF_REG_F(addr, value) \ +do { \ + f32 xfData = (value); \ + GX_WRITE_F32(value); \ + VERIF_XF_REG_alt(addr, *(u32 *)&xfData); \ +} while (0) +#else +#define GX_WRITE_XF_REG_2(addr, value) \ +do { \ + GX_WRITE_U32(value); \ +} while (0) + +#define GX_WRITE_XF_REG_F(addr, value) \ +do { \ + GX_WRITE_F32(value); \ +} while (0) +#endif + +#define GX_WRITE_RAS_REG(value) \ +do { \ + GX_WRITE_U8(0x61); \ + GX_WRITE_U32(value); \ + VERIF_RAS_REG(value); \ +} while (0) + +#ifdef DEBUG +#define GX_WRITE_SOME_REG2(a, b, c, addr) \ +do { \ + long regAddr; \ + GX_WRITE_U8(a); \ + GX_WRITE_U8(b); \ + GX_WRITE_U32(c); \ + regAddr = addr; \ + if (regAddr >= 0 && regAddr < 4) { \ + __GXData->indexBase[regAddr] = c; \ + } \ +} while (0) +#else +#define GX_WRITE_SOME_REG2(a, b, c, addr) \ +do { \ + GX_WRITE_U8(a); \ + GX_WRITE_U8(b); \ + GX_WRITE_U32(c); \ +} while (0) +#endif + +#ifdef DEBUG +#define GX_WRITE_SOME_REG3(a, b, c, addr) \ +do { \ + long regAddr; \ + GX_WRITE_U8(a); \ + GX_WRITE_U8(b); \ + GX_WRITE_U32(c); \ + regAddr = addr; \ + if (regAddr >= 0 && regAddr < 4) { \ + __GXData->indexStride[regAddr] = c; \ + } \ +} while (0) +#else +#define GX_WRITE_SOME_REG3(a, b, c, addr) \ +do { \ + GX_WRITE_U8(a); \ + GX_WRITE_U8(b); \ + GX_WRITE_U32(c); \ +} while (0) +#endif + +#define GX_WRITE_SOME_REG4(a, b, c, addr) \ +do { \ + long regAddr; \ + GX_WRITE_U8(a); \ + GX_WRITE_U8(b); \ + GX_WRITE_U32(c); \ + regAddr = addr; \ +} while (0) + +// REG MACROS + +#define GET_REG_FIELD(reg, size, shift) ((int)((reg) >> (shift)) & ((1 << (size)) - 1)) + +// TODO: reconcile reg macro differences +// this one is needed to match non GX libs +#define OLD_SET_REG_FIELD(line, reg, size, shift, val) \ +do { \ + ASSERTMSGLINE(line, ((u32)(val) & ~((1 << (size)) - 1)) == 0, "GX Internal: Register field out of range"); \ + (reg) = ((u32)(reg) & ~(((1 << (size)) - 1) << (shift))) | ((u32)(val) << (shift)); \ +} while (0) + +// above doesn't seem to work with GX, only can get it to work with this +#define SET_REG_FIELD(line, reg, size, shift, val) \ +do { \ + ASSERTMSGLINE(line, ((u32)(val) & ~((1 << (size)) - 1)) == 0, "GX Internal: Register field out of range"); \ + (reg) = ((u32)__rlwimi((u32)(reg), (val), (shift), 32 - (shift) - (size), 31 - (shift))); \ +} while (0) + +#define CHECK_GXBEGIN(line, name) ASSERTMSGLINE(line, !__GXinBegin, "'" name "' is not allowed between GXBegin/GXEnd") + +/* GXAttr */ +void __GXSetVCD(void); +void __GXSetVAT(void); + +/* GXBump */ +void __GXUpdateBPMask(void); +void __GXFlushTextureState(void); + +/* GXFifo */ +// GXFifoObj private data +typedef struct __GXFifoObj { + u8* base; + u8* top; + u32 size; + u32 hiWatermark; + u32 loWatermark; + void* rdPtr; + void* wrPtr; + s32 count; + u8 bind_cpu; + u8 bind_gp; +} __GXFifoObj; + +void __GXSaveCPUFifoAux(__GXFifoObj* realFifo); +void __GXFifoInit(void); +void __GXInsaneWatermark(void); +void __GXCleanGPFifo(void); + +/* GXGeometry */ +void __GXSetDirtyState(void); +void __GXSendFlushPrim(void); +void __GXSetGenMode(void); + +/* GXInit */ +void __GXInitGX(); +void __GXInitRevisionBits(void); + +typedef struct __GXData_struct { + u16 vNumNot; + u16 bpSentNot; + u16 vNum; + u16 vLim; + u32 cpEnable; + u32 cpStatus; + u32 cpClr; + u32 vcdLo; + u32 vcdHi; + u32 vatA[8]; + u32 vatB[8]; + u32 vatC[8]; + u32 lpSize; + u32 matIdxA; + u32 matIdxB; + u32 indexBase[4]; + u32 indexStride[4]; + u32 ambColor[2]; + u32 matColor[2]; + u32 suTs0[8]; + u32 suTs1[8]; + u32 suScis0; + u32 suScis1; + u32 tref[8]; + u32 iref; + u32 bpMask; + u32 IndTexScale0; + u32 IndTexScale1; + u32 tevc[16]; + u32 teva[16]; + u32 tevKsel[8]; + u32 cmode0; + u32 cmode1; + u32 zmode; + u32 peCtrl; + u32 cpDispSrc; + u32 cpDispSize; + u32 cpDispStride; + u32 cpDisp; + u32 cpTexSrc; + u32 cpTexSize; + u32 cpTexStride; + u32 cpTex; + u8 cpTexZ; + u32 genMode; + GXTexRegion TexRegions0[8]; + GXTexRegion TexRegions1[8]; + GXTexRegion TexRegions2[8]; + GXTlutRegion TlutRegions[20]; + GXTexRegion* (*texRegionCallback)(GXTexObj*, GXTexMapID); + GXTlutRegion* (*tlutRegionCallback)(u32); + GXAttrType nrmType; + u8 hasNrms; + u8 hasBiNrms; + u32 projType; + f32 projMtx[6]; + f32 vpLeft; + f32 vpTop; + f32 vpWd; + f32 vpHt; + f32 vpNearz; + f32 vpFarz; + f32 zOffset; + f32 zScale; + u32 tImage0[8]; + u32 tMode0[8]; + u32 texmapId[16]; + u32 tcsManEnab; + u32 tevTcEnab; + GXPerf0 perf0; + GXPerf1 perf1; + u32 perfSel; + u8 inDispList; + u8 dlSaveContext; + u8 abtWaitPECopy; + u8 dirtyVAT; + u32 dirtyState; +} GXData; + +extern GXData* const __GXData; +extern void* __memReg; +extern void* __peReg; +extern void* __cpReg; +extern void* __piReg; + +#if DEBUG +extern GXBool __GXinBegin; +#endif + +#define GX_GET_MEM_REG(offset) (*(volatile u16*)((volatile u16*)(__memReg) + (offset))) +#define GX_GET_CP_REG(offset) (*(volatile u16*)((volatile u16*)(__cpReg) + (offset))) +#define GX_GET_PE_REG(offset) (*(volatile u16*)((volatile u16*)(__peReg) + (offset))) +#define GX_GET_PI_REG(offset) (*(volatile u32*)((volatile u32*)(__piReg) + (offset))) + +#define GX_SET_MEM_REG(offset, val) (*(volatile u16*)((volatile u16*)(__memReg) + (offset)) = val) +#define GX_SET_CP_REG(offset, val) (*(volatile u16*)((volatile u16*)(__cpReg) + (offset)) = val) +#define GX_SET_PE_REG(offset, val) (*(volatile u16*)((volatile u16*)(__peReg) + (offset)) = val) +#define GX_SET_PI_REG(offset, val) (*(volatile u32*)((volatile u32*)(__piReg) + (offset)) = val) + +/* GXMisc */ +void __GXBypass(u32 reg); +u16 __GXReadPEReg(u32 reg); +void __GXPEInit(void); +void __GXAbort(); + +/* GXPerf */ +void __GXSetBWDials(u16 cpDial, u16 tcDial, u16 peDial, u16 cpuRdDial, u16 cpuWrDial); + +static inline u32 __GXReadCPCounterU32(u32 regAddrL, u32 regAddrH) { + u32 ctrH0; + u32 ctrH1; + u32 ctrL; + + ctrH0 = GX_GET_CP_REG(regAddrH); + + do { + ctrH1 = ctrH0; + ctrL = GX_GET_CP_REG(regAddrL); + ctrH0 = GX_GET_CP_REG(regAddrH); + } while (ctrH0 != ctrH1); + + return (ctrH0 << 0x10) | ctrL; +} + +static inline u32 __GXReadMEMCounterU32(u32 regAddrL, u32 regAddrH) { + u32 ctrH0; + u32 ctrH1; + u32 ctrL; + + ctrH0 = GX_GET_MEM_REG(regAddrH); + + do { + ctrH1 = ctrH0; + ctrL = GX_GET_MEM_REG(regAddrL); + ctrH0 = GX_GET_MEM_REG(regAddrH); + } while (ctrH0 != ctrH1); + + return (ctrH0 << 0x10) | ctrL; +} + +static inline u32 __GXReadPECounterU32(u32 regAddrL, u32 regAddrH) { + u32 ctrH0; + u32 ctrH1; + u32 ctrL; + + ctrH0 = GX_GET_PE_REG(regAddrH); + + do { + ctrH1 = ctrH0; + ctrL = GX_GET_PE_REG(regAddrL); + ctrH0 = GX_GET_PE_REG(regAddrH); + } while (ctrH0 != ctrH1); + + return (ctrH0 << 0x10) | ctrL; +} + +/* GXSave */ +void __GXShadowDispList(void* list, u32 nbytes); +void __GXShadowIndexState(u32 idx_reg, u32 reg_data); +void __GXPrintShadowState(void); + +/* GXStubs */ +void __GXSetRange(f32 nearz, f32 fgSideX); + +/* GXTexture */ +void __GetImageTileCount(GXTexFmt fmt, u16 wd, u16 ht, u32* rowTiles, u32* colTiles, u32* cmpTiles); +void __GXSetSUTexRegs(void); +void __GXGetSUTexSize(GXTexCoordID coord, u16* width, u16* height); +void __GXSetTmemConfig(u32 config); + +/* GXTransform */ +void __GXSetMatrixIndex(GXAttr matIdxAttr); +void __GXSetProjection(void); +void __GXSetViewport(); + + +/* GXVerifRAS */ +void __GXVerifySU(void); +void __GXVerifyBUMP(void); +void __GXVerifyTEX(void); +void __GXVerifyTEV(void); +void __GXVerifyPE(void); + +/* GXVerif */ +typedef enum { + GXWARN_INVALID_VTX_FMT = 0, + GXWARN_TEX_SIZE_INIT = 1, + GXWARN_SCISSOR_RECT_LEFT = 2, + GXWARN_SCISSOR_RECT_TOP = 3, + GXWARN_SCISSOR_RECT_RIGHT = 4, + GXWARN_SCISSOR_RECT_BOT = 5, + GXWARN_SAMPLE_VALUE = 6, + GXWARN_BUMP_CMD = 7, + GXWARN_INVALID_INDIRECT = 8, + GXWARN_INDIRECT_MTX = 9, + GXWARN_IND_TEX_NO_INIT = 10, + GXWARN_IND_TEX_NO_SCALE = 11, + GXWARN_IND_TEX_BUMP = 12, + GXWARN_BUMP_ACCUMULATION = 13, + GXWARN_BUMP_ALPHA_EN = 14, + GXWARN_IND_DIR_MASK = 15, + GXWARN_TEV_TEX_REF = 16, + GXWARN_TEV_INV_TEX_COORD = 17, + GXWARN_IND_DIR_BOTH = 18, + GXWARN_TEX_CONFIG = 19, + GXWARN_TEX_BASE = 20, + GXWARN_TLUT_CONFIG = 21, + GXWARN_TEX_POW2 = 22, + GXWARN_TEX_CLAMP = 23, + GXWARN_TEX_MIN_FILT = 24, + GXWARN_MIN_LOD = 25, + GXWARN_MAX_LOD = 26, + GXWARN_DIAG_LOD = 27, + GXWARN_TEX_ANISO = 28, + GXWARN_TEX_FIELD = 29, + GXWARN_TEX_RND_FP = 30, + GXWARN_RND_CLR_INDX = 31, + GXWARN_TEV_ENV = 32, + GXWARN_TEV_INV_CHAN = 33, + GXWARN_TEV_NULL_TEX = 34, + GXWARN_TEV_NULL_TEX_A = 35, + GXWARN_TEV_DIRTY_REG = 36, + GXWARN_TEV_DIRTY_REG_A = 37, + GXWARN_TEV_CLR_CLAMP = 38, + GXWARN_TEV_A_CLAMP = 39, + GXWARN_ZTEX_OFFSET = 40, + GXWARN_ZTEX_INVALID = 41, + GXWARN_TEV_LAST_CLR = 42, + GXWARN_TEV_LAST_A = 43, + GXWARN_TEV_LAST_CLR_WRAP = 44, + GXWARN_TEV_LAST_A_WRAP = 45, + GXWARN_Z_BEFORE_T_A = 46, + GXWARN_BLEND_LOGICOP = 47, + GXWARN_DITHER_MODE = 48, + GXWARN_MULTISAMP0 = 49, + GXWARN_MULTISAMP1 = 50, + GXWARN_SAMP_ORDER = 51, + GXWARN_INVALID_TG_TYPE = 52, + GXWARN_XF_CTRL_UNINIT = 53, + GXWARN_XF_CTRL_INIT = 54, + GXWARN_INV_COLOR_TG_COMB = 55, + GXWARN_XF_NO_CLR_TEX = 56, + GXWARN_VTX_NO_GEOM = 57, + GXWARN_VAT_MISMATCH = 58, + GXWARN_VAT_NRM_TYPE = 59, + GXWARN_VAT_NRM_FRAC = 60, + GXWARN_VAT_F32_FRAC = 61, + GXWARN_VAT_CLR_FRAC = 62, + GXWARN_INV_IVS_CLR = 63, + GXWARN_NRM_XF0_CP1 = 64, + GXWARN_NRM_XF0_CP3 = 65, + GXWARN_NRM_XF1_CP0 = 66, + GXWARN_NRM_XF1_CP3 = 67, + GXWARN_NRM_XF3_CP1 = 68, + GXWARN_VCD_FMT_UNSUP = 69, + GXWARN_VCD_CLR_ORDER = 70, + GXWARN_VCD_TEX_ORDER = 71, + GXWARN_TEX_SRC_NPOS = 72, + GXWARN_TEX_SRC_NNRM = 73, + GXWARN_TEX_SRC_NCLR0 = 74, + GXWARN_TEX_SRC_NCLR1 = 75, + GXWARN_TEX_SRC_NNBT = 76, + GXWARN_TEX_SRC_NTEX = 77, + GXWARN_INV_TEX_SRC = 78, + GXWARN_INV_TG_ORDER = 79, + GXWARN_BM_INV_MTX_NDX = 80, + GXWARN_BM_INV_TEX = 81, + GXWARN_BM_INV_LIT_POS = 82, + GXWARN_BM_NO_NBT = 83, + GXWARN_INV_TEX_NUM = 84, + GXWARN_VIEWPORT_TOP = 85, + GXWARN_VIEWPORT_BOTTOM = 86, + GXWARN_VIEWPORT_LEFT = 87, + GXWARN_VIEWPORT_RIGHT = 88, + GXWARN_CLR_INV_SPEC = 89, + GXWARN_CLR_NO_NRM = 90, + GXWARN_CLR_INV_MTX_NDX = 91, + GXWARN_VAL_INFINITY = 92, + GXWARN_VAL_NAN = 93, + GXWARN_VAL_SMALL = 94, + GXWARN_VAL_LARGE = 95, + GXWARN_MTX1_UNINIT = 96, + GXWARN_GM_UNINIT = 97, + GXWARN_TEX_XFN_SUM = 98, + GXWARN_CLR_XFN_SUM = 99, + GXWARN_INV_NUM_ANY_TEX = 100, + GXWARN_INV_NUM_REG_TEX = 101, + GXWARN_INV_NUM_BM_TEX = 102, + GXWARN_INV_NUM_CLR_TEX = 103, + GXWARN_INV_CLR_TEX = 104, + GXWARN_DUP_CLR_TEX = 105, + GXWARN_BM_INV_MTX_VAL = 106, + GXWARN_TEX_INV_MTX_VAL = 107, + GXWARN_LIT_INV_REG = 108, + GXWARN_CLR_INV_MTX_VAL = 109, + GXWARN_INV_MTX_VAL = 110, + GXWARN_ADDR_UNINIT = 111, + GXWARN_REG_UNINIT = 112, + GXWARN_DL_INV_CMD = 113, + GXWARN_DL_NESTED = 114, + GXWARN_CLR_XF0_CP1 = 115, + GXWARN_CLR_XF1_CP0 = 116, + GXWARN_CLR_XF1_CP2 = 117, + GXWARN_CLR_XF2_CPN1 = 118, + GXWARN_CLR_XF2_CPN2 = 119, + GXWARN_INV_NUM_COLORS = 120, + GXWARN_INV_TG_SRC = 121, + GXWARN_CLR_ADDR_UNINIT = 122, + GXWARN_CLR_MAT_UNINIT = 123, + GXWARN_CLR_AMB_UNINIT = 124, + GXWARN_MAX = 125, +} GXWarnID; + +#define __GX_WARN(id) (__gxVerif->cb(__gxvWarnLev[(id)], (id), __gxvWarnings[(id)])) +#define __GX_WARNF(id, ...) \ +do { \ + sprintf(__gxvDummyStr, __gxvWarnings[(id)], __VA_ARGS__); \ + __gxVerif->cb(__gxvWarnLev[(id)], (id), __gxvDummyStr); \ +} while (0) + +#define __GX_WARN2(level, id) (__gxVerif->cb(level, (id), __gxvWarnings[(id)])) +#define __GX_WARN2F(level, id, ...) \ +do { \ + sprintf(__gxvDummyStr, __gxvWarnings[(id)], __VA_ARGS__); \ + __gxVerif->cb(level, (id), __gxvDummyStr); \ +} while (0) + +typedef struct __GXVerifyData { + GXVerifyCallback cb; + GXWarningLevel verifyLevel; + u32 xfRegs[80]; + u32 xfMtx[256]; + u32 xfNrm[96]; + u32 xfDMtx[256]; + u32 xfLight[128]; + u32 rasRegs[256]; + u8 xfRegsDirty[80]; + u8 xfMtxDirty[256]; + u8 xfNrmDirty[96]; + u8 xfDMtxDirty[256]; + u8 xfLightDirty[128]; +} __GXVerifyData; + +extern __GXVerifyData* __gxVerif; +extern char* __gxvWarnings[125]; +extern char __gxvDummyStr[256]; +extern GXWarningLevel __gxvWarnLev[]; + +void __GXVerifyGlobal(void); +void __GXVerifyCP(GXVtxFmt fmt); +void __GXVerifyState(GXVtxFmt vtxfmt); + +/* GXVerifXF */ +void __GXVerifyXF(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dolphin/hio/hio.c b/src/dolphin/hio/hio.c new file mode 100644 index 0000000000..aa146d5c90 --- /dev/null +++ b/src/dolphin/hio/hio.c @@ -0,0 +1,409 @@ +#include +#include +#include +#include + +static u32 Dev; +#define HIO_DEV Dev + +#ifdef DEBUG +const char* __HIOVersion = "<< Dolphin SDK - HIO\tdebug build: Apr 5 2004 03:57:05 (0x2301) >>"; +#else +const char* __HIOVersion = "<< Dolphin SDK - HIO\trelease build: Apr 5 2004 04:15:47 (0x2301) >>"; +#endif + +static char __HIODigest1[71] = "\"HIO library - Copyright (C) 2000-2002 Nintendo. All rights reserved.\""; + +#ifdef DEBUG +static char __HIODigest2[34] = "\"HIO built: Apr 5 2004 03:57:05\""; +#else +static char __HIODigest2[34] = "\"HIO built: Apr 5 2004 04:15:47\""; +#endif + +static s32 Chan = -1; +static HIOCallback ExiCallback; +static HIOCallback TxCallback; +static HIOCallback RxCallback; + +static void ExtHandler(s32 chan, OSContext *context) { + Chan = -1; + HIO_DEV = 0; + + if (chan < 2 && HIO_DEV == 0) { + EXISetExiCallback(chan, NULL); + } else if (chan == 0 && HIO_DEV == 2) { + EXISetExiCallback(2, NULL); + } +} + +static void ExiHandler(s32 chan, OSContext* context) { + if (ExiCallback) { + ExiCallback(); + } +} + +static void DbgHandler(__OSInterrupt interrupt, OSContext *context) { + OSContext exceptionContext; + + __PIRegs[0] = 0x1000; + if (ExiCallback) { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + ExiCallback(); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } +} + +static void TxHandler(s32 chan, OSContext* context) { + EXIDeselect(Chan); + EXIUnlock(Chan); + if (TxCallback) { + TxCallback(); + } +} + +static void RxHandler(s32 chan, OSContext* context) { + EXIDeselect(Chan); + EXIUnlock(Chan); + if (RxCallback) { + RxCallback(); + } +} + +BOOL HIOEnumDevices(HIOEnumCallback callback) { + s32 chan; + u32 id; + + if (Chan != -1 || callback == NULL) { + return 0; + } + + HIO_DEV = 0; + for (chan = 0; chan <= 2; chan++) { + if (chan < 2) { + while (EXIProbeEx(chan) == 0) {} + } + + if (EXIGetID(chan, HIO_DEV, &id) != 0 && id - 0x1010000 == 0 && !callback(chan)) { + return 1; + } + } + + return 1; +} + +static inline int CheckConsoleType() { + if (__OSGetDIConfig() == 0xFF) { + if (((OSGetConsoleType() & 0xF0000000) + 0xE0000000) == 0) { + return 1; + } + + switch (__OSDeviceCode) { + case 0x8200: + return 1; + } + + return 0; + } + + return 1; +} + +BOOL HIOInit(s32 chan, HIOCallback callback) { + int err; + u32 cmd; + u32 id; + + while (__OSDeviceCode == 0) {} + + if (CheckConsoleType() == 0) { + Chan = -1; + HIO_DEV = 0; + OSReport("%s\n", __HIODigest1, __HIODigest2); + return 0; + } + + if (Chan != -1) { + return 1; + } + + Chan = chan; + ExiCallback = callback; + TxCallback = NULL; + RxCallback = NULL; + + if (chan < 2 && HIO_DEV == 0) { + while (EXIProbeEx(Chan) == 0) {} + + if (EXIAttach(Chan, ExtHandler) == 0) { + Chan = -1; + HIO_DEV = 0; + return 0; + } + } + + if (EXILock(Chan, HIO_DEV, 0) == 0) { + EXIDetach(Chan); + Chan = -1; + HIO_DEV = 0; + return 0; + } + + if (EXISelect(Chan, HIO_DEV, 0) == 0) { + EXIUnlock(Chan); + EXIDetach(Chan); + Chan = -1; + HIO_DEV = 0; + return 0; + } + + cmd = 0; + err = 0; + err |= !EXIImm(Chan, &cmd, 2, 1, 0); + err |= !EXISync(Chan); + err |= !EXIImm(Chan, &id, 4, 0, 0); + err |= !EXISync(Chan); + err |= !EXIDeselect(Chan); + EXIUnlock(Chan); + + if (err != 0 || id != 0x1010000) { + if (chan < 2 && HIO_DEV == 0) { + EXIDetach(Chan); + } + EXIUnlock(Chan); + Chan = -1; + HIO_DEV = 0; + return 0; + } + + if (ExiCallback) { + if (chan < 2) { + if (HIO_DEV == 0) { + EXISetExiCallback(Chan, ExiHandler); + } else { + ASSERTLINE(331, HIO_DEV == 2); + EXISetExiCallback(2, ExiHandler); + } + } else { + __OSSetInterruptHandler(0x19, DbgHandler); + __OSUnmaskInterrupts(0x40); + } + } + + OSRegisterVersion(__HIOVersion); + return 1; +} + +BOOL HIOInitEx(s32 chan, u32 dev, HIOCallback callback) { + ASSERTLINE(348, dev == 0 || chan == 0 && dev == 2); + + if (dev != 0 && (chan != 0 || dev != 2)) { + return 0; + } + + if (Chan != -1) { + return 1; + } + + HIO_DEV = dev; + return HIOInit(chan, callback); +} + +BOOL HIOReadMailbox(u32* word) { + int err; + u32 cmd; + + if (Chan == -1 || CheckConsoleType() == 0) { + return 0; + } + + if (EXILock(Chan, HIO_DEV, 0) == 0) { + return 0; + } + + if (EXISelect(Chan, HIO_DEV, 4) == 0) { + EXIUnlock(Chan); + return 0; + } + + cmd = 0x60000000; + err = 0; + err |= !EXIImm(Chan, &cmd, 2, 1, 0); + err |= !EXISync(Chan); + err |= !EXIImm(Chan, word, 4, 0, 0); + err |= !EXISync(Chan); + err |= !EXIDeselect(Chan); + EXIUnlock(Chan); + return !err; +} + +BOOL HIOWriteMailbox(u32 word) { + int err; + u32 cmd; + + if (Chan == -1 || CheckConsoleType() == 0) { + return 0; + } + + if (EXILock(Chan, HIO_DEV, 0) == 0) { + return 0; + } + + if (EXISelect(Chan, HIO_DEV, 4) == 0) { + EXIUnlock(Chan); + return 0; + } + + cmd = (word & 0x1FFFFFFF) | 0xC0000000; + err = 0; + err |= !EXIImm(Chan, &cmd, 4, 1, 0); + err |= !EXISync(Chan); + err |= !EXIDeselect(Chan); + EXIUnlock(Chan); + return !err; +} + +BOOL HIORead(u32 addr, void* buffer, s32 size) { + int err; + u32 cmd; + + if (Chan == -1 || CheckConsoleType() == 0) { + return 0; + } + + ASSERTLINE(436, (addr % 4) == 0); + + if (EXILock(Chan, HIO_DEV, 0) == 0) { + return 0; + } + + if (EXISelect(Chan, HIO_DEV, 4) == 0) { + EXIUnlock(Chan); + return 0; + } + + cmd = ((addr << 8) & 0x01FFFC00) | 0x20000000; + err = 0; + err |= !EXIImm(Chan, &cmd, 4, 1, 0); + err |= !EXISync(Chan); + err |= !EXIDma(Chan, buffer, size, 0, NULL); + err |= !EXISync(Chan); + err |= !EXIDeselect(Chan); + EXIUnlock(Chan); + return !err; +} + +BOOL HIOWrite(u32 addr, void* buffer, s32 size) { + int err; + u32 cmd; + + if (Chan == -1 || CheckConsoleType() == 0) { + return 0; + } + + ASSERTLINE(470, (addr % 4) == 0); + + if (EXILock(Chan, HIO_DEV, 0) == 0) { + return 0; + } + + if (EXISelect(Chan, HIO_DEV, 4) == 0) { + EXIUnlock(Chan); + return 0; + } + + cmd = ((addr << 8) & 0x01FFFC00) | 0xA0000000; + err = 0; + err |= !EXIImm(Chan, &cmd, 4, 1, 0); + err |= !EXISync(Chan); + err |= !EXIDma(Chan, buffer, size, 1, NULL); + err |= !EXISync(Chan); + err |= !EXIDeselect(Chan); + EXIUnlock(Chan); + return !err; +} + +BOOL HIOReadAsync(u32 addr, void* buffer, s32 size, HIOCallback callback) { + int err; + u32 cmd; + + if (Chan == -1 || CheckConsoleType() == 0) { + return 0; + } + + ASSERTLINE(504, (addr % 4) == 0); + RxCallback = callback; + + if (EXILock(Chan, HIO_DEV, 0) == 0) { + return 0; + } + + if (EXISelect(Chan, HIO_DEV, 4) == 0) { + EXIUnlock(Chan); + return 0; + } + + cmd = ((addr << 8) & 0x01FFFC00) | 0x20000000; + err = 0; + err |= !EXIImm(Chan, &cmd, 4, 1, 0); + err |= !EXISync(Chan); + err |= !EXIDma(Chan, buffer, size, 0, RxHandler); + return !err; +} + +BOOL HIOWriteAsync(u32 addr, void* buffer, s32 size, HIOCallback callback) { + int err; + u32 cmd; + + if (Chan == -1 || CheckConsoleType() == 0) { + return 0; + } + + ASSERTLINE(537, (addr % 4) == 0); + TxCallback = callback; + + if (EXILock(Chan, HIO_DEV, 0) == 0) { + return 0; + } + + if (EXISelect(Chan, HIO_DEV, 4) == 0) { + EXIUnlock(Chan); + return 0; + } + + cmd = ((addr << 8) & 0x01FFFC00) | 0xA0000000; + err = 0; + err |= !EXIImm(Chan, &cmd, 4, 1, 0); + err |= !EXISync(Chan); + err |= !EXIDma(Chan, buffer, size, 1, TxHandler); + return !err; +} + +BOOL HIOReadStatus(u32* status) { + int err; + u32 cmd; + + if (Chan == -1 || CheckConsoleType() == 0) { + return 0; + } + + if (EXILock(Chan, HIO_DEV, 0) == 0) { + return 0; + } + + if (EXISelect(Chan, HIO_DEV, 4) == 0) { + EXIUnlock(Chan); + return 0; + } + + cmd = 0x40000000; + err = 0; + err |= !EXIImm(Chan, &cmd, 2, 1, 0); + err |= !EXISync(Chan); + err |= !EXIImm(Chan, status, 4, 0, 0); + err |= !EXISync(Chan); + err |= !EXIDeselect(Chan); + EXIUnlock(Chan); + return !err; +} diff --git a/src/dolphin/mcc/fio.c b/src/dolphin/mcc/fio.c new file mode 100644 index 0000000000..dca9488d74 --- /dev/null +++ b/src/dolphin/mcc/fio.c @@ -0,0 +1,1290 @@ +#include +#include + +#ifdef DEBUG +const char* __FIOVersion = "<< Dolphin SDK - FIO\tdebug build: Apr 5 2004 03:57:07 (0x2301) >>"; +#else +const char* __FIOVersion = "<< Dolphin SDK - FIO\trelease build: Apr 5 2004 04:15:50 (0x2301) >>"; +#endif + +static u8 gBuf[0x2000]; +static u8 gPrintBuf[0x400]; + +static u8 gmSizeOfBlocks = 1; +static u8 gSizeOfBlocks = 1; +volatile static BOOL gProcDone = TRUE; + +static MCC_CHANNEL gmChID; +static MCC_CHANNEL gChID; +static int gQuery; +volatile static int gProcBusy; +volatile static u32 gStreamReady; +static u8 gLastErr; +static BOOL bAsyncIsRead; +static FIO_ASYNC_STATE bAsyncBusy; +static void* bAsyncBuffer; +static u32 gAsyncDataSize; +static u32 gRequestSequenceNumber; + +// prototypes +static BOOL fioIsInitialized(void); +static u16 EndianConvert16(u16 n); +static u32 EndianConvert32(u32 n); +static int MPDWaiting(int timeout, volatile int* flag, int value); +static void ShowChannelInfo(MCC_CHANNEL chID); +static void fioErrorReport(char* msg); +static void fioMccChannelEvent(MCC_CHANNEL chID, u32 event, u32 value); +static void* fioPacketMakeHeader(u32 fioCode, u32 dataSize, BOOL bEndianConvert); +static int fioPacketSendPacket(u8 sizeOfBlocks, void* pTopOfSecondBlockData); +static void* fioPacketReceiveResult(u32 fioCode, BOOL bDone); +static void fioPacketReceiveDone(void); +static int fioPacketRead(int fd, void* buffer, int size, int async); +static int fioPacketWrite(int fd, void* buffer, int size, int async); +static int fioPacketResultRead(void* buffer, u32 dataSize); +static int fioPacketResultWrite(void* buffer, u32 dataSize); + +static BOOL fioIsInitialized(void) { + return !!gChID; +} + +static u16 EndianConvert16(u16 n) { + return ((n & 0x00FF) << 8) | ((n & 0xFF00) >> 8); +} + +static u32 EndianConvert32(u32 n) { + return EndianConvert16((n >> 16) & 0xFFFF) | (EndianConvert16(n & 0xFFFF) << 0x10); +} + +static int MPDWaiting(int timeout, volatile int* flag, int value) { + OSTick tickStart; + OSTick tickDist; + + tickStart = OSGetTick(); + while(*flag != value) { + tickDist = OSGetTick() - tickStart; + tickDist = (tickDist & 0x80000000) ? (0x80000000 - tickStart) + OSGetTick() : tickDist; + if (OSTicksToSeconds(tickDist) >= timeout) { + OSReport("Error:Time is over.\n"); + return 0; + } + } + + return 1; +} + +static void ShowChannelInfo(MCC_CHANNEL chID) { + MCC_Info info; + + MCCGetChannelInfo(chID, &info); + OSReport("%2d: FirstBlock:%02d,BlockLength:%02d,Connect:%s,Lock:%s.\n", + chID, info.firstBlock, info.blockLength, + (info.connect == MCC_CONNECT_DISCONNECT) ? "DISCONNECT" : + (info.connect == MCC_CONNECT_HOST_OPEN) ? "HOST_OPEN" : + (info.connect == MCC_CONNECT_TARGET_OPEN) ? "TARGET_OPEN" : + (info.connect == MCC_CONNECT_CONNECTED) ? "CONNECTED" : "UNKNOWN", + (info.isLocked == FALSE) ? "UNLOCKED" : + (info.isLocked == TRUE) ? "LOCKED" : "UNKNOWN"); +} + +static void fioErrorReport(char* msg) { + OSReport("[fio] Error: %s\n", msg); +} + +static void fioMccChannelEvent(MCC_CHANNEL chID, u32 event, u32 value) { + u32 notify; + + switch(event) { + case MCC_EVENT_CONNECT: + gChID = chID; + return; + case MCC_EVENT_DISCONNECT: + gChID = 0; + return; + case MCC_EVENT_UNK_0x100: + notify = value & 0xF00000; + switch (notify) { + case 0x200000: + if ((u16)value == 0x120) { + gQuery = 1; + } + return; + case 0xF00000: + gProcDone = TRUE; + if (bAsyncBusy != 0) { + bAsyncBusy = FIO_ASYNC_STATE_DONE; + return; + } + break; + } + break; + case MCC_EVENT_READ: + gStreamReady = 0x10; + return; + case MCC_EVENT_WRITE: + gStreamReady = 0x20; + break; + } +} + +int FIOInit(MCC_EXI exiChannel, MCC_CHANNEL chID, u8 blockSize) { + OSRegisterVersion(__FIOVersion); + + if (MCCInit(exiChannel, 10, NULL) == 0) { + gLastErr = FIO_ERROR_MCC; + goto exit; + } + if (MCCOpen(chID, blockSize, fioMccChannelEvent) == 0) { + gLastErr = FIO_ERROR_MCC; + goto exit; + } + + gChID = chID; + gmChID = chID; + gSizeOfBlocks = blockSize; + gmSizeOfBlocks = blockSize; + gQuery = 0; + gProcDone = TRUE; + gProcBusy = FALSE; + gLastErr = FIO_ERROR_NONE; + bAsyncBusy = FIO_ASYNC_STATE_IDOL; + bAsyncBuffer = NULL; + bAsyncIsRead = FALSE; + return 1; + +exit:; + return 0; +} + +void FIOExit(void) { + if (MCCClose(gChID) == 0) { + gLastErr = FIO_ERROR_MCC; + return; + } + + gmChID = gChID = 0; + gmSizeOfBlocks = gSizeOfBlocks = 1; + gQuery = 0; + gProcDone = TRUE; + gProcBusy = FALSE; + gLastErr = FIO_ERROR_NONE; + bAsyncBusy = FIO_ASYNC_STATE_IDOL; + bAsyncBuffer = NULL; + bAsyncIsRead = FALSE; +} + +int FIOQuery(void) { + OSTick tick; + + if (fioIsInitialized()) { + gQuery = 0; + if (MCCNotify(gChID, 0x100120) == 0) { + gLastErr = FIO_ERROR_MCC; + goto exit; + } + if (MPDWaiting(10, &gQuery, 1) == 0) { + gLastErr = FIO_ERROR_TIMEOUT; + goto exit; + } + gLastErr = FIO_ERROR_NONE; + return 1; + } + +exit:; + tick = OSGetTick(); + do {} while(OSTicksToSeconds(OSGetTick() - tick) < 5); + return 0; +} + +u8 FIOGetLastError(void) { + return gLastErr; +} + +int FIOFopen(const char* filename, u32 mode) { + struct FIO_Code { + /* 0x00 */ u32 flag; + /* 0x04 */ s8 filename; // dynamic length + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ u32 descriptor; + } *coder; + + if (filename == NULL) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (mode & ~0xE03) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + code = fioPacketMakeHeader(0, strlen(filename) + sizeof(u32) + sizeof(s8), FALSE); + code->flag = mode; + memcpy(&code->filename, filename, strlen(filename) + 1); + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(1, TRUE); + if (coder != NULL) { + if (coder->result != 0) { + gLastErr = coder->result; + goto exit; + } + gLastErr = FIO_ERROR_NONE; + return coder->descriptor; + } + } +exit:; + return -1; +} + +int FIOFclose(int handle) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + } *coder; + + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + code = fioPacketMakeHeader(2, sizeof(struct FIO_Code), FALSE); + code->descriptor = handle; + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(3, TRUE); + if (coder != NULL) { + gLastErr = coder->result; + return 1; + } + } + +exit:; + return 0; +} + +u32 FIOFread(int handle, void* data, u32 size) { + char* pBuf; + volatile int nSizeRemain; + int nResult; + int nReadSize; + + pBuf = data; + nSizeRemain = size; + nResult = -1; + + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (data == NULL || (u32)data & 0x1F) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (size == 0) { + return 0; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + nReadSize = fioPacketRead(handle, pBuf, nSizeRemain, 0); + nSizeRemain = nSizeRemain - nReadSize; + if (nReadSize < 0) { + gLastErr = FIO_ERROR_PACKET_READ; + return -1; + } + + gLastErr = FIO_ERROR_NONE; + return size - nSizeRemain; + +exit:; + return -1; +} + +u32 FIOFwrite(int handle, void* data, u32 size) { + volatile int nSizeRemain; + int nResult; + int nWriteSize; + + nSizeRemain = size; + nResult = 0; + + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (data == NULL || (u32)data & 0x1F) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (size == 0) { + return 0; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + nWriteSize = fioPacketWrite(handle, data, nSizeRemain, 0); + nSizeRemain -= nWriteSize; + if (nWriteSize < 0) { + gLastErr = FIO_ERROR_PACKET_WRITE; + return -1; + } + + gLastErr = FIO_ERROR_NONE; + return size - nSizeRemain; + +exit:; + return -1; +} + +u32 FIOFseek(int handle, s32 offset, u32 mode) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + /* 0x04 */ u32 offset; + /* 0x08 */ u32 base; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ u32 pos; + } *coder; + + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (!(mode == 0 || mode == 2 || mode == 1)) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (mode == 0 && offset < 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (mode == 2 && offset > 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + code = fioPacketMakeHeader(8, sizeof(struct FIO_Code), FALSE); + code->descriptor = handle; + code->offset = offset; + code->base = mode; + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(9, TRUE); + if (coder != NULL && coder->result == 0) { + gLastErr = FIO_ERROR_NONE; + return coder->pos; + } + } + +exit: + return -1; +} + +int FIOFprintf(int handle, const char* format, ...) { + char* str; + int length; + int err; + va_list argptr; + + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (format == NULL) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + str = (char*)gPrintBuf; + va_start(argptr, format); + err = vsprintf(str, format, argptr); + if ((length = strlen(str)) < 0x100) { + str[length] = 0; + } else { + str[0xFF] = 0; + } + + length = strlen(str); + if (err < 0) { + gLastErr = FIO_ERROR_MSG_TOO_LONG; + return -1; + } + + gLastErr = FIO_ERROR_NONE; + return FIOFwrite(handle, str, length + 0); + +exit:; + va_end(argptr); + return -1; +} + +int FIOFflush(int handle) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + } *coder; + + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + code = fioPacketMakeHeader(10, 4, FALSE); + code->descriptor = handle; + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(11, TRUE); + if (coder != NULL) { + if (coder->result != 0) { + gLastErr = coder->result; + goto exit; + } + gLastErr = FIO_ERROR_NONE; + return 1; + } + } + +exit: + return 0; +} + +int FIOFstat(int handle, FIO_Stat* stat) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ FIO_Stat stat; + } *coder; + + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (stat == NULL) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + code = fioPacketMakeHeader(12, 4, FALSE); + code->descriptor = handle; + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(13, TRUE); + if (coder != NULL) { + if (stat) { + memcpy(stat, &coder->stat, sizeof(FIO_Stat)); + } + + if (coder->result != 0) { + gLastErr = coder->result; + goto exit; + } + + gLastErr = FIO_ERROR_NONE; + return 1; + } + } + +exit:; + return 0; +} + +int FIOFerror(int handle) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + } *coder; + + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + code = fioPacketMakeHeader(14, 4, FALSE); + code->descriptor = handle; + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(15, TRUE); + if (coder != NULL) { + if (coder->result != 0) { + gLastErr = coder->result; + goto exit; + } + gLastErr = FIO_ERROR_NONE; + return gLastErr; + } + } + +exit:; + return gLastErr; +} + +int FIOFindFirst(const char* filename, FIO_Finddata* finddata) { + struct FIO_Code { + /* 0x00 */ u8 filename; // dynamic length + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ FIO_Finddata findData; + } *coder; + + if (filename == NULL) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (finddata == NULL) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + code = fioPacketMakeHeader(16, strlen(filename) + 1, FALSE); + strcpy((void*)&code->filename, filename); + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(17, TRUE); + if (coder != NULL) { + if (finddata) { + memcpy(finddata, &coder->findData, sizeof(FIO_Finddata)); + } + + if (coder->result != 0) { + gLastErr = coder->result; + goto exit; + } + + gLastErr = FIO_ERROR_NONE; + return 1; + } + } + +exit:; + return 0; +} + +int FIOFindNext(FIO_Finddata* finddata) { + struct FIO_Code { + /* 0x00 */ u32 reserved; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ FIO_Finddata findData; + } *coder; + + if (finddata == NULL) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + code = fioPacketMakeHeader(18, 4, FALSE); + code->reserved = 0; + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(19, TRUE); + if (coder != NULL) { + if (finddata) { + memcpy(finddata, &coder->findData, sizeof(FIO_Finddata)); + } + + if (coder->result) { + gLastErr = coder->result; + goto exit; + } + + gLastErr = FIO_ERROR_NONE; + return 1; + } + } + +exit:; + return 0; +} + +int FIOOpenDir(const char* dirname, int* dir) { + struct FIO_Code { + /* 0x00 */ s8 filename; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ u32 descriptor; + } *coder; + + if (dirname == NULL) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + return 0; + } + if (dir == NULL) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + return 0; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + return 0; + } + + code = fioPacketMakeHeader(20, strlen(dirname) + 1, FALSE); + memcpy(&code->filename, dirname, strlen(dirname) + 1); + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(21, TRUE); + if (coder != NULL) { + if (coder->result != 0) { + gLastErr = coder->result; + goto exit; + } + + gLastErr = FIO_ERROR_NONE; + *dir = coder->descriptor; + return 1; + } + } + +exit:; + return 0; +} + +int FIOCloseDir(int dir) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + } *coder; + + if (dir == 0 || dir == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + return 0; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + return 0; + } + + code = fioPacketMakeHeader(22, 4, FALSE); + code->descriptor = dir; + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(23, TRUE); + if (coder != NULL) { + gLastErr = coder->result; + return 1; + } + } + + return 0; +} + +s32 FIOGetDirSize(int dir) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ u32 size; + } *coder; + + if (dir == 0 || dir == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + return -1; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + return -1; + } + + code = fioPacketMakeHeader(24, 4, FALSE); + code->descriptor = dir; + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(25, TRUE); + if (coder != NULL) { + gLastErr = coder->result; + return coder->size; + } + } + + return -1; +} + +s32 FIOReadDir(int dir, FIO_Finddata* data, s32 numOfData) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + /* 0x04 */ u32 size; + } *code; + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ u32 readsize; + } *coder; + s32 readSize; + u32 fReadSize; + + if (dir == 0 || dir == -1 || data == NULL || numOfData < 1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + return -1; + } + + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + return -1; + } + + code = fioPacketMakeHeader(26, 8, FALSE); + code->descriptor = dir; + code->size = numOfData; + + if (fioPacketSendPacket(1, NULL)) { + coder = fioPacketReceiveResult(27, TRUE); + if (coder != NULL) { + readSize = coder->readsize; + fReadSize = readSize * sizeof(FIO_Finddata); + gLastErr = coder->result; + + if (gLastErr == FIO_ERROR_NONE || gLastErr == FIO_ERROR_UNK_0x91) { + if (FIOFread(dir, data, fReadSize) == 0) { + return -1; + } + } else { + return -1; + } + + return readSize; + } + } + + return -1; +} + +u32 FIOGetAsyncBufferSize(void) { + int nPacketSize; + int nHeaderSize; + u32 nResult; + + if (gChID == 0) { + return 0; + } + + nPacketSize = gSizeOfBlocks << 0xD; + nHeaderSize = 0x18; + + nResult = nPacketSize - nHeaderSize; + return !(nResult & 0x1F) ? nResult : nResult & ~0x1F; +} + +int FIOFreadAsync(int handle, void* data, u32 size) { + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (data == NULL || (u32)data & 0x1F) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + + if (size != 0) { + if (size > FIOGetAsyncBufferSize()) { + gLastErr = FIO_ERROR_ASYNC_SIZE_TOO_BIG; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + bAsyncBusy = TRUE; + bAsyncBuffer = data; + bAsyncIsRead = TRUE; + if (fioPacketRead(handle, data, size, 1) >= 0) { + return 1; + } + } + +exit:; + return 0; +} + +int FIOFwriteAsync(int handle, void* data, u32 size) { + if (handle == 0) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (handle == -1) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + if (data == NULL || (u32)data & 0x1F) { + gLastErr = FIO_ERROR_INVALID_PARAMETERS; + goto exit; + } + + if (size != 0) { + if (size > FIOGetAsyncBufferSize()) { + gLastErr = FIO_ERROR_ASYNC_SIZE_TOO_BIG; + goto exit; + } + if (bAsyncBusy) { + gLastErr = FIO_ERROR_ASYNC_BUSY; + goto exit; + } + + bAsyncBusy = TRUE; + bAsyncBuffer = data; + bAsyncIsRead = FALSE; + if (fioPacketWrite(handle, data, size, 1) >= 0) { + return 1; + } + } + +exit: + return 0; +} + +int FIOCheckAsyncDone(u32* result) { + if (bAsyncBusy) { + if (bAsyncIsRead) { + if (result) { + *result = fioPacketResultRead(bAsyncBuffer, gAsyncDataSize); + } + } else if (result) { + *result = fioPacketResultWrite(bAsyncBuffer, gAsyncDataSize); + } + + bAsyncBusy = FALSE; + return 1; + } + + return 0; +} + +static void* fioPacketMakeHeader(u32 fioCode, u32 dataSize, BOOL bEndianConvert) { + MCC_Hdr* hdrDpci; + MCC_HdrFio* hdrFio; + char* data; + + hdrDpci = (void*)&gBuf[0]; + hdrFio = (void*)((char*)hdrDpci + 0x8); + data = (void*)((char*)hdrFio + 0x8); + + gRequestSequenceNumber += 1; + hdrFio->code = fioCode; + hdrFio->number = gRequestSequenceNumber; + hdrDpci->length = dataSize + 0x10; + hdrDpci->rsvd = 0; + hdrDpci->protocol = 0x120; + + if (bEndianConvert) { + hdrFio->code = EndianConvert32(hdrFio->code); + hdrFio->number = EndianConvert32(hdrFio->number); + hdrDpci->length = EndianConvert32(hdrDpci->length); + hdrDpci->protocol = EndianConvert16(hdrDpci->protocol); + } + return data; +} + +static int fioPacketSendPacket(u8 sizeOfBlocks, void* pTopOfSecondBlockData) { + u32 oldMaskWrite; + u8 indexOfBlocks; + + oldMaskWrite = MCCSetChannelEventMask(gChID, 0xA0); + + do {} while (gProcBusy); + do {} while (!gProcDone); + + gProcDone = FALSE; + gProcBusy = TRUE; + + for (indexOfBlocks = 0; indexOfBlocks < sizeOfBlocks; indexOfBlocks++) { + if (MCCWrite(gChID, ((u8)indexOfBlocks << 0xD), &gBuf, 0x2000, 0) == 0) { + gLastErr = FIO_ERROR_PACKET_WRITE; + MCCSetChannelEventMask(gChID, oldMaskWrite); + fioErrorReport("fioPacketSendPacket.MCCWrite.NG"); + return 0; + } + + if (sizeOfBlocks > 1) { + memcpy(&gBuf, pTopOfSecondBlockData, 0x2000); + ((char*)pTopOfSecondBlockData) += 0x2000; + } + } + + MCCSetChannelEventMask(gChID, oldMaskWrite); + if (MCCNotify(gChID, 0xF00000) == 0) { + gLastErr = FIO_ERROR_MCC; + fioErrorReport("fioPacketSendPacket.MCCNotify.NG"); + return 0; + } + + gLastErr = FIO_ERROR_NONE; + return 1; +} + +static void* fioPacketReceiveResult(u32 fioCode, BOOL bDone) { + u32 oldMaskRead; + MCC_Hdr* hdrDpci; + MCC_HdrFio* hdrFio; + char* data; + + if (MPDWaiting(10, &gProcDone, 1) == 0) { + gLastErr = FIO_ERROR_TIMEOUT; + goto exit; + } + + oldMaskRead = MCCSetChannelEventMask(gChID, 0x50); + if (MCCRead(gChID, 0, &gBuf, 0x2000, 0) == 0) { + gLastErr = FIO_ERROR_PACKET_READ; + MCCSetChannelEventMask(gChID, oldMaskRead); + goto exit; + } + + hdrDpci = (void*)((char*)&gBuf[0]); + hdrFio = (void*)((char*)hdrDpci + 0x8); + data = (void*)((char*)hdrFio + 0x8); + MCCSetChannelEventMask(gChID, oldMaskRead); + + if (hdrFio->code != fioCode) { + gLastErr = FIO_ERROR_WRONG_CODE; + goto exit; + } + if (hdrFio->number != gRequestSequenceNumber) { + gLastErr = FIO_ERROR_WRONG_SEQUENCE; + goto exit; + } + + if (bDone) { + fioPacketReceiveDone(); + } + + gLastErr = FIO_ERROR_NONE; + return data; + +exit:; + fioPacketReceiveDone(); + return NULL; +} + +static void fioPacketReceiveDone(void) { + gProcBusy = 0; +} + +static int fioPacketRead(int fd, void* buffer, int size, int async) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + /* 0x04 */ u32 nbytes; + } *code; + + code = fioPacketMakeHeader(4, sizeof(struct FIO_Code), FALSE); + code->descriptor = fd; + code->nbytes = size; + gStreamReady = 0; + + if (fioPacketSendPacket(1, NULL)) { + if (async == 0) { + return fioPacketResultRead(buffer, size); + } + gAsyncDataSize = size; + return 0; + } + + return -1; +} + +static int fioPacketWrite(int fd, void* buffer, int size, int async) { + struct FIO_Code { + /* 0x00 */ u32 descriptor; + /* 0x04 */ u32 nbytes; + } *code; + + code = fioPacketMakeHeader(6, 0xC, FALSE); + code->descriptor = fd; + code->nbytes = size; + + if (fioPacketSendPacket(1, NULL)) { + gStreamReady = 0; + if (async == 0) { + return fioPacketResultWrite(buffer, size); + } + gAsyncDataSize = size; + return 0; + } + + return -1; +} + +static int fioPacketResultRead(void* buffer, u32 dataSize) { + int bResult; + MCC_CHANNEL nChID; + u8 nChannelBlocks; + u32 dataBlockSize; + u32 readDataBlocks; + u32 nPacketSize; + u32 nDataPacketSize; + u32 nFraction; + MCC_CONNECT state; + BOOL bNeedWaitDisconnect; + u32 oldMaskWrite; + u8 err; + char msg[256]; + + bResult = 1; + nChID = gmChID; + nChannelBlocks = gmSizeOfBlocks; + dataBlockSize = (u32) (dataSize + 0x1FFF) >> 0xDU; + nPacketSize = ((u8)nChannelBlocks << 0xD); + nDataPacketSize = dataSize / nPacketSize; + nFraction = dataSize - (nDataPacketSize * nPacketSize); + nFraction = OSRoundUp32B(nFraction) & ~1; + + if (nFraction != 0) { + do {} while ((u32) gStreamReady != 0x20); + MCCRead(nChID, 0, buffer, nFraction, 0); + ((char*)buffer) += nFraction; + } + + if (nDataPacketSize != 0) { + bNeedWaitDisconnect = FALSE; + oldMaskWrite = MCCSetChannelEventMask(nChID, 0); + MCCSetChannelEventMask(nChID, oldMaskWrite); + + if (MCCClose(nChID) == 0) { + fioErrorReport("fioPacketResultRead.MCCClose.NG"); + bResult = 0; + } else { + do { + MCCGetConnectionStatus(nChID, &state); + } while (state != 0); + + if (MCCStreamOpen(nChID, nChannelBlocks) == 0) { + fioErrorReport("fioPacketResultRead.MCCStreamOpen.NG"); + bResult = 0; + } else { + do { + MCCGetConnectionStatus(nChID, &state); + } while (state != 3); + + if ((nDataPacketSize * nChannelBlocks) != (readDataBlocks = MCCStreamRead(nChID, buffer))) { + err = MCCGetLastError(); + sprintf(msg, "fioPacketResultRead.MCCStreamRead.NG(Err:%d)", err); + fioErrorReport(msg); + bResult = 0; + } + + if (MCCStreamClose(nChID) == 0) { + OSReport("MCCStream:MCCStreamClose.NG\n"); + bResult = 0; + } else { + MCC_CONNECT state; + do { + MCCGetConnectionStatus(nChID, &state); + } while (state != 0); + + if (MCCOpen(nChID, nChannelBlocks, fioMccChannelEvent) == 0) { + OSReport("MCCStream:MCCOpen.NG\n"); + bResult = 0; + } else { + do { + MCCGetConnectionStatus(nChID, &state); + } while (state != 3); + } + } + } + } + + MCCSetChannelEventMask(gChID, oldMaskWrite); + } + + // scope for variable? + { + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ u32 nbytes; + /* 0x08 */ char data; + } *coder; + + coder = fioPacketReceiveResult(5, FALSE); + if (coder == NULL) { + bResult = 0; + } else if (coder->result != 0) { + gLastErr = coder->result; + bResult = 0; + } else { + gLastErr = FIO_ERROR_NONE; + } + + fioPacketReceiveDone(); + if (bResult == 1) { + return dataSize; + } + goto exit; + } + +exit:; + return -1; +} + +static int fioPacketResultWrite(void* buffer, u32 dataSize) { + register int nResult = 0; + MCC_CHANNEL nChID; + u8 nChannelBlocks = 0; + u32 dataBlockSize; + MCC_CONNECT state; + BOOL bNeedWaitDisconnect; + u32 oldMaskWrite; + + nChID = gmChID; + nChannelBlocks = gmSizeOfBlocks; + dataBlockSize = (dataSize + 0x1FFF) >> 0xD; + bNeedWaitDisconnect = FALSE; + oldMaskWrite = MCCSetChannelEventMask(nChID, 0); + + MCCSetChannelEventMask(nChID, oldMaskWrite); + if (MCCClose(nChID) == 0) { + fioErrorReport("fioPacketResultWrite.MCCClose.NG"); + } else { +loop:; + MCCGetConnectionStatus(nChID, &state); + if (state != 0) { + goto loop; + } + + if (MCCStreamOpen(nChID, nChannelBlocks) == 0) { + fioErrorReport("fioPacketResultWrite.MCCStreamOpen.NG"); + goto loop; + } + + do { + MCCGetConnectionStatus(nChID, &state); + } while (state != 3); + + if (MCCStreamWrite(nChID, buffer, dataBlockSize) == 0) { + fioErrorReport("fioPacketResultWrite.MCCStreamWrite.NG"); + } + + { + MCC_CONNECT state; + do { + MCCGetConnectionStatus(nChID, &state); + } while (state == 3); + + if (MCCStreamClose(nChID) == 0) { + OSReport("MCCStream:MCCStreamClose.NG\n"); + } else { + do { + MCCGetConnectionStatus(nChID, &state); + } while (state == 0); + + if (MCCOpen(nChID, nChannelBlocks, fioMccChannelEvent) == 0) { + OSReport("MCCStream:MCCOpen.NG\n"); + } + } + } + goto exit_loop; + } + +exit_loop:; + { + struct FIO_Coder { + /* 0x00 */ u32 result; + /* 0x04 */ u32 nbytes; + } *coder; + + oldMaskWrite = MCCSetChannelEventMask(gChID, oldMaskWrite); + coder = fioPacketReceiveResult(7, TRUE); + + if (coder == NULL) { + (void)0; + } else { + if (coder->result) { + gLastErr = coder->result; + goto exit; + } + gLastErr = FIO_ERROR_NONE; + return coder->nbytes; + } + } + +exit: + return -1; +} diff --git a/src/dolphin/mcc/mcc.c b/src/dolphin/mcc/mcc.c new file mode 100644 index 0000000000..bed12b501c --- /dev/null +++ b/src/dolphin/mcc/mcc.c @@ -0,0 +1,1417 @@ +#include +#include + +#ifdef DEBUG +const char* __MCCVersion = "<< Dolphin SDK - MCC\tdebug build: Apr 5 2004 03:57:07 (0x2301) >>"; +#else +const char* __MCCVersion = "<< Dolphin SDK - MCC\trelease build: Apr 5 2004 04:15:49 (0x2301) >>"; +#endif + +static MCC_ChannelInfo gChannelInfo[16] ATTRIBUTE_ALIGN(32); +static char gStreamWork[32] ATTRIBUTE_ALIGN(32); +static char m_szAdapterMode[32] ATTRIBUTE_ALIGN(32); +static char m_szInitCode[32] ATTRIBUTE_ALIGN(32); +static MCC_Info channelInfo[16] ATTRIBUTE_ALIGN(32); + +volatile static BOOL gIsChannelinfoDirty = TRUE; + +static void (*volatile gCallbackSysEvent)(MCC_SYSEVENT); +static BOOL gOtherSideInitDone; +volatile static u8 gLastError; +static BOOL gMccInitialized; +static int gMccSession; +volatile static int gPingFlag; +volatile static u16 gAsyncResourceStatus; + +// prototypes +static void mccDebugPrint(char* str); +static void callbackEventStream(MCC_CHANNEL chID, u32 event, u32 value); +static int SetUsbAdapterMode(u8 mode); +static u8 GetUsbAdapterMode(void); +static int InitializeCodeClear(void); +static int InitializeCodeSet(void); +static int InitializeCodeCheck(void); +static void AsyncResourceClearState(void); +static void AsyncResourceSetState(u16 state); +static void AsyncResourceStateBusy(u8 channel, u16 mode); +static void AsyncResourceStateDone(void); +static u16 AsyncResourceGetStat(void); +static u16 AsyncResourceGetMode(void); +static u8 AsyncResourceGetChannel(void); +static int AsyncResourceIsBusy(void); +static int LoadChannelInfo(MCC_ChannelInfo* info); +static int FlushChannelInfo(MCC_ChannelInfo* info); +static void SetChannelInfoDirty(int dirty); +static void ClearChannelInfo(int i); +static void MakeMemoryMap(u8* map); +static BOOL IsChannelOpened(MCC_CHANNEL chID); +static u8 SearchFreeBlocks(MCC_MODE mode, u8* index); +static int NotifyCompulsorily(MCC_CHANNEL chID, u32 notify, u32 timeout); +static int NotifyInit(void); +static int NotifyInitDone(void); +static int NotifyChannelEvent(MCC_CHANNEL chID, u32 notify); +static int WaitAMinute(int timeout, volatile int* flag, int value); +static void MailboxCheck(void); +static void MCCExiCallback(void); +static void MCCTxCallback(void); +static void MCCRxCallback(void); +static int mccInitializeCheck(u8 timeout); + +static void mccDebugPrint(char* str) {} + +static void callbackEventStream(MCC_CHANNEL chID, u32 event, u32 value) { + value; // needed to bump registers. what? + + if (event == MCC_EVENT_READ) { + gChannelInfo[chID].isStreamDone = TRUE; + } + if (event == MCC_EVENT_WRITE) { + gChannelInfo[chID].isStreamDone = TRUE; + } + if (event == MCC_EVENT_CONNECT) { + gChannelInfo[chID].isStreamConnection = TRUE; + } + if (event == MCC_EVENT_DISCONNECT) { + gChannelInfo[chID].isStreamConnection = TRUE; + } + if (event == MCC_EVENT_UNK_0x100) { + gChannelInfo[chID].isStreamConnection = TRUE; + } +} + +BOOL MCCStreamOpen(MCC_CHANNEL chID, u8 blockSize) { + BOOL bResult; + + bResult = FALSE; + if (MCCOpen(chID, blockSize, callbackEventStream)) { + gChannelInfo[chID].isStreamOpened = 0; + gChannelInfo[chID].isStreamConnection = 0; + gChannelInfo[chID].isStreamDone = 0; + bResult = TRUE; + } + + return bResult; +} + +int MCCStreamClose(MCC_CHANNEL chID) { + gChannelInfo[chID].isStreamOpened = FALSE; + return MCCClose(chID); +} + +int MCCStreamWrite(MCC_CHANNEL chID, void* data, u32 dataBlockSize) { + MCC_Info chanInfo; + char* dataAddress; + u32 lastBlocks; + + if (!gMccInitialized) { + gLastError = 1; + } else if (chID < 1 || chID >= 16) { + gLastError = 14; + } else if (LoadChannelInfo(gChannelInfo) == 0) { + gLastError = 11; + } else { + if (gChannelInfo[chID].isStreamOpened != TRUE) { + gChannelInfo[chID].isStreamOpened = TRUE; + } else { + MCCNotify(chID, 0); + } + + if (WaitAMinute(5, &gChannelInfo[chID].isStreamConnection, 1) == 0) { + gLastError = 2; + } else { + gChannelInfo[chID].isStreamConnection = 0; + if (MCCGetChannelInfo(chID, &chanInfo) != 0) { + *(u32*)&gStreamWork = dataBlockSize; + if (MCCWrite(chID, 0, gStreamWork, 0x20, 0) != 0) { + if (WaitAMinute(5, &gChannelInfo[chID].isStreamDone, 1) == 0) { + gLastError = 2; + } else { + dataAddress = data; + lastBlocks = dataBlockSize; + gChannelInfo[chID].isStreamDone = FALSE; + while (lastBlocks) { + if (!MCCWrite(chID, 0, dataAddress, chanInfo.blockLength << 0xD, 0)) { + break; + } + + if (WaitAMinute(5, &gChannelInfo[chID].isStreamDone, 1) == 0) { + gLastError = 2; + break; + } else { + gChannelInfo[chID].isStreamDone = 0; + dataAddress += chanInfo.blockLength << 0xD; + if (lastBlocks > chanInfo.blockLength) { + lastBlocks -= chanInfo.blockLength; + } else { + lastBlocks = 0; + break; + } + } + } + + return lastBlocks == 0; + } + } + } + } + } + + return 0; +} + +u32 MCCStreamRead(MCC_CHANNEL chID, void* data) { + MCC_Info chanInfo; + char* dataAddress; + u32 allBlocks; + u32 lastBlocks; + + if (!gMccInitialized) { + gLastError = 1; + } else if (chID < 1 || chID >= 0x10) { + gLastError = 0xE; + } else if (LoadChannelInfo(gChannelInfo) == 0) { + gLastError = 0xB; + } else { + if (gChannelInfo[chID].isStreamOpened != TRUE) { + gChannelInfo[chID].isStreamOpened = TRUE; + } else { + MCCNotify(chID, 0); + } + + if (WaitAMinute(5, &gChannelInfo[chID].isStreamConnection, 1) == 0) { + gLastError = 2; + } else { + gChannelInfo[chID].isStreamConnection = FALSE; + if (MCCGetChannelInfo(chID, &chanInfo) != 0) { + if (WaitAMinute(5, &gChannelInfo[chID].isStreamDone, 1) == 0) { + gLastError = 2; + } else { + gChannelInfo[chID].isStreamDone = FALSE; + if (MCCRead(chID, 0, gStreamWork, 0x20, 0) != 0) { + dataAddress = data; + allBlocks = lastBlocks = *(u32*)&gStreamWork[0]; + while (lastBlocks) { + if (WaitAMinute(5, &gChannelInfo[chID].isStreamDone, 1) == 0) { + gLastError = 2; + break; + } + + gChannelInfo[chID].isStreamDone = FALSE; + if (MCCRead(chID, 0, dataAddress, (lastBlocks > chanInfo.blockLength) ? chanInfo.blockLength << 0xD : lastBlocks << 0xD, 0) != 0) { + dataAddress += chanInfo.blockLength << 0xD; + if (lastBlocks > chanInfo.blockLength) { + lastBlocks -= chanInfo.blockLength; + } else { + lastBlocks = 0; + break; + } + } else { + break; + } + } + return allBlocks - lastBlocks; + } + } + } + } + } + + return 0; +} + +static int SetUsbAdapterMode(u8 mode) { + int result = 0; + + if (HIORead(0x680, m_szAdapterMode, 0x20) != 0) { + DCInvalidateRange(m_szAdapterMode, 0x20); + m_szAdapterMode[0] = mode; + DCFlushRange(m_szAdapterMode, 0x20); + if (HIOWrite(0x680, m_szAdapterMode, 0x20) != 0) { + result = 1; + } + } + return result; +} + +static u8 GetUsbAdapterMode(void) { + if (HIORead(0x680, m_szAdapterMode, 0x20) != 0) { + DCInvalidateRange(m_szAdapterMode, 0x20); + return m_szAdapterMode[0]; + } + return 0; +} + +static int InitializeCodeClear(void) { + memset(m_szInitCode, 0, 0x20); + DCFlushRange(m_szInitCode, 0x20); + HIOWrite(0x600, m_szInitCode, 0x20); +} + +static int InitializeCodeSet(void) { + strcpy(m_szInitCode, "HUDSON/USB2EXI/INITCODE/TARGET"); + DCFlushRange(m_szInitCode, 0x20); + HIOWrite(0x600, m_szInitCode, 0x20); +} + +static int InitializeCodeCheck(void) { + int result; + + if ((result = HIORead(0x600, m_szInitCode, 0x20)) != 0) { + DCInvalidateRange(m_szInitCode, 0x20); + result = strcmp(m_szInitCode, "HUDSON/USB2EXI/INITCODE/HOST"); + return result == 0; + } + return result; +} + +static void AsyncResourceClearState(void) { + gAsyncResourceStatus = 0; +} + +static void AsyncResourceSetState(u16 state) { + gAsyncResourceStatus &= 0xFFFF0FFF; + gAsyncResourceStatus |= state; +} + +static void AsyncResourceStateBusy(u8 channel, u16 mode) { + AsyncResourceClearState(); + AsyncResourceSetState(0x1000); + gAsyncResourceStatus |= channel; + gAsyncResourceStatus |= mode; +} + +static void AsyncResourceStateDone(void) { + AsyncResourceSetState(0x2000); +} + +static u16 AsyncResourceGetStat(void) { + return gAsyncResourceStatus & 0xF000; +} + +static u16 AsyncResourceGetMode(void) { + return gAsyncResourceStatus & 0xF00; +} + +static u8 AsyncResourceGetChannel(void) { + return gAsyncResourceStatus; +} + +static int AsyncResourceIsBusy(void) { + return AsyncResourceGetStat() & 0x1000; +} + +static int LoadChannelInfo(MCC_ChannelInfo* info) { + volatile int result = 0; + u8 count; +#ifndef DEBUG + int unused; // this is fake, but i cant seem to find whats messing with the stack. +#endif + + if (!gIsChannelinfoDirty) { + result = 1; + } else { + count = 0; + mccDebugPrint("+++ Load channel info."); + while ((result = HIORead(0x700, channelInfo, 0x40)) != 1) { + count -= 1; + if (count == 0) { + break; + } + } + + if (result) { + DCInvalidateRange(channelInfo, 0x40); + for(count = 0; count < 16; count++) { + info[count].info = channelInfo[count]; + } + SetChannelInfoDirty(0); + } + } + + return result; +} + +static int FlushChannelInfo(MCC_ChannelInfo* info) { + volatile int result; + u8 count; + + result = 0; + for(count = 0; count < 16; count++) { + channelInfo[count] = info[count].info; + } + + DCFlushRange(channelInfo, 0x40); + while ((result = HIOWrite(0x700, channelInfo, 0x40)) != 1) { + count -= 1; + if (count == 0) { + break; + } + } + + if (result != 0) { + SetChannelInfoDirty(1); + result = NotifyCompulsorily(0, 5, 10); + } + return result; +} + +static void SetChannelInfoDirty(int dirty) { + gIsChannelinfoDirty = dirty; +} + +static void ClearChannelInfo(int i) { + gChannelInfo[i].info.firstBlock = 0; + gChannelInfo[i].info.blockLength = 0; + gChannelInfo[i].info.connect = 0; + gChannelInfo[i].info.isLocked = FALSE; + gChannelInfo[i].eventMask = 0; + gChannelInfo[i].callbackEvent = NULL; + gChannelInfo[i].isStreamDone = FALSE; + //! isStreamConnection isnt cleared. Intentional? +} + +static void MakeMemoryMap(u8* map) { + u8 iMap; + u8 jMap; + + memset(map, 0, 0x10); + for (iMap = 0; iMap < 16; iMap++) { + if (gChannelInfo[iMap].info.connect) { + for (jMap = 0; jMap < gChannelInfo[iMap].info.blockLength; jMap++) { + if (jMap + gChannelInfo[iMap].info.firstBlock < 0x10) { + map[gChannelInfo[iMap].info.firstBlock + jMap] = iMap + 1; + } else { + gLastError = 0xD; + } + } + } + } + + *map = 0xFF; +} + +static int IsChannelOpened(MCC_CHANNEL chID) { + u8 connectSide; + + if (chID <= 0 || chID >= 0x10) { + gLastError = 0xE; + goto exit; + } + connectSide = 2; + + return (connectSide & gChannelInfo[chID].info.connect) ? TRUE : FALSE; + +exit:; + return 0; +} + +static u8 SearchFreeBlocks(MCC_MODE mode, u8* index) { + u8 map[16]; + u8 iMap; + u8 fIndex; + u8 fSize; + u8 fCount; + + MakeMemoryMap(map); + fCount = 0; + fIndex = 0; + fSize = (mode == 0) ? 0x10 : 0; + + //! @bug I think this will read OOB of the map array by 1. + for (iMap = 0; iMap <= 16; iMap++) { + if (map[iMap] || iMap == 16) { + if (fCount != 0) { + if (mode == 0) { + if (fSize > fCount) { + fSize = fCount; + fIndex = iMap - fCount; + } + } else if (mode == 1) { + if (fSize < fCount) { + fSize = fCount; + fIndex = iMap - fCount; + } + } else if (mode == 2) { + fSize += fCount; + } + fCount = 0; + } + } else { + fCount += 1; + } + } + + if (index) { + *index = fIndex; + } + return fSize; +} + +static int NotifyCompulsorily(MCC_CHANNEL chID, u32 notify, u32 timeout) { + u32 status; + u32 notifyData; + volatile u32 tickStart; + volatile u32 tickCur; + volatile u32 tickSec; +#ifndef DEBUG + int unused; // fake but blah +#endif + + status = 0; + tickStart = OSGetTick(); + + notifyData = (chID << 0x18); + notifyData |= (notify & 0x10000000); + notifyData |= (notify & 0xFFFFFF); + + while (1) { + if (!HIOReadStatus(&status)) { + mccDebugPrint("ERROR:HIOReadStatus\n"); + } + + if ((status & 2) == 0) { + break; + } + + tickCur = OSGetTick(); + tickSec = (tickStart < tickCur) ? tickCur - tickStart : (-1 - tickStart) + tickCur; + tickSec = OSTicksToSeconds(tickSec); + if (timeout == 0 || tickSec > timeout) { + break; + } + } + + if (!HIOWriteMailbox(notifyData)) { + gLastError = 6; + goto exit; + } + return 1; + +exit:; + return 0; +} + +static int NotifyInit(void) { + return NotifyCompulsorily(0, 1, 0); +} + +static int NotifyInitDone(void) { + return NotifyCompulsorily(0, 2, 0); +} + +static int NotifyChannelEvent(MCC_CHANNEL chID, u32 notify) { +#ifndef DEBUG + int unused[2]; // fake but blah +#endif + + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + } else if (!IsChannelOpened(chID)) { + mccDebugPrint("Error:Channel is not opened.\n"); + gLastError = 0x12; + } else if (NotifyCompulsorily(chID, notify, 10) != 0) { + return 1; + } + + return 0; +} + +static int WaitAMinute(int timeout, volatile int* flag, int value) { + u32 tickStart; + u32 tickDist; + + tickStart = OSGetTick(); + while (*flag != value) { + tickDist = OSGetTick() - tickStart; + tickDist = (tickDist & 0x80000000) ? (0x80000000 - tickStart) + OSGetTick() : tickDist; + if (OSTicksToSeconds(tickDist) >= timeout) { + mccDebugPrint("Error:Time is over.\n"); + return 0; + } + } + return 1; +} + +static void MailboxCheck(void) { + u32 mailbox; + BOOL isNotify; + u8 chID; + u32 value; + BOOL bDoCall; +#ifndef DEBUG + int unused[3]; // fake but blah +#endif + + mailbox = 0; + if (HIOReadMailbox(&mailbox) == 0) { + mccDebugPrint("Error:Could not read mailbox.\n"); + gLastError = 5; + return; + } + + isNotify = (mailbox & 0x10000000) != 0; + chID = (mailbox >> 0x18U) & 0xF; + value = (mailbox & 0xFFFFFF); + + if (chID == 0) { + bDoCall = TRUE; + switch(value) { + case 2: + gMccInitialized = TRUE; + gMccSession = 1; + gOtherSideInitDone = TRUE; + break; + case 3: + NotifyCompulsorily(0, 4, 10); + break; + case 1: + gMccSession = 0; + break; + case 4: + if (gPingFlag == 0) { + bDoCall = FALSE; + } + gPingFlag = 0; + break; + case 5: + SetChannelInfoDirty(1); + break; + default: + if (value == 8) { + bDoCall = FALSE; + } else { + value = 0; + } + break; + } + + if (bDoCall && gCallbackSysEvent) { + gCallbackSysEvent(value); + } + } else { + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + return; + } + + if (IsChannelOpened(chID)) { + if (!!isNotify) { + if (gChannelInfo[chID].callbackEvent) { + gChannelInfo[chID].callbackEvent(chID, MCC_EVENT_UNK_0x100, value); + } + } else { + switch(value) { + case MCC_EVENT_READ_DONE_INSIDE: + case MCC_EVENT_WRITE_DONE_INSIDE: + mccDebugPrint("ERROR: MCC_EVENT_READ_DONE_INSIDE / MCC_EVENT_WRITE_DONE_INSIDE received."); + break; + case MCC_EVENT_CONNECT: + case MCC_EVENT_DISCONNECT: + case MCC_EVENT_LOCK: + case MCC_EVENT_UNLOCK: + case MCC_EVENT_READ: + case MCC_EVENT_WRITE: + if (gChannelInfo[chID].callbackEvent) { + gChannelInfo[chID].callbackEvent(chID, value, 0); + } + break; + default: + if (gChannelInfo[chID].callbackEvent) { + gChannelInfo[chID].callbackEvent(chID, 0, 0); + } + break; + } + } + } + } +} + +static void MCCExiCallback(void) { + MailboxCheck(); +} + +static void MCCTxCallback(void) { + AsyncResourceStateDone(); +} + +static void MCCRxCallback(void) { + AsyncResourceStateDone(); +} + +static int mccInitializeCheck(u8 timeout) { + int dmyFlag; + int i; +#ifndef DEBUG + int unused[3]; // fake but blah +#endif + + dmyFlag = 0; + if (InitializeCodeCheck() == 0) { + if (gMccInitialized) { + if (gMccSession == 0) { + SetChannelInfoDirty(1); + for (i = 0; i < 16; i++) { + ClearChannelInfo(i); + } + + if (FlushChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not flush channelInfo.\n"); + gLastError = 0xA; + return 0; + } + } + return 1; + } + + InitializeCodeSet(); + if (FlushChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not flush channelInfo.\n"); + gLastError = 0xA; + } else if (timeout != 0 && WaitAMinute(timeout, &gOtherSideInitDone, 1) == 0) { + InitializeCodeClear(); + mccDebugPrint("Error:Time is over.\n"); + gLastError = 2; + return 0; + } else { + return 1; + } + } else { + InitializeCodeClear(); + if (NotifyInitDone() == 0) { + gLastError = 4; + } else { + if (gCallbackSysEvent) { + gCallbackSysEvent(2); + } + gMccInitialized = TRUE; + gMccSession = 1; + return 1; + } + } + return 0; +} + +int MCCInit(MCC_EXI exiChannel, u8 timeout, MCC_CBSysEvent callbackSysEvent) { + int dmyFlag; + u8 adapterMode; + u32 mailbox; + u32 status; + int i; +#ifndef DEBUG + int unused[3]; // fake but blah +#endif + + OSRegisterVersion(__MCCVersion); + + mccDebugPrint("MCCInit\n"); + if (gMccInitialized) { + SetChannelInfoDirty(1); + return mccInitializeCheck(timeout); + } + + if (!(exiChannel == 0 || exiChannel == 1 || exiChannel == 2)) { + mccDebugPrint("[MCC] Error: Exi channel is out of range.\n"); + gLastError = 4; + return 0; + } + + if (HIOInit(exiChannel, MCCExiCallback) == 0) { + mccDebugPrint("Error:Initialized Host I/O\n"); + gLastError = 4; + } else { + dmyFlag = 0; + adapterMode = GetUsbAdapterMode(); + adapterMode = SetUsbAdapterMode(1); + mailbox = 0; + status = 0; + + if (HIOReadStatus(&status) != 0 && status & 1) { + HIOReadMailbox(&mailbox); + } + + WaitAMinute(1, &dmyFlag, 1); + if (NotifyInit() == 0) { + gLastError = 4; + } else { + gCallbackSysEvent = callbackSysEvent; + gLastError = 0; + SetChannelInfoDirty(1); + for (i = 0; i < 16; i++) { + ClearChannelInfo(i); + } + AsyncResourceClearState(); + return mccInitializeCheck(timeout); + } + } + + return 0; +} + +void MCCExit(void) { + u8 chID; + + if (!gMccInitialized) { + gLastError = 1; + } else { + mccDebugPrint("MCCExit\n"); + for (chID = 1; chID < 16; chID++) { + if (IsChannelOpened(chID)) { + MCCClose(chID); + } + } + gLastError = 0; + } + + gMccInitialized = FALSE; + gMccSession = 0; +} + +int MCCPing(void) { + mccDebugPrint("MCCPing\n"); + if (!gMccInitialized) { + gLastError = 1; + } else { + gPingFlag = 1; + gLastError = 0; + return NotifyCompulsorily(0, 3, 10); + } + return 0; +} + +int MCCEnumDevices(MCC_CBEnumDevices callbackEnumDevices) { + if (callbackEnumDevices == NULL) { + gLastError = 0xD; + } + + if (HIOEnumDevices(callbackEnumDevices) == 0) { + gLastError = 0xD; + } else { + gLastError = 0; + return 1; + } + + return 0; +} + +u8 MCCGetFreeBlocks(MCC_MODE mode) { +#ifndef DEBUG + int unused[3]; // fake but blah +#endif + + mccDebugPrint("MCCGetFreeBlocks\n"); + if (!gMccInitialized) { + gLastError = 1; + } else if (!(mode == 0 || mode == 1 || mode == 2)) { + gLastError = 0xD; + } else { + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + } else { + gLastError = 0; + return SearchFreeBlocks(mode, NULL); + } + } + + return 0; +} + +u8 MCCGetLastError(void) { + mccDebugPrint("MCCGetFreeBlocks\n"); //! wrong print? + return gLastError; +} + +int MCCGetChannelInfo(MCC_CHANNEL chID, MCC_Info* info) { +#ifndef DEBUG + int unused[3]; // fake but blah +#endif + + mccDebugPrint("MCCGetChannelInfo\n"); + if (!gMccInitialized) { + gLastError = 1; + } else if (chID <= 0 || chID >= 0x10) { + gLastError = 0xE; + } else if (!info) { + mccDebugPrint("Error:Bad parameter channelInfo.\n"); + gLastError = 0xD; + } else { + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + } else { + memcpy(info, &gChannelInfo[chID].info, sizeof(MCC_Info)); + gLastError = 0; + return 1; + } + } + + return 0; +} + +int MCCGetConnectionStatus(MCC_CHANNEL chID, MCC_CONNECT* connect) { + MCC_Info info; +#ifndef DEBUG + int unused[2]; // fake but blah +#endif + + mccDebugPrint("MCCGetConnectionStatus\n"); + if (!gMccInitialized) { + gLastError = 1; + return 0; + } + if (chID < 1 || chID >= 0x10) { + gLastError = 0xE; + return 0; + } + if (AsyncResourceIsBusy()) { + gLastError = 0x15; + return 0; + } + + if (!connect) { + mccDebugPrint("Error:Parameter error.\n"); + gLastError = 0xD; + } else { + if (MCCGetChannelInfo(chID, &info) != 0) { + *connect = info.connect; + gLastError = 0; + return 1; + } + } + + return 0; +} + +int MCCNotify(MCC_CHANNEL chID, u32 notify) { + MCC_CONNECT connect; +#ifndef DEBUG + int unused[3]; // fake but blah +#endif + + + mccDebugPrint("MCCNotify\n"); + if (!gMccInitialized) { + gLastError = 1; + } else if(chID <= 0 || chID >= 0x10) { + gLastError = 0xE;; + } else if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + } else if(MCCGetConnectionStatus(chID, &connect) == 0) { + gLastError = 9; + } else { + if (connect != 3) { + mccDebugPrint("Error:Channel is not opened.\n"); + gLastError = 0x12; + } else { + notify |= 0x10000000; + return NotifyCompulsorily(chID, notify, 0xAU); + } + } + + return 0; +} + +u32 MCCSetChannelEventMask(MCC_CHANNEL chID, u32 event) { + u32 oldMask; +#ifndef DEBUG + int unused[2]; // fake but blah +#endif + + oldMask = 0xFFFFFFFF; + if (!gMccInitialized) { + gLastError = 1; + } else if (chID <= 0 || chID >= 0x10) { + gLastError = 0xE; + } else if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + } else if (!IsChannelOpened(chID)) { + mccDebugPrint("Error:This channel is closed."); + gLastError = 0x12; + } else { + oldMask = gChannelInfo[chID].eventMask; + gChannelInfo[chID].eventMask = (u16)event; + } + + return oldMask; +} + +int MCCOpen(MCC_CHANNEL chID, u8 blockSize, MCC_CBEvent callbackEvent) { + u8 connectSide; + u8 blockIndex; +#ifndef DEBUG + int unused2[2]; +#endif + u8 freeBlocks; +#ifndef DEBUG + int unused[6]; // fake but blah +#endif + + mccDebugPrint("MCCOpen\n"); + if (!gMccInitialized) { + gLastError = 1; + return 0; + } + if (chID < 1 || chID >= 0x10) { + gLastError = 0xE; + return 0; + } + if (AsyncResourceIsBusy()) { + gLastError = 0x15; + return 0; + } + if (blockSize == 0) { + gLastError = 0xF; + return 0; + } + + if (chID <= 0 || chID >= 0x10) { + mccDebugPrint("Error:Invalid channel.\n"); + gLastError = 0xE; + goto exit; + } else { + connectSide = 2; + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + goto exit; + } else if (!gChannelInfo[chID].info.connect) { + freeBlocks = SearchFreeBlocks(1, &blockIndex); + if (blockSize > freeBlocks) { + mccDebugPrint("Error:Not enough free blocks.\n"); + gLastError = 0xC; + goto exit; + } else { + gChannelInfo[chID].info.firstBlock = blockIndex; + gChannelInfo[chID].info.blockLength = blockSize; + gChannelInfo[chID].info.connect = connectSide; + gChannelInfo[chID].info.isLocked = FALSE; + gChannelInfo[chID].eventMask = 0; + gChannelInfo[chID].callbackEvent = callbackEvent; + gChannelInfo[chID].isStreamDone = FALSE; + + if (FlushChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not flush channelInfo.\n"); + gLastError = 0xA; + goto exit; + } + gLastError = 0; + return 1; + } + } + } + + if (gChannelInfo[chID].info.connect & connectSide) { + mccDebugPrint("Error:Already opened.\n"); + gLastError = 0x11; + goto exit; + } else if (blockSize != gChannelInfo[chID].info.blockLength) { + mccDebugPrint("Error:Block size error.\n"); + gLastError = 0xD; + goto exit; + } + + gChannelInfo[chID].info.connect = 3; + gChannelInfo[chID].callbackEvent = callbackEvent; + + if (FlushChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not flush channelInfo.\n"); + gLastError = 0xA; + goto exit; + } + + if (~(gChannelInfo[chID].eventMask) & 1) { + NotifyCompulsorily(chID, 1, 10); + if (gChannelInfo[chID].callbackEvent) { + gChannelInfo[chID].callbackEvent(chID, 1, 0); + } + } + + gLastError = 0; + return 1; +exit:; + return 0; +} + +int MCCClose(MCC_CHANNEL chID) { + u8 connectSide; +#ifndef DEBUG + int unused[4]; // fake but blah +#endif + + connectSide = 2; + mccDebugPrint("MCCClose\n"); + if (!gMccInitialized) { + gLastError = 1; + return 0; + } + if (chID < 1 || chID >= 0x10) { + gLastError = 0xE; + return 0; + } + if (AsyncResourceIsBusy()) { + gLastError = 0x15; + return 0; + } + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + goto exit; + } + if (!IsChannelOpened(chID)) { + mccDebugPrint("Error:This channel is closed."); + gLastError = 0x12; + goto exit; + } + + gChannelInfo[chID].info.connect &= ~connectSide; + if (gChannelInfo[chID].info.connect == 0) { + ClearChannelInfo(chID); + } + if (FlushChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not flush channelInfo.\n"); + gLastError = 0xA; + goto exit; + } + + if (gChannelInfo[chID].info.connect != 0) { + if (~(gChannelInfo[chID].eventMask) & 2) { + NotifyCompulsorily(chID, 2, 10); + if (gChannelInfo[chID].callbackEvent) { + gChannelInfo[chID].callbackEvent(chID, 2, 0); + } + } + } + + gLastError = 0; + return 1; +exit:; + return 0; +} + +int MCCLock(MCC_CHANNEL chID) { +#ifndef DEBUG + int unused[7]; // fake but blah +#endif + + mccDebugPrint("MCCLock\n"); + + if (!gMccInitialized) { + gLastError = 1; + return 0; + } + if (chID < 1 || chID >= 0x10) { + gLastError = 0xE; + return 0; + } + if (AsyncResourceIsBusy()) { + gLastError = 0x15; + return 0; + } + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + goto exit; + } + if (!IsChannelOpened(chID)) { + mccDebugPrint("Error:This channel is closed."); + gLastError = 0x12; + goto exit; + } + if (gChannelInfo[chID].info.isLocked == TRUE) { + mccDebugPrint("Error:This channel is already locked."); + gLastError = 0x13; + goto exit; + } + + gChannelInfo[chID].info.isLocked = TRUE; + + if (FlushChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not flush channelInfo.\n"); + gLastError = 0xA; + goto exit; + } + + if (~(gChannelInfo[chID].eventMask) & 4) { + NotifyChannelEvent(chID, 4); + } + gLastError = 0; + return 1; + +exit:; + return 0; +} + +int MCCUnlock(MCC_CHANNEL chID) { +#ifndef DEBUG + int unused[7]; // fake but blah +#endif + + mccDebugPrint("MCCUnlock\n"); + + if (!gMccInitialized) { + gLastError = 1; + return 0; + } + if (chID < 1 || chID >= 0x10) { + gLastError = 0xE; + return 0; + } + if (AsyncResourceIsBusy()) { + gLastError = 0x15; + return 0; + } + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + goto exit; + } + if (!IsChannelOpened(chID)) { + mccDebugPrint("Error:This channel is closed."); + gLastError = 0x12; + goto exit; + } + if (gChannelInfo[chID].info.isLocked == FALSE) { + mccDebugPrint("Error:This channel is already unlocked."); + gLastError = 0x14; + goto exit; + } + + gChannelInfo[chID].info.isLocked = FALSE; + + if (FlushChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not flush channelInfo.\n"); + gLastError = 0xA; + goto exit; + } + + if (~(gChannelInfo[chID].eventMask) & 8) { + NotifyChannelEvent(chID, 8); + } + gLastError = 0; + return 1; + +exit: + return 0; +} + +int MCCRead(MCC_CHANNEL chID, u32 offset, void* data, s32 size, MCC_SYNC_STATE async) { +#ifndef DEBUG + int unused[11]; // fake but blah +#endif + + mccDebugPrint("MCCRead\n"); + if (!gMccInitialized) { + gLastError = 1; + return 0; + } + if (chID < 1 || chID >= 0x10) { + gLastError = 0xE; + return 0; + } + if (!(async == 1 || async == 0)) { + gLastError = 0xD; + return 0; + } + if ((offset & 3) || ((u32)data & 0x1F) || (size % 32) != 0) { + gLastError = 0xD; + return 0; + } + if (AsyncResourceIsBusy()) { + gLastError = 0x15; + return 0; + } + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + goto exit; + } + if (!IsChannelOpened(chID)) { + mccDebugPrint("Error:This channel is closed."); + gLastError = 0x12; + goto exit; + } + if (offset > gChannelInfo[chID].info.blockLength << 0xD) { + mccDebugPrint("Error:Invarid offset"); + gLastError = 0x10; + goto exit; + } + if ((offset + size) > gChannelInfo[chID].info.blockLength << 0xD) { + mccDebugPrint("Error:Invarid data size."); + gLastError = 0xF; + goto exit; + } + + if (async == 1) { + if (MCCCheckAsyncDone() == 0) { + mccDebugPrint("Error:Channel busy."); + gLastError = 0x15; + goto exit; + } + AsyncResourceStateBusy(chID, 0U); + if (HIOReadAsync(offset + (gChannelInfo[chID].info.firstBlock << 0xD), data, size, MCCRxCallback) == 0) { + mccDebugPrint("Error:Read data error."); + gLastError = 7; + goto exit; + } + DCInvalidateRange(data, size); + gLastError = 0; + return 1; + } + + if (HIORead(offset + (gChannelInfo[chID].info.firstBlock << 0xD), data, size) == 0) { + mccDebugPrint("Error:Read data error."); + gLastError = 7; + goto exit; + } + + DCInvalidateRange(data, size); + + if (~(gChannelInfo[chID].eventMask) & 0x10) { + NotifyChannelEvent(chID, 0x10); + } + + if (~(gChannelInfo[chID].eventMask) & 0x40 && gChannelInfo[chID].callbackEvent) { + gChannelInfo[chID].callbackEvent(chID, 0x40, 0); + } + gLastError = 0; + return 1; + +exit:; + return 0; +} + +int MCCWrite(MCC_CHANNEL chID, u32 offset, void* data, s32 size, MCC_SYNC_STATE async) { +#ifndef DEBUG + int unused[11]; // fake but blah +#endif + mccDebugPrint("MCCWrite\n"); + + if (!gMccInitialized) { + gLastError = 1; + return 0; + } + if (chID < 1 || chID >= 0x10) { + gLastError = 0xE; + return 0; + } + if (!(async == 1 || async == 0)) { + gLastError = 0xD; + return 0; + } + if ((offset & 3) || ((u32)data & 0x1F) || (size % 32) != 0) { + gLastError = 0xD; + return 0; + } + if (AsyncResourceIsBusy()) { + gLastError = 0x15; + return 0; + } + if (LoadChannelInfo(gChannelInfo) == 0) { + mccDebugPrint("Error:Could not update channelInfo.\n"); + gLastError = 0xB; + goto exit; + } + if (!IsChannelOpened(chID)) { + mccDebugPrint("Error:This channel is closed."); + gLastError = 0x12; + goto exit; + } + if (gChannelInfo[chID].info.isLocked == 1) { + mccDebugPrint("Error:This channel was locked."); + gLastError = 0x13; + goto exit; + } + if (offset > (gChannelInfo[chID].info.blockLength << 0xD)) { + mccDebugPrint("Error:Invarid offset"); + gLastError = 0x10; + goto exit; + } + if (offset + size > (gChannelInfo[chID].info.blockLength << 0xD)) { + mccDebugPrint("Error:Invarid data size."); + gLastError = 0xF; + goto exit; + } + + if (async == 1) { + if (MCCCheckAsyncDone() == 0) { + mccDebugPrint("Error:Channel busy."); + gLastError = 0x15; + goto exit; + } + AsyncResourceStateBusy(chID, 0x100); + DCFlushRange(data, size); + if (HIOWriteAsync(offset + (gChannelInfo[chID].info.firstBlock << 0xD), data, size, MCCTxCallback) == 0) { + mccDebugPrint("Error:Write data error."); + gLastError = 8; + goto exit; + } + gLastError = 0; + return 1; + } + + DCFlushRange(data, size); + + if (HIOWrite(offset + (gChannelInfo[chID].info.firstBlock << 0xD), data, size) == 0) { + mccDebugPrint("Error:Write data error."); + gLastError = 8; + goto exit; + } + + if (~(gChannelInfo[chID].eventMask) & 0x20) { + NotifyChannelEvent(chID, 0x20); + } + + if (~(gChannelInfo[chID].eventMask) & 0x80 && gChannelInfo[chID].callbackEvent) { + gChannelInfo[chID].callbackEvent(chID, 0x80, 0); + } + gLastError = 0; + return 1; + +exit: + return 0; +} + +int MCCCheckAsyncDone() { + u16 stat; + u16 mode; + u8 chID; +#ifndef DEBUG + int unused[5]; // fake but blah +#endif + + if (!gMccInitialized) { + gLastError = 1; + return 0; + } + + stat = AsyncResourceGetStat(); + + if (stat == 0x1000) { + return 0; + } else if (stat && stat == 0x2000) { + mode = AsyncResourceGetMode(); + chID = AsyncResourceGetChannel(); + AsyncResourceClearState(); + if (mode == 0) { + if (~(gChannelInfo[chID].eventMask) & 0x10) { + NotifyChannelEvent(chID, 0x10); + } + if (~(gChannelInfo[chID].eventMask) & 0x40 && gChannelInfo[chID].callbackEvent) { + gChannelInfo[chID].callbackEvent(chID, 0x40, 0); + } + } else { + if (~(gChannelInfo[chID].eventMask) & 0x20) { + NotifyChannelEvent(chID, 0x20); + } + if (~(gChannelInfo[chID].eventMask) & 0x80 && gChannelInfo[chID].callbackEvent) { + gChannelInfo[chID].callbackEvent(chID, 0x80, 0); + } + } + } + + return 1; +} diff --git a/src/dolphin/mcc/tty.c b/src/dolphin/mcc/tty.c new file mode 100644 index 0000000000..1c230e4757 --- /dev/null +++ b/src/dolphin/mcc/tty.c @@ -0,0 +1,260 @@ +#include +#include + +#ifdef DEBUG +const char* __TTYVersion = "<< Dolphin SDK - TTY\tdebug build: Apr 5 2004 03:57:08 (0x2301) >>"; +#else +const char* __TTYVersion = "<< Dolphin SDK - TTY\trelease build: Apr 5 2004 04:15:50 (0x2301) >>"; +#endif + +volatile static u8 gBuf[0x2000]; + +static u32 gOldEvent; +volatile static MCC_CHANNEL gChID; +volatile static int gQuery; +volatile static u32 gReadDone; +volatile static u32 gPrintfID; +volatile static u32 gBufHead; +volatile static u32 gBufTail; + +// prototypes +static int ttyIsInitialized(void); +static void ShowChannelInfo(MCC_CHANNEL chID); +static void ttyMccChannelEvent(MCC_CHANNEL chID, u32 event, u32 value); +static void ttyClearProperty(MCC_CHANNEL chID); +static int ttyWaiting(int timeout, volatile int* flag); +static int ttyWrite(u32 offset, void* data, s32 size); +static int ttyFlush(u32 msgID, BOOL waitResult); + +static int ttyIsInitialized(void) { + BOOL bResult = gChID != 0; + return bResult; +} + +static void ShowChannelInfo(MCC_CHANNEL chID) { + MCC_Info info; + + MCCGetChannelInfo(chID, &info); + OSReport("%2d: FirstBlock:%02d,BlockLength:%02d,Connect:%s,Lock:%s.\n", chID, + info.firstBlock,info.blockLength, + (info.connect == MCC_CONNECT_DISCONNECT) ? "DISCONNECT" : + (info.connect == MCC_CONNECT_HOST_OPEN) ? "HOST_OPEN" : + (info.connect == MCC_CONNECT_TARGET_OPEN) ? "TARGET_OPEN" : + (info.connect == MCC_CONNECT_CONNECTED) ? "CONNECTED" : "UNKNOWN", + (info.isLocked == FALSE) ? "UNLOCKED" : + (info.isLocked == TRUE) ? "LOCKED" : "UNKNOWN"); +} + +static void ttyMccChannelEvent(MCC_CHANNEL chID, u32 event, u32 value) { + u32 notify; + u32 size; + u32 msgID; + + switch(event) { + case MCC_EVENT_CONNECT: + gChID = chID; + return; + case MCC_EVENT_DISCONNECT: + gChID = 0; + return; + case MCC_EVENT_UNK_0x100: + notify = (value & (0xF00000)); + switch(notify) { + case 0x200000: + if ((u16)value == 0x210) { + gQuery = 1; + } + return; + case 0x400000: + size = (value >> 8) & 0xFF; + msgID = (value) & 0xFF; + if ((gBufTail - gBufHead) >= 0x2000) { + gBufHead = ((u32) gBufHead < 0x2000U) ? gBufHead : gBufHead - 0x2000; + gBufTail = ((u32) gBufTail < 0x2000U) ? gBufTail : gBufTail - 0x2000; + } + if ((u32) gBufHead >= 0x2000U) { + gBufHead -= 0x2000; + gBufTail -= 0x2000; + } + if (size == 0) { + gBufHead += size << 5; + gReadDone = (u32) msgID; + return; + } + gBufHead += size << 5; + gReadDone = (u32) msgID; + } + } +} + +int TTYInit(MCC_EXI exiChannel, MCC_CHANNEL chID) { + if (ttyIsInitialized()) { + return 0; + } + + OSRegisterVersion(__TTYVersion); + + if (MCCInit(exiChannel, 5, NULL) && MCCOpen(chID, 1, ttyMccChannelEvent)) { + gOldEvent = MCCSetChannelEventMask(chID, 0x30); + ttyClearProperty(chID); + return 1; + } + + return 0; +} + +void TTYExit(void) { + if (ttyIsInitialized()) { + MCCSetChannelEventMask(gChID, gOldEvent); + if (MCCClose(gChID) != 0) { + ttyClearProperty(0); + } + } +} + +int TTYQuery(void) { + u32 tick; + + if (ttyIsInitialized()) { + gQuery = 0; + if (MCCNotify(gChID, 0x100210)) { + return ttyWaiting(5, &gQuery); + } + } + + tick = OSGetTick(); + do {} while(OSTicksToSeconds(OSGetTick() - tick) < 5); + return 0; +} + +int TTYPrintf(const char* format, ...) { + if (ttyIsInitialized() && format != NULL) { + MCC_Hdr* hdr; + u32* id; + char* str; + u32 maxDataSize; + u32 formatLength; + u32 dataSize; + int err; + char* eof; + va_list argptr; + u32 prosecced; + + hdr = (void*)&gBuf; + id = (u32*)(hdr + 1); + str = (char*)(id + 1); + + maxDataSize = 8179; + formatLength = strlen(format); + if (formatLength > maxDataSize) { + eof = (void*)((-1 + maxDataSize + (u32)format)); + *(eof) = 0; + } + + va_start(argptr, format); + err = vsprintf(str, format, argptr); + if (strlen(str) < maxDataSize) { + str[strlen(str)] = 0; + } else { + err = -1; + } + + if (err < 0) { + return 0; + } + + hdr->length = strlen(str) + 13; + hdr->rsvd = 0; + hdr->protocol = 0x210; + dataSize = OSRoundUp32B(hdr->length) & ~1; + if ((0x2000 - (gBufTail - gBufHead)) <= dataSize) { + ttyFlush(gPrintfID, 1); + } + + gPrintfID += 1; + gPrintfID = (u8) gPrintfID; + *id = gPrintfID; + + if ((0x2000 - (gBufTail & 0x1FFF)) < dataSize) { + prosecced = 0x2000 - (gBufTail & 0x1FFF); + ttyWrite(gBufTail & 0x1FFF, (char*)&gBuf, prosecced); + ttyWrite(0, (char*)&gBuf + prosecced, dataSize - prosecced); + } else { + ttyWrite(gBufTail & 0x1FFF, (char*)&gBuf, dataSize); + } + + gBufTail += dataSize; + if (strchr(str, '\n') != 0) { + ttyFlush(gPrintfID, TRUE); + } else if (gPrintfID == 0xFF) { + ttyFlush(gPrintfID, TRUE); + } + + va_end(format); + return 1; + } + + return 0; +} + +int TTYFlush(void) { + if (!ttyIsInitialized()) { + return 0; + } + + return ttyFlush(gPrintfID, TRUE); +} + +static void ttyClearProperty(MCC_CHANNEL chID) { + gChID = chID; + gQuery = 0; + gReadDone = 0; + gPrintfID = 0; + gBufHead = 0; + gBufTail = 0; +} + +static int ttyWaiting(int timeout, volatile int* flag) { + u32 tickStart; + u32 tickDist; + + tickStart = OSGetTick(); + timeout = OSSecondsToTicks(timeout); + while(*flag == 0) { + tickDist = OSGetTick() - tickStart; + tickDist = (tickDist & 0x80000000) ? (0x80000000 - tickStart) + OSGetTick() : tickDist; + if (OSTicksToSeconds(tickDist) >= timeout) { + return 0; + } + } + + return 1; +} + +static int ttyWrite(u32 offset, void* data, s32 size) { + if (MCCWrite(gChID, offset, data, size, 0)) { + return 1; + } + return 0; +} + +static int ttyFlush(u32 msgID, BOOL waitResult) { + u32 notify; + + notify = msgID | 0x300000; + + if ((gBufTail - gBufHead) == 0) { + return 1; + } + + if (MCCNotify(gChID, notify) == 0) { + while(1) + ; + } + + if (waitResult) { + do {} while (gReadDone != msgID); + } + + return 1; +} diff --git a/src/dolphin/mix/mix.c b/src/dolphin/mix/mix.c new file mode 100644 index 0000000000..1ec6539b02 --- /dev/null +++ b/src/dolphin/mix/mix.c @@ -0,0 +1,1035 @@ +#include +#include + +u16 __MIXVolumeTable[965] = { + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 11, 11, 11, 11, 11, 11, + 11, 12, 12, 12, 12, 12, 12, 12, + 13, 13, 13, 13, 13, 13, 13, 14, + 14, 14, 14, 14, 14, 15, 15, 15, + 15, 15, 16, 16, 16, 16, 16, 17, + 17, 17, 17, 17, 18, 18, 18, 18, + 18, 19, 19, 19, 19, 19, 20, 20, + 20, 20, 21, 21, 21, 21, 22, 22, + 22, 22, 23, 23, 23, 24, 24, 24, + 24, 25, 25, 25, 26, 26, 26, 26, + 27, 27, 27, 28, 28, 28, 29, 29, + 29, 30, 30, 30, 31, 31, 32, 32, + 32, 33, 33, 33, 34, 34, 35, 35, + 35, 36, 36, 37, 37, 38, 38, 38, + 39, 39, 40, 40, 41, 41, 42, 42, + 43, 43, 44, 44, 45, 45, 46, 46, + 47, 47, 48, 49, 49, 50, 50, 51, + 51, 52, 53, 53, 54, 55, 55, 56, + 56, 57, 58, 58, 59, 60, 61, 61, + 62, 63, 63, 64, 65, 66, 66, 67, + 68, 69, 70, 70, 71, 72, 73, 74, + 75, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, + 98, 100, 101, 102, 103, 104, 106, 107, + 108, 109, 111, 112, 113, 114, 116, 117, + 118, 120, 121, 123, 124, 126, 127, 128, + 130, 131, 133, 135, 136, 138, 139, 141, + 143, 144, 146, 148, 149, 151, 153, 155, + 156, 158, 160, 162, 164, 166, 168, 170, + 171, 173, 175, 178, 180, 182, 184, 186, + 188, 190, 192, 195, 197, 199, 202, 204, + 206, 209, 211, 214, 216, 219, 221, 224, + 226, 229, 231, 234, 237, 240, 242, 245, + 248, 251, 254, 257, 260, 263, 266, 269, + 272, 275, 278, 282, 285, 288, 292, 295, + 298, 302, 305, 309, 312, 316, 320, 323, + 327, 331, 335, 339, 343, 347, 351, 355, + 359, 363, 367, 371, 376, 380, 384, 389, + 393, 398, 403, 407, 412, 417, 422, 427, + 431, 436, 442, 447, 452, 457, 462, 468, + 473, 479, 484, 490, 495, 501, 507, 513, + 519, 525, 531, 537, 543, 550, 556, 562, + 569, 576, 582, 589, 596, 603, 610, 617, + 624, 631, 638, 646, 653, 661, 669, 676, + 684, 692, 700, 708, 716, 725, 733, 742, + 750, 759, 768, 777, 786, 795, 804, 813, + 823, 832, 842, 852, 861, 871, 881, 892, + 902, 912, 923, 934, 945, 955, 967, 978, + 989, 1001, 1012, 1024, 1036, 1048, 1060, 1072, + 1085, 1097, 1110, 1123, 1136, 1149, 1162, 1176, + 1189, 1203, 1217, 1231, 1245, 1260, 1274, 1289, + 1304, 1319, 1334, 1350, 1365, 1381, 1397, 1414, + 1430, 1446, 1463, 1480, 1497, 1515, 1532, 1550, + 1568, 1586, 1604, 1623, 1642, 1661, 1680, 1700, + 1719, 1739, 1759, 1780, 1800, 1821, 1842, 1864, + 1885, 1907, 1929, 1951, 1974, 1997, 2020, 2043, + 2067, 2091, 2115, 2140, 2164, 2190, 2215, 2241, + 2266, 2293, 2319, 2346, 2373, 2401, 2429, 2457, + 2485, 2514, 2543, 2573, 2602, 2632, 2663, 2694, + 2725, 2757, 2789, 2821, 2853, 2887, 2920, 2954, + 2988, 3023, 3058, 3093, 3129, 3165, 3202, 3239, + 3276, 3314, 3353, 3391, 3431, 3470, 3511, 3551, + 3592, 3634, 3676, 3719, 3762, 3805, 3849, 3894, + 3939, 3985, 4031, 4078, 4125, 4173, 4221, 4270, + 4319, 4369, 4420, 4471, 4523, 4575, 4628, 4682, + 4736, 4791, 4846, 4902, 4959, 5017, 5075, 5133, + 5193, 5253, 5314, 5375, 5438, 5501, 5564, 5629, + 5694, 5760, 5827, 5894, 5962, 6031, 6101, 6172, + 6243, 6316, 6389, 6463, 6538, 6613, 6690, 6767, + 6846, 6925, 7005, 7086, 7168, 7251, 7335, 7420, + 7506, 7593, 7681, 7770, 7860, 7951, 8043, 8136, + 8230, 8326, 8422, 8520, 8618, 8718, 8819, 8921, + 9025, 9129, 9235, 9342, 9450, 9559, 9670, 9782, + 9895, 10010, 10126, 10243, 10362, 10482, 10603, 10726, + 10850, 10976, 11103, 11231, 11361, 11493, 11626, 11761, + 11897, 12035, 12174, 12315, 12458, 12602, 12748, 12895, + 13045, 13196, 13349, 13503, 13659, 13818, 13978, 14140, + 14303, 14469, 14636, 14806, 14977, 15151, 15326, 15504, + 15683, 15865, 16049, 16234, 16422, 16613, 16805, 17000, + 17196, 17396, 17597, 17801, 18007, 18215, 18426, 18640, + 18856, 19074, 19295, 19518, 19744, 19973, 20204, 20438, + 20675, 20914, 21156, 21401, 21649, 21900, 22153, 22410, + 22669, 22932, 23197, 23466, 23738, 24013, 24291, 24572, + 24857, 25144, 25436, 25730, 26028, 26329, 26634, 26943, + 27255, 27570, 27890, 28213, 28539, 28870, 29204, 29542, + 29884, 30230, 30580, 30934, 31293, 31655, 32022, 32392, + 32767, 33147, 33531, 33919, 34312, 34709, 35111, 35518, + 35929, 36345, 36766, 37192, 37622, 38058, 38499, 38944, + 39395, 39851, 40313, 40780, 41252, 41730, 42213, 42702, + 43196, 43696, 44202, 44714, 45232, 45756, 46286, 46821, + 47364, 47912, 48467, 49028, 49596, 50170, 50751, 51339, + 51933, 52535, 53143, 53758, 54381, 55011, 55648, 56292, + 56944, 57603, 58270, 58945, 59627, 60318, 61016, 61723, + 62438, 63161, 63892, 64632, 65380 +}; + +int __MIXPanTable[128] = { + 0x00000000, + 0x00000000, + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFE, + 0xFFFFFFFE, + 0xFFFFFFFE, + 0xFFFFFFFD, + 0xFFFFFFFD, + 0xFFFFFFFC, + 0xFFFFFFFC, + 0xFFFFFFFC, + 0xFFFFFFFB, + 0xFFFFFFFB, + 0xFFFFFFFB, + 0xFFFFFFFA, + 0xFFFFFFFA, + 0xFFFFFFF9, + 0xFFFFFFF9, + 0xFFFFFFF9, + 0xFFFFFFF8, + 0xFFFFFFF8, + 0xFFFFFFF7, + 0xFFFFFFF7, + 0xFFFFFFF6, + 0xFFFFFFF6, + 0xFFFFFFF6, + 0xFFFFFFF5, + 0xFFFFFFF5, + 0xFFFFFFF4, + 0xFFFFFFF4, + 0xFFFFFFF3, + 0xFFFFFFF3, + 0xFFFFFFF2, + 0xFFFFFFF2, + 0xFFFFFFF2, + 0xFFFFFFF1, + 0xFFFFFFF1, + 0xFFFFFFF0, + 0xFFFFFFF0, + 0xFFFFFFEF, + 0xFFFFFFEF, + 0xFFFFFFEE, + 0xFFFFFFEE, + 0xFFFFFFED, + 0xFFFFFFEC, + 0xFFFFFFEC, + 0xFFFFFFEB, + 0xFFFFFFEB, + 0xFFFFFFEA, + 0xFFFFFFEA, + 0xFFFFFFE9, + 0xFFFFFFE9, + 0xFFFFFFE8, + 0xFFFFFFE7, + 0xFFFFFFE7, + 0xFFFFFFE6, + 0xFFFFFFE6, + 0xFFFFFFE5, + 0xFFFFFFE4, + 0xFFFFFFE4, + 0xFFFFFFE3, + 0xFFFFFFE2, + 0xFFFFFFE2, + 0xFFFFFFE1, + 0xFFFFFFE0, + 0xFFFFFFDF, + 0xFFFFFFDF, + 0xFFFFFFDE, + 0xFFFFFFDD, + 0xFFFFFFDC, + 0xFFFFFFDC, + 0xFFFFFFDB, + 0xFFFFFFDA, + 0xFFFFFFD9, + 0xFFFFFFD8, + 0xFFFFFFD8, + 0xFFFFFFD7, + 0xFFFFFFD6, + 0xFFFFFFD5, + 0xFFFFFFD4, + 0xFFFFFFD3, + 0xFFFFFFD2, + 0xFFFFFFD1, + 0xFFFFFFD0, + 0xFFFFFFCF, + 0xFFFFFFCE, + 0xFFFFFFCD, + 0xFFFFFFCC, + 0xFFFFFFCA, + 0xFFFFFFC9, + 0xFFFFFFC8, + 0xFFFFFFC7, + 0xFFFFFFC5, + 0xFFFFFFC4, + 0xFFFFFFC3, + 0xFFFFFFC1, + 0xFFFFFFC0, + 0xFFFFFFBE, + 0xFFFFFFBD, + 0xFFFFFFBB, + 0xFFFFFFB9, + 0xFFFFFFB8, + 0xFFFFFFB6, + 0xFFFFFFB4, + 0xFFFFFFB2, + 0xFFFFFFB0, + 0xFFFFFFAD, + 0xFFFFFFAB, + 0xFFFFFFA9, + 0xFFFFFFA6, + 0xFFFFFFA3, + 0xFFFFFFA0, + 0xFFFFFF9D, + 0xFFFFFF9A, + 0xFFFFFF96, + 0xFFFFFF92, + 0xFFFFFF8D, + 0xFFFFFF88, + 0xFFFFFF82, + 0xFFFFFF7B, + 0xFFFFFF74, + 0xFFFFFF6A, + 0xFFFFFF5D, + 0xFFFFFF4C, + 0xFFFFFF2E, + 0xFFFFFC78 +}; + +s16 __MIX_DPL2_front[128] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFD, 0xFFFD, + 0xFFFD, 0xFFFC, 0xFFFC, 0xFFFC, 0xFFFB, 0xFFFB, + 0xFFFA, 0xFFFA, 0xFFFA, 0xFFF9, 0xFFF9, 0xFFF8, + 0xFFF8, 0xFFF7, 0xFFF7, 0xFFF6, 0xFFF5, 0xFFF5, + 0xFFF4, 0xFFF4, 0xFFF3, 0xFFF2, 0xFFF2, 0xFFF1, + 0xFFF0, 0xFFEF, 0xFFEF, 0xFFEE, 0xFFED, 0xFFEC, + 0xFFEB, 0xFFEB, 0xFFEA, 0xFFE9, 0xFFE8, 0xFFE7, + 0xFFE6, 0xFFE5, 0xFFE4, 0xFFE3, 0xFFE2, 0xFFE1, + 0xFFE0, 0xFFDE, 0xFFDD, 0xFFDC, 0xFFDB, 0xFFDA, + 0xFFD8, 0xFFD7, 0xFFD6, 0xFFD4, 0xFFD3, 0xFFD1, + 0xFFD0, 0xFFCE, 0xFFCC, 0xFFCB, 0xFFC9, 0xFFC7, + 0xFFC6, 0xFFC4, 0xFFC2, 0xFFC0, 0xFFBE, 0xFFBC, + 0xFFBA, 0xFFB7, 0xFFB5, 0xFFB3, 0xFFB0, 0xFFAE, + 0xFFAB, 0xFFA8, 0xFFA6, 0xFFA3, 0xFFA0, 0xFF9C, + 0xFF99, 0xFF96, 0xFF92, 0xFF8E, 0xFF8A, 0xFF86, + 0xFF82, 0xFF7D, 0xFF78, 0xFF73, 0xFF6E, 0xFF68, + 0xFF61, 0xFF5A, 0xFF53, 0xFF4B, 0xFF42, 0xFF37, + 0xFF2C, 0xFF1F, 0xFF0F, 0xFEFB, 0xFEE2, 0xFEBF, + 0xFE83, 0xFC40 +}; + +s16 __MIX_DPL2_rear[128] = { + 0xFFC3, 0xFFC3, 0xFFC4, 0xFFC5, 0xFFC5, 0xFFC6, + 0xFFC6, 0xFFC7, 0xFFC8, 0xFFC8, 0xFFC9, 0xFFC9, + 0xFFCA, 0xFFCB, 0xFFCB, 0xFFCC, 0xFFCC, 0xFFCD, + 0xFFCE, 0xFFCE, 0xFFCF, 0xFFCF, 0xFFD0, 0xFFD0, + 0xFFD1, 0xFFD1, 0xFFD2, 0xFFD2, 0xFFD3, 0xFFD3, + 0xFFD4, 0xFFD4, 0xFFD5, 0xFFD5, 0xFFD6, 0xFFD6, + 0xFFD7, 0xFFD7, 0xFFD8, 0xFFD8, 0xFFD9, 0xFFD9, + 0xFFDA, 0xFFDA, 0xFFDA, 0xFFDB, 0xFFDB, 0xFFDC, + 0xFFDC, 0xFFDD, 0xFFDD, 0xFFDD, 0xFFDE, 0xFFDE, + 0xFFDF, 0xFFDF, 0xFFE0, 0xFFE0, 0xFFE0, 0xFFE1, + 0xFFE1, 0xFFE1, 0xFFE2, 0xFFE2, 0xFFE3, 0xFFE3, + 0xFFE3, 0xFFE4, 0xFFE4, 0xFFE4, 0xFFE5, 0xFFE5, + 0xFFE5, 0xFFE6, 0xFFE6, 0xFFE6, 0xFFE7, 0xFFE7, + 0xFFE7, 0xFFE8, 0xFFE8, 0xFFE8, 0xFFE9, 0xFFE9, + 0xFFE9, 0xFFEA, 0xFFEA, 0xFFEA, 0xFFEB, 0xFFEB, + 0xFFEB, 0xFFEC, 0xFFEC, 0xFFEC, 0xFFEC, 0xFFED, + 0xFFED, 0xFFED, 0xFFEE, 0xFFEE, 0xFFEE, 0xFFEE, + 0xFFEF, 0xFFEF, 0xFFEF, 0xFFEF, 0xFFF0, 0xFFF0, + 0xFFF0, 0xFFF0, 0xFFF1, 0xFFF1, 0xFFF1, 0xFFF1, + 0xFFF2, 0xFFF2, 0xFFF2, 0xFFF2, 0xFFF3, 0xFFF3, + 0xFFF3, 0xFFF3, 0xFFF3, 0xFFF4, 0xFFF4, 0xFFF4, + 0xFFF4, 0xFFF5 +}; + +u8 __MIXAIVolumeTable[50] = { + 0x00, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x02, + 0x02, 0x02, 0x02, 0x03, + 0x03, 0x04, 0x04, 0x05, + 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, + 0x0E, 0x10, 0x12, 0x14, + 0x16, 0x19, 0x1C, 0x20, + 0x24, 0x28, 0x2D, 0x32, + 0x39, 0x40, 0x47, 0x50, + 0x5A, 0x65, 0x71, 0x7F, + 0x8F, 0xA0, 0xB4, 0xCA, + 0xE3, 0xFF +}; + +static MIXChannel __MIXChannel[64]; + +static int __MIXDvdStreamAttenCurrent; +static int __MIXDvdStreamAttenUser; +static u32 __MIXSoundMode; + +// prototypes +static u16 __MIXGetVolume(int db); +static int __MIXGetPanL(int pan); +static int __MIXGetPanR(int pan); +static void __MIXResetChannel(MIXChannel* channel); +static void __MIXSetPan(MIXChannel* channel); +static int __MIXClampPan(int pan); + +static u16 __MIXGetVolume(int db_) { + int db = db_; + if (db <= -0x388) { + return 0; + } + if (db >= 0x3C) { + return 0xFF64; + } + return __MIXVolumeTable[db + 0x388]; +} + +static void __MIXSetPan(MIXChannel* channel) { + int pan, span; + int ipan, ispan; + + ASSERTLINE(281, (channel->pan <= 127) && (channel->pan >= 0)); + ASSERTLINE(282, (channel->span <= 127) && (channel->span >= 0)); + + pan = channel->pan; + ipan = 127 - pan; + span = channel->span; + ispan = 127 - span; + + if (__MIXSoundMode == MIX_SOUND_MODE_DPL2) { + channel->l = __MIX_DPL2_front[pan]; + channel->r = __MIX_DPL2_front[ipan]; + channel->f = __MIX_DPL2_front[ispan]; + channel->b = __MIX_DPL2_front[span]; + channel->l1 = __MIX_DPL2_rear[ipan]; + channel->r1 = __MIX_DPL2_rear[pan]; + } else { + channel->l = __MIXPanTable[pan]; + channel->r = __MIXPanTable[ipan]; + channel->f = __MIXPanTable[ispan]; + channel->b = __MIXPanTable[span]; + } +} + +static void __MIXResetChannel(MIXChannel* channel) { + channel->mode = 0x50000000; + channel->input = 0; + channel->auxA = -0x3C0; + channel->auxB = -0x3C0; + channel->fader = 0; + channel->pan = 0x40; + channel->span = 0x7F; + + channel->v = channel->vL = channel->vR = channel->vS = channel->vAL = + channel->vAR = channel->vAS = channel->vBL = channel->vBR = channel->vBS = 0; + + __MIXSetPan(channel); +} + +static int __MIXClampPan(int pan) { + if (pan < 0) { + return 0; + } + if (pan > 0x7F) { + return 0x7F; + } + return pan; +} + +void MIXInit(void) { + int i; + + for (i = 0; i < 64; i++) { + __MIXResetChannel(&__MIXChannel[i]); + } + + __MIXDvdStreamAttenCurrent = 0; + __MIXDvdStreamAttenUser = 0; + __MIXSoundMode = MIX_SOUND_MODE_STEREO; +} + +void MIXQuit(void) {} + +void MIXSetSoundMode(u32 mode) { + ASSERTLINE(421, (mode == MIX_SOUND_MODE_MONO) || (mode == MIX_SOUND_MODE_STEREO) || + (mode == MIX_SOUND_MODE_SURROUND) || (mode == MIX_SOUND_MODE_DPL2)); + __MIXSoundMode = mode; +} + +u32 MIXGetSoundMode(void) { + return __MIXSoundMode; +} + +void MIXInitChannel(AXVPB* axvpb, u32 mode, int input, int auxA, int auxB, int pan, int span, int fader) { + BOOL old; + MIXChannel* c; + u16 mixerCtrl; + u16* p; + + ASSERTLINE(478, axvpb); + + c = &__MIXChannel[axvpb->index]; + + c->axvpb = axvpb; + c->mode = mode & 7; + c->input = input; + c->auxA = auxA; + c->auxB = auxB; + c->pan = pan; + c->span = span; + c->fader = fader; + + __MIXSetPan(c); + + if (c->mode & 4) { + c->v = 0; + } else { + c->v = __MIXGetVolume(input); + } + + mixerCtrl = 0; + + switch(__MIXSoundMode) { + case MIX_SOUND_MODE_MONO: + c->vL = __MIXGetVolume(c->fader + c->f); + c->vR = __MIXGetVolume(c->fader + c->f); + c->vS = __MIXGetVolume(c->fader + c->b - 30); + + if (c->mode & 1) { + c->vAL = __MIXGetVolume(c->auxA + c->f); + c->vAR = __MIXGetVolume(c->auxA + c->f); + c->vAS = __MIXGetVolume(c->auxA + c->b - 30); + } else { + c->vAL = __MIXGetVolume(c->fader + c->auxA + c->f); + c->vAR = __MIXGetVolume(c->fader + c->auxA + c->f); + c->vAS = __MIXGetVolume(c->fader + c->auxA + c->b - 30); + } + + if (c->mode & 2) { + c->vBL = __MIXGetVolume(c->auxB + c->f); + c->vBR = __MIXGetVolume(c->auxB + c->f); + c->vBS = __MIXGetVolume(c->auxB + c->b - 30); + } else { + c->vBL = __MIXGetVolume(c->fader + c->auxB + c->f); + c->vBR = __MIXGetVolume(c->fader + c->auxB + c->f); + c->vBS = __MIXGetVolume(c->fader + c->auxB + c->b - 30); + } + break; + case MIX_SOUND_MODE_STEREO: + case MIX_SOUND_MODE_SURROUND: + c->vL = __MIXGetVolume(c->fader + c->l + c->f); + c->vR = __MIXGetVolume(c->fader + c->r + c->f); + c->vS = __MIXGetVolume(c->fader + c->b - 30); + + if (c->mode & 1) { + c->vAL = __MIXGetVolume(c->auxA + c->l + c->f); + c->vAR = __MIXGetVolume(c->auxA + c->r + c->f); + c->vAS = __MIXGetVolume(c->auxA + c->b - 30); + } else { + c->vAL = __MIXGetVolume(c->fader + c->auxA + c->l + c->f); + c->vAR = __MIXGetVolume(c->fader + c->auxA + c->r + c->f); + c->vAS = __MIXGetVolume(c->fader + c->auxA + c->b - 30); + } + + if (c->mode & 2) { + c->vBL = __MIXGetVolume(c->auxB + c->l + c->f); + c->vBR = __MIXGetVolume(c->auxB + c->r + c->f); + c->vBS = __MIXGetVolume(c->auxB + c->b - 30); + } else { + c->vBL = __MIXGetVolume(c->fader + c->auxB + c->l + c->f); + c->vBR = __MIXGetVolume(c->fader + c->auxB + c->r + c->f); + c->vBS = __MIXGetVolume(c->fader + c->auxB + c->b - 30); + } + break; + case MIX_SOUND_MODE_DPL2: + c->vL = __MIXGetVolume(c->fader + c->l + c->f); + c->vR = __MIXGetVolume(c->fader + c->r + c->f); + c->vBL = __MIXGetVolume(c->fader + c->l1 + c->b); + c->vBR = __MIXGetVolume(c->fader + c->r1 + c->b); + + if (c->mode & 1) { + c->vAL = __MIXGetVolume(c->auxA + c->l + c->f); + c->vAR = __MIXGetVolume(c->auxA + c->r + c->f); + c->vAS = __MIXGetVolume(c->auxA + c->l1 + c->b); + c->vBS = __MIXGetVolume(c->auxA + c->r1 + c->b); + } else { + c->vAL = __MIXGetVolume(c->fader + c->auxA + c->l + c->f); + c->vAR = __MIXGetVolume(c->fader + c->auxA + c->r + c->f); + c->vAS = __MIXGetVolume(c->fader + c->auxA + c->l1 + c->b); + c->vBS = __MIXGetVolume(c->fader + c->auxA + c->r1 + c->b); + } + + mixerCtrl |= 0x4000; + break; + } + + old = OSDisableInterrupts(); + axvpb->pb.ve.currentVolume = c->v; + axvpb->pb.ve.currentDelta = 0; + + p = (u16*)&axvpb->pb.mix; + + if ((*p++ = c->vL)) + mixerCtrl |= 0x1; + *p++ = 0; + + if ((*p++ = c->vR)) + mixerCtrl |= 0x2; + *p++ = 0; + + if ((*p++ = c->vAL)) + mixerCtrl |= 0x10; + *p++ = 0; + + if ((*p++ = c->vAR)) + mixerCtrl |= 0x20; + *p++ = 0; + + if ((*p++ = c->vBL)) + mixerCtrl |= 0x200; + *p++ = 0; + + if ((*p++ = c->vBR)) + mixerCtrl |= 0x400; + *p++ = 0; + + if ((*p++ = c->vBS)) + mixerCtrl |= 0x1000; + *p++ = 0; + + if ((*p++ = c->vS)) + mixerCtrl |= 0x4; + *p++ = 0; + + if ((*p++ = c->vAS)) + mixerCtrl |= 0x80; + *p++ = 0; + + axvpb->pb.mixerCtrl = mixerCtrl; + axvpb->sync |= (AX_SYNC_FLAG_COPYMXRCTRL | AX_SYNC_FLAG_COPYAXPBMIX | AX_SYNC_FLAG_COPYVOL); + OSRestoreInterrupts(old); +} + +void MIXReleaseChannel(AXVPB* axvpb) { + ASSERTLINE(657, axvpb); + __MIXChannel[axvpb->index].axvpb = 0; +} + +void MIXResetControls(AXVPB* p) { + __MIXResetChannel(&__MIXChannel[p->index]); +} + +void MIXSetInput(AXVPB* p, int dB) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->input = dB; + channel->mode |= 0x10000000; +} + +void MIXAdjustInput(AXVPB* p, int dB) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->input += dB; + channel->mode |= 0x10000000; +} + +int MIXGetInput(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + return channel->input; +} + +void MIXAuxAPostFader(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->mode &= 0xFFFFFFFE; + channel->mode |= 0x40000000; +} + +void MIXAuxAPreFader(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->mode |= 0x40000001; +} + +int MIXAuxAIsPostFader(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + if (channel->mode & 1) { + return 0; + } + return 1; +} + +void MIXSetAuxA(AXVPB* p, int dB) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->auxA = dB; + channel->mode |= 0x40000000; +} + +void MIXAdjustAuxA(AXVPB* p, int dB) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->auxA += dB; + channel->mode |= 0x40000000; +} + +int MIXGetAuxA(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + return channel->auxA; +} + +void MIXAuxBPostFader(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->mode &= 0xFFFFFFFD; + channel->mode |= 0x40000000; +} + +void MIXAuxBPreFader(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->mode |= 0x40000002; +} + +int MIXAuxBIsPostFader(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + if (channel->mode & 2) { + return 0; + } + return 1; +} + +void MIXSetAuxB(AXVPB* p, int dB) { + MIXChannel* channel; + if (__MIXSoundMode == MIX_SOUND_MODE_DPL2) + return; + + channel = &__MIXChannel[p->index]; + channel->auxB = dB; + channel->mode |= 0x40000000; +} + +void MIXAdjustAuxB(AXVPB* p, int dB) { + MIXChannel* channel; + if (__MIXSoundMode == MIX_SOUND_MODE_DPL2) + return; + + channel = &__MIXChannel[p->index]; + channel->auxB += dB; + channel->mode |= 0x40000000; +} + +int MIXGetAuxB(AXVPB* p) { + MIXChannel* channel; + if (__MIXSoundMode == MIX_SOUND_MODE_DPL2) + return -0x3C0; + + channel = &__MIXChannel[p->index]; + return channel->auxB; +} + +void MIXSetPan(AXVPB* p, int pan) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->pan = __MIXClampPan(pan); + __MIXSetPan(channel); + channel->mode |= 0x40000000; +} + +void MIXAdjustPan(AXVPB* p, int pan) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->pan = __MIXClampPan(channel->pan + pan); + __MIXSetPan(channel); + channel->mode |= 0x40000000; +} + +int MIXGetPan(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + return channel->pan; +} + +void MIXSetSPan(AXVPB* p, int span) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->span = __MIXClampPan(span); + __MIXSetPan(channel); + channel->mode |= 0x40000000; +} + +void MIXAdjustSPan(AXVPB* p, int span) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->span = __MIXClampPan(channel->span + span); + __MIXSetPan(channel); + channel->mode |= 0x40000000; +} + +int MIXGetSPan(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + return channel->span; +} + +void MIXMute(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->mode |= 0x10000004; +} + +void MIXUnMute(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->mode &= 0xFFFFFFFB; + channel->mode |= 0x10000000; +} + +int MIXIsMute(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + if (channel->mode & 4) { + return 1; + } + return 0; +} + +void MIXSetFader(AXVPB* p, int dB) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->fader = dB; + channel->mode |= 0x40000000; +} + +void MIXAdjustFader(AXVPB* p, int dB) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + channel->fader += dB; + channel->mode |= 0x40000000; +} + +int MIXGetFader(AXVPB* p) { + MIXChannel* channel; + + channel = &__MIXChannel[p->index]; + return channel->fader; +} + +void MIXSetDvdStreamFader(int dB) { + int db; + + db = dB; + if (db < -0x31) { + db = -0x31; + } + if (db > 0) { + db = 0; + } + __MIXDvdStreamAttenUser = db; +} + +int MIXGetDvdStreamFader(void) { + return __MIXDvdStreamAttenUser; +} + +void MIXUpdateSettings(void) { + int i; + int setNewMixLevel; + int setNewInputLevel; + MIXChannel* c; + AXVPB* axvpb; + u16 mixerCtrl; + u16* p; + + for (i = 0; i < AX_MAX_VOICES; i++) { + setNewInputLevel = 0; + setNewMixLevel = 0; + + c = &__MIXChannel[i]; + axvpb = c->axvpb; + + if (axvpb) { + mixerCtrl = 0; + + if (c->mode & 0x20000000) { + c->v = c->v1; + c->mode &= ~0x20000000; + setNewInputLevel = TRUE; + } + + if (c->mode & 0x10000000) { + if (c->mode & 4) { + c->v1 = 0; + } else { + c->v1 = __MIXGetVolume(c->input); + } + + c->mode &= ~0x10000000; + c->mode |= 0x20000000; + setNewInputLevel = TRUE; + } + + if (c->mode & 0x80000000) { + c->vL = c->vL1; + c->vR = c->vR1; + c->vS = c->vS1; + c->vAL = c->vAL1; + c->vAR = c->vAR1; + c->vAS = c->vAS1; + c->vBL = c->vBL1; + c->vBR = c->vBR1; + c->vBS = c->vBS1; + + c->mode &= ~0x80000000; + setNewMixLevel = TRUE; + } + + if (c->mode & 0x40000000) { + switch(__MIXSoundMode) { + case MIX_SOUND_MODE_MONO: + c->vL1 = __MIXGetVolume(c->fader + c->f); + c->vR1 = __MIXGetVolume(c->fader + c->f); + c->vS1 = __MIXGetVolume(c->fader + c->b - 30); + + if (c->mode & 1) { + c->vAL1 = __MIXGetVolume(c->auxA + c->f); + c->vAR1 = __MIXGetVolume(c->auxA + c->f); + c->vAS1 = __MIXGetVolume(c->auxA + c->b - 30); + } else { + c->vAL1 = __MIXGetVolume(c->fader + c->auxA + c->f); + c->vAR1 = __MIXGetVolume(c->fader + c->auxA + c->f); + c->vAS1 = __MIXGetVolume(c->fader + c->auxA + c->b - 30); + } + + if (c->mode & 2) { + c->vBL1 = __MIXGetVolume(c->auxB + c->f); + c->vBR1 = __MIXGetVolume(c->auxB + c->f); + c->vBS1 = __MIXGetVolume(c->auxB + c->b - 30); + } else { + c->vBL1 = __MIXGetVolume(c->fader + c->auxB + c->f); + c->vBR1 = __MIXGetVolume(c->fader + c->auxB + c->f); + c->vBS1 = __MIXGetVolume(c->fader + c->auxB + c->b - 30); + } + break; + case MIX_SOUND_MODE_STEREO: + case MIX_SOUND_MODE_SURROUND: + c->vL1 = __MIXGetVolume(c->fader + c->l + c->f); + c->vR1 = __MIXGetVolume(c->fader + c->r + c->f); + c->vS1 = __MIXGetVolume(c->fader + c->b - 30); + + if (c->mode & 1) { + c->vAL1 = __MIXGetVolume(c->auxA + c->l + c->f); + c->vAR1 = __MIXGetVolume(c->auxA + c->r + c->f); + c->vAS1 = __MIXGetVolume(c->auxA + c->b - 30); + } else { + c->vAL1 = __MIXGetVolume(c->fader + c->auxA + c->l + c->f); + c->vAR1 = __MIXGetVolume(c->fader + c->auxA + c->r + c->f); + c->vAS1 = __MIXGetVolume(c->fader + c->auxA + c->b - 30); + } + + if (c->mode & 2) { + c->vBL1 = __MIXGetVolume(c->auxB + c->l + c->f); + c->vBR1 = __MIXGetVolume(c->auxB + c->r + c->f); + c->vBS1 = __MIXGetVolume(c->auxB + c->b - 30); + } else { + c->vBL1 = __MIXGetVolume(c->fader + c->auxB + c->l + c->f); + c->vBR1 = __MIXGetVolume(c->fader + c->auxB + c->r + c->f); + c->vBS1 = __MIXGetVolume(c->fader + c->auxB + c->b - 30); + } + break; + case MIX_SOUND_MODE_DPL2: + c->vL1 = __MIXGetVolume(c->fader + c->l + c->f); + c->vR1 = __MIXGetVolume(c->fader + c->r + c->f); + c->vBL1 = __MIXGetVolume(c->fader + c->l1 + c->b); + c->vBR1 = __MIXGetVolume(c->fader + c->r1 + c->b); + + if (c->mode & 1) { + c->vAL1 = __MIXGetVolume(c->auxA + c->l + c->f); + c->vAR1 = __MIXGetVolume(c->auxA + c->r + c->f); + c->vAS1 = __MIXGetVolume(c->auxA + c->l1 + c->b); + c->vBS1 = __MIXGetVolume(c->auxA + c->r1 + c->b); + } else { + c->vAL1 = __MIXGetVolume(c->fader + c->auxA + c->l + c->f); + c->vAR1 = __MIXGetVolume(c->fader + c->auxA + c->r + c->f); + c->vAS1 = __MIXGetVolume(c->fader + c->auxA + c->l1 + c->b); + c->vBS1 = __MIXGetVolume(c->fader + c->auxA + c->r1 + c->b); + } + + mixerCtrl |= 0x4000; + break; + } + + c->mode &= ~0x40000000; + c->mode |= 0x80000000; + setNewMixLevel = TRUE; + } + + if (setNewInputLevel) { + axvpb->pb.ve.currentVolume = c->v; + axvpb->pb.ve.currentDelta = (s16)((c->v1 - c->v) / 160); + axvpb->sync |= 0x200; + } + + if (setNewMixLevel) { + p = (u16*)&axvpb->pb.mix; + + if ((*p++ = c->vL)) + mixerCtrl |= 0x1; + + if ((*p++ = (u16)((c->vL1 - c->vL) / 160))) + mixerCtrl |= 0x8; + + if ((*p++ = c->vR)) + mixerCtrl |= 0x2; + + if ((*p++ = (u16)((c->vR1 - c->vR) / 160))) + mixerCtrl |= 0x8; + + if ((*p++ = c->vAL)) + mixerCtrl |= 0x10; + + if ((*p++ = (u16)((c->vAL1 - c->vAL) / 160))) + mixerCtrl |= 0x40; + + if ((*p++ = c->vAR)) + mixerCtrl |= 0x20; + + if ((*p++ = (u16)((c->vAR1 - c->vAR) / 160))) + mixerCtrl |= 0x40; + + if ((*p++ = c->vBL)) + mixerCtrl |= 0x200; + + if ((*p++ = (u16)((c->vBL1 - c->vBL) / 160))) + mixerCtrl |= 0x800; + + if ((*p++ = c->vBR)) + mixerCtrl |= 0x400; + + if ((*p++ = (u16)((c->vBR1 - c->vBR) / 160))) + mixerCtrl |= 0x800; + + if ((*p++ = c->vBS)) + mixerCtrl |= 0x1000; + + if ((*p++ = (u16)((c->vBS1 - c->vBS) / 160))) + mixerCtrl |= 0x2000; + + if ((*p++ = c->vS)) + mixerCtrl |= 0x4; + + if ((*p++ = (u16)((c->vS1 - c->vS) / 160))) + mixerCtrl |= 0x8; + + if ((*p++ = c->vAS)) + mixerCtrl |= 0x80; + + if ((*p++ = (u16)((c->vAS1 - c->vAS) / 160))) + mixerCtrl |= 0x100; + + axvpb->pb.mixerCtrl = mixerCtrl; + axvpb->sync |= 0x12; + } + } + } + + if (__MIXDvdStreamAttenUser > __MIXDvdStreamAttenCurrent) { + __MIXDvdStreamAttenCurrent++; + AISetStreamVolLeft(__MIXAIVolumeTable[__MIXDvdStreamAttenCurrent]); + AISetStreamVolRight(__MIXAIVolumeTable[__MIXDvdStreamAttenCurrent]); + } else if (__MIXDvdStreamAttenUser < __MIXDvdStreamAttenCurrent) { + __MIXDvdStreamAttenCurrent--; + AISetStreamVolLeft(__MIXAIVolumeTable[__MIXDvdStreamAttenCurrent]); + AISetStreamVolRight(__MIXAIVolumeTable[__MIXDvdStreamAttenCurrent]); + } +} diff --git a/src/dolphin/mtx/mtx.c b/src/dolphin/mtx/mtx.c index e744abace3..f177c1739a 100644 --- a/src/dolphin/mtx/mtx.c +++ b/src/dolphin/mtx/mtx.c @@ -1,234 +1,566 @@ -#include "dolphin/mtx.h" -#include "math.h" +#include +#include +#include -void C_MTXIdentity(Mtx mtx) { - mtx[0][0] = 1.0f; - mtx[0][1] = 0.0f; - mtx[0][2] = 0.0f; - mtx[1][0] = 0.0f; - mtx[1][1] = 1.0f; - mtx[1][2] = 0.0f; - mtx[2][0] = 0.0f; - mtx[2][1] = 0.0f; - mtx[2][2] = 1.0f; +static f32 Unit01[2] = { + 0.0f, + 1.0f +}; + +void C_MTXIdentity(Mtx m) { + ASSERTMSGLINE(189, m, "MtxIdentity(): NULL Mtx 'm' "); + m[0][0] = 1; + m[0][1] = 0; + m[0][2] = 0; + m[0][3] = 0; + m[1][0] = 0; + m[1][1] = 1; + m[1][2] = 0; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = 1; + m[2][3] = 0; } -/* 80346484-803464B0 340DC4 002C+00 0/0 27/27 13/13 .text PSMTXIdentity */ void PSMTXIdentity(register Mtx m) { - register f32 zero_c = 0.0f; - register f32 one_c = 1.0f; + register f32 c_zero = 0.0f; + register f32 c_one = 1.0f; register f32 c_01; register f32 c_10; -#ifdef __MWERKS__ // clang-format off - asm { - psq_st zero_c, 8(m), 0, 0 - ps_merge01 c_01, zero_c, one_c - psq_st zero_c, 24(m), 0, 0 - ps_merge10 c_10, one_c, zero_c - psq_st zero_c, 32(m), 0, 0 - psq_st c_01, 16(m), 0, 0 - psq_st c_10, 0(m), 0, 0 - psq_st c_10, 40(m), 0, 0 - } -#endif // clang-format on + asm { + psq_st c_zero, 8(m), 0, 0 + ps_merge01 c_01, c_zero, c_one + psq_st c_zero, 24(m), 0, 0 + ps_merge10 c_10, c_one, c_zero + psq_st c_zero, 32(m), 0, 0 + psq_st c_01, 16(m), 0, 0 + psq_st c_10, 0(m), 0, 0 + psq_st c_10, 40(m), 0, 0 + } +} + +void C_MTXCopy(const Mtx src, Mtx dst) { + ASSERTMSGLINE(250, src, "MTXCopy(): NULL MtxPtr 'src' "); + ASSERTMSGLINE(251, dst, "MTXCopy(): NULL MtxPtr 'dst' "); + if (src != dst) { + dst[0][0] = src[0][0]; + dst[0][1] = src[0][1]; + dst[0][2] = src[0][2]; + dst[0][3] = src[0][3]; + dst[1][0] = src[1][0]; + dst[1][1] = src[1][1]; + dst[1][2] = src[1][2]; + dst[1][3] = src[1][3]; + dst[2][0] = src[2][0]; + dst[2][1] = src[2][1]; + dst[2][2] = src[2][2]; + dst[2][3] = src[2][3]; + } } -/* 803464B0-803464E4 340DF0 0034+00 0/0 119/119 1436/1436 .text PSMTXCopy */ asm void PSMTXCopy(const register Mtx src, register Mtx dst) { -#ifdef __MWERKS__ // clang-format off - nofralloc - - psq_l fp0, 0(src), 0, 0 - psq_st fp0, 0(dst), 0, 0 - psq_l fp1, 8(src), 0, 0 - psq_st fp1, 8(dst), 0, 0 - psq_l fp2, 16(src), 0, 0 - psq_st fp2, 16(dst), 0, 0 - psq_l fp3, 24(src), 0, 0 - psq_st fp3, 24(dst), 0, 0 - psq_l fp4, 32(src), 0, 0 - psq_st fp4, 32(dst), 0, 0 - psq_l fp5, 40(src), 0, 0 - psq_st fp5, 40(dst), 0, 0 - - blr -#endif // clang-format on + psq_l f0, 0(src), 0, 0 + psq_st f0, 0(dst), 0, 0 + psq_l f1, 8(src), 0, 0 + psq_st f1, 8(dst), 0, 0 + psq_l f2, 16(src), 0, 0 + psq_st f2, 16(dst), 0, 0 + psq_l f3, 24(src), 0, 0 + psq_st f3, 24(dst), 0, 0 + psq_l f4, 32(src), 0, 0 + psq_st f4, 32(dst), 0, 0 + psq_l f5, 40(src), 0, 0 + psq_st f5, 40(dst), 0, 0 } -/* 804509D0-804509D8 000450 0008+00 1/1 0/0 0/0 .sdata Unit01 */ -static f32 Unit01[2] = {0.0f, 1.0f}; +void C_MTXConcat(const Mtx a, const Mtx b, Mtx ab) { + Mtx mTmp; + MtxPtr m; -/* 803464E4-803465B0 340E24 00CC+00 0/0 109/109 30/30 .text PSMTXConcat */ -asm void PSMTXConcat(const register Mtx mA, const register Mtx mB, register Mtx mAB) { -#ifdef __MWERKS__ // clang-format off - nofralloc + ASSERTMSGLINE(324, a, "MTXConcat(): NULL MtxPtr 'a' "); + ASSERTMSGLINE(325, b, "MTXConcat(): NULL MtxPtr 'b' "); + ASSERTMSGLINE(326, ab, "MTXConcat(): NULL MtxPtr 'ab' "); -#define FP0 fp0 -#define FP1 fp1 -#define FP2 fp2 -#define FP3 fp3 -#define FP4 fp4 -#define FP5 fp5 -#define FP6 fp6 -#define FP7 fp7 -#define FP8 fp8 -#define FP9 fp9 -#define FP10 fp10 -#define FP11 fp11 -#define FP12 fp12 -#define FP13 fp13 -#define FP14 fp14 -#define FP15 fp15 -#define FP31 fp31 - stwu r1, -64(r1) - psq_l FP0, 0(mA), 0, 0 - stfd fp14, 8(r1) - psq_l FP6, 0(mB), 0, 0 - addis r6, 0, Unit01@ha - psq_l FP7, 8(mB), 0, 0 - stfd fp15, 16(r1) - addi r6, r6, Unit01@l - stfd fp31, 40(r1) - psq_l FP8, 16(mB), 0, 0 - ps_muls0 FP12, FP6, FP0 - psq_l FP2, 16(mA), 0, 0 - ps_muls0 FP13, FP7, FP0 - psq_l FP31, 0(r6), 0, 0 - ps_muls0 FP14, FP6, FP2 - psq_l FP9, 24(mB), 0, 0 - ps_muls0 FP15, FP7, FP2 - psq_l FP1, 8(mA), 0, 0 - ps_madds1 FP12, FP8, FP0, FP12 - psq_l FP3, 24(mA), 0, 0 - ps_madds1 FP14, FP8, FP2, FP14 - psq_l FP10, 32(mB), 0, 0 - ps_madds1 FP13, FP9, FP0, FP13 - psq_l FP11, 40(mB), 0, 0 - ps_madds1 FP15, FP9, FP2, FP15 - psq_l FP4, 32(mA), 0, 0 - psq_l FP5, 40(mA), 0, 0 - ps_madds0 FP12, FP10, FP1, FP12 - ps_madds0 FP13, FP11, FP1, FP13 - ps_madds0 FP14, FP10, FP3, FP14 - ps_madds0 FP15, FP11, FP3, FP15 - psq_st FP12, 0(mAB), 0, 0 + if (ab == a || ab == b) { + m = mTmp; + } else { + m = ab; + } - ps_muls0 FP2, FP6, FP4 - ps_madds1 FP13, FP31, FP1, FP13 - ps_muls0 FP0, FP7, FP4 - psq_st FP14, 16(mAB), 0, 0 - ps_madds1 FP15, FP31, FP3, FP15 + m[0][0] = 0 + a[0][2] * b[2][0] + ((a[0][0] * b[0][0]) + (a[0][1] * b[1][0])); + m[0][1] = 0 + a[0][2] * b[2][1] + ((a[0][0] * b[0][1]) + (a[0][1] * b[1][1])); + m[0][2] = 0 + a[0][2] * b[2][2] + ((a[0][0] * b[0][2]) + (a[0][1] * b[1][2])); + m[0][3] = a[0][3] + (a[0][2] * b[2][3] + (a[0][0] * b[0][3] + (a[0][1] * b[1][3]))); - psq_st FP13, 8(mAB), 0, 0 + m[1][0] = 0 + a[1][2] * b[2][0] + ((a[1][0] * b[0][0]) + (a[1][1] * b[1][0])); + m[1][1] = 0 + a[1][2] * b[2][1] + ((a[1][0] * b[0][1]) + (a[1][1] * b[1][1])); + m[1][2] = 0 + a[1][2] * b[2][2] + ((a[1][0] * b[0][2]) + (a[1][1] * b[1][2])); + m[1][3] = a[1][3] + (a[1][2] * b[2][3] + (a[1][0] * b[0][3] + (a[1][1] * b[1][3]))); - ps_madds1 FP2, FP8, FP4, FP2 - ps_madds1 FP0, FP9, FP4, FP0 - ps_madds0 FP2, FP10, FP5, FP2 - lfd fp14, 8(r1) - psq_st FP15, 24(mAB), 0, 0 - ps_madds0 FP0, FP11, FP5, FP0 - psq_st FP2, 32(mAB), 0, 0 - ps_madds1 FP0, FP31, FP5, FP0 - lfd fp15, 16(r1) - psq_st FP0, 40(mAB), 0, 0 + m[2][0] = 0 + a[2][2] * b[2][0] + ((a[2][0] * b[0][0]) + (a[2][1] * b[1][0])); + m[2][1] = 0 + a[2][2] * b[2][1] + ((a[2][0] * b[0][1]) + (a[2][1] * b[1][1])); + m[2][2] = 0 + a[2][2] * b[2][2] + ((a[2][0] * b[0][2]) + (a[2][1] * b[1][2])); + m[2][3] = a[2][3] + (a[2][2] * b[2][3] + (a[2][0] * b[0][3] + (a[2][1] * b[1][3]))); - lfd fp31, 40(r1) - addi r1, r1, 64 - - blr - -#undef FP0 -#undef FP1 -#undef FP2 -#undef FP3 -#undef FP4 -#undef FP5 -#undef FP6 -#undef FP7 -#undef FP8 -#undef FP9 -#undef FP10 -#undef FP11 -#undef FP12 -#undef FP13 -#undef FP14 -#undef FP15 -#undef FP31 -#endif // clang-format on + if (m == mTmp) { + C_MTXCopy(mTmp, ab); + } +} + +asm void PSMTXConcat(const register Mtx a, const register Mtx b, register Mtx ab) { + nofralloc + stwu r1, -64(r1) + psq_l f0, 0(a), 0, 0 + stfd f14, 8(r1) + psq_l f6, 0(b), 0, 0 + lis r6, Unit01@ha + psq_l f7, 8(b), 0, 0 + stfd f15, 16(r1) + addi r6, r6, Unit01@l + stfd f31, 40(r1) + psq_l f8, 16(b), 0, 0 + ps_muls0 f12, f6, f0 + psq_l f2, 16(a), 0, 0 + ps_muls0 f13, f7, f0 + psq_l f31, 0(r6), 0, 0 + ps_muls0 f14, f6, f2 + psq_l f9, 24(b), 0, 0 + ps_muls0 f15, f7, f2 + psq_l f1, 8(a), 0, 0 + ps_madds1 f12, f8, f0, f12 + psq_l f3, 24(a), 0, 0 + ps_madds1 f14, f8, f2, f14 + psq_l f10, 32(b), 0, 0 + ps_madds1 f13, f9, f0, f13 + psq_l f11, 40(b), 0, 0 + ps_madds1 f15, f9, f2, f15 + psq_l f4, 32(a), 0, 0 + psq_l f5, 40(a), 0, 0 + ps_madds0 f12, f10, f1, f12 + ps_madds0 f13, f11, f1, f13 + ps_madds0 f14, f10, f3, f14 + ps_madds0 f15, f11, f3, f15 + psq_st f12, 0(ab), 0, 0 + ps_muls0 f2, f6, f4 + ps_madds1 f13, f31, f1, f13 + ps_muls0 f0, f7, f4 + psq_st f14, 16(ab), 0, 0 + ps_madds1 f15, f31, f3, f15 + psq_st f13, 8(ab), 0, 0 + ps_madds1 f2, f8, f4, f2 + ps_madds1 f0, f9, f4, f0 + ps_madds0 f2, f10, f5, f2 + lfd f14, 8(r1) + psq_st f15, 24(ab), 0, 0 + ps_madds0 f0, f11, f5, f0 + psq_st f2, 32(ab), 0, 0 + ps_madds1 f0, f31, f5, f0 + lfd f15, 16(r1) + psq_st f0, 40(ab), 0, 0 + lfd f31, 40(r1) + addi r1, r1, 64 + blr +} + +void C_MTXConcatArray(const Mtx a, const Mtx* srcBase, Mtx* dstBase, u32 count) { + u32 i; + + ASSERTMSGLINE(580, a != 0, "MTXConcatArray(): NULL MtxPtr 'a' "); + ASSERTMSGLINE(581, srcBase != 0, "MTXConcatArray(): NULL MtxPtr 'srcBase' "); + ASSERTMSGLINE(582, dstBase != 0, "MTXConcatArray(): NULL MtxPtr 'dstBase' "); + ASSERTMSGLINE(583, count > 1, "MTXConcatArray(): count must be greater than 1."); + + for (i = 0; i < count; i++) { + C_MTXConcat(a, *srcBase, *dstBase); + srcBase++; + dstBase++; + } +} + +#if DEBUG +#pragma push +#pragma optimization_level 1 +// This function will not compile at optimization level 0 +#endif +void PSMTXConcatArray(const register Mtx a, const register Mtx* srcBase, register Mtx* dstBase, register u32 count) { + register f32 va0, va1, va2, va3, va4, va5; + register f32 vb0, vb1, vb2, vb3, vb4, vb5; + register f32 vd0, vd1, vd2, vd3, vd4, vd5; + register f32 u01; + register f32* u01Ptr = Unit01; + + asm { + psq_l va0, 0(a), 0, 0; + psq_l va1, 8(a), 0, 0; + psq_l va2, 16(a), 0, 0; + psq_l va3, 24(a), 0, 0; + subi count, count, 1; + psq_l va4, 32(a), 0, 0; + psq_l va5, 40(a), 0, 0; + mtctr count; + psq_l u01, 0(u01Ptr), 0, 0; + psq_l vb0, 0(srcBase), 0, 0; + psq_l vb2, 16(srcBase), 0, 0; + ps_muls0 vd0, vb0, va0; + ps_muls0 vd2, vb0, va2; + ps_muls0 vd4, vb0, va4; + psq_l vb4, 32(srcBase), 0, 0; + ps_madds1 vd0, vb2, va0, vd0; + ps_madds1 vd2, vb2, va2, vd2; + ps_madds1 vd4, vb2, va4, vd4; + psq_l vb1, 8(srcBase), 0, 0; + ps_madds0 vd0, vb4, va1, vd0; + ps_madds0 vd2, vb4, va3, vd2; + ps_madds0 vd4, vb4, va5, vd4; + psq_l vb3, 24(srcBase), 0, 0; + psq_st vd0, 0(dstBase), 0, 0; + ps_muls0 vd1, vb1, va0; + ps_muls0 vd3, vb1, va2; + ps_muls0 vd5, vb1, va4; + psq_l vb5, 40(srcBase), 0, 0; + psq_st vd2, 16(dstBase), 0, 0; + ps_madds1 vd1, vb3, va0, vd1; + ps_madds1 vd3, vb3, va2, vd3; + ps_madds1 vd5, vb3, va4, vd5; + _loop: + addi srcBase, srcBase, sizeof(Mtx); + ps_madds0 vd1, vb5, va1, vd1; + ps_madds0 vd3, vb5, va3, vd3; + ps_madds0 vd5, vb5, va5, vd5; + psq_l vb0, 0(srcBase), 0, 0; + psq_st vd4, 32(dstBase), 0, 0; + ps_madd vd1, u01, va1, vd1; + ps_madd vd3, u01, va3, vd3; + ps_madd vd5, u01, va5, vd5; + psq_l vb2, 16(srcBase), 0, 0; + psq_st vd1, 8(dstBase), 0, 0; + ps_muls0 vd0, vb0, va0; + ps_muls0 vd2, vb0, va2; + ps_muls0 vd4, vb0, va4; + psq_l vb4, 32(srcBase), 0, 0; + psq_st vd3, 24(dstBase), 0, 0; + ps_madds1 vd0, vb2, va0, vd0; + ps_madds1 vd2, vb2, va2, vd2; + ps_madds1 vd4, vb2, va4, vd4; + psq_l vb1, 8(srcBase), 0, 0; + psq_st vd5, 40(dstBase), 0, 0; + addi dstBase, dstBase, sizeof(Mtx); + ps_madds0 vd0, vb4, va1, vd0; + ps_madds0 vd2, vb4, va3, vd2; + ps_madds0 vd4, vb4, va5, vd4; + psq_l vb3, 24(srcBase), 0, 0; + psq_st vd0, 0(dstBase), 0, 0; + ps_muls0 vd1, vb1, va0; + ps_muls0 vd3, vb1, va2; + ps_muls0 vd5, vb1, va4; + psq_l vb5, 40(srcBase), 0, 0; + psq_st vd2, 16(dstBase), 0, 0; + ps_madds1 vd1, vb3, va0, vd1; + ps_madds1 vd3, vb3, va2, vd3; + ps_madds1 vd5, vb3, va4, vd5; + bdnz _loop; + psq_st vd4, 32(dstBase), 0, 0; + ps_madds0 vd1, vb5, va1, vd1; + ps_madds0 vd3, vb5, va3, vd3; + ps_madds0 vd5, vb5, va5, vd5; + ps_madd vd1, u01, va1, vd1; + ps_madd vd3, u01, va3, vd3; + ps_madd vd5, u01, va5, vd5; + psq_st vd1, 8(dstBase), 0, 0; + psq_st vd3, 24(dstBase), 0, 0; + psq_st vd5, 40(dstBase), 0, 0; + } +} +#if DEBUG +#pragma pop +#endif + +void C_MTXTranspose(const Mtx src, Mtx xPose) { + Mtx mTmp; + MtxPtr m; + + ASSERTMSGLINE(851, src, "MTXTranspose(): NULL MtxPtr 'src' "); + ASSERTMSGLINE(852, xPose, "MTXTranspose(): NULL MtxPtr 'xPose' "); + + if (src == xPose) { + m = mTmp; + } else { + m = xPose; + } + + m[0][0] = src[0][0]; + m[0][1] = src[1][0]; + m[0][2] = src[2][0]; + m[0][3] = 0; + m[1][0] = src[0][1]; + m[1][1] = src[1][1]; + m[1][2] = src[2][1]; + m[1][3] = 0; + m[2][0] = src[0][2]; + m[2][1] = src[1][2]; + m[2][2] = src[2][2]; + m[2][3] = 0; + if (m == mTmp) { + C_MTXCopy(mTmp, xPose); + } +} + +void PSMTXTranspose(const register Mtx src, register Mtx xPose) { + register f32 c_zero = 0; + register f32 row0a; + register f32 row1a; + register f32 row0b; + register f32 row1b; + register f32 trns0; + register f32 trns1; + register f32 trns2; + + asm { + psq_l row0a, 0(src), 0, 0 + } + xPose[2][3] = c_zero; + asm { + psq_l row1a, 16(src), 0, 0 + ps_merge00 trns0, row0a, row1a + psq_l row0b, 8(src), 1, 0 + ps_merge11 trns1, row0a, row1a + psq_l row1b, 24(src), 1, 0 + psq_st trns0, 0(xPose), 0, 0 + psq_l row0a, 32(src), 0, 0 + ps_merge00 trns2, row0b, row1b + psq_st trns1, 16(xPose), 0, 0 + ps_merge00 trns0, row0a, c_zero + psq_st trns2, 32(xPose), 0, 0 + ps_merge10 trns1, row0a, c_zero + psq_st trns0, 8(xPose), 0, 0 + } + row0b = src[2][2]; + asm { + psq_st trns1, 24(xPose), 0, 0 + } + xPose[2][2] = row0b; +} + +u32 C_MTXInverse(const Mtx src, Mtx inv) { + Mtx mTmp; + MtxPtr m; + f32 det; + + ASSERTMSGLINE(950, src, "MTXInverse(): NULL MtxPtr 'src' "); + ASSERTMSGLINE(951, inv, "MTXInverse(): NULL MtxPtr 'inv' "); + + if (src == inv) { + m = mTmp; + } else { + m = inv; + } + det = ((((src[2][1] * (src[0][2] * src[1][0])) + + ((src[2][2] * (src[0][0] * src[1][1])) + + (src[2][0] * (src[0][1] * src[1][2])))) + - (src[0][2] * (src[2][0] * src[1][1]))) + - (src[2][2] * (src[1][0] * src[0][1]))) + - (src[1][2] * (src[0][0] * src[2][1])); + if (0 == det) { + return 0; + } + det = 1 / det; + m[0][0] = (det * +((src[1][1] * src[2][2]) - (src[2][1] * src[1][2]))); + m[0][1] = (det * -((src[0][1] * src[2][2]) - (src[2][1] * src[0][2]))); + m[0][2] = (det * +((src[0][1] * src[1][2]) - (src[1][1] * src[0][2]))); + + m[1][0] = (det * -((src[1][0] * src[2][2]) - (src[2][0] * src[1][2]))); + m[1][1] = (det * +((src[0][0] * src[2][2]) - (src[2][0] * src[0][2]))); + m[1][2] = (det * -((src[0][0] * src[1][2]) - (src[1][0] * src[0][2]))); + + m[2][0] = (det * +((src[1][0] * src[2][1]) - (src[2][0] * src[1][1]))); + m[2][1] = (det * -((src[0][0] * src[2][1]) - (src[2][0] * src[0][1]))); + m[2][2] = (det * +((src[0][0] * src[1][1]) - (src[1][0] * src[0][1]))); + + m[0][3] = ((-m[0][0] * src[0][3]) - (m[0][1] * src[1][3])) - (m[0][2] * src[2][3]); + m[1][3] = ((-m[1][0] * src[0][3]) - (m[1][1] * src[1][3])) - (m[1][2] * src[2][3]); + m[2][3] = ((-m[2][0] * src[0][3]) - (m[2][1] * src[1][3])) - (m[2][2] * src[2][3]); + + if (m == mTmp) { + C_MTXCopy(mTmp, inv); + } + return 1; } -/* 803465B0-803466A8 340EF0 00F8+00 0/0 43/43 39/39 .text PSMTXInverse */ asm u32 PSMTXInverse(const register Mtx src, register Mtx inv) { -#ifdef __MWERKS__ // clang-format off - nofralloc - psq_l fp0, 0(src), 1, 0 - psq_l fp1, 4(src), 0, 0 - psq_l fp2, 16(src), 1, 0 - ps_merge10 fp6, fp1, fp0 - psq_l fp3, 20(src), 0, 0 - psq_l fp4, 32(src), 1, 0 - ps_merge10 fp7, fp3, fp2 - psq_l fp5, 36(src), 0, 0 - ps_mul fp11, fp3, fp6 - ps_mul fp13, fp5, fp7 - ps_merge10 fp8, fp5, fp4 - ps_msub fp11, fp1, fp7, fp11 - ps_mul fp12, fp1, fp8 - ps_msub fp13, fp3, fp8, fp13 - ps_mul fp10, fp3, fp4 - ps_msub fp12, fp5, fp6, fp12 - ps_mul fp9, fp0, fp5 - ps_mul fp8, fp1, fp2 - ps_sub fp6, fp6, fp6 - ps_msub fp10, fp2, fp5, fp10 - ps_mul fp7, fp0, fp13 - ps_msub fp9, fp1, fp4, fp9 - ps_madd fp7, fp2, fp12, fp7 - ps_msub fp8, fp0, fp3, fp8 - ps_madd fp7, fp4, fp11, fp7 - ps_cmpo0 cr0, fp7, fp6 - bne _regular - addi r3, 0, 0 - blr - _regular: - fres fp0, fp7 - ps_add fp6, fp0, fp0 - ps_mul fp5, fp0, fp0 - ps_nmsub fp0, fp7, fp5, fp6 - lfs fp1, 12(src) - ps_muls0 fp13, fp13, fp0 - lfs fp2, 28(src) - ps_muls0 fp12, fp12, fp0 - lfs fp3, 44(src) - ps_muls0 fp11, fp11, fp0 - ps_merge00 fp5, fp13, fp12 - ps_muls0 fp10, fp10, fp0 - ps_merge11 fp4, fp13, fp12 - ps_muls0 fp9, fp9, fp0 - psq_st fp5, 0(inv), 0, 0 - ps_mul fp6, fp13, fp1 - psq_st fp4, 16(inv), 0, 0 - ps_muls0 fp8, fp8, fp0 - ps_madd fp6, fp12, fp2, fp6 - psq_st fp10, 32(inv), 1, 0 - ps_nmadd fp6, fp11, fp3, fp6 - psq_st fp9, 36(inv), 1, 0 - ps_mul fp7, fp10, fp1 - ps_merge00 fp5, fp11, fp6 - psq_st fp8, 40(inv), 1, 0 - ps_merge11 fp4, fp11, fp6 - psq_st fp5, 8(inv), 0, 0 - ps_madd fp7, fp9, fp2, fp7 - psq_st fp4, 24(inv), 0, 0 - ps_nmadd fp7, fp8, fp3, fp7 - addi r3, 0, 1 - psq_st fp7, 44(inv), 1, 0 - blr -#endif // clang-format on + psq_l f0, 0(src), 1, 0 + psq_l f1, 4(src), 0, 0 + psq_l f2, 16(src), 1, 0 + ps_merge10 f6, f1, f0 + psq_l f3, 20(src), 0, 0 + psq_l f4, 32(src), 1, 0 + ps_merge10 f7, f3, f2 + psq_l f5, 36(src), 0, 0 + ps_mul f11, f3, f6 + ps_mul f13, f5, f7 + ps_merge10 f8, f5, f4 + ps_msub f11, f1, f7, f11 + ps_mul f12, f1, f8 + ps_msub f13, f3, f8, f13 + ps_mul f10, f3, f4 + ps_msub f12, f5, f6, f12 + ps_mul f9, f0, f5 + ps_mul f8, f1, f2 + ps_sub f6, f6, f6 + ps_msub f10, f2, f5, f10 + ps_mul f7, f0, f13 + ps_msub f9, f1, f4, f9 + ps_madd f7, f2, f12, f7 + ps_msub f8, f0, f3, f8 + ps_madd f7, f4, f11, f7 + ps_cmpo0 cr0, f7, f6 + bne skip_return + li r3, 0 + blr +skip_return: + fres f0, f7 + ps_add f6, f0, f0 + ps_mul f5, f0, f0 + ps_nmsub f0, f7, f5, f6 + lfs f1, 12(src) + ps_muls0 f13, f13, f0 + lfs f2, 28(src) + ps_muls0 f12, f12, f0 + lfs f3, 44(src) + ps_muls0 f11, f11, f0 + ps_merge00 f5, f13, f12 + ps_muls0 f10, f10, f0 + ps_merge11 f4, f13, f12 + ps_muls0 f9, f9, f0 + psq_st f5, 0(inv), 0, 0 + ps_mul f6, f13, f1 + psq_st f4, 16(inv), 0, 0 + ps_muls0 f8, f8, f0 + ps_madd f6, f12, f2, f6 + psq_st f10, 32(inv), 1, 0 + ps_nmadd f6, f11, f3, f6 + psq_st f9, 36(inv), 1, 0 + ps_mul f7, f10, f1 + ps_merge00 f5, f11, f6 + psq_st f8, 40(inv), 1, 0 + ps_merge11 f4, f11, f6 + psq_st f5, 8(inv), 0, 0 + ps_madd f7, f9, f2, f7 + psq_st f4, 24(inv), 0, 0 + ps_nmadd f7, f8, f3, f7 + li r3, 1 + psq_st f7, 44(inv), 1, 0 +} + +u32 C_MTXInvXpose(const Mtx src, Mtx invX) { + Mtx mTmp; + MtxPtr m; + f32 det; + + ASSERTMSGLINE(1185, src, "MTXInvXpose(): NULL MtxPtr 'src' "); + ASSERTMSGLINE(1186, invX, "MTXInvXpose(): NULL MtxPtr 'invX' "); + + if (src == invX) { + m = mTmp; + } else { + m = invX; + } + det = ((((src[2][1] * (src[0][2] * src[1][0])) + + ((src[2][2] * (src[0][0] * src[1][1])) + + (src[2][0] * (src[0][1] * src[1][2])))) + - (src[0][2] * (src[2][0] * src[1][1]))) + - (src[2][2] * (src[1][0] * src[0][1]))) + - (src[1][2] * (src[0][0] * src[2][1])); + if (0 == det) { + return 0; + } + det = 1 / det; + m[0][0] = (det * +((src[1][1] * src[2][2]) - (src[2][1] * src[1][2]))); + m[0][1] = (det * -((src[1][0] * src[2][2]) - (src[2][0] * src[1][2]))); + m[0][2] = (det * +((src[1][0] * src[2][1]) - (src[2][0] * src[1][1]))); + + m[1][0] = (det * -((src[0][1] * src[2][2]) - (src[2][1] * src[0][2]))); + m[1][1] = (det * +((src[0][0] * src[2][2]) - (src[2][0] * src[0][2]))); + m[1][2] = (det * -((src[0][0] * src[2][1]) - (src[2][0] * src[0][1]))); + + m[2][0] = (det * +((src[0][1] * src[1][2]) - (src[1][1] * src[0][2]))); + m[2][1] = (det * -((src[0][0] * src[1][2]) - (src[1][0] * src[0][2]))); + m[2][2] = (det * +((src[0][0] * src[1][1]) - (src[1][0] * src[0][1]))); + + m[0][3] = 0; + m[1][3] = 0; + m[2][3] = 0; + + if (m == mTmp) { + C_MTXCopy(mTmp, invX); + } + return 1; +} + +asm u32 PSMTXInvXpose(const register Mtx src, register Mtx invX) { + psq_l f0, 0(src), 1, 0 + psq_l f1, 4(src), 0, 0 + psq_l f2, 16(src), 1, 0 + ps_merge10 f6, f1, f0 + psq_l f3, 20(src), 0, 0 + psq_l f4, 32(src), 1, 0 + ps_merge10 f7, f3, f2 + psq_l f5, 36(src), 0, 0 + ps_mul f11, f3, f6 + ps_merge10 f8, f5, f4 + ps_mul f13, f5, f7 + ps_msub f11, f1, f7, f11 + ps_mul f12, f1, f8 + ps_msub f13, f3, f8, f13 + ps_msub f12, f5, f6, f12 + ps_mul f10, f3, f4 + ps_mul f9, f0, f5 + ps_mul f8, f1, f2 + ps_msub f10, f2, f5, f10 + ps_msub f9, f1, f4, f9 + ps_msub f8, f0, f3, f8 + ps_mul f7, f0, f13 + ps_sub f1, f1, f1 + ps_madd f7, f2, f12, f7 + ps_madd f7, f4, f11, f7 + ps_cmpo0 cr0, f7, f1 + bne skip_return + li r3, 0 + blr +skip_return: + fres f0, f7 + psq_st f1, 12(invX), 1, 0 + ps_add f6, f0, f0 + ps_mul f5, f0, f0 + psq_st f1, 28(invX), 1, 0 + ps_nmsub f0, f7, f5, f6 + psq_st f1, 44(invX), 1, 0 + ps_muls0 f13, f13, f0 + ps_muls0 f12, f12, f0 + ps_muls0 f11, f11, f0 + psq_st f13, 0(invX), 0, 0 + psq_st f12, 16(invX), 0, 0 + ps_muls0 f10, f10, f0 + ps_muls0 f9, f9, f0 + psq_st f11, 32(invX), 0, 0 + psq_st f10, 8(invX), 1, 0 + ps_muls0 f8, f8, f0 + li r3, 1 + psq_st f9, 24(invX), 1, 0 + psq_st f8, 40(invX), 1, 0 +} + +void C_MTXRotRad(Mtx m, char axis, f32 rad) { + f32 sinA; + f32 cosA; + + ASSERTMSGLINE(1447, m, "MTXRotRad(): NULL MtxPtr 'm' "); + sinA = sinf(rad); + cosA = cosf(rad); + C_MTXRotTrig(m, axis, sinA, cosA); } -/* 803466A8-80346718 340FE8 0070+00 0/0 17/17 0/0 .text PSMTXRotRad */ void PSMTXRotRad(Mtx m, char axis, f32 rad) { f32 sinA, cosA; sinA = sinf(rad); @@ -236,22 +568,72 @@ void PSMTXRotRad(Mtx m, char axis, f32 rad) { PSMTXRotTrig(m, axis, sinA, cosA); } -/* 80346718-803467C8 341058 00B0+00 1/1 0/0 0/0 .text PSMTXRotTrig */ +void C_MTXRotTrig(Mtx m, char axis, f32 sinA, f32 cosA) { + ASSERTMSGLINE(1502, m, "MTXRotTrig(): NULL MtxPtr 'm' "); + switch(axis) { + case 'x': + case 'X': + m[0][0] = 1; + m[0][1] = 0; + m[0][2] = 0; + m[0][3] = 0; + m[1][0] = 0; + m[1][1] = cosA; + m[1][2] = -sinA; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = sinA; + m[2][2] = cosA; + m[2][3] = 0; + break; + case 'y': + case 'Y': + m[0][0] = cosA; + m[0][1] = 0; + m[0][2] = sinA; + m[0][3] = 0; + m[1][0] = 0; + m[1][1] = 1; + m[1][2] = 0; + m[1][3] = 0; + m[2][0] = -sinA; + m[2][1] = 0; + m[2][2] = cosA; + m[2][3] = 0; + break; + case 'z': + case 'Z': + m[0][0] = cosA; + m[0][1] = -sinA; + m[0][2] = 0; + m[0][3] = 0; + m[1][0] = sinA; + m[1][1] = cosA; + m[1][2] = 0; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = 1; + m[2][3] = 0; + break; + default: + ASSERTMSGLINE(1529, FALSE, "MTXRotTrig(): invalid 'axis' value "); + break; + } +} + void PSMTXRotTrig(register Mtx m, register char axis, register f32 sinA, register f32 cosA) { register f32 fc0, fc1, nsinA; register f32 fw0, fw1, fw2, fw3; -#ifdef __MWERKS__ // clang-format off asm { frsp sinA, sinA frsp cosA, cosA } -#endif // clang-format on fc0 = 0.0f; fc1 = 1.0f; -#ifdef __MWERKS__ // clang-format off asm { ori axis, axis, 0x20 ps_neg nsinA, sinA @@ -300,69 +682,61 @@ void PSMTXRotTrig(register Mtx m, register char axis, register f32 sinA, registe psq_st fw1, 40(m), 0, 0 _end: - } -#endif // clang-format on } -/* 803467C8-80346878 341108 00B0+00 1/1 0/0 0/0 .text __PSMTXRotAxisRadInternal */ -static void __PSMTXRotAxisRadInternal(register Mtx m, const register Vec* axis, register f32 sT, - register f32 cT) { +static void __PSMTXRotAxisRadInternal(register Mtx m, const register Vec* axis, register f32 sT, register f32 cT) { register f32 tT, fc0; register f32 tmp0, tmp1, tmp2, tmp3, tmp4; register f32 tmp5, tmp6, tmp7, tmp8, tmp9; - tmp9 = 0.5f; tmp8 = 3.0f; -#ifdef __MWERKS__ // clang-format off - asm { - frsp cT, cT - psq_l tmp0, 0(axis), 0, 0 - frsp sT, sT - lfs tmp1, 8(axis) - ps_mul tmp2, tmp0, tmp0 - fadds tmp7, tmp9, tmp9 - ps_madd tmp3, tmp1, tmp1, tmp2 - fsubs fc0, tmp9, tmp9 - ps_sum0 tmp4, tmp3, tmp1, tmp2 - fsubs tT, tmp7, cT - frsqrte tmp5, tmp4 - fmuls tmp2, tmp5, tmp5 - fmuls tmp3, tmp5, tmp9 - fnmsubs tmp2, tmp2, tmp4, tmp8 - fmuls tmp5, tmp2, tmp3 - ps_merge00 cT, cT, cT - ps_muls0 tmp0, tmp0, tmp5 - ps_muls0 tmp1, tmp1, tmp5 - ps_muls0 tmp4, tmp0, tT - ps_muls0 tmp9, tmp0, sT - ps_muls0 tmp5, tmp1, tT - ps_muls1 tmp3, tmp4, tmp0 - ps_muls0 tmp2, tmp4, tmp0 - ps_muls0 tmp4, tmp4, tmp1 - fnmsubs tmp6, tmp1, sT, tmp3 - fmadds tmp7, tmp1, sT, tmp3 - ps_neg tmp0, tmp9 - ps_sum0 tmp8, tmp4, fc0, tmp9 - ps_sum0 tmp2, tmp2, tmp6, cT - ps_sum1 tmp3, cT, tmp7, tmp3 - ps_sum0 tmp6, tmp0, fc0 ,tmp4 - psq_st tmp8, 8(m), 0, 0 - ps_sum0 tmp0, tmp4, tmp4, tmp0 - psq_st tmp2, 0(m), 0, 0 - ps_muls0 tmp5, tmp5, tmp1 - psq_st tmp3, 16(m), 0, 0 - ps_sum1 tmp4, tmp9, tmp0, tmp4 - psq_st tmp6, 24(m), 0, 0 - ps_sum0 tmp5, tmp5, fc0, cT - psq_st tmp4, 32(m), 0, 0 - psq_st tmp5, 40(m), 0, 0 - } -#endif // clang-format on + asm { + frsp cT, cT; + psq_l tmp0, 0(axis), 0, 0; + frsp sT, sT; + lfs tmp1, 8(axis); + ps_mul tmp2, tmp0, tmp0; + fadds tmp7, tmp9, tmp9; + ps_madd tmp3, tmp1, tmp1, tmp2; + fsubs fc0, tmp9, tmp9; + ps_sum0 tmp4, tmp3, tmp1, tmp2; + fsubs tT, tmp7, cT; + frsqrte tmp5, tmp4; + fmuls tmp2, tmp5, tmp5; + fmuls tmp3, tmp5, tmp9; + fnmsubs tmp2, tmp2, tmp4, tmp8; + fmuls tmp5, tmp2, tmp3; + ps_merge00 cT, cT, cT; + ps_muls0 tmp0, tmp0, tmp5; + ps_muls0 tmp1, tmp1, tmp5; + ps_muls0 tmp4, tmp0, tT; + ps_muls0 tmp9, tmp0, sT; + ps_muls0 tmp5, tmp1, tT; + ps_muls1 tmp3, tmp4, tmp0; + ps_muls0 tmp2, tmp4, tmp0; + ps_muls0 tmp4, tmp4, tmp1; + fnmsubs tmp6, tmp1, sT, tmp3; + fmadds tmp7, tmp1, sT, tmp3; + ps_neg tmp0, tmp9; + ps_sum0 tmp8, tmp4, fc0, tmp9; + ps_sum0 tmp2, tmp2, tmp6, cT; + ps_sum1 tmp3, cT, tmp7, tmp3; + ps_sum0 tmp6, tmp0, fc0, tmp4; + psq_st tmp8, 8(m), 0, 0; + ps_sum0 tmp0, tmp4, tmp4, tmp0; + psq_st tmp2, 0(m), 0, 0; + ps_muls0 tmp5, tmp5, tmp1; + psq_st tmp3, 16(m), 0, 0; + ps_sum1 tmp4, tmp9, tmp0, tmp4; + psq_st tmp6, 24(m), 0, 0; + ps_sum0 tmp5, tmp5, fc0, cT; + psq_st tmp4, 32(m), 0, 0; + psq_st tmp5, 40(m), 0, 0; + } } -/* 80346878-803468E8 3411B8 0070+00 0/0 6/6 8/8 .text PSMTXRotAxisRad */ void PSMTXRotAxisRad(Mtx m, const Vec* axis, f32 rad) { f32 sinT, cosT; @@ -372,247 +746,452 @@ void PSMTXRotAxisRad(Mtx m, const Vec* axis, f32 rad) { __PSMTXRotAxisRadInternal(m, axis, sinT, cosT); } -/* 803468E8-8034691C 341228 0034+00 0/0 38/38 471/471 .text PSMTXTrans */ +void C_MTXRotAxisRad(Mtx m, const Vec* axis, f32 rad) { + Vec vN; + f32 s; + f32 c; + f32 t; + f32 x; + f32 y; + f32 z; + f32 xSq; + f32 ySq; + f32 zSq; + + ASSERTMSGLINE(1677, m, "MTXRotAxisRad(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(1678, axis, "MTXRotAxisRad(): NULL VecPtr 'axis' "); + + s = sinf(rad); + c = cosf(rad); + t = 1 - c; + C_VECNormalize(axis, &vN); + x = vN.x; + y = vN.y; + z = vN.z; + xSq = (x * x); + ySq = (y * y); + zSq = (z * z); + m[0][0] = (c + (t * xSq)); + m[0][1] = (y * (t * x)) - (s * z); + m[0][2] = (z * (t * x)) + (s * y); + m[0][3] = 0; + m[1][0] = ((y * (t * x)) + (s * z)); + m[1][1] = (c + (t * ySq)); + m[1][2] = ((z * (t * y)) - (s * x)); + m[1][3] = 0; + m[2][0] = ((z * (t * x)) - (s * y)); + m[2][1] = ((z * (t * y)) + (s * x)); + m[2][2] = (c + (t * zSq)); + m[2][3] = 0; +} + +void C_MTXTrans(Mtx m, f32 xT, f32 yT, f32 zT) { + ASSERTMSGLINE(1866, m, "MTXTrans(): NULL MtxPtr 'm' "); + m[0][0] = 1; + m[0][1] = 0; + m[0][2] = 0; + m[0][3] = xT; + m[1][0] = 0; + m[1][1] = 1; + m[1][2] = 0; + m[1][3] = yT; + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = 1; + m[2][3] = zT; +} + void PSMTXTrans(register Mtx m, register f32 xT, register f32 yT, register f32 zT) { register f32 c0 = 0.0f; register f32 c1 = 1.0f; -#ifdef __MWERKS__ // clang-format off asm { - stfs xT, 12(m) - stfs yT, 28(m) - psq_st c0, 4(m), 0, 0 - psq_st c0, 32(m), 0, 0 - stfs c0, 16(m) - stfs c1, 20(m) - stfs c0, 24(m) - stfs c1, 40(m) - stfs zT, 44(m) - stfs c1, 0(m) + stfs xT, 12(m) + stfs yT, 28(m) + psq_st c0, 4(m), 0, 0 + psq_st c0, 32(m), 0, 0 + stfs c0, 16(m) + stfs c1, 20(m) + stfs c0, 24(m) + stfs c1, 40(m) + stfs zT, 44(m) + stfs c1, 0(m) } -#endif // clang-format on } -/* 8034691C-80346968 34125C 004C+00 0/0 3/3 0/0 .text PSMTXTransApply */ -asm void PSMTXTransApply(const register Mtx src, register Mtx dst, register f32 xT, register f32 yT, - register f32 zT) { -#ifdef __MWERKS__ // clang-format off - nofralloc; - psq_l fp4, 0(src), 0, 0; - frsp xT, xT; - psq_l fp5, 8(src), 0, 0; - frsp yT, yT; - psq_l fp7, 24(src), 0, 0; - frsp zT, zT; - psq_l fp8, 40(src), 0, 0; - psq_st fp4, 0(dst), 0, 0; - ps_sum1 fp5, xT, fp5, fp5; - psq_l fp6, 16(src), 0, 0; - psq_st fp5, 8(dst), 0, 0; - ps_sum1 fp7, yT, fp7, fp7; - psq_l fp9, 32(src), 0, 0; - psq_st fp6, 16(dst), 0, 0; - ps_sum1 fp8, zT, fp8, fp8; - psq_st fp7, 24(dst), 0, 0; - psq_st fp9, 32(dst), 0, 0; - psq_st fp8, 40(dst), 0, 0; - blr; -#endif // clang-format on +void C_MTXTransApply(const Mtx src, Mtx dst, f32 xT, f32 yT, f32 zT) { + ASSERTMSGLINE(1933, src, "MTXTransApply(): NULL MtxPtr 'src' "); + ASSERTMSGLINE(1934, dst, "MTXTransApply(): NULL MtxPtr 'src' "); //! wrong assert string + + if (src != dst) { + dst[0][0] = src[0][0]; + dst[0][1] = src[0][1]; + dst[0][2] = src[0][2]; + dst[1][0] = src[1][0]; + dst[1][1] = src[1][1]; + dst[1][2] = src[1][2]; + dst[2][0] = src[2][0]; + dst[2][1] = src[2][1]; + dst[2][2] = src[2][2]; + } + + dst[0][3] = (src[0][3] + xT); + dst[1][3] = (src[1][3] + yT); + dst[2][3] = (src[2][3] + zT); +} + +asm void PSMTXTransApply(const register Mtx src, register Mtx dst, register f32 xT, register f32 yT, register f32 zT) { + nofralloc + psq_l fp4, 0(src), 0, 0 + frsp xT, xT + psq_l fp5, 8(src), 0, 0 + frsp yT, yT + psq_l fp7, 24(src), 0, 0 + frsp zT, zT + psq_l fp8, 40(src), 0, 0 + psq_st fp4, 0(dst), 0, 0 + ps_sum1 fp5, xT, fp5, fp5 + psq_l fp6, 16(src), 0, 0 + psq_st fp5, 8(dst), 0, 0 + ps_sum1 fp7, yT, fp7, fp7 + psq_l fp9, 32(src), 0, 0 + psq_st fp6, 16(dst), 0, 0 + ps_sum1 fp8, zT, fp8, fp8 + psq_st fp7, 24(dst), 0, 0 + psq_st fp9, 32(dst), 0, 0 + psq_st fp8, 40(dst), 0, 0 + blr +} + +void C_MTXScale(Mtx m, f32 xS, f32 yS, f32 zS) { + ASSERTMSGLINE(2008, m, "MTXScale(): NULL MtxPtr 'm' "); + m[0][0] = xS; + m[0][1] = 0; + m[0][2] = 0; + m[0][3] = 0; + m[1][0] = 0; + m[1][1] = yS; + m[1][2] = 0; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = zS; + m[2][3] = 0; } -/* 80346968-80346990 3412A8 0028+00 0/0 14/14 8/8 .text PSMTXScale */ void PSMTXScale(register Mtx m, register f32 xS, register f32 yS, register f32 zS) { register f32 c0 = 0.0f; -#ifdef __MWERKS__ // clang-format off asm { - stfs xS, 0(m) - psq_st c0, 4(m), 0, 0 - psq_st c0, 12(m), 0, 0 - stfs yS, 20(m) - psq_st c0, 24(m), 0, 0 - psq_st c0, 32(m), 0, 0 - stfs zS, 40(m) - stfs c0, 44(m) + stfs xS, 0(m) + psq_st c0, 4(m), 0, 0 + psq_st c0, 12(m), 0, 0 + stfs yS, 20(m) + psq_st c0, 24(m), 0, 0 + psq_st c0, 32(m), 0, 0 + stfs zS, 40(m) + stfs c0, 44(m) } -#endif // clang-format on } -/* 80346990-803469E8 3412D0 0058+00 0/0 1/1 0/0 .text PSMTXScaleApply */ -asm void PSMTXScaleApply(const register Mtx src, register Mtx dst, register f32 xS, register f32 yS, - register f32 zS) { -#ifdef __MWERKS__ // clang-format off - nofralloc; - frsp xS, xS; - psq_l fp4, 0(src), 0, 0; - frsp yS, yS; - psq_l fp5, 8(src), 0, 0; - frsp zS, zS; - ps_muls0 fp4, fp4, xS; - psq_l fp6, 16(src), 0, 0; - ps_muls0 fp5, fp5, xS; - psq_l fp7, 24(src), 0, 0; - ps_muls0 fp6, fp6, yS; - psq_l fp8, 32(src), 0, 0; - psq_st fp4, 0(dst), 0, 0; - ps_muls0 fp7, fp7, yS; - psq_l fp2, 40(src), 0, 0; - psq_st fp5, 8(dst), 0, 0; - ps_muls0 fp8, fp8, zS; - psq_st fp6, 16(dst), 0, 0; - ps_muls0 fp2, fp2, zS; - psq_st fp7, 24(dst), 0, 0; - psq_st fp8, 32(dst), 0, 0; - psq_st fp2, 40(dst), 0, 0; - blr; -#endif // clang-format on +void C_MTXScaleApply(const Mtx src, Mtx dst, f32 xS, f32 yS, f32 zS) { + ASSERTMSGLINE(2070, src, "MTXScaleApply(): NULL MtxPtr 'src' "); + ASSERTMSGLINE(2071, dst, "MTXScaleApply(): NULL MtxPtr 'dst' "); + dst[0][0] = (src[0][0] * xS); + dst[0][1] = (src[0][1] * xS); + dst[0][2] = (src[0][2] * xS); + dst[0][3] = (src[0][3] * xS); + dst[1][0] = (src[1][0] * yS); + dst[1][1] = (src[1][1] * yS); + dst[1][2] = (src[1][2] * yS); + dst[1][3] = (src[1][3] * yS); + dst[2][0] = (src[2][0] * zS); + dst[2][1] = (src[2][1] * zS); + dst[2][2] = (src[2][2] * zS); + dst[2][3] = (src[2][3] * zS); } -/* 803469E8-80346A8C 341328 00A4+00 0/0 8/8 2/2 .text PSMTXQuat */ -void PSMTXQuat(register Mtx m, const register PSQuaternion* q) { +asm void PSMTXScaleApply(const register Mtx src, register Mtx dst, register f32 xS, register f32 yS, register f32 zS) { + nofralloc + frsp xS, xS + psq_l fp4, 0(src), 0, 0 + frsp yS, yS + psq_l fp5, 8(src), 0, 0 + frsp zS, zS + ps_muls0 fp4, fp4, xS + psq_l fp6, 16(src), 0, 0 + ps_muls0 fp5, fp5, xS + psq_l fp7, 24(src), 0, 0 + ps_muls0 fp6, fp6, yS + psq_l fp8, 32(src), 0, 0 + psq_st fp4, 0(dst), 0, 0 + ps_muls0 fp7, fp7, yS + psq_l fp2, 40(src), 0, 0 + psq_st fp5, 8(dst), 0, 0 + ps_muls0 fp8, fp8, zS + psq_st fp6, 16(dst), 0, 0 + ps_muls0 fp2, fp2, zS + psq_st fp7, 24(dst), 0, 0 + psq_st fp8, 32(dst), 0, 0 + psq_st fp2, 40(dst), 0, 0 + blr +} + +void C_MTXQuat(Mtx m, const Quaternion* q) { + f32 s; + f32 xs; + f32 ys; + f32 zs; + f32 wx; + f32 wy; + f32 wz; + f32 xx; + f32 xy; + f32 xz; + f32 yy; + f32 yz; + f32 zz; + + ASSERTMSGLINE(2145, m, "MTXQuat(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(2146, q, "MTXQuat(): NULL QuaternionPtr 'q' "); + ASSERTMSGLINE(2147, q->x || q->y || q->z || q->w, "MTXQuat(): zero-value quaternion "); + s = 2 / ((q->w * q->w) + ((q->z * q->z) + ((q->x * q->x) + (q->y * q->y)))); + xs = q->x * s; + ys = q->y * s; + zs = q->z * s; + wx = q->w * xs; + wy = q->w * ys; + wz = q->w * zs; + xx = q->x * xs; + xy = q->x * ys; + xz = q->x * zs; + yy = q->y * ys; + yz = q->y * zs; + zz = q->z * zs; + m[0][0] = (1 - (yy + zz)); + m[0][1] = (xy - wz); + m[0][2] = (xz + wy); + m[0][3] = 0; + m[1][0] = (xy + wz); + m[1][1] = (1 - (xx + zz)); + m[1][2] = (yz - wx); + m[1][3] = 0; + m[2][0] = (xz - wy); + m[2][1] = (yz + wx); + m[2][2] = (1 - (xx + yy)); + m[2][3] = 0; +} + +void PSMTXQuat(register Mtx m, const register Quaternion* q) { register f32 c_zero, c_one, c_two, scale; register f32 tmp0, tmp1, tmp2, tmp3, tmp4; register f32 tmp5, tmp6, tmp7, tmp8, tmp9; c_one = 1.0f; -#ifdef __MWERKS__ // clang-format off + asm { - psq_l tmp0, 0(q), 0, 0 - psq_l tmp1, 8(q), 0, 0 - fsubs c_zero, c_one, c_one - fadds c_two, c_one, c_one - ps_mul tmp2, tmp0, tmp0 - ps_merge10 tmp5, tmp0, tmp0 - ps_madd tmp4, tmp1, tmp1, tmp2 - ps_mul tmp3, tmp1, tmp1 - ps_sum0 scale, tmp4, tmp4, tmp4 - ps_muls1 tmp7, tmp5, tmp1 - fres tmp9, scale - ps_sum1 tmp4, tmp3, tmp4, tmp2 - ps_nmsub scale, scale, tmp9, c_two - ps_muls1 tmp6, tmp1, tmp1 - ps_mul scale, tmp9, scale - ps_sum0 tmp2, tmp2, tmp2, tmp2 - fmuls scale, scale, c_two - ps_madd tmp8, tmp0, tmp5, tmp6 - ps_msub tmp6, tmp0, tmp5, tmp6 - psq_st c_zero, 12(m), 1, 0 - ps_nmsub tmp2, tmp2, scale, c_one - ps_nmsub tmp4, tmp4, scale, c_one - psq_st c_zero, 44(m), 1, 0 - ps_mul tmp8, tmp8, scale - ps_mul tmp6, tmp6, scale - psq_st tmp2, 40(m), 1, 0 - ps_madds0 tmp5, tmp0, tmp1, tmp7 - ps_merge00 tmp1, tmp8, tmp4 - ps_nmsub tmp7, tmp7, c_two, tmp5 - ps_merge10 tmp0, tmp4, tmp6 - psq_st tmp1, 16(m), 0, 0 - ps_mul tmp5, tmp5, scale - ps_mul tmp7, tmp7, scale - psq_st tmp0, 0(m), 0, 0 - psq_st tmp5, 8(m), 1, 0 - ps_merge10 tmp3, tmp7, c_zero - ps_merge01 tmp9, tmp7, tmp5 - psq_st tmp3, 24(m), 0, 0 - psq_st tmp9, 32(m), 0, 0 + psq_l tmp0, 0(q), 0, 0 + psq_l tmp1, 8(q), 0, 0 + fsubs c_zero, c_one, c_one + fadds c_two, c_one, c_one + ps_mul tmp2, tmp0, tmp0 + ps_merge10 tmp5, tmp0, tmp0 + ps_madd tmp4, tmp1, tmp1, tmp2 + ps_mul tmp3, tmp1, tmp1 + ps_sum0 scale, tmp4, tmp4, tmp4 + ps_muls1 tmp7, tmp5, tmp1 + fres tmp9, scale + ps_sum1 tmp4, tmp3, tmp4, tmp2 + ps_nmsub scale, scale, tmp9, c_two + ps_muls1 tmp6, tmp1, tmp1 + ps_mul scale, tmp9, scale + ps_sum0 tmp2, tmp2, tmp2, tmp2 + fmuls scale, scale, c_two + ps_madd tmp8, tmp0, tmp5, tmp6 + ps_msub tmp6, tmp0, tmp5, tmp6 + psq_st c_zero, 12(m), 1, 0 + ps_nmsub tmp2, tmp2, scale, c_one + ps_nmsub tmp4, tmp4, scale, c_one + psq_st c_zero, 44(m), 1, 0 + ps_mul tmp8, tmp8, scale + ps_mul tmp6, tmp6, scale + psq_st tmp2, 40(m), 1, 0 + ps_madds0 tmp5, tmp0, tmp1, tmp7 + ps_merge00 tmp1, tmp8, tmp4 + ps_nmsub tmp7, tmp7, c_two, tmp5 + ps_merge10 tmp0, tmp4, tmp6 + psq_st tmp1, 16(m), 0, 0 + ps_mul tmp5, tmp5, scale + ps_mul tmp7, tmp7, scale + psq_st tmp0, 0(m), 0, 0 + psq_st tmp5, 8(m), 1, 0 + ps_merge10 tmp3, tmp7, c_zero + ps_merge01 tmp9, tmp7, tmp5 + psq_st tmp3, 24(m), 0, 0 + psq_st tmp9, 32(m), 0, 0 } -#endif // clang-format on } -/* 80346A8C-80346C18 3413CC 018C+00 0/0 2/2 0/0 .text C_MTXLookAt */ -void C_MTXLookAt(Mtx m, const Vec* camPos, const Vec* camUp, const Vec* target) { - Vec vLook, vRight, vUp; +void C_MTXReflect(Mtx m, const Vec* p, const Vec* n) { + f32 vxy; + f32 vxz; + f32 vyz; + f32 pdotn; + + vxy = -2 * n->x * n->y; + vxz = -2 * n->x * n->z; + vyz = -2 * n->y * n->z; + pdotn = 2 * C_VECDotProduct(p, n); + m[0][0] = (1 - (2 * n->x * n->x)); + m[0][1] = vxy; + m[0][2] = vxz; + m[0][3] = (pdotn * n->x); + m[1][0] = vxy; + m[1][1] = (1 - (2 * n->y * n->y)); + m[1][2] = vyz; + m[1][3] = (pdotn * n->y); + m[2][0] = vxz; + m[2][1] = vyz; + m[2][2] = (1 - (2 * n->z * n->z)); + m[2][3] = (pdotn * n->z); +} + +void PSMTXReflect(register Mtx m, const register Vec* p, const register Vec* n) { + register f32 c_one; + register f32 vn_xy, vn_z1; + register f32 n2vn_xy, n2vn_z1; + register f32 pdotn; + register f32 tmp0, tmp1, tmp2, tmp3; + register f32 tmp4, tmp5, tmp6, tmp7; + + c_one = 1.0f; + + asm { + psq_l vn_z1, 0x8(n), 1, 0 + psq_l vn_xy, 0x0(n), 0, 0 + psq_l tmp0, 0x0(p), 0, 0 + ps_nmadd n2vn_z1, vn_z1, c_one, vn_z1 + psq_l tmp1, 0x8(p), 1, 0 + ps_nmadd n2vn_xy, vn_xy, c_one, vn_xy + ps_muls0 tmp4, vn_xy, n2vn_z1 + ps_mul pdotn, n2vn_xy, tmp0 + ps_muls0 tmp2, vn_xy, n2vn_xy + ps_sum0 pdotn, pdotn, pdotn, pdotn + ps_muls1 tmp3, vn_xy, n2vn_xy + psq_st tmp4, 0x20(m), 0, 0 + ps_sum0 tmp2, tmp2, tmp2, c_one + ps_nmadd pdotn, n2vn_z1, tmp1, pdotn + ps_sum1 tmp3, c_one, tmp3, tmp3 + psq_st tmp2, 0x0(m), 0, 0 + ps_muls0 tmp5, vn_xy, pdotn + ps_merge00 tmp6, n2vn_z1, pdotn + psq_st tmp3, 0x10(m), 0, 0 + ps_merge00 tmp7, tmp4, tmp5 + ps_muls0 tmp6, tmp6, vn_z1 + ps_merge11 tmp5, tmp4, tmp5 + psq_st tmp7, 0x8(m), 0, 0 + ps_sum0 tmp6, tmp6, tmp6, c_one + psq_st tmp5, 0x18(m), 0, 0 + psq_st tmp6, 0x28(m), 0, 0 + } +} + +void C_MTXLookAt(Mtx m, const Point3d* camPos, const Vec* camUp, const Point3d* target) { + Vec vLook; + Vec vRight; + Vec vUp; + + ASSERTMSGLINE(2438, m, "MTXLookAt(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(2439, camPos, "MTXLookAt(): NULL VecPtr 'camPos' "); + ASSERTMSGLINE(2440, camUp, "MTXLookAt(): NULL VecPtr 'camUp' "); + ASSERTMSGLINE(2441, target, "MTXLookAt(): NULL Point3dPtr 'target' "); vLook.x = camPos->x - target->x; vLook.y = camPos->y - target->y; vLook.z = camPos->z - target->z; - PSVECNormalize(&vLook, &vLook); - - PSVECCrossProduct(camUp, &vLook, &vRight); - PSVECNormalize(&vRight, &vRight); - - PSVECCrossProduct(&vLook, &vRight, &vUp); - + VECNormalize(&vLook, &vLook); + VECCrossProduct(camUp, &vLook, &vRight); + VECNormalize(&vRight, &vRight); + VECCrossProduct(&vLook, &vRight, &vUp); m[0][0] = vRight.x; m[0][1] = vRight.y; m[0][2] = vRight.z; - m[0][3] = -(camPos->x * vRight.x + camPos->y * vRight.y + camPos->z * vRight.z); - + m[0][3] = -((camPos->z * vRight.z) + ((camPos->x * vRight.x) + (camPos->y * vRight.y))); m[1][0] = vUp.x; m[1][1] = vUp.y; m[1][2] = vUp.z; - m[1][3] = -(camPos->x * vUp.x + camPos->y * vUp.y + camPos->z * vUp.z); - + m[1][3] = -((camPos->z * vUp.z) + ((camPos->x * vUp.x) + (camPos->y * vUp.y))); m[2][0] = vLook.x; m[2][1] = vLook.y; m[2][2] = vLook.z; - m[2][3] = -(camPos->x * vLook.x + camPos->y * vLook.y + camPos->z * vLook.z); + m[2][3] = -((camPos->z * vLook.z) + ((camPos->x * vLook.x) + (camPos->y * vLook.y))); } -void C_MTXLightFrustum(Mtx m, f32 arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6, f32 arg7, - f32 arg8, f32 arg9) { - f32 tmp = 1.0f / (arg4 - arg3); - m[0][0] = ((2 * arg5) * tmp) * arg6; - m[0][1] = 0.0f; - m[0][2] = (((arg4 + arg3) * tmp) * arg6) - arg8; - m[0][3] = 0.0f; - tmp = 1.0f / (arg1 - arg2); - m[1][0] = 0.0f; - m[1][1] = ((2 * arg5) * tmp) * arg7; - m[1][2] = (((arg1 + arg2) * tmp) * arg7) - arg9; - m[1][3] = 0.0f; - m[2][0] = 0.0f; - m[2][1] = 0.0f; - m[2][2] = -1.0f; - m[2][3] = 0.0f; +void C_MTXLightFrustum(Mtx m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 scaleS, f32 scaleT, f32 transS, f32 transT) { + f32 tmp; + + ASSERTMSGLINE(2541, m, "MTXLightFrustum(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(2542, (t != b), "MTXLightFrustum(): 't' and 'b' clipping planes are equal "); + ASSERTMSGLINE(2543, (l != r), "MTXLightFrustum(): 'l' and 'r' clipping planes are equal "); + + tmp = 1 / (r - l); + m[0][0] = (scaleS * (2 * n * tmp)); + m[0][1] = 0; + m[0][2] = (scaleS * (tmp * (r + l))) - transS; + m[0][3] = 0; + tmp = 1 / (t - b); + m[1][0] = 0; + m[1][1] = (scaleT * (2 * n * tmp)); + m[1][2] = (scaleT * (tmp * (t + b))) - transT; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = -1; + m[2][3] = 0; } -/* 80346C18-80346CE4 341558 00CC+00 0/0 4/4 7/7 .text C_MTXLightPerspective */ -void C_MTXLightPerspective(Mtx m, f32 fovY, f32 aspect, f32 scaleS, f32 scaleT, f32 transS, - f32 transT) { +void C_MTXLightPerspective(Mtx m, f32 fovY, f32 aspect, f32 scaleS, f32 scaleT, f32 transS, f32 transT) { f32 angle; f32 cot; - angle = fovY * 0.5f; + ASSERTMSGLINE(2605, m, "MTXLightPerspective(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(2606, (fovY > 0.0) && (fovY < 180.0), "MTXLightPerspective(): 'fovY' out of range "); + ASSERTMSGLINE(2607, 0 != aspect, "MTXLightPerspective(): 'aspect' is 0 "); + + angle = (0.5f * fovY); angle = MTXDegToRad(angle); - - cot = 1.0f / tanf(angle); - - m[0][0] = (cot / aspect) * scaleS; - m[0][1] = 0.0f; + cot = 1 / tanf(angle); + m[0][0] = (scaleS * (cot / aspect)); + m[0][1] = 0; m[0][2] = -transS; - m[0][3] = 0.0f; - - m[1][0] = 0.0f; - m[1][1] = cot * scaleT; + m[0][3] = 0; + m[1][0] = 0; + m[1][1] = (cot * scaleT); m[1][2] = -transT; - m[1][3] = 0.0f; - - m[2][0] = 0.0f; - m[2][1] = 0.0f; - m[2][2] = -1.0f; - m[2][3] = 0.0f; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = -1; + m[2][3] = 0; } -/* 80346CE4-80346D6C 341624 0088+00 0/0 2/2 5/5 .text C_MTXLightOrtho */ -void C_MTXLightOrtho(Mtx m, f32 t, f32 b, f32 l, f32 r, f32 scaleS, f32 scaleT, f32 transS, - f32 transT) { +void C_MTXLightOrtho(Mtx m, f32 t, f32 b, f32 l, f32 r, f32 scaleS, f32 scaleT, f32 transS, f32 transT) { f32 tmp; - tmp = 1.0f / (r - l); - m[0][0] = (2.0f * tmp * scaleS); - m[0][1] = 0.0f; - m[0][2] = 0.0f; - m[0][3] = ((-(r + l) * tmp) * scaleS) + transS; - - tmp = 1.0f / (t - b); - m[1][0] = 0.0f; - m[1][1] = (2.0f * tmp) * scaleT; - m[1][2] = 0.0f; - m[1][3] = ((-(t + b) * tmp) * scaleT) + transT; - - m[2][0] = 0.0f; - m[2][1] = 0.0f; - m[2][2] = 0.0f; - m[2][3] = 1.0f; -} \ No newline at end of file + ASSERTMSGLINE(2673, m, "MTXLightOrtho(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(2674, (t != b), "MTXLightOrtho(): 't' and 'b' clipping planes are equal "); + ASSERTMSGLINE(2675, (l != r), "MTXLightOrtho(): 'l' and 'r' clipping planes are equal "); + tmp = 1 / (r - l); + m[0][0] = (2 * tmp * scaleS); + m[0][1] = 0; + m[0][2] = 0; + m[0][3] = (transS + (scaleS * (tmp * -(r + l)))); + tmp = 1/ (t - b); + m[1][0] = 0; + m[1][1] = (2 * tmp * scaleT); + m[1][2] = 0; + m[1][3] = (transT + (scaleT * (tmp * -(t + b)))); + m[2][0] = 0; + m[2][1] = 0; + m[2][2] = 0; + m[2][3] = 1; +} diff --git a/src/dolphin/mtx/mtx44.c b/src/dolphin/mtx/mtx44.c index 0cfd76b10c..59376a3bb3 100644 --- a/src/dolphin/mtx/mtx44.c +++ b/src/dolphin/mtx/mtx44.c @@ -1,97 +1,888 @@ -#include "dolphin/mtx.h" -#include "math.h" +#include +#include +#include -void C_MTXFrustum(Mtx44 m, f32 arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6) { - f32 tmp = 1.0f / (arg4 - arg3); - m[0][0] = (2 * arg5) * tmp; - m[0][1] = 0.0f; - m[0][2] = (arg4 + arg3) * tmp; - m[0][3] = 0.0f; - tmp = 1.0f / (arg1 - arg2); - m[1][0] = 0.0f; - m[1][1] = (2 * arg5) * tmp; - m[1][2] = (arg1 + arg2) * tmp; - m[1][3] = 0.0f; - m[2][0] = 0.0f; - m[2][1] = 0.0f; - tmp = 1.0f / (arg6 - arg5); - m[2][2] = -(arg5)*tmp; - m[2][3] = -(arg6 * arg5) * tmp; - m[3][0] = 0.0f; - m[3][1] = 0.0f; - m[3][2] = -1.0f; - m[3][3] = 0.0f; +static f32 mtxUnit[] = {0.0f, 1.0f, 0.5f, 3.0f}; + +void C_MTXFrustum(Mtx44 m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f) { + f32 tmp; + + ASSERTMSGLINE(105, m, "MTXFrustum(): NULL Mtx44Ptr 'm' "); + ASSERTMSGLINE(106, t != b, "MTXFrustum(): 't' and 'b' clipping planes are equal "); + ASSERTMSGLINE(107, l != r, "MTXFrustum(): 'l' and 'r' clipping planes are equal "); + ASSERTMSGLINE(108, n != f, "MTXFrustum(): 'n' and 'f' clipping planes are equal "); + tmp = 1 / (r - l); + m[0][0] = (2 * n * tmp); + m[0][1] = 0; + m[0][2] = (tmp * (r + l)); + m[0][3] = 0; + tmp = 1 / (t - b); + m[1][0] = 0; + m[1][1] = (2 * n * tmp); + m[1][2] = (tmp * (t + b)); + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = 0; + tmp = 1 / (f - n); + m[2][2] = (-n * tmp); + m[2][3] = (tmp * -(f * n)); + m[3][0] = 0; + m[3][1] = 0; + m[3][2] = -1; + m[3][3] = 0; } -/* 80346F28-80346FF8 341868 00D0+00 0/0 6/6 0/0 .text C_MTXPerspective */ -// Functions match but has issues with float constants void C_MTXPerspective(Mtx44 m, f32 fovY, f32 aspect, f32 n, f32 f) { - f32 angle = fovY * 0.5f; + f32 angle; f32 cot; f32 tmp; + + ASSERTMSGLINE(179, m, "MTXPerspective(): NULL Mtx44Ptr 'm' "); + ASSERTMSGLINE(180, (fovY > 0.0) && (fovY < 180.0), "MTXPerspective(): 'fovY' out of range "); + ASSERTMSGLINE(181, 0.0f != aspect, "MTXPerspective(): 'aspect' is 0 "); + + angle = (0.5f * fovY); angle = MTXDegToRad(angle); - cot = 1.0f / tanf(angle); - m[0][0] = cot / aspect; + cot = 1 / tanf(angle); + m[0][0] = (cot / aspect); + m[0][1] = 0; + m[0][2] = 0; + m[0][3] = 0; + m[1][0] = 0; + m[1][1] = (cot); + m[1][2] = 0; + m[1][3] = 0; + m[2][0] = 0; + m[2][1] = 0; + tmp = 1 / (f - n); + m[2][2] = (-n * tmp); + m[2][3] = (tmp * -(f * n)); + m[3][0] = 0; + m[3][1] = 0; + m[3][2] = -1; + m[3][3] = 0; +} + +void C_MTXOrtho(Mtx44 m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f) { + f32 tmp; + + ASSERTMSGLINE(254, m, "MTXOrtho(): NULL Mtx44Ptr 'm' "); + ASSERTMSGLINE(255, t != b, "MTXOrtho(): 't' and 'b' clipping planes are equal "); + ASSERTMSGLINE(256, l != r, "MTXOrtho(): 'l' and 'r' clipping planes are equal "); + ASSERTMSGLINE(257, n != f, "MTXOrtho(): 'n' and 'f' clipping planes are equal "); + tmp = 1 / (r - l); + m[0][0] = 2 * tmp; + m[0][1] = 0; + m[0][2] = 0; + m[0][3] = (tmp * -(r + l)); + tmp = 1 / (t - b); + m[1][0] = 0; + m[1][1] = 2 * tmp; + m[1][2] = 0; + m[1][3] = (tmp * -(t + b)); + m[2][0] = 0; + m[2][1] = 0; + tmp = 1 / (f - n); + m[2][2] = (-1 * tmp); + m[2][3] = (-f * tmp); + m[3][0] = 0; + m[3][1] = 0; + m[3][2] = 0; + m[3][3] = 1; +} + +void C_MTX44Identity(Mtx44 m) { + ASSERTMSGLINE(324, m != 0, "MTX44Identity(): NULL Mtx44 'm' "); + + m[0][0] = 1.0f; m[0][1] = 0.0f; m[0][2] = 0.0f; m[0][3] = 0.0f; m[1][0] = 0.0f; - m[1][1] = cot; + m[1][1] = 1.0f; m[1][2] = 0.0f; m[1][3] = 0.0f; m[2][0] = 0.0f; m[2][1] = 0.0f; - tmp = 1.0f / (f - n); - m[2][2] = -(n)*tmp; - m[2][3] = -(f * n) * tmp; - m[3][0] = 0.0f; - m[3][1] = 0.0f; - m[3][2] = -1.0f; - m[3][3] = 0.0f; -} - -/* 80346FF8-80347090 341938 0098+00 0/0 11/11 2/2 .text C_MTXOrtho */ -void C_MTXOrtho(Mtx44 m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f) { - f32 tmp = 1.0f / (r - l); - m[0][0] = 2.0f * tmp; - m[0][1] = 0.0f; - m[0][2] = 0.0f; - m[0][3] = -(r + l) * tmp; - tmp = 1.0f / (t - b); - m[1][0] = 0.0f; - m[1][1] = 2.0f * tmp; - m[1][2] = 0.0f; - m[1][3] = -(t + b) * tmp; - m[2][0] = 0.0f; - m[2][1] = 0.0f; - tmp = 1.0f / (f - n); - m[2][2] = -(1.0f) * tmp; - m[2][3] = -(f)*tmp; + m[2][2] = 1.0f; + m[2][3] = 0.0f; m[3][0] = 0.0f; m[3][1] = 0.0f; m[3][2] = 0.0f; m[3][3] = 1.0f; } -asm void PSMTX44Copy(register Mtx44 src, register Mtx44 dest) { -#ifdef __MWERKS__ // clang-format off - nofralloc; - psq_l fp1, 0(src), 0, 0; - psq_st fp1, 0(dest), 0, 0; - psq_l fp1, 8(src), 0, 0; - psq_st fp1, 8(dest), 0, 0; - psq_l fp1, 0x10(src), 0, 0; - psq_st fp1, 0x10(dest), 0, 0; - psq_l fp1, 0x18(src), 0, 0; - psq_st fp1, 0x18(dest), 0, 0; - psq_l fp1, 0x20(src), 0, 0; - psq_st fp1, 0x20(dest), 0, 0; - psq_l fp1, 0x28(src), 0, 0; - psq_st fp1, 0x28(dest), 0, 0; - psq_l fp1, 0x30(src), 0, 0; - psq_st fp1, 0x30(dest), 0, 0; - psq_l fp1, 0x38(src), 0, 0; - psq_st fp1, 0x38(dest), 0, 0; - blr; -#endif // clang-format on -} \ No newline at end of file +void PSMTX44Identity(register Mtx44 m) { + register f32 c1 = 1.0f; + register f32 c0 = 0.0f; + + asm { + stfs c1, 0x0(m) + psq_st c0, 0x4(m), 0, 0 + psq_st c0, 0xc(m), 0, 0 + stfs c1, 0x14(m) + psq_st c0, 0x18(m), 0, 0 + psq_st c0, 0x20(m), 0, 0 + stfs c1, 0x28(m) + psq_st c0, 0x2c(m), 0, 0 + psq_st c0, 0x34(m), 0, 0 + stfs c1, 0x3c(m) + } +} + +void C_MTX44Copy(const Mtx44 src, Mtx44 dst) { + ASSERTMSGLINE(382, src != 0, "MTX44Copy(): NULL Mtx44Ptr 'src' "); + ASSERTMSGLINE(383, dst != 0, "MTX44Copy(): NULL Mtx44Ptr 'dst' "); + + if (src != dst) { + dst[0][0] = src[0][0]; + dst[0][1] = src[0][1]; + dst[0][2] = src[0][2]; + dst[0][3] = src[0][3]; + dst[1][0] = src[1][0]; + dst[1][1] = src[1][1]; + dst[1][2] = src[1][2]; + dst[1][3] = src[1][3]; + dst[2][0] = src[2][0]; + dst[2][1] = src[2][1]; + dst[2][2] = src[2][2]; + dst[2][3] = src[2][3]; + dst[3][0] = src[3][0]; + dst[3][1] = src[3][1]; + dst[3][2] = src[3][2]; + dst[3][3] = src[3][3]; + } +} + +asm void PSMTX44Copy(const register Mtx44 src, register Mtx44 dst) { + nofralloc + psq_l f1, 0x0(src), 0, 0 + psq_st f1, 0x0(dst), 0, 0 + psq_l f1, 0x8(src), 0, 0 + psq_st f1, 0x8(dst), 0, 0 + psq_l f1, 0x10(src), 0, 0 + psq_st f1, 0x10(dst), 0, 0 + psq_l f1, 0x18(src), 0, 0 + psq_st f1, 0x18(dst), 0, 0 + psq_l f1, 0x20(src), 0, 0 + psq_st f1, 0x20(dst), 0, 0 + psq_l f1, 0x28(src), 0, 0 + psq_st f1, 0x28(dst), 0, 0 + psq_l f1, 0x30(src), 0, 0 + psq_st f1, 0x30(dst), 0, 0 + psq_l f1, 0x38(src), 0, 0 + psq_st f1, 0x38(dst), 0, 0 + blr +} + +void C_MTX44Concat(const Mtx44 a, const Mtx44 b, Mtx44 ab) { + Mtx44 mTmp; + Mtx44Ptr m; + + ASSERTMSGLINE(454, a, "MTX44Concat(): NULL Mtx44Ptr 'a' "); + ASSERTMSGLINE(455, b, "MTX44Concat(): NULL Mtx44Ptr 'b' "); + ASSERTMSGLINE(456, ab, "MTX44Concat(): NULL Mtx44Ptr 'ab' "); + + if (ab == a || ab == b) { + m = mTmp; + } else { + m = ab; + } + + m[0][0] = (a[0][0] * b[0][0]) + (a[0][1] * b[1][0]) + (a[0][2] * b[2][0]) + (a[0][3] * b[3][0]); + m[0][1] = (a[0][0] * b[0][1]) + (a[0][1] * b[1][1]) + (a[0][2] * b[2][1]) + (a[0][3] * b[3][1]); + m[0][2] = (a[0][0] * b[0][2]) + (a[0][1] * b[1][2]) + (a[0][2] * b[2][2]) + (a[0][3] * b[3][2]); + m[0][3] = (a[0][0] * b[0][3]) + (a[0][1] * b[1][3]) + (a[0][2] * b[2][3]) + (a[0][3] * b[3][3]); + + m[1][0] = (a[1][0] * b[0][0]) + (a[1][1] * b[1][0]) + (a[1][2] * b[2][0]) + (a[1][3] * b[3][0]); + m[1][1] = (a[1][0] * b[0][1]) + (a[1][1] * b[1][1]) + (a[1][2] * b[2][1]) + (a[1][3] * b[3][1]); + m[1][2] = (a[1][0] * b[0][2]) + (a[1][1] * b[1][2]) + (a[1][2] * b[2][2]) + (a[1][3] * b[3][2]); + m[1][3] = (a[1][0] * b[0][3]) + (a[1][1] * b[1][3]) + (a[1][2] * b[2][3]) + (a[1][3] * b[3][3]); + + m[2][0] = (a[2][0] * b[0][0]) + (a[2][1] * b[1][0]) + (a[2][2] * b[2][0]) + (a[2][3] * b[3][0]); + m[2][1] = (a[2][0] * b[0][1]) + (a[2][1] * b[1][1]) + (a[2][2] * b[2][1]) + (a[2][3] * b[3][1]); + m[2][2] = (a[2][0] * b[0][2]) + (a[2][1] * b[1][2]) + (a[2][2] * b[2][2]) + (a[2][3] * b[3][2]); + m[2][3] = (a[2][0] * b[0][3]) + (a[2][1] * b[1][3]) + (a[2][2] * b[2][3]) + (a[2][3] * b[3][3]); + + m[3][0] = (a[3][0] * b[0][0]) + (a[3][1] * b[1][0]) + (a[3][2] * b[2][0]) + (a[3][3] * b[3][0]); + m[3][1] = (a[3][0] * b[0][1]) + (a[3][1] * b[1][1]) + (a[3][2] * b[2][1]) + (a[3][3] * b[3][1]); + m[3][2] = (a[3][0] * b[0][2]) + (a[3][1] * b[1][2]) + (a[3][2] * b[2][2]) + (a[3][3] * b[3][2]); + m[3][3] = (a[3][0] * b[0][3]) + (a[3][1] * b[1][3]) + (a[3][2] * b[2][3]) + (a[3][3] * b[3][3]); + + if (m == mTmp) { + C_MTX44Copy(mTmp, ab); + } +} + +asm void PSMTX44Concat(const register Mtx44 a, const register Mtx44 b, register Mtx44 ab) { + nofralloc + psq_l f0, 0x0(a), 0, 0 + psq_l f2, 0x0(b), 0, 0 + ps_muls0 f6, f2, f0 + psq_l f3, 0x10(b), 0, 0 + psq_l f4, 0x20(b), 0, 0 + ps_madds1 f6, f3, f0, f6 + psq_l f1, 0x8(a), 0, 0 + psq_l f5, 0x30(b), 0, 0 + ps_madds0 f6, f4, f1, f6 + psq_l f0, 0x10(a), 0, 0 + ps_madds1 f6, f5, f1, f6 + psq_l f1, 0x18(a), 0, 0 + ps_muls0 f8, f2, f0 + ps_madds1 f8, f3, f0, f8 + psq_l f0, 0x20(a), 0, 0 + ps_madds0 f8, f4, f1, f8 + ps_madds1 f8, f5, f1, f8 + psq_l f1, 0x28(a), 0, 0 + ps_muls0 f10, f2, f0 + ps_madds1 f10, f3, f0, f10 + psq_l f0, 0x30(a), 0, 0 + ps_madds0 f10, f4, f1, f10 + ps_madds1 f10, f5, f1, f10 + psq_l f1, 0x38(a), 0, 0 + ps_muls0 f12, f2, f0 + psq_l f2, 0x8(b), 0, 0 + ps_madds1 f12, f3, f0, f12 + psq_l f0, 0x0(a), 0, 0 + ps_madds0 f12, f4, f1, f12 + psq_l f3, 0x18(b), 0, 0 + ps_madds1 f12, f5, f1, f12 + psq_l f1, 0x8(a), 0, 0 + ps_muls0 f7, f2, f0 + psq_l f4, 0x28(b), 0, 0 + ps_madds1 f7, f3, f0, f7 + psq_l f5, 0x38(b), 0, 0 + ps_madds0 f7, f4, f1, f7 + psq_l f0, 0x10(a), 0, 0 + ps_madds1 f7, f5, f1, f7 + psq_l f1, 0x18(a), 0, 0 + ps_muls0 f9, f2, f0 + psq_st f6, 0x0(ab), 0, 0 + ps_madds1 f9, f3, f0, f9 + psq_l f0, 0x20(a), 0, 0 + ps_madds0 f9, f4, f1, f9 + psq_st f8, 0x10(ab), 0, 0 + ps_madds1 f9, f5, f1, f9 + psq_l f1, 0x28(a), 0, 0 + ps_muls0 f11, f2, f0 + psq_st f10, 0x20(ab), 0, 0 + ps_madds1 f11, f3, f0, f11 + psq_l f0, 0x30(a), 0, 0 + ps_madds0 f11, f4, f1, f11 + psq_st f12, 0x30(ab), 0, 0 + ps_madds1 f11, f5, f1, f11 + psq_l f1, 0x38(a), 0, 0 + ps_muls0 f13, f2, f0 + psq_st f7, 0x8(ab), 0, 0 + ps_madds1 f13, f3, f0, f13 + psq_st f9, 0x18(ab), 0, 0 + ps_madds0 f13, f4, f1, f13 + psq_st f11, 0x28(ab), 0, 0 + ps_madds1 f13, f5, f1, f13 + psq_st f13, 0x38(ab), 0, 0 + blr +} + +void C_MTX44Transpose(const Mtx44 src, Mtx44 xPose) { + Mtx44 mTmp; + Mtx44Ptr m; + + ASSERTMSGLINE(637, src, "MTX44Transpose(): NULL Mtx44Ptr 'src' "); + ASSERTMSGLINE(638, xPose, "MTX44Transpose(): NULL Mtx44Ptr 'xPose' "); + + if (src == xPose) { + m = mTmp; + } else { + m = xPose; + } + + m[0][0] = src[0][0]; + m[0][1] = src[1][0]; + m[0][2] = src[2][0]; + m[0][3] = src[3][0]; + m[1][0] = src[0][1]; + m[1][1] = src[1][1]; + m[1][2] = src[2][1]; + m[1][3] = src[3][1]; + m[2][0] = src[0][2]; + m[2][1] = src[1][2]; + m[2][2] = src[2][2]; + m[2][3] = src[3][2]; + m[3][0] = src[0][3]; + m[3][1] = src[1][3]; + m[3][2] = src[2][3]; + m[3][3] = src[3][3]; + + if (m == mTmp) { + MTX44Copy(mTmp, xPose); + } +} + +asm void PSMTX44Transpose(const register Mtx44 src, register Mtx44 xPose) { + nofralloc + psq_l f0, 0x0(src), 0, 0 + psq_l f1, 0x10(src), 0, 0 + ps_merge00 f4, f0, f1 + psq_l f2, 0x8(src), 0, 0 + psq_st f4, 0x0(xPose), 0, 0 + ps_merge11 f5, f0, f1 + psq_l f3, 0x18(src), 0, 0 + psq_st f5, 0x10(xPose), 0, 0 + ps_merge00 f4, f2, f3 + psq_l f0, 0x20(src), 0, 0 + psq_st f4, 0x20(xPose), 0, 0 + ps_merge11 f5, f2, f3 + psq_l f1, 0x30(src), 0, 0 + psq_st f5, 0x30(xPose), 0, 0 + ps_merge00 f4, f0, f1 + psq_l f2, 0x28(src), 0, 0 + psq_st f4, 0x8(xPose), 0, 0 + ps_merge11 f5, f0, f1 + psq_l f3, 0x38(src), 0, 0 + psq_st f5, 0x18(xPose), 0, 0 + ps_merge00 f4, f2, f3 + psq_st f4, 0x28(xPose), 0, 0 + ps_merge11 f5, f2, f3 + psq_st f5, 0x38(xPose), 0, 0 + blr +} + +#define SWAP(a, b) \ + { \ + f32 tmp; \ + tmp = a; \ + a = b; \ + b = tmp; \ + } + +u32 C_MTX44Inverse(const Mtx44 src, Mtx44 inv) { + Mtx44 gjm; + s32 i; + s32 j; + s32 k; + f32 w; + f32 max; + s32 swp; + f32 ftmp; + + ASSERTMSGLINE(734, src, "MTX44Inverse(): NULL Mtx44Ptr 'src' "); + ASSERTMSGLINE(735, inv, "MTX44Inverse(): NULL Mtx44Ptr 'inv' "); + + MTX44Copy(src, gjm); + MTX44Identity(inv); + + for (i = 0; i < 4; i++) { + max = 0.0f; + swp = i; + + for (k = i; k < 4; k++) { + ftmp = fabsf(gjm[k][i]); + if (ftmp > max) { + max = ftmp; + swp = k; + } + } + + if (max == 0.0f) { + return 0; + } + + if (swp != i) { + for (k = 0; k < 4; k++) { + SWAP(gjm[i][k], gjm[swp][k]); + SWAP(inv[i][k], inv[swp][k]); + } + } + + w = 1.0f / gjm[i][i]; + for (j = 0; j < 4; j++) { + gjm[i][j] *= w; + inv[i][j] *= w; + } + + for (k = 0; k < 4; k++) { + if (k != i) { + w = gjm[k][i]; + for (j = 0; j < 4; j++) { + gjm[k][j] -= gjm[i][j] * w; + inv[k][j] -= inv[i][j] * w; + } + } + } + } + + return 1; +} + +void C_MTX44Trans(Mtx44 m, f32 xT, f32 yT, f32 zT) { + ASSERTMSGLINE(835, m, "MTX44Trans(): NULL Mtx44Ptr 'm' "); + + m[0][0] = 1.0f; + m[0][1] = 0.0f; + m[0][2] = 0.0f; + m[0][3] = xT; + + m[1][0] = 0.0f; + m[1][1] = 1.0f; + m[1][2] = 0.0f; + m[1][3] = yT; + + m[2][0] = 0.0f; + m[2][1] = 0.0f; + m[2][2] = 1.0f; + m[2][3] = zT; + + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[3][2] = 0.0f; + m[3][3] = 1.0f; +} + +void PSMTX44Trans(register Mtx44 m, register f32 xT, register f32 yT, register f32 zT) { + register f32 c_zero = 0.0f; + register f32 c_one = 1.0f; + register f32 c_01; + + asm { + stfs xT, 0xc(m) + stfs yT, 0x1c(m) + ps_merge00 c_01, c_zero, c_one + stfs zT, 0x2c(m) + psq_st c_one, 0x0(m), 1, 0 + psq_st c_zero, 0x4(m), 0, 0 + psq_st c_01, 0x10(m), 0, 0 + psq_st c_zero, 0x18(m), 1, 0 + psq_st c_zero, 0x20(m), 0, 0 + psq_st c_one, 0x28(m), 1, 0 + psq_st c_zero, 0x30(m), 0, 0 + psq_st c_01, 0x38(m), 0, 0 + } +} + +void C_MTX44TransApply(const Mtx44 src, Mtx44 dst, f32 xT, f32 yT, f32 zT) { + ASSERTMSGLINE(899, src, "MTX44TransApply(): NULL Mtx44Ptr 'src' "); + ASSERTMSGLINE(900, dst, "MTX44TransApply(): NULL Mtx44Ptr 'src' "); //! wrong assert string + + if (src != dst) { + dst[0][0] = src[0][0]; + dst[0][1] = src[0][1]; + dst[0][2] = src[0][2]; + + dst[1][0] = src[1][0]; + dst[1][1] = src[1][1]; + dst[1][2] = src[1][2]; + + dst[2][0] = src[2][0]; + dst[2][1] = src[2][1]; + dst[2][2] = src[2][2]; + + dst[3][0] = src[3][0]; + dst[3][1] = src[3][1]; + dst[3][2] = src[3][2]; + + dst[3][3] = src[3][3]; + } + + dst[0][3] = (src[0][3] + xT); + dst[1][3] = (src[1][3] + yT); + dst[2][3] = (src[2][3] + zT); +} + +asm void PSMTX44TransApply(const register Mtx44 src, register Mtx44 dst, register f32 xT, register f32 yT, register f32 zT) { + nofralloc + psq_l f4, 0x0(src), 0, 0 + frsp xT, xT + psq_l f5, 0x8(src), 0, 0 + frsp yT, yT + psq_l f6, 0x10(src), 0, 0 + frsp zT, zT + psq_l f7, 0x18(src), 0, 0 + psq_st f4, 0x0(dst), 0, 0 + ps_sum1 f5, xT, f5, f5 + psq_l f4, 0x28(src), 0, 0 + psq_st f6, 0x10(dst), 0, 0 + ps_sum1 f7, yT, f7, f7 + psq_l f8, 0x20(src), 0, 0 + psq_st f5, 0x8(dst), 0, 0 + ps_sum1 f4, zT, f4, f4 + psq_st f7, 0x18(dst), 0, 0 + psq_st f8, 0x20(dst), 0, 0 + psq_l f5, 0x30(src), 0, 0 + psq_l f6, 0x38(src), 0, 0 + psq_st f4, 0x28(dst), 0, 0 + psq_st f5, 0x30(dst), 0, 0 + psq_st f6, 0x38(dst), 0, 0 + blr +} + +void C_MTX44Scale(Mtx44 m, f32 xS, f32 yS, f32 zS) { + ASSERTMSGLINE(976, m, "MTX44Scale(): NULL Mtx44Ptr 'm' "); + m[0][0] = xS; + m[0][1] = 0.0f; + m[0][2] = 0.0f; + m[0][3] = 0.0f; + + m[1][0] = 0.0f; + m[1][1] = yS; + m[1][2] = 0.0f; + m[1][3] = 0.0f; + + m[2][0] = 0.0f; + m[2][1] = 0.0f; + m[2][2] = zS; + m[2][3] = 0.0f; + + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[3][2] = 0.0f; + m[3][3] = 1.0f; +} + +void PSMTX44Scale(register Mtx44 m, register f32 xS, register f32 yS, register f32 zS) { + register f32 c_zero = 0.0f; + register f32 c_one = 1.0f; + + asm { + stfs xS, 0x0(m) + psq_st c_zero, 0x4(m), 0, 0 + psq_st c_zero, 0xc(m), 0, 0 + stfs yS, 0x14(m) + psq_st c_zero, 0x18(m), 0, 0 + psq_st c_zero, 0x20(m), 0, 0 + stfs zS, 0x28(m) + psq_st c_zero, 0x2c(m), 0, 0 + psq_st c_zero, 0x34(m), 0, 0 + stfs c_one, 0x3c(m) + } +} + +void C_MTX44ScaleApply(const Mtx44 src, Mtx44 dst, f32 xS, f32 yS, f32 zS) { + ASSERTMSGLINE(1036, src, "MTX44ScaleApply(): NULL Mtx44Ptr 'src' "); + ASSERTMSGLINE(1037, dst, "MTX44ScaleApply(): NULL Mtx44Ptr 'dst' "); + + dst[0][0] = (src[0][0] * xS); + dst[0][1] = (src[0][1] * xS); + dst[0][2] = (src[0][2] * xS); + dst[0][3] = (src[0][3] * xS); + + dst[1][0] = (src[1][0] * yS); + dst[1][1] = (src[1][1] * yS); + dst[1][2] = (src[1][2] * yS); + dst[1][3] = (src[1][3] * yS); + + dst[2][0] = (src[2][0] * zS); + dst[2][1] = (src[2][1] * zS); + dst[2][2] = (src[2][2] * zS); + dst[2][3] = (src[2][3] * zS); + + dst[3][0] = src[3][0]; + dst[3][1] = src[3][1]; + dst[3][2] = src[3][2]; + dst[3][3] = src[3][3]; +} + +asm void PSMTX44ScaleApply(const register Mtx44 src, register Mtx44 dst, register f32 xS, register f32 yS, register f32 zS) { + nofralloc + psq_l f4, 0x0(src), 0, 0 + frsp xS, xS + psq_l f5, 0x8(src), 0, 0 + frsp yS, yS + psq_l f6, 0x10(src), 0, 0 + ps_muls0 f4, f4, xS + psq_l f7, 0x18(src), 0, 0 + ps_muls0 f5, f5, xS + psq_l f8, 0x20(src), 0, 0 + frsp zS, zS + psq_st f4, 0x0(dst), 0, 0 + ps_muls0 f6, f6, yS + psq_l f9, 0x28(src), 0, 0 + psq_st f5, 0x8(dst), 0, 0 + ps_muls0 f7, f7, yS + psq_l f10, 0x30(src), 0, 0 + psq_st f6, 0x10(dst), 0, 0 + ps_muls0 f8, f8, zS + psq_l f11, 0x38(src), 0, 0 + psq_st f7, 0x18(dst), 0, 0 + ps_muls0 f9, f9, zS + psq_st f8, 0x20(dst), 0, 0 + psq_st f9, 0x28(dst), 0, 0 + psq_st f10, 0x30(dst), 0, 0 + psq_st f11, 0x38(dst), 0, 0 + blr +} + +void C_MTX44RotRad(Mtx44 m, char axis, f32 rad) { + f32 sinA; + f32 cosA; + + ASSERTMSGLINE(1118, m, "MTX44RotRad(): NULL Mtx44Ptr 'm' "); + sinA = sinf(rad); + cosA = cosf(rad); + C_MTX44RotTrig(m, axis, sinA, cosA); +} + +void PSMTX44RotRad(Mtx44 m, char axis, f32 rad) { + f32 sinA; + f32 cosA; + + sinA = sinf(rad); + cosA = cosf(rad); + PSMTX44RotTrig(m, axis, sinA, cosA); +} + +void C_MTX44RotTrig(Mtx44 m, char axis, f32 sinA, f32 cosA) { + ASSERTMSGLINE(1163, m, "MTX44RotTrig(): NULL Mtx44Ptr 'm' "); + + axis |= 0x20; + switch(axis) { + case 'x': + m[0][0] = 1.0f; + m[0][1] = 0.0f; + m[0][2] = 0.0f; + m[0][3] = 0.0f; + m[1][0] = 0.0f; + m[1][1] = cosA; + m[1][2] = -sinA; + m[1][3] = 0.0f; + m[2][0] = 0.0f; + m[2][1] = sinA; + m[2][2] = cosA; + m[2][3] = 0.0f; + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[3][2] = 0.0f; + m[3][3] = 1.0f; + break; + case 'y': + m[0][0] = cosA; + m[0][1] = 0.0f; + m[0][2] = sinA; + m[0][3] = 0.0f; + m[1][0] = 0.0f; + m[1][1] = 1.0f; + m[1][2] = 0.0f; + m[1][3] = 0.0f; + m[2][0] = -sinA; + m[2][1] = 0.0f; + m[2][2] = cosA; + m[2][3] = 0.0f; + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[3][2] = 0.0f; + m[3][3] = 1.0f; + break; + case 'z': + m[0][0] = cosA; + m[0][1] = -sinA; + m[0][2] = 0.0f; + m[0][3] = 0.0f; + m[1][0] = sinA; + m[1][1] = cosA; + m[1][2] = 0.0f; + m[1][3] = 0.0f; + m[2][0] = 0.0f; + m[2][1] = 0.0f; + m[2][2] = 1.0f; + m[2][3] = 0.0f; + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[3][2] = 0.0f; + m[3][3] = 1.0f; + break; + default: + ASSERTMSGLINE(1191, FALSE, "MTX44RotTrig(): invalid 'axis' value "); + break; + } +} + +void PSMTX44RotTrig(register Mtx44 m, register char axis, register f32 sinA, register f32 cosA) { + register f32 ftmp0; + register f32 ftmp1; + register f32 ftmp2; + register f32 ftmp3; + register f32 ftmp4; + + register f32 c_zero = 0.0f; + register f32 c_one = 1.0f; + + asm { + frsp sinA, sinA + ori axis, axis, 0x20 + frsp cosA, cosA + cmplwi axis, 'x' + beq L_00001AB4 + cmplwi axis, 'y' + beq L_00001AE8 + cmplwi axis, 'z' + beq L_00001B20 + b L_00001B54 + L_00001AB4: + psq_st c_one, 0x0(m), 1, 0 + psq_st c_zero, 0x4(m), 0, 0 + ps_neg ftmp0, sinA + psq_st c_zero, 0xc(m), 0, 0 + ps_merge00 ftmp1, sinA, cosA + psq_st c_zero, 0x1c(m), 0, 0 + ps_merge00 ftmp0, cosA, ftmp0 + psq_st c_zero, 0x2c(m), 0, 0 + psq_st c_zero, 0x34(m), 0, 0 + psq_st ftmp1, 0x24(m), 0, 0 + psq_st ftmp0, 0x14(m), 0, 0 + psq_st c_one, 0x3c(m), 1, 0 + b L_00001B54 + L_00001AE8: + ps_merge00 ftmp1, cosA, c_zero + psq_st c_zero, 0x30(m), 0, 0 + ps_neg ftmp0, sinA + psq_st c_zero, 0x18(m), 0, 0 + ps_merge00 ftmp3, c_zero, c_one + psq_st ftmp1, 0x0(m), 0, 0 + ps_merge00 ftmp4, ftmp0, c_zero + ps_merge00 ftmp2, sinA, c_zero + psq_st ftmp3, 0x10(m), 0, 0 + psq_st ftmp2, 0x8(m), 0, 0 + psq_st ftmp4, 0x20(m), 0, 0 + psq_st ftmp1, 0x28(m), 0, 0 + psq_st ftmp3, 0x38(m), 0, 0 + b L_00001B54 + L_00001B20: + psq_st c_zero, 0x8(m), 0, 0 + ps_neg ftmp0, sinA + psq_st c_zero, 0x18(m), 0, 0 + ps_merge00 ftmp1, sinA, cosA + psq_st c_zero, 0x20(m), 0, 0 + ps_merge00 ftmp2, c_one, c_zero + psq_st c_zero, 0x30(m), 0, 0 + ps_merge00 ftmp3, c_zero, c_one + psq_st ftmp1, 0x10(m), 0, 0 + ps_merge00 ftmp4, cosA, ftmp0 + psq_st ftmp2, 0x28(m), 0, 0 + psq_st ftmp3, 0x38(m), 0, 0 + psq_st ftmp4, 0x0(m), 0, 0 + L_00001B54: + } +} + +void C_MTX44RotAxisRad(Mtx44 m, const Vec* axis, f32 rad) { + Vec vN; + f32 s; + f32 c; + f32 t; + f32 x; + f32 y; + f32 z; + f32 xSq; + f32 ySq; + f32 zSq; + + ASSERTMSGLINE(1300, m, "MTX44RotAxisRad(): NULL Mtx44Ptr 'm' "); + ASSERTMSGLINE(1301, axis, "MTX44RotAxisRad(): NULL VecPtr 'axis' "); + + s = sinf(rad); + c = cosf(rad); + t = 1 - c; + + C_VECNormalize(axis, &vN); + + x = vN.x; + y = vN.y; + z = vN.z; + + xSq = (x * x); + ySq = (y * y); + zSq = (z * z); + + m[0][0] = (c + (t * xSq)); + m[0][1] = (y * (t * x)) - (s * z); + m[0][2] = (z * (t * x)) + (s * y); + m[0][3] = 0.0f; + + m[1][0] = ((y * (t * x)) + (s * z)); + m[1][1] = (c + (t * ySq)); + m[1][2] = ((z * (t * y)) - (s * x)); + m[1][3] = 0.0f; + + m[2][0] = ((z * (t * x)) - (s * y)); + m[2][1] = ((z * (t * y)) + (s * x)); + m[2][2] = (c + (t * zSq)); + m[2][3] = 0.0f; + + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[3][2] = 0.0f; + m[3][3] = 1.0f; +} + +static void __PSMTX44RotAxisRadInternal(register Mtx44 m, const register Vec* axis, register f32 sT, register f32 cT) { + register f32 tT; + register f32 fc0; + register f32 tmp0; + register f32 tmp1; + register f32 tmp2; + register f32 tmp3; + register f32 tmp4; + register f32 tmp5; + register f32 tmp6; + register f32 tmp7; + register f32 tmp8; + register f32 tmp9; + + tmp9 = 0.5f; + tmp8 = 3.0f; + + asm { + frsp cT, cT + psq_l tmp0, 0x0(axis), 0, 0 + frsp sT, sT + lfs tmp1, 0x8(axis) + ps_mul tmp2, tmp0, tmp0 + fadds tmp7, tmp9, tmp9 + ps_madd tmp3, tmp1, tmp1, tmp2 + fsubs fc0, tmp9, tmp9 + ps_sum0 tmp4, tmp3, tmp1, tmp2 + fsubs tT, tmp7, cT + frsqrte tmp5, tmp4 + ps_merge00 tmp7, fc0, tmp7 + fmuls tmp2, tmp5, tmp5 + fmuls tmp3, tmp5, tmp9 + psq_st fc0, 0x30(m), 0, 0 + fnmsubs tmp2, tmp2, tmp4, tmp8 + fmuls tmp5, tmp2, tmp3 + psq_st tmp7, 0x38(m), 0, 0 + ps_merge00 cT, cT, cT + ps_muls0 tmp0, tmp0, tmp5 + ps_muls0 tmp1, tmp1, tmp5 + ps_muls0 tmp4, tmp0, tT + ps_muls0 tmp9, tmp0, sT + ps_muls0 tmp5, tmp1, tT + ps_muls1 tmp3, tmp4, tmp0 + ps_muls0 tmp2, tmp4, tmp0 + ps_muls0 tmp4, tmp4, tmp1 + fnmsubs tmp6, tmp1, sT, tmp3 + fmadds tmp7, tmp1, sT, tmp3 + ps_neg tmp0, tmp9 + ps_sum0 tmp8, tmp4, fc0, tmp9 + ps_sum0 tmp2, tmp2, tmp6, cT + ps_sum1 tmp3, cT, tmp7, tmp3 + ps_sum0 tmp6, tmp0, fc0, tmp4 + psq_st tmp8, 0x8(m), 0, 0 + ps_sum0 tmp0, tmp4, tmp4, tmp0 + psq_st tmp2, 0x0(m), 0, 0 + ps_muls0 tmp5, tmp5, tmp1 + psq_st tmp3, 0x10(m), 0, 0 + ps_sum1 tmp4, tmp9, tmp0, tmp4 + psq_st tmp6, 0x18(m), 0, 0 + ps_sum0 tmp5, tmp5, fc0, cT + psq_st tmp4, 0x20(m), 0, 0 + psq_st tmp5, 0x28(m), 0, 0 + } +} + +void PSMTX44RotAxisRad(Mtx44 m, const Vec* axis, f32 rad) { + f32 sinT, cosT; + + sinT = sinf(rad); + cosT = cosf(rad); + + __PSMTX44RotAxisRadInternal(m, axis, sinT, cosT); +} diff --git a/src/dolphin/mtx/mtx44vec.c b/src/dolphin/mtx/mtx44vec.c new file mode 100644 index 0000000000..478c49fc97 --- /dev/null +++ b/src/dolphin/mtx/mtx44vec.c @@ -0,0 +1,247 @@ +#include +#include +#include "fake_tgmath.h" + +void C_MTX44MultVec(const Mtx44 m, const Vec* src, Vec* dst) { + Vec vTmp; + f32 w; + + ASSERTMSGLINE(67, m, "MTX44MultVec(): NULL Mtx44Ptr 'm' "); + ASSERTMSGLINE(68, src, "MTX44MultVec(): NULL VecPtr 'src' "); + ASSERTMSGLINE(69, dst, "MTX44MultVec(): NULL VecPtr 'dst' "); + + vTmp.x = m[0][0] * src->x + m[0][1] * src->y + m[0][2] * src->z + m[0][3]; + vTmp.y = m[1][0] * src->x + m[1][1] * src->y + m[1][2] * src->z + m[1][3]; + vTmp.z = m[2][0] * src->x + m[2][1] * src->y + m[2][2] * src->z + m[2][3]; + w = m[3][0] * src->x + m[3][1] * src->y + m[3][2] * src->z + m[3][3]; + w = 1.0f / w; + + dst->x = vTmp.x * w; + dst->y = vTmp.y * w; + dst->z = vTmp.z * w; +} + +asm void PSMTX44MultVec(const register Mtx44 m, const register Vec* src, register Vec* dst) { + nofralloc + psq_l f0, 0x0(src), 0, 0 + psq_l f2, 0x30(m), 0, 0 + psq_l f1, 0x8(src), 1, 0 + ps_mul f4, f0, f2 + psq_l f3, 0x38(m), 0, 0 + ps_madd f5, f1, f3, f4 + ps_merge11 f12, f1, f1 + ps_sum0 f13, f5, f5, f5 + psq_l f4, 0x0(m), 0, 0 + ps_merge00 f13, f13, f13 + psq_l f5, 0x8(m), 0, 0 + ps_div f13, f12, f13 + psq_l f6, 0x10(m), 0, 0 + psq_l f7, 0x18(m), 0, 0 + psq_l f8, 0x20(m), 0, 0 + psq_l f9, 0x28(m), 0, 0 + ps_mul f4, f0, f4 + ps_madd f2, f1, f5, f4 + ps_mul f6, f0, f6 + ps_madd f3, f1, f7, f6 + ps_mul f8, f0, f8 + ps_sum0 f2, f2, f2, f2 + ps_madd f9, f1, f9, f8 + ps_sum1 f2, f3, f2, f3 + ps_sum0 f3, f9, f9, f9 + ps_mul f2, f2, f13 + psq_st f2, 0x0(dst), 0, 0 + ps_mul f3, f3, f13 + psq_st f3, 0x8(dst), 1, 0 + blr +} + +void C_MTX44MultVecArray(const Mtx44 m, const Vec* srcBase, Vec* dstBase, u32 count) { + u32 i; + Vec vTmp; + f32 w; + + ASSERTMSGLINE(154, m, "MTX44MultVecArray(): NULL Mtx44Ptr 'm' "); + ASSERTMSGLINE(155, srcBase, "MTX44MultVecArray(): NULL VecPtr 'srcBase' "); + ASSERTMSGLINE(156, dstBase, "MTX44MultVecArray(): NULL VecPtr 'dstBase' "); + + for(i = 0; i < count; i++) { + vTmp.x = m[0][0] * srcBase->x + m[0][1] * srcBase->y + m[0][2] * srcBase->z + m[0][3]; + vTmp.y = m[1][0] * srcBase->x + m[1][1] * srcBase->y + m[1][2] * srcBase->z + m[1][3]; + vTmp.z = m[2][0] * srcBase->x + m[2][1] * srcBase->y + m[2][2] * srcBase->z + m[2][3]; + w = m[3][0] * srcBase->x + m[3][1] * srcBase->y + m[3][2] * srcBase->z + m[3][3]; + w = 1.0f / w; + dstBase->x = vTmp.x * w; + dstBase->y = vTmp.y * w; + dstBase->z = vTmp.z * w; + srcBase++; + dstBase++; + } +} + +asm void PSMTX44MultVecArray(const register Mtx44 m, const register Vec* srcBase, register Vec* dstBase, register u32 count) { + nofralloc + stwu r1, -0x10(r1) + subi count, count, 0x1 + psq_l f6, 0x30(m), 0, 0 + mtctr count + psq_l f8, 0x0(srcBase), 0, 0 + subi dstBase, dstBase, 0x4 + psq_l f7, 0x38(m), 0, 0 + psq_lu f9, 0x8(srcBase), 1, 0 + ps_mul f13, f6, f8 + psq_l f0, 0x0(m), 0, 0 + stfd f14, 0x8(r1) + ps_madd f13, f7, f9, f13 + psq_l f2, 0x10(m), 0, 0 + ps_merge11 f14, f9, f9 + ps_mul f10, f0, f8 + psq_l f4, 0x20(m), 0, 0 + ps_mul f11, f2, f8 + psq_l f1, 0x8(m), 0, 0 + ps_mul f12, f4, f8 + psq_l f3, 0x18(m), 0, 0 + ps_sum0 f13, f13, f13, f13 + psq_l f5, 0x28(m), 0, 0 +L_00000468: + ps_madd f10, f1, f9, f10 + ps_madd f11, f3, f9, f11 + ps_madd f12, f5, f9, f12 + ps_sum0 f10, f10, f10, f10 + ps_sum0 f11, f11, f11, f11 + ps_sum0 f12, f12, f12, f12 + ps_div f13, f14, f13 + psq_lu f8, 0x4(srcBase), 0, 0 + psq_lu f9, 0x8(srcBase), 1, 0 + ps_mul f10, f10, f13 + psq_stu f10, 0x4(dstBase), 1, 0 + ps_mul f11, f11, f13 + psq_stu f11, 0x4(dstBase), 1, 0 + ps_mul f12, f12, f13 + psq_stu f12, 0x4(dstBase), 1, 0 + ps_mul f13, f6, f8 + ps_mul f10, f0, f8 + ps_mul f11, f2, f8 + ps_madd f13, f7, f9, f13 + ps_mul f12, f4, f8 + ps_sum0 f13, f13, f13, f13 + bdnz L_00000468 + ps_madd f10, f1, f9, f10 + ps_madd f11, f3, f9, f11 + ps_madd f12, f5, f9, f12 + ps_sum0 f10, f10, f10, f10 + ps_sum0 f11, f11, f11, f11 + ps_sum0 f12, f12, f12, f12 + ps_div f13, f14, f13 + ps_mul f10, f10, f13 + psq_st f10, 0x4(dstBase), 1, 0 + ps_mul f11, f11, f13 + psq_st f11, 0x8(dstBase), 1, 0 + ps_mul f12, f12, f13 + psq_st f12, 0xc(dstBase), 1, 0 + lfd f14, 0x8(r1) + addi r1, r1, 0x10 + blr +} + +void C_MTX44MultVecSR(const Mtx44 m, const Vec* src, Vec* dst) { + Vec vTmp; + + ASSERTMSGLINE(288, m, "MTX44MultVecSR(): NULL Mtx44Ptr 'm' "); + ASSERTMSGLINE(289, src, "MTX44MultVecSR(): NULL VecPtr 'src' "); + ASSERTMSGLINE(290, dst, "MTX44MultVecSR(): NULL VecPtr 'dst' "); + vTmp.x = (m[0][2] * src->z) + ((m[0][0] * src->x) + (m[0][1] * src->y)); + vTmp.y = (m[1][2] * src->z) + ((m[1][0] * src->x) + (m[1][1] * src->y)); + vTmp.z = (m[2][2] * src->z) + ((m[2][0] * src->x) + (m[2][1] * src->y)); + dst->x = vTmp.x; + dst->y = vTmp.y; + dst->z = vTmp.z; +} + +asm void PSMTX44MultVecSR(const register Mtx m, const register Vec* src, register Vec* dst) { + nofralloc + psq_l f0, 0x0(m), 0, 0 + psq_l f6, 0x0(src), 0, 0 + psq_l f2, 0x10(m), 0, 0 + ps_mul f8, f0, f6 + psq_l f4, 0x20(m), 0, 0 + ps_mul f10, f2, f6 + psq_l f7, 0x8(src), 1, 0 + ps_mul f12, f4, f6 + psq_l f3, 0x18(m), 0, 0 + ps_sum0 f8, f8, f8, f8 + psq_l f5, 0x28(m), 0, 0 + ps_sum0 f10, f10, f10, f10 + psq_l f1, 0x8(m), 0, 0 + ps_sum0 f12, f12, f12, f12 + ps_madd f9, f1, f7, f8 + psq_st f9, 0x0(dst), 1, 0 + ps_madd f11, f3, f7, f10 + psq_st f11, 0x4(dst), 1, 0 + ps_madd f13, f5, f7, f12 + psq_st f13, 0x8(dst), 1, 0 + blr +} + +void C_MTX44MultVecArraySR(const Mtx44 m, const Vec* srcBase, Vec* dstBase, u32 count) { + u32 i; + Vec vTmp; + + ASSERTMSGLINE(379, m, "MTX44MultVecArraySR(): NULL Mtx44Ptr 'm' "); + ASSERTMSGLINE(380, srcBase, "MTX44MultVecArraySR(): NULL VecPtr 'srcBase' "); + ASSERTMSGLINE(381, dstBase, "MTX44MultVecArraySR(): NULL VecPtr 'dstBase' "); + + for(i = 0; i < count; i++) { + vTmp.x = (m[0][2] * srcBase->z) + ((m[0][0] * srcBase->x) + (m[0][1] * srcBase->y)); + vTmp.y = (m[1][2] * srcBase->z) + ((m[1][0] * srcBase->x) + (m[1][1] * srcBase->y)); + vTmp.z = (m[2][2] * srcBase->z) + ((m[2][0] * srcBase->x) + (m[2][1] * srcBase->y)); + dstBase->x = vTmp.x; + dstBase->y = vTmp.y; + dstBase->z = vTmp.z; + srcBase++; + dstBase++; + } +} + +asm void PSMTX44MultVecArraySR(const register Mtx44 m, const register Vec* srcBase, register Vec* dstBase, register u32 count) { + nofralloc + psq_l f0, 0x0(m), 0, 0 + subi count, count, 0x1 + psq_l f6, 0x0(srcBase), 0, 0 + ps_mul f8, f0, f6 + psq_l f2, 0x10(m), 0, 0 + ps_mul f9, f2, f6 + psq_l f4, 0x20(m), 0, 0 + psq_lu f7, 0x8(srcBase), 1, 0 + ps_mul f10, f4, f6 + psq_l f1, 0x8(m), 1, 0 + mtctr count + psq_l f3, 0x18(m), 1, 0 + subi dstBase, dstBase, 0x4 + psq_l f5, 0x28(m), 1, 0 +L_00000890: + ps_madd f11, f1, f7, f8 + psq_lu f6, 0x4(srcBase), 0, 0 + ps_madd f12, f3, f7, f9 + ps_madd f13, f5, f7, f10 + psq_lu f7, 0x8(srcBase), 1, 0 + ps_sum0 f11, f11, f8, f8 + psq_stu f11, 0x4(dstBase), 1, 0 + ps_sum0 f12, f12, f9, f9 + psq_stu f12, 0x4(dstBase), 1, 0 + ps_sum0 f13, f13, f10, f10 + psq_stu f13, 0x4(dstBase), 1, 0 + ps_mul f8, f0, f6 + ps_mul f9, f2, f6 + ps_mul f10, f4, f6 + bdnz L_00000890 + ps_madd f11, f1, f7, f8 + ps_madd f12, f3, f7, f9 + ps_madd f13, f5, f7, f10 + ps_sum0 f11, f11, f8, f8 + psq_stu f11, 0x4(dstBase), 1, 0 + ps_sum0 f12, f12, f9, f9 + psq_stu f12, 0x4(dstBase), 1, 0 + ps_sum0 f13, f13, f10, f10 + psq_stu f13, 0x4(dstBase), 1, 0 + blr +} diff --git a/src/dolphin/mtx/mtxstack.c b/src/dolphin/mtx/mtxstack.c new file mode 100644 index 0000000000..475175c2ca --- /dev/null +++ b/src/dolphin/mtx/mtxstack.c @@ -0,0 +1,108 @@ +#include +#include +#include "fake_tgmath.h" + +void MTXInitStack(MTXStack* sPtr, u32 numMtx) { + ASSERTMSGLINE(74, sPtr, "MTXInitStack(): NULL MtxStackPtr 'sPtr' "); + ASSERTMSGLINE(75, sPtr->stackBase, "MTXInitStack(): 'sPtr' contains a NULL ptr to stack memory "); + ASSERTMSGLINE(76, numMtx, "MTXInitStack(): 'numMtx' is 0 "); + + sPtr->numMtx = numMtx; + sPtr->stackPtr = 0; +} + +MtxPtr MTXPush(MTXStack* sPtr, const Mtx m) { + ASSERTMSGLINE(104, sPtr, "MTXPush(): NULL MtxStackPtr 'sPtr' "); + ASSERTMSGLINE(105, sPtr->stackBase, "MTXPush(): 'sPtr' contains a NULL ptr to stack memory "); + ASSERTMSGLINE(106, m, "MTXPush(): NULL MtxPtr 'm' "); + + if (sPtr->stackPtr == NULL) { + sPtr->stackPtr = sPtr->stackBase; + MTXCopy(m, sPtr->stackPtr); + } else { + ASSERTMSGLINE(121, ((((s32)sPtr->stackPtr - (s32)sPtr->stackBase) / 16) / 3) < (sPtr->numMtx - 1), "MTXPush(): stack overflow "); + MTXCopy(m, sPtr->stackPtr + 3); + sPtr->stackPtr += 3; + } + + return sPtr->stackPtr; +} + +MtxPtr MTXPushFwd(MTXStack* sPtr, const Mtx m) { + ASSERTMSGLINE(157, sPtr, "MTXPushFwd(): NULL MtxStackPtr 'sPtr' "); + ASSERTMSGLINE(158, sPtr->stackBase, "MTXPushFwd(): 'sPtr' contains a NULL ptr to stack memory "); + ASSERTMSGLINE(159, m, "MTXPushFwd(): NULL MtxPtr 'm' "); + + if (sPtr->stackPtr == NULL) { + sPtr->stackPtr = sPtr->stackBase; + MTXCopy(m, sPtr->stackPtr); + } else { + ASSERTMSGLINE(174, ((((s32)sPtr->stackPtr - (s32)sPtr->stackBase) / 16) / 3) < (sPtr->numMtx - 1), "MTXPushFwd(): stack overflow"); + MTXConcat(sPtr->stackPtr, m, sPtr->stackPtr + 3); + sPtr->stackPtr += 3; + } + + return sPtr->stackPtr; +} + +MtxPtr MTXPushInv(MTXStack* sPtr, const Mtx m) { + Mtx mInv; + ASSERTMSGLINE(216, sPtr, "MTXPushInv(): NULL MtxStackPtr 'sPtr' "); + ASSERTMSGLINE(217, sPtr->stackBase, "MTXPushInv(): 'sPtr' contains a NULL ptr to stack memory "); + ASSERTMSGLINE(218, m, "MTXPushInv(): NULL MtxPtr 'm' "); + + MTXInverse(m, mInv); + if (sPtr->stackPtr == NULL) { + sPtr->stackPtr = sPtr->stackBase; + MTXCopy(mInv, sPtr->stackPtr); + } else { + ASSERTMSGLINE(236, ((((s32)sPtr->stackPtr - (s32)sPtr->stackBase) / 16) / 3) < (sPtr->numMtx - 1), "MTXPushInv(): stack overflow"); + MTXConcat(mInv, sPtr->stackPtr, sPtr->stackPtr + 3); + sPtr->stackPtr += 3; + } + + return sPtr->stackPtr; +} + +MtxPtr MTXPushInvXpose(MTXStack* sPtr, const Mtx m) { + Mtx mIT; + ASSERTMSGLINE(279, sPtr, "MTXPushInvXpose(): NULL MtxStackPtr 'sPtr' "); + ASSERTMSGLINE(280, sPtr->stackBase, "MTXPushInvXpose(): 'sPtr' contains a NULL ptr to stack memory "); + ASSERTMSGLINE(281, m, "MTXPushInvXpose(): NULL MtxPtr 'm' "); + + MTXInverse(m, mIT); + MTXTranspose(mIT, mIT); + if (sPtr->stackPtr == NULL) { + sPtr->stackPtr = sPtr->stackBase; + MTXCopy(mIT, sPtr->stackPtr); + } else { + ASSERTMSGLINE(300, ((((s32)sPtr->stackPtr - (s32)sPtr->stackBase) / 16) / 3) < (sPtr->numMtx - 1), "MTXPushInvXpose(): stack overflow "); + MTXConcat(sPtr->stackPtr, mIT, sPtr->stackPtr + 3); + sPtr->stackPtr += 3; + } + + return sPtr->stackPtr; +} + +MtxPtr MTXPop(MTXStack* sPtr) { + ASSERTMSGLINE(328, sPtr, "MTXPop(): NULL MtxStackPtr 'sPtr' "); + ASSERTMSGLINE(329, sPtr->stackBase, "MTXPop(): 'sPtr' contains a NULL ptr to stack memory "); + + if (sPtr->stackPtr == NULL) { + return NULL; + } + + if (sPtr->stackBase == sPtr->stackPtr) { + sPtr->stackPtr = NULL; + return NULL; + } + + sPtr->stackPtr -= 3; + return sPtr->stackPtr; +} + +MtxPtr MTXGetStackPtr(const MTXStack* sPtr) { + ASSERTMSGLINE(366, sPtr, "MTXGetStackPtr(): NULL MtxStackPtr 'sPtr' "); + ASSERTMSGLINE(367, sPtr->stackBase, "MTXGetStackPtr(): 'sPtr' contains a NULL ptr to stack memory "); + return sPtr->stackPtr; +} diff --git a/src/dolphin/mtx/mtxvec.c b/src/dolphin/mtx/mtxvec.c index 4fa1eb830e..cf98b5d94b 100644 --- a/src/dolphin/mtx/mtxvec.c +++ b/src/dolphin/mtx/mtxvec.c @@ -1,155 +1,204 @@ -/** - * mtxvec.c - * Description: - */ +#include +#include +#include -#include "dolphin/mtx.h" +void C_MTXMultVec(const Mtx m, const Vec* src, Vec* dst) { + Vec vTmp; -/* 80346D6C-80346DC0 3416AC 0054+00 0/0 158/158 826/826 .text PSMTXMultVec */ -asm void PSMTXMultVec(const register Mtx m, const register Vec* in, register Vec* out) { -#ifdef __MWERKS__ // clang-format off - nofralloc; - psq_l fp0, 0(in), 0, 0; - psq_l fp2, 0(m), 0, 0; - psq_l fp1, 8(in), 1, 0; - ps_mul fp4, fp2, fp0; - psq_l fp3, 8(m), 0, 0; - ps_madd fp5, fp3, fp1, fp4; - psq_l fp8, 16(m), 0, 0; - ps_sum0 fp6, fp5, fp6, fp5; - psq_l fp9, 24(m), 0, 0; - ps_mul fp10, fp8, fp0; - psq_st fp6, 0(out), 1, 0; - ps_madd fp11, fp9, fp1, fp10; - psq_l fp2, 32(m), 0, 0; - ps_sum0 fp12, fp11, fp12, fp11; - psq_l fp3, 40(m), 0, 0; - ps_mul fp4, fp2, fp0; - psq_st fp12, 4(out), 1, 0; - ps_madd fp5, fp3, fp1, fp4; - ps_sum0 fp6, fp5, fp6, fp5; - psq_st fp6, 8(out), 1, 0; - blr -#endif // clang-format on + ASSERTMSGLINE(66, m, "MTXMultVec(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(67, src, "MTXMultVec(): NULL VecPtr 'src' "); + ASSERTMSGLINE(68, dst, "MTXMultVec(): NULL VecPtr 'dst' "); + + vTmp.x = m[0][3] + ((m[0][2] * src->z) + ((m[0][0] * src->x) + (m[0][1] * src->y))); + vTmp.y = m[1][3] + ((m[1][2] * src->z) + ((m[1][0] * src->x) + (m[1][1] * src->y))); + vTmp.z = m[2][3] + ((m[2][2] * src->z) + ((m[2][0] * src->x) + (m[2][1] * src->y))); + dst->x = vTmp.x; + dst->y = vTmp.y; + dst->z = vTmp.z; } -/* 80346DC0-80346E4C 341700 008C+00 0/0 2/2 3/3 .text PSMTXMultVecArray */ -asm void PSMTXMultVecArray(register const Mtx m, register const Vec* srcBase, register Vec* dstBase, - register u32 count) { -#ifdef __MWERKS__ // clang-format off +asm void PSMTXMultVec(const register Mtx m, const register Vec* src, register Vec* dst) { nofralloc + psq_l f0, Vec.x(src), 0, 0 + psq_l f2, 0(m), 0, 0 + psq_l f1, Vec.z(src), 1, 0 + ps_mul f4, f2, f0 + psq_l f3, 8(m), 0, 0 + ps_madd f5, f3, f1, f4 + psq_l f8, 16(m), 0, 0 + ps_sum0 f6, f5, f6, f5 + psq_l f9, 24(m), 0, 0 + ps_mul f10, f8, f0 + psq_st f6, Vec.x(dst), 1, 0 + ps_madd f11, f9, f1, f10 + psq_l f2, 32(m), 0, 0 + ps_sum0 f12, f11, f12, f11 + psq_l f3, 40(m), 0, 0 + ps_mul f4, f2, f0 + psq_st f12, Vec.y(dst), 1, 0 + ps_madd f5, f3, f1, f4 + ps_sum0 f6, f5, f6, f5 + psq_st f6, Vec.z(dst), 1, 0 + blr +} - psq_l f13, 0(m), 0, 0 - psq_l f12, 16(m), 0, 0 - addi count, count, -1 - psq_l f11, 8(m), 0, 0 +void C_MTXMultVecArray(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count) { + u32 i; + Vec vTmp; + + ASSERTMSGLINE(168, m, "MTXMultVecArray(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(169, srcBase, "MTXMultVecArray(): NULL VecPtr 'srcBase' "); + ASSERTMSGLINE(170, dstBase, "MTXMultVecArray(): NULL VecPtr 'dstBase' "); + ASSERTMSGLINE(171, count > 1, "MTXMultVecArray(): count must be greater than 1."); + + for(i = 0; i < count; i++) { + vTmp.x = m[0][3] + ((m[0][2] * srcBase->z) + ((m[0][0] * srcBase->x) + (m[0][1] * srcBase->y))); + vTmp.y = m[1][3] + ((m[1][2] * srcBase->z) + ((m[1][0] * srcBase->x) + (m[1][1] * srcBase->y))); + vTmp.z = m[2][3] + ((m[2][2] * srcBase->z) + ((m[2][0] * srcBase->x) + (m[2][1] * srcBase->y))); + dstBase->x = vTmp.x; + dstBase->y = vTmp.y; + dstBase->z = vTmp.z; + srcBase++; + dstBase++; + } +} + +asm void PSMTXMultVecArray(const register Mtx m, const register Vec* srcBase, register Vec* dstBase, register u32 count) { + nofralloc + psq_l f13, 0x0(m), 0, 0 + psq_l f12, 0x10(m), 0, 0 + subi count, count, 0x1 + psq_l f11, 0x8(m), 0, 0 ps_merge00 f0, f13, f12 - addi dstBase, dstBase, -4 - psq_l f10, 24(m), 0, 0 + subi dstBase, dstBase, 0x4 + psq_l f10, 0x18(m), 0, 0 ps_merge11 f1, f13, f12 mtctr count - psq_l f4, 32(m), 0, 0 + psq_l f4, 0x20(m), 0, 0 ps_merge00 f2, f11, f10 - psq_l f5, 40(m), 0, 0 + psq_l f5, 0x28(m), 0, 0 ps_merge11 f3, f11, f10 - psq_l f6, 0(srcBase), 0, 0 - psq_lu f7, 8(srcBase), 1, 0 + psq_l f6, 0x0(srcBase), 0, 0 + psq_lu f7, 0x8(srcBase), 1, 0 ps_madds0 f8, f0, f6, f3 ps_mul f9, f4, f6 ps_madds1 f8, f1, f6, f8 ps_madd f10, f5, f7, f9 - -lbl_80346E0C: - psq_lu f6, 4(srcBase), 0, 0 +L_000003C4: + psq_lu f6, 0x4(srcBase), 0, 0 ps_madds0 f12, f2, f7, f8 - psq_lu f7, 8(srcBase), 1, 0 + psq_lu f7, 0x8(srcBase), 1, 0 ps_sum0 f13, f10, f9, f10 ps_madds0 f8, f0, f6, f3 ps_mul f9, f4, f6 - psq_stu f12, 4(dstBase), 0, 0 + psq_stu f12, 0x4(dstBase), 0, 0 ps_madds1 f8, f1, f6, f8 - psq_stu f13, 8(dstBase), 1, 0 + psq_stu f13, 0x8(dstBase), 1, 0 ps_madd f10, f5, f7, f9 - bdnz lbl_80346E0C - + bdnz L_000003C4 ps_madds0 f12, f2, f7, f8 ps_sum0 f13, f10, f9, f10 - psq_stu f12, 4(dstBase), 0, 0 - psq_stu f13, 8(dstBase), 1, 0 + psq_stu f12, 0x4(dstBase), 0, 0 + psq_stu f13, 0x8(dstBase), 1, 0 blr -#endif // clang-format on } -/* 80346E4C-80346EA0 34178C 0054+00 0/0 47/47 9/9 .text PSMTXMultVecSR */ -asm void PSMTXMultVecSR(const register Mtx mtx, const register Vec* in, register Vec* out) { -#ifdef __MWERKS__ // clang-format off - nofralloc; - psq_l fp0, 0(mtx), 0, 0; - psq_l fp6, 0(in), 0, 0; - psq_l fp2, 0x10(mtx), 0, 0; - ps_mul fp8, fp0, fp6; - psq_l fp4, 0x20(mtx), 0, 0; - ps_mul fp10, fp2, fp6; - psq_l fp7, 8(in), 1, 0; - ps_mul fp12, fp4, fp6; - psq_l fp3, 0x18(mtx), 0, 0; - ps_sum0 fp8, fp8, fp8, fp8; - psq_l fp5, 0x28(mtx), 0, 0; - ps_sum0 fp10, fp10, fp10, fp10; - psq_l fp1, 8(mtx), 0, 0; - ps_sum0 fp12, fp12, fp12, fp12; - ps_madd fp9, fp1, fp7, fp8; - psq_st fp9, 0(out), 1, 0; - ps_madd fp11, fp3, fp7, fp10; - psq_st fp11, 4(out), 1, 0; - ps_madd fp13, fp5, fp7, fp12; - psq_st fp13, 8(out), 1, 0; - blr -#endif // clang-format on +void C_MTXMultVecSR(const Mtx m, const Vec* src, Vec* dst) { + Vec vTmp; + + ASSERTMSGLINE(313, m, "MTXMultVecSR(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(314, src, "MTXMultVecSR(): NULL VecPtr 'src' "); + ASSERTMSGLINE(315, dst, "MTXMultVecSR(): NULL VecPtr 'dst' "); + + vTmp.x = (m[0][2] * src->z) + ((m[0][0] * src->x) + (m[0][1] * src->y)); + vTmp.y = (m[1][2] * src->z) + ((m[1][0] * src->x) + (m[1][1] * src->y)); + vTmp.z = (m[2][2] * src->z) + ((m[2][0] * src->x) + (m[2][1] * src->y)); + dst->x = vTmp.x; + dst->y = vTmp.y; + dst->z = vTmp.z; } -/* 80346EA0-80346F28 3417E0 0088+00 0/0 2/2 0/0 .text PSMTXMultVecArraySR */ -asm void PSMTXMultVecArraySR(register const Mtx m, register const Vec* srcBase, - register Vec* dstBase, register u32 count) { -#ifdef __MWERKS__ // clang-format off +asm void PSMTXMultVecSR(const register Mtx m, const register Vec* src, register Vec* dst) { nofralloc + psq_l f0, 0x0(m), 0, 0 + psq_l f6, 0x0(src), 0, 0 + psq_l f2, 0x10(m), 0, 0 + ps_mul f8, f0, f6 + psq_l f4, 0x20(m), 0, 0 + ps_mul f10, f2, f6 + psq_l f7, 0x8(src), 1, 0 + ps_mul f12, f4, f6 + psq_l f3, 0x18(m), 0, 0 + ps_sum0 f8, f8, f8, f8 + psq_l f5, 0x28(m), 0, 0 + ps_sum0 f10, f10, f10, f10 + psq_l f1, 0x8(m), 0, 0 + ps_sum0 f12, f12, f12, f12 + ps_madd f9, f1, f7, f8 + psq_st f9, 0x0(dst), 1, 0 + ps_madd f11, f3, f7, f10 + psq_st f11, 0x4(dst), 1, 0 + ps_madd f13, f5, f7, f12 + psq_st f13, 0x8(dst), 1, 0 + blr +} - psq_l f13, 0(m), 0, 0 - psq_l f12, 16(m), 0, 0 - addi count, count, -1 - psq_l f11, 8(m), 1, 0 +void C_MTXMultVecArraySR(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count) { + u32 i; + Vec vTmp; + + ASSERTMSGLINE(410, m, "MTXMultVecArraySR(): NULL MtxPtr 'm' "); + ASSERTMSGLINE(411, srcBase, "MTXMultVecArraySR(): NULL VecPtr 'srcBase' "); + ASSERTMSGLINE(412, dstBase, "MTXMultVecArraySR(): NULL VecPtr 'dstBase' "); + ASSERTMSGLINE(413, count > 1, "MTXMultVecArraySR(): count must be greater than 1."); + + for(i = 0; i < count; i++) { + vTmp.x = (m[0][2] * srcBase->z) + ((m[0][0] * srcBase->x) + (m[0][1] * srcBase->y)); + vTmp.y = (m[1][2] * srcBase->z) + ((m[1][0] * srcBase->x) + (m[1][1] * srcBase->y)); + vTmp.z = (m[2][2] * srcBase->z) + ((m[2][0] * srcBase->x) + (m[2][1] * srcBase->y)); + dstBase->x = vTmp.x; + dstBase->y = vTmp.y; + dstBase->z = vTmp.z; + srcBase++; + dstBase++; + } +} + +asm void PSMTXMultVecArraySR(const register Mtx m, const register Vec* srcBase, register Vec* dstBase, register u32 count) { + nofralloc + psq_l f13, 0x0(m), 0, 0 + psq_l f12, 0x10(m), 0, 0 + subi count, count, 0x1 + psq_l f11, 0x8(m), 1, 0 ps_merge00 f0, f13, f12 - addi dstBase, dstBase, -4 - psq_l f10, 24(m), 1, 0 + subi dstBase, dstBase, 0x4 + psq_l f10, 0x18(m), 1, 0 ps_merge11 f1, f13, f12 mtctr count - psq_l f3, 32(m), 0, 0 + psq_l f3, 0x20(m), 0, 0 ps_merge00 f2, f11, f10 - psq_l f4, 40(m), 1, 0 - psq_l f6, 0(srcBase), 0, 0 - psq_lu f7, 8(srcBase), 1, 0 + psq_l f4, 0x28(m), 1, 0 + psq_l f6, 0x0(srcBase), 0, 0 + psq_lu f7, 0x8(srcBase), 1, 0 ps_muls0 f8, f0, f6 ps_mul f9, f3, f6 ps_madds1 f8, f1, f6, f8 ps_madd f10, f4, f7, f9 - -lbl_80346EE8: - psq_lu f6, 4(srcBase), 0, 0 +L_000007D0: + psq_lu f6, 0x4(srcBase), 0, 0 ps_madds0 f12, f2, f7, f8 - psq_lu f7, 8(srcBase), 1, 0 + psq_lu f7, 0x8(srcBase), 1, 0 ps_sum0 f13, f10, f9, f9 ps_muls0 f8, f0, f6 ps_mul f9, f3, f6 - psq_stu f12, 4(dstBase), 0, 0 + psq_stu f12, 0x4(dstBase), 0, 0 ps_madds1 f8, f1, f6, f8 - psq_stu f13, 8(dstBase), 1, 0 + psq_stu f13, 0x8(dstBase), 1, 0 ps_madd f10, f4, f7, f9 - bdnz lbl_80346EE8 - + bdnz L_000007D0 ps_madds0 f12, f2, f7, f8 ps_sum0 f13, f10, f9, f9 - psq_stu f12, 4(dstBase), 0, 0 - psq_stu f13, 8(dstBase), 1, 0 + psq_stu f12, 0x4(dstBase), 0, 0 + psq_stu f13, 0x8(dstBase), 1, 0 blr -#endif // clang-format on -} \ No newline at end of file +} diff --git a/src/dolphin/mtx/psmtx.c b/src/dolphin/mtx/psmtx.c new file mode 100644 index 0000000000..6ec6c29554 --- /dev/null +++ b/src/dolphin/mtx/psmtx.c @@ -0,0 +1,336 @@ +#include +#include +#include "fake_tgmath.h" + +asm void PSMTXReorder(const register Mtx src, register ROMtx dest) { + psq_l f0, 0(src), 0, 0 + psq_l f2, 16(src), 0, 0 + psq_l f4, 32(src), 0, 0 + psq_l f1, 8(src), 0, 0 + ps_merge00 f6, f0, f2 + psq_l f3, 24(src), 0, 0 + ps_merge01 f12, f4, f0 + psq_l f5, 40(src), 0, 0 + ps_merge11 f7, f2, f4 + psq_st f6, 0(dest), 0, 0 + ps_merge00 f8, f1, f3 + psq_st f12, 8(dest), 0, 0 + ps_merge01 f9, f5, f1 + psq_st f7, 16(dest), 0, 0 + ps_merge11 f10, f3, f5 + psq_st f8, 24(dest), 0, 0 + psq_st f9, 32(dest), 0, 0 + psq_st f10, 40(dest), 0, 0 +} + +asm void PSMTXROMultVecArray(const register ROMtx m, const register Vec* srcBase, register Vec* dstBase, register u32 count) { + nofralloc + stwu r1, -64(r1) + stfd f14, 8(r1) + subi r7, count, 1 + stfd f15, 16(r1) + srwi r7, r7, 1 + stfd f16, 24(r1) + stfd f17, 32(r1) + stfd f18, 40(r1) + mtctr r7 + psq_l f0, 0(m), 0, 0 + subi srcBase, srcBase, 8 + psq_l f1, 8(m), 1, 0 + subi dstBase, dstBase, 4 + psq_l f6, 36(m), 0, 0 + psq_lu f8, 8(srcBase), 0, 0 + psq_l f7, 44(m), 1, 0 + psq_lu f9, 8(srcBase), 0, 0 + ps_madds0 f11, f0, f8, f6 + psq_l f2, 12(m), 0, 0 + ps_madds0 f12, f1, f8, f7 + psq_l f3, 20(m), 1, 0 + ps_madds1 f13, f0, f9, f6 + psq_lu f10, 8(srcBase), 0, 0 + ps_madds1 f14, f1, f9, f7 + psq_l f5, 32(m), 1, 0 + ps_madds1 f11, f2, f8, f11 + ps_madds1 f12, f3, f8, f12 + psq_l f4, 24(m), 0, 0 + ps_madds0 f13, f2, f10, f13 + psq_lu f8, 8(srcBase), 0, 0 + ps_madds0 f14, f3, f10, f14 + ps_madds0 f15, f4, f9, f11 + ps_madds0 f16, f5, f9, f12 + psq_lu f9, 8(srcBase), 0, 0 + ps_madds1 f17, f4, f10, f13 + ps_madds1 f18, f5, f10, f14 + psq_lu f10, 8(srcBase), 0, 0 +loop: + ps_madds0 f11, f0, f8, f6 + psq_stu f15, 4(dstBase), 0, 0 + ps_madds0 f12, f1, f8, f7 + psq_stu f16, 8(dstBase), 1, 0 + ps_madds1 f13, f0, f9, f6 + psq_stu f17, 4(dstBase), 0, 0 + ps_madds1 f14, f1, f9, f7 + psq_stu f18, 8(dstBase), 1, 0 + ps_madds1 f11, f2, f8, f11 + ps_madds1 f12, f3, f8, f12 + psq_lu f8, 8(srcBase), 0, 0 + ps_madds0 f13, f2, f10, f13 + ps_madds0 f14, f3, f10, f14 + ps_madds0 f15, f4, f9, f11 + ps_madds0 f16, f5, f9, f12 + psq_lu f9, 8(srcBase), 0, 0 + ps_madds1 f17, f4, f10, f13 + ps_madds1 f18, f5, f10, f14 + psq_lu f10, 8(srcBase), 0, 0 + bdnz loop + psq_stu f15, 4(dstBase), 0, 0 + clrlwi. r7, count, 31 + psq_stu f16, 8(dstBase), 1, 0 + bne exit + psq_stu f17, 4(dstBase), 0, 0 + psq_stu f18, 8(dstBase), 1, 0 +exit: + lfd f14, 8(r1) + lfd f15, 16(r1) + lfd f16, 24(r1) + lfd f17, 32(r1) + lfd f18, 40(r1) + addi r1, r1, 64 + blr +} + +asm void PSMTXROSkin2VecArray(const register ROMtx m0, const register ROMtx m1, const register f32* wtBase, const register Vec* srcBase, register Vec* dstBase, register u32 count) { + nofralloc + stwu r1, -160(r1) + stfd f14, 8(r1) + stfd f15, 16(r1) + stfd f16, 24(r1) + stfd f17, 32(r1) + stfd f18, 40(r1) + stfd f19, 48(r1) + stfd f20, 56(r1) + stfd f21, 64(r1) + stfd f22, 72(r1) + stfd f23, 80(r1) + stfd f24, 88(r1) + stfd f25, 96(r1) + stfd f26, 104(r1) + stfd f27, 112(r1) + stfd f28, 120(r1) + stfd f29, 128(r1) + stfd f30, 136(r1) + subi r9, r8, 1 + mtctr r9 + subi srcBase, srcBase, 4 + subi dstBase, dstBase, 4 + subi wtBase, wtBase, 4 + psq_l f14, 0(m0), 0, 0 + psq_l f22, 0(m1), 0, 0 + psq_l f15, 8(m0), 1, 0 + psq_l f23, 8(m1), 1, 0 + psq_l f16, 12(m0), 0, 0 + psq_l f24, 12(m1), 0, 0 + ps_sub f22, f22, f14 + psq_l f17, 20(m0), 1, 0 + psq_l f25, 20(m1), 1, 0 + ps_sub f23, f23, f15 + psq_l f18, 24(m0), 0, 0 + psq_l f26, 24(m1), 0, 0 + ps_sub f24, f24, f16 + psq_l f19, 32(m0), 1, 0 + psq_l f27, 32(m1), 1, 0 + ps_sub f25, f25, f17 + psq_l f20, 36(m0), 0, 0 + psq_l f28, 36(m1), 0, 0 + ps_sub f26, f26, f18 + psq_l f21, 44(m0), 1, 0 + psq_l f29, 44(m1), 1, 0 + ps_sub f27, f27, f19 + ps_sub f28, f28, f20 + ps_sub f29, f29, f21 + psq_lu f30, 4(wtBase), 1, 0 + psq_lu f8, 4(srcBase), 0, 0 + psq_lu f9, 8(srcBase), 1, 0 + ps_madds0 f0, f22, f30, f14 + ps_madds0 f1, f23, f30, f15 + ps_madds0 f2, f24, f30, f16 + ps_madds0 f3, f25, f30, f17 + ps_madds0 f4, f26, f30, f18 + ps_madds0 f5, f27, f30, f19 + ps_madds0 f6, f28, f30, f20 + ps_madds0 f7, f29, f30, f21 + ps_madds0 f12, f0, f8, f6 + ps_madds0 f13, f1, f8, f7 + psq_lu f30, 4(wtBase), 1, 0 +loop: + ps_madds1 f12, f2, f8, f12 + ps_madds1 f13, f3, f8, f13 + psq_lu f8, 4(srcBase), 0, 0 + ps_madds0 f10, f4, f9, f12 + ps_madds0 f11, f5, f9, f13 + psq_lu f9, 8(srcBase), 1, 0 + ps_madds0 f0, f22, f30, f14 + ps_madds0 f1, f23, f30, f15 + ps_madds0 f2, f24, f30, f16 + ps_madds0 f3, f25, f30, f17 + ps_madds0 f4, f26, f30, f18 + ps_madds0 f5, f27, f30, f19 + ps_madds0 f6, f28, f30, f20 + ps_madds0 f7, f29, f30, f21 + psq_stu f10, 4(dstBase), 0, 0 + ps_madds0 f12, f0, f8, f6 + ps_madds0 f13, f1, f8, f7 + psq_stu f11, 8(dstBase), 1, 0 + psq_lu f30, 4(wtBase), 1, 0 + bdnz loop + ps_madds1 f12, f2, f8, f12 + ps_madds1 f13, f3, f8, f13 + ps_madds0 f10, f4, f9, f12 + psq_stu f10, 4(dstBase), 0, 0 + ps_madds0 f11, f5, f9, f13 + psq_stu f11, 8(dstBase), 1, 0 + lfd f14, 8(r1) + lfd f15, 16(r1) + lfd f16, 24(r1) + lfd f17, 32(r1) + lfd f18, 40(r1) + lfd f19, 48(r1) + lfd f20, 56(r1) + lfd f21, 64(r1) + lfd f22, 72(r1) + lfd f23, 80(r1) + lfd f24, 88(r1) + lfd f25, 96(r1) + lfd f26, 104(r1) + lfd f27, 112(r1) + lfd f28, 120(r1) + lfd f29, 128(r1) + lfd f30, 136(r1) + addi r1, r1, 160 + blr +} + +asm void PSMTXROMultS16VecArray(const register Mtx m, const register S16Vec* srcBase, register Vec* dstBase, register u32 count) { + nofralloc + stwu r1, -64(r1) + stfd f14, 8(r1) + subi r7, count, 1 + stfd f15, 16(r1) + srwi r7, r7, 1 + stfd f16, 24(r1) + lis r8, 7 + stfd f17, 32(r1) + mtspr GQR6, r8 + stfd f18, 40(r1) + mtctr r7 + psq_l f0, 0(m), 0, 0 + subi srcBase, srcBase, 4 + psq_l f1, 8(m), 1, 0 + subi dstBase, dstBase, 4 + psq_l f6, 36(m), 0, 0 + psq_lu f8, 4(srcBase), 0, 6 + psq_l f7, 44(m), 1, 0 + psq_lu f9, 4(srcBase), 0, 6 + ps_madds0 f11, f0, f8, f6 + psq_l f2, 12(m), 0, 0 + ps_madds0 f12, f1, f8, f7 + psq_l f3, 20(m), 1, 0 + ps_madds1 f13, f0, f9, f6 + psq_lu f10, 4(srcBase), 0, 6 + ps_madds1 f14, f1, f9, f7 + psq_l f5, 32(m), 1, 0 + ps_madds1 f11, f2, f8, f11 + ps_madds1 f12, f3, f8, f12 + psq_l f4, 24(m), 0, 0 + ps_madds0 f13, f2, f10, f13 + psq_lu f8, 4(srcBase), 0, 6 + ps_madds0 f14, f3, f10, f14 + ps_madds0 f15, f4, f9, f11 + ps_madds0 f16, f5, f9, f12 + psq_lu f9, 4(srcBase), 0, 6 + ps_madds1 f17, f4, f10, f13 + ps_madds1 f18, f5, f10, f14 + psq_lu f10, 4(srcBase), 0, 6 +loop: + ps_madds0 f11, f0, f8, f6 + psq_stu f15, 4(dstBase), 0, 0 + ps_madds0 f12, f1, f8, f7 + psq_stu f16, 8(dstBase), 1, 0 + ps_madds1 f13, f0, f9, f6 + psq_stu f17, 4(dstBase), 0, 0 + ps_madds1 f14, f1, f9, f7 + psq_stu f18, 8(dstBase), 1, 0 + ps_madds1 f11, f2, f8, f11 + ps_madds1 f12, f3, f8, f12 + psq_lu f8, 4(srcBase), 0, 6 + ps_madds0 f13, f2, f10, f13 + ps_madds0 f14, f3, f10, f14 + ps_madds0 f15, f4, f9, f11 + ps_madds0 f16, f5, f9, f12 + psq_lu f9, 4(srcBase), 0, 6 + ps_madds1 f17, f4, f10, f13 + ps_madds1 f18, f5, f10, f14 + psq_lu f10, 4(srcBase), 0, 6 + bdnz loop + psq_stu f15, 4(dstBase), 0, 0 + clrlwi. r7, count, 31 + psq_stu f16, 8(dstBase), 1, 0 + bne exit + psq_stu f17, 4(dstBase), 0, 0 + psq_stu f18, 8(dstBase), 1, 0 +exit: + lfd f14, 8(r1) + lfd f15, 16(r1) + lfd f16, 24(r1) + lfd f17, 32(r1) + lfd f18, 40(r1) + addi r1, r1, 64 + blr +} + +asm void PSMTXMultS16VecArray(const register ROMtx* m, const register S16Vec* srcBase, register Vec* dstBase, register u32 count) { + psq_l f0, 0(m), 0, 0 + lis r7, 7 + mtspr GQR6, r7 + psq_l f6, 0(srcBase), 0, 6 + subi count, count, 1 + psq_l f7, 4(srcBase), 1, 6 + mtctr count + psq_l f1, 8(m), 0, 0 + addi srcBase, srcBase, 4 + psq_l f2, 16(m), 0, 0 + subi dstBase, dstBase, 4 + psq_l f3, 24(m), 0, 0 + ps_mul f8, f0, f6 + psq_l f4, 32(m), 0, 0 + ps_mul f10, f2, f6 + psq_l f5, 40(m), 0, 0 + ps_mul f12, f4, f6 + psq_lu f6, 2(srcBase), 0, 6 + ps_madd f8, f1, f7, f8 + ps_madd f10, f3, f7, f10 + ps_madd f12, f5, f7, f12 + psq_lu f7, 4(srcBase), 1, 6 + ps_sum0 f9, f8, f8, f8 +loop: + ps_sum0 f11, f10, f10, f10 + ps_mul f8, f0, f6 + ps_sum0 f13, f12, f12, f12 + ps_mul f10, f2, f6 + psq_stu f9, 4(dstBase), 1, 0 + ps_mul f12, f4, f6 + psq_stu f11, 4(dstBase), 1, 0 + ps_madd f8, f1, f7, f8 + psq_stu f13, 4(dstBase), 1, 0 + ps_madd f10, f3, f7, f10 + psq_lu f6, 2(srcBase), 0, 6 + ps_madd f12, f5, f7, f12 + psq_lu f7, 4(srcBase), 1, 6 + ps_sum0 f9, f8, f8, f8 + bdnz loop + ps_sum0 f11, f10, f10, f10 + ps_sum0 f13, f12, f12, f12 + psq_stu f9, 4(dstBase), 1, 0 + psq_stu f11, 4(dstBase), 1, 0 + psq_stu f13, 4(dstBase), 1, 0 +} diff --git a/src/dolphin/mtx/quat.c b/src/dolphin/mtx/quat.c index 5707c58784..9af3c3cd56 100644 --- a/src/dolphin/mtx/quat.c +++ b/src/dolphin/mtx/quat.c @@ -1,94 +1,486 @@ -/** - * quat.c - * Dolphin - Matrix Quaternion Functions - */ +#include +#include +#include -#include "dolphin/mtx/quat.h" -#include "math.h" +void C_QUATAdd(const Quaternion* p, const Quaternion* q, Quaternion* r) { + ASSERTMSGLINE(77, p, "QUATAdd(): NULL QuaternionPtr 'p' "); + ASSERTMSGLINE(78, q, "QUATAdd(): NULL QuaternionPtr 'q' "); + ASSERTMSGLINE(79, r, "QUATAdd(): NULL QuaternionPtr 'r' "); + + r->x = p->x + q->x; + r->y = p->y + q->y; + r->z = p->z + q->z; + r->w = p->w + q->w; +} + +void PSQUATAdd(const register Quaternion* p, const register Quaternion* q, register Quaternion* r) { + register f32 pxy, qxy, rxy, pzw, qzw, rzw; -/* 80347418-80347474 341D58 005C+00 0/0 0/0 2/2 .text PSQUATMultiply */ -void PSQUATMultiply(register const Quaternion* a, register const Quaternion* b, - register Quaternion* ab) { asm { - psq_l f0, 0(a), 0, 0 - psq_l f1, 8(a), 0, 0 - psq_l f2, 0(b), 0, 0 - ps_neg f5, f0 - psq_l f3, 8(b), 0, 0 - ps_neg f6, f1 - ps_merge01 f4, f5, f0 - ps_muls0 f7, f1, f2 - ps_muls0 f5, f5, f2 - ps_merge01 f1, f6, f1 - ps_muls1 f8, f4, f2 - ps_madds0 f7, f4, f3, f7 - ps_muls1 f2, f1, f2 - ps_madds0 f5, f1, f3, f5 - ps_madds1 f8, f6, f3, f8 - ps_merge10 f7, f7, f7 - ps_madds1 f2, f0, f3, f2 - ps_merge10 f5, f5, f5 - ps_add f7, f7, f2 - psq_st f7, 0(ab), 0, 0 - ps_sub f5, f5, f8 - psq_st f5, 8(ab), 0, 0 + psq_l pxy, 0(p), 0, 0 + psq_l qxy, 0(q), 0, 0 + ps_add rxy, pxy, qxy + psq_st rxy, 0(r), 0, 0 + psq_l pzw, 8(p), 0, 0 + psq_l qzw, 8(q), 0, 0 + ps_add rzw, pzw, qzw + psq_st rzw, 8(r), 0, 0 } } -// Dummy functions to set literal order -static f32 dummyLiteralFunc() { - return 0.0f; +void C_QUATSubtract(const Quaternion* p, const Quaternion* q, Quaternion* r) { + ASSERTMSGLINE(133, p, "QUATSubtract(): NULL QuaternionPtr 'p' "); + ASSERTMSGLINE(134, q, "QUATSubtract(): NULL QuaternionPtr 'q' "); + ASSERTMSGLINE(135, r, "QUATSubtract(): NULL QuaternionPtr 'r' "); + + r->x = p->x - q->x; + r->y = p->y - q->y; + r->z = p->z - q->z; + r->w = p->w - q->w; } -static f32 dummyLiteralFunc2() { - return 1.0f; -} +void PSQUATSubtract(const register Quaternion* p, const register Quaternion* q, register Quaternion* r) { + register f32 pxy, qxy, rxy, pzw, qzw, rzw; -/* 80347474-80347500 341DB4 008C+00 0/0 1/1 0/0 .text C_QUATRotAxisRad */ -void C_QUATRotAxisRad(Quaternion* q, const Vec* axis, f32 rad) { - f32 tmp, tmp2, tmp3; - Vec dst; - - tmp = rad; - PSVECNormalize(axis, &dst); - - tmp2 = tmp * 0.5f; - tmp3 = sinf(tmp * 0.5f); - tmp = tmp3; - tmp3 = cosf(tmp2); - - q->x = tmp * dst.x; - q->y = tmp * dst.y; - q->z = tmp * dst.z; - q->w = tmp3; -} - -/* 80347500-80347674 341E40 0174+00 0/0 0/0 2/2 .text C_QUATSlerp */ -void C_QUATSlerp(const Quaternion* p, const Quaternion* q, Quaternion* r, f32 t) { - f32 ratioA, ratioB; - - f32 value = 1.0f; - f32 cosHalfTheta = p->x * q->x + p->y * q->y + p->z * q->z + p->w * q->w; - - if (cosHalfTheta < 0.0f) { - cosHalfTheta = -cosHalfTheta; - value = -value; + asm { + psq_l pxy, 0(p), 0, 0 + psq_l qxy, 0(q), 0, 0 + ps_sub rxy, pxy, qxy + psq_st rxy, 0(r), 0, 0 + psq_l pzw, 8(p), 0, 0 + psq_l qzw, 8(q), 0, 0 + ps_sub rzw, pzw, qzw + psq_st rzw, 8(r), 0, 0 } +} - if (cosHalfTheta <= 0.9999899864196777f) { - f32 halfTheta = acosf(cosHalfTheta); - f32 sinHalfTheta = sinf(halfTheta); +void C_QUATMultiply(const Quaternion* p, const Quaternion* q, Quaternion* pq) { + Quaternion* r; + Quaternion pqTmp; - ratioA = sinf((1.0f - t) * halfTheta) / sinHalfTheta; - ratioB = sinf(t * halfTheta) / sinHalfTheta; - value *= ratioB; + ASSERTMSGLINE(193, p, "QUATMultiply(): NULL QuaternionPtr 'p' "); + ASSERTMSGLINE(194, q, "QUATMultiply(): NULL QuaternionPtr 'q' "); + ASSERTMSGLINE(195, pq, "QUATMultiply(): NULL QuaternionPtr 'pq' "); + + if (p == pq || q == pq){ + r = &pqTmp; } else { - ratioA = 1.0f - t; - value *= t; + r = pq; } - r->x = (ratioA * p->x) + (value * q->x); - r->y = (ratioA * p->y) + (value * q->y); - r->z = (ratioA * p->z) + (value * q->z); - r->w = (ratioA * p->w) + (value * q->w); -} \ No newline at end of file + r->w = (p->w * q->w) - (p->x * q->x) - (p->y * q->y) - (p->z * q->z); + r->x = (p->w * q->x) + (p->x * q->w) + (p->y * q->z) - (p->z * q->y); + r->y = (p->w * q->y) + (p->y * q->w) + (p->z * q->x) - (p->x * q->z); + r->z = (p->w * q->z) + (p->z * q->w) + (p->x * q->y) - (p->y * q->x); + + if (r == &pqTmp) { + *pq = pqTmp; + } +} + +void PSQUATMultiply(const register Quaternion* p, const register Quaternion* q, register Quaternion* pq) { + register f32 pxy, pzw; + register f32 qxy, qzw; + register f32 pnxy, pnzw, pnxny, pnznw; + register f32 rxy, rzw; + register f32 sxy, szw; + + asm { + psq_l pxy, 0x0(p), 0, 0 + psq_l pzw, 0x8(p), 0, 0 + psq_l qxy, 0x0(q), 0, 0 + ps_neg pnxny, pxy + psq_l qzw, 0x8(q), 0, 0 + ps_neg pnznw, pzw + ps_merge01 pnxy, pnxny, pxy + ps_muls0 rxy, pzw, qxy + ps_muls0 rzw, pnxny, qxy + ps_merge01 pnzw, pnznw, pzw + ps_muls1 szw, pnxy, qxy + ps_madds0 rxy, pnxy, qzw, rxy + ps_muls1 sxy, pnzw, qxy + ps_madds0 rzw, pnzw, qzw, rzw + ps_madds1 szw, pnznw, qzw, szw + ps_merge10 rxy, rxy, rxy + ps_madds1 sxy, pxy, qzw, sxy + ps_merge10 rzw, rzw, rzw + ps_add rxy, rxy, sxy + psq_st rxy, 0x0(pq), 0, 0 + ps_sub rzw, rzw, szw + psq_st rzw, 0x8(pq), 0, 0 + } +} + +void C_QUATScale(const Quaternion* q, Quaternion* r, f32 scale) { + ASSERTMSGLINE(306, q, "QUATScale(): NULL QuaternionPtr 'q' "); + ASSERTMSGLINE(307, r, "QUATScale(): NULL QuaternionPtr 'r' "); + + r->x = q->x * scale; + r->y = q->y * scale; + r->z = q->z * scale; + r->w = q->w * scale; +} + +void PSQUATScale(const register Quaternion* q, register Quaternion* r, register f32 scale) { + register f32 rxy, rzw; + + asm { + psq_l rxy, 0(q), 0, 0 + psq_l rzw, 8(q), 0, 0 + ps_muls0 rxy, rxy, scale + psq_st rxy, 0(r), 0, 0 + ps_muls0 rzw, rzw, scale + psq_st rzw, 8(r), 0, 0 + } +} + +f32 C_QUATDotProduct(const Quaternion* p, const Quaternion* q) { + ASSERTMSGLINE(357, p, "QUATDotProduct(): NULL QuaternionPtr 'p' "); + ASSERTMSGLINE(358, q, "QUATDotProduct(): NULL QuaternionPtr 'q' "); + + return (q->x * p->x) + (q->y * p->y) + (q->z * p->z) + (q->w * p->w); +} + +f32 PSQUATDotProduct(const register Quaternion* p, const register Quaternion* q) { + register f32 pxy, pzw, qxy, qzw, dp; + + asm { + psq_l pxy, 0(p), 0, 0 + psq_l qxy, 0(q), 0, 0 + ps_mul dp, pxy, qxy + psq_l pzw, 8(p), 0, 0 + psq_l qzw, 8(q), 0, 0 + ps_madd dp, pzw, qzw, dp + ps_sum0 dp, dp, dp, dp + } + + return dp; +} + +void C_QUATNormalize(const Quaternion* src, Quaternion* unit) { + f32 mag; + ASSERTMSGLINE(407, src, "QUATNormalize(): NULL QuaternionPtr 'src' "); + ASSERTMSGLINE(408, unit, "QUATNormalize(): NULL QuaternionPtr 'unit' "); + + mag = (src->x * src->x) + (src->y * src->y) + (src->z * src->z) + (src->w * src->w); + if (mag >= 0.00001f) { + mag = 1.0f / sqrtf(mag); + + unit->x = src->x * mag; + unit->y = src->y * mag; + unit->z = src->z * mag; + unit->w = src->w * mag; + } else { + unit->x = unit->y = unit->z = unit->w = 0.0f; + } +} + +void PSQUATNormalize(const register Quaternion* src, register Quaternion* unit) { + register f32 sxy, szw; + register f32 mag, rsqmag; + register f32 diff; + register f32 c_zero; + register f32 nwork0, nwork1; + + register f32 epsilon = 0.00001f; + register f32 c_half = 0.5f; + register f32 c_three = 3.0f; + + asm { + psq_l sxy, 0x0(src), 0, 0 + ps_mul mag, sxy, sxy + psq_l szw, 0x8(src), 0, 0 + ps_sub c_zero, epsilon, epsilon + ps_madd mag, szw, szw, mag + ps_sum0 mag, mag, mag, mag + frsqrte rsqmag, mag + ps_sub diff, mag, epsilon + fmul nwork0, rsqmag, rsqmag + fmul nwork1, rsqmag, c_half + fnmsub nwork0, nwork0, mag, c_three + fmul rsqmag, nwork0, nwork1 + ps_sel rsqmag, diff, rsqmag, c_zero + ps_muls0 sxy, sxy, rsqmag + ps_muls0 szw, szw, rsqmag + psq_st sxy, 0x0(unit), 0, 0 + psq_st szw, 0x8(unit), 0, 0 + } +} + +void C_QUATInverse(const Quaternion* src, Quaternion* inv) { + f32 mag, norminv; + ASSERTMSGLINE(498, src, "QUATInverse(): NULL QuaternionPtr 'src' "); + ASSERTMSGLINE(499, inv, "QUATInverse(): NULL QuaternionPtr 'inv' "); + + mag = (src->x * src->x) + (src->y * src->y) + (src->z * src->z) + (src->w * src->w); + if (mag == 0.0f) { + mag = 1.0f; + } + + norminv = 1.0f / mag; + inv->x = -src->x * norminv; + inv->y = -src->y * norminv; + inv->z = -src->z * norminv; + inv->w = src->w * norminv; +} + +void PSQUATInverse(const register Quaternion* src, register Quaternion* inv) { + register f32 sxy, szw; + register f32 izz, iww; + register f32 mag, nmag; + register f32 norminv, nninv; + register f32 nwork0; + register f32 c_two; + register f32 c_zero; + register f32 c_one = 1.0f; + + asm { + psq_l sxy, 0x0(src), 0, 0 + ps_mul mag, sxy, sxy + ps_sub c_zero, c_one, c_one + psq_l szw, 0x8(src), 0, 0 + ps_madd mag, szw, szw, mag + ps_add c_two, c_one, c_one + ps_sum0 mag, mag, mag, mag + fcmpu cr0, mag, c_zero + beq L_00000948 + fres norminv, mag + ps_neg nmag, mag + ps_nmsub nwork0, mag, norminv, c_two + ps_mul norminv, norminv, nwork0 + b L_0000094C + L_00000948: + fmr norminv, c_one + L_0000094C: + ps_neg nninv, norminv + ps_muls1 iww, norminv, szw + ps_muls0 sxy, sxy, nninv + psq_st iww, 0xc(inv), 1, 0 + ps_muls0 izz, szw, nninv + psq_st sxy, 0x0(inv), 0, 0 + psq_st izz, 0x8(inv), 1, 0 + } +} + +void C_QUATDivide(const Quaternion* p, const Quaternion* q, Quaternion* r) { + Quaternion qtmp; + ASSERTMSGLINE(606, p, "QUATDivide(): NULL QuaternionPtr 'p' "); + ASSERTMSGLINE(607, q, "QUATDivide(): NULL QuaternionPtr 'q' "); + ASSERTMSGLINE(608, r, "QUATDivide(): NULL QuaternionPtr 'r' "); + + C_QUATInverse(q, &qtmp); + C_QUATMultiply(&qtmp, p, r); +} + +void PSQUATDivide(const Quaternion* p, const Quaternion* q, Quaternion* r) { + Quaternion qtmp; + + PSQUATInverse(q, &qtmp); + PSQUATMultiply(&qtmp, p, r); +} + +void C_QUATExp(const Quaternion* q, Quaternion* r) { + f32 theta, scale; + ASSERTMSGLINE(643, q, "QUATExp(): NULL QuaternionPtr 'q' "); + ASSERTMSGLINE(644, r, "QUATExp(): NULL QuaternionPtr 'r' "); + ASSERTMSGLINE(647, q->w == 0.0f, "QUATExp(): 'q' is not a pure quaternion. "); + + theta = sqrtf((q->x * q->x) + (q->y * q->y) + (q->z * q->z)); + scale = 1.0f; + + if (theta > 0.00001f) { + scale = sinf(theta) / theta; + } + + r->x = scale * q->x; + r->y = scale * q->y; + r->z = scale * q->z; + r->w = cosf(theta); +} + +void C_QUATLogN(const Quaternion* q, Quaternion* r) { + f32 theta, scale, mag; + ASSERTMSGLINE(676, q, "QUATLogN(): NULL QuaternionPtr 'q' "); + ASSERTMSGLINE(677, r, "QUATLogN(): NULL QuaternionPtr 'r' "); + + scale = (q->x * q->x) + (q->y * q->y) + (q->z * q->z); + +#ifdef DEBUG + mag = scale + (q->z * q->z); + if (mag < 1.0f - 0.00001f || mag > 1.0f + 0.00001f || mag > 1.00001f) {} +#endif + + scale = sqrtf(scale); + theta = atan2f(scale, q->w); + + if (scale > 0.0f) { + scale = theta / scale; + } + + r->x = scale * q->x; + r->y = scale * q->y; + r->z = scale * q->z; + r->w = 0.0f; +} + +void C_QUATMakeClosest(const Quaternion* q, const Quaternion* qto, Quaternion* r) { + f32 dot; + ASSERTMSGLINE(722, q, "QUATMakeClosest(): NULL QuaternionPtr 'q' "); + ASSERTMSGLINE(723, qto, "QUATMakeClosest(): NULL QuaternionPtr 'qto' "); + ASSERTMSGLINE(724, r, "QUATMakeClosest(): NULL QuaternionPtr 'r' "); + + dot = (q->x * qto->x) + (q->y * qto->y) + (q->z * qto->z) + (q->w * qto->w); + if (dot < 0.0f) { + r->x = -q->x; + r->y = -q->y; + r->z = -q->z; + r->w = -q->w; + } else { + *r = *q; + } +} + +void C_QUATRotAxisRad(Quaternion* r, const Vec* axis, f32 rad) { + f32 half, sh, ch; + Vec nAxis; + + ASSERTMSGLINE(758, r, "QUATRotAxisRad(): NULL QuaternionPtr 'r' "); + ASSERTMSGLINE(759, axis, "QUATRotAxisRad(): NULL VecPtr 'axis' "); + + VECNormalize(axis, &nAxis); + + half = rad * 0.5f; + sh = sinf(half); + ch = cosf(half); + + r->x = sh * nAxis.x; + r->y = sh * nAxis.y; + r->z = sh * nAxis.z; + r->w = ch; +} + +void C_QUATMtx(Quaternion* r, const Mtx m) { + f32 tr,s; + s32 i, j, k; + s32 nxt[3] = {1, 2, 0}; + f32 q[3]; + + ASSERTMSGLINE(791, r, "QUATMtx(): NULL QuaternionPtr 'r' "); + ASSERTMSGLINE(792, m, "QUATMtx(): NULL MtxPtr 'm' "); + + tr = m[0][0] + m[1][1] + m[2][2]; + if (tr > 0.0f) { + s = sqrtf(tr + 1.0f); + r->w = s * 0.5f; + s = 0.5f / s; + + r->x = (m[2][1] - m[1][2]) * s; + r->y = (m[0][2] - m[2][0]) * s; + r->z = (m[1][0] - m[0][1]) * s; + } else { + i = 0; + if (m[1][1] > m[0][0]) { + i = 1; + } + + if (m[2][2] > m[i][i]) { + i = 2; + } + + j = nxt[i]; + k = nxt[j]; + + s = sqrtf((m[i][i] - (m[j][j] + m[k][k])) + 1.0f); + q[i] = s * 0.5f; + + if (s != 0.0f) { + s = 0.5f / s; + } + + r->w = (m[k][j] - m[j][k]) * s; + q[j] = (m[i][j] + m[j][i]) * s; + q[k] = (m[i][k] + m[k][i]) * s; + + r->x = q[0]; + r->y = q[1]; + r->z = q[2]; + } +} + +void C_QUATLerp(const Quaternion* p, const Quaternion* q, Quaternion* r, f32 t) { + ASSERTMSGLINE(842, p, "QUATLerp(): NULL QuaternionPtr 'p' "); + ASSERTMSGLINE(843, q, "QUATLerp(): NULL QuaternionPtr 'q' "); + ASSERTMSGLINE(844, r, "QUATLerp(): NULL QuaternionPtr 'r' "); + + r->x = t * (q->x - p->x) + p->x; + r->y = t * (q->y - p->y) + p->y; + r->z = t * (q->z - p->z) + p->z; + r->w = t * (q->w - p->w) + p->w; +} + +void C_QUATSlerp(const Quaternion* p, const Quaternion* q, Quaternion* r, f32 t) { + f32 theta, sin_th, cos_th; + f32 tp, tq; + + ASSERTMSGLINE(869, p, "QUATSlerp(): NULL QuaternionPtr 'p' "); + ASSERTMSGLINE(870, q, "QUATSlerp(): NULL QuaternionPtr 'q' "); + ASSERTMSGLINE(871, r, "QUATSlerp(): NULL QuaternionPtr 'r' "); + + cos_th = p->x * q->x + p->y * q->y + p->z * q->z + p->w * q->w; + tq = 1.0f; + + if (cos_th < 0.0f) { + cos_th = -cos_th; + tq = -tq; + } + + if (cos_th <= 0.99999f) { + theta = acosf(cos_th); + sin_th = sinf(theta); + + tp = sinf((1.0f - t) * theta) / sin_th; + tq *= sinf(t * theta) / sin_th; + } else { + tp = 1.0f - t; + tq *= t; + } + + r->x = (tp * p->x) + (tq * q->x); + r->y = (tp * p->y) + (tq * q->y); + r->z = (tp * p->z) + (tq * q->z); + r->w = (tp * p->w) + (tq * q->w); +} + +void C_QUATSquad(const Quaternion* p, const Quaternion* a, const Quaternion* b, const Quaternion* q, Quaternion* r, f32 t) { + Quaternion pq, ab; + f32 t2; + + ASSERTMSGLINE(927, p, "QUATSquad(): NULL QuaternionPtr 'p' "); + ASSERTMSGLINE(928, a, "QUATSquad(): NULL QuaternionPtr 'a' "); + ASSERTMSGLINE(929, b, "QUATSquad(): NULL QuaternionPtr 'b' "); + ASSERTMSGLINE(930, q, "QUATSquad(): NULL QuaternionPtr 'q' "); + ASSERTMSGLINE(931, r, "QUATSquad(): NULL QuaternionPtr 'r' "); + + t2 = 2.0f * t * (1.0f - t); + C_QUATSlerp(p, q, &pq, t); + C_QUATSlerp(a, b, &ab, t); + C_QUATSlerp(&pq, &ab, r, t2); +} + +void C_QUATCompA(const Quaternion* qprev, const Quaternion* q, const Quaternion* qnext, Quaternion* a) { + Quaternion qm, qp, lqm, lqp, qpqm, exq; + + ASSERTMSGLINE(958, qprev, "QUATCompA(): NULL QuaternionPtr 'qprev' "); + ASSERTMSGLINE(959, q, "QUATCompA(): NULL QuaternionPtr 'q' "); + ASSERTMSGLINE(960, qnext, "QUATCompA(): NULL QuaternionPtr 'qnext' "); + ASSERTMSGLINE(961, a, "QUATCompA(): NULL QuaternionPtr 'a' "); + + C_QUATDivide(qprev, q, &qm); + C_QUATLogN(&qm, &lqm); + C_QUATDivide(qnext, q, &qp); + C_QUATLogN(&qp, &lqp); + C_QUATAdd(&lqp, &lqm, &qpqm); + C_QUATScale(&qpqm, &qpqm, -0.25f); + C_QUATExp(&qpqm, &exq); + C_QUATMultiply(q, &exq, a); +} diff --git a/src/dolphin/mtx/vec.c b/src/dolphin/mtx/vec.c index 8d6f345a4c..646caa410c 100644 --- a/src/dolphin/mtx/vec.c +++ b/src/dolphin/mtx/vec.c @@ -1,290 +1,344 @@ -#include "dolphin/mtx/vec.h" -#include "math.h" +#include +#include +#include -#define R_RET fp1 -#define FP2 fp2 -#define FP3 fp3 -#define FP4 fp4 -#define FP5 fp5 -#define FP6 fp6 -#define FP7 fp7 -#define FP8 fp8 -#define FP9 fp9 -#define FP10 fp10 -#define FP11 fp11 -#define FP12 fp12 -#define FP13 fp13 - -/* 80347090-803470B4 3419D0 0024+00 1/1 103/103 679/679 .text PSVECAdd */ -asm void PSVECAdd(const register Vec* vec1, const register Vec* vec2, register Vec* ret) { -#ifdef __MWERKS__ // clang-format off - nofralloc; - psq_l FP2, 0(vec1), 0, 0; - psq_l FP4, 0(vec2), 0, 0; - ps_add FP6, FP2, FP4; - psq_st FP6, 0(ret), 0, 0; - psq_l FP3, 8(vec1), 1, 0; - psq_l FP5, 8(vec2), 1, 0; - ps_add FP7, FP3, FP5; - psq_st FP7, 8(ret), 1, 0; - blr -#endif // clang-format on +void C_VECAdd(const Vec* a, const Vec* b, Vec* ab) { + ASSERTMSGLINE(108, a, "VECAdd(): NULL VecPtr 'a' "); + ASSERTMSGLINE(109, b, "VECAdd(): NULL VecPtr 'b' "); + ASSERTMSGLINE(110, ab, "VECAdd(): NULL VecPtr 'ab' "); + ab->x = a->x + b->x; + ab->y = a->y + b->y; + ab->z = a->z + b->z; } -/* 803470B4-803470D8 3419F4 0024+00 0/0 60/60 59/59 .text PSVECSubtract */ -asm void PSVECSubtract(const register Vec* vec1, const register Vec* vec2, register Vec* ret) { -#ifdef __MWERKS__ // clang-format off - nofralloc; - psq_l FP2, 0(vec1), 0, 0; - psq_l FP4, 0(vec2), 0, 0; - ps_sub FP6, FP2, FP4; - psq_st FP6, 0(ret), 0, 0; - psq_l FP3, 8(vec1), 1, 0; - psq_l FP5, 8(vec2), 1, 0; - ps_sub FP7, FP3, FP5; - psq_st FP7, 8(ret), 1, 0; - blr -#endif // clang-format on +asm void PSVECAdd(const register Vec* a, const register Vec* b, register Vec* ab) { + psq_l f2, Vec.x(a), 0, 0 + psq_l f4, Vec.x(b), 0, 0 + ps_add f6, f2, f4 + psq_st f6, Vec.x(ab), 0, 0 + psq_l f3, Vec.z(a), 1, 0 + psq_l f5, Vec.z(b), 1, 0 + ps_add f7, f3, f5 + psq_st f7, Vec.z(ab), 1, 0 } -/* 803470D8-803470F4 341A18 001C+00 0/0 58/58 101/101 .text PSVECScale */ -asm void PSVECScale(register const Vec* src, register Vec* dst, register f32 scale) { -#ifdef __MWERKS__ // clang-format off - nofralloc - psq_l f0, 0(src), 0, 0 - psq_l f2, 8(src), 1, 0 - ps_muls0 f0, f0, f1 - psq_st f0, 0(dst), 0, 0 - ps_muls0 f0, f2, f1 - psq_st f0, 8(dst), 1, 0 - blr -#endif // clang-format on +void C_VECSubtract(const Vec* a, const Vec* b, Vec* a_b) { + ASSERTMSGLINE(177, a, "VECSubtract(): NULL VecPtr 'a' "); + ASSERTMSGLINE(178, b, "VECSubtract(): NULL VecPtr 'b' "); + ASSERTMSGLINE(179, a_b, "VECSubtract(): NULL VecPtr 'a_b' "); + a_b->x = a->x - b->x; + a_b->y = a->y - b->y; + a_b->z = a->z - b->z; +} + +asm void PSVECSubtract(const register Vec* a, const register Vec* b, register Vec* a_b) { + psq_l f2, Vec.x(a), 0, 0 + psq_l f4, Vec.x(b), 0, 0 + ps_sub f6, f2, f4 + psq_st f6, Vec.x(a_b), 0, 0 + psq_l f3, Vec.z(a), 1, 0 + psq_l f5, Vec.z(b), 1, 0 + ps_sub f7, f3, f5 + psq_st f7, Vec.z(a_b), 1, 0 } void C_VECScale(const Vec* src, Vec* dst, f32 scale) { - f32 s; - - s = 1.0f / sqrtf(src->z * src->z + src->x * src->x + src->y * src->y); - dst->x = src->x * s; - dst->y = src->y * s; - dst->z = src->z * s; + ASSERTMSGLINE(247, src, "VECScale(): NULL VecPtr 'src' "); + ASSERTMSGLINE(248, dst, "VECScale(): NULL VecPtr 'dst' "); + dst->x = (src->x * scale); + dst->y = (src->y * scale); + dst->z = (src->z * scale); } -/* 803470F4-80347138 341A34 0044+00 2/2 16/16 0/0 .text PSVECNormalize */ -void PSVECNormalize(const register Vec* vec1, register Vec* ret) { -#ifdef __MWERKS__ // clang-format off - register f32 half = 0.5f; - register f32 three = 3.0f; - register f32 xx_zz, xx_yy; - register f32 square_sum; - register f32 ret_sqrt; - register f32 n_0, n_1; - asm { - psq_l FP2, 0(vec1), 0, 0; - ps_mul xx_yy, FP2, FP2; - psq_l FP3, 8(vec1), 1, 0; - ps_madd xx_zz, FP3, FP3, xx_yy; - ps_sum0 square_sum, xx_zz, FP3, xx_yy; - frsqrte ret_sqrt, square_sum; - fmuls n_0, ret_sqrt, ret_sqrt; - fmuls n_1, ret_sqrt, half; - fnmsubs n_0, n_0, square_sum, three; - fmuls ret_sqrt, n_0, n_1; - ps_muls0 FP2, FP2, ret_sqrt; - psq_st FP2, 0(ret), 0, 0; - ps_muls0 FP3, FP3, ret_sqrt; - psq_st FP3, 8(ret), 1, 0; - } -#endif // clang-format on -} +void PSVECScale(const register Vec* src, register Vec* dst, register f32 scale) { + register f32 vxy, vz, rxy, rz; -/* 80347138-80347150 341A78 0018+00 0/0 140/140 727/727 .text PSVECSquareMag */ -asm f32 PSVECSquareMag(register const Vec* v){ -#ifdef __MWERKS__ // clang-format off - nofralloc - psq_l f0, 0(v), 0, 0 - ps_mul f0, f0, f0 - lfs f1, 8(v) - ps_madd f1, f1, f1, f0 - ps_sum0 f1, f1, f0, f0 - blr -#endif // clang-format on -} - -/* 80347150-80347194 341A90 0044+00 0/0 24/24 0/0 .text PSVECMag */ -f32 PSVECMag(const register Vec* v) { - register f32 v_xy, v_zz, square_mag; - register f32 ret_mag, n_0, n_1; - register f32 three, half, zero; - half = 0.5f; -#ifdef __MWERKS__ // clang-format off - asm { - psq_l v_xy, 0(v), 0, 0 - ps_mul v_xy, v_xy, v_xy - lfs v_zz, 8(v) - fsubs zero, half, half - ps_madd square_mag, v_zz, v_zz, v_xy - ps_sum0 square_mag, square_mag, v_xy, v_xy - fcmpu cr0, square_mag, zero - beq- __exit - frsqrte ret_mag, square_mag - } -#endif // clang-format on - three = 3.0f; -#ifdef __MWERKS__ // clang-format off - asm { - fmuls n_0, ret_mag, ret_mag - fmuls n_1, ret_mag, half - fnmsubs n_0, n_0, square_mag, three - fmuls ret_mag, n_0, n_1 - fmuls square_mag, square_mag, ret_mag - __exit: - } -#endif // clang-format on - return square_mag; -} - -/* 80347194-803471B4 341AD4 0020+00 2/2 39/39 15/15 .text PSVECDotProduct */ -asm f32 PSVECDotProduct(const register Vec* vec1, const register Vec* vec2) { -#ifdef __MWERKS__ // clang-format off - nofralloc; - psq_l f2, 4(r3), 0, 0 /* qr0 */ - psq_l f3, 4(r4), 0, 0 /* qr0 */ - ps_mul f2, f2, f3 - psq_l f5, 0(r3), 0, 0 /* qr0 */ - psq_l f4, 0(r4), 0, 0 /* qr0 */ - ps_madd f3, f5, f4, f2 - ps_sum0 f1, f3, f2, f2 - blr -#endif // clang-format on -} - -/* 803471B4-803471F0 341AF4 003C+00 0/0 20/20 3/3 .text PSVECCrossProduct */ -asm void PSVECCrossProduct(register const Vec* a, register const Vec* b, register Vec* axb) { -#ifdef __MWERKS__ // clang-format off - nofralloc - psq_l f1, 0(b), 0, 0 - lfs f2, 8(a) - psq_l f0, 0(a), 0, 0 - ps_merge10 f6, f1, f1 - lfs f3, 8(b) - ps_mul f4, f1, f2 - ps_muls0 f7, f1, f0 - ps_msub f5, f0, f3, f4 - ps_msub f8, f0, f6, f7 - ps_merge11 f9, f5, f5 - ps_merge01 f10, f5, f8 - psq_st f9, 0(axb), 1, 0 - ps_neg f10, f10 - psq_st f10, 4(axb), 0, 0 - blr -#endif // clang-format on -} - -/* 803471F0-803472C8 341B30 00D8+00 0/0 1/1 0/0 .text C_VECHalfAngle */ -void C_VECHalfAngle(const Vec* a, const Vec* b, Vec* half) { - Vec a0; - Vec b0; - Vec ab; - - a0.x = -a->x; - a0.y = -a->y; - a0.z = -a->z; - - b0.x = -b->x; - b0.y = -b->y; - b0.z = -b->z; - - VECNormalize(&a0, &a0); - VECNormalize(&b0, &b0); - VECAdd(&a0, &b0, &ab); - - if (VECDotProduct(&ab, &ab) > 0.0f) { - VECNormalize(&ab, half); - } else { - *half = ab; + asm { + psq_l vxy, 0x0(src), 0, 0 + psq_l vz, 0x8(src), 1, 0 + ps_muls0 rxy, vxy, scale + psq_st rxy, 0x0(dst), 0, 0 + ps_muls0 rz, vz, scale + psq_st rz, 0x8(dst), 1, 0 } } -/* 803472C8-8034739C 341C08 00D4+00 0/0 1/1 11/11 .text C_VECReflect */ -void C_VECReflect(const Vec* src, const Vec* normal, Vec* dst) { - Vec a0; - Vec b0; +void C_VECNormalize(const Vec* src, Vec* unit) { + f32 mag; + + ASSERTMSGLINE(315, src, "VECNormalize(): NULL VecPtr 'src' "); + ASSERTMSGLINE(316, unit, "VECNormalize(): NULL VecPtr 'unit' "); + + mag = (src->z * src->z) + ((src->x * src->x) + (src->y * src->y)); + ASSERTMSGLINE(321, 0.0f != mag, "VECNormalize(): zero magnitude vector "); + + mag = 1.0f/ sqrtf(mag); + unit->x = src->x * mag; + unit->y = src->y * mag; + unit->z = src->z * mag; +} + +void PSVECNormalize(const register Vec* src, register Vec* unit) { + register float c_half = 0.5f; + register float c_three = 3.0f; + register float v1_xy; + register float v1_z; + register float xx_zz; + register float xx_yy; + register float sqsum; + register float rsqrt; + register float nwork0; + register float nwork1; + + asm { + psq_l v1_xy, 0x0(src), 0, 0 + ps_mul xx_yy, v1_xy, v1_xy + psq_l v1_z, 0x8(src), 1, 0 + ps_madd xx_zz, v1_z, v1_z, xx_yy + ps_sum0 sqsum, xx_zz, v1_z, xx_yy + frsqrte rsqrt, sqsum + fmuls nwork0, rsqrt, rsqrt + fmuls nwork1, rsqrt, c_half + fnmsubs nwork0, nwork0, sqsum, c_three + fmuls rsqrt, nwork0, nwork1 + ps_muls0 v1_xy, v1_xy, rsqrt + psq_st v1_xy, 0x0(unit), 0, 0 + ps_muls0 v1_z, v1_z, rsqrt + psq_st v1_z, 0x8(unit), 1, 0 + } +} + +f32 C_VECSquareMag(const Vec* v) { + f32 sqmag; + + ASSERTMSGLINE(405, v, "VECMag(): NULL VecPtr 'v' "); + + sqmag = v->z * v->z + ((v->x * v->x) + (v->y * v->y)); + return sqmag; +} + +f32 PSVECSquareMag(const register Vec* v) { + register f32 vxy, vzz, sqmag; + + asm { + psq_l vxy, 0x0(v), 0, 0 + ps_mul vxy, vxy, vxy + lfs vzz, 0x8(v) + ps_madd sqmag, vzz, vzz, vxy + ps_sum0 sqmag, sqmag, vxy, vxy + } + + return sqmag; +} + +f32 C_VECMag(const Vec* v) { + return sqrtf(C_VECSquareMag(v)); +} + +f32 PSVECMag(const register Vec* v) { + register f32 vxy, vzz; + register f32 sqmag, rmag; + register f32 nwork0, nwork1; + register f32 c_three, c_half, c_zero; + + c_half = 0.5f; + + asm { + psq_l vxy, 0x0(v), 0, 0 + ps_mul vxy, vxy, vxy + lfs vzz, 0x8(v) + fsubs c_zero, c_half, c_half + ps_madd sqmag, vzz, vzz, vxy + ps_sum0 sqmag, sqmag, vxy, vxy + fcmpu cr0, sqmag, c_zero + beq L_000005F0 + frsqrte rmag, sqmag + } + + c_three = 3.0f; + + asm { + fmuls nwork0, rmag, rmag + fmuls nwork1, rmag, c_half + fnmsubs nwork0, nwork0, sqmag, c_three + fmuls rmag, nwork0, nwork1 + fmuls sqmag, sqmag, rmag + L_000005F0: + } + + return sqmag; +} + +f32 C_VECDotProduct(const Vec* a, const Vec* b) { f32 dot; - a0.x = -src->x; - a0.y = -src->y; - a0.z = -src->z; + ASSERTMSGLINE(540, a, "VECDotProduct(): NULL VecPtr 'a' "); + ASSERTMSGLINE(541, b, "VECDotProduct(): NULL VecPtr 'b' "); + dot = (a->z * b->z) + ((a->x * b->x) + (a->y * b->y)); + return dot; +} - VECNormalize(&a0, &a0); - VECNormalize(normal, &b0); +asm f32 PSVECDotProduct(const register Vec* a, const register Vec* b) { + psq_l f2, Vec.y(a), 0, 0 + psq_l f3, Vec.y(b), 0, 0 + ps_mul f2, f2, f3 + psq_l f5, Vec.x(a), 0, 0 + psq_l f4, Vec.x(b), 0, 0 + ps_madd f3, f5, f4, f2 + ps_sum0 f1, f3, f2, f2 +} - dot = VECDotProduct(&a0, &b0); - dst->x = b0.x * 2.0f * dot - a0.x; - dst->y = b0.y * 2.0f * dot - a0.y; - dst->z = b0.z * 2.0f * dot - a0.z; +void C_VECCrossProduct(const Vec* a, const Vec* b, Vec* axb) { + Vec vTmp; + ASSERTMSGLINE(602, a, "VECCrossProduct(): NULL VecPtr 'a' "); + ASSERTMSGLINE(603, b, "VECCrossProduct(): NULL VecPtr 'b' "); + ASSERTMSGLINE(604, axb, "VECCrossProduct(): NULL VecPtr 'axb' "); + + vTmp.x = (a->y * b->z) - (a->z * b->y); + vTmp.y = (a->z * b->x) - (a->x * b->z); + vTmp.z = (a->x * b->y) - (a->y * b->x); + axb->x = vTmp.x; + axb->y = vTmp.y; + axb->z = vTmp.z; +} + +asm void PSVECCrossProduct(const register Vec* a, const register Vec* b, register Vec* axb) { + psq_l f1, Vec.x(b), 0, 0 + lfs f2, Vec.z(a) + psq_l f0, Vec.x(a), 0, 0 + ps_merge10 f6, f1, f1 + lfs f3, Vec.z(b) + ps_mul f4, f1, f2 + ps_muls0 f7, f1, f0 + ps_msub f5, f0, f3, f4 + ps_msub f8, f0, f6, f7 + ps_merge11 f9, f5, f5 + ps_merge01 f10, f5, f8 + psq_st f9, Vec.x(axb), 1, 0 + ps_neg f10, f10 + psq_st f10, Vec.y(axb), 0, 0 +} + +void C_VECHalfAngle(const Vec* a, const Vec* b, Vec* half) { + Vec aTmp; + Vec bTmp; + Vec hTmp; + + ASSERTMSGLINE(707, a, "VECHalfAngle(): NULL VecPtr 'a' "); + ASSERTMSGLINE(708, b, "VECHalfAngle(): NULL VecPtr 'b' "); + ASSERTMSGLINE(709, half, "VECHalfAngle(): NULL VecPtr 'half' "); + + aTmp.x = -a->x; + aTmp.y = -a->y; + aTmp.z = -a->z; + bTmp.x = -b->x; + bTmp.y = -b->y; + bTmp.z = -b->z; + + VECNormalize(&aTmp, &aTmp); + VECNormalize(&bTmp, &bTmp); + VECAdd(&aTmp, &bTmp, &hTmp); + + if (VECDotProduct(&hTmp, &hTmp) > 0.0f) { + VECNormalize(&hTmp, half); + return; + } + *half = hTmp; +} + +void C_VECReflect(const Vec* src, const Vec* normal, Vec* dst) { + f32 cosA; + Vec uI; + Vec uN; + + ASSERTMSGLINE(763, src, "VECReflect(): NULL VecPtr 'src' "); + ASSERTMSGLINE(764, normal, "VECReflect(): NULL VecPtr 'normal' "); + ASSERTMSGLINE(765, dst, "VECReflect(): NULL VecPtr 'dst' "); + + uI.x = -src->x; + uI.y = -src->y; + uI.z = -src->z; + + VECNormalize(&uI, &uI); + VECNormalize(normal, &uN); + + cosA = VECDotProduct(&uI, &uN); + dst->x = (2.0f * uN.x * cosA) - uI.x; + dst->y = (2.0f * uN.y * cosA) - uI.y; + dst->z = (2.0f * uN.z * cosA) - uI.z; VECNormalize(dst, dst); } -/* 8034739C-803473C4 341CDC 0028+00 0/0 107/107 446/446 .text PSVECSquareDistance */ -asm f32 PSVECSquareDistance(register const Vec* a, register const Vec* b){ -#ifdef __MWERKS__ // clang-format off - nofralloc - psq_l f0, 4(a), 0, 0 - psq_l f1, 4(b), 0, 0 - ps_sub f2, f0, f1 - psq_l f0, 0(a), 0, 0 - psq_l f1, 0(b), 0, 0 - ps_mul f2, f2, f2 - ps_sub f0, f0, f1 - ps_madd f1, f0, f0, f2 - ps_sum0 f1, f1, f2, f2 - blr -#endif // clang-format on +f32 C_VECSquareDistance(const Vec* a, const Vec* b) { + Vec diff; + + diff.x = a->x - b->x; + diff.y = a->y - b->y; + diff.z = a->z - b->z; + return (diff.z * diff.z) + ((diff.x * diff.x) + (diff.y * diff.y)); } -/* 803473C4-80347418 341D04 0054+00 0/0 4/4 0/0 .text PSVECDistance */ -f32 PSVECDistance(register const Vec* a, register const Vec* b) { - - register f32 half_c; - register f32 three_c; - register f32 dist; - -#ifdef __MWERKS__ // clang-format off - asm { - psq_l f0, 4(a), 0, 0 /* qr0 */ - psq_l f1, 4(b), 0, 0 /* qr0 */ - ps_sub f2, f0, f1 - psq_l f0, 0(a), 0, 0 /* qr0 */ - psq_l f1, 0(b), 0, 0 /* qr0 */ - ps_mul f2, f2, f2 - ps_sub f0, f0, f1 - } - - half_c = 0.5f; +f32 PSVECSquareDistance(const register Vec* a, const register Vec* b) { + register f32 v0yz, v1yz, v0xy, v1xy, dyz, dxy; + register f32 sqdist; asm { - ps_madd dist, f0, f0, f2 - fsubs f0, half_c, half_c - ps_sum0 dist, dist, f2, f2 - fcmpu cr0, f0, dist - beq exit + psq_l v0yz, 0x4(a), 0, 0 + psq_l v1yz, 0x4(b), 0, 0 + ps_sub dyz, v0yz, v1yz + psq_l v0xy, 0x0(a), 0, 0 + psq_l v1xy, 0x0(b), 0, 0 + ps_mul dyz, dyz, dyz + ps_sub dxy, v0xy, v1xy + ps_madd sqdist, dxy, dxy, dyz + ps_sum0 sqdist, sqdist, dyz, dyz } - three_c = 3.0f; + return sqdist; +} + +f32 C_VECDistance(const Vec* a, const Vec* b) { + return sqrtf(C_VECSquareDistance(a, b)); +} + +f32 PSVECDistance(const register Vec* a, const register Vec* b) { + register f32 v0yz, v1yz, v0xy, v1xy, dyz, dxy; + register f32 sqdist, rdist; + register f32 nwork0, nwork1; + register f32 c_half, c_three, c_zero; asm { - frsqrte f0, dist - fmuls f2, f0, f0 - fmuls f0, f0, half_c - fnmsubs f2, f2, dist, three_c - fmuls f0, f2, f0 - fmuls dist, dist, f0 - - exit: + psq_l v0yz, 0x4(a), 0, 0 + psq_l v1yz, 0x4(b), 0, 0 + ps_sub dyz, v0yz, v1yz + psq_l v0xy, 0x0(a), 0, 0 + psq_l v1xy, 0x0(b), 0, 0 + ps_mul dyz, dyz, dyz + ps_sub dxy, v0xy, v1xy } - return dist; -#endif // clang-format on -} \ No newline at end of file + c_half = 0.5f; + + asm { + ps_madd sqdist, dxy, dxy, dyz + fsubs c_zero, c_half, c_half + ps_sum0 sqdist, sqdist, dyz, dyz + fcmpu cr0, c_zero, sqdist + beq L_00000CBC + } + + c_three = 3.0f; + + asm { + frsqrte rdist, sqdist + fmuls nwork0, rdist, rdist + fmuls nwork1, rdist, c_half + fnmsubs nwork0, nwork0, sqdist, c_three + fmuls rdist, nwork0, nwork1 + fmuls sqdist, sqdist, rdist + L_00000CBC: + } + + return sqdist; +} diff --git a/src/dolphin/odemustubs/odemustubs.c b/src/dolphin/odemustubs/odemustubs.c new file mode 100644 index 0000000000..ddc413833f --- /dev/null +++ b/src/dolphin/odemustubs/odemustubs.c @@ -0,0 +1,34 @@ +#include + +// prototypes +__declspec(weak) int Hu_IsStub(); +void DBInitInterrupts(); +s32 DBQueryData(); +u32 DBRead(); +u32 DBWrite(); +void DBOpen(); +void DBClose(); + +__declspec(weak) int Hu_IsStub() { + return 1; +} + +void DBInitComm(int* inputFlagPtr, int* mtrCallback) {} + +void DBInitInterrupts() {} + +s32 DBQueryData() { + return 0; +} + +u32 DBRead(u8*, u32) { + return 0; +} + +u32 DBWrite() { + return 0; +} + +void DBOpen() {} + +void DBClose() {} diff --git a/src/dolphin/odenotstub/odenotstub.c b/src/dolphin/odenotstub/odenotstub.c new file mode 100644 index 0000000000..fd35d7ad32 --- /dev/null +++ b/src/dolphin/odenotstub/odenotstub.c @@ -0,0 +1,8 @@ +#include + +// prototypes +__declspec(weak) int Hu_IsStub(); + +__declspec(weak) int Hu_IsStub() { + return 0; +} diff --git a/src/dolphin/os/OS.c b/src/dolphin/os/OS.c index eff7103adb..67fe5457b9 100644 --- a/src/dolphin/os/OS.c +++ b/src/dolphin/os/OS.c @@ -1,70 +1,88 @@ -// -// OS -// +#include +#include +#include +#include +#include -#include "dolphin/os.h" -#include "dolphin/base/PPCArch.h" -#include "dolphin/db.h" -#include "dolphin/pad.h" -#include "dolphin/dvd/dvdfs.h" -#include "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk.h" -#include "__ppc_eabi_linker.h" +#include "__os.h" + +#define NOP 0x60000000 + +// external functions +extern void EnableMetroTRKInterrupts(void); +extern void __OSInitMemoryProtection(void); -#define OS_BI2_DEBUG_ADDRESS 0x800000F4 -#define OS_BI2_DEBUGFLAG_OFFSET 0xC -#define PAD3_BUTTON_ADDR 0x800030E4 -#define OS_DVD_DEVICECODE 0x800030E6 -#define DEBUGFLAG_ADDR 0x800030E8 -#define OS_DEBUG_ADDRESS_2 0x800030E9 #define DB_EXCEPTIONRET_OFFSET 0xC #define DB_EXCEPTIONDEST_OFFSET 0x8 - +#define OS_CURRENTCONTEXT_PADDR 0x00C0 #define OS_EXCEPTIONTABLE_ADDR 0x3000 #define OS_DBJUMPPOINT_ADDR 0x60 -#define OS_CURRENTCONTEXT_PADDR 0xC0 -// -// External References: -// +#if SDK_REVISION < 1 +#define BUILD_DATE "Apr 5 2004" +#define DBUILD_TIME "03:55:13" +#define RBUILD_TIME "04:13:58" +#elif SDK_REVISION < 2 +#define BUILD_DATE "May 21 2004" +#define DBUILD_TIME "09:15:32" +#define RBUILD_TIME "09:28:09" +#else +#define BUILD_DATE "Nov 10 2004" +#define DBUILD_TIME "06:08:19" +#define RBUILD_TIME "06:26:41" +#endif -void _epilog(); +#ifdef DEBUG +const char* __OSVersion = "<< Dolphin SDK - OS\tdebug build: "BUILD_DATE" "DBUILD_TIME" (0x2301) >>"; +#else +const char* __OSVersion = "<< Dolphin SDK - OS\trelease build: "BUILD_DATE" "RBUILD_TIME" (0x2301) >>"; +#endif + +static DVDDriveInfo DriveInfo; +static DVDCommandBlock DriveBlock; +OSExecParams __OSRebootParams; + +extern u32 __DVDLongFileNameFlag; +extern u32 __PADSpec; + +// defined in link script +extern u8 __ArenaLo[]; +extern char _stack_addr[]; +extern u8 __ArenaHi[]; -/* ############################################################################################## */ -/* 80451600-80451604 000B00 0004+00 2/2 0/0 0/0 .sbss BootInfo */ static OSBootInfo* BootInfo; +static u32* BI2DebugFlag; +static u32 BI2DebugFlagHolder; -/* 80451604-80451608 000B04 0004+00 2/2 0/0 0/0 .sbss BI2DebugFlag */ -static volatile u32* BI2DebugFlag; - -/* 80451608-8045160C 000B08 0004+00 1/1 0/0 0/0 .sbss BI2DebugFlagHolder */ -static u32* BI2DebugFlagHolder; - -/* 80451630-80451634 000B30 0004+00 1/1 1/1 0/0 .sbss __OSStartTime */ OSTime __OSStartTime; - -/* 80451628-80451630 000B28 0004+04 1/1 1/1 0/0 .sbss __OSInIPL */ BOOL __OSInIPL; - -/* 80451624-80451628 000B24 0004+00 3/3 0/0 0/0 .sbss OSExceptionTable */ -extern OSExceptionHandler* OSExceptionTable; -OSExceptionHandler* OSExceptionTable; - -/* 80451620-80451624 000B20 0004+00 1/1 0/0 0/0 .sbss AreWeInitialized */ -extern BOOL AreWeInitialized; +void (**OSExceptionTable)(u8, OSContext*); BOOL AreWeInitialized; - -/* 80451618-80451620 000B18 0008+00 1/1 0/0 0/0 .sbss ZeroPS */ -extern f64 ZeroPS; -f64 ZeroPS; - -/* 80451610-80451618 000B10 0008+00 1/1 0/0 0/0 .sbss ZeroF */ -extern f64 ZeroF; +f32 ZeroPS[2]; f64 ZeroF; - -/* 8045160C-80451610 000B0C 0004+00 1/1 1/1 0/0 .sbss __OSIsGcam */ BOOL __OSIsGcam; -/* 80339DD4-80339EFC 334714 0128+00 0/0 1/1 0/0 .text __OSFPRInit */ +// prototypes +static void __OSInitFPRs(void); +static void OSExceptionInit(void); + +// dummy entry points to the OS Exception vector +void __OSEVStart(void); +void __OSEVEnd(void); +void __OSEVSetNumber(void); +void __OSExceptionVector(void); +void __DBVECTOR(void); +void __OSDBINTSTART(void); +void __OSDBINTEND(void); +void __OSDBJUMPSTART(void); +void __OSDBJUMPEND(void); + +u32 __OSIsDebuggerPresent(void) { + return *(u32*)OSPhysicalToCached(0x40); +} + +/* clang-format off */ +#ifdef __GEKKO__ asm void __OSFPRInit(void) { // clang-format off nofralloc @@ -150,63 +168,58 @@ skip_ps_init: blr // clang-format on } +#endif -/* 80339EFC-80339F24 33483C 0028+00 0/0 5/5 0/0 .text OSGetConsoleType */ -u32 OSGetConsoleType(void) { - if (BootInfo == NULL || BootInfo->console_type == 0) { - return OS_CONSOLE_ARTHUR; - } +static void DisableWriteGatherPipe(void) { + u32 hid2; - return BootInfo->console_type; + hid2 = PPCMfhid2(); + hid2 &= ~0x40000000; + PPCMthid2(hid2); } -/* ############################################################################################## */ -/* 8044BA60-8044BA80 078780 0020+00 2/2 0/0 0/0 .bss DriveInfo */ -static DVDDriveInfo DriveInfo; - -void* __OSSavedRegionStart; -void* __OSSavedRegionEnd; - -extern OSExecParams __OSRebootParams; - -static inline void ClearArena(void) { - BOOL var_r0; - if (OSGetResetCode() & 0x80000000) { - var_r0 = TRUE; - } else { - var_r0 = FALSE; +u32 OSGetConsoleType(void) { + if (!BootInfo || BootInfo->consoleType == 0) { + return OS_CONSOLE_ARTHUR; } + return BootInfo->consoleType; +} - if (!var_r0) { - memset(OSGetArenaLo(), 0U, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); +// needed for assert +#undef NULL +#define NULL 0 + +static void ClearArena(void) { + if (!((OSGetResetCode() & 0x80000000) ? TRUE : FALSE)) { + memset(OSGetArenaLo(), 0, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); return; } - if (*(u32*)&__OSRebootParams.regionStart == 0U) { - memset(OSGetArenaLo(), 0U, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); + if (*(u32*)&__OSRebootParams.regionStart == 0) { + memset(OSGetArenaLo(), 0, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); return; } + ASSERTLINE(683, __OSRebootParams.regionEnd != NULL); + if ((u32)OSGetArenaLo() < *(u32*)&__OSRebootParams.regionStart) { if ((u32)OSGetArenaHi() <= *(u32*)&__OSRebootParams.regionStart) { - memset((u32)OSGetArenaLo(), 0U, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); + memset(OSGetArenaLo(), 0, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); return; } - memset(OSGetArenaLo(), 0U, *(u32*)&__OSRebootParams.regionStart - (u32)OSGetArenaLo()); + memset(OSGetArenaLo(), 0, *(u32*)&__OSRebootParams.regionStart - (u32)OSGetArenaLo()); - if ((u32)OSGetArenaHi() > *(u32*)&__OSRebootParams.regionEnd) { - memset(*(u32*)&__OSRebootParams.regionEnd, 0, - (u32)OSGetArenaHi() - *(u32*)&__OSRebootParams.regionEnd); + if ((u32)OSGetArenaHi() > (u32)__OSRebootParams.regionEnd) { + memset(__OSRebootParams.regionEnd, 0, (u32)OSGetArenaHi() - (u32)__OSRebootParams.regionEnd); } } } -/* 80339F24-80339F60 334864 003C+00 1/1 0/0 0/0 .text InquiryCallback */ -static void InquiryCallback(s32 result, DVDCommandBlock* block) { +static void InquiryCallback(s32, DVDCommandBlock* block) { switch (block->state) { case 0: - __OSDeviceCode = (u16)(0x8000 | DriveInfo.device_code); + __OSDeviceCode = (u16)(0x8000 | DriveInfo.deviceCode); break; default: __OSDeviceCode = 1; @@ -214,37 +227,13 @@ static void InquiryCallback(s32 result, DVDCommandBlock* block) { } } -/* 8044BA80-8044BAB0 0787A0 0030+00 0/1 0/0 0/0 .bss DriveBlock */ -static u8 DriveBlock[48]; - -/* 8044BAB0-8044BAD0 0787D0 001C+04 0/1 1/1 0/0 .bss __OSRebootParams */ -OSExecParams __OSRebootParams; - -/* 80450980-80450984 -00001 0004+00 1/1 0/0 0/0 .sdata __OSVersion */ -static const char* __OSVersion = "<< Dolphin SDK - OS release build: Nov 10 2004 06:26:41 (0x2301) >>"; - -extern u8 __ArenaHi[]; -extern u8 __ArenaLo[]; -extern char _db_stack_end[]; - -/* 80339F60-8033A440 3348A0 04E0+00 0/0 2/2 0/0 .text OSInit */ void OSInit(void) { - /* - Initializes the Dolphin operating system. - - most of the main operations get farmed out to other functions - - loading debug info and setting up heap bounds largely happen here - - a lot of OS reporting also gets controlled here - */ + u32 consoleType; + void* bi2StartAddr; - BI2Debug* DebugInfo; - void* debugArenaLo; - u32 inputConsoleType; - u32 tdev; - - if ((BOOL)AreWeInitialized == FALSE) { + if (AreWeInitialized == FALSE) { AreWeInitialized = TRUE; - // SYSTEM // __OSStartTime = __OSGetSystemTime(); OSDisableInterrupts(); @@ -258,50 +247,36 @@ void OSInit(void) { PPCDisableSpeculation(); PPCSetFpNonIEEEMode(); - // DEBUG // - BI2DebugFlag = 0; // debug flag from the DVD BI2 header - BootInfo = (OSBootInfo*)OS_BASE_CACHED; // set pointer to BootInfo + BootInfo = (OSBootInfo*)OSPhysicalToCached(0); + BI2DebugFlag = 0; + __DVDLongFileNameFlag = 0; - __DVDLongFileNameFlag = - (u32)0; // flag to tell us whether we make it through the debug loading - - // time to grab a bunch of debug info from the DVD - // the address for where the BI2 debug info is, is stored at OS_BI2_DEBUG_ADDRESS - DebugInfo = (BI2Debug*)*((u32*)OS_BI2_DEBUG_ADDRESS); - - if (DebugInfo != NULL) { - BI2DebugFlag = &DebugInfo->debugFlag; // debug flag from DVD BI2 - __PADSpec = (u32)DebugInfo->padSpec; // some other info from DVD BI2 - *((u8*)DEBUGFLAG_ADDR) = (u8)*BI2DebugFlag; // store flag in mem - *((u8*)OS_DEBUG_ADDRESS_2) = (u8)__PADSpec; // store other info in mem - } else if (BootInfo->arena_hi) { - BI2DebugFlagHolder = - (u32*)*((u8*)DEBUGFLAG_ADDR); // grab whatever's stored at 0x800030E8 - BI2DebugFlag = (u32*)&BI2DebugFlagHolder; // flag is then address of flag holder - __PADSpec = (u32) * ((u8*)OS_DEBUG_ADDRESS_2); // pad spec is whatever's at 0x800030E9 + bi2StartAddr = (void*)(*(u32*)OSPhysicalToCached(0xF4)); + if (bi2StartAddr) { + BI2DebugFlag = (void*)((char*)bi2StartAddr + 0xC); + __PADSpec = ((u32*)bi2StartAddr)[9]; + *(u8*)OSPhysicalToCached(0x30E8) = *BI2DebugFlag; + *(u8*)OSPhysicalToCached(0x30E9) = __PADSpec; + } else if (BootInfo->arenaHi) { + BI2DebugFlagHolder = *(u8*)OSPhysicalToCached(0x30E8); + BI2DebugFlag = &BI2DebugFlagHolder; + __PADSpec = *(u8*)OSPhysicalToCached(0x30E9); } __DVDLongFileNameFlag = 1; - // HEAP // - OSSetArenaLo((BootInfo->arena_lo == NULL) ? __ArenaLo : BootInfo->arena_lo); - - // if the input arenaLo is null, and debug flag location exists (and flag is < 2), - // set arenaLo to just past the end of the db stack - if ((BootInfo->arena_lo == NULL) && (BI2DebugFlag != 0) && (*BI2DebugFlag < 2)) { - debugArenaLo = (char*)(((u32)_stack_addr + 0x1f) & ~0x1f); - OSSetArenaLo(debugArenaLo); + OSSetArenaLo((!BootInfo->arenaLo) ? &__ArenaLo : BootInfo->arenaLo); + if ((!BootInfo->arenaLo) && (BI2DebugFlag) && (*(u32*)BI2DebugFlag < 2)) { + OSSetArenaLo((void*)(((u32)(char*)&_stack_addr + 0x1F) & 0xFFFFFFE0)); } + OSSetArenaHi((!BootInfo->arenaHi) ? &__ArenaHi : BootInfo->arenaHi); - OSSetArenaHi((BootInfo->arena_hi == NULL) ? __ArenaHi : BootInfo->arena_hi); - - // OS INIT AND REPORT // OSExceptionInit(); __OSInitSystemCall(); OSInitAlarm(); __OSModuleInit(); __OSInterruptInit(); - __OSSetInterruptHandler(OS_INTR_PI_RSW, (void*)__OSResetSWInterruptHandler); + __OSSetInterruptHandler(0x16, &__OSResetSWInterruptHandler); __OSContextInit(); __OSCacheInit(); EXIInit(); @@ -309,28 +284,29 @@ void OSInit(void) { __OSInitSram(); __OSThreadInit(); __OSInitAudioSystem(); - PPCMthid2(PPCMfhid2() & 0xBFFFFFFF); - if ((BOOL)__OSInIPL == FALSE) { + + DisableWriteGatherPipe(); + + if (!__OSInIPL) { __OSInitMemoryProtection(); } OSReport("\nDolphin OS\n"); - OSReport("Kernel built : %s %s\n", "Nov 10 2004", "06:26:41"); +#if DEBUG + OSReport("Kernel built : %s %s\n", BUILD_DATE, DBUILD_TIME); +#else + OSReport("Kernel built : %s %s\n", BUILD_DATE, RBUILD_TIME); +#endif OSReport("Console Type : "); - if (BootInfo == NULL || (inputConsoleType = BootInfo->console_type) == 0) { - inputConsoleType = OS_CONSOLE_ARTHUR; // default console type - } else { - inputConsoleType = BootInfo->console_type; - } - - switch (inputConsoleType & 0xF0000000) { + consoleType = OSGetConsoleType(); + switch (consoleType & 0xF0000000) { case OS_CONSOLE_RETAIL: - OSReport("Retail %d\n", inputConsoleType); + OSReport("Retail %d\n", consoleType); break; case OS_CONSOLE_DEVELOPMENT: case OS_CONSOLE_TDEV: - switch (inputConsoleType & 0x0FFFFFFF) { + switch (consoleType & 0x0FFFFFFF) { case OS_CONSOLE_EMULATOR: OSReport("Mac Emulator\n"); break; @@ -344,20 +320,20 @@ void OSInit(void) { OSReport("EPPC Minnow\n"); break; default: - tdev = (u32)inputConsoleType & 0x0FFFFFFF; - OSReport("Development HW%d (%08x)\n", tdev - 3, inputConsoleType); + OSReport("Development HW%d (%08x)\n", (consoleType & 0xFFFFFFF) - 3, consoleType); break; } break; default: - OSReport("%08x\n", inputConsoleType); + OSReport("%08x\n", consoleType); break; } - OSReport("Memory %d MB\n", (u32)BootInfo->memory_size >> 0x14U); + OSReport("Memory %d MB\n", (u32)BootInfo->memorySize >> 0x14U); OSReport("Arena : 0x%x - 0x%x\n", OSGetArenaLo(), OSGetArenaHi()); OSRegisterVersion(__OSVersion); + // if location of debug flag exists, and flag is >= 2, enable MetroTRKInterrupts if (BI2DebugFlag && ((*BI2DebugFlag) >= 2)) { EnableMetroTRKInterrupts(); } @@ -365,70 +341,71 @@ void OSInit(void) { ClearArena(); OSEnableInterrupts(); - if ((BOOL)__OSInIPL == FALSE) { + if (!__OSInIPL) { DVDInit(); - if ((BOOL)__OSIsGcam) { + + if (__OSIsGcam) { __OSDeviceCode = 0x9000; return; } + DCInvalidateRange(&DriveInfo, sizeof(DriveInfo)); - DVDInquiryAsync((DVDCommandBlock*)&DriveBlock, &DriveInfo, InquiryCallback); + DVDInquiryAsync(&DriveBlock, &DriveInfo, InquiryCallback); } } } -/* ############################################################################################## */ -/* 803CF3AC-803CF3E8 02C4CC 003C+00 0/1 0/0 0/0 .data __OSExceptionLocations */ static u32 __OSExceptionLocations[] = { - 0x00000100, // 0 System reset - 0x00000200, // 1 Machine check - 0x00000300, // 2 DSI - seg fault or DABR - 0x00000400, // 3 ISI - 0x00000500, // 4 External interrupt - 0x00000600, // 5 Alignment - 0x00000700, // 6 Program - 0x00000800, // 7 FP Unavailable - 0x00000900, // 8 Decrementer - 0x00000C00, // 9 System call - 0x00000D00, // 10 Trace - 0x00000F00, // 11 Performance monitor - 0x00001300, // 12 Instruction address breakpoint. - 0x00001400, // 13 System management interrupt - 0x00001700 // 14 Thermal interrupt + 0x00000100, 0x00000200, 0x00000300, 0x00000400, 0x00000500, 0x00000600, 0x00000700, 0x00000800, + 0x00000900, 0x00000C00, 0x00000D00, 0x00000F00, 0x00001300, 0x00001400, 0x00001700, }; -// dummy entry points to the OS Exception vector -void __OSEVStart(void); -void __OSDBINTSTART(void); -void __OSDBINTEND(void); -void __OSDBJUMPSTART(void); -void __OSDBJUMPEND(void); +#if DEBUG +char * __OSExceptionNames[17] = { + "System reset", + "MachineCheck", + "DSI", + "ISI", + "External Int.", + "Alignment", + "Program", + "FP Unavailable", + "Decrementer", + "System call", + "Trace", + "Perf mon", + "IABR", + "SMI", + "Thermal Int.", + "Protection error", + "FP Exception", +}; +#endif -#define NOP 0x60000000 - -/* 8033A440-8033A6C0 334D80 0280+00 1/1 0/0 0/0 .text OSExceptionInit */ static void OSExceptionInit(void) { __OSException exception; void* destAddr; - + // These two vars help us change the exception number embedded // in the exception handler code. u32* opCodeAddr; u32 oldOpCode; - + // Address range of the actual code to be copied. u8* handlerStart; u32 handlerSize; - + + ASSERTMSGLINE(1063, ((u32)&__OSEVEnd - (u32)&__OSEVStart) <= 0x100, "OSExceptionInit(): too big exception vector code."); + // Install the first level exception vector. opCodeAddr = (u32*)__OSEVSetNumber; oldOpCode = *opCodeAddr; handlerStart = (u8*)__OSEVStart; handlerSize = (u32)((u8*)__OSEVEnd - (u8*)__OSEVStart); - + // Install the DB integrator, only if we are the first OSInit to be run destAddr = (void*)OSPhysicalToCached(OS_DBJUMPPOINT_ADDR); - if (*(u32*)destAddr == 0) // Lomem should be zero cleared only once by BS2 + if (*(u32*)destAddr == 0) // Lomem should be zero cleared only once by BS2 { DBPrintf("Installing OSDBIntegrator\n"); memcpy(destAddr, (void*)__OSDBINTSTART, (u32)__OSDBINTEND - (u32)__OSDBINTSTART); @@ -436,34 +413,33 @@ static void OSExceptionInit(void) { __sync(); ICInvalidateRange(destAddr, (u32)__OSDBINTEND - (u32)__OSDBINTSTART); } - + // Copy the right vector into the table - for (exception = 0; exception < 15; exception++) { + for (exception = 0; exception < __OS_EXCEPTION_MAX; exception++) { if (BI2DebugFlag && (*BI2DebugFlag >= 2) && __DBIsExceptionMarked(exception)) { // this DBPrintf is suspicious. DBPrintf(">>> OSINIT: exception %d commandeered by TRK\n", exception); continue; } - + // Modify the copy of code in text before transferring // to the exception table. *opCodeAddr = oldOpCode | exception; - + // Modify opcodes at __DBVECTOR if necessary if (__DBIsExceptionMarked(exception)) { DBPrintf(">>> OSINIT: exception %d vectored to debugger\n", exception); - memcpy((void*)__DBVECTOR, (void*)__OSDBJUMPSTART, - (u32)__OSDBJUMPEND - (u32)__OSDBJUMPSTART); + memcpy((void*)__DBVECTOR, (void*)__OSDBJUMPSTART, (u32)__OSDBJUMPEND - (u32)__OSDBJUMPSTART); } else { // make sure the opcodes are still nop u32* ops = (u32*)__DBVECTOR; int cb; - + for (cb = 0; cb < (u32)__OSDBJUMPEND - (u32)__OSDBJUMPSTART; cb += sizeof(u32)) { *ops++ = NOP; } } - + // Install the modified handler. destAddr = (void*)OSPhysicalToCached(__OSExceptionLocations[(u32)exception]); memcpy(destAddr, handlerStart, handlerSize); @@ -471,223 +447,185 @@ static void OSExceptionInit(void) { __sync(); ICInvalidateRange(destAddr, handlerSize); } - // initialize pointer to exception table - OSExceptionTable = OSPhysicalToCached(OS_EXCEPTIONTABLE_ADDR); - + OSExceptionTable = (void*)OSPhysicalToCached(OS_EXCEPTIONTABLE_ADDR); + // install default exception handlers - for (exception = 0; exception < 15; exception++) { + for (exception = 0; exception < __OS_EXCEPTION_MAX; exception++) { __OSSetExceptionHandler(exception, OSDefaultExceptionHandler); } - + // restore the old opcode, so that we can re-start an application without // downloading the text segments *opCodeAddr = oldOpCode; - + DBPrintf("Exceptions initialized...\n"); } -/* 8033A6C0-8033A6E4 335000 0024+00 1/1 0/0 0/0 .text __OSDBIntegrator */ -asm void __OSDBIntegrator(void) { - // clang-format off +#ifdef __GEKKO__ +static asm void __OSDBIntegrator(void) { nofralloc - entry __OSDBINTSTART - li r5, 0x40 - mflr r3 - stw r3, 0xc(r5) - lwz r3, 8(r5) - oris r3, r3, 0x8000 - mtlr r3 - li r3, 0x30 - mtmsr r3 + li r5, OS_DBINTERFACE_ADDR + mflr r3 + stw r3, DB_EXCEPTIONRET_OFFSET(r5) + lwz r3, DB_EXCEPTIONDEST_OFFSET(r5) + oris r3, r3, OS_CACHED_REGION_PREFIX + mtlr r3 + li r3, 0x30 // MSR_IR | MSR_DR // turn on memory addressing + mtmsr r3 blr entry __OSDBINTEND - // clang-format on } +#endif -/* 8033A6E4-8033A6E8 335024 0004+00 1/1 0/0 0/0 .text __OSDBJump */ -asm void __OSDBJump(void){ - // clang-format off +#ifdef __GEKKO__ +static asm void __OSDBJump(void) { nofralloc - entry __OSDBJUMPSTART - bla 0x60 + bla OS_DBJUMPPOINT_ADDR entry __OSDBJUMPEND - // clang-format on } +#endif -/* 8033A6E8-8033A704 335028 001C+00 1/1 3/3 0/0 .text __OSSetExceptionHandler */ -OSExceptionHandler __OSSetExceptionHandler(__OSException exception, OSExceptionHandler handler) { - OSExceptionHandler old = OSExceptionTable[exception]; +__OSExceptionHandler __OSSetExceptionHandler(__OSException exception, __OSExceptionHandler handler) { + __OSExceptionHandler oldHandler; + + ASSERTMSGLINE(1205, exception < __OS_EXCEPTION_MAX, "__OSSetExceptionHandler(): unknown exception."); + + oldHandler = OSExceptionTable[exception]; OSExceptionTable[exception] = handler; - return old; + return oldHandler; } -/* 8033A704-8033A718 335044 0014+00 0/0 1/1 0/0 .text __OSGetExceptionHandler */ -OSExceptionHandler __OSGetExceptionHandler(__OSException exception) { +__OSExceptionHandler __OSGetExceptionHandler(__OSException exception) { + ASSERTMSGLINE(1228, exception < __OS_EXCEPTION_MAX, "__OSGetExceptionHandler(): unknown exception."); return OSExceptionTable[exception]; } -/* 8033A718-8033A770 335058 0058+00 1/1 0/0 0/0 .text OSExceptionVector */ +#ifdef __GEKKO__ static asm void OSExceptionVector(void) { - // clang-format off nofralloc entry __OSEVStart // Save r4 into SPRG0 - mtsprg 0, r4 + mtsprg 0, r4 // Load current context physical address into r4 - lwz r4, OS_CURRENTCONTEXT_PADDR + lwz r4, OS_CURRENTCONTEXT_PADDR // Save r3 - r5 into the current context - stw r3, OS_CONTEXT_R3(r4) - mfsprg r3, 0 - stw r3, OS_CONTEXT_R4(r4) - stw r5, OS_CONTEXT_R5(r4) + stw r3, OS_CONTEXT_R3(r4) + mfsprg r3, 0 + stw r3, OS_CONTEXT_R4(r4) + stw r5, OS_CONTEXT_R5(r4) - lhz r3, OS_CONTEXT_STATE(r4) - ori r3, r3, OS_CONTEXT_STATE_EXC - sth r3, OS_CONTEXT_STATE(r4) + lhz r3, OS_CONTEXT_STATE(r4) + ori r3, r3, OS_CONTEXT_STATE_EXC + sth r3, OS_CONTEXT_STATE(r4) // Save misc registers - mfcr r3 - stw r3, OS_CONTEXT_CR(r4) - mflr r3 - stw r3, OS_CONTEXT_LR(r4) - mfctr r3 - stw r3, OS_CONTEXT_CTR(r4) - mfxer r3 - stw r3, OS_CONTEXT_XER(r4) - mfsrr0 r3 - stw r3, OS_CONTEXT_SRR0(r4) - mfsrr1 r3 - stw r3, OS_CONTEXT_SRR1(r4) - mr r5, r3 + mfcr r3 + stw r3, OS_CONTEXT_CR(r4) + mflr r3 + stw r3, OS_CONTEXT_LR(r4) + mfctr r3 + stw r3, OS_CONTEXT_CTR(r4) + mfxer r3 + stw r3, OS_CONTEXT_XER(r4) + mfsrr0 r3 + stw r3, OS_CONTEXT_SRR0(r4) + mfsrr1 r3 + stw r3, OS_CONTEXT_SRR1(r4) + mr r5, r3 entry __DBVECTOR nop // Set SRR1[IR|DR] to turn on address // translation at the next RFI - mfmsr r3 - ori r3, r3, 0x30 - mtsrr1 r3 + mfmsr r3 + ori r3, r3, 0x30 + mtsrr1 r3 // This lets us change the exception number based on the // exception we're installing. entry __OSEVSetNumber - li r3, 0 + addi r3, 0, 0x0000 // Load current context virtual address into r4 - lwz r4, 0xd4(r0) + lwz r4, 0xD4 // Check non-recoverable interrupt rlwinm. r5, r5, 0, MSR_RI_BIT, MSR_RI_BIT - bne recoverable - lis r5, OSDefaultExceptionHandler@ha - addi r5, r5, OSDefaultExceptionHandler@l - mtsrr0 r5 + bne recoverable + addis r5, 0, OSDefaultExceptionHandler@ha + addi r5, r5, OSDefaultExceptionHandler@l + mtsrr0 r5 rfi // NOT REACHED HERE recoverable: // Locate exception handler. - rlwinm r5, r3, 2, 0x16, 0x1d // r5 contains exception*4 - lwz r5, OS_EXCEPTIONTABLE_ADDR(r5) - mtsrr0 r5 + rlwinm r5, r3, 2, 22, 29 // r5 contains exception*4 + lwz r5, OS_EXCEPTIONTABLE_ADDR(r5) + mtsrr0 r5 // Final state // r3 - exception number // r4 - pointer to context // r5 - garbage // srr0 - exception handler - // srr1 - address translation enabled, not yet recoverable + // srr1 - address translation enalbed, not yet recoverable - rfi + rfi // NOT REACHED HERE // The handler will restore state entry __OSEVEnd nop - // clang-format on } +#endif -/* 8033A7B4-8033A80C 3350F4 0058+00 2/2 0/0 0/0 .text OSDefaultExceptionHandler */ -static asm void OSDefaultExceptionHandler(register __OSException exception, - register OSContext* context) { - // clang-format off +void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar); + +#ifdef __GEKKO__ +asm void OSDefaultExceptionHandler(register __OSException exception, register OSContext* context) { nofralloc - - stw r0, 0(context) - stw r1, 4(context) - stw r2, 8(context) - stmw r6, 0x18(context) - mfspr r0, 0x391 - stw r0, 0x1a8(context) - mfspr r0, 0x392 - stw r0, 0x1ac(context) - mfspr r0, 0x393 - stw r0, 0x1b0(context) - mfspr r0, 0x394 - stw r0, 0x1b4(context) - mfspr r0, 0x395 - stw r0, 0x1b8(context) - mfspr r0, 0x396 - stw r0, 0x1bc(context) - mfspr r0, 0x397 - stw r0, 0x1c0(context) - + OS_EXCEPTION_SAVE_GPRS(context) mfdsisr r5 - mfdar r6 + mfdar r6 stwu r1, -8(r1) - b __OSUnhandledException - // clang-format on + b __OSUnhandledException } +#endif -/* 8033A80C-8033A860 33514C 0054+00 0/0 1/1 0/0 .text __OSPSInit */ -asm void __OSPSInit(void){ - // clang-format off - nofralloc +#ifdef __GEKKO__ +void __OSPSInit(void) { + PPCMthid2(PPCMfhid2() | 0x80000000 | 0x20000000); + ICFlashInvalidate(); + __sync(); - mflr r0 - stw r0, 4(r1) - stwu r1, -8(r1) - bl PPCMfhid2 - oris r3, r3, 0xa000 - bl PPCMthid2 - bl ICFlashInvalidate - sync - - li r3, 0 - mtspr 0x390, r3 - mtspr 0x391, r3 - mtspr 0x392, r3 - mtspr 0x393, r3 - mtspr 0x394, r3 - mtspr 0x395, r3 - mtspr 0x396, r3 - mtspr 0x397, r3 - - lwz r0, 0xc(r1) - addi r1, r1, 8 - mtlr r0 - blr - // clang-format on + asm + { + li r3, 0 + mtspr GQR0, r3 + mtspr GQR1, r3 + mtspr GQR2, r3 + mtspr GQR3, r3 + mtspr GQR4, r3 + mtspr GQR5, r3 + mtspr GQR6, r3 + mtspr GQR7, r3 + } } +#endif -vu32 __DIRegs[16] AT_ADDRESS(0xCC006000); -#define DI_CONFIG_IDX 0x9 -#define DI_CONFIG_CONFIG_MASK 0xFF - -/* 8033A860-8033A874 3351A0 0014+00 0/0 1/1 0/0 .text __OSGetDIConfig */ u32 __OSGetDIConfig(void) { - return (__DIRegs[DI_CONFIG_IDX] & DI_CONFIG_CONFIG_MASK); + return (__DIRegs[9] & 0xFF); } -/* 8033A874-8033A8A0 3351B4 002C+00 1/1 11/11 0/0 .text OSRegisterVersion */ -void OSRegisterVersion(const char* version) { - OSReport("%s\n", version); +void OSRegisterVersion(const char* id) { + OSReport("%s\n", id); } diff --git a/src/dolphin/os/OSAddress.c b/src/dolphin/os/OSAddress.c new file mode 100644 index 0000000000..4445c5a465 --- /dev/null +++ b/src/dolphin/os/OSAddress.c @@ -0,0 +1,39 @@ +#include + +// undefine the macros so they do not error the file. +#undef OSPhysicalToCached +#undef OSPhysicalToUncached +#undef OSCachedToPhysical +#undef OSUncachedToPhysical +#undef OSCachedToUncached +#undef OSUncachedToCached + +void* OSPhysicalToCached(u32 paddr) { + ASSERTMSGLINE(47, paddr < 0x10000000U, "OSPhysicalToCached(): illegal address."); + return (void*)(paddr + 0x80000000); +} + +void* OSPhysicalToUncached(u32 paddr) { + ASSERTMSGLINE(62, paddr < 0x10000000U, "OSPhysicalToUncached(): illegal address."); + return (void*)(paddr - 0x40000000); +} + +u32 OSCachedToPhysical(void* caddr) { + ASSERTMSGLINE(77, 0x80000000U <= (u32)caddr && (u32)caddr < 0x90000000U, "OSCachedToPhysical(): illegal address."); + return (u32)caddr + 0x80000000; +} + +u32 OSUncachedToPhysical(void* ucaddr) { + ASSERTMSGLINE(92, 0xC0000000U <= (u32)ucaddr && (u32)ucaddr < 0xD0000000U, "OSUncachedToPhysical(): illegal address."); + return (u32)ucaddr + 0x40000000; +} + +void* OSCachedToUncached(void* caddr) { + ASSERTMSGLINE(107, 0x80000000U <= (u32)caddr && (u32)caddr < 0x90000000U, "OSCachedToUncached(): illegal address."); + return (void*)((u32)caddr + 0x40000000); +} + +void* OSUncachedToCached(void* ucaddr) { + ASSERTMSGLINE(122, 0xC0000000U <= (u32)ucaddr && (u32)ucaddr < 0xD0000000U, "OSUncachedToCached(): illegal address."); + return (void*)((u32)ucaddr - 0x40000000); +} diff --git a/src/dolphin/os/OSAlarm.c b/src/dolphin/os/OSAlarm.c index 79d62d26bf..9a0d0d610b 100644 --- a/src/dolphin/os/OSAlarm.c +++ b/src/dolphin/os/OSAlarm.c @@ -1,37 +1,44 @@ -#include "dolphin/os/OSAlarm.h" -#include "dolphin/os.h" +#include +#include -static BOOL OnReset(BOOL param_0); -BOOL __DVDTestAlarm(OSAlarm* alarm); +#include "__os.h" +#include "__dvd.h" -/* 803CF480-803CF490 -00001 0010+00 1/1 0/0 0/0 .data ResetFunctionInfo */ -static OSResetFunctionInfo ResetFunctionInfo = { - OnReset, - 0xFFFFFFFF, -}; +typedef struct { + OSAlarm* head; + OSAlarm* tail; +} OSAlarmQueue; -/* 80451638-80451640 000B38 0008+00 5/5 0/0 0/0 .sbss AlarmQueue */ +// prototypes +static void SetTimer(OSAlarm * alarm); +static void InsertAlarm(OSAlarm* alarm, OSTime fire, OSAlarmHandler handler); +static void DecrementerExceptionCallback(register __OSException exception, register OSContext* context); +static void DecrementerExceptionHandler(__OSException exception, OSContext* context); +static BOOL OnReset(BOOL final); + +static OSResetFunctionInfo ResetFunctionInfo = {OnReset, 0xFFFFFFFF, NULL, NULL}; static OSAlarmQueue AlarmQueue; -/* 8033A8A0-8033A8F8 3351E0 0058+00 0/0 3/3 0/0 .text OSInitAlarm */ -void OSInitAlarm(void) { - if (__OSGetExceptionHandler(8) != DecrementerExceptionHandler) { - AlarmQueue.head = AlarmQueue.tail = NULL; - __OSSetExceptionHandler(8, DecrementerExceptionHandler); - OSRegisterResetFunction(&ResetFunctionInfo); +#define ASSERTREPORT(line, cond) \ + if (!(cond)) { OSReport("OSCheckAlarmQueue: Failed " #cond " in %d", line); return 0; } + +BOOL OSCheckAlarmQueue(void) { + OSAlarm* alarm; + + ASSERTREPORT(146, AlarmQueue.head == NULL && AlarmQueue.tail == NULL || AlarmQueue.head != NULL && AlarmQueue.tail != NULL); + ASSERTREPORT(147, AlarmQueue.head == NULL || AlarmQueue.head->prev == NULL); + ASSERTREPORT(148, AlarmQueue.tail == NULL || AlarmQueue.tail->next == NULL); + + for(alarm = AlarmQueue.head; alarm; alarm = alarm->next) { + ASSERTREPORT(151, alarm->next == NULL || alarm->next->prev == alarm); + ASSERTREPORT(152, alarm->next != NULL || AlarmQueue.tail == alarm); } + return TRUE; } -/* 8033A8F8-8033A908 335238 0010+00 0/0 17/17 0/0 .text OSCreateAlarm */ -void OSCreateAlarm(OSAlarm* alarm) { - alarm->handler = NULL; - alarm->tag = 0; -} +static void SetTimer(OSAlarm* alarm) { + OSTime delta = alarm->fire - __OSGetSystemTime(); -static inline SetTimer(OSAlarm* alarm) { - OSTime delta; - - delta = alarm->fire_time - __OSGetSystemTime(); if (delta < 0) { PPCMtdec(0); } else if (delta < 0x80000000) { @@ -41,74 +48,106 @@ static inline SetTimer(OSAlarm* alarm) { } } -/* 8033A908-8033AB58 335248 0250+00 3/3 0/0 0/0 .text InsertAlarm */ +void OSInitAlarm(void) { + if (__OSGetExceptionHandler(8) != DecrementerExceptionHandler) { + AlarmQueue.head = AlarmQueue.tail = NULL; + __OSSetExceptionHandler(8, DecrementerExceptionHandler); + OSRegisterResetFunction(&ResetFunctionInfo); + } +} + +void OSCreateAlarm(OSAlarm* alarm) { + alarm->handler = 0; + alarm->tag = 0; +} + static void InsertAlarm(OSAlarm* alarm, OSTime fire, OSAlarmHandler handler) { OSAlarm* next; OSAlarm* prev; - - if (0 < alarm->period_time) { + + if (0 < alarm->period) { OSTime time = __OSGetSystemTime(); - - fire = alarm->start_time; - if (alarm->start_time < time) { - fire += alarm->period_time * ((time - alarm->start_time) / alarm->period_time + 1); + + fire = alarm->start; + if (alarm->start < time) { + fire += alarm->period * ((time - alarm->start) / alarm->period + 1); } } - + + ASSERTLINE(251, alarm->handler == 0); + alarm->handler = handler; - alarm->fire_time = fire; - - for (next = AlarmQueue.head; next; next = next->link.next) { - if (next->fire_time <= fire) { + alarm->fire = fire; + + for (next = AlarmQueue.head; next; next = next->next) { + if (next->fire <= fire) { continue; } + + alarm->prev = next->prev; + next->prev = alarm; + alarm->next = next; + prev = alarm->prev; - alarm->link.prev = next->link.prev; - next->link.prev = alarm; - alarm->link.next = next; - prev = alarm->link.prev; if (prev) { - prev->link.next = alarm; + prev->next = alarm; } else { AlarmQueue.head = alarm; SetTimer(alarm); } + return; } - alarm->link.next = 0; + ASSERTLINE(280, next == 0); + + alarm->next = 0; prev = AlarmQueue.tail; AlarmQueue.tail = alarm; - alarm->link.prev = prev; + alarm->prev = prev; if (prev) { - prev->link.next = alarm; + prev->next = alarm; } else { AlarmQueue.head = AlarmQueue.tail = alarm; SetTimer(alarm); } } -/* 8033AB58-8033ABC0 335498 0068+00 0/0 18/18 0/0 .text OSSetAlarm */ void OSSetAlarm(OSAlarm* alarm, OSTime tick, OSAlarmHandler handler) { BOOL enabled; + ASSERTMSGLINE(313, tick > 0, "OSSetAlarm(): tick was less than zero."); + ASSERTMSGLINE(314, handler, "OSSetAlarm(): null handler was specified."); enabled = OSDisableInterrupts(); - alarm->period_time = 0; + alarm->period = 0; InsertAlarm(alarm, __OSGetSystemTime() + tick, handler); + ASSERTLINE(321, OSCheckAlarmQueue()); + OSRestoreInterrupts(enabled); +} + +void OSSetAbsAlarm(OSAlarm* alarm, OSTime time, OSAlarmHandler handler) { + BOOL enabled; + + ASSERTMSGLINE(343, handler, "OSSetAbsAlarm(): null handler was specified."); + enabled = OSDisableInterrupts(); + alarm->period = 0; + InsertAlarm(alarm, __OSTimeToSystemTime(time), handler); + ASSERTLINE(350, OSCheckAlarmQueue()); OSRestoreInterrupts(enabled); } -/* 8033ABC0-8033AC3C 335500 007C+00 0/0 1/1 0/0 .text OSSetPeriodicAlarm */ void OSSetPeriodicAlarm(OSAlarm* alarm, OSTime start, OSTime period, OSAlarmHandler handler) { BOOL enabled; + ASSERTMSGLINE(374, period > 0, "OSSetPeriodicAlarm(): period was less than zero."); + ASSERTMSGLINE(375, handler, "OSSetPeriodicAlarm(): null handler was specified."); enabled = OSDisableInterrupts(); - alarm->period_time = period; - alarm->start_time = __OSTimeToSystemTime(start); + alarm->period = period; + alarm->start = __OSTimeToSystemTime(start); InsertAlarm(alarm, 0, handler); + ASSERTLINE(383, OSCheckAlarmQueue()); OSRestoreInterrupts(enabled); } -/* 8033AC3C-8033AD58 33557C 011C+00 1/1 11/11 0/0 .text OSCancelAlarm */ void OSCancelAlarm(OSAlarm* alarm) { OSAlarm* next; BOOL enabled; @@ -120,14 +159,14 @@ void OSCancelAlarm(OSAlarm* alarm) { return; } - next = alarm->link.next; + next = alarm->next; if (next == 0) { - AlarmQueue.tail = alarm->link.prev; + AlarmQueue.tail = alarm->prev; } else { - next->link.prev = alarm->link.prev; + next->prev = alarm->prev; } - if (alarm->link.prev) { - alarm->link.prev->link.next = next; + if (alarm->prev) { + alarm->prev->next = next; } else { AlarmQueue.head = next; if (next) { @@ -135,11 +174,10 @@ void OSCancelAlarm(OSAlarm* alarm) { } } alarm->handler = 0; - + ASSERTLINE(434, OSCheckAlarmQueue()); OSRestoreInterrupts(enabled); } -/* 8033AD58-8033AF88 335698 0230+00 1/1 0/0 0/0 .text DecrementerExceptionCallback */ static void DecrementerExceptionCallback(register __OSException exception, register OSContext* context) { OSAlarm* alarm; @@ -147,29 +185,33 @@ static void DecrementerExceptionCallback(register __OSException exception, OSAlarmHandler handler; OSTime time; OSContext exceptionContext; + time = __OSGetSystemTime(); alarm = AlarmQueue.head; if (alarm == 0) { OSLoadContext(context); } - if (time < alarm->fire_time) { + if (time < alarm->fire) { SetTimer(alarm); OSLoadContext(context); } - next = alarm->link.next; + next = alarm->next; AlarmQueue.head = next; if (next == 0) { AlarmQueue.tail = 0; } else { - next->link.prev = 0; + next->prev = 0; } + ASSERTLINE(492, OSCheckAlarmQueue()); + handler = alarm->handler; alarm->handler = 0; - if (0 < alarm->period_time) { + if (0 < alarm->period) { InsertAlarm(alarm, 0, handler); + ASSERTLINE(502, OSCheckAlarmQueue()); } if (AlarmQueue.head) { @@ -187,53 +229,69 @@ static void DecrementerExceptionCallback(register __OSException exception, OSLoadContext(context); } -/* 8033AF88-8033AFD8 3358C8 0050+00 1/1 0/0 0/0 .text DecrementerExceptionHandler */ +#ifdef __GEKKO__ static asm void DecrementerExceptionHandler(register __OSException exception, register OSContext* context) { - // clang-format off - nofralloc - - stw r0, 0(context) - stw r1, 4(context) - stw r2, 8(context) - stmw r6, 0x18(context) - mfspr r0, 0x391 - stw r0, 0x1a8(context) - mfspr r0, 0x392 - stw r0, 0x1ac(context) - mfspr r0, 0x393 - stw r0, 0x1b0(context) - mfspr r0, 0x394 - stw r0, 0x1b4(context) - mfspr r0, 0x395 - stw r0, 0x1b8(context) - mfspr r0, 0x396 - stw r0, 0x1bc(context) - mfspr r0, 0x397 - stw r0, 0x1c0(context) + nofralloc + OS_EXCEPTION_SAVE_GPRS(context) stwu r1, -8(r1) b DecrementerExceptionCallback - // clang-format on +} +#endif + +void OSSetAlarmTag(OSAlarm* alarm, u32 tag) { + alarm->tag = tag; +} + +void OSCancelAlarms(u32 tag) { + BOOL enabled; + OSAlarm* alarm; + OSAlarm* next; + + ASSERTMSGLINE(569, tag != 0, "OSCancelAlarms(): invalid tag. (tag zero is used by the operating system.)"); + + if (tag != 0) { + enabled = OSDisableInterrupts(); + ASSERTLINE(575, OSCheckAlarmQueue()); + + alarm = AlarmQueue.head; + next = (alarm) ? alarm->next : NULL; + + while (alarm != 0) { + if (alarm->tag == tag) { + OSCancelAlarm(alarm); + } + + alarm = next; + next = (alarm) ? alarm->next : NULL; + } + + ASSERTLINE(585, OSCheckAlarmQueue()); + OSRestoreInterrupts(enabled); + } } -/* 8033AFD8-8033B078 335918 00A0+00 1/0 0/0 0/0 .text OnReset */ static BOOL OnReset(BOOL final) { OSAlarm* alarm; OSAlarm* next; if (final != FALSE) { - alarm = AlarmQueue.head; - next = (alarm) ? alarm->link.next : NULL; + ASSERTLINE(606, OSCheckAlarmQueue()); - while (alarm != NULL) { + alarm = AlarmQueue.head; + next = (alarm) ? alarm->next : NULL; + + while (alarm != 0) { if (__DVDTestAlarm(alarm) == FALSE) { OSCancelAlarm(alarm); } alarm = next; - next = (alarm) ? alarm->link.next : NULL; + next = (alarm) ? alarm->next : NULL; } + + ASSERTLINE(616, OSCheckAlarmQueue()); } return TRUE; -} \ No newline at end of file +} diff --git a/src/dolphin/os/OSAlloc.c b/src/dolphin/os/OSAlloc.c index 813c9fa1db..2ad58e3b4d 100644 --- a/src/dolphin/os/OSAlloc.c +++ b/src/dolphin/os/OSAlloc.c @@ -1,140 +1,609 @@ -#include "dolphin/os/OSAlloc.h" +#include +#include -/* 8033B078-8033B124 3359B8 00AC+00 1/1 0/0 0/0 .text DLInsert */ -static OSHeapCell* DLInsert(OSHeapCell* list, OSHeapCell* child) { - OSHeapCell* prev = NULL; - OSHeapCell* next = list; +#define ALIGNMENT 32 - for (; next != NULL; prev = next, next = next->next) { - if ((char*)child <= (char*)next) { +#define InRange(cell, arenaStart, arenaEnd) \ + ((u32) arenaStart <= (u32) cell) && ((u32) cell < (u32) arenaEnd) + +#define HEADERSIZE 32u +#define MINOBJSIZE 64u + +#ifdef DEBUG +#define ENABLE_HEAPDESC +#endif + +typedef struct Cell Cell; +typedef struct HeapDesc HeapDesc; +struct Cell { + Cell* prev; + Cell* next; + s32 size; +#ifdef ENABLE_HEAPDESC + HeapDesc* hd; + s32 requested; +#endif +}; + +struct HeapDesc { + s32 size; + Cell* free; + Cell* allocated; +#ifdef ENABLE_HEAPDESC + u32 paddingBytes; + u32 headerBytes; + u32 payloadBytes; +#endif +}; + +volatile int __OSCurrHeap = -1; + +static HeapDesc* HeapArray; +static int NumHeaps; +static void* ArenaStart; +static void* ArenaEnd; + +// prototypes +static Cell* DLAddFront(Cell* list, Cell* cell); +static Cell* DLLookup(Cell* list, Cell* cell); +static Cell* DLExtract(Cell* list, Cell* cell); +static Cell* DLInsert(Cell* list, Cell* cell); +static int DLOverlap(Cell* list, void* start, void* end); +static s32 DLSize(Cell* list); + +static Cell* DLAddFront(Cell* list, Cell* cell) { + cell->next = list; + cell->prev = 0; + if (list) { + list->prev = cell; + } + return cell; +} + +static Cell* DLLookup(Cell* list, Cell* cell) { + for(; list; list = list->next) { + if (list == cell) { + return list; + } + } + return NULL; +} + +static Cell* DLExtract(Cell* list, Cell* cell) { + if (cell->next) { + cell->next->prev = cell->prev; + } + if (cell->prev == NULL) { + return cell->next; + } + cell->prev->next = cell->next; + return list; +} + +static Cell* DLInsert(Cell* list, Cell* cell) { + Cell* prev; + Cell* next; + + for(next = list, prev = NULL; next != 0; prev = next, next = next->next) { + if (cell <= next) { break; } } - child->next = next; - child->prev = prev; - - if (next != NULL) { - next->prev = child; - - if ((char*)child + child->size == (char*)next) { - child->size += next->size; + cell->next = next; + cell->prev = prev; + if (next) { + next->prev = cell; + if ((u8*)cell + cell->size == (u8*)next) { + cell->size += next->size; next = next->next; - child->next = next; - if (next != NULL) { - next->prev = child; + cell->next = next; + if (next) { + next->prev = cell; } } } - - if (prev != NULL) { - prev->next = child; - - if ((char*)prev + prev->size == (char*)child) { - prev->size += child->size; + if (prev) { + prev->next = cell; + if ((u8*)prev + prev->size == (u8*)cell) { + prev->size += cell->size; prev->next = next; - if (next != NULL) { + if (next) { next->prev = prev; } } - return list; + } + return cell; +} + +static int DLOverlap(Cell* list, void* start, void* end) { + Cell* cell = list; + + while(cell) { + if (((start <= cell) + && (cell < end)) + || ((start < (void* ) ((u8*)cell + cell->size)) + && ((void* ) ((u8*)cell + cell->size) <= end))) { + return 1; + } + cell = cell->next; + } + return 0; +} + +static s32 DLSize(Cell* list) { + Cell* cell; + s32 size; + + size = 0; + cell = list; + + while(cell) { + size += cell->size; + cell = cell->next; + } + + return size; +} + +void* OSAllocFromHeap(int heap, u32 size) { + HeapDesc* hd; + Cell* cell; + Cell* newCell; + s32 leftoverSize; + s32 requested; + + requested = size; + ASSERTMSGLINE(337, HeapArray, "OSAllocFromHeap(): heap is not initialized."); + ASSERTMSGLINE(338, (s32)size > 0, "OSAllocFromHeap(): invalid size."); + ASSERTMSGLINE(339, heap >= 0 && heap < NumHeaps, "OSAllocFromHeap(): invalid heap handle."); + ASSERTMSGLINE(340, HeapArray[heap].size >= 0, "OSAllocFromHeap(): invalid heap handle."); + + hd = &HeapArray[heap]; + size += 0x20; + size = (size + 0x1F) & 0xFFFFFFE0; + + for(cell = hd->free; cell != NULL; cell = cell->next) { + if ((signed)size <= (signed)cell->size) { + break; + } + } + + if (cell == NULL) { +#if DEBUG + OSReport("OSAllocFromHeap: Warning- failed to allocate %d bytes\n", size); +#endif + return NULL; + } + ASSERTMSGLINE(364, !((s32)cell & 0x1F), "OSAllocFromHeap(): heap is broken."); + ASSERTMSGLINE(365, cell->hd == NULL, "OSAllocFromHeap(): heap is broken."); + + leftoverSize = cell->size - size; + if (leftoverSize < 0x40U) { + hd->free = DLExtract(hd->free, cell); } else { - return child; - } -} - -inline OSHeapCell* DLExtract(OSHeapCell* list, OSHeapCell* child) { - if (child->next != NULL) { - child->next->prev = child->prev; + cell->size = size; + newCell = (void*)((u8*)cell + size); + newCell->size = leftoverSize; +#ifdef ENABLE_HEAPDESC + newCell->hd = 0; +#endif + newCell->prev = cell->prev; + newCell->next = cell->next; + if (newCell->next != NULL) { + newCell->next->prev = newCell; + } + if (newCell->prev != NULL) { + newCell->prev->next = newCell; + } else { + ASSERTMSGLINE(394, hd->free == cell, "OSAllocFromHeap(): heap is broken."); + hd->free = newCell; + } } - if (child->prev == NULL) { - return child->next; - } - - child->prev->next = child->next; - return list; + hd->allocated = DLAddFront(hd->allocated, cell); +#ifdef ENABLE_HEAPDESC + cell->hd = hd; + cell->requested = requested; + hd->headerBytes += 0x20; + hd->paddingBytes += (cell->size - (requested + 0x20)); + hd->payloadBytes += requested; +#endif + return (u8*)cell + 0x20; } -/* ############################################################################################## */ -/* 80451640-80451644 000B40 0004+00 3/3 0/0 0/0 .sbss HeapArray */ -static OSHeapDescriptor* HeapArray; - -/* 8033B124-8033B1A0 335A64 007C+00 0/0 1/1 0/0 .text OSFreeToHeap */ -void OSFreeToHeap(OSHeapHandle handle, void* ptr) { - OSHeapDescriptor* hd = &HeapArray[handle]; - OSHeapCell* cell = (OSHeapCell*)((char*)ptr - sizeof(OSHeapCell)); - hd->usedList = DLExtract(hd->usedList, cell); - hd->freeList = DLInsert(hd->freeList, cell); -} - -/* ############################################################################################## */ -/* 80450990-80450998 000410 0004+04 2/2 1/1 0/0 .sdata __OSCurrHeap */ -volatile s32 __OSCurrHeap = -1; - -/* 8033B1A0-8033B1B0 335AE0 0010+00 0/0 1/1 0/0 .text OSSetCurrentHeap */ -s32 OSSetCurrentHeap(OSHeapHandle handle) { - s32 old = __OSCurrHeap; - __OSCurrHeap = handle; - return old; -} - -/* ############################################################################################## */ -/* 80451644-80451648 000B44 0004+00 2/2 0/0 0/0 .sbss NumHeaps */ -static s32 NumHeaps; - -/* 80451648-8045164C 000B48 0004+00 1/1 0/0 0/0 .sbss ArenaStart */ -static void* ArenaStart; - -/* 8045164C-80451650 000B4C 0004+00 1/1 0/0 0/0 .sbss ArenaEnd */ -static void* ArenaEnd; - -/* 8033B1B0-8033B220 335AF0 0070+00 0/0 2/2 0/0 .text OSInitAlloc */ -void* OSInitAlloc(void* lo, void* hi, s32 maxHeaps) { - u32 totalSize = maxHeaps * sizeof(OSHeapDescriptor); +void* OSAllocFixed(void* rstart, void* rend) { int i; + Cell* cell; + Cell* newCell; + HeapDesc* hd; + void* start; + void* end; + void* cellEnd; - HeapArray = lo; + start = (void*)((*(u32*)rstart) & ~((32)-1)); + end = (void*)((*(u32*)rend + 0x1FU) & ~((32)-1)); + + ASSERTMSGLINE(436, HeapArray, "OSAllocFixed(): heap is not initialized."); + ASSERTMSGLINE(437, (u32)start < (u32)end, "OSAllocFixed(): invalid range."); + ASSERTMSGLINE(439, ((u32) ArenaStart <= (u32) start) && ((u32) end <= (u32) ArenaEnd), "OSAllocFixed(): invalid range."); + + for(i = 0; i < NumHeaps; i++) { + hd = &HeapArray[i]; + if(hd->size >= 0) { + if (DLOverlap(hd->allocated, start, end)) { +#if DEBUG + OSReport("OSAllocFixed: Warning - failed to allocate from %p to %p\n", start, end); +#endif + return NULL; + } + } + } + + for(i = 0; i < NumHeaps; i++) { + hd = &HeapArray[i]; + if (hd->size >= 0) { + for(cell = hd->free; cell; cell = cell->next) { + cellEnd = ((u8*)cell + cell->size); + if(cellEnd > start) { + if (end <= cell) { + break; + } + if ((char*)start-0x20 <= (char*)cell && cell < end && (start <= cellEnd) && (cellEnd < ((char*)end + 0x40))) { + if (cell < start) { + start = cell; + } + if (end < cellEnd) { + end = cellEnd; + } + hd->free = DLExtract(hd->free, cell); + hd->size -= cell->size; + } else if((char*)start-0x20 <= (char*)cell && cell < end) { + if (cell < start) { + start = cell; + } + ASSERTLINE(503, MINOBJSIZE <= (char*) cellEnd - (char*) end); + newCell = (Cell*)end; + + newCell->size = (s32) ((char*)cellEnd - (char*)end); +#ifdef ENABLE_HEAPDESC + newCell->hd = 0; +#endif + newCell->next = cell->next; + if (newCell->next) { + newCell->next->prev = newCell; + } + newCell->prev = cell->prev; + if (newCell->prev) { + newCell->prev->next = newCell; + } else { + hd->free = newCell; + } + hd->size -= ((char*)end - (char*)cell); + break; + } else { + if ((start <= cellEnd) && (cellEnd < ((char*)end + 0x40U))) { + if (end < cellEnd) { + end = cellEnd; + } + ASSERTLINE(528, MINOBJSIZE <= (char*) start - (char*) cell); + hd->size -= ((char*)cellEnd - (char*)start); + cell->size = ((char*)start - (char*)cell); + } else { + ASSERTLINE(535, MINOBJSIZE <= (char*) cellEnd - (char*) end); + newCell = (Cell*)end; + newCell->size = ((char*)cellEnd - (char*)end); +#ifdef ENABLE_HEAPDESC + newCell->hd = 0; +#endif + newCell->next = cell->next; + if (newCell->next) { + newCell->next->prev = newCell; + } + newCell->prev = cell; + cell->next = newCell; + cell->size = ((char*)start - (char*)cell); + hd->size -= ((char*)end - (char*)start); + break; + } + } + } + } + ASSERTLINE(550, 0 <= hd->size); + } + } + ASSERTLINE(553, OFFSET(start, ALIGNMENT) == 0); + ASSERTLINE(554, OFFSET(end, ALIGNMENT) == 0); + ASSERTLINE(555, start < end); + *(u32*)rstart = (u32)start; + *(u32*)rend = (u32)end; + return (void*)*(u32*)rstart; +} + +void OSFreeToHeap(int heap, void* ptr) { + HeapDesc* hd; + Cell* cell; + + ASSERTMSGLINE(577, HeapArray, "OSFreeToHeap(): heap is not initialized."); + ASSERTMSGLINE(579, ((u32)ArenaStart+0x20) <= (u32)ptr && (u32)ptr < (u32)ArenaEnd, "OSFreeToHeap(): invalid pointer."); + ASSERTMSGLINE(580, OFFSET(ptr, ALIGNMENT) == 0, "OSFreeToHeap(): invalid pointer."); + ASSERTMSGLINE(581, HeapArray[heap].size >= 0, "OSFreeToHeap(): invalid heap handle."); + cell = (void*)((u32)ptr-0x20); + hd = &HeapArray[heap]; + ASSERTMSGLINE(586, cell->hd == hd, "OSFreeToHeap(): invalid pointer."); + ASSERTMSGLINE(587, DLLookup(hd->allocated, cell), "OSFreeToHeap(): invalid pointer."); +#ifdef ENABLE_HEAPDESC + cell->hd = 0; + hd->headerBytes -= 0x20; + hd->paddingBytes -= (cell->size - (cell->requested + 0x20)); + hd->payloadBytes -= cell->requested; +#endif + hd->allocated = DLExtract(hd->allocated, cell); + hd->free = DLInsert(hd->free, cell); +} + +int OSSetCurrentHeap(int heap) { + int prev; + + ASSERTMSGLINE(619, HeapArray, "OSSetCurrentHeap(): heap is not initialized."); + ASSERTMSGLINE(620, (heap >= 0) && (heap < NumHeaps), "OSSetCurrentHeap(): invalid heap handle."); + ASSERTMSGLINE(621, HeapArray[heap].size >= 0, "OSSetCurrentHeap(): invalid heap handle."); + prev = __OSCurrHeap; + __OSCurrHeap = heap; + return prev; +} + +void* OSInitAlloc(void* arenaStart, void* arenaEnd, int maxHeaps) { + u32 arraySize; + int i; + HeapDesc* hd; + + ASSERTMSGLINE(647, maxHeaps > 0, "OSInitAlloc(): invalid number of heaps."); + ASSERTMSGLINE(649, (u32)arenaStart < (u32)arenaEnd, "OSInitAlloc(): invalid range."); + ASSERTMSGLINE(652, maxHeaps <= (((u32)arenaEnd - (u32)arenaStart) / 24U), "OSInitAlloc(): too small range."); + arraySize = maxHeaps * sizeof(HeapDesc); + HeapArray = arenaStart; NumHeaps = maxHeaps; - for (i = 0; i < NumHeaps; i++) { - OSHeapDescriptor* hd = &HeapArray[i]; + for(i = 0; i < NumHeaps; i++) { + hd = &HeapArray[i]; hd->size = -1; - - hd->freeList = hd->usedList = NULL; + hd->free = hd->allocated = 0; +#ifdef ENABLE_HEAPDESC + hd->paddingBytes = hd->headerBytes = hd->payloadBytes = 0; +#endif } - __OSCurrHeap = -1; - - lo = (u8*)HeapArray + totalSize; - lo = OSRoundUpPtr(lo, 0x20); - - ArenaStart = lo; - ArenaEnd = OSRoundDownPtr(hi, 0x20); - - return ArenaStart; + arenaStart = (void*) ((u32)((char*)HeapArray + arraySize)); + arenaStart = (void*) (((u32)arenaStart + 0x1F) & 0xFFFFFFE0); + ArenaStart = arenaStart; + ArenaEnd = (void*) ((u32)arenaEnd & 0xFFFFFFE0); + ASSERTMSGLINE(680, ((u32)ArenaEnd - (u32)ArenaStart) >= 0x40U, "OSInitAlloc(): too small range."); + return arenaStart; } -/* 8033B220-8033B28C 335B60 006C+00 0/0 1/1 0/0 .text OSCreateHeap */ -OSHeapHandle OSCreateHeap(void* start, void* end) { +int OSCreateHeap(void* start, void* end) { + int heap; + HeapDesc* hd; + Cell* cell; + + ASSERTMSGLINE(705, HeapArray, "OSCreateHeap(): heap is not initialized."); + ASSERTMSGLINE(706, (u32)start < (u32)end, "OSCreateHeap(): invalid range."); + + start = (void*)(((u32)start + 0x1FU) & ~((32)-1)); + end = (void*)(((u32)end) & ~((32)-1)); + + ASSERTMSGLINE(709, (u32)start < (u32)end, "OSCreateHeap(): invalid range."); + ASSERTMSGLINE(711, (u32)ArenaStart <= (u32)start && (u32)end <= (u32)ArenaEnd, "OSCreateHeap(): invalid range."); + ASSERTMSGLINE(713, ((u32)end - (u32)start) >= 0x40U, "OSCreateHeap(): too small range."); + +#if DEBUG + for(heap = 0; heap < NumHeaps; heap++) { + if (HeapArray[heap].size >= 0) { + ASSERTMSGLINE(723, !DLOverlap(HeapArray[heap].free, start, end), "OSCreateHeap(): invalid range."); + ASSERTMSGLINE(725, !DLOverlap(HeapArray[heap].allocated, start, end), "OSCreateHeap(): invalid range."); + } + } +#endif + + for(heap = 0; heap < NumHeaps; heap++) { + hd = &HeapArray[heap]; + if (hd->size < 0) { + hd->size = (u32)end - (u32)start; + cell = start; + cell->prev = 0; + cell->next = 0; + cell->size = hd->size; +#ifdef ENABLE_HEAPDESC + cell->hd = 0; +#endif + hd->free = cell; + hd->allocated = 0; +#ifdef ENABLE_HEAPDESC + hd->paddingBytes = hd->headerBytes = hd->payloadBytes = 0; +#endif + return heap; + } + } +#if DEBUG + OSReport("OSCreateHeap: Warning - Failed to find free heap descriptor."); +#endif + return -1; +} + +void OSDestroyHeap(int heap) { + HeapDesc* hd; + s32 size; + + ASSERTMSGLINE(782, HeapArray, "OSDestroyHeap(): heap is not initialized."); + ASSERTMSGLINE(783, (heap >= 0) && (heap < NumHeaps), "OSDestroyHeap(): invalid heap handle."); + ASSERTMSGLINE(784, HeapArray[heap].size >= 0, "OSDestroyHeap(): invalid heap handle."); + + hd = &HeapArray[heap]; +#if DEBUG + size = DLSize(hd->free); + + if (hd->size != size) { + OSReport("OSDestroyHeap(%d): Warning - free list size %d, heap size %d\n", heap, size, hd->size); + } +#endif + + hd->size = -1; + hd->free = hd->allocated = 0; +#ifdef ENABLE_HEAPDESC + hd->paddingBytes = hd->headerBytes = hd->payloadBytes = 0; + if (__OSCurrHeap == heap) { + __OSCurrHeap = -1; + } +#endif +} + +void OSAddToHeap(int heap, void* start, void* end) { + HeapDesc* hd; + Cell* cell; int i; - OSHeapCell* cell = OSRoundUpPtr(start, 0x20); - end = OSRoundDownPtr(end, 0x20); - for (i = 0; i < NumHeaps; i++) { - OSHeapDescriptor* hd = &HeapArray[i]; + ASSERTMSGLINE(830, HeapArray, "OSAddToHeap(): heap is not initialized."); + ASSERTMSGLINE(831, (heap >= 0) && (heap < NumHeaps), "OSAddToHeap(): invalid heap handle."); + ASSERTMSGLINE(832, HeapArray[heap].size >= 0, "OSAddToHeap(): invalid heap handle."); - if (hd->size < 0) { - hd->size = (u8*)end - (u8*)cell; - cell->prev = NULL; - cell->next = NULL; - cell->size = hd->size; - hd->freeList = cell; - hd->usedList = NULL; - return i; - } - } + hd = &HeapArray[heap]; - return -1; -} \ No newline at end of file + ASSERTMSGLINE(836, (u32)start < (u32)end, "OSAddToHeap(): invalid range."); + + start = (void*)(((u32)start + 0x1F) & ~((32)-1)); + end = (void*)(((u32)end) & ~((32)-1)); + + ASSERTMSGLINE(840, ((u32)end - (u32)start) >= 0x40U, "OSAddToHeap(): too small range."); + ASSERTMSGLINE(842, (u32)ArenaStart <= (u32)start && (u32)end <= (u32)ArenaEnd, "OSAddToHeap(): invalid range."); + +#if DEBUG + for(i = 0; i < NumHeaps; i++) { + if (HeapArray[i].size >= 0) { + ASSERTMSGLINE(852, !DLOverlap(HeapArray[i].free, start, end), "OSAddToHeap(): invalid range."); + ASSERTMSGLINE(854, !DLOverlap(HeapArray[i].allocated, start, end), "OSAddToHeap(): invalid range."); + } + } +#endif + cell = (Cell*)start; + cell->size = ((char*)end - (char*)start); +#ifdef ENABLE_HEAPDESC + cell->hd = 0; +#endif + hd->size += cell->size; + hd->free = DLInsert(hd->free, cell); +} + +// custom macro for OSCheckHeap +#define ASSERTREPORT(line, cond) \ + if (!(cond)) { OSReport("OSCheckHeap: Failed " #cond " in %d", line); return -1; } + +s32 OSCheckHeap(int heap) { + HeapDesc* hd; + Cell* cell; + s32 total = 0; + s32 free = 0; + + ASSERTREPORT(898, HeapArray); + ASSERTREPORT(899, 0 <= heap && heap < NumHeaps); + hd = &HeapArray[heap]; + ASSERTREPORT(902, 0 <= hd->size); + + ASSERTREPORT(0x388, hd->allocated == NULL || hd->allocated->prev == NULL); + + for(cell = hd->allocated; cell; cell = cell->next) { + ASSERTREPORT(907, InRange(cell, ArenaStart, ArenaEnd)); + ASSERTREPORT(908, OFFSET(cell, ALIGNMENT) == 0); + ASSERTREPORT(909, cell->next == NULL || cell->next->prev == cell); + ASSERTREPORT(910, MINOBJSIZE <= cell->size); + ASSERTREPORT(911, OFFSET(cell->size, ALIGNMENT) == 0); + total += cell->size; + ASSERTREPORT(914, 0 < total && total <= hd->size); +#ifdef ENABLE_HEAPDESC + ASSERTREPORT(917, cell->hd == hd); + ASSERTREPORT(918, HEADERSIZE + cell->requested <= cell->size); +#endif + } + + + ASSERTREPORT(922, hd->free == NULL || hd->free->prev == NULL); + + for(cell = hd->free; cell; cell = cell->next) { + ASSERTREPORT(925, InRange(cell, ArenaStart, ArenaEnd)); + ASSERTREPORT(926, OFFSET(cell, ALIGNMENT) == 0); + ASSERTREPORT(927, cell->next == NULL || cell->next->prev == cell); + ASSERTREPORT(928, MINOBJSIZE <= cell->size); + ASSERTREPORT(929, OFFSET(cell->size, ALIGNMENT) == 0); + ASSERTREPORT(930, cell->next == NULL || (char*) cell + cell->size < (char*) cell->next); + total += cell->size; + free = (cell->size + free); + free -= HEADERSIZE; + ASSERTREPORT(934, 0 < total && total <= hd->size); +#ifdef ENABLE_HEAPDESC + ASSERTREPORT(937, cell->hd == NULL); +#endif + } + ASSERTREPORT(941, total == hd->size); + return free; +} + +u32 OSReferentSize(void* ptr) { + Cell* cell; + + ASSERTMSGLINE(960, HeapArray, "OSReferentSize(): heap is not initialized."); + ASSERTMSGLINE(962, InRange(ptr, ArenaStart+HEADERSIZE, ArenaEnd), "OSReferentSize(): invalid pointer."); + ASSERTMSGLINE(963, !OFFSET(ptr, 32), "OSReferentSize(): invalid pointer."); + cell = (void*)((u32)ptr-HEADERSIZE); + ASSERTMSGLINE(967, cell->hd, "OSReferentSize(): invalid pointer."); + ASSERTMSGLINE(969, !(((u32)cell->hd - (u32)HeapArray) % 24), "OSReferentSize(): invalid pointer."); + ASSERTMSGLINE(971, ((u32)HeapArray <= (u32)cell->hd) && ((u32)cell->hd < (u32)((u32)HeapArray + (NumHeaps * 0x18))), "OSReferentSize(): invalid pointer."); + ASSERTMSGLINE(972, cell->hd->size >= 0, "OSReferentSize(): invalid pointer."); + ASSERTMSGLINE(974, DLLookup(cell->hd->allocated, cell), "OSReferentSize(): invalid pointer."); + return (s32)((u32)cell->size-HEADERSIZE); +} + +void OSDumpHeap(int heap) { + HeapDesc* hd; + Cell* cell; + + OSReport("\nOSDumpHeap(%d):\n", heap); + ASSERTMSGLINE(995, HeapArray, "OSDumpHeap(): heap is not initialized."); + ASSERTMSGLINE(996, (heap >= 0) && (heap < NumHeaps), "OSDumpHeap(): invalid heap handle."); + hd = &HeapArray[heap]; + if (hd->size < 0) { + OSReport("--------Inactive\n"); + return; + } + ASSERTMSGLINE(1005, OSCheckHeap(heap) >= 0, "OSDumpHeap(): heap is broken."); +#ifdef ENABLE_HEAPDESC + OSReport("padding %d/(%f%%) header %d/(%f%%) payload %d/(%f%%)\n", + hd->paddingBytes, (100.0 * hd->paddingBytes / hd->size), hd->headerBytes, (100.0 * hd->headerBytes / hd->size), hd->payloadBytes, + (100.0 * hd->payloadBytes / hd->size)); +#endif + OSReport("addr size end prev next\n"); + OSReport("--------Allocated\n"); + + ASSERTMSGLINE(1018, hd->allocated == NULL || hd->allocated->prev == NULL, "OSDumpHeap(): heap is broken."); + + for(cell = hd->allocated; cell; cell = cell->next) { + OSReport("%x %d %x %x %x\n", cell, cell->size, (char*)cell + cell->size, cell->prev, cell->next); + } + OSReport("--------Free\n"); + for(cell = hd->free; cell; cell = cell->next) { + OSReport("%x %d %x %x %x\n", cell, cell->size, (char*)cell + cell->size, cell->prev, cell->next); + } +} + +void OSVisitAllocated(void (*visitor)(void*, u32)) { + u32 heap; + Cell* cell; + + for(heap = 0; heap < NumHeaps; heap++) { + if (HeapArray[heap].size >= 0) { + for(cell = HeapArray[heap].allocated; cell; cell = cell->next) { + visitor((char*)cell+HEADERSIZE, cell->size); + } + } + } +} diff --git a/src/dolphin/os/OSArena.c b/src/dolphin/os/OSArena.c index 1defd3d594..ab7b5feeab 100644 --- a/src/dolphin/os/OSArena.c +++ b/src/dolphin/os/OSArena.c @@ -1,38 +1,52 @@ -#include "dolphin/os/OSArena.h" -#include "dolphin/os/OSAlloc.h" +#include +#include + +#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) +#define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) -/* 80451650-80451658 000B50 0004+04 2/1 0/0 0/0 .sbss __OSArenaHi */ static void* __OSArenaHi; +static void* __OSArenaLo = (void*)-1; -/* 8033B28C-8033B294 -00001 0008+00 0/0 0/0 0/0 .text OSGetArenaHi */ void* OSGetArenaHi(void) { + ASSERTMSGLINE(55, (u32)__OSArenaLo != -1, "OSGetArenaHi(): OSInit() must be called in advance."); + ASSERTMSGLINE(57, (u32)__OSArenaLo <= (u32)__OSArenaHi, "OSGetArenaHi(): invalid arena (hi < lo)."); return __OSArenaHi; } -/* 80450998-804509A0 000418 0004+04 3/2 0/0 0/0 .sdata __OSArenaLo */ -static void* __OSArenaLo = (void*)0xFFFFFFFF; - -/* 8033B294-8033B29C -00001 0008+00 0/0 0/0 0/0 .text OSGetArenaLo */ void* OSGetArenaLo(void) { + ASSERTMSGLINE(73, (u32)__OSArenaLo != -1, "OSGetArenaLo(): OSInit() must be called in advance."); + ASSERTMSGLINE(75, (u32)__OSArenaLo <= (u32)__OSArenaHi, "OSGetArenaLo(): invalid arena (hi < lo)."); return __OSArenaLo; } -/* 8033B29C-8033B2A4 335BDC 0008+00 0/0 5/5 0/0 .text OSSetArenaHi */ -void OSSetArenaHi(void* hi) { - __OSArenaHi = hi; +void OSSetArenaHi(void* newHi) { + __OSArenaHi = newHi; } -/* 8033B2A4-8033B2AC 335BE4 0008+00 0/0 5/5 0/0 .text OSSetArenaLo */ -void OSSetArenaLo(void* lo) { - __OSArenaLo = lo; +void OSSetArenaLo(void* newLo) { + __OSArenaLo = newLo; } -/* 8033B2AC-8033B2D8 335BEC 002C+00 0/0 4/4 0/0 .text OSAllocFromArenaLo */ -void* OSAllocFromArenaLo(u32 size, s32 alignment) { - u8* blk_start = OSRoundUpPtr(__OSArenaLo, alignment); - u8* blk_end = blk_start + size; - blk_end = OSRoundUpPtr(blk_end, alignment); +void* OSAllocFromArenaLo(u32 size, u32 align) { + void* ptr; + u8* arenaLo; - __OSArenaLo = blk_end; - return blk_start; -} \ No newline at end of file + ptr = OSGetArenaLo(); + arenaLo = ptr = (void*)ROUND(ptr, align); + arenaLo += size; + arenaLo = (u8*)ROUND(arenaLo, align); + OSSetArenaLo(arenaLo); + return ptr; +} + +void* OSAllocFromArenaHi(u32 size, u32 align) { + void* ptr; + u8* arenaHi; + + arenaHi = OSGetArenaHi(); + arenaHi = (u8*)TRUNC(arenaHi, align); + arenaHi -= size; + arenaHi = ptr = (void*)TRUNC(arenaHi, align); + OSSetArenaHi(arenaHi); + return ptr; +} diff --git a/src/dolphin/os/OSAudioSystem.c b/src/dolphin/os/OSAudioSystem.c index 3a02b6bd12..3ffd4403e2 100644 --- a/src/dolphin/os/OSAudioSystem.c +++ b/src/dolphin/os/OSAudioSystem.c @@ -1,8 +1,8 @@ -#include "dolphin/os/OSAudioSystem.h" -#include "dolphin/dsp.h" -#include "string.h" +#include +#include + +#include "__os.h" -/* 803CF490-803CF510 02C5B0 0080+00 1/1 0/0 0/0 .data DSPInitCode */ static u8 DSPInitCode[128] = { 0x02, 0x9F, 0x00, 0x10, 0x02, 0x9F, 0x00, 0x33, 0x02, 0x9F, 0x00, 0x34, 0x02, 0x9F, 0x00, 0x35, 0x02, 0x9F, 0x00, 0x36, 0x02, 0x9F, 0x00, 0x37, 0x02, 0x9F, 0x00, 0x38, 0x02, 0x9F, 0x00, 0x39, @@ -11,98 +11,107 @@ static u8 DSPInitCode[128] = { 0x00, 0x44, 0x1B, 0x1E, 0x00, 0x84, 0x08, 0x00, 0x00, 0x64, 0x00, 0x27, 0x19, 0x1E, 0x00, 0x00, 0x00, 0xDE, 0xFF, 0xFC, 0x02, 0xA0, 0x80, 0x00, 0x02, 0x9C, 0x00, 0x28, 0x16, 0xFC, 0x00, 0x54, 0x16, 0xFD, 0x43, 0x48, 0x00, 0x21, 0x02, 0xFF, 0x02, 0xFF, 0x02, 0xFF, 0x02, 0xFF, 0x02, 0xFF, - 0x02, 0xFF, 0x02, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0xFF, 0x02, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; #define __DSPWorkBuffer (void*)0x81000000 -/* 8033B2D8-8033B494 335C18 01BC+00 0/0 1/1 0/0 .text __OSInitAudioSystem */ void __OSInitAudioSystem(void) { - u32 r28; - u16 r3; + u8 errFlag; + u16 reg16; + u32 start_tick; - u32 padding; - - memcpy((void*)((u8*)OSGetArenaHi() - 128), __DSPWorkBuffer, 128); - memcpy(__DSPWorkBuffer, (void*)DSPInitCode, 128); - - DCFlushRange(__DSPWorkBuffer, 128); + memcpy((void*)((u32)OSGetArenaHi() - 0x80), __DSPWorkBuffer, sizeof(DSPInitCode)); + memcpy(__DSPWorkBuffer, (void*)DSPInitCode, sizeof(DSPInitCode)); + DCFlushRange(__DSPWorkBuffer, sizeof(DSPInitCode)); __DSPRegs[9] = 0x43; + ASSERTMSGLINE(113, !(__DSPRegs[5] & 0x200), "__OSInitAudioSystem(): ARAM DMA already in progress"); + ASSERTMSGLINE(117, !(__DSPRegs[5] & 0x400), "__OSInitAudioSystem(): DSP DMA already in progress"); + ASSERTMSGLINE(121, (__DSPRegs[5] & 0x004), "__OSInitAudioSystem(): DSP already working"); + __DSPRegs[5] = 0x8AC; __DSPRegs[5] |= 1; - while (__DSPRegs[5] & 1) - ; - __DSPRegs[0] = 0; - while (((__DSPRegs[2] << 16) | __DSPRegs[3]) & 0x80000000) - ; - *(u32*)&__DSPRegs[16] = 0x1000000; - *(u32*)&__DSPRegs[18] = 0; - *(u32*)&__DSPRegs[20] = 0x20; - r3 = __DSPRegs[5]; - while (!(r3 & 0x20)) - r3 = __DSPRegs[5]; - __DSPRegs[5] = r3; + while (__DSPRegs[5] & 1); + __DSPRegs[0] = 0; - r28 = OSGetTick(); - while ((s32)(OSGetTick() - r28) < 0x892) - ; + while (((__DSPRegs[2] << 16) | __DSPRegs[3]) & 0x80000000); *(u32*)&__DSPRegs[16] = 0x1000000; *(u32*)&__DSPRegs[18] = 0; *(u32*)&__DSPRegs[20] = 0x20; - r3 = __DSPRegs[5]; - while (!(r3 & 0x20)) - r3 = __DSPRegs[5]; - __DSPRegs[5] = r3; + reg16 = __DSPRegs[5]; + while (!(reg16 & 0x20)) + reg16 = __DSPRegs[5]; + + __DSPRegs[5] = reg16; + + start_tick = OSGetTick(); + while ((s32)(OSGetTick() - start_tick) < 0x892); + + *(u32*)&__DSPRegs[16] = 0x1000000; + *(u32*)&__DSPRegs[18] = 0; + *(u32*)&__DSPRegs[20] = 0x20; + + reg16 = __DSPRegs[5]; + while (!(reg16 & 0x20)) { + reg16 = __DSPRegs[5]; + } + __DSPRegs[5] = reg16; __DSPRegs[5] &= ~0x800; - while ((__DSPRegs[5]) & 0x400) - ; + while ((__DSPRegs[5]) & 0x400); + __DSPRegs[5] &= ~4; + errFlag = 0; - r3 = __DSPRegs[2]; + reg16 = __DSPRegs[2]; - while (!(r3 & 0x8000)) - r3 = __DSPRegs[2]; + while (!(reg16 & 0x8000)) { + reg16 = __DSPRegs[2]; + } - (void)__DSPRegs[3]; - r3 != 42069; + if(((u32)((reg16 << 16) | __DSPRegs[3]) + 0x7FAC0000U) != 0x4348) { + ASSERTMSGLINE(193, 0, "__OSInitAudioSystem(): DSP returns invalid message"); + } + + reg16 != 0x81800; // fake but fixes reg alloc on retail __DSPRegs[5] |= 4; __DSPRegs[5] = 0x8AC; __DSPRegs[5] |= 1; - while (__DSPRegs[5] & 1) - ; - memcpy(__DSPWorkBuffer, (void*)((u8*)OSGetArenaHi() - 128), 128); + while (__DSPRegs[5] & 1); + + memcpy(__DSPWorkBuffer, (void*)((u32)OSGetArenaHi() - 0x80), sizeof(DSPInitCode)); } -/* 8033B494-8033B56C 335DD4 00D8+00 0/0 1/1 0/0 .text __OSStopAudioSystem */ void __OSStopAudioSystem(void) { - u32 r28; + u16 reg16; + u32 start_tick; -#define waitUntil(load, mask) \ - r28 = (load); \ - while (r28 & (mask)) { \ - r28 = (load); \ - } + #define waitUntil(load, mask) \ + reg16 = (load); \ + while (reg16 & (mask)) { \ + reg16 = (load); \ + } __DSPRegs[5] = 0x804; - r28 = __DSPRegs[27]; - __DSPRegs[27] = r28 & ~0x8000; + reg16 = __DSPRegs[27]; + __DSPRegs[27] = reg16 & ~0x8000; waitUntil(__DSPRegs[5], 0x400); waitUntil(__DSPRegs[5], 0x200); __DSPRegs[5] = 0x8ac; __DSPRegs[0] = 0; - while (((__DSPRegs[2] << 16) | __DSPRegs[3]) & 0x80000000) - ; - r28 = OSGetTick(); - while ((s32)(OSGetTick() - r28) < 0x2c) - ; - __DSPRegs[5] |= 1; + while (((__DSPRegs[2] << 16) | __DSPRegs[3]) & 0x80000000); + + start_tick = OSGetTick(); + while ((s32)(OSGetTick() - start_tick) < 0x2c); + + reg16 = __DSPRegs[5]; + __DSPRegs[5] = reg16 | 1; waitUntil(__DSPRegs[5], 0x001); -#undef waitUntil -} \ No newline at end of file + #undef waitUntil +} diff --git a/src/dolphin/os/OSCache.c b/src/dolphin/os/OSCache.c index 551ee8f8ff..b09cfbb1c9 100644 --- a/src/dolphin/os/OSCache.c +++ b/src/dolphin/os/OSCache.c @@ -1,266 +1,336 @@ -#include "dolphin/os/OSCache.h" -#include "dolphin/base/PPCArch.h" -#include "dolphin/db.h" -#include "dolphin/os.h" +#include +#include +#include -/* 8033B56C-8033B580 335EAC 0014+00 1/1 0/0 0/0 .text DCEnable */ -static asm void DCEnable(void) { - // clang-format off +#include "__os.h" + +#define HID2 920 + +// prototypes +void DMAErrorHandler(OSError error, OSContext* context, ...); + +#ifdef __GEKKO__ +asm void DCFlashInvalidate(void) { nofralloc + mfspr r3, HID0 + ori r3, r3, 0x400 + mtspr HID0, r3 + blr +} +asm void DCEnable(void) { + nofralloc sync - mfspr r3, 0x3F0 - ori r3, r3, 0x4000 - mtspr 0x3F0, r3 - + mfspr r3, HID0 + ori r3, r3, 0x4000 + mtspr HID0, r3 blr - // clang-format on } -/* 8033B580-8033B5AC 335EC0 002C+00 0/0 30/30 1/1 .text DCInvalidateRange */ -asm void DCInvalidateRange(register void* start, register u32 nBytes) { - // clang-format off +asm void DCDisable(void) { nofralloc + sync + mfspr r3, HID0 + rlwinm r3, r3, 0, 18, 16 + mtspr HID0, r3 + blr +} +asm void DCFreeze(void) { + nofralloc + sync + mfspr r3, HID0 + ori r3, r3, 0x1000 + mtspr HID0, r3 + blr +} + +asm void DCUnfreeze(void) { + nofralloc + mfspr r3, HID0 + rlwinm r3, r3, 0, 20, 18 + mtspr HID0, r3 + blr +} + +asm void DCTouchLoad(register void* addr) { + nofralloc + dcbt r0, addr + blr +} + +asm void DCBlockZero(register void* addr) { + nofralloc + dcbz r0, addr + blr +} + +asm void DCBlockStore(register void* addr) { + nofralloc + dcbst r0, addr + blr +} + +asm void DCBlockFlush(register void* addr) { + nofralloc + dcbf r0, addr + blr +} + +asm void DCBlockInvalidate(register void* addr) { + nofralloc + dcbi r0, addr + blr +} + +asm void DCInvalidateRange(register void* addr, register u32 nBytes) { + nofralloc cmplwi nBytes, 0 blelr + clrlwi r5, addr, 27 + add nBytes, nBytes, r5 + addi nBytes, nBytes, 31 + srwi nBytes, nBytes, 5 + mtctr nBytes - clrlwi r5, start, 0x1B +@1 + dcbi r0, addr + addi addr, addr, 32 + bdnz @1 + blr +} + +asm void DCFlushRange(register void* addr, register u32 nBytes) { + nofralloc + cmplwi nBytes, 0 + blelr + clrlwi r5, addr, 27 add nBytes, nBytes, r5 - addi nBytes, nBytes, 0x1F + addi nBytes, nBytes, 31 srwi nBytes, nBytes, 5 mtctr nBytes -do_invalidate: - dcbi 0, start - addi start, start, 0x20 - bdnz do_invalidate - +@1 + dcbf r0, addr + addi addr, addr, 32 + bdnz @1 + sc blr - // clang-format on } -/* 8033B5AC-8033B5DC 335EEC 0030+00 0/0 11/11 0/0 .text DCFlushRange */ -asm void DCFlushRange(register void* start, register u32 nBytes) { - // clang-format off +asm void DCStoreRange(register void* addr, register u32 nBytes) { nofralloc - cmplwi nBytes, 0 blelr - - clrlwi r5, start, 0x1B + clrlwi r5, addr, 27 add nBytes, nBytes, r5 - addi nBytes, nBytes, 0x1F + addi nBytes, nBytes, 31 srwi nBytes, nBytes, 5 mtctr nBytes -do_flush: - dcbf 0, start - addi start, start, 0x20 - bdnz do_flush +@1 + dcbst r0, addr + addi addr, addr, 32 + bdnz @1 sc blr - // clang-format on } -/* 8033B5DC-8033B60C 335F1C 0030+00 0/0 54/54 1/1 .text DCStoreRange */ -asm void DCStoreRange(register void* start, register u32 nBytes) { - // clang-format off +asm void DCFlushRangeNoSync(register void* addr, register u32 nBytes) { nofralloc - cmplwi nBytes, 0 blelr - - clrlwi r5, start, 0x1B + clrlwi r5, addr, 27 add nBytes, nBytes, r5 - addi nBytes, nBytes, 0x1F + addi nBytes, nBytes, 31 srwi nBytes, nBytes, 5 mtctr nBytes -do_store: - dcbst 0, start - addi start, start, 0x20 - bdnz do_store - sc +@1 + dcbf r0, addr + addi addr, addr, 32 + bdnz @1 + blr +} + +asm void DCStoreRangeNoSync(register void* addr, register u32 nBytes) { + nofralloc + cmplwi nBytes, 0 + blelr + clrlwi r5, addr, 27 + add nBytes, nBytes, r5 + addi nBytes, nBytes, 31 + srwi nBytes, nBytes, 5 + mtctr nBytes + +@1 + dcbst r0, addr + addi addr, addr, 32 + bdnz @1 blr - // clang-format on } -/* 8033B60C-8033B638 335F4C 002C+00 0/0 2/2 0/0 .text DCFlushRangeNoSync */ -asm void DCFlushRangeNoSync(register void* start, register u32 nBytes) { - // clang-format off - nofralloc +asm void DCZeroRange(register void* addr, register u32 nBytes) { + nofralloc + cmplwi nBytes, 0 + blelr + clrlwi r5, addr, 27 + add nBytes, nBytes, r5 + addi nBytes, nBytes, 31 + srwi nBytes, nBytes, 5 + mtctr nBytes +@1 + dcbz r0, addr + addi addr, addr, 32 + bdnz @1 + + blr +} + +asm void DCTouchRange(register void* addr, register u32 nBytes) { + nofralloc cmplwi nBytes, 0 blelr - - clrlwi r5, start, 0x1B + clrlwi r5, addr, 27 add nBytes, nBytes, r5 - addi nBytes, nBytes, 0x1F + addi nBytes, nBytes, 31 srwi nBytes, nBytes, 5 mtctr nBytes -do_flush: - dcbf 0, start - addi start, start, 0x20 - bdnz do_flush +@1 + dcbt r0, addr + addi addr, addr, 32 + bdnz @1 blr - // clang-format on } -/* 8033B638-8033B664 335F78 002C+00 0/0 13/13 3/3 .text DCStoreRangeNoSync */ -asm void DCStoreRangeNoSync(register void* start, register u32 nBytes) { - // clang-format off +asm void ICInvalidateRange(register void* addr, register u32 nBytes) { nofralloc - cmplwi nBytes, 0 blelr - - clrlwi r5, start, 0x1B + clrlwi r5, addr, 27 add nBytes, nBytes, r5 - addi nBytes, nBytes, 0x1F + addi nBytes, nBytes, 31 srwi nBytes, nBytes, 5 mtctr nBytes -do_store: - dcbst 0, start - addi start, start, 0x20 - bdnz do_store - - blr - // clang-format on -} - -/* 8033B664-8033B690 335FA4 002C+00 0/0 1/1 1/1 .text DCZeroRange */ -asm void DCZeroRange(register void* start, register u32 nBytes) { - // clang-format off - nofralloc - - cmplwi nBytes, 0 - blelr - - clrlwi r5, start, 0x1B - add nBytes, nBytes, r5 - addi nBytes, nBytes, 0x1F - srwi nBytes, nBytes, 5 - mtctr nBytes - -do_zero: - dcbz 0, start - addi start, start, 0x20 - bdnz do_zero - - blr - // clang-format on -} - -/* 8033B690-8033B6C4 335FD0 0034+00 0/0 6/6 0/0 .text ICInvalidateRange */ -asm void ICInvalidateRange(register void* start, register u32 nBytes) { - // clang-format off - nofralloc - - cmplwi nBytes, 0 - blelr - - clrlwi r5, start, 0x1B - add nBytes, nBytes, r5 - addi nBytes, nBytes, 0x1F - srwi nBytes, nBytes, 5 - mtctr nBytes - -do_invalidate: - icbi 0, start - addi start, start, 0x20 - bdnz do_invalidate - +@1 + icbi r0, addr + addi addr, addr, 32 + bdnz @1 sync isync blr - // clang-format on } -/* 8033B6C4-8033B6D4 336004 0010+00 0/0 5/5 0/0 .text ICFlashInvalidate */ asm void ICFlashInvalidate(void) { - // clang-format off nofralloc - - mfspr r3, 0x3F0 + mfspr r3, HID0 ori r3, r3, 0x800 - mtspr 0x3F0, r3 - + mtspr HID0, r3 blr - // clang-format on } -/* 8033B6D4-8033B6E8 336014 0014+00 1/1 0/0 0/0 .text ICEnable */ -static asm void ICEnable(void) { - // clang-format off +asm void ICEnable(void) { nofralloc - isync - mfspr r3, 0x3F0 + mfspr r3, HID0 ori r3, r3, 0x8000 - mtspr 0x3F0, r3 - + mtspr HID0, r3 blr - // clang-format on } -/* 8033B6E8-8033B7B4 336028 00CC+00 1/1 0/0 0/0 .text __LCEnable */ -asm void __LCEnable(void) { - // clang-format off +asm void ICDisable(void) { nofralloc - - mfmsr r5 - ori r5, r5, 0x1000 - mtmsr r5 - - lis r3, 0x8000 - li r4, 0x400 - mtctr r4 - -do_store: - dcbt 0, r3 - dcbst 0, r3 - addi r3, r3, 0x20 - bdnz do_store - - mfspr r4, 0x398 - oris r4, r4, 0x100F - mtspr 0x398, r4 - - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - - lis r3, 0xE000 - ori r3, r3, 0x0002 - mtdbatl 3, r3 - ori r3, r3, 0x1FE - mtdbatu 3, r3 isync + mfspr r3, HID0 + rlwinm r3, r3, 0, 17, 15 + mtspr HID0, r3 + blr +} - lis r3, 0xE000 - li r6, 0x200 - mtctr r6 - li r6, 0 -do_load: - dcbz_l r6, r3 - addi r3, r3, 0x0020 - bdnz do_load +asm void ICFreeze(void) { + nofralloc + isync + mfspr r3, HID0 + ori r3, r3, 0x2000 + mtspr HID0, r3 + blr +} + +asm void ICUnfreeze(void) { + nofralloc + mfspr r3, HID0 + rlwinm r3, r3, 0, 19, 17 + mtspr HID0, r3 + blr +} + +asm void ICBlockInvalidate(register void* addr) { + nofralloc + icbi r0, addr + blr +} + +asm void ICSync(void) { + nofralloc + isync + blr +} + +#define LC_LINES 512 +#define CACHE_LINES 1024 + +static asm void __LCEnable(void) { + nofralloc + mfmsr r5 + ori r5, r5, 0x1000 + mtmsr r5 + + lis r3, OS_CACHED_REGION_PREFIX + li r4, CACHE_LINES + mtctr r4 +_touchloop: + dcbt 0,r3 + dcbst 0,r3 + addi r3,r3,32 + bdnz _touchloop + mfspr r4, HID2 + oris r4, r4, 0x100F + mtspr HID2, r4 + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + lis r3, LC_BASE_PREFIX + ori r3, r3, 0x0002 + mtspr DBAT3L, r3 + ori r3, r3, 0x01fe + mtspr DBAT3U, r3 + isync + lis r3, LC_BASE_PREFIX + li r6, LC_LINES + mtctr r6 + li r6, 0 + +_lockloop: + dcbz_l r6, r3 + addi r3, r3, 32 + bdnz+ _lockloop nop nop @@ -276,115 +346,253 @@ do_load: nop blr - // clang-format on } -/* 8033B7B4-8033B7EC 3360F4 0038+00 0/0 0/0 1/1 .text LCEnable */ void LCEnable(void) { - BOOL interrupt = OSDisableInterrupts(); + BOOL enabled; + + enabled = OSDisableInterrupts(); __LCEnable(); - OSRestoreInterrupts(interrupt); + OSRestoreInterrupts(enabled); } -/* 8033B7EC-8033B814 33612C 0028+00 0/0 2/2 1/1 .text LCDisable */ asm void LCDisable(void) { - // clang-format off nofralloc - - lis r3, 0xE000 - li r4, 0x200 + lis r3, LC_BASE_PREFIX + li r4, LC_LINES mtctr r4 -do_invalidate: - dcbi 0, r3 - addi r3, r3, 0x20 - bdnz do_invalidate - - mfspr r4, 0x398 +@1 + dcbi r0, r3 + addi r3, r3, 32 + bdnz @1 + mfspr r4, HID2 rlwinm r4, r4, 0, 4, 2 - mtspr 0x398, r4 - + mtspr HID2, r4 blr - // clang-format on } -/* 8033B814-8033B838 336154 0024+00 1/1 0/0 0/0 .text LCStoreBlocks */ -static asm void LCStoreBlocks(register void* destAddr, register void* srcAddr, - register u32 blockNum){ - // clang-format off +asm void LCAllocOneTag(register BOOL invalidate, register void* tag) { nofralloc - - rlwinm r6, blockNum, 0x1E, 0x1B, 0x1F - clrlwi destAddr, destAddr, 4 - or r6, r6, destAddr - mtspr 0x39A, r6 - rlwinm r6, blockNum, 2, 0x1C, 0x1D - or r6, r6, srcAddr - ori r6, r6, 2 - mtspr 0x39B, r6 - + cmpwi invalidate, 0 + beq @1 + dcbi r0, tag +@1 + dcbz_l r0, tag blr - // clang-format on -} /* 8033B838-8033B8E4 336178 00AC+00 0/0 0/0 3/3 .text LCStoreData */ -u32 LCStoreData(void* destAddr, void* srcAddr, u32 nBytes) { - u32 blocks = (nBytes + 31) / 32; - u32 ret = (blocks + 127) / 128; +} - while (blocks > 0) { - if (blocks < 128) { - LCStoreBlocks(destAddr, srcAddr, blocks); - blocks = 0; +asm void LCAllocTags(register BOOL invalidate, register void* startTag, register u32 numBlocks) { + nofralloc + mflr r6 + cmplwi numBlocks, 0 + ble @3 + mtctr numBlocks + cmpwi invalidate, 0 + beq @2 +@1 + dcbi r0, startTag + dcbz_l r0, startTag + addi startTag, startTag, 32 + bdnz @1 + b @3 +@2 + dcbz_l r0, startTag + addi startTag, startTag, 32 + bdnz @2 +@3 + mtlr r6 + blr +} + +asm void LCLoadBlocks(register void* destTag, register void* srcAddr, register u32 numBlocks) { + nofralloc + rlwinm r6, numBlocks, 30, 27, 31 + rlwinm srcAddr, srcAddr, 0, 4, 31 + or r6, r6, srcAddr + mtspr DMA_U, r6 + rlwinm r6, numBlocks, 2, 28, 29 + or r6, r6, destTag + ori r6, r6, 0x12 + mtspr DMA_L, r6 + blr +} + +asm void LCStoreBlocks(register void* destAddr, register void* srcTag, register u32 numBlocks) { + nofralloc + rlwinm r6, numBlocks, 30, 27, 31 + rlwinm destAddr, destAddr, 0, 4, 31 + or r6, r6, destAddr + mtspr DMA_U, r6 + rlwinm r6, numBlocks, 2, 28, 29 + or r6, r6, srcTag + ori r6, r6, 0x2 + mtspr DMA_L, r6 + blr +} +#endif + +void LCAlloc(void* addr, u32 nBytes) { + u32 numBlocks = nBytes >> 5; + u32 hid2 = PPCMfhid2(); + + ASSERTMSGLINE(1319, !((u32)addr & 31), "LCAlloc(): addr must be 32 byte aligned"); + ASSERTMSGLINE(1321, !((u32)nBytes & 31), "LCAlloc(): nBytes must be 32 byte aligned"); + + if ((hid2 & 0x10000000) == 0) { + LCEnable(); + } + LCAllocTags(TRUE, addr, numBlocks); +} + +void LCAllocNoInvalidate(void* addr, u32 nBytes) { + u32 numBlocks = nBytes >> 5; + u32 hid2 = PPCMfhid2(); + + ASSERTMSGLINE(1366, !((u32)addr & 31), "LCAllocNoFlush(): addr must be 32 byte aligned"); + ASSERTMSGLINE(1368, !((u32)nBytes & 31), "LCAllocNoFlush(): nBytes must be 32 byte aligned"); + + if ((hid2 & 0x10000000) == 0) { + LCEnable(); + } + LCAllocTags(FALSE, addr, numBlocks); +} + +u32 LCLoadData(void* destAddr, void* srcAddr, u32 nBytes) { + u32 numBlocks = (nBytes + 31) / 32; + u32 numTransactions = (numBlocks + 128 - 1) / 128; + + ASSERTMSGLINE(1426, !((u32)srcAddr & 31), "LCLoadData(): srcAddr not 32 byte aligned"); + ASSERTMSGLINE(1428, !((u32)destAddr & 31), "LCLoadData(): destAddr not 32 byte aligned"); + + while (numBlocks > 0) { + if (numBlocks < 128) { + LCLoadBlocks(destAddr, srcAddr, numBlocks); + numBlocks = 0; } else { - LCStoreBlocks(destAddr, srcAddr, 0); - blocks -= 128; - - destAddr = (char*)destAddr + 0x1000; - srcAddr = (char*)srcAddr + 0x1000; + LCLoadBlocks(destAddr, srcAddr, 0); + numBlocks -= 128; + destAddr = (void*)((u32)destAddr + 4096); + srcAddr = (void*)((u32)srcAddr + 4096); } } - return ret; + return numTransactions; } -/* 8033B8E4-8033B8F8 336224 0014+00 0/0 0/0 3/3 .text LCQueueWait */ -asm void LCQueueWait(register u32 len) { - // clang-format off +u32 LCStoreData(void* destAddr, void* srcAddr, u32 nBytes) { + u32 numBlocks = (nBytes + 31) / 32; + u32 numTransactions = (numBlocks + 128 - 1) / 128; + + ASSERTMSGLINE(1494, !((u32)srcAddr & 31), "LCStoreData(): srcAddr not 32 byte aligned"); + ASSERTMSGLINE(1496, !((u32)destAddr & 31), "LCStoreData(): destAddr not 32 byte aligned"); + + while (numBlocks > 0) { + if (numBlocks < 128) { + LCStoreBlocks(destAddr, srcAddr, numBlocks); + numBlocks = 0; + } else { + LCStoreBlocks(destAddr, srcAddr, 0); + numBlocks -= 128; + destAddr = (void*)((u32)destAddr + 4096); + srcAddr = (void*)((u32)srcAddr + 4096); + } + } + + return numTransactions; +} + +#ifdef __GEKKO__ +asm u32 LCQueueLength(void) { nofralloc - - mfspr r4, 0x398 - rlwinm r4, r4, 8, 28, 31 - cmpw r4, len - bgt LCQueueWait - + mfspr r4, HID2 + rlwinm r3, r4, 8, 28, 31 blr - // clang-format on } -static void L2Disable(void) { +asm void LCQueueWait(register u32 len) { + nofralloc +@1 + mfspr r4, HID2 + rlwinm r4, r4, 8, 28, 31 + cmpw r4, r3 + bgt @1 + blr +} +#endif + +void LCFlushQueue() { + union { + u32 val; + struct { + u32 lcAddr : 27; + u32 dmaLd : 1; + u32 dmaLenL : 2; + u32 dmaTrigger : 1; + u32 dmaFlush : 1; + } f; + } dmaL; + + dmaL.val = 0; + dmaL.f.dmaFlush = 1; + PPCMtdmaU(0); + PPCMtdmaL(dmaL.val); + PPCSync(); +} + +static void L2Init(void) { + u32 oldMSR; + oldMSR = PPCMfmsr(); + __sync(); + PPCMtmsr(MSR_IR | MSR_DR); + __sync(); + L2Disable(); + L2GlobalInvalidate(); + PPCMtmsr(oldMSR); +} + +void L2Enable(void) { + PPCMtl2cr((PPCMfl2cr() | L2CR_L2E) & ~L2CR_L2I); +} + +void L2Disable(void) { __sync(); PPCMtl2cr(PPCMfl2cr() & ~0x80000000); __sync(); } -/* 8033B8F8-8033B990 336238 0098+00 1/1 0/0 0/0 .text L2GlobalInvalidate */ void L2GlobalInvalidate(void) { L2Disable(); PPCMtl2cr(PPCMfl2cr() | 0x00200000); - while (PPCMfl2cr() & 0x00000001u) - ; + while (PPCMfl2cr() & 0x00000001u); + PPCMtl2cr(PPCMfl2cr() & ~0x00200000); while (PPCMfl2cr() & 0x00000001u) { DBPrintf(">>> L2 INVALIDATE : SHOULD NEVER HAPPEN\n"); } } -/* 8033B990-8033BAF0 3362D0 0160+00 1/1 0/0 0/0 .text DMAErrorHandler */ -void DMAErrorHandler(u16 error, OSContext* context, ...) { +void L2SetDataOnly(BOOL dataOnly) { + if (dataOnly) { + PPCMtl2cr(PPCMfl2cr() | 0x400000); + return; + } + PPCMtl2cr(PPCMfl2cr() & 0xFFBFFFFF); +} + +void L2SetWriteThrough(BOOL writeThrough) { + if (writeThrough) { + PPCMtl2cr(PPCMfl2cr() | 0x80000); + return; + } + PPCMtl2cr(PPCMfl2cr() & 0xFFF7FFFF); +} + +void DMAErrorHandler(OSError error, OSContext* context, ...) { u32 hid2 = PPCMfhid2(); OSReport("Machine check received\n"); OSReport("HID2 = 0x%x SRR1 = 0x%x\n", hid2, context->srr1); - if (!(hid2 & (HID2_DCHERR | HID2_DNCERR | HID2_DCMERR | HID2_DQOERR)) || - !(context->srr1 & SRR1_DMA_BIT)) { + if (!(hid2 & (HID2_DCHERR | HID2_DNCERR | HID2_DCMERR | HID2_DQOERR)) || !(context->srr1 & SRR1_DMA_BIT)) { OSReport("Machine check was not DMA/locked cache related\n"); OSDumpContext(context); PPCHalt(); @@ -413,27 +621,12 @@ void DMAErrorHandler(u16 error, OSContext* context, ...) { PPCMthid2(hid2); } -static void L2Init(void) { - u32 oldMSR; - oldMSR = PPCMfmsr(); - __sync(); - PPCMtmsr(MSR_IR | MSR_DR); - __sync(); - L2Disable(); - L2GlobalInvalidate(); - PPCMtmsr(oldMSR); -} - -void L2Enable(void) { - PPCMtl2cr((PPCMfl2cr() | L2CR_L2E) & ~L2CR_L2I); -} - -/* 8033BAF0-8033BBE4 336430 00F4+00 0/0 2/2 0/0 .text __OSCacheInit */ void __OSCacheInit() { if (!(PPCMfhid0() & HID0_ICE)) { ICEnable(); DBPrintf("L1 i-caches initialized\n"); } + if (!(PPCMfhid0() & HID0_DCE)) { DCEnable(); DBPrintf("L1 d-caches initialized\n"); @@ -447,4 +640,4 @@ void __OSCacheInit() { OSSetErrorHandler(OS_ERROR_MACHINE_CHECK, DMAErrorHandler); DBPrintf("Locked cache machine check handler installed\n"); -} \ No newline at end of file +} diff --git a/src/dolphin/os/OSContext.c b/src/dolphin/os/OSContext.c index cd74840952..a0c49b8481 100644 --- a/src/dolphin/os/OSContext.c +++ b/src/dolphin/os/OSContext.c @@ -1,437 +1,444 @@ -#include "dolphin/os/OSContext.h" -#include "dolphin/db.h" -#include "dolphin/os.h" +#include +#include -volatile OSContext* __OSCurrentContext : (OS_BASE_CACHED | 0x00D4); -volatile OSContext* __OSFPUContext : (OS_BASE_CACHED | 0x00D8); +#include "__os.h" -/* 8033BBE4-8033BD08 336524 0124+00 1/1 0/0 0/0 .text __OSLoadFPUContext */ -asm void __OSLoadFPUContext(void) { - // clang-format off +// external functions +extern void __RAS_OSDisableInterrupts_begin(); +extern void __RAS_OSDisableInterrupts_end(); +extern void DBPrintf(char*, ...); + +#define HID2 920 + +volatile OSContext* __OSCurrentContext AT_ADDRESS(OS_BASE_CACHED | 0x00D4); +volatile OSContext* __OSFPUContext AT_ADDRESS(OS_BASE_CACHED | 0x00D8); + +#ifdef __GEKKO__ +static asm void __OSLoadFPUContext(register u32 dummy, register OSContext* fpucontext) { nofralloc + lhz r5, fpucontext->state; + clrlwi. r5, r5, 31 + beq _return - lhz r5, 0x1A2(r4) - clrlwi. r5, r5, 0x1f - beq exit + lfd fp0, OS_CONTEXT_FPSCR(fpucontext) + mtfsf 0xFF, fp0 + mfspr r5, HID2 + rlwinm. r5, r5, 3, 31, 31 + beq _regular_FPRs - lfd f0, 0x190(r4) - mtfsf 0xFF, f0 - mfspr r5, 0x398 - rlwinm. r5, r5, 3, 0x1F, 0x1F - beq load_fprs + psq_l fp0, OS_CONTEXT_PSF0(fpucontext), 0, 0 + psq_l fp1, OS_CONTEXT_PSF1(fpucontext), 0, 0 + psq_l fp2, OS_CONTEXT_PSF2(fpucontext), 0, 0 + psq_l fp3, OS_CONTEXT_PSF3(fpucontext), 0, 0 + psq_l fp4, OS_CONTEXT_PSF4(fpucontext), 0, 0 + psq_l fp5, OS_CONTEXT_PSF5(fpucontext), 0, 0 + psq_l fp6, OS_CONTEXT_PSF6(fpucontext), 0, 0 + psq_l fp7, OS_CONTEXT_PSF7(fpucontext), 0, 0 + psq_l fp8, OS_CONTEXT_PSF8(fpucontext), 0, 0 + psq_l fp9, OS_CONTEXT_PSF9(fpucontext), 0, 0 + psq_l fp10, OS_CONTEXT_PSF10(fpucontext), 0, 0 + psq_l fp11, OS_CONTEXT_PSF11(fpucontext), 0, 0 + psq_l fp12, OS_CONTEXT_PSF12(fpucontext), 0, 0 + psq_l fp13, OS_CONTEXT_PSF13(fpucontext), 0, 0 + psq_l fp14, OS_CONTEXT_PSF14(fpucontext), 0, 0 + psq_l fp15, OS_CONTEXT_PSF15(fpucontext), 0, 0 + psq_l fp16, OS_CONTEXT_PSF16(fpucontext), 0, 0 + psq_l fp17, OS_CONTEXT_PSF17(fpucontext), 0, 0 + psq_l fp18, OS_CONTEXT_PSF18(fpucontext), 0, 0 + psq_l fp19, OS_CONTEXT_PSF19(fpucontext), 0, 0 + psq_l fp20, OS_CONTEXT_PSF20(fpucontext), 0, 0 + psq_l fp21, OS_CONTEXT_PSF21(fpucontext), 0, 0 + psq_l fp22, OS_CONTEXT_PSF22(fpucontext), 0, 0 + psq_l fp23, OS_CONTEXT_PSF23(fpucontext), 0, 0 + psq_l fp24, OS_CONTEXT_PSF24(fpucontext), 0, 0 + psq_l fp25, OS_CONTEXT_PSF25(fpucontext), 0, 0 + psq_l fp26, OS_CONTEXT_PSF26(fpucontext), 0, 0 + psq_l fp27, OS_CONTEXT_PSF27(fpucontext), 0, 0 + psq_l fp28, OS_CONTEXT_PSF28(fpucontext), 0, 0 + psq_l fp29, OS_CONTEXT_PSF29(fpucontext), 0, 0 + psq_l fp30, OS_CONTEXT_PSF30(fpucontext), 0, 0 + psq_l fp31, OS_CONTEXT_PSF31(fpucontext), 0, 0 - psq_l f0, 0x1C8(r4), 0, 0 - psq_l f1, 0x1D0(r4), 0, 0 - psq_l f2, 0x1D8(r4), 0, 0 - psq_l f3, 0x1E0(r4), 0, 0 - psq_l f4, 0x1E8(r4), 0, 0 - psq_l f5, 0x1F0(r4), 0, 0 - psq_l f6, 0x1F8(r4), 0, 0 - psq_l f7, 0x200(r4), 0, 0 - psq_l f8, 0x208(r4), 0, 0 - psq_l f9, 0x210(r4), 0, 0 - psq_l f10, 0x218(r4), 0, 0 - psq_l f11, 0x220(r4), 0, 0 - psq_l f12, 0x228(r4), 0, 0 - psq_l f13, 0x230(r4), 0, 0 - psq_l f14, 0x238(r4), 0, 0 - psq_l f15, 0x240(r4), 0, 0 - psq_l f16, 0x248(r4), 0, 0 - psq_l f17, 0x250(r4), 0, 0 - psq_l f18, 0x258(r4), 0, 0 - psq_l f19, 0x260(r4), 0, 0 - psq_l f20, 0x268(r4), 0, 0 - psq_l f21, 0x270(r4), 0, 0 - psq_l f22, 0x278(r4), 0, 0 - psq_l f23, 0x280(r4), 0, 0 - psq_l f24, 0x288(r4), 0, 0 - psq_l f25, 0x290(r4), 0, 0 - psq_l f26, 0x298(r4), 0, 0 - psq_l f27, 0x2A0(r4), 0, 0 - psq_l f28, 0x2A8(r4), 0, 0 - psq_l f29, 0x2B0(r4), 0, 0 - psq_l f30, 0x2B8(r4), 0, 0 - psq_l f31, 0x2C0(r4), 0, 0 - -load_fprs: - lfd f0, 0x90(r4) - lfd f1, 0x98(r4) - lfd f2, 0xA0(r4) - lfd f3, 0xA8(r4) - lfd f4, 0xB0(r4) - lfd f5, 0xB8(r4) - lfd f6, 0xC0(r4) - lfd f7, 0xC8(r4) - lfd f8, 0xD0(r4) - lfd f9, 0xD8(r4) - lfd f10, 0xE0(r4) - lfd f11, 0xE8(r4) - lfd f12, 0xF0(r4) - lfd f13, 0xF8(r4) - lfd f14, 0x100(r4) - lfd f15, 0x108(r4) - lfd f16, 0x110(r4) - lfd f17, 0x118(r4) - lfd f18, 0x120(r4) - lfd f19, 0x128(r4) - lfd f20, 0x130(r4) - lfd f21, 0x138(r4) - lfd f22, 0x140(r4) - lfd f23, 0x148(r4) - lfd f24, 0x150(r4) - lfd f25, 0x158(r4) - lfd f26, 0x160(r4) - lfd f27, 0x168(r4) - lfd f28, 0x170(r4) - lfd f29, 0x178(r4) - lfd f30, 0x180(r4) - lfd f31, 0x188(r4) - -exit: +_regular_FPRs: + lfd fp0, fpucontext->fpr[0] + lfd fp1, fpucontext->fpr[1] + lfd fp2, fpucontext->fpr[2] + lfd fp3, fpucontext->fpr[3] + lfd fp4, fpucontext->fpr[4] + lfd fp5, fpucontext->fpr[5] + lfd fp6, fpucontext->fpr[6] + lfd fp7, fpucontext->fpr[7] + lfd fp8, fpucontext->fpr[8] + lfd fp9, fpucontext->fpr[9] + lfd fp10, fpucontext->fpr[10] + lfd fp11, fpucontext->fpr[11] + lfd fp12, fpucontext->fpr[12] + lfd fp13, fpucontext->fpr[13] + lfd fp14, fpucontext->fpr[14] + lfd fp15, fpucontext->fpr[15] + lfd fp16, fpucontext->fpr[16] + lfd fp17, fpucontext->fpr[17] + lfd fp18, fpucontext->fpr[18] + lfd fp19, fpucontext->fpr[19] + lfd fp20, fpucontext->fpr[20] + lfd fp21, fpucontext->fpr[21] + lfd fp22, fpucontext->fpr[22] + lfd fp23, fpucontext->fpr[23] + lfd fp24, fpucontext->fpr[24] + lfd fp25, fpucontext->fpr[25] + lfd fp26, fpucontext->fpr[26] + lfd fp27, fpucontext->fpr[27] + lfd fp28, fpucontext->fpr[28] + lfd fp29, fpucontext->fpr[29] + lfd fp30, fpucontext->fpr[30] + lfd fp31, fpucontext->fpr[31] +_return: blr - // clang-format on } -/* 8033BD08-8033BE30 336648 0128+00 2/2 0/0 0/0 .text __OSSaveFPUContext */ -asm void __OSSaveFPUContext(s32 unused0, s32 unused1, register OSContext* context) { - // clang-format off +static asm void __OSSaveFPUContext(register u32 dummy1, register u32 dummy2, register OSContext* fpucontext) { nofralloc - lhz r3, 0x1A2(context) - ori r3, r3, 1 - sth r3, 0x1A2(context) + lhz r3, fpucontext->state + ori r3, r3, 1 + sth r3, fpucontext->state - stfd f0, 0x90(context) - stfd f1, 0x98(context) - stfd f2, 0xa0(context) - stfd f3, 0xa8(context) - stfd f4, 0xb0(context) - stfd f5, 0xb8(context) - stfd f6, 0xc0(context) - stfd f7, 0xc8(context) - stfd f8, 0xd0(context) - stfd f9, 0xd8(context) - stfd f10, 0xe0(context) - stfd f11, 0xe8(context) - stfd f12, 0xf0(context) - stfd f13, 0xf8(context) - stfd f14, 0x100(context) - stfd f15, 0x108(context) - stfd f16, 0x110(context) - stfd f17, 0x118(context) - stfd f18, 0x120(context) - stfd f19, 0x128(context) - stfd f20, 0x130(context) - stfd f21, 0x138(context) - stfd f22, 0x140(context) - stfd f23, 0x148(context) - stfd f24, 0x150(context) - stfd f25, 0x158(context) - stfd f26, 0x160(context) - stfd f27, 0x168(context) - stfd f28, 0x170(context) - stfd f29, 0x178(context) - stfd f30, 0x180(context) - stfd f31, 0x188(context) + stfd fp0, fpucontext->fpr[0] + stfd fp1, fpucontext->fpr[1] + stfd fp2, fpucontext->fpr[2] + stfd fp3, fpucontext->fpr[3] + stfd fp4, fpucontext->fpr[4] + stfd fp5, fpucontext->fpr[5] + stfd fp6, fpucontext->fpr[6] + stfd fp7, fpucontext->fpr[7] + stfd fp8, fpucontext->fpr[8] + stfd fp9, fpucontext->fpr[9] + stfd fp10, fpucontext->fpr[10] + stfd fp11, fpucontext->fpr[11] + stfd fp12, fpucontext->fpr[12] + stfd fp13, fpucontext->fpr[13] + stfd fp14, fpucontext->fpr[14] + stfd fp15, fpucontext->fpr[15] + stfd fp16, fpucontext->fpr[16] + stfd fp17, fpucontext->fpr[17] + stfd fp18, fpucontext->fpr[18] + stfd fp19, fpucontext->fpr[19] + stfd fp20, fpucontext->fpr[20] + stfd fp21, fpucontext->fpr[21] + stfd fp22, fpucontext->fpr[22] + stfd fp23, fpucontext->fpr[23] + stfd fp24, fpucontext->fpr[24] + stfd fp25, fpucontext->fpr[25] + stfd fp26, fpucontext->fpr[26] + stfd fp27, fpucontext->fpr[27] + stfd fp28, fpucontext->fpr[28] + stfd fp29, fpucontext->fpr[29] + stfd fp30, fpucontext->fpr[30] + stfd fp31, fpucontext->fpr[31] - mffs f0 - stfd f0, 0x190(context) - lfd f0, 0x90(context) - mfspr r3, 0x398 - rlwinm. r3, r3, 3, 0x1f, 0x1f - beq exit + mffs fp0 + stfd fp0, OS_CONTEXT_FPSCR(fpucontext) - psq_st f0, 456(context), 0, 0 - psq_st f1, 464(context), 0, 0 - psq_st f2, 472(context), 0, 0 - psq_st f3, 480(context), 0, 0 - psq_st f4, 488(context), 0, 0 - psq_st f5, 496(context), 0, 0 - psq_st f6, 504(context), 0, 0 - psq_st f7, 512(context), 0, 0 - psq_st f8, 520(context), 0, 0 - psq_st f9, 528(context), 0, 0 - psq_st f10, 536(context), 0, 0 - psq_st f11, 544(context), 0, 0 - psq_st f12, 552(context), 0, 0 - psq_st f13, 560(context), 0, 0 - psq_st f14, 568(context), 0, 0 - psq_st f15, 576(context), 0, 0 - psq_st f16, 584(context), 0, 0 - psq_st f17, 592(context), 0, 0 - psq_st f18, 600(context), 0, 0 - psq_st f19, 608(context), 0, 0 - psq_st f20, 616(context), 0, 0 - psq_st f21, 624(context), 0, 0 - psq_st f22, 632(context), 0, 0 - psq_st f23, 640(context), 0, 0 - psq_st f24, 648(context), 0, 0 - psq_st f25, 656(context), 0, 0 - psq_st f26, 664(context), 0, 0 - psq_st f27, 672(context), 0, 0 - psq_st f28, 680(context), 0, 0 - psq_st f29, 688(context), 0, 0 - psq_st f30, 696(context), 0, 0 - psq_st f31, 704(context), 0, 0 + lfd fp0, fpucontext->fpr[0] -exit: + mfspr r3, HID2 + rlwinm. r3, r3, 3, 31, 31 + bc 12, 2, _return + + psq_st fp0, OS_CONTEXT_PSF0(fpucontext), 0, 0 + psq_st fp1, OS_CONTEXT_PSF1(fpucontext), 0, 0 + psq_st fp2, OS_CONTEXT_PSF2(fpucontext), 0, 0 + psq_st fp3, OS_CONTEXT_PSF3(fpucontext), 0, 0 + psq_st fp4, OS_CONTEXT_PSF4(fpucontext), 0, 0 + psq_st fp5, OS_CONTEXT_PSF5(fpucontext), 0, 0 + psq_st fp6, OS_CONTEXT_PSF6(fpucontext), 0, 0 + psq_st fp7, OS_CONTEXT_PSF7(fpucontext), 0, 0 + psq_st fp8, OS_CONTEXT_PSF8(fpucontext), 0, 0 + psq_st fp9, OS_CONTEXT_PSF9(fpucontext), 0, 0 + psq_st fp10, OS_CONTEXT_PSF10(fpucontext), 0, 0 + psq_st fp11, OS_CONTEXT_PSF11(fpucontext), 0, 0 + psq_st fp12, OS_CONTEXT_PSF12(fpucontext), 0, 0 + psq_st fp13, OS_CONTEXT_PSF13(fpucontext), 0, 0 + psq_st fp14, OS_CONTEXT_PSF14(fpucontext), 0, 0 + psq_st fp15, OS_CONTEXT_PSF15(fpucontext), 0, 0 + psq_st fp16, OS_CONTEXT_PSF16(fpucontext), 0, 0 + psq_st fp17, OS_CONTEXT_PSF17(fpucontext), 0, 0 + psq_st fp18, OS_CONTEXT_PSF18(fpucontext), 0, 0 + psq_st fp19, OS_CONTEXT_PSF19(fpucontext), 0, 0 + psq_st fp20, OS_CONTEXT_PSF20(fpucontext), 0, 0 + psq_st fp21, OS_CONTEXT_PSF21(fpucontext), 0, 0 + psq_st fp22, OS_CONTEXT_PSF22(fpucontext), 0, 0 + psq_st fp23, OS_CONTEXT_PSF23(fpucontext), 0, 0 + psq_st fp24, OS_CONTEXT_PSF24(fpucontext), 0, 0 + psq_st fp25, OS_CONTEXT_PSF25(fpucontext), 0, 0 + psq_st fp26, OS_CONTEXT_PSF26(fpucontext), 0, 0 + psq_st fp27, OS_CONTEXT_PSF27(fpucontext), 0, 0 + psq_st fp28, OS_CONTEXT_PSF28(fpucontext), 0, 0 + psq_st fp29, OS_CONTEXT_PSF29(fpucontext), 0, 0 + psq_st fp30, OS_CONTEXT_PSF30(fpucontext), 0, 0 + psq_st fp31, OS_CONTEXT_PSF31(fpucontext), 0, 0 + +_return: blr - // clang-format on } -/* 8033BE30-8033BE38 336770 0008+00 0/0 1/1 0/0 .text OSSaveFPUContext */ -asm void OSSaveFPUContext(register OSContext* context) { - // clang-format off +asm void OSLoadFPUContext(register OSContext* fpucontext) { nofralloc - - addi r5, context, 0 - b __OSSaveFPUContext - // clang-format on + addi r4, fpucontext, 0 + b __OSLoadFPUContext } -/* 8033BE38-8033BE94 336778 005C+00 1/1 18/18 0/0 .text OSSetCurrentContext */ -asm void OSSetCurrentContext(register OSContext* context) { - // clang-format off +asm void OSSaveFPUContext(register OSContext* fpucontext) { + nofralloc + addi r5, fpucontext, 0 + b __OSSaveFPUContext +} + +asm void OSSetCurrentContext(register OSContext* context){ nofralloc - lis r4, OS_CURRENT_CONTEXT@ha - stw context, OS_CURRENT_CONTEXT@l(r4) - clrlwi r5, context, 2 - stw r5, 0xc0(r4) - lwz r5, 0xd8(r4) - cmpw r5, context - bne lbl_800EE9AC - lwz r6, 0x19c(context) - ori r6, r6, 0x2000 - stw r6, 0x19c(context) - mfmsr r6 - ori r6, r6, 2 - mtmsr r6 + addis r4, r0, OS_CACHED_REGION_PREFIX + + stw context, 0x00D4(r4) + + clrlwi r5, context, 2 + stw r5, 0x00C0(r4) + + lwz r5, 0x00D8(r4) + cmpw r5, context + bne _disableFPU + + lwz r6, context->srr1 + ori r6, r6, 0x2000 + stw r6, context->srr1 + mfmsr r6 + ori r6, r6, 2 + mtmsr r6 blr -lbl_800EE9AC: - lwz r6, 0x19c(context) - rlwinm r6, r6, 0, 0x13, 0x11 - stw r6, 0x19c(context) - mfmsr r6 - rlwinm r6, r6, 0, 0x13, 0x11 - ori r6, r6, 2 - mtmsr r6 +_disableFPU: + lwz r6, context->srr1 + rlwinm r6, r6, 0, 19, 17 + stw r6, context->srr1 + mfmsr r6 + rlwinm r6, r6, 0, 19, 17 + ori r6, r6, 2 + mtmsr r6 isync blr - // clang-format on } +#endif -/* 8033BE94-8033BEA0 3367D4 000C+00 0/0 2/2 0/0 .text OSGetCurrentContext */ OSContext* OSGetCurrentContext(void) { - return OS_CURRENT_CONTEXT; + return (OSContext*)__OSCurrentContext; } -/* 8033BEA0-8033BF20 3367E0 0080+00 0/0 1/1 0/0 .text OSSaveContext */ +#ifdef __GEKKO__ asm u32 OSSaveContext(register OSContext* context) { - // clang-format off nofralloc - - stmw r13, 0x34(context) - - mfspr r0, GQR1 - stw r0, 0x1a8(context) - mfspr r0, GQR2 - stw r0, 0x1ac(context) - mfspr r0, GQR3 - stw r0, 0x1b0(context) - mfspr r0, GQR4 - stw r0, 0x1b4(context) - mfspr r0, GQR5 - stw r0, 0x1b8(context) - mfspr r0, GQR6 - stw r0, 0x1bc(context) - mfspr r0, GQR7 - stw r0, 0x1c0(context) - - mfcr r0 - stw r0, 0x80(context) - mflr r0 - stw r0, 0x84(context) - stw r0, 0x198(context) - mfmsr r0 - stw r0, 0x19c(context) - mfctr r0 - stw r0, 0x88(context) - mfxer r0 - stw r0, 0x8c(context) - - stw r1, 4(context) - stw r2, 8(context) - - li r0, 1 - stw r0, 0xc(context) - - li r3, 0 + stmw r13, context->gpr[13] + mfspr r0, GQR1 + stw r0, context->gqr[1] + mfspr r0, GQR2 + stw r0, context->gqr[2] + mfspr r0, GQR3 + stw r0, context->gqr[3] + mfspr r0, GQR4 + stw r0, context->gqr[4] + mfspr r0, GQR5 + stw r0, context->gqr[5] + mfspr r0, GQR6 + stw r0, context->gqr[6] + mfspr r0, GQR7 + stw r0, context->gqr[7] + mfcr r0 + stw r0, context->cr + mflr r0 + stw r0, context->lr + stw r0, context->srr0 + mfmsr r0 + stw r0, context->srr1 + mfctr r0 + stw r0, context->ctr + mfxer r0 + stw r0, context->xer + stw r1, context->gpr[1] + stw r2, context->gpr[2] + li r0, 0x1 + stw r0, context->gpr[3] + li r3, 0 blr - // clang-format on } -/* 8033BF20-8033BFF8 336860 00D8+00 0/0 4/4 0/0 .text OSLoadContext */ asm void OSLoadContext(register OSContext* context) { - // clang-format off nofralloc - lis r4, OSDisableInterrupts@ha - lwz r6, 0x198(context) - addi r5, r4, OSDisableInterrupts@l - cmplw r6, r5 - ble srr0_not_in_disableintr - lis r4, __RAS_OSDisableInterrupts_end@ha - addi r0, r4, __RAS_OSDisableInterrupts_end@l - cmplw r6, r0 - bge srr0_not_in_disableintr - stw r5, 0x198(context) - -srr0_not_in_disableintr: - lwz r0, 0(context) - lwz r1, 4(context) - lwz r2, 8(context) - lhz r4, 0x1a2(context) - rlwinm. r5, r4, 0, 0x1e, 0x1e - beq load_saved_gprs - rlwinm r4, r4, 0, 0x1f, 0x1d - sth r4, 0x1a2(context) - lmw r5, 0x14(context) - b load_special_regs - -load_saved_gprs: - lmw r13, 0x34(context) - -load_special_regs: - lwz r4, 0x1a8(context) - mtspr 0x391, r4 - lwz r4, 0x1ac(context) - mtspr 0x392, r4 - lwz r4, 0x1b0(context) - mtspr 0x393, r4 - lwz r4, 0x1b4(context) - mtspr 0x394, r4 - lwz r4, 0x1b8(context) - mtspr 0x395, r4 - lwz r4, 0x1bc(context) - mtspr 0x396, r4 - lwz r4, 0x1c0(context) - mtspr 0x397, r4 - lwz r4, 0x80(context) - mtcrf 0xff, r4 - lwz r4, 0x84(context) - mtlr r4 - lwz r4, 0x88(context) - mtctr r4 - lwz r4, 0x8c(context) - mtxer r4 - mfmsr r4 - rlwinm r4, r4, 0, 0x11, 0xf - rlwinm r4, r4, 0, 0x1f, 0x1d - mtmsr r4 - lwz r4, 0x198(context) - mtspr 0x1a, r4 - lwz r4, 0x19c(context) - mtspr 0x1b, r4 - lwz r4, 0x10(context) - lwz context, 0xc(context) + lis r4,__RAS_OSDisableInterrupts_begin@ha + lwz r6,context->srr0 + addi r5,r4,__RAS_OSDisableInterrupts_begin@l + cmplw r6,r5 + ble _notInRAS + lis r4,__RAS_OSDisableInterrupts_end@ha + addi r0,r4,__RAS_OSDisableInterrupts_end@l + cmplw r6,r0 + bge _notInRAS + stw r5,context->srr0 + +_notInRAS: + + lwz r0, context->gpr[0] + lwz r1, context->gpr[1] + lwz r2, context->gpr[2] + + lhz r4, context->state + rlwinm. r5, r4, 0, 30, 30 + beq notexc + rlwinm r4, r4, 0, 31, 29 + sth r4, context->state + lmw r5, context->gpr[5] + b misc +notexc: + lmw r13, context->gpr[13] + misc: + + lwz r4, context->gqr[1] + mtspr GQR1, r4 + lwz r4, context->gqr[2] + mtspr GQR2, r4 + lwz r4, context->gqr[3] + mtspr GQR3, r4 + lwz r4, context->gqr[4] + mtspr GQR4, r4 + lwz r4, context->gqr[5] + mtspr GQR5, r4 + lwz r4, context->gqr[6] + mtspr GQR6, r4 + lwz r4, context->gqr[7] + mtspr GQR7, r4 + + lwz r4, context->cr + mtcr r4 + lwz r4, context->lr + mtlr r4 + lwz r4, context->ctr + mtctr r4 + lwz r4, context->xer + mtxer r4 + + mfmsr r4 + rlwinm r4, r4, 0, 17, 15 + rlwinm r4, r4, 0, 31, 29 + mtmsr r4 + + lwz r4, context->srr0 + mtsrr0 r4 + lwz r4, context->srr1 + mtsrr1 r4 + + lwz r4, context->gpr[4] + lwz r3, context->gpr[3] + rfi - // clang-format on } -/* 8033BFF8-8033C000 336938 0008+00 0/0 5/5 0/0 .text OSGetStackPointer */ -asm u8* OSGetStackPointer(void) { - // clang-format off - nofralloc - - mr r3, r1 +asm u32 OSGetStackPointer() { + nofralloc + mr r3, r1 blr - // clang-format on } -/* 8033C000-8033C024 336940 0024+00 1/1 20/20 0/0 .text OSClearContext */ -void OSClearContext(OSContext* context) { - context->mode = 0; - context->state = 0; - - if (context == OS_CURRENT_FPU_CONTEXT) { - OS_CURRENT_FPU_CONTEXT = NULL; - } -} - -/* 8033C024-8033C0E0 336964 00BC+00 0/0 1/1 0/0 .text OSInitContext */ -asm void OSInitContext(register OSContext* context, register u32 srr0, register u32 stack) { - // clang-format off +asm u32 OSSwitchStack(register u32 newsp) { nofralloc - - stw srr0, 0x198(context) - stw stack, 4(context) - li r11, 0 - ori r11, r11, 0x9032 - stw r11, 0x19c(context) - li r0, 0 - stw r0, 0x80(context) - stw r0, 0x8c(context) - stw r2, 8(context) - stw r13, 0x34(context) - stw r0, 0xc(context) - stw r0, 0x10(context) - stw r0, 0x14(context) - stw r0, 0x18(context) - stw r0, 0x1c(context) - stw r0, 0x20(context) - stw r0, 0x24(context) - stw r0, 0x28(context) - stw r0, 0x2c(context) - stw r0, 0x30(context) - stw r0, 0x38(context) - stw r0, 0x3c(context) - stw r0, 0x40(context) - stw r0, 0x44(context) - stw r0, 0x48(context) - stw r0, 0x4c(context) - stw r0, 0x50(context) - stw r0, 0x54(context) - stw r0, 0x58(context) - stw r0, 0x5c(context) - stw r0, 0x60(context) - stw r0, 0x64(context) - stw r0, 0x68(context) - stw r0, 0x6c(context) - stw r0, 0x70(context) - stw r0, 0x74(context) - stw r0, 0x78(context) - stw r0, 0x7c(context) - stw r0, 0x1a4(context) - stw r0, 0x1a8(context) - stw r0, 0x1ac(context) - stw r0, 0x1b0(context) - stw r0, 0x1b4(context) - stw r0, 0x1b8(context) - stw r0, 0x1bc(context) - stw r0, 0x1c0(context) - - b OSClearContext - // clang-format on + mr r5, r1 + mr r1, newsp + mr r3, r5 + blr } -// inline duplicates for OSDumpContext to match -// maybe need to change inlining compiler flag for better match? -inline void i_OSClearContext(OSContext* context) { +asm int OSSwitchFiber(register u32 pc, register u32 newsp) { + nofralloc + mflr r0 + mr r5, r1 + stwu r5, -8(newsp) + mr r1, newsp + stw r0, 4(r5) + mtlr pc + blrl + lwz r5, 0(r1) + lwz r0, 4(r5) + mtlr r0 + mr r1, r5 + blr +} +#endif + +void OSClearContext(register OSContext* context) { context->mode = 0; context->state = 0; - - if (context == OS_CURRENT_FPU_CONTEXT) { - OS_CURRENT_FPU_CONTEXT = NULL; - } + if (context == __OSFPUContext) + __OSFPUContext = NULL; } -inline OSContext* i_OSGetCurrentContext(void) { - return OS_CURRENT_CONTEXT; -} +#ifdef __GEKKO__ +asm void OSInitContext(register OSContext* context, register u32 pc, register u32 newsp) { + nofralloc + + stw pc, OS_CONTEXT_SRR0(context) + stw newsp, OS_CONTEXT_R1(context) + li r11, 0 + ori r11, r11, 0x00008000 | 0x00000020 | 0x00000010 | 0x00000002 | 0x00001000 + stw r11, OS_CONTEXT_SRR1(context) + li r0, 0x0 + stw r0, OS_CONTEXT_CR(context) + stw r0, OS_CONTEXT_XER(context) + + + stw r2, OS_CONTEXT_R2(context) + stw r13, OS_CONTEXT_R13(context) + + stw r0, OS_CONTEXT_R3(context) + stw r0, OS_CONTEXT_R4(context) + stw r0, OS_CONTEXT_R5(context) + stw r0, OS_CONTEXT_R6(context) + stw r0, OS_CONTEXT_R7(context) + stw r0, OS_CONTEXT_R8(context) + stw r0, OS_CONTEXT_R9(context) + stw r0, OS_CONTEXT_R10(context) + stw r0, OS_CONTEXT_R11(context) + stw r0, OS_CONTEXT_R12(context) + + stw r0, OS_CONTEXT_R14(context) + stw r0, OS_CONTEXT_R15(context) + stw r0, OS_CONTEXT_R16(context) + stw r0, OS_CONTEXT_R17(context) + stw r0, OS_CONTEXT_R18(context) + stw r0, OS_CONTEXT_R19(context) + stw r0, OS_CONTEXT_R20(context) + stw r0, OS_CONTEXT_R21(context) + stw r0, OS_CONTEXT_R22(context) + stw r0, OS_CONTEXT_R23(context) + stw r0, OS_CONTEXT_R24(context) + stw r0, OS_CONTEXT_R25(context) + stw r0, OS_CONTEXT_R26(context) + stw r0, OS_CONTEXT_R27(context) + stw r0, OS_CONTEXT_R28(context) + stw r0, OS_CONTEXT_R29(context) + stw r0, OS_CONTEXT_R30(context) + stw r0, OS_CONTEXT_R31(context) + + stw r0, OS_CONTEXT_GQR0(context) + stw r0, OS_CONTEXT_GQR1(context) + stw r0, OS_CONTEXT_GQR2(context) + stw r0, OS_CONTEXT_GQR3(context) + stw r0, OS_CONTEXT_GQR4(context) + stw r0, OS_CONTEXT_GQR5(context) + stw r0, OS_CONTEXT_GQR6(context) + stw r0, OS_CONTEXT_GQR7(context) + + b OSClearContext +} +#endif -/* 8033C0E0-8033C388 336A20 02A8+00 0/0 3/3 0/0 .text OSDumpContext */ void OSDumpContext(OSContext* context) { u32 i; u32* p; @@ -440,7 +447,7 @@ void OSDumpContext(OSContext* context) { for (i = 0; i < 16; ++i) { OSReport("r%-2d = 0x%08x (%14d) r%-2d = 0x%08x (%14d)\n", i, context->gpr[i], - context->gpr[i], i + 16, context->gpr[i + 16], context->gpr[i + 16]); + context->gpr[i], i + 16, context->gpr[i + 16], context->gpr[i + 16]); } OSReport("LR = 0x%08x CR = 0x%08x\n", context->lr, context->cr); @@ -448,32 +455,31 @@ void OSDumpContext(OSContext* context) { OSReport("\nGQRs----------\n"); for (i = 0; i < 4; ++i) { - OSReport("gqr%d = 0x%08x \t gqr%d = 0x%08x\n", i, context->gqr[i], i + 4, - context->gqr[i + 4]); + OSReport("gqr%d = 0x%08x \t gqr%d = 0x%08x\n", i, context->gqr[i], i + 4, context->gqr[i + 4]); } if (context->state & OS_CONTEXT_STATE_FPSAVED) { OSContext* currentContext; - OSContext fpuContext; + OSContext fpucontext; BOOL enabled; enabled = OSDisableInterrupts(); - currentContext = i_OSGetCurrentContext(); - i_OSClearContext(&fpuContext); - OSSetCurrentContext(&fpuContext); + currentContext = OSGetCurrentContext(); + OSClearContext(&fpucontext); + OSSetCurrentContext(&fpucontext); OSReport("\n\nFPRs----------\n"); for (i = 0; i < 32; i += 2) { OSReport("fr%d \t= %d \t fr%d \t= %d\n", i, (u32)context->fpr[i], i + 1, - (u32)context->fpr[i + 1]); + (u32)context->fpr[i + 1]); } OSReport("\n\nPSFs----------\n"); for (i = 0; i < 32; i += 2) { - OSReport("ps%d \t= 0x%x \t ps%d \t= 0x%x\n", i, (u32)context->ps[i], i + 1, - (u32)context->ps[i + 1]); + OSReport("ps%d \t= 0x%x \t ps%d \t= 0x%x\n", i, (u32)context->psf[i], i + 1, + (u32)context->psf[i + 1]); } - i_OSClearContext(&fpuContext); + OSClearContext(&fpucontext); OSSetCurrentContext(currentContext); OSRestoreInterrupts(enabled); } @@ -484,142 +490,137 @@ void OSDumpContext(OSContext* context) { } } -/* 8033C388-8033C40C 336CC8 0084+00 1/1 0/0 0/0 .text OSSwitchFPUContext */ -static asm void OSSwitchFPUContext(register u8 err, register OSContext* context) { - // clang-format off +#ifdef __GEKKO__ +static asm void OSSwitchFPUContext(register __OSException exception, register OSContext* context) { nofralloc - - mfmsr r5 - ori r5, r5, 0x2000 - mtmsr r5 + mfmsr r5 + ori r5, r5, 0x2000 + mtmsr r5 isync - lwz r5, 0x19c(context) - ori r5, r5, 0x2000 - mtspr 0x1b, r5 - lis r3, OS_CURRENT_FPU_CONTEXT@ha - lwz r5, OS_CURRENT_FPU_CONTEXT@l(r3) - stw context, 0xd8(r3) - cmpw r5, context - beq context_is_curr_fpu_context - cmpwi r5, 0 - beq context_is_null - bl __OSSaveFPUContext - -context_is_null: - bl __OSLoadFPUContext - -context_is_curr_fpu_context: - lwz r3, 0x80(context) - mtcrf 0xff, r3 - lwz r3, 0x84(context) - mtlr r3 - lwz r3, 0x198(context) - mtspr 0x1a, r3 - lwz r3, 0x88(context) - mtctr r3 - lwz r3, 0x8c(context) - mtxer r3 - lhz r3, 0x1a2(context) - rlwinm r3, r3, 0, 0x1f, 0x1d - sth r3, 0x1a2(context) - lwz r5, 0x14(context) - lwz r3, 0xc(context) - lwz context, 0x10(context) + lwz r5, OS_CONTEXT_SRR1(context) + ori r5, r5, 0x2000 + mtsrr1 r5 + addis r3, r0, OS_CACHED_REGION_PREFIX + lwz r5, 0x00D8(r3) + stw context, 0x00D8(r3) + cmpw r5, r4 + beq _restoreAndExit + cmpwi r5, 0x0 + beq _loadNewFPUContext + bl __OSSaveFPUContext +_loadNewFPUContext: + bl __OSLoadFPUContext +_restoreAndExit: + lwz r3, OS_CONTEXT_CR(context) + mtcr r3 + lwz r3, OS_CONTEXT_LR(context) + mtlr r3 + lwz r3, OS_CONTEXT_SRR0(context) + mtsrr0 r3 + lwz r3, OS_CONTEXT_CTR(context) + mtctr r3 + lwz r3, OS_CONTEXT_XER(context) + mtxer r3 + lhz r3, context->state + rlwinm r3, r3, 0, 31, 29 + sth r3, context->state + lwz r5, OS_CONTEXT_R5(context) + lwz r3, OS_CONTEXT_R3(context) + lwz r4, OS_CONTEXT_R4(context) rfi - // clang-format on } +#endif -/* 8033C40C-8033C454 336D4C 0048+00 0/0 1/1 0/0 .text __OSContextInit */ void __OSContextInit(void) { - __OSSetExceptionHandler(EXCEPTION_FLOATING_POINT, OSSwitchFPUContext); + __OSSetExceptionHandler(__OS_EXCEPTION_FLOATING_POINT, OSSwitchFPUContext); __OSFPUContext = NULL; DBPrintf("FPU-unavailable handler installed\n"); } -/* 8033C454-8033C580 336D94 012C+00 0/0 1/1 0/0 .text OSFillFPUContext */ +#ifdef __GEKKO__ asm void OSFillFPUContext(register OSContext* context) { - // clang-format off nofralloc - - mfmsr r5 - ori r5, r5, 0x2000 - mtmsr r5 + mfmsr r5 + ori r5, r5, 0x2000 + mtmsr r5 isync - stfd f0, 0x90(context) - stfd f1, 0x98(context) - stfd f2, 0xa0(context) - stfd f3, 0xa8(context) - stfd f4, 0xb0(context) - stfd f5, 0xb8(context) - stfd f6, 0xc0(context) - stfd f7, 0xc8(context) - stfd f8, 0xd0(context) - stfd f9, 0xd8(context) - stfd f10, 0xe0(context) - stfd f11, 0xe8(context) - stfd f12, 0xf0(context) - stfd f13, 0xf8(context) - stfd f14, 0x100(context) - stfd f15, 0x108(context) - stfd f16, 0x110(context) - stfd f17, 0x118(context) - stfd f18, 0x120(context) - stfd f19, 0x128(context) - stfd f20, 0x130(context) - stfd f21, 0x138(context) - stfd f22, 0x140(context) - stfd f23, 0x148(context) - stfd f24, 0x150(context) - stfd f25, 0x158(context) - stfd f26, 0x160(context) - stfd f27, 0x168(context) - stfd f28, 0x170(context) - stfd f29, 0x178(context) - stfd f30, 0x180(context) - stfd f31, 0x188(context) + stfd fp0, context->fpr[0] + stfd fp1, context->fpr[1] + stfd fp2, context->fpr[2] + stfd fp3, context->fpr[3] + stfd fp4, context->fpr[4] + stfd fp5, context->fpr[5] + stfd fp6, context->fpr[6] + stfd fp7, context->fpr[7] + stfd fp8, context->fpr[8] + stfd fp9, context->fpr[9] + stfd fp10, context->fpr[10] + stfd fp11, context->fpr[11] + stfd fp12, context->fpr[12] + stfd fp13, context->fpr[13] + stfd fp14, context->fpr[14] + stfd fp15, context->fpr[15] + stfd fp16, context->fpr[16] + stfd fp17, context->fpr[17] + stfd fp18, context->fpr[18] + stfd fp19, context->fpr[19] + stfd fp20, context->fpr[20] + stfd fp21, context->fpr[21] + stfd fp22, context->fpr[22] + stfd fp23, context->fpr[23] + stfd fp24, context->fpr[24] + stfd fp25, context->fpr[25] + stfd fp26, context->fpr[26] + stfd fp27, context->fpr[27] + stfd fp28, context->fpr[28] + stfd fp29, context->fpr[29] + stfd fp30, context->fpr[30] + stfd fp31, context->fpr[31] - mffs f0 - stfd f0, 0x190(context) - lfd f0, 0x90(context) - mfspr r5, 0x398 - rlwinm. r5, r5, 3, 0x1f, 0x1f - beq exit + mffs fp0 + stfd fp0, OS_CONTEXT_FPSCR(context) - psq_st f0, 456(context), 0, 0 - psq_st f1, 464(context), 0, 0 - psq_st f2, 472(context), 0, 0 - psq_st f3, 480(context), 0, 0 - psq_st f4, 488(context), 0, 0 - psq_st f5, 496(context), 0, 0 - psq_st f6, 504(context), 0, 0 - psq_st f7, 512(context), 0, 0 - psq_st f8, 520(context), 0, 0 - psq_st f9, 528(context), 0, 0 - psq_st f10, 536(context), 0, 0 - psq_st f11, 544(context), 0, 0 - psq_st f12, 552(context), 0, 0 - psq_st f13, 560(context), 0, 0 - psq_st f14, 568(context), 0, 0 - psq_st f15, 576(context), 0, 0 - psq_st f16, 584(context), 0, 0 - psq_st f17, 592(context), 0, 0 - psq_st f18, 600(context), 0, 0 - psq_st f19, 608(context), 0, 0 - psq_st f20, 616(context), 0, 0 - psq_st f21, 624(context), 0, 0 - psq_st f22, 632(context), 0, 0 - psq_st f23, 640(context), 0, 0 - psq_st f24, 648(context), 0, 0 - psq_st f25, 656(context), 0, 0 - psq_st f26, 664(context), 0, 0 - psq_st f27, 672(context), 0, 0 - psq_st f28, 680(context), 0, 0 - psq_st f29, 688(context), 0, 0 - psq_st f30, 696(context), 0, 0 - psq_st f31, 704(context), 0, 0 + lfd fp0, context->fpr[0] -exit: + mfspr r5, HID2 + rlwinm. r5, r5, 3, 31, 31 + bc 12, 2, _return + + psq_st fp0, OS_CONTEXT_PSF0(context), 0, 0 + psq_st fp1, OS_CONTEXT_PSF1(context), 0, 0 + psq_st fp2, OS_CONTEXT_PSF2(context), 0, 0 + psq_st fp3, OS_CONTEXT_PSF3(context), 0, 0 + psq_st fp4, OS_CONTEXT_PSF4(context), 0, 0 + psq_st fp5, OS_CONTEXT_PSF5(context), 0, 0 + psq_st fp6, OS_CONTEXT_PSF6(context), 0, 0 + psq_st fp7, OS_CONTEXT_PSF7(context), 0, 0 + psq_st fp8, OS_CONTEXT_PSF8(context), 0, 0 + psq_st fp9, OS_CONTEXT_PSF9(context), 0, 0 + psq_st fp10, OS_CONTEXT_PSF10(context), 0, 0 + psq_st fp11, OS_CONTEXT_PSF11(context), 0, 0 + psq_st fp12, OS_CONTEXT_PSF12(context), 0, 0 + psq_st fp13, OS_CONTEXT_PSF13(context), 0, 0 + psq_st fp14, OS_CONTEXT_PSF14(context), 0, 0 + psq_st fp15, OS_CONTEXT_PSF15(context), 0, 0 + psq_st fp16, OS_CONTEXT_PSF16(context), 0, 0 + psq_st fp17, OS_CONTEXT_PSF17(context), 0, 0 + psq_st fp18, OS_CONTEXT_PSF18(context), 0, 0 + psq_st fp19, OS_CONTEXT_PSF19(context), 0, 0 + psq_st fp20, OS_CONTEXT_PSF20(context), 0, 0 + psq_st fp21, OS_CONTEXT_PSF21(context), 0, 0 + psq_st fp22, OS_CONTEXT_PSF22(context), 0, 0 + psq_st fp23, OS_CONTEXT_PSF23(context), 0, 0 + psq_st fp24, OS_CONTEXT_PSF24(context), 0, 0 + psq_st fp25, OS_CONTEXT_PSF25(context), 0, 0 + psq_st fp26, OS_CONTEXT_PSF26(context), 0, 0 + psq_st fp27, OS_CONTEXT_PSF27(context), 0, 0 + psq_st fp28, OS_CONTEXT_PSF28(context), 0, 0 + psq_st fp29, OS_CONTEXT_PSF29(context), 0, 0 + psq_st fp30, OS_CONTEXT_PSF30(context), 0, 0 + psq_st fp31, OS_CONTEXT_PSF31(context), 0, 0 + +_return: blr - // clang-format on -} \ No newline at end of file +} +#endif diff --git a/src/dolphin/os/OSError.c b/src/dolphin/os/OSError.c index 4345b772c9..5a545392f4 100644 --- a/src/dolphin/os/OSError.c +++ b/src/dolphin/os/OSError.c @@ -1,38 +1,26 @@ -#include "dolphin/os/OSError.h" -#include "dolphin/base/PPCArch.h" -#include "dolphin/dsp.h" -#include "dolphin/dvd/dvdlow.h" -#include "dolphin/os.h" +#include +#include +#include -OSThread* __OSCurrentThread : (OS_BASE_CACHED | 0x00E4); -OSThreadQueue __OSActiveThreadQueue : (OS_BASE_CACHED | 0x00DC); -volatile OSContext* __OSFPUContext : (OS_BASE_CACHED | 0x00D8); +#include "__os.h" -extern volatile u32 __OSLastInterruptSrr0; -extern volatile s16 __OSLastInterrupt; -extern volatile OSTime __OSLastInterruptTime; +OSErrorHandler __OSErrorTable[17]; -/* 8044BAD0-8044BB20 0787F0 0044+0C 2/2 2/2 0/0 .bss __OSErrorTable */ -extern OSErrorHandlerEx __OSErrorTable[16]; -OSErrorHandlerEx __OSErrorTable[16]; - -/* 804509A0-804509A4 000420 0004+00 1/1 2/2 0/0 .sdata __OSFpscrEnableBits */ #define FPSCR_ENABLE (FPSCR_VE | FPSCR_OE | FPSCR_UE | FPSCR_ZE | FPSCR_XE) -extern u32 __OSFpscrEnableBits = FPSCR_ENABLE; +u32 __OSFpscrEnableBits = FPSCR_ENABLE; -__declspec(weak) void OSReport(char* msg, ...) { +void OSReport(const char* msg, ...) { va_list marker; - va_start(marker, msg); vprintf(msg, marker); va_end(marker); } -__declspec(weak) void OSVReport(const char* msg, va_list list) { +void OSVReport(const char* msg, va_list list) { vprintf(msg, list); } -__declspec(weak) void OSPanic(const char* file, s32 line, const char* msg, ...) { +void OSPanic(const char* file, int line, const char* msg, ...) { va_list marker; u32 i; u32* p; @@ -43,45 +31,43 @@ __declspec(weak) void OSPanic(const char* file, s32 line, const char* msg, ...) va_end(marker); OSReport(" in \"%s\" on line %d.\n", file, line); - // actually useful for debugging- stack crawl OSReport("\nAddress: Back Chain LR Save\n"); - for (i = 0, p = (u32*)OSGetStackPointer(); // get current stack pointer - p && (u32)p != 0xffffffff && i++ < 16; p = (u32*)*p) // get caller stack pointer - { + for (i = 0, p = (u32*)OSGetStackPointer(); p && (u32)p != 0xffffffff && i++ < 16; p = (u32*)*p) { OSReport("0x%08x: 0x%08x 0x%08x\n", p, p[0], p[1]); } PPCHalt(); } -/* 8033C580-8033C798 336EC0 0218+00 0/0 4/4 0/0 .text OSSetErrorHandler */ OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler) { - OSErrorHandlerEx oldHandler; - BOOL enabled; + OSErrorHandler oldHandler; + int enabled; + u32 msr; + u32 fpscr; + OSThread* thread; + int i; + + ASSERTMSGLINE(209, error < 17, "OSSetErrorHandler(): unknown error."); enabled = OSDisableInterrupts(); oldHandler = __OSErrorTable[error]; - __OSErrorTable[error] = (OSErrorHandlerEx)handler; - - if (error == EXCEPTION_FLOATING_POINT_EXCEPTION) { - u32 msr; - u32 fpscr; - OSThread* thread; + __OSErrorTable[error] = handler; + if (error == __OS_EXCEPTION_FLOATING_POINT_EXCEPTION) { msr = PPCMfmsr(); PPCMtmsr(msr | MSR_FP); fpscr = PPCMffpscr(); + if (handler) { for (thread = __OSActiveThreadQueue.head; thread; - thread = thread->active_threads_link.next) + thread = thread->linkActive.next) { thread->context.srr1 |= MSR_FE0 | MSR_FE1; if ((thread->context.state & OS_CONTEXT_STATE_FPSAVED) == 0) { - int i; thread->context.state |= OS_CONTEXT_STATE_FPSAVED; for (i = 0; i < 32; ++i) { *(u64*)&thread->context.fpr[i] = (u64)0xffffffffffffffffLL; - *(u64*)&thread->context.ps[i] = (u64)0xffffffffffffffffLL; + *(u64*)&thread->context.psf[i] = (u64)0xffffffffffffffffLL; } thread->context.fpscr = FPSCR_NI; } @@ -95,7 +81,7 @@ OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler) { msr |= MSR_FE0 | MSR_FE1; } else { for (thread = __OSActiveThreadQueue.head; thread; - thread = thread->active_threads_link.next) + thread = thread->linkActive.next) { thread->context.srr1 &= ~(MSR_FE0 | MSR_FE1); thread->context.fpscr &= ~FPSCR_ENABLE; @@ -120,23 +106,22 @@ OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler) { return oldHandler; } -/* 8033C798-8033CA80 3370D8 02E8+00 1/0 2/2 0/0 .text __OSUnhandledException */ +volatile OSContext* __OSFPUContext AT_ADDRESS(OS_BASE_CACHED | 0x00D8); + void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar) { OSTime now; + u32 fpscr; + u32 msr; now = OSGetTime(); - if (!(context->srr1 & 2)) { + if (!(context->srr1 & MSR_RI)) { OSReport("Non-recoverable Exception %d", exception); - } else { - if (exception == EXCEPTION_PROGRAM && (context->srr1 & (0x80000000 >> 11)) && - __OSErrorTable[EXCEPTION_FLOATING_POINT_EXCEPTION] != 0) + if (exception == __OS_EXCEPTION_PROGRAM && (context->srr1 & (0x80000000 >> 11)) && + __OSErrorTable[__OS_EXCEPTION_FLOATING_POINT_EXCEPTION] != 0) { - u32 fpscr; - u32 msr; - - exception = EXCEPTION_FLOATING_POINT_EXCEPTION; + exception = __OS_EXCEPTION_FLOATING_POINT_EXCEPTION; msr = PPCMfmsr(); PPCMtmsr(msr | 0x2000); @@ -180,52 +165,51 @@ void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsi __OSReschedule(); OSLoadContext(context); } - - if (exception == OS_ERROR_DECREMENTER) { + if (exception == __OS_EXCEPTION_DECREMENTER) { OSLoadContext(context); } - OSReport("Unhandled Exception %d", exception); } - +#if DEBUG + OSReport("(%s)", __OSExceptionNames[exception]); +#endif OSReport("\n"); OSDumpContext(context); OSReport("\nDSISR = 0x%08x DAR = 0x%08x\n", dsisr, dar); OSReport("TB = 0x%016llx\n", now); - switch (exception) { - case EXCEPTION_DSI: + switch(exception) { + case __OS_EXCEPTION_DSI: OSReport("\nInstruction at 0x%x (read from SRR0) attempted to access " - "invalid address 0x%x (read from DAR)\n", - context->srr0, dar); + "invalid address 0x%x (read from DAR)\n", + context->srr0, dar); break; - case EXCEPTION_ISI: + case __OS_EXCEPTION_ISI: OSReport("\nAttempted to fetch instruction from invalid address 0x%x " - "(read from SRR0)\n", - context->srr0); + "(read from SRR0)\n", + context->srr0); break; - case EXCEPTION_ALIGNMENT: + case __OS_EXCEPTION_ALIGNMENT: OSReport("\nInstruction at 0x%x (read from SRR0) attempted to access " - "unaligned address 0x%x (read from DAR)\n", - context->srr0, dar); + "unaligned address 0x%x (read from DAR)\n", + context->srr0, dar); break; - case EXCEPTION_PROGRAM: + case __OS_EXCEPTION_PROGRAM: OSReport("\nProgram exception : Possible illegal instruction/operation " - "at or around 0x%x (read from SRR0)\n", - context->srr0, dar); + "at or around 0x%x (read from SRR0)\n", + context->srr0, dar); break; - case EXCEPTION_MEMORY_PROTECTION: + case __OS_EXCEPTION_MEMORY_PROTECTION: OSReport("\n"); OSReport("AI DMA Address = 0x%04x%04x\n", __DSPRegs[DSP_DMA_START_HI], - __DSPRegs[DSP_DMA_START_LO]); + __DSPRegs[DSP_DMA_START_LO]); OSReport("ARAM DMA Address = 0x%04x%04x\n", __DSPRegs[DSP_ARAM_DMA_MM_HI], - __DSPRegs[DSP_ARAM_DMA_MM_LO]); + __DSPRegs[DSP_ARAM_DMA_MM_LO]); OSReport("DI DMA Address = 0x%08x\n", __DIRegs[5]); break; } OSReport("\nLast interrupt (%d): SRR0 = 0x%08x TB = 0x%016llx\n", __OSLastInterrupt, __OSLastInterruptSrr0, __OSLastInterruptTime); - PPCHalt(); -} \ No newline at end of file +} diff --git a/src/dolphin/os/OSExec.c b/src/dolphin/os/OSExec.c index 1f20351ec8..9033bc44c2 100644 --- a/src/dolphin/os/OSExec.c +++ b/src/dolphin/os/OSExec.c @@ -1,17 +1,15 @@ -// -// Generated By: dol2asm -// Translation Unit: OSExec -// +#include +#include -#include "dolphin/os/OSExec.h" -#include "dolphin/os.h" -#include "dolphin/ai.h" -#include "dolphin/macros.h" -#include "dol2asm.h" -#include "string.h" -#include "printf.h" +#include "__os.h" +#include "__dvd.h" + +extern volatile u32 BOOT_REGION_START AT_ADDRESS(0x812FDFF0); +extern volatile u32 BOOT_REGION_END AT_ADDRESS(0x812FDFEC); +extern volatile u8 g_unk_800030E2 AT_ADDRESS(0x800030E2); + +static int Prepared; -/* 8033CA80-8033CC08 3373C0 0188+00 1/1 0/0 0/0 .text PackArgs */ static int PackArgs(void* addr, s32 argc, char** argv) { s32 numArgs; char* bootInfo2; @@ -44,7 +42,7 @@ static int PackArgs(void* addr, s32 argc, char** argv) { ptr -= 4; *(u32*)ptr = numArgs; - ASSERTMSGLINE(0x81, ptr - bootInfo2 >= 0x1000U, "OSExec: Argument list is too long"); + ASSERTMSGLINE(LINE(129, 138, 140), ptr - bootInfo2 >= 0x1000U, "OSExec: Argument list is too long"); *(u32*)(bootInfo2 + 8) = (ptr - bootInfo2); } @@ -52,7 +50,7 @@ static int PackArgs(void* addr, s32 argc, char** argv) { return 1; } -/* 8033CC08-8033CC44 337548 003C+00 1/1 0/0 0/0 .text Run */ +#ifdef __GEKKO__ static asm void Run(register void* entryPoint) { nofralloc @@ -73,6 +71,7 @@ static asm void Run(register void* entryPoint) { mtlr r0 blr } +#endif static void StartDol(const OSExecParams* params, void* entry) { OSExecParams* paramsWork = OSAllocFromArenaLo(sizeof(OSExecParams), 1); @@ -84,61 +83,77 @@ static void StartDol(const OSExecParams* params, void* entry) { Run(entry); } -/* 8033CC44-8033CCB0 337584 006C+00 1/1 0/0 0/0 .text ReadDisc */ -static void ReadDisc(void* param_0, s32 param_1, s32 param_2) { - DVDCommandBlock cmd; - DVDReadAbsAsyncPrio(&cmd, param_0, param_1, param_2, NULL, 0); - while (DVDGetCommandBlockStatus(&cmd)) { - if (!DVDCheckDisk()) { +static void ReadDisc(void* addr, s32 length, s32 offset) { + DVDCommandBlock block; +#if SDK_REVISION < 1 + OSTime start; +#endif + + DVDReadAbsAsyncPrio(&block, addr, length, offset, NULL, 0); + +#if SDK_REVISION < 1 + start = OSGetTime(); +#endif + + while (DVDGetCommandBlockStatus(&block)) { +#if SDK_REVISION < 1 + if (!DVDCheckDisk() || OS_TIMER_CLOCK < (OSGetTime() - start)) +#else + if (!DVDCheckDisk()) +#endif + { __OSDoHotReset(0); } } } -/* ############################################################################################## */ -/* 80451658-8045165C 000B58 0004+00 2/2 0/0 0/0 .sbss Prepared */ -static BOOL Prepared; - -/* 8033CCB0-8033CCBC 3375F0 000C+00 1/1 0/0 0/0 .text Callback */ static void Callback(s32, DVDCommandBlock*) { Prepared = TRUE; } -OSExecParams* osExecParams AT_ADDRESS(0x800030f0); - static int IsStreamEnabled() { - if (DVDGetCurrentDiskID()->is_streaming) { + if (DVDGetCurrentDiskID()->streaming) { return TRUE; } return FALSE; } -/* 8033CCBC-8033CCFC 3375FC 0040+00 0/0 1/1 0/0 .text __OSGetExecParams */ -void __OSGetExecParams(OSExecParams* param_0) { - if (OSPhysicalToCached(0) <= osExecParams) { - memcpy(param_0, osExecParams, sizeof(OSExecParams)); +void __OSGetExecParams(OSExecParams* params) { + if (0x80000000 <= (u32)__OSExecParams) { + memcpy(params, __OSExecParams, sizeof(OSExecParams)); } else { - param_0->valid = FALSE; + params->valid = FALSE; } } -__OSSetExecParams(const OSExecParams* src, OSExecParams* dst) { - memcpy(dst, src, sizeof(OSExecParams)); - osExecParams = dst; +void __OSSetExecParams(const OSExecParams* params, OSExecParams* addr) { + memcpy(addr, params, sizeof(OSExecParams)); + __OSExecParams = addr; } static void StopStreaming() { DVDCommandBlock block; - s64 start; +#if SDK_REVISION < 1 + OSTime start; +#endif if (!__OSIsGcam && IsStreamEnabled()) { AISetStreamVolLeft(0); AISetStreamVolRight(0); DVDCancelStreamAsync(&block, NULL); +#if SDK_REVISION < 1 + start = OSGetTime(); +#endif + while (DVDGetCommandBlockStatus(&block)) { - if (!DVDCheckDisk()) { +#if SDK_REVISION < 1 + if (!DVDCheckDisk() || OS_TIMER_CLOCK < (OSGetTime() - start)) +#else + if (!DVDCheckDisk()) +#endif + { __OSDoHotReset(0); } } @@ -147,9 +162,6 @@ static void StopStreaming() { } } -/* 8033CCFC-8033CDC0 33763C 00C4+00 1/1 0/0 0/0 .text GetApploaderPosition */ -s32 __OSAppLoaderOffset AT_ADDRESS(0x800030f4); - static int GetApploaderPosition(void) { static s32 apploaderPosition; @@ -161,10 +173,10 @@ static int GetApploaderPosition(void) { } if (__OSAppLoaderOffset != 0) { - tgcHeader = OSAllocFromArenaLo(0x40, 0x20); + tgcHeader = OSAllocFromArenaLo(0x40, DOLPHIN_ALIGNMENT); ReadDisc(tgcHeader, 0x40, __OSAppLoaderOffset); apploaderOffsetInTGC = tgcHeader[14]; - ASSERTMSGLINE(0x172, apploaderOffsetInTGC != 0, "OSExec() or OSResetSystem(): Wrong apploader offset. Maybe converted by an\nolder version of gcm2tgc. Use gcm2tgc v.1.20 or later."); + ASSERTMSGLINE(LINE(370, 376, 378), apploaderOffsetInTGC != 0, "OSExec() or OSResetSystem(): Wrong apploader offset. Maybe converted by an\nolder version of gcm2tgc. Use gcm2tgc v.1.20 or later."); apploaderPosition = __OSAppLoaderOffset + apploaderOffsetInTGC; } else { @@ -174,20 +186,19 @@ static int GetApploaderPosition(void) { } typedef struct { - // total size: 0x20 - char date[16]; // offset 0x0, size 0x10 - u32 entry; // offset 0x10, size 0x4 - u32 size; // offset 0x14, size 0x4 - u32 rebootSize; // offset 0x18, size 0x4 - u32 reserved2; // offset 0x1C, size 0x4 + char date[16]; + u32 entry; + u32 size; + u32 rebootSize; + u32 reserved2; } AppLoaderStruct; static AppLoaderStruct* LoadApploader() { AppLoaderStruct* header; - header = (AppLoaderStruct*)OSAllocFromArenaLo(sizeof(AppLoaderStruct), 0x20); + header = (AppLoaderStruct*)OSAllocFromArenaLo(sizeof(AppLoaderStruct), DOLPHIN_ALIGNMENT); ReadDisc(header, sizeof(AppLoaderStruct), GetApploaderPosition()); - ASSERTMSGLINE(0x191, header->rebootSize != 0, "OSResetSystem(): old apploader"); + ASSERTMSGLINE(LINE(401, 407, 409), header->rebootSize != 0, "OSResetSystem(): old apploader"); ReadDisc((void*)0x81200000, OSRoundUp32B(header->size), GetApploaderPosition() + 0x20); ICInvalidateRange((void*)0x81200000, OSRoundUp32B(header->size)); @@ -206,7 +217,7 @@ static void* LoadDol(const OSExecParams* params, AppLoaderCallback getInterface) getInterface(&appInit, &appGetNext, &appGetEntry); paramsWork = (OSExecParams*)OSAllocFromArenaLo(sizeof(OSExecParams), 1); __OSSetExecParams(params, paramsWork); - appInit(OSReport); + appInit((void(*)(char*))OSReport); OSSetArenaLo(paramsWork); while (appGetNext(&addr, &length, &offset) != 0) { @@ -220,16 +231,15 @@ static BOOL IsNewApploader(AppLoaderStruct* header) { return strncmp(header->date, "2004/02/01", 10) > 0 ? TRUE : FALSE; } -extern volatile u32 BOOT_REGION_START AT_ADDRESS(0x812FDFF0); -extern volatile u32 BOOT_REGION_END AT_ADDRESS(0x812FDFEC); -extern volatile u8 g_unk_800030E2 AT_ADDRESS(0x800030E2); - -/* 8033CDC0-8033D244 337700 0484+00 1/1 0/0 0/0 .text __OSBootDolSimple */ void __OSBootDolSimple(u32 doloffset, u32 restartCode, void* regionStart, void* regionEnd, BOOL argsUseDefault, s32 argc, char** argv) { OSExecParams* params; void* dolEntry; AppLoaderStruct* header; +#if SDK_REVISION < 1 + OSTime start; +#endif + OSDisableInterrupts(); params = (OSExecParams*)OSAllocFromArenaLo(sizeof(OSExecParams), 1); params->valid = TRUE; @@ -254,8 +264,17 @@ void __OSBootDolSimple(u32 doloffset, u32 restartCode, void* regionStart, void* __OSUnmaskInterrupts(0x400); OSEnableInterrupts(); +#if SDK_REVISION < 1 + start = OSGetTime(); +#endif + while (Prepared != TRUE) { - if (!DVDCheckDisk()) { +#if SDK_REVISION < 1 + if (!DVDCheckDisk() || OS_TIMER_CLOCK < (OSGetTime() - start)) +#else + if (!DVDCheckDisk()) +#endif + { __OSDoHotReset(0); } } @@ -284,7 +303,6 @@ void __OSBootDolSimple(u32 doloffset, u32 restartCode, void* regionStart, void* } } -/* 8033D244-8033D3E0 337B84 019C+00 0/0 1/1 0/0 .text __OSBootDol */ void __OSBootDol(u32 doloffset, u32 restartCode, const char** argv) { char doloffInString[20]; s32 argvlen; @@ -313,3 +331,72 @@ void __OSBootDol(u32 doloffset, u32 restartCode, const char** argv) { __OSBootDolSimple(-1, restartCode, saveStart, saveEnd, FALSE, argvlen, argvToPass); } + +static void ExecCommon(const char* dolfile, const char** argv) { + DVDFileInfo fileInfo; + u32 doloff; + + if ((s8)*dolfile == '\0') { + doloff = 0; + } else if (DVDOpen((char*)dolfile, &fileInfo)) { + doloff = fileInfo.startAddr; + } else { + ASSERTMSGLINE(LINE(689, 695, 697), 0, "OSExec(): The specified file doesn't exist"); + return; + } + + __OSBootDol(doloff, 0xC0000000, argv); +} + +void OSExecv(const char* dolfile, const char** argv) { + ASSERTMSGLINE(LINE(718, 724, 726), dolfile != 0, "OSExecv(): null pointer was specified for the dol file name."); + ASSERTMSGLINE(LINE(719, 725, 727), argv != 0, "OSExecv(): null pointer was specified for argv."); + + OSDisableScheduler(); + __OSShutdownDevices(FALSE); + OSEnableScheduler(); + OSSetArenaLo((void*)0x81280000); + OSSetArenaHi((void*)0x812F0000); + ExecCommon(dolfile, argv); +} + +void OSExecl(const char* dolfile, const char* arg0, ...) { + va_list vl; + char* ptr; + s32 i; + char** argv; + + ASSERTMSGLINE(LINE(759, 765, 767), dolfile != 0, "OSExecl(): null pointer was specified for the dol file name."); + + OSDisableScheduler(); + __OSShutdownDevices(FALSE); + OSEnableScheduler(); + OSSetArenaLo((void*)0x81280000); + OSSetArenaHi((void*)0x812F0000); + + argv = OSAllocFromArenaLo(4, 0x1000); + va_start(vl, arg0); +#if SDK_REVISION < 2 + *argv = (char*)arg0; + + i = 1; + do { + ptr = va_arg(vl, char*); + argv[i++] = ptr; + } while (ptr != 0); +#else + i = 0; + ptr = (char*)arg0; + goto setarg; + + do { + ptr = va_arg(vl, char*); +setarg: + argv[i++] = ptr; + } while (ptr != 0); +#endif + va_end(vl); + ASSERTMSGLINE(LINE(787, 793, 794), i < 0x400U, "OSExecl(): Arguments too long"); + + ExecCommon(dolfile, argv); +} diff --git a/src/dolphin/os/OSFatal.c b/src/dolphin/os/OSFatal.c new file mode 100644 index 0000000000..673ddf90db --- /dev/null +++ b/src/dolphin/os/OSFatal.c @@ -0,0 +1,246 @@ +#include +#include +#include +#include + +#include "__os.h" + +typedef struct OSFatalParam { + GXColor fg; + GXColor bg; + const char* msg; +} OSFatalParam; + +static OSFatalParam FatalParam; +static OSContext FatalContext; + +// prototypes +static void Halt(); + +static void ScreenClear(void* xfb, u16 xfbW, u16 xfbH, GXColor yuv) { + int i; + int j; + u8* ptr; + + ptr = xfb; + for (i = 0; i < xfbH; i++) { + for (j = 0; j < xfbW; j += 2) { + *ptr++ = yuv.r; + *ptr++ = yuv.g; + *ptr++ = yuv.r; + *ptr++ = yuv.b; + } + } +} + +static void ScreenReport(void* xfb, u16 xfbW, u16 xfbH, GXColor yuv, s32 x, s32 y, s32 leading, const char* string) { + u8* ptr; + s32 width; + u32 i; + u32 j; + u32 image[72]; + u32 k; + u32 l; + u8 Y; + u32 pixel; + s32 col; + +loop_1: + if (xfbH - 24 >= y) { + ptr = (u8*)xfb + ((x + (y * xfbW)) * 2); + col = x; + + while ((s8)*string != 0) { + if ((s8)*string == '\n') { + string++; + y += leading; + goto loop_1; + } + + if (xfbW - 48 < col) { + y += leading; + goto loop_1; + } + + for (i = 0; i < 24; i++) { + j = (i & 7) + ((i >> 3) * 24); + image[j + 0 ] = 0; + image[j + 8 ] = 0; + image[j + 16] = 0; + } + + string = OSGetFontTexel((char*)string, image, 0, 6, &width); + + for (i = 0; i < 24; i++) { + j = (i & 7) + ((i >> 3) * 24); + + for (k = 0; k < 24; k++) { + l = j + (k & 0xFFFFFFF8); + + Y = (image[l] >> ((7 - (k & 7)) * 4)) & 0xF; + if (Y != 0) { + Y = (((yuv.r * (Y * 0xEF)) / 255) / 15) + 0x10; + pixel = k + (i * xfbW); + ptr[pixel * 2] = Y; + + if ((col + k) & 1) { + ptr[(pixel * 2) - 1] = yuv.g; + ptr[(pixel * 2) + 1] = yuv.b; + } else { + ptr[(pixel * 2) - 1] = yuv.b; + ptr[(pixel * 2) + 1] = yuv.g; + } + } + } + } + + ptr += width * 2; + col += width; + } + } +} + +static void ConfigureVideo(u16 xfbW, u16 xfbH) { + GXRenderModeObj mode; + mode.fbWidth = xfbW; + mode.efbHeight = 480; + mode.xfbHeight = xfbH; + mode.viXOrigin = 40; + mode.viWidth = 640; + mode.viHeight = xfbH; + + switch (VIGetTvFormat()) { + case 2: + case 0: + if (__VIRegs[54] & 1) { + mode.viTVmode = 2; + mode.viYOrigin = 0; + mode.xFBmode = 0; + } else { + mode.viTVmode = 0; + mode.viYOrigin = 0; + mode.xFBmode = 1; + } + break; + case 5: + mode.viTVmode = 20; + mode.viYOrigin = 0; + mode.xFBmode = 1; + break; + case 1: + mode.viTVmode = 4; + mode.viYOrigin = 47; + mode.xFBmode = 1; + break; + } + + VIConfigure(&mode); + VIConfigurePan(0, 0, 640, 480); +} + +static GXColor RGB2YUV(GXColor rgb) { + f32 Y; + f32 Cb; + f32 Cr; + GXColor yuv; + + Y = 0.5f + (16.0f + ((0.098f * (f32) rgb.b) + ((0.257f * (f32) rgb.r) + (0.504f * (f32) rgb.g)))); + Cb = 0.5f + (128.0f + ((0.439f * (f32) rgb.b) + ((-0.148f * (f32) rgb.r) - (0.291f * (f32) rgb.g)))); + Cr = 0.5f + (128.0f + (((0.439f * (f32) rgb.r) - (0.368f * (f32) rgb.g)) - (0.071f * (f32) rgb.b))); + + yuv.r = (Y > 235.0f) ? 235.0f : (Y < 16.0f) ? 16.0f : Y; + yuv.g = (Cb > 240.0f) ? 240.0f : (Cb < 16.0f) ? 16.0f : Cb; + yuv.b = (Cr > 240.0f) ? 240.0f : (Cr < 16.0f) ? 16.0f : Cr; + yuv.a = 0; + + return yuv; +} + +void OSFatal(GXColor fg, GXColor bg, const char* msg) { + OSBootInfo* bootInfo; + u32 count; + OSTime t; + + bootInfo = (OSBootInfo*)OSPhysicalToCached(0); + OSDisableInterrupts(); + OSDisableScheduler(); + OSClearContext(&FatalContext); + OSSetCurrentContext(&FatalContext); + __OSStopAudioSystem(); + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + VIInit(); + __OSUnmaskInterrupts(0x80); + VISetBlack(TRUE); + VIFlush(); + VISetPreRetraceCallback(NULL); + VISetPostRetraceCallback(NULL); + OSEnableInterrupts(); + + count = VIGetRetraceCount(); + do {} while ((s32)(VIGetRetraceCount() - count) < 1); + + t = OSGetTime(); + while (!__OSCallResetFunctions(FALSE) && OSGetTime() - t < OSMillisecondsToTicks(1000)) {} + + OSDisableInterrupts(); + __OSCallResetFunctions(TRUE); + EXISetExiCallback(0, NULL); + EXISetExiCallback(2, NULL); + + while (!EXILock(0, 1, NULL)) { + EXISync(0); + EXIDeselect(0); + EXIUnlock(0); + } + EXIUnlock(0); + + do {} while ((__EXIRegs[3] & 1) == 1); + + __OSSetExceptionHandler(8, &OSDefaultExceptionHandler); + GXAbortFrame(); + OSSetArenaLo((void*)0x81400000); + OSSetArenaHi(bootInfo->FSTLocation); + + FatalParam.fg = fg; + FatalParam.bg = bg; + FatalParam.msg = msg; + OSSwitchFiber((u32)&Halt, (u32)OSGetArenaHi()); +} + +static void Halt() { + u32 count; + OSFontHeader* fontData; + void* xfb; + u32 len; + OSFatalParam* fp; + + OSEnableInterrupts(); + fp = &FatalParam; + len = strlen(fp->msg) + 1; + fp->msg = memmove(OSAllocFromArenaLo(len, DOLPHIN_ALIGNMENT), fp->msg, len); + + fontData = OSAllocFromArenaLo(0xA1004, DOLPHIN_ALIGNMENT); + OSLoadFont(fontData, OSGetArenaLo()); + + xfb = OSAllocFromArenaLo(0x96000, DOLPHIN_ALIGNMENT); + ScreenClear(xfb, 640, 480, RGB2YUV(fp->bg)); + VISetNextFrameBuffer(xfb); + ConfigureVideo(640, 480); + VIFlush(); + + count = VIGetRetraceCount(); + do {} while ((s32)(VIGetRetraceCount() - count) < 2); + + ScreenReport(xfb, 640, 480, RGB2YUV(fp->fg), 48, 100, fontData->leading, fp->msg); + DCFlushRange(xfb, 0x96000); + VISetBlack(FALSE); + VIFlush(); + + count = VIGetRetraceCount(); + do {} while ((s32)(VIGetRetraceCount() - count) < 1); + + OSDisableInterrupts(); + OSReport("%s\n", fp->msg); + PPCHalt(); +} diff --git a/src/dolphin/os/OSFont.c b/src/dolphin/os/OSFont.c index c4f28bd1c3..4e6738bf7e 100644 --- a/src/dolphin/os/OSFont.c +++ b/src/dolphin/os/OSFont.c @@ -1,237 +1,250 @@ -#include "dolphin/os/OSFont.h" -#include "dolphin/os.h" -#include "dolphin/vi.h" +#include +#include -/* ############################################################################################## */ -/* 803CFC48-803CFDC8 02CD68 0180+00 1/1 0/0 0/0 .data HankakuToCode */ -static u16 HankakuToCode[192] = { - 0x020C, 0x020D, 0x020E, 0x020F, 0x0210, 0x0211, 0x0212, 0x0213, - 0x0214, 0x0215, 0x0216, 0x0217, 0x0218, 0x0219, 0x021A, 0x021B, - 0x021C, 0x021D, 0x021E, 0x021F, 0x0220, 0x0221, 0x0222, 0x0223, - 0x0224, 0x0225, 0x0226, 0x0227, 0x0228, 0x0229, 0x022A, 0x022B, - 0x022C, 0x022D, 0x022E, 0x022F, 0x0230, 0x0231, 0x0232, 0x0233, - 0x0234, 0x0235, 0x0236, 0x0237, 0x0238, 0x0239, 0x023A, 0x023B, - 0x023C, 0x023D, 0x023E, 0x023F, 0x0240, 0x0241, 0x0242, 0x0243, - 0x0244, 0x0245, 0x0246, 0x0247, 0x0248, 0x0249, 0x024A, 0x024B, - 0x024C, 0x024D, 0x024E, 0x024F, 0x0250, 0x0251, 0x0252, 0x0253, - 0x0254, 0x0255, 0x0256, 0x0257, 0x0258, 0x0259, 0x025A, 0x025B, - 0x025C, 0x025D, 0x025E, 0x025F, 0x0260, 0x0261, 0x0262, 0x0263, - 0x0264, 0x0265, 0x0266, 0x0267, 0x0268, 0x0269, 0x026A, 0x020C, - 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, - 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, - 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, - 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, - 0x020C, 0x026B, 0x026C, 0x026D, 0x026E, 0x026F, 0x0270, 0x0271, - 0x0272, 0x0273, 0x0274, 0x0275, 0x0276, 0x0277, 0x0278, 0x0279, - 0x027A, 0x027B, 0x027C, 0x027D, 0x027E, 0x027F, 0x0280, 0x0281, - 0x0282, 0x0283, 0x0284, 0x0285, 0x0286, 0x0287, 0x0288, 0x0289, - 0x028A, 0x028B, 0x028C, 0x028D, 0x028E, 0x028F, 0x0290, 0x0291, - 0x0292, 0x0293, 0x0294, 0x0295, 0x0296, 0x0297, 0x0298, 0x0299, - 0x029A, 0x029B, 0x029C, 0x029D, 0x029E, 0x029F, 0x02A0, 0x02A1, - 0x02A2, 0x02A3, 0x02A4, 0x02A5, 0x02A6, 0x02A7, 0x02A8, 0x02A9, -}; +#include "__os.h" -/* 803CFDC8-803D0758 02CEE8 098A+06 1/1 0/0 0/0 .data Zenkaku2Code */ -static u16 Zenkaku2Code[1221] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, - 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, - 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, - 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, - 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, - 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, - 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, - 0x0068, 0x0069, 0x006A, 0x006B, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x006C, - 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0074, - 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x0080, 0x0081, - 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x008A, - 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, 0x0090, 0x0091, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0092, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, - 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x009D, 0x009E, 0x009F, 0x00A0, - 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, - 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, - 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x00B7, 0x00B8, 0x00B9, 0x00BA, - 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, 0x00C0, 0x00C1, 0x00C2, - 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, - 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x00D0, 0x0000, 0x0000, - 0x0000, 0x0000, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, - 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, - 0x00DF, 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, - 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, - 0x00EF, 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, - 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, - 0x00FF, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, - 0x0107, 0x0108, 0x0109, 0x010A, 0x010B, 0x010C, 0x010D, 0x010E, - 0x010F, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, - 0x0117, 0x0118, 0x0119, 0x011A, 0x011B, 0x011C, 0x011D, 0x011E, - 0x011F, 0x0120, 0x0121, 0x0122, 0x0123, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0124, 0x0125, 0x0126, 0x0127, 0x0128, 0x0129, 0x012A, 0x012B, - 0x012C, 0x012D, 0x012E, 0x012F, 0x0130, 0x0131, 0x0132, 0x0133, - 0x0134, 0x0135, 0x0136, 0x0137, 0x0138, 0x0139, 0x013A, 0x013B, - 0x013C, 0x013D, 0x013E, 0x013F, 0x0140, 0x0141, 0x0142, 0x0143, - 0x0144, 0x0145, 0x0146, 0x0147, 0x0148, 0x0149, 0x014A, 0x014B, - 0x014C, 0x014D, 0x014E, 0x014F, 0x0150, 0x0151, 0x0152, 0x0153, - 0x0154, 0x0155, 0x0156, 0x0157, 0x0158, 0x0159, 0x015A, 0x015B, - 0x015C, 0x015D, 0x015E, 0x015F, 0x0160, 0x0161, 0x0162, 0x0163, - 0x0164, 0x0165, 0x0166, 0x0167, 0x0168, 0x0169, 0x016A, 0x016B, - 0x016C, 0x016D, 0x016E, 0x016F, 0x0170, 0x0171, 0x0172, 0x0173, - 0x0174, 0x0175, 0x0176, 0x0177, 0x0178, 0x0179, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x017A, 0x017B, - 0x017C, 0x017D, 0x017E, 0x017F, 0x0180, 0x0181, 0x0182, 0x0183, - 0x0184, 0x0185, 0x0186, 0x0187, 0x0188, 0x0189, 0x018A, 0x018B, - 0x018C, 0x018D, 0x018E, 0x018F, 0x0190, 0x0191, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0193, - 0x0194, 0x0195, 0x0196, 0x0197, 0x0198, 0x0199, 0x019A, 0x019B, - 0x019C, 0x019D, 0x019E, 0x019F, 0x01A0, 0x01A1, 0x01A2, 0x01A3, - 0x01A4, 0x01A5, 0x01A6, 0x01A7, 0x01A8, 0x01A9, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x01AA, 0x01AB, 0x01AC, 0x01AD, - 0x01AE, 0x01AF, 0x01B0, 0x01B1, 0x01B2, 0x01B3, 0x01B4, 0x01B5, - 0x01B6, 0x01B7, 0x01B8, 0x01B9, 0x01BA, 0x01BB, 0x01BC, 0x01BD, - 0x01BE, 0x01BF, 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C5, - 0x01C6, 0x01C7, 0x01C8, 0x01C9, 0x01CA, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x01CB, 0x01CC, 0x01CD, 0x01CE, - 0x01CF, 0x01D0, 0x01D1, 0x01D2, 0x01D3, 0x01D4, 0x01D5, 0x01D6, - 0x01D7, 0x01D8, 0x01D9, 0x01DA, 0x01DB, 0x01DC, 0x01DD, 0x01DE, - 0x01DF, 0x01E0, 0x01E1, 0x01E2, 0x01E3, 0x01E4, 0x01E5, 0x01E6, - 0x01E7, 0x01E8, 0x01E9, 0x01EA, 0x01EB, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x01EC, 0x01ED, 0x01EE, 0x01EF, 0x01F0, 0x01F1, - 0x01F2, 0x01F3, 0x01F4, 0x01F5, 0x01F6, 0x01F7, 0x01F8, 0x01F9, - 0x01FA, 0x01FB, 0x01FC, 0x01FD, 0x01FE, 0x01FF, 0x0200, 0x0201, - 0x0202, 0x0203, 0x0204, 0x0205, 0x0206, 0x0207, 0x0208, 0x0209, - 0x020A, 0x020B, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x020C, - 0x020D, 0x020E, 0x020F, 0x0210, 0x0211, 0x0212, 0x0213, 0x0214, - 0x0215, 0x0216, 0x0217, 0x0218, 0x0219, 0x021A, 0x021B, 0x021C, - 0x021D, 0x021E, 0x021F, 0x0220, 0x0221, 0x0222, 0x0223, 0x0224, - 0x0225, 0x0226, 0x0227, 0x0228, 0x0229, 0x022A, 0x022B, 0x022C, - 0x022D, 0x022E, 0x022F, 0x0230, 0x0231, 0x0232, 0x0233, 0x0234, - 0x0235, 0x0236, 0x0237, 0x0238, 0x0239, 0x023A, 0x023B, 0x023C, - 0x023D, 0x023E, 0x023F, 0x0240, 0x0241, 0x0242, 0x0243, 0x0244, - 0x0245, 0x0246, 0x0247, 0x0248, 0x0249, 0x024A, 0x024B, 0x024C, - 0x024D, 0x024E, 0x024F, 0x0250, 0x0251, 0x0252, 0x0253, 0x0254, - 0x0255, 0x0256, 0x0257, 0x0258, 0x0259, 0x025A, 0x025B, 0x025C, - 0x025D, 0x025E, 0x025F, 0x0260, 0x0261, 0x0262, 0x0263, 0x0264, - 0x0265, 0x0266, 0x0267, 0x0268, 0x0269, 0x026A, 0x026B, 0x026C, - 0x026D, 0x026E, 0x026F, 0x0270, 0x0271, 0x0272, 0x0273, 0x0274, - 0x0275, 0x0276, 0x0277, 0x0278, 0x0279, 0x027A, 0x027B, 0x027C, - 0x027D, 0x027E, 0x027F, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, - 0x0285, 0x0286, 0x0287, 0x0288, 0x0289, 0x028A, 0x028B, 0x028C, - 0x028D, 0x028E, 0x028F, 0x0290, 0x0291, 0x0292, 0x0293, 0x0294, - 0x0295, 0x0296, 0x0297, 0x0298, 0x0299, 0x029A, 0x029B, 0x029C, - 0x029D, 0x029E, 0x029F, 0x02A0, 0x02A1, 0x02A2, 0x02A3, 0x02A4, - 0x02A5, 0x02A6, 0x02A7, 0x02A8, 0x02A9, 0x02AA, 0x02AB, 0x02AC, - 0x02AD, 0x02AE, 0x02AF, 0x02B0, 0x02B1, 0x02B2, 0x02B3, 0x02B4, - 0x02B5, 0x02B6, 0x02B7, 0x02B8, 0x02B9, 0x02BA, 0x02BB, 0x02BC, - 0x02BD, 0x02BE, 0x02BF, 0x02C0, 0x02C1, 0x02C2, 0x02C3, 0x02C4, - 0x02C5, 0x02C6, 0x02C7, 0x02C8, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x02C9, 0x02CA, 0x02CB, 0x02CC, 0x02CD, 0x02CE, 0x02CF, 0x02D0, - 0x02D1, 0x02D2, 0x02D3, 0x02D4, 0x02D5, 0x02D6, 0x02D7, 0x02D8, - 0x02D9, 0x02DA, 0x02DB, 0x02DC, 0x02DD, 0x02DE, 0x02DF, 0x02E0, - 0x02E1, 0x02E2, 0x02E3, 0x02E4, 0x02E5, 0x02E6, 0x0000, 0x02E7, - 0x02E8, 0x02E9, 0x02EA, 0x02EB, 0x02EC, 0x02ED, 0x02EE, 0x02EF, - 0x02F0, 0x02F1, 0x02F2, 0x02F3, 0x02F4, 0x02F5, 0x02F6, 0x02F7, - 0x02F8, 0x02F9, 0x02FA, 0x02FB, 0x02FC, 0x02FD, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x02FE, 0x02FF, - 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, - 0x0308, 0x0309, 0x030A, 0x030B, 0x030C, 0x030D, 0x030E, 0x030F, - 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317, - 0x0318, 0x0319, 0x031A, 0x031B, 0x0000, -}; +typedef char* (*ParseStringCallback)(u16, char*, OSFontHeader**, int*); -static BOOL IsSjisLeadByte(u8 ch) { - return (0x81 <= ch && ch <= 0x9F) || (0xE0 <= ch && ch <= 0xFC); +static OSFontHeader* FontDataAnsi; +static OSFontHeader* FontDataSjis; +static int FixedPitch; +static ParseStringCallback ParseString; +static u16 FontEncode = 0xFFFF; + +// prototypes +static char* ParseStringS(u16 encode, const char* string, OSFontHeader** pfont, int* pfontCode); +static char* ParseStringW(u16 encode, const char* string, OSFontHeader** pfont, int* pfontCode); + +static u16 HankakuToCode[] + = { 0x20C, 0x20D, 0x20E, 0x20F, 0x210, 0x211, 0x212, 0x213, + 0x214, 0x215, 0x216, 0x217, 0x218, 0x219, 0x21A, 0x21B, + 0x21C, 0x21D, 0x21E, 0x21F, 0x220, 0x221, 0x222, 0x223, + 0x224, 0x225, 0x226, 0x227, 0x228, 0x229, 0x22A, 0x22B, + 0x22C, 0x22D, 0x22E, 0x22F, 0x230, 0x231, 0x232, 0x233, + 0x234, 0x235, 0x236, 0x237, 0x238, 0x239, 0x23A, 0x23B, + 0x23C, 0x23D, 0x23E, 0x23F, 0x240, 0x241, 0x242, 0x243, + 0x244, 0x245, 0x246, 0x247, 0x248, 0x249, 0x24A, 0x24B, + 0x24C, 0x24D, 0x24E, 0x24F, 0x250, 0x251, 0x252, 0x253, + 0x254, 0x255, 0x256, 0x257, 0x258, 0x259, 0x25A, 0x25B, + 0x25C, 0x25D, 0x25E, 0x25F, 0x260, 0x261, 0x262, 0x263, + 0x264, 0x265, 0x266, 0x267, 0x268, 0x269, 0x26A, 0x20C, + 0x20C, 0x20C, 0x20C, 0x20C, 0x20C, 0x20C, 0x20C, 0x20C, + 0x20C, 0x20C, 0x20C, 0x20C, 0x20C, 0x20C, 0x20C, 0x20C, + 0x20C, 0x20C, 0x20C, 0x20C, 0x20C, 0x20C, 0x20C, 0x20C, + 0x20C, 0x20C, 0x20C, 0x20C, 0x20C, 0x20C, 0x20C, 0x20C, + 0x20C, 0x26B, 0x26C, 0x26D, 0x26E, 0x26F, 0x270, 0x271, + 0x272, 0x273, 0x274, 0x275, 0x276, 0x277, 0x278, 0x279, + 0x27A, 0x27B, 0x27C, 0x27D, 0x27E, 0x27F, 0x280, 0x281, + 0x282, 0x283, 0x284, 0x285, 0x286, 0x287, 0x288, 0x289, + 0x28A, 0x28B, 0x28C, 0x28D, 0x28E, 0x28F, 0x290, 0x291, + 0x292, 0x293, 0x294, 0x295, 0x296, 0x297, 0x298, 0x299, + 0x29A, 0x29B, 0x29C, 0x29D, 0x29E, 0x29F, 0x2A0, 0x2A1, + 0x2A2, 0x2A3, 0x2A4, 0x2A5, 0x2A6, 0x2A7, 0x2A8, 0x2A9, + }; + +static u16 Zenkaku2Code[] + = { 0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, + 0x008, 0x009, 0x00A, 0x00B, 0x00C, 0x00D, 0x00E, 0x00F, + 0x010, 0x011, 0x012, 0x013, 0x014, 0x015, 0x016, 0x017, + 0x018, 0x019, 0x01A, 0x01B, 0x01C, 0x01D, 0x01E, 0x01F, + 0x020, 0x021, 0x022, 0x023, 0x024, 0x025, 0x026, 0x027, + 0x028, 0x029, 0x02A, 0x02B, 0x02C, 0x02D, 0x02E, 0x02F, + 0x030, 0x031, 0x032, 0x033, 0x034, 0x035, 0x036, 0x037, + 0x038, 0x039, 0x03A, 0x03B, 0x03C, 0x03D, 0x03E, + 0x03F, 0x040, 0x041, 0x042, 0x043, 0x044, 0x045, 0x046, + 0x047, 0x048, 0x049, 0x04A, 0x04B, 0x04C, 0x04D, 0x04E, + 0x04F, 0x050, 0x051, 0x052, 0x053, 0x054, 0x055, 0x056, + 0x057, 0x058, 0x059, 0x05A, 0x05B, 0x05C, 0x05D, 0x05E, + 0x05F, 0x060, 0x061, 0x062, 0x063, 0x064, 0x065, 0x066, + 0x067, 0x068, 0x069, 0x06A, 0x06B, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x06C, 0x06D, 0x06E, 0x06F, 0x070, 0x071, 0x072, 0x073, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x074, 0x075, 0x076, 0x077, 0x078, 0x079, 0x07A, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x07B, 0x07C, 0x07D, 0x07E, 0x07F, 0x080, + 0x081, 0x082, 0x083, 0x084, 0x085, 0x086, 0x087, 0x088, + 0x089, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x08A, 0x08B, 0x08C, 0x08D, 0x08E, 0x08F, 0x090, 0x091, + 0x000, 0x000, 0x000, 0x000, 0x092, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x093, + 0x094, 0x095, 0x096, 0x097, 0x098, 0x099, 0x09A, 0x09B, + 0x09C, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x09D, 0x09E, 0x09F, 0x0A0, 0x0A1, 0x0A2, 0x0A3, 0x0A4, + 0x0A5, 0x0A6, 0x0A7, 0x0A8, 0x0A9, 0x0AA, 0x0AB, 0x0AC, + 0x0AD, 0x0AE, 0x0AF, 0x0B0, 0x0B1, 0x0B2, 0x0B3, 0x0B4, + 0x0B5, 0x0B6, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x0B7, 0x0B8, 0x0B9, 0x0BA, 0x0BB, 0x0BC, 0x0BD, + 0x0BE, 0x0BF, 0x0C0, 0x0C1, 0x0C2, 0x0C3, 0x0C4, 0x0C5, + 0x0C6, 0x0C7, 0x0C8, 0x0C9, 0x0CA, 0x0CB, 0x0CC, 0x0CD, + 0x0CE, 0x0CF, 0x0D0, 0x000, 0x000, 0x000, 0x000, 0x0D1, + 0x0D2, 0x0D3, 0x0D4, 0x0D5, 0x0D6, 0x0D7, 0x0D8, 0x0D9, + 0x0DA, 0x0DB, 0x0DC, 0x0DD, 0x0DE, 0x0DF, 0x0E0, 0x0E1, + 0x0E2, 0x0E3, 0x0E4, 0x0E5, 0x0E6, 0x0E7, 0x0E8, 0x0E9, + 0x0EA, 0x0EB, 0x0EC, 0x0ED, 0x0EE, 0x0EF, 0x0F0, 0x0F1, + 0x0F2, 0x0F3, 0x0F4, 0x0F5, 0x0F6, 0x0F7, 0x0F8, 0x0F9, + 0x0FA, 0x0FB, 0x0FC, 0x0FD, 0x0FE, 0x0FF, 0x100, 0x101, + 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109, + 0x10A, 0x10B, 0x10C, 0x10D, 0x10E, 0x10F, 0x110, 0x111, + 0x112, 0x113, 0x114, 0x115, 0x116, 0x117, 0x118, 0x119, + 0x11A, 0x11B, 0x11C, 0x11D, 0x11E, 0x11F, 0x120, 0x121, + 0x122, 0x123, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, + 0x124, 0x125, 0x126, 0x127, 0x128, 0x129, 0x12A, 0x12B, + 0x12C, 0x12D, 0x12E, 0x12F, 0x130, 0x131, 0x132, 0x133, + 0x134, 0x135, 0x136, 0x137, 0x138, 0x139, 0x13A, 0x13B, + 0x13C, 0x13D, 0x13E, 0x13F, 0x140, 0x141, 0x142, 0x143, + 0x144, 0x145, 0x146, 0x147, 0x148, 0x149, 0x14A, 0x14B, + 0x14C, 0x14D, 0x14E, 0x14F, 0x150, 0x151, 0x152, 0x153, + 0x154, 0x155, 0x156, 0x157, 0x158, 0x159, 0x15A, 0x15B, + 0x15C, 0x15D, 0x15E, 0x15F, 0x160, 0x161, 0x162, + 0x163, 0x164, 0x165, 0x166, 0x167, 0x168, 0x169, 0x16A, + 0x16B, 0x16C, 0x16D, 0x16E, 0x16F, 0x170, 0x171, 0x172, + 0x173, 0x174, 0x175, 0x176, 0x177, 0x178, 0x179, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x17A, + 0x17B, 0x17C, 0x17D, 0x17E, 0x17F, 0x180, 0x181, 0x182, + 0x183, 0x184, 0x185, 0x186, 0x187, 0x188, 0x189, 0x18A, + 0x18B, 0x18C, 0x18D, 0x18E, 0x18F, 0x190, 0x191, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x192, + 0x193, 0x194, 0x195, 0x196, 0x197, 0x198, 0x199, 0x19A, + 0x19B, 0x19C, 0x19D, 0x19E, 0x19F, 0x1A0, 0x1A1, 0x1A2, + 0x1A3, 0x1A4, 0x1A5, 0x1A6, 0x1A7, 0x1A8, 0x1A9, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, + 0x1AA, 0x1AB, 0x1AC, 0x1AD, 0x1AE, 0x1AF, 0x1B0, 0x1B1, + 0x1B2, 0x1B3, 0x1B4, 0x1B5, 0x1B6, 0x1B7, 0x1B8, 0x1B9, + 0x1BA, 0x1BB, 0x1BC, 0x1BD, 0x1BE, 0x1BF, 0x1C0, 0x1C1, + 0x1C2, 0x1C3, 0x1C4, 0x1C5, 0x1C6, 0x1C7, 0x1C8, 0x1C9, + 0x1CA, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x1CB, 0x1CC, 0x1CD, 0x1CE, 0x1CF, 0x1D0, 0x1D1, 0x1D2, + 0x1D3, 0x1D4, 0x1D5, 0x1D6, 0x1D7, 0x1D8, 0x1D9, + 0x1DA, 0x1DB, 0x1DC, 0x1DD, 0x1DE, 0x1DF, 0x1E0, 0x1E1, + 0x1E2, 0x1E3, 0x1E4, 0x1E5, 0x1E6, 0x1E7, 0x1E8, 0x1E9, + 0x1EA, 0x1EB, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x1EC, + 0x1ED, 0x1EE, 0x1EF, 0x1F0, 0x1F1, 0x1F2, 0x1F3, 0x1F4, + 0x1F5, 0x1F6, 0x1F7, 0x1F8, 0x1F9, 0x1FA, 0x1FB, 0x1FC, + 0x1FD, 0x1FE, 0x1FF, 0x200, 0x201, 0x202, 0x203, 0x204, + 0x205, 0x206, 0x207, 0x208, 0x209, 0x20A, 0x20B, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x20C, + 0x20D, 0x20E, 0x20F, 0x210, 0x211, 0x212, 0x213, 0x214, + 0x215, 0x216, 0x217, 0x218, 0x219, 0x21A, 0x21B, 0x21C, + 0x21D, 0x21E, 0x21F, 0x220, 0x221, 0x222, 0x223, 0x224, + 0x225, 0x226, 0x227, 0x228, 0x229, 0x22A, 0x22B, 0x22C, + 0x22D, 0x22E, 0x22F, 0x230, 0x231, 0x232, 0x233, 0x234, + 0x235, 0x236, 0x237, 0x238, 0x239, 0x23A, 0x23B, 0x23C, + 0x23D, 0x23E, 0x23F, 0x240, 0x241, 0x242, 0x243, 0x244, + 0x245, 0x246, 0x247, 0x248, 0x249, 0x24A, 0x24B, + 0x24C, 0x24D, 0x24E, 0x24F, 0x250, 0x251, 0x252, 0x253, + 0x254, 0x255, 0x256, 0x257, 0x258, 0x259, 0x25A, 0x25B, + 0x25C, 0x25D, 0x25E, 0x25F, 0x260, 0x261, 0x262, 0x263, + 0x264, 0x265, 0x266, 0x267, 0x268, 0x269, 0x26A, 0x26B, + 0x26C, 0x26D, 0x26E, 0x26F, 0x270, 0x271, 0x272, 0x273, + 0x274, 0x275, 0x276, 0x277, 0x278, 0x279, 0x27A, 0x27B, + 0x27C, 0x27D, 0x27E, 0x27F, 0x280, 0x281, 0x282, 0x283, + 0x284, 0x285, 0x286, 0x287, 0x288, 0x289, 0x28A, 0x28B, + 0x28C, 0x28D, 0x28E, 0x28F, 0x290, 0x291, 0x292, 0x293, + 0x294, 0x295, 0x296, 0x297, 0x298, 0x299, 0x29A, 0x29B, + 0x29C, 0x29D, 0x29E, 0x29F, 0x2A0, 0x2A1, 0x2A2, 0x2A3, + 0x2A4, 0x2A5, 0x2A6, 0x2A7, 0x2A8, 0x2A9, 0x2AA, 0x2AB, + 0x2AC, 0x2AD, 0x2AE, 0x2AF, 0x2B0, 0x2B1, 0x2B2, 0x2B3, + 0x2B4, 0x2B5, 0x2B6, 0x2B7, 0x2B8, 0x2B9, 0x2BA, 0x2BB, + 0x2BC, 0x2BD, 0x2BE, 0x2BF, 0x2C0, 0x2C1, 0x2C2, 0x2C3, + 0x2C4, 0x2C5, 0x2C6, 0x2C7, 0x2C8, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, + 0x2C9, 0x2CA, 0x2CB, 0x2CC, 0x2CD, 0x2CE, 0x2CF, 0x2D0, + 0x2D1, 0x2D2, 0x2D3, 0x2D4, 0x2D5, 0x2D6, 0x2D7, 0x2D8, + 0x2D9, 0x2DA, 0x2DB, 0x2DC, 0x2DD, 0x2DE, 0x2DF, 0x2E0, + 0x2E1, 0x2E2, 0x2E3, 0x2E4, 0x2E5, 0x2E6, 0x000, 0x2E7, + 0x2E8, 0x2E9, 0x2EA, 0x2EB, 0x2EC, 0x2ED, 0x2EE, 0x2EF, + 0x2F0, 0x2F1, 0x2F2, 0x2F3, 0x2F4, 0x2F5, 0x2F6, 0x2F7, + 0x2F8, 0x2F9, 0x2FA, 0x2FB, 0x2FC, 0x2FD, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x2FE, + 0x2FF, 0x300, 0x301, 0x302, 0x303, 0x304, 0x305, 0x306, + 0x307, 0x308, 0x309, 0x30A, 0x30B, 0x30C, 0x30D, 0x30E, + 0x30F, 0x310, 0x311, 0x312, 0x313, 0x314, 0x315, 0x316, + 0x317, 0x318, 0x319, 0x31A, 0x31B, 0x000 + }; + +static BOOL IsSjisLeadByte(u8 c) { + return (0x81 <= c && c <= 0x9F) || (0xE0 <= c && c <= 0xFC); } -static BOOL IsSjisTrailByte(u8 ch) { - return (0x40 <= ch && ch <= 0xFC) && (ch != 0x7F); +static BOOL IsSjisTrailByte(u8 c) { + return (0x40 <= c && c <= 0xFC) && (c != 0x7F); } -/* 8033D3E0-8033D554 337D20 0174+00 1/1 0/0 0/0 .text GetFontCode */ -static u32 GetFontCode(u16 encode, u16 code) { - u32 tmp; - s32 trail; - +static int GetFontCode(u16 encode, u16 code) { if (encode == OS_FONT_ENCODE_SJIS) { - if (0x20 <= code && code <= 0xDF) { + if (code >= 0x20 && code <= 0xDF) { return HankakuToCode[code - 0x20]; - } else if (0x889E < code && code <= 0x9872) { - tmp = ((code >> 8) - 0x88) * 0xBC; - trail = code & 0xFF; + } - if (!IsSjisTrailByte(trail)) { + if (code > 0x889E && code <= 0x9872) { + int i = ((code >> 8) - 0x88) * 188; + int j = (code & 0xFF); + + if (!IsSjisTrailByte(j)) { return 0; } - trail -= 0x40; - if (trail >= 0x40) { - trail--; + j -= 0x40; + if (j >= 0x40) { + j--; } - return tmp + trail + 0x2BE; - } else if (0x8140 <= code && code < 0x879E) { - tmp = ((code >> 8) - 0x81) * 0xBC; - trail = code & 0xFF; + return (i + j + 0x2BE); + } - if (!IsSjisTrailByte(trail)) { + if (code >= 0x8140 && code < 0x879E) { + int i = ((code >> 8) - 0x81) * 188; + int j = (code & 0xFF); + + if (!IsSjisTrailByte(j)) { return 0; } - trail -= 0x40; - if (trail >= 0x40) { - trail--; + j -= 0x40; + if (j >= 0x40) { + j--; } - return Zenkaku2Code[tmp + trail]; + return Zenkaku2Code[i + j]; } } else if (code > 0x20 && code <= 0xFF) { return code - 0x20; @@ -240,30 +253,82 @@ static u32 GetFontCode(u16 encode, u16 code) { return 0; } -/* ############################################################################################## */ -/* 804509B0-804509B8 000430 0002+06 1/1 0/0 0/0 .sdata FontEncode */ -static u16 FontEncode = 0xFFFF; +static void Decode(u8* s, u8* d) { + int i; + int j; + int k; + int p; + int q; + int r7; // huh? DWARF info says these 2 variables might be register names and not actual names. + int r25; + int cnt; + int os; + unsigned int flag; + unsigned int code; -/* 80451660-80451664 000B60 0004+00 1/1 0/0 0/0 .sbss FontDataAnsi */ -static OSFontHeader* FontDataAnsi; + os = *(int*)(s + 0x4); + r7 = *(int*)(s + 0x8); + r25 = *(int*)(s + 0xC); -/* 80451664-80451668 000B64 0004+00 1/1 0/0 0/0 .sbss FontDataSjis */ -static OSFontHeader* FontDataSjis; + q = 0; + flag = 0; + p = 16; -/* 80451668-80451670 000B68 0004+04 1/1 0/0 0/0 .sbss ParseString */ -static void* ParseString; + do { + // Get next mask + if (flag == 0) { + code = *(u32*)(s + p); + p += sizeof(u32); + flag = sizeof(u32) * 8; + } + + // Non-linked chunk + if (code & 0x80000000) { + d[q++] = s[r25++]; + } + // Linked chunk + else { + // Read offset from link table + j = s[r7] << 8 | s[r7 + 1]; + r7 += sizeof(u16); + + // Apply offset + k = q - (j & 0x0FFF); + cnt = j >> 12; + if (cnt == 0) { + cnt = s[r25++] + 0x12; + } else { + cnt += 2; + } + + // Copy chunk + for (i = 0; i < cnt; i++, q++, k++) { + d[q] = d[k - 1]; + } + } + + // Prepare next mask bit + code <<= 1; + flag--; + } while (q < os); +} + +static u32 GetFontSize(u8* buf) { + if (buf[0] == 'Y' && buf[1] == 'a' && buf[2] == 'y') { + return *(u32*)(buf + 0x4); + } + + return 0; +} -/* 8033D554-8033D5B8 337E94 0064+00 0/0 1/1 0/0 .text OSGetFontEncode */ u16 OSGetFontEncode(void) { if (FontEncode != 0xFFFF) { return FontEncode; } - switch (*(u32*)OSPhysicalToCached(0xCC)) { + switch (*(int*)OSPhysicalToCached(0xCC)) { case VI_NTSC: - FontEncode = ((__VIRegs[55] & 2) != 0) - ? OS_FONT_ENCODE_SJIS - : OS_FONT_ENCODE_ANSI; + FontEncode = (__VIRegs[VI_DTV_STAT] & 2) ? OS_FONT_ENCODE_SJIS : OS_FONT_ENCODE_ANSI; break; case VI_PAL: case VI_MPAL: @@ -274,41 +339,413 @@ u16 OSGetFontEncode(void) { FontEncode = OS_FONT_ENCODE_ANSI; } - ParseString = ParseStringS; - + ParseString = (ParseStringCallback)ParseStringS; return FontEncode; } -/* 8033D5B8-8033D6F4 337EF8 013C+00 1/1 0/0 0/0 .text ParseStringS */ -static const u8* ParseStringS(u16 encode, const u8* str, OSFontHeader** fontOut, - u32* codeOut) { +u16 OSSetFontEncode(u16 encode) { + u16 prev; + + ASSERTLINE(463, encode <= OS_FONT_ENCODE_MAX); + + prev = OSGetFontEncode(); + if (encode <= OS_FONT_ENCODE_MAX) { + FontEncode = encode; + if (encode >= 3 && encode <= OS_FONT_ENCODE_MAX) { + ParseString = (ParseStringCallback)ParseStringW; + } + } + + return prev; +} + +static void ReadROM(void* buf, int length, int offset) { + int len; + while (length > 0) { + len = (length <= 0x100) ? length : 0x100; + length -= len; + + while (!__OSReadROM(buf, len, offset)) { + ; + } + + offset += len; + (u8*)buf += len; + } +} + +static u32 ReadFont(void* img, u16 encode, void* fontData) { + u32 size; +#ifndef DEBUG + u32 padding[1]; +#endif + + if (encode == OS_FONT_ENCODE_SJIS) { + ReadROM(img, OS_FONT_ROM_SIZE_SJIS, 0x1AFF00); + } else { + ReadROM(img, OS_FONT_ROM_SIZE_ANSI, 0x1FCF00); + } + + size = GetFontSize(img); + if (size == 0) { + return 0; + } + + Decode(img, fontData); + if (encode == OS_FONT_ENCODE_SJIS) { + OSFontHeader* font = (OSFontHeader*)fontData; + int fontCode; + u8* imageSrc; + int sheet; + int numChars; + int row; + int column; + int x; + int y; + u8* src; + u16 imageT[4] = {0x2ABE, 0x003D, 0x003D, 0x003D}; + + fontCode = GetFontCode(encode, 0x54); + sheet = fontCode / (font->sheetColumn * font->sheetRow); + numChars = fontCode - (sheet * (font->sheetColumn * font->sheetRow)); + row = numChars / font->sheetColumn; + column = numChars - (row * font->sheetColumn); + row *= font->cellHeight; + column *= font->cellWidth; + + imageSrc = (u8*)font + font->sheetImage; + imageSrc += ((sheet * font->sheetSize) >> 1); + + for (y = 4; y < 8; y++) { + x = 0; + src = imageSrc + ((((font->sheetWidth / 8) << 5) / 2) * ((row + y) / 8)); + src += ((column + x) / 8) * 0x10; + src += ((row + y) % 8) * 2; + src += ((column + x) % 8) / 4; + + *(u16*)src = imageT[y - 4]; + } + } + + return size; +} + +u32 OSLoadFont(OSFontHeader* fontData, void* tmp) { + u16 encode; + u32 size; + + encode = OSGetFontEncode(); + switch (encode) { + case 0: + FontDataAnsi = fontData; + size = ReadFont(tmp, 0, FontDataAnsi); + break; + case 1: + FontDataSjis = fontData; + size = ReadFont(tmp, 1, FontDataSjis); + break; + case 3: + case 4: + case 5: + FontDataAnsi = fontData; + size = ReadFont(tmp, 0, FontDataAnsi); + if (size != 0) { + FontDataSjis = (OSFontHeader*)((u8*)FontDataAnsi + size); + size += ReadFont(tmp, 1, FontDataSjis); + } + break; + case 2: + default: + size = 0; + break; + } + + return size; +} + +static char* ParseStringS(u16 encode, const char* string, OSFontHeader** pfont, int* pfontCode) { OSFontHeader* font; u16 code = 0; switch (encode) { case OS_FONT_ENCODE_ANSI: font = FontDataAnsi; - code = *str; + code = *string; if (code != 0) { - str++; + string++; } break; case OS_FONT_ENCODE_SJIS: font = FontDataSjis; - code = *str; + code = *string; if (code == 0) { break; } - str++; + string++; - if (IsSjisLeadByte(code) && IsSjisTrailByte(*str)) { - code = (code << 8 | *str++); + if (IsSjisLeadByte(code) && IsSjisTrailByte(*string)) { + code = (code << 8 | *string++); } break; } - *fontOut = font; - *codeOut = GetFontCode(encode, code); + *pfont = font; + *pfontCode = GetFontCode(encode, code); - return str; -} \ No newline at end of file + return (char*)string; +} + +static char* ParseStringW(u16 encode, const char* string, OSFontHeader** pfont, int* pfontCode) { + OSFontHeader* font; + u16 code = 0; + u32 utf32 = 0; + + switch (encode) { + case OS_FONT_ENCODE_ANSI: + font = FontDataAnsi; + code = *string; + if (code != 0) { + string++; + } + break; + case OS_FONT_ENCODE_SJIS: + font = FontDataSjis; + code = *string; + if (code == 0) { + break; + } + string++; + + if (IsSjisLeadByte(code) && IsSjisTrailByte(*string)) { + code = (code << 8 | *string++); + } + break; + case 3: + string = OSUTF8to32(string, &utf32); + break; + case 4: + string = (const char*)OSUTF16to32((u16*)string, &utf32); + break; + case 5: + utf32 = *(u32*)string; + if (utf32 != 0) { + string += 4; + } + break; + } + + if (utf32 != 0) { + encode = 0; + font = FontDataAnsi; + code = OSUTF32toANSI(utf32); + + if (code == 0 || (FixedPitch != 0 && utf32 <= 0x7F)) { + code = OSUTF32toSJIS(utf32); + if (code != 0) { + encode = 1; + font = FontDataSjis; + } + } + } + + *pfont = font; + *pfontCode = GetFontCode(encode, code); + + return (char*)string; +} + +char* OSGetFontTexel(const char* string, void* image, s32 pos, s32 stride, s32* width) { + u16 encode; + OSFontHeader* font; + u8* src; + u8* dst; + int fontCode; + int sheet; + int numChars; + int row; + int column; + int x; + int y; + int offsetSrc; + int offsetDst; + u8* colorIndex; + u8* imageSrc; + + encode = OSGetFontEncode(); + string = ParseString(encode, (char*)string, &font, &fontCode); + colorIndex = &font->c0; + ASSERTLINE(828, font->sheetFormat == GX_TF_I4); + + sheet = fontCode / (font->sheetColumn * font->sheetRow); + numChars = fontCode - (sheet * (font->sheetColumn * font->sheetRow)); + row = numChars / font->sheetColumn; + column = numChars - (row * font->sheetColumn); + row *= font->cellHeight; + column *= font->cellWidth; + + imageSrc = (u8*)font + font->sheetImage; + imageSrc += ((sheet * font->sheetSize) >> 1); + + for (y = 0; y < font->cellHeight; y++) { + for (x = 0; x < font->cellWidth; x++) { + src = imageSrc + (((font->sheetWidth / 8) * 32) / 2) * ((row + y) / 8); + src += ((column + x) / 8) * 16; + src += ((row + y) % 8) * 2; + src += ((column + x) % 8) / 4; + + offsetSrc = (column + x) % 4; + + dst = (u8*)image + ((y / 8) * (((stride * 4) / 8) * 32)); + dst += (((pos + x) / 8) * 32); + dst += ((y % 8) * 4); + dst += ((pos + x) % 8) / 2; + + offsetDst = (pos + x) % 2; + + *dst |= colorIndex[*src >> (6 - (offsetSrc * 2)) & 3] & ((offsetDst != 0) ? 0x0F : 0xF0); + } + } + + if (width != 0) { + *width = ((u8*)font + font->widthTable)[fontCode]; + } + + return (char*)string; +} + +static void ExpandFontSheet(OSFontHeader* font, u8* src, u8* dst) { + int i; + u8* colorIndex = &font->c0; + + if (font->sheetFormat == GX_TF_I4) { + for (i = (s32)(font->sheetFullSize) / 2 - 1; i >= 0; i--) { + dst[i * 2 + 0] = + colorIndex[src[i] >> 6 & 3] & 0xF0 | colorIndex[src[i] >> 4 & 3] & 0x0F; + dst[i * 2 + 1] = + colorIndex[src[i] >> 2 & 3] & 0xF0 | colorIndex[src[i] >> 0 & 3] & 0x0F; + } + } else if (font->sheetFormat == GX_TF_IA4) { + for (i = (s32)(font->sheetFullSize) / 4 - 1; i >= 0; i--) { + dst[i * 4 + 0] = colorIndex[src[i] >> 6 & 3]; + dst[i * 4 + 1] = colorIndex[src[i] >> 4 & 3]; + dst[i * 4 + 2] = colorIndex[src[i] >> 2 & 3]; + dst[i * 4 + 3] = colorIndex[src[i] >> 0 & 3]; + } + } + + DCStoreRange(dst, font->sheetFullSize); +} + +int OSInitFont(OSFontHeader* fontData) { + u16 encode; + u32 size; + void* tmp; + u8* img; + + ASSERTLINE(919, (u32) fontData % 32 == 0); + + encode = OSGetFontEncode(); + switch (encode) { + case 0: + tmp = (void*)((u8*)fontData + 0x1D120); + FontDataAnsi = fontData; + size = ReadFont(tmp, 0, FontDataAnsi); + if (size == 0) { + return 0; + } + + img = (u8*)FontDataAnsi + FontDataAnsi->sheetImage; + FontDataAnsi->sheetImage = OSRoundUp32B(FontDataAnsi->sheetImage); + ExpandFontSheet(FontDataAnsi, img, (u8*)FontDataAnsi + FontDataAnsi->sheetImage); + break; + case 1: + tmp = (void*)((u8*)fontData + 0xD3F00); + FontDataSjis = fontData; + size = ReadFont(tmp, 1, FontDataSjis); + if (size == 0) { + return 0; + } + + img = (u8*)FontDataSjis + FontDataSjis->sheetImage; + FontDataSjis->sheetImage = OSRoundUp32B(FontDataSjis->sheetImage); + ExpandFontSheet(FontDataSjis, img, (u8*)FontDataSjis + FontDataSjis->sheetImage); + break; + case 3: + case 4: + case 5: + tmp = (void*)((u8*)fontData + 0xF4020); + FontDataAnsi = fontData; + size = ReadFont(tmp, 0, FontDataAnsi); + if (size == 0) { + return 0; + } + + img = (u8*)FontDataAnsi + FontDataAnsi->sheetImage; + FontDataAnsi->sheetImage = OSRoundUp32B(FontDataAnsi->sheetImage); + ExpandFontSheet(FontDataAnsi, img, (u8*)FontDataAnsi + FontDataAnsi->sheetImage); + + FontDataSjis = (OSFontHeader*)((u8*)FontDataAnsi + 0x20120); + size = ReadFont(tmp, 1, FontDataSjis); + if (size == 0) { + return 0; + } + + img = (u8*)FontDataSjis + FontDataSjis->sheetImage; + FontDataSjis->sheetImage = OSRoundUp32B(FontDataSjis->sheetImage); + ExpandFontSheet(FontDataSjis, img, (u8*)FontDataSjis + FontDataSjis->sheetImage); + break; + case 2: + default: + break; + } + + return 1; +} + +char* OSGetFontTexture(const char* string, void** image, s32* x, s32* y, s32* width) { + OSFontHeader* font; + u16 encode; + int fontCode; + int sheet; + int numChars; + int row; + int column; + + encode = OSGetFontEncode(); + string = ParseString(encode, (char*)string, &font, &fontCode); + sheet = fontCode / (font->sheetColumn * font->sheetRow); + ((u32*)image)[0] = (u32)font + font->sheetImage + (font->sheetSize * sheet); + numChars = fontCode - (sheet * (font->sheetColumn * font->sheetRow)); + row = numChars / font->sheetColumn; + column = numChars - (row * font->sheetColumn); + *x = column * font->cellWidth; + *y = row * font->cellHeight; + + ASSERTLINE(1016, (u32) *image % 32 == 0); + + if (width != 0) { + *width = ((u8*)font + font->widthTable)[fontCode]; + } + return (char*)string; +} + +char* OSGetFontWidth(const char* string, s32* width) { + OSFontHeader* font; + u16 encode; + int fontCode; + + encode = OSGetFontEncode(); + string = ParseString(encode, (char*)string, &font, &fontCode); + + if (width != 0) { + *width = ((u8*)font + font->widthTable)[fontCode]; + } + + return (char*)string; +} + +int OSSetFontWidth(int fixed) { + int prev = FixedPitch; + FixedPitch = fixed; + return prev; +} diff --git a/src/dolphin/os/OSInterrupt.c b/src/dolphin/os/OSInterrupt.c index 1168572aff..77d92bba23 100644 --- a/src/dolphin/os/OSInterrupt.c +++ b/src/dolphin/os/OSInterrupt.c @@ -1,115 +1,171 @@ -#include "dolphin/os/OSInterrupt.h" -#include "dolphin/dsp.h" -#include "dolphin/exi/EXIBios.h" -#include "dolphin/os.h" +#include +#include -vu32 __PIRegs[12] AT_ADDRESS(0xCC003000); -vu16 __MEMRegs[64] AT_ADDRESS(0xCC004000); +#include "__os.h" -/* 8033D6F4-8033D700 338034 000C+00 2/2 200/200 5/5 .text OSDisableInterrupts */ -asm BOOL OSDisableInterrupts(void) { - // clang-format off - nofralloc - - entry __RAS_OSDisableInterrupts_begin - - mfmsr r3 - // Clear external interrupts bit - rlwinm r4, r3, 0, 17, 15 - mtmsr r4 - - entry __RAS_OSDisableInterrupts_end - - // Return old interrupt status - rlwinm r3, r3, 17, 31, 31 - blr - // clang-format on -} - -/* 8033D708-8033D71C 338048 0014+00 0/0 10/10 1/1 .text OSEnableInterrupts */ -asm BOOL OSEnableInterrupts(void) { - // clang-format off - nofralloc - - mfmsr r3 - // Set external interrupts bit - ori r4, r3, (1 << 15) - mtmsr r4 - - // Return old interrupt status - rlwinm r3, r3, 17, 31, 31 - blr - // clang-format on -} - -/* 8033D71C-8033D740 33805C 0024+00 2/2 197/197 6/6 .text OSRestoreInterrupts */ -asm BOOL OSRestoreInterrupts(register BOOL status) { - // clang-format off - nofralloc - - cmpwi status, 0 - mfmsr r4 - beq disable - - // Set external interrupts bit - ori r5, r4, (1 << 15) - b set_msr - -disable: - // Clear external interrupts bit - rlwinm r5, r4, 0, 17, 15 - -set_msr: - mtmsr r5 - // Return old interrupt status - rlwinm r3, r4, 17, 31, 31 - blr - // clang-format on -} - -/* ############################################################################################## */ -/* 80451670-80451674 000B70 0004+00 4/4 0/0 0/0 .sbss InterruptHandlerTable */ +#if DEBUG +u64 __OSSpuriousInterrupts = 0; +#endif static __OSInterruptHandler* InterruptHandlerTable; -/* 8033D740-8033D75C 338080 001C+00 0/0 12/12 0/0 .text __OSSetInterruptHandler */ -__OSInterruptHandler __OSSetInterruptHandler(__OSInterrupt type, __OSInterruptHandler handler) { - __OSInterruptHandler old = InterruptHandlerTable[type]; - InterruptHandlerTable[type] = handler; - return old; +volatile OSTime __OSLastInterruptTime; +volatile __OSInterrupt __OSLastInterrupt; +volatile u32 __OSLastInterruptSrr0; + +static OSInterruptMask InterruptPrioTable[] = { + OS_INTERRUPTMASK_PI_ERROR, + OS_INTERRUPTMASK_PI_DEBUG, + OS_INTERRUPTMASK_MEM, + OS_INTERRUPTMASK_PI_RSW, + OS_INTERRUPTMASK_PI_VI, + OS_INTERRUPTMASK_PI_PE, + OS_INTERRUPTMASK_PI_HSP, + OS_INTERRUPTMASK_DSP_ARAM | OS_INTERRUPTMASK_DSP_DSP | OS_INTERRUPTMASK_AI | + OS_INTERRUPTMASK_EXI | OS_INTERRUPTMASK_PI_SI | OS_INTERRUPTMASK_PI_DI, + OS_INTERRUPTMASK_DSP_AI, + OS_INTERRUPTMASK_PI_CP, + 0xFFFFFFFF, +}; + +#if DEBUG +char* __OSInterruptNames[33] = { + "MEM_0", + "MEM_1", + "MEM_2", + "MEM_3", + "MEM_ADDRESS", + "DSP_AI", + "DSP_ARAM", + "DSP_DSP", + "AI_AI", + "EXI_0_EXI", + "EXI_0_TC", + "EXI_0_EXT", + "EXI_1_EXI", + "EXI_1_TC", + "EXI_1_EXT", + "EXI_2_EXI", + "EXI_2_TC", + "PI_CP", + "PI_PE_TOKEN", + "PI_PE_FINISH", + "PI_SI", + "PI_DI", + "PI_RSW", + "PI_ERROR", + "PI_VI", + "PI_DEBUG", + "PI_HSP", + "unknown", + "unknown", + "unknown", + "unknown", + "unknown", + "unknown" +}; + +char* __OSPIErrors[8] = { + "No Error", + "Misaligned address for CPU request", + "Incorrect transfer type (tt) from CPU", + "Unsupported transfer size", + "Address out of range", + "Write to ROM address space", + "Read from GX Fifo", + "Reserved error code", +}; +#endif + +// prototypes +static void ExternalInterruptHandler(register __OSException exception, register OSContext* context); +extern void __RAS_OSDisableInterrupts_begin(void); +extern void __RAS_OSDisableInterrupts_end(void); + +#ifdef __GEKKO__ +asm BOOL OSDisableInterrupts(void) { + nofralloc +entry __RAS_OSDisableInterrupts_begin + mfmsr r3 + rlwinm r4, r3, 0, 17, 15 + mtmsr r4 +entry __RAS_OSDisableInterrupts_end + rlwinm r3, r3, 17, 31, 31 + blr } -/* 8033D75C-8033D770 33809C 0014+00 0/0 1/1 0/0 .text __OSGetInterruptHandler */ -__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt type) { - return InterruptHandlerTable[type]; +asm BOOL OSEnableInterrupts(void) { + nofralloc + + mfmsr r3 + ori r4, r3, 0x8000 + mtmsr r4 + rlwinm r3, r3, 17, 31, 31 + blr +} + +asm BOOL OSRestoreInterrupts(register BOOL level) { + nofralloc + + cmpwi level, 0 + mfmsr r4 + beq _disable + ori r5, r4, 0x8000 + b _restore +_disable: + rlwinm r5, r4, 0, 17, 15 +_restore: + mtmsr r5 + rlwinm r3, r4, 17, 31, 31 + blr +} +#endif + +__OSInterruptHandler __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler) { + __OSInterruptHandler oldHandler; + + ASSERTMSGLINE(411, InterruptHandlerTable, "__OSSetInterruptHandler(): OSInit() must be called in advance."); + ASSERTMSGLINE(413, interrupt < 0x20, "__OSSetInterruptHandler(): unknown interrupt."); + + oldHandler = InterruptHandlerTable[interrupt]; + InterruptHandlerTable[interrupt] = handler; + return oldHandler; +} + +__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt) { + ASSERTMSGLINE(433, InterruptHandlerTable, "__OSGetInterruptHandler(): OSInit() must be called in advance."); + ASSERTMSGLINE(435, interrupt < 0x20, "__OSGetInterruptHandler(): unknown interrupt."); + return InterruptHandlerTable[interrupt]; } -/* 8033D770-8033D7E4 3380B0 0074+00 0/0 1/1 0/0 .text __OSInterruptInit */ void __OSInterruptInit(void) { - InterruptHandlerTable = OSPhysicalToCached(0x3040); - memset(InterruptHandlerTable, 0, 32 * sizeof(__OSInterruptHandler)); + InterruptHandlerTable = (void*)OSPhysicalToCached(0x3040); + + memset(InterruptHandlerTable, 0, __OS_INTERRUPT_MAX * sizeof(__OSInterruptHandler)); *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = 0; - *(OSInterruptMask*)OSPhysicalToCached(0x00C8) = 0; __PIRegs[1] = 0xf0; __OSMaskInterrupts(OS_INTERRUPTMASK_MEM | OS_INTERRUPTMASK_DSP | OS_INTERRUPTMASK_AI | - OS_INTERRUPTMASK_EXI | OS_INTERRUPTMASK_PI); + OS_INTERRUPTMASK_EXI | OS_INTERRUPTMASK_PI); - __OSSetExceptionHandler(4, (OSExceptionHandler)ExternalInterruptHandler); + __OSSetExceptionHandler(4, ExternalInterruptHandler); + #if DEBUG + __PIRegs[0] = 1; + __OSUnmaskInterrupts(0x100); + #endif } -/* 8033D7E4-8033DABC 338124 02D8+00 2/2 0/0 0/0 .text SetInterruptMask */ -u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current) { +static u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current) { u32 reg; switch (__cntlzw(mask)) { - case OS_INTR_MEM_0: - case OS_INTR_MEM_1: - case OS_INTR_MEM_2: - case OS_INTR_MEM_3: - case OS_INTR_MEM_ADDRESS: + case __OS_INTERRUPT_MEM_0: + case __OS_INTERRUPT_MEM_1: + case __OS_INTERRUPT_MEM_2: + case __OS_INTERRUPT_MEM_3: + case __OS_INTERRUPT_MEM_ADDRESS: reg = 0; if (!(current & OS_INTERRUPTMASK_MEM_0)) reg |= 0x1; @@ -124,9 +180,9 @@ u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current) { __MEMRegs[0x0000000e] = (u16)reg; mask &= ~OS_INTERRUPTMASK_MEM; break; - case OS_INTR_DSP_AI: - case OS_INTR_DSP_ARAM: - case OS_INTR_DSP_DSP: + case __OS_INTERRUPT_DSP_AI: + case __OS_INTERRUPT_DSP_ARAM: + case __OS_INTERRUPT_DSP_DSP: reg = __DSPRegs[0x00000005]; reg &= ~0x1F8; if (!(current & OS_INTERRUPTMASK_DSP_AI)) @@ -138,7 +194,7 @@ u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current) { __DSPRegs[0x00000005] = (u16)reg; mask &= ~OS_INTERRUPTMASK_DSP; break; - case OS_INTR_AI_AI: + case __OS_INTERRUPT_AI_AI: reg = __AIRegs[0]; reg &= ~0x2C; if (!(current & OS_INTERRUPTMASK_AI_AI)) @@ -146,9 +202,9 @@ u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current) { __AIRegs[0] = reg; mask &= ~OS_INTERRUPTMASK_AI; break; - case OS_INTR_EXI_0_EXI: - case OS_INTR_EXI_0_TC: - case OS_INTR_EXI_0_EXT: + case __OS_INTERRUPT_EXI_0_EXI: + case __OS_INTERRUPT_EXI_0_TC: + case __OS_INTERRUPT_EXI_0_EXT: reg = __EXIRegs[0]; reg &= ~0x2C0F; if (!(current & OS_INTERRUPTMASK_EXI_0_EXI)) @@ -160,9 +216,9 @@ u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current) { __EXIRegs[0] = reg; mask &= ~OS_INTERRUPTMASK_EXI_0; break; - case OS_INTR_EXI_1_EXI: - case OS_INTR_EXI_1_TC: - case OS_INTR_EXI_1_EXT: + case __OS_INTERRUPT_EXI_1_EXI: + case __OS_INTERRUPT_EXI_1_TC: + case __OS_INTERRUPT_EXI_1_EXT: reg = __EXIRegs[5]; reg &= ~0xC0F; @@ -175,8 +231,8 @@ u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current) { __EXIRegs[5] = reg; mask &= ~OS_INTERRUPTMASK_EXI_1; break; - case OS_INTR_EXI_2_EXI: - case OS_INTR_EXI_2_TC: + case __OS_INTERRUPT_EXI_2_EXI: + case __OS_INTERRUPT_EXI_2_TC: reg = __EXIRegs[10]; reg &= ~0xF; if (!(current & OS_INTERRUPTMASK_EXI_2_EXI)) @@ -187,16 +243,16 @@ u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current) { __EXIRegs[10] = reg; mask &= ~OS_INTERRUPTMASK_EXI_2; break; - case OS_INTR_PI_CP: - case OS_INTR_PI_SI: - case OS_INTR_PI_DI: - case OS_INTR_PI_RSW: - case OS_INTR_PI_ERROR: - case OS_INTR_PI_VI: - case OS_INTR_PI_DEBUG: - case OS_INTR_PI_PE_TOKEN: - case OS_INTR_PI_PE_FINISH: - case OS_INTR_PI_HSP: + case __OS_INTERRUPT_PI_CP: + case __OS_INTERRUPT_PI_SI: + case __OS_INTERRUPT_PI_DI: + case __OS_INTERRUPT_PI_RSW: + case __OS_INTERRUPT_PI_ERROR: + case __OS_INTERRUPT_PI_VI: + case __OS_INTERRUPT_PI_DEBUG: + case __OS_INTERRUPT_PI_PE_TOKEN: + case __OS_INTERRUPT_PI_PE_FINISH: + case __OS_INTERRUPT_PI_HSP: reg = 0xF0; if (!(current & OS_INTERRUPTMASK_PI_CP)) { @@ -238,7 +294,28 @@ u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current) { return mask; } -/* 8033DABC-8033DB44 3383FC 0088+00 1/1 15/15 0/0 .text __OSMaskInterrupts */ +OSInterruptMask OSGetInterruptMask(void) { + return *(OSInterruptMask *)OSPhysicalToCached(0x00C8); +} + +OSInterruptMask OSSetInterruptMask(OSInterruptMask local) { + BOOL enabled; + OSInterruptMask global; + OSInterruptMask prev; + OSInterruptMask mask; + + enabled = OSDisableInterrupts(); + global = *(OSInterruptMask *)OSPhysicalToCached(0x00C4); + prev = *(OSInterruptMask *)OSPhysicalToCached(0x00C8); + mask = (global | prev) ^ local; + *(OSInterruptMask *)OSPhysicalToCached(0x00C8) = local; + while (mask) { + mask = SetInterruptMask(mask, global | local); + } + OSRestoreInterrupts(enabled); + return prev; +} + OSInterruptMask __OSMaskInterrupts(OSInterruptMask global) { BOOL enabled; OSInterruptMask prev; @@ -246,11 +323,11 @@ OSInterruptMask __OSMaskInterrupts(OSInterruptMask global) { OSInterruptMask mask; enabled = OSDisableInterrupts(); - prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4); - local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8); + prev = *(OSInterruptMask *)OSPhysicalToCached(0x00C4); + local = *(OSInterruptMask *)OSPhysicalToCached(0x00C8); mask = ~(prev | local) & global; global |= prev; - *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global; + *(OSInterruptMask *)OSPhysicalToCached(0x00C4) = global; while (mask) { mask = SetInterruptMask(mask, global | local); } @@ -258,7 +335,6 @@ OSInterruptMask __OSMaskInterrupts(OSInterruptMask global) { return prev; } -/* 8033DB44-8033DBCC 338484 0088+00 0/0 18/18 0/0 .text __OSUnmaskInterrupts */ OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask global) { BOOL enabled; OSInterruptMask prev; @@ -266,11 +342,11 @@ OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask global) { OSInterruptMask mask; enabled = OSDisableInterrupts(); - prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4); - local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8); + prev = *(OSInterruptMask *)OSPhysicalToCached(0x00C4); + local = *(OSInterruptMask *)OSPhysicalToCached(0x00C8); mask = (prev | local) & global; global = prev & ~global; - *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global; + *(OSInterruptMask *)OSPhysicalToCached(0x00C4) = global; while (mask) { mask = SetInterruptMask(mask, global | local); } @@ -278,26 +354,6 @@ OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask global) { return prev; } -/* ############################################################################################## */ -/* 803D0758-803D0788 02D878 002C+04 1/1 0/0 0/0 .data InterruptPrioTable */ -static u32 InterruptPrioTable[] = { - 0x00000100, 0x00000040, 0xF8000000, 0x00000200, 0x00000080, 0x00003000, - 0x00000020, 0x03FF8C00, 0x04000000, 0x00004000, 0xFFFFFFFF, -}; - -/* 80451680-80451684 000B80 0004+00 1/1 1/1 0/0 .sbss __OSLastInterruptTime */ -extern OSTime __OSLastInterruptTime; -OSTime __OSLastInterruptTime; - -/* 80451678-80451680 000B78 0002+06 1/1 1/1 0/0 .sbss __OSLastInterrupt */ -extern s16 __OSLastInterrupt; -s16 __OSLastInterrupt; - -/* 80451674-80451678 000B74 0004+00 1/1 1/1 0/0 .sbss __OSLastInterruptSrr0 */ -extern u32 __OSLastInterruptSrr0; -u32 __OSLastInterruptSrr0; - -/* 8033DBCC-8033DF10 33850C 0344+00 1/1 0/0 0/0 .text __OSDispatchInterrupt */ void __OSDispatchInterrupt(__OSException exception, OSContext* context) { u32 intsr; u32 reg; @@ -306,10 +362,14 @@ void __OSDispatchInterrupt(__OSException exception, OSContext* context) { OSInterruptMask* prio; __OSInterrupt interrupt; __OSInterruptHandler handler; + intsr = __PIRegs[0]; intsr &= ~0x00010000; if (intsr == 0 || (intsr & __PIRegs[1]) == 0) { + #if DEBUG + __OSSpuriousInterrupts++; + #endif OSLoadContext(context); } @@ -388,8 +448,19 @@ void __OSDispatchInterrupt(__OSException exception, OSContext* context) { if (intsr & 0x00000001) cause |= OS_INTERRUPTMASK_PI_ERROR; - unmasked = cause & ~(*(OSInterruptMask*)OSPhysicalToCached(0x00C4) | - *(OSInterruptMask*)OSPhysicalToCached(0x00C8)); + #if DEBUG + if (cause & OS_INTERRUPTMASK_PI_ERROR) { + OSReport("PI ERROR\n"); + OSDumpContext(context); + OSReport("\nPIESR = 0x%08x PIEAR = 0x%08x\n", __PIRegs[7], __PIRegs[8]); + __PIRegs[0] = 1; + OSReport("PI Error = %s\n", __OSPIErrors[__PIRegs[7]]); + OSReport("Offending address = 0x%x (from PIEAR)\n", __PIRegs[8]); + } + #endif + + unmasked = cause & ~(*(OSInterruptMask *)OSPhysicalToCached(0x00C4) | + *(OSInterruptMask *)OSPhysicalToCached(0x00C8)); if (unmasked) { for (prio = InterruptPrioTable;; ++prio) { if (unmasked & *prio) { @@ -400,12 +471,11 @@ void __OSDispatchInterrupt(__OSException exception, OSContext* context) { handler = __OSGetInterruptHandler(interrupt); if (handler) { - if (OS_INTR_MEM_ADDRESS < interrupt) { + if (__OS_INTERRUPT_MEM_ADDRESS < interrupt) { __OSLastInterrupt = interrupt; __OSLastInterruptTime = OSGetTime(); __OSLastInterruptSrr0 = context->srr0; } - OSDisableScheduler(); handler(interrupt, context); OSEnableScheduler(); @@ -414,35 +484,26 @@ void __OSDispatchInterrupt(__OSException exception, OSContext* context) { } } + #if DEBUG + OSReport("Unhandled Interrupt(s): cause %08x intsr %08x\n", cause, intsr); + while (cause) { + interrupt = __cntlzw(cause); + cause &= ~(1 << (0x1F - __cntlzw(cause))); + OSReport(" %s\n", __OSInterruptNames[interrupt]); + } + #endif + OSLoadContext(context); } -/* 8033DF10-8033DF60 338850 0050+00 1/1 0/0 0/0 .text ExternalInterruptHandler */ -static asm void ExternalInterruptHandler(register __OSInterrupt type, register OSContext* context) { - // clang-format off - nofralloc +#ifdef __GEKKO__ +static asm void ExternalInterruptHandler(register __OSException exception, + register OSContext* context) { +#pragma unused(exception) + nofralloc + OS_EXCEPTION_SAVE_GPRS(context) - stw r0, context->gpr[0] - stw r1, context->gpr[1] - stw r2, context->gpr[2] - stmw r6, context->gpr[6] - - mfspr r0, GQR1 - stw r0, context->gqr[1] - mfspr r0, GQR2 - stw r0, context->gqr[2] - mfspr r0, GQR3 - stw r0, context->gqr[3] - mfspr r0, GQR4 - stw r0, context->gqr[4] - mfspr r0, GQR5 - stw r0, context->gqr[5] - mfspr r0, GQR6 - stw r0, context->gqr[6] - mfspr r0, GQR7 - stw r0, context->gqr[7] - - stwu r1, -8(r1) + stwu r1, -0x8(r1) b __OSDispatchInterrupt - // clang-format on } +#endif diff --git a/src/dolphin/os/OSLink.c b/src/dolphin/os/OSLink.c index 63f1aa1ce9..fbe11fef3c 100644 --- a/src/dolphin/os/OSLink.c +++ b/src/dolphin/os/OSLink.c @@ -1,4 +1,7 @@ -#include "dolphin/os.h" +#include +#include + +#include "__os.h" #define SHN_UNDEF 0 #define SHN_LORESERVE 0xff00 @@ -13,118 +16,113 @@ #define ELF32_R_INFO(s, t) (((s) << 8) + (unsigned char)(t)) // Name Value Field Calculation -#define R_PPC_NONE 0 // none none -#define R_PPC_ADDR32 1 // word32 S + A -#define R_PPC_ADDR24 2 // low24* (S + A) >> 2 -#define R_PPC_ADDR16 3 // half16* S + A -#define R_PPC_ADDR16_LO 4 // half16 #lo(S + A) -#define R_PPC_ADDR16_HI 5 // half16 #hi(S + A) -#define R_PPC_ADDR16_HA 6 // half16 #ha(S + A) -#define R_PPC_ADDR14 7 // low14* (S + A) >> 2 -#define R_PPC_ADDR14_BRTAKEN 8 // low14* (S + A) >> 2 -#define R_PPC_ADDR14_BRNTAKEN 9 // low14* (S + A) >> 2 -#define R_PPC_REL24 10 // low24* (S + A - P) >> 2 -#define R_PPC_REL14 11 // low14* (S + A - P) >> 2 -#define R_PPC_REL14_BRTAKEN 12 // low14* (S + A - P) >> 2 -#define R_PPC_REL14_BRNTAKEN 13 // low14* (S + A - P) >> 2 +#define R_PPC_NONE 0 // none none +#define R_PPC_ADDR32 1 // word32 S + A +#define R_PPC_ADDR24 2 // low24* (S + A) >> 2 +#define R_PPC_ADDR16 3 // half16* S + A +#define R_PPC_ADDR16_LO 4 // half16 #lo(S + A) +#define R_PPC_ADDR16_HI 5 // half16 #hi(S + A) +#define R_PPC_ADDR16_HA 6 // half16 #ha(S + A) +#define R_PPC_ADDR14 7 // low14* (S + A) >> 2 +#define R_PPC_ADDR14_BRTAKEN 8 // low14* (S + A) >> 2 +#define R_PPC_ADDR14_BRNTAKEN 9 // low14* (S + A) >> 2 +#define R_PPC_REL24 10 // low24* (S + A - P) >> 2 +#define R_PPC_REL14 11 // low14* (S + A - P) >> 2 +#define R_PPC_REL14_BRTAKEN 12 // low14* (S + A - P) >> 2 +#define R_PPC_REL14_BRNTAKEN 13 // low14* (S + A - P) >> 2 -#define R_PPC_GOT16 14 // half16* G + A -#define R_PPC_GOT16_LO 15 // half16 #lo(G + A) -#define R_PPC_GOT16_HI 16 // half16 #hi(G + A) -#define R_PPC_GOT16_HA 17 // half16 #ha(G + A) -#define R_PPC_PLTREL24 18 // low24* (L + A - P) >> 2 -#define R_PPC_COPY 19 // none none -#define R_PPC_GLOB_DAT 20 // word32 S + A -#define R_PPC_JMP_SLOT 21 // none -#define R_PPC_RELATIVE 22 // word32 B + A +#define R_PPC_GOT16 14 // half16* G + A +#define R_PPC_GOT16_LO 15 // half16 #lo(G + A) +#define R_PPC_GOT16_HI 16 // half16 #hi(G + A) +#define R_PPC_GOT16_HA 17 // half16 #ha(G + A) +#define R_PPC_PLTREL24 18 // low24* (L + A - P) >> 2 +#define R_PPC_COPY 19 // none none +#define R_PPC_GLOB_DAT 20 // word32 S + A +#define R_PPC_JMP_SLOT 21 // none +#define R_PPC_RELATIVE 22 // word32 B + A -#define R_PPC_LOCAL24PC 23 // low24* +#define R_PPC_LOCAL24PC 23 // low24* -#define R_PPC_UADDR32 24 // word32 S + A -#define R_PPC_UADDR16 25 // half16* S + A -#define R_PPC_REL32 26 // word32 S + A - P +#define R_PPC_UADDR32 24 // word32 S + A +#define R_PPC_UADDR16 25 // half16* S + A +#define R_PPC_REL32 26 // word32 S + A - P -#define R_PPC_PLT32 27 // word32 L + A -#define R_PPC_PLTREL32 28 // word32 L + A - P -#define R_PPC_PLT16_LO 29 // half16 #lo(L + A) -#define R_PPL_PLT16_HI 30 // half16 #hi(L + A) -#define R_PPC_PLT16_HA 31 // half16 #ha(L + A) +#define R_PPC_PLT32 27 // word32 L + A +#define R_PPC_PLTREL32 28 // word32 L + A - P +#define R_PPC_PLT16_LO 29 // half16 #lo(L + A) +#define R_PPL_PLT16_HI 30 // half16 #hi(L + A) +#define R_PPC_PLT16_HA 31 // half16 #ha(L + A) -#define R_PPC_SDAREL16 32 // half16* S + A - _SDA_BASE_ -#define R_PPC_SECTOFF 33 // half16* R + A -#define R_PPC_SECTOFF_LO 34 // half16 #lo(R + A) -#define R_PPC_SECTOFF_HI 35 // half16 #hi(R + A) -#define R_PPC_SECTOFF_HA 36 // half16 #ha(R + A) -#define R_PPC_ADDR30 37 // word30 (S + A - P) >> 2 +#define R_PPC_SDAREL16 32 // half16* S + A - _SDA_BASE_ +#define R_PPC_SECTOFF 33 // half16* R + A +#define R_PPC_SECTOFF_LO 34 // half16 #lo(R + A) +#define R_PPC_SECTOFF_HI 35 // half16 #hi(R + A) +#define R_PPC_SECTOFF_HA 36 // half16 #ha(R + A) +#define R_PPC_ADDR30 37 // word30 (S + A - P) >> 2 -#define R_PPC_EMB_NADDR32 101 // uword32 N (A - S) -#define R_PPC_EMB_NADDR16 102 // uhalf16 Y (A - S) -#define R_PPC_EMB_NADDR16_LO 103 // uhalf16 N #lo(A - S) -#define R_PPC_EMB_NADDR16_HI 104 // uhalf16 N #hi(A - S) -#define R_PPC_EMB_NADDR16_HA 105 // uhalf16 N #ha(A - S) -#define R_PPC_EMB_SDAI16 106 // uhalf16 Y T -#define R_PPC_EMB_SDA2I16 107 // uhalf16 Y U -#define R_PPC_EMB_SDA2REL 108 // uhalf16 Y S + A - _SDA2_BASE_ -#define R_PPC_EMB_SDA21 109 // ulow21 N -#define R_PPC_EMB_MRKREF 110 // none N -#define R_PPC_EMB_RELSEC16 111 // uhalf16 Y V + A -#define R_PPC_EMB_RELST_LO 112 // uhalf16 N #lo(W + A) -#define R_PPC_EMB_RELST_HI 113 // uhalf16 N #hi(W + A) -#define R_PPC_EMB_RELST_HA 114 // uhalf16 N #ha(W + A) -#define R_PPC_EMB_BIT_FLD 115 // uword32 Y -#define R_PPC_EMB_RELSDA 116 // uhalf16 Y +#define R_PPC_EMB_NADDR32 101 // uword32 N (A - S) +#define R_PPC_EMB_NADDR16 102 // uhalf16 Y (A - S) +#define R_PPC_EMB_NADDR16_LO 103 // uhalf16 N #lo(A - S) +#define R_PPC_EMB_NADDR16_HI 104 // uhalf16 N #hi(A - S) +#define R_PPC_EMB_NADDR16_HA 105 // uhalf16 N #ha(A - S) +#define R_PPC_EMB_SDAI16 106 // uhalf16 Y T +#define R_PPC_EMB_SDA2I16 107 // uhalf16 Y U +#define R_PPC_EMB_SDA2REL 108 // uhalf16 Y S + A - _SDA2_BASE_ +#define R_PPC_EMB_SDA21 109 // ulow21 N +#define R_PPC_EMB_MRKREF 110 // none N +#define R_PPC_EMB_RELSEC16 111 // uhalf16 Y V + A +#define R_PPC_EMB_RELST_LO 112 // uhalf16 N #lo(W + A) +#define R_PPC_EMB_RELST_HI 113 // uhalf16 N #hi(W + A) +#define R_PPC_EMB_RELST_HA 114 // uhalf16 N #ha(W + A) +#define R_PPC_EMB_BIT_FLD 115 // uword32 Y +#define R_PPC_EMB_RELSDA 116 // uhalf16 Y -#define EnqueueTail(queue, moduleInfo, link) \ - do { \ - OSModuleInfo* __prev; \ - \ - __prev = (queue)->tail; \ - if (__prev == NULL) \ - (queue)->head = (moduleInfo); \ - else \ - __prev->link.next = (moduleInfo); \ - (moduleInfo)->link.prev = __prev; \ - (moduleInfo)->link.next = NULL; \ - (queue)->tail = (moduleInfo); \ - } while (0) +OSModuleQueue __OSModuleInfoList AT_ADDRESS(OS_BASE_CACHED | 0x30C8); +const void* __OSStringTable AT_ADDRESS(OS_BASE_CACHED | 0x30D0); -#define DequeueItem(queue, moduleInfo, link) \ - do { \ - OSModuleInfo* __next; \ - OSModuleInfo* __prev; \ - \ - __next = (moduleInfo)->link.next; \ - __prev = (moduleInfo)->link.prev; \ - \ - if (__next == NULL) \ - (queue)->tail = __prev; \ - else \ - __next->link.prev = __prev; \ - \ - if (__prev == NULL) \ - (queue)->head = __next; \ - else \ - __prev->link.next = __next; \ - } while (0) +#define ENQUEUE_INFO(queue, info, link) \ + do { \ + OSModuleInfo* __prev; \ + \ + __prev = (queue)->tail; \ + if (__prev == NULL) \ + (queue)->head = (info); \ + else \ + __prev->link.next = (info); \ + (info)->link.prev = __prev; \ + (info)->link.next = NULL; \ + (queue)->tail = (info); \ + } while (0) -OSModuleQueue __OSModuleInfoList : (OS_BASE_CACHED | 0x30C8); +#define DEQUEUE_INFO(info, queue, link) \ + do { \ + OSModuleInfo* __next; \ + OSModuleInfo* __prev; \ + \ + __next = (info)->link.next; \ + __prev = (info)->link.prev; \ + \ + if (__next == NULL) \ + (queue)->tail = __prev; \ + else \ + __next->link.prev = __prev; \ + \ + if (__prev == NULL) \ + (queue)->head = __next; \ + else \ + __prev->link.next = __next; \ + } while (0) #pragma dont_inline on +void OSNotifyLink(OSModuleInfo* module) {} -/* 8033DF60-8033DF64 3388A0 0004+00 1/1 0/0 0/0 .text OSNotifyLink */ -__declspec(weak) void OSNotifyLink(OSModuleInfo* module) {} - -/* 8033DF64-8033DF68 3388A4 0004+00 1/1 0/0 0/0 .text OSNotifyUnlink */ -__declspec(weak) void OSNotifyUnlink(OSModuleInfo* module) {} - +void OSNotifyUnlink(OSModuleInfo* module) {} #pragma dont_inline reset -/* 8033DF68-8033DF74 3388A8 000C+00 0/0 1/1 0/0 .text OSSetStringTable */ -void OSSetStringTable(void* string_table) { - __OSStringTable = string_table; +void OSSetStringTable(void* stringTable) { + __OSStringTable = stringTable; } -/* 8033DF74-8033E230 3388B4 02BC+00 1/1 0/0 0/0 .text Relocate */ static BOOL Relocate(OSModuleHeader* newModule, OSModuleHeader* module) { OSModuleID idNew; OSImportInfo* imp; @@ -155,6 +153,7 @@ Found: } else { offset = 0; } + switch (rel->type) { case R_PPC_NONE: break; @@ -225,7 +224,6 @@ Found: return TRUE; } -/* 8033E230-8033E510 338B70 02E0+00 2/2 0/0 0/0 .text Link */ static BOOL Link(OSModuleInfo* newModule, void* bss, BOOL fixed) { u32 i; OSSectionInfo* si; @@ -233,9 +231,14 @@ static BOOL Link(OSModuleInfo* newModule, void* bss, BOOL fixed) { OSModuleInfo* moduleInfo; OSImportInfo* imp; + ASSERTLINE(282, newModule->version <= OS_MODULE_VERSION); + moduleHeader = (OSModuleHeader*)newModule; moduleHeader->bssSection = 0; + ASSERTLINE(290, newModule->version < 2 || moduleHeader->align == 0 || (u32) newModule % moduleHeader->align == 0); + ASSERTLINE(293, newModule->version < 2 || moduleHeader->bssAlign == 0 || (u32) bss % moduleHeader->bssAlign == 0); + if (OS_MODULE_VERSION < newModule->version || 2 <= newModule->version && (moduleHeader->align && (u32)newModule % moduleHeader->align != 0 || @@ -244,7 +247,7 @@ static BOOL Link(OSModuleInfo* newModule, void* bss, BOOL fixed) { return FALSE; } - EnqueueTail(&__OSModuleInfoList, newModule, link); + ENQUEUE_INFO(&__OSModuleInfoList, newModule, link); newModule->sectionInfoOffset += (u32)moduleHeader; moduleHeader->relOffset += (u32)moduleHeader; moduleHeader->impOffset += (u32)moduleHeader; @@ -257,6 +260,7 @@ static BOOL Link(OSModuleInfo* newModule, void* bss, BOOL fixed) { if (si->offset != 0) { si->offset += (u32)moduleHeader; } else if (si->size != 0) { + ASSERTLINE(326, moduleHeader->bssSection == 0); moduleHeader->bssSection = (u8)i; si->offset = (u32)bss; } @@ -313,20 +317,19 @@ static BOOL Link(OSModuleInfo* newModule, void* bss, BOOL fixed) { return TRUE; } -/* 8033E510-8033E534 338E50 0024+00 0/0 1/1 0/0 .text OSLink */ BOOL OSLink(OSModuleInfo* newModule, void* bss) { return Link(newModule, bss, FALSE); } -/* 8033E534-8033E570 338E74 003C+00 0/0 1/1 0/0 .text OSLinkFixed */ BOOL OSLinkFixed(OSModuleInfo* newModule, void* bss) { + ASSERTLINE(400, newModule->version <= OS_MODULE_VERSION && 3 <= newModule->version); + if (OS_MODULE_VERSION < newModule->version || newModule->version < 3) { return FALSE; } return Link(newModule, bss, TRUE); } -/* 8033E570-8033E7A8 338EB0 0238+00 1/1 0/0 0/0 .text Undo */ static BOOL Undo(OSModuleHeader* newModule, OSModuleHeader* module) { OSModuleID idNew; OSImportInfo* imp; @@ -337,7 +340,11 @@ static BOOL Undo(OSModuleHeader* newModule, OSModuleHeader* module) { u32 offset; u32 x; + ASSERTLINE(434, newModule); + idNew = newModule->info.id; + ASSERTLINE(436, idNew); + for (imp = (OSImportInfo*)module->impOffset; imp < (OSImportInfo*)(module->impOffset + module->impSize); imp++) { @@ -418,7 +425,6 @@ Found: return TRUE; } -/* 8033E7A8-8033E97C 3390E8 01D4+00 0/0 1/1 0/0 .text OSUnlink */ BOOL OSUnlink(OSModuleInfo* oldModule) { OSModuleHeader* moduleHeader; OSModuleInfo* moduleInfo; @@ -426,9 +432,11 @@ BOOL OSUnlink(OSModuleInfo* oldModule) { OSSectionInfo* si; OSImportInfo* imp; + ASSERTLINE(546, oldModule->version <= OS_MODULE_VERSION); + moduleHeader = (OSModuleHeader*)oldModule; - DequeueItem(&__OSModuleInfoList, oldModule, link); + DEQUEUE_INFO(oldModule, &__OSModuleInfoList, link); for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) { Undo(moduleHeader, (OSModuleHeader*)moduleInfo); @@ -464,6 +472,7 @@ BOOL OSUnlink(OSModuleInfo* oldModule) { for (i = 1; i < oldModule->numSections; i++) { si = &OSGetSectionInfo(oldModule)[i]; if (i == moduleHeader->bssSection) { + ASSERTLINE(589, si->size != 0); moduleHeader->bssSection = 0; si->offset = 0; } else if (si->offset != 0) { @@ -477,9 +486,43 @@ BOOL OSUnlink(OSModuleInfo* oldModule) { return TRUE; } -/* 8033E97C-8033E994 3392BC 0018+00 0/0 1/1 0/0 .text __OSModuleInit */ void __OSModuleInit(void) { - __OSModuleList.tail = NULL; - __OSModuleList.head = NULL; - __OSStringTable = NULL; -} \ No newline at end of file + __OSModuleInfoList.head = __OSModuleInfoList.tail = 0; + __OSStringTable = 0; +} + +OSModuleInfo* OSSearchModule(void* ptr, u32* section, u32* offset) { + OSModuleInfo* moduleInfo; + OSSectionInfo* sectionInfo; + u32 i; + u32 baseSection; + + if (ptr == NULL) { + return NULL; + } + + moduleInfo = __OSModuleInfoList.head; + while (moduleInfo != 0) { + sectionInfo = (OSSectionInfo*)moduleInfo->sectionInfoOffset; + for (i = 0; i < moduleInfo->numSections; i++) { + if (sectionInfo->size != 0) { + baseSection = sectionInfo->offset & 0xFFFFFFFE; + if (baseSection <= (u32)ptr && (u32)ptr < baseSection + sectionInfo->size) { + if (section != 0) { + *section = i; + } + + if (offset != 0) { + *offset = (u32)ptr - baseSection; + } + + return moduleInfo; + } + } + sectionInfo++; + } + moduleInfo = moduleInfo->link.next; + } + + return NULL; +} diff --git a/src/dolphin/os/OSMemory.c b/src/dolphin/os/OSMemory.c index a9eb77848b..defbad9901 100644 --- a/src/dolphin/os/OSMemory.c +++ b/src/dolphin/os/OSMemory.c @@ -1,14 +1,41 @@ -#include "dolphin/os/OSMemory.h" -#include "dolphin/os.h" +#include +#include +#include + +#include "__os.h" #define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) #define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) -vu16 __MEMRegs[64] AT_ADDRESS(0xCC004000); +static BOOL OnReset(BOOL final); -extern OSErrorHandlerEx __OSErrorTable[16]; +static OSResetFunctionInfo ResetFunctionInfo = { + OnReset, + 0x7F, + NULL, + NULL +}; + +u32 OSGetPhysicalMemSize(void) { +#if DEBUG + OSBootInfo* BootInfo = (OSBootInfo*)OSPhysicalToCached(0); + + return BootInfo->memorySize; +#else + return __OSPhysicalMemSize; +#endif +} + +u32 OSGetConsoleSimulatedMemSize(void) { +#if DEBUG + u32* memSize = (u32*)OSPhysicalToCached(0xF0); + + return *memSize; +#else + return __OSSimulatedMemSize; +#endif +} -/* 8033EC6C-8033ECA8 3395AC 003C+00 1/0 0/0 0/0 .text OnReset */ static BOOL OnReset(BOOL final) { if (final != FALSE) { __MEMRegs[8] = 0xFF; @@ -17,7 +44,8 @@ static BOOL OnReset(BOOL final) { return TRUE; } -/* 8033ECA8-8033ED14 3395E8 006C+00 1/1 0/0 0/0 .text MEMIntrruptHandler */ +void (*__OSErrorTable[])(u16, OSContext*, ...); + static void MEMIntrruptHandler(__OSInterrupt interrupt, OSContext* context) { u32 addr; u32 cause; @@ -26,26 +54,28 @@ static void MEMIntrruptHandler(__OSInterrupt interrupt, OSContext* context) { addr = (((u32)__MEMRegs[0x12] & 0x3ff) << 16) | __MEMRegs[0x11]; __MEMRegs[0x10] = 0; - if (__OSErrorTable[EXCEPTION_MEMORY_PROTECTION]) { - __OSErrorTable[EXCEPTION_MEMORY_PROTECTION](EXCEPTION_MEMORY_PROTECTION, context, cause, - addr); + if (__OSErrorTable[__OS_EXCEPTION_MEMORY_PROTECTION]) { + __OSErrorTable[__OS_EXCEPTION_MEMORY_PROTECTION](__OS_EXCEPTION_MEMORY_PROTECTION, context, cause, addr); return; } - __OSUnhandledException(EXCEPTION_MEMORY_PROTECTION, context, cause, addr); + __OSUnhandledException(__OS_EXCEPTION_MEMORY_PROTECTION, context, cause, addr); } -/* 8033ED14-8033EDD8 339654 00C4+00 0/0 1/1 0/0 .text OSProtectRange */ void OSProtectRange(u32 chan, void* addr, u32 nBytes, u32 control) { BOOL enabled; u32 start; u32 end; u16 reg; + + ASSERTLINE(206, chan < 4); + ASSERTLINE(207, (control & ~(OS_PROTECT_CONTROL_RDWR)) == 0); + if (4 <= chan) { return; } - control &= OS_PROTECT_CONTROL_RDWR; + control &= 3; end = (u32)addr + nBytes; start = TRUNC(addr, 1u << 10); @@ -55,138 +85,120 @@ void OSProtectRange(u32 chan, void* addr, u32 nBytes, u32 control) { enabled = OSDisableInterrupts(); - __OSMaskInterrupts(OS_INTERRUPTMASK(OS_INTR_MEM_0 + chan)); + __OSMaskInterrupts(OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_0 + chan)); __MEMRegs[0 + 2 * chan] = (u16)(start >> 10); __MEMRegs[1 + 2 * chan] = (u16)(end >> 10); reg = __MEMRegs[8]; - reg &= ~(OS_PROTECT_CONTROL_RDWR << 2 * chan); + reg &= ~(3 << 2 * chan); reg |= control << 2 * chan; __MEMRegs[8] = reg; - if (control != OS_PROTECT_CONTROL_RDWR) { - __OSUnmaskInterrupts(OS_INTERRUPTMASK(OS_INTR_MEM_0 + chan)); + if (control != 3) { + __OSUnmaskInterrupts(OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_0 + chan)); } OSRestoreInterrupts(enabled); } -/* 8033EDD8-8033EE58 339718 0080+00 1/1 0/0 0/0 .text Config24MB */ +#ifdef __GEKKO__ static asm void Config24MB(void) { - // clang-format off nofralloc - - li r7, 0 - lis r4, 0x0000 - addi r4, r4, 0x0002 + li r7, 0x0 + lis r4, 0x0 + addi r4, r4, 0x2 lis r3, 0x8000 - addi r3, r3, 0x01FF - lis r6, 0x0100 - addi r6, r6, 0x0002 + addi r3, r3, 0x1ff + lis r6, 0x100 + addi r6, r6, 0x2 lis r5, 0x8100 - addi r5, r5, 0x00FF - isync + addi r5, r5, 0xff + isync mtdbatu 0, r7 mtdbatl 0, r4 mtdbatu 0, r3 - isync + isync mtibatu 0, r7 mtibatl 0, r4 mtibatu 0, r3 - isync + isync mtdbatu 2, r7 mtdbatl 2, r6 mtdbatu 2, r5 - isync + isync mtibatu 2, r7 mtibatl 2, r6 mtibatu 2, r5 - isync + isync mfmsr r3 ori r3, r3, 0x30 - mtspr 0x1b, r3 + mtsrr1 r3 mflr r3 - mtspr 0x1a, r3 + mtsrr0 r3 rfi - // clang-format on } +#endif -/* 8033EE58-8033EED8 339798 0080+00 1/1 0/0 0/0 .text Config48MB */ +#ifdef __GEKKO__ static asm void Config48MB(void) { - // clang-format off nofralloc - - li r7, 0 - lis r4, 0x0000 - addi r4, r4, 0x0002 + li r7, 0x0 + lis r4, 0x0 + addi r4, r4, 0x2 lis r3, 0x8000 - addi r3, r3, 0x03FF - lis r6, 0x0200 - addi r6, r6, 0x0002 + addi r3, r3, 0x3ff + lis r6, 0x200 + addi r6, r6, 0x2 lis r5, 0x8200 - addi r5, r5, 0x01FF - isync + addi r5, r5, 0x1ff + isync mtdbatu 0, r7 mtdbatl 0, r4 mtdbatu 0, r3 - isync + isync mtibatu 0, r7 mtibatl 0, r4 mtibatu 0, r3 - isync + isync mtdbatu 2, r7 mtdbatl 2, r6 mtdbatu 2, r5 - isync + isync mtibatu 2, r7 mtibatl 2, r6 mtibatu 2, r5 - isync + isync mfmsr r3 ori r3, r3, 0x30 - mtspr 0x1b, r3 + mtsrr1 r3 mflr r3 - mtspr 0x1a, r3 + mtsrr0 r3 rfi - // clang-format on } +#endif -/* 8033EED8-8033EEF0 339818 0018+00 1/1 0/0 0/0 .text RealMode */ -static asm void RealMode(register u32 config) { - // clang-format off +#ifdef __GEKKO__ +static asm void RealMode(register u32 addr) { nofralloc - - clrlwi config, config, 2 - mtspr 0x1a, config - mfmsr config - rlwinm config, config, 0, 0x1c, 0x19 - mtspr 0x1b, config + clrlwi addr, addr, 2 + mtsrr0 addr + mfmsr addr + rlwinm addr, addr, 0, 28, 25 + mtsrr1 addr rfi - // clang-format on } +#endif -/* ############################################################################################## */ -/* 803D07D8-803D07E8 -00001 0010+00 1/1 0/0 0/0 .data ResetFunctionInfo */ -static OSResetFunctionInfo ResetFunctionInfo = { - OnReset, - 0x7F, -}; - -inline u32 OSGetPhysicalMemSize() { - return *(u32*)(OSPhysicalToCached(0x0028)); -} - -inline u32 OSGetConsoleSimulatedMemSize() { - return *(u32*)(OSPhysicalToCached(0x00F0)); -} - -/* 8033EEF0-8033F008 339830 0118+00 0/0 1/1 0/0 .text __OSInitMemoryProtection */ -void __OSInitMemoryProtection() { - u32 padding[8]; - u32 simulatedSize; +void __OSInitMemoryProtection(void) { +#ifndef DEBUG + u32 padding[9]; + u32 temp; +#endif BOOL enabled; - simulatedSize = OSGetConsoleSimulatedMemSize(); + u32 size; + + size = OSGetConsoleSimulatedMemSize(); enabled = OSDisableInterrupts(); __MEMRegs[16] = 0; @@ -194,23 +206,27 @@ void __OSInitMemoryProtection() { __OSMaskInterrupts(OS_INTERRUPTMASK_MEM_0 | OS_INTERRUPTMASK_MEM_1 | OS_INTERRUPTMASK_MEM_2 | OS_INTERRUPTMASK_MEM_3); - __OSSetInterruptHandler(OS_INTR_MEM_0, MEMIntrruptHandler); - __OSSetInterruptHandler(OS_INTR_MEM_1, MEMIntrruptHandler); - __OSSetInterruptHandler(OS_INTR_MEM_2, MEMIntrruptHandler); - __OSSetInterruptHandler(OS_INTR_MEM_3, MEMIntrruptHandler); - __OSSetInterruptHandler(OS_INTR_MEM_ADDRESS, MEMIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_MEM_0, MEMIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_MEM_1, MEMIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_MEM_2, MEMIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_MEM_3, MEMIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_MEM_ADDRESS, MEMIntrruptHandler); OSRegisterResetFunction(&ResetFunctionInfo); - if (OSGetConsoleSimulatedMemSize() < OSGetPhysicalMemSize() && - OSGetConsoleSimulatedMemSize() == 0x1800000) +#ifdef DEBUG + if (OSGetConsoleSimulatedMemSize() < OSGetPhysicalMemSize() && OSGetConsoleSimulatedMemSize() == 0x1800000) +#else + temp = OSGetConsoleSimulatedMemSize(); // not sure how else to get the order right on retail + if (temp < OSGetPhysicalMemSize() && temp == 0x1800000) +#endif { DCInvalidateRange((void*)0x81800000, 0x1800000); __MEMRegs[20] = 2; } - if (simulatedSize <= 0x1800000) { + if (size <= 0x1800000) { RealMode((u32)&Config24MB); - } else if (simulatedSize <= 0x3000000) { + } else if (size <= 0x3000000) { RealMode((u32)&Config48MB); } diff --git a/src/dolphin/os/OSMessage.c b/src/dolphin/os/OSMessage.c index 1a12c2e65d..476891b6ee 100644 --- a/src/dolphin/os/OSMessage.c +++ b/src/dolphin/os/OSMessage.c @@ -1,91 +1,70 @@ -#include "dolphin/os/OSMessage.h" +#include +#include -/* 8033E994-8033E9F4 3392D4 0060+00 0/0 13/13 5/5 .text OSInitMessageQueue */ -void OSInitMessageQueue(OSMessageQueue* mq, OSMessage* msgArray, s32 msgCount) { - OSInitThreadQueue(&mq->sending_queue); - OSInitThreadQueue(&mq->receiving_queue); - mq->message_array = msgArray; - mq->num_messages = msgCount; - mq->first_index = 0; - mq->num_used = 0; +void OSInitMessageQueue(OSMessageQueue* mq, void* msgArray, s32 msgCount) { + OSInitThreadQueue(&mq->queueSend); + OSInitThreadQueue(&mq->queueReceive); + mq->msgArray = msgArray; + mq->msgCount = msgCount; + mq->firstIndex = 0; + mq->usedCount = 0; } -/* 8033E9F4-8033EABC 339334 00C8+00 0/0 21/21 9/9 .text OSSendMessage */ -BOOL OSSendMessage(OSMessageQueue* mq, OSMessage msg, s32 flags) { +int OSSendMessage(OSMessageQueue* mq, void* msg, s32 flags) { BOOL enabled; s32 lastIndex; enabled = OSDisableInterrupts(); - - while (mq->num_messages <= mq->num_used) { - if (!(flags & OS_MESSAGE_BLOCK)) { + while(mq->msgCount <= mq->usedCount) { + if (!(flags & 1)) { OSRestoreInterrupts(enabled); - return FALSE; - } else { - OSSleepThread(&mq->sending_queue); + return 0; } + OSSleepThread(&mq->queueSend); } - - lastIndex = (mq->first_index + mq->num_used) % mq->num_messages; - mq->message_array[lastIndex] = msg; - mq->num_used++; - - OSWakeupThread(&mq->receiving_queue); - + lastIndex = (mq->firstIndex + mq->usedCount) % mq->msgCount; + ((u32*)mq->msgArray)[lastIndex] = (u32)msg; + mq->usedCount++; + OSWakeupThread(&mq->queueReceive); OSRestoreInterrupts(enabled); - return TRUE; + return 1; } -/* 8033EABC-8033EB98 3393FC 00DC+00 0/0 15/15 9/9 .text OSReceiveMessage */ -BOOL OSReceiveMessage(OSMessageQueue* mq, OSMessage* msg, s32 flags) { - BOOL enabled; +int OSReceiveMessage(OSMessageQueue* mq, void* msg, s32 flags) { + BOOL enabled = OSDisableInterrupts(); - enabled = OSDisableInterrupts(); - - while (mq->num_used == 0) { - if (!(flags & OS_MESSAGE_BLOCK)) { + while(mq->usedCount == 0) { + if (!(flags & 1)) { OSRestoreInterrupts(enabled); - return FALSE; - } else { - OSSleepThread(&mq->receiving_queue); + return 0; } + OSSleepThread(&mq->queueReceive); } - - if (msg != NULL) { - *msg = mq->message_array[mq->first_index]; + if(msg != NULL) { + *(u32*)msg = ((u32*)mq->msgArray)[mq->firstIndex]; } - mq->first_index = (mq->first_index + 1) % mq->num_messages; - mq->num_used--; - - OSWakeupThread(&mq->sending_queue); - + + mq->firstIndex = (mq->firstIndex + 1) % mq->msgCount; + mq->usedCount--; + OSWakeupThread(&mq->queueSend); OSRestoreInterrupts(enabled); - return TRUE; + return 1; } -/* 8033EB98-8033EC6C 3394D8 00D4+00 0/0 1/1 0/0 .text OSJamMessage */ -BOOL OSJamMessage(OSMessageQueue* queue, void* msg, s32 flags) { - s32 lastMesg; - u32 interrupt; +int OSJamMessage(OSMessageQueue* mq, void* msg, s32 flags) { + BOOL enabled = OSDisableInterrupts(); - interrupt = OSDisableInterrupts(); - - while (queue->num_messages <= queue->num_used) { - if (!(flags & OS_MSG_PERSISTENT)) { - OSRestoreInterrupts(interrupt); - return FALSE; + while(mq->msgCount <= mq->usedCount) { + if(!(flags & 1)) { + OSRestoreInterrupts(enabled); + return 0; } - - OSSleepThread(&queue->sending_queue); + OSSleepThread(&mq->queueSend); } - - // Find last position in queue - lastMesg = (queue->first_index + queue->num_messages - 1) % queue->num_messages; - queue->first_index = lastMesg; - queue->message_array[queue->first_index] = msg; - queue->num_used++; - - OSWakeupThread(&queue->receiving_queue); - OSRestoreInterrupts(interrupt); - return TRUE; -} \ No newline at end of file + mq->firstIndex = (mq->firstIndex + mq->msgCount - 1) % mq->msgCount; + ((u32*)mq->msgArray)[mq->firstIndex] = (u32)msg; + mq->usedCount++; + OSWakeupThread(&mq->queueReceive); + OSRestoreInterrupts(enabled); + return 1; +} diff --git a/src/dolphin/os/OSMutex.c b/src/dolphin/os/OSMutex.c index d9fed8bad1..66b4abd2cb 100644 --- a/src/dolphin/os/OSMutex.c +++ b/src/dolphin/os/OSMutex.c @@ -1,128 +1,135 @@ -#include "dolphin/os/OSMutex.h" -#include "dolphin/os.h" +#include +#include -#define PushTail(queue, mutex, link) \ - do { \ - OSMutex* __prev; \ - \ - __prev = (queue)->tail; \ - if (__prev == NULL) \ - (queue)->head = (mutex); \ - else \ - __prev->link.next = (mutex); \ - (mutex)->link.prev = __prev; \ - (mutex)->link.next = NULL; \ - (queue)->tail = (mutex); \ - } while (0) +#include "__os.h" -#define PopHead(queue, mutex, link) \ - do { \ - OSMutex* __next; \ - \ - (mutex) = (queue)->head; \ - __next = (mutex)->link.next; \ - if (__next == NULL) \ - (queue)->tail = NULL; \ - else \ - __next->link.prev = NULL; \ - (queue)->head = __next; \ - } while (0) +#define ENQUEUE_MUTEX(mutex, queue, link) \ + do { \ + OSMutex* __prev = (queue)->tail; \ + if (__prev == NULL) { \ + (queue)->head = (mutex); \ + } else { \ + __prev->link.next = (mutex); \ + } \ + (mutex)->link.prev = __prev; \ + (mutex)->link.next = 0; \ + (queue)->tail = (mutex); \ + } while(0); -#define PopItem(queue, mutex, link) \ - do { \ - OSMutex* __next; \ - OSMutex* __prev; \ - \ - __next = (mutex)->link.next; \ - __prev = (mutex)->link.prev; \ - \ - if (__next == NULL) \ - (queue)->tail = __prev; \ - else \ - __next->link.prev = __prev; \ - \ - if (__prev == NULL) \ - (queue)->head = __next; \ - else \ - __prev->link.next = __next; \ - } while (0) +#define DEQUEUE_MUTEX(mutex, queue, link) \ + do { \ + OSMutex* __next = (mutex)->link.next; \ + OSMutex* __prev = (mutex)->link.prev; \ + if (__next == NULL) { \ + (queue)->tail = __prev; \ + } else { \ + __next->link.prev = __prev; \ + } \ + if (__prev == NULL) { \ + (queue)->head = __next; \ + } else { \ + __prev->link.next = __next; \ + } \ + } while(0); -// -// Declarations: -// +#define DEQUEUE_HEAD(mutex, queue, link) \ + do { \ + OSMutex* __next = mutex->link.next; \ + if (__next == NULL) { \ + (queue)->tail = 0; \ + } else { \ + __next->link.prev = 0; \ + } \ + (queue)->head = __next; \ + } while(0); + +// prototypes +static int IsMember(OSMutexQueue* queue, OSMutex* mutex); +int __OSCheckMutex(OSMutex* mutex); +int __OSCheckDeadLock(OSThread* thread); +int __OSCheckMutexes(OSThread* thread); -/* 8033F008-8033F040 339948 0038+00 0/0 12/12 0/0 .text OSInitMutex */ void OSInitMutex(OSMutex* mutex) { OSInitThreadQueue(&mutex->queue); mutex->thread = 0; mutex->count = 0; } -/* 8033F040-8033F11C 339980 00DC+00 1/1 62/62 0/0 .text OSLockMutex */ void OSLockMutex(OSMutex* mutex) { BOOL enabled = OSDisableInterrupts(); OSThread* currentThread = OSGetCurrentThread(); - OSThread* ownerThread; - while (TRUE) { - ownerThread = ((OSMutex*)mutex)->thread; + ASSERTMSGLINE(140, currentThread, "OSLockMutex(): current thread does not exist."); + ASSERTMSGLINE(142, currentThread->state == 2, "OSLockMutex(): current thread is not running."); + + while (1) { + OSThread* ownerThread = mutex->thread; if (ownerThread == 0) { mutex->thread = currentThread; mutex->count++; - PushTail(¤tThread->owned_mutexes, mutex, link); + ENQUEUE_MUTEX(mutex, ¤tThread->queueMutex, link); break; } else if (ownerThread == currentThread) { mutex->count++; break; } else { currentThread->mutex = mutex; - __OSPromoteThread(mutex->thread, currentThread->effective_priority); + __OSPromoteThread(mutex->thread, currentThread->priority); + ASSERTMSG2LINE(164, __OSCheckDeadLock(currentThread) == 0, "OSLockMutex(): detected deadlock: current thread %p, mutex %p.", currentThread, mutex); OSSleepThread(&mutex->queue); - currentThread->mutex = 0; + currentThread->mutex = NULL; } } OSRestoreInterrupts(enabled); } -/* 8033F11C-8033F1E4 339A5C 00C8+00 0/0 71/71 0/0 .text OSUnlockMutex */ void OSUnlockMutex(OSMutex* mutex) { BOOL enabled = OSDisableInterrupts(); OSThread* currentThread = OSGetCurrentThread(); - if (mutex->thread == currentThread && --mutex->count == 0) { - PopItem(¤tThread->owned_mutexes, mutex, link); - mutex->thread = NULL; - if ((s32)currentThread->effective_priority < (s32)currentThread->base_priority) { - currentThread->effective_priority = __OSGetEffectivePriority(currentThread); - } + ASSERTMSGLINE(189, currentThread, "OSUnlockMutex(): current thread does not exist."); + ASSERTMSGLINE(191, currentThread->state == 2, "OSUnlockMutex(): current thread is not running."); + ASSERTMSG2LINE(194, mutex->thread == currentThread, "OSUnlockMutex(): current thread %p is not the owner of mutex %p.", currentThread, mutex); - OSWakeupThread(&mutex->queue); + if (mutex->thread == currentThread) { + if (!--mutex->count) { + DEQUEUE_MUTEX(mutex, ¤tThread->queueMutex, link); + mutex->thread = 0; + + if (currentThread->priority < currentThread->base) { + currentThread->priority = __OSGetEffectivePriority(currentThread); + } + OSWakeupThread(&mutex->queue); + } } OSRestoreInterrupts(enabled); } -/* 8033F1E4-8033F254 339B24 0070+00 0/0 2/2 0/0 .text __OSUnlockAllMutex */ void __OSUnlockAllMutex(OSThread* thread) { OSMutex* mutex; - while (thread->owned_mutexes.head) { - PopHead(&thread->owned_mutexes, mutex, link); + while (thread->queueMutex.head) { + mutex = thread->queueMutex.head; + DEQUEUE_HEAD(mutex, &thread->queueMutex, link); + ASSERTLINE(229, mutex->thread == thread); mutex->count = 0; - mutex->thread = NULL; + mutex->thread = 0; OSWakeupThread(&mutex->queue); } } -/* 8033F254-8033F310 339B94 00BC+00 0/0 9/9 0/0 .text OSTryLockMutex */ - BOOL OSTryLockMutex(OSMutex* mutex) { BOOL enabled = OSDisableInterrupts(); OSThread* currentThread = OSGetCurrentThread(); BOOL locked; - if (mutex->thread == 0) { + + ASSERTMSGLINE(255, currentThread, "OSTryLockMutex(): current thread does not exist."); + ASSERTMSGLINE(257, currentThread->state == 2, "OSTryLockMutex(): current thread is not running."); + + if (!mutex->thread) { mutex->thread = currentThread; mutex->count++; - PushTail(¤tThread->owned_mutexes, mutex, link); + ENQUEUE_MUTEX(mutex, ¤tThread->queueMutex, link); locked = TRUE; } else if (mutex->thread == currentThread) { mutex->count++; @@ -134,25 +141,26 @@ BOOL OSTryLockMutex(OSMutex* mutex) { return locked; } -/* 8033F310-8033F330 339C50 0020+00 0/0 1/1 0/0 .text OSInitCond */ -void OSInitCond(OSCond* cond) { OSInitThreadQueue(&cond->queue); } +void OSInitCond(OSCond* cond) { + OSInitThreadQueue(&cond->queue); +} -/* 8033F330-8033F404 339C70 00D4+00 0/0 1/1 0/0 .text OSWaitCond */ void OSWaitCond(OSCond* cond, OSMutex* mutex) { BOOL enabled = OSDisableInterrupts(); OSThread* currentThread = OSGetCurrentThread(); - s32 count; + + ASSERTMSGLINE(313, currentThread, "OSWaitCond(): current thread does not exist."); + ASSERTMSGLINE(315, currentThread->state == 2, "OSWaitCond(): current thread is not running."); + ASSERTMSG2LINE(318, mutex->thread == currentThread, "OSWaitCond(): current thread %p is not the owner of mutex %p.", currentThread, mutex); if (mutex->thread == currentThread) { - count = mutex->count; + s32 count = mutex->count; mutex->count = 0; - PopItem(¤tThread->owned_mutexes, mutex, link); - mutex->thread = NULL; - - if (currentThread->effective_priority < (s32)currentThread->base_priority) { - currentThread->effective_priority = __OSGetEffectivePriority(currentThread); + DEQUEUE_MUTEX(mutex, ¤tThread->queueMutex, link); + mutex->thread = 0; + if (currentThread->priority < currentThread->base) { + currentThread->priority = __OSGetEffectivePriority(currentThread); } - OSDisableScheduler(); OSWakeupThread(&mutex->queue); OSEnableScheduler(); @@ -160,83 +168,89 @@ void OSWaitCond(OSCond* cond, OSMutex* mutex) { OSLockMutex(mutex); mutex->count = count; } - OSRestoreInterrupts(enabled); } -/* 8033F404-8033F424 339D44 0020+00 0/0 5/5 0/0 .text OSSignalCond */ void OSSignalCond(OSCond* cond) { OSWakeupThread(&cond->queue); } -static BOOL IsMember(OSMutexQueue* queue, OSMutex* mutex) { - OSMutex* member; +static int IsMember(OSMutexQueue* queue, OSMutex* mutex) { + OSMutex* member = queue->head; - for (member = queue->head; member; member = member->link.next) { - if (mutex == member) - return TRUE; + while (member) { + if (mutex == member) { + return 1; + } + member = member->link.next; } - return FALSE; + return 0; } -/* 8033F424-8033F524 339D64 0100+00 1/1 0/0 0/0 .text __OSCheckMutex */ -BOOL __OSCheckMutex(OSMutex* mutex) { +int __OSCheckMutex(OSMutex* mutex) { OSThread* thread; OSThreadQueue* queue; - OSPriority priority = 0; + s32 priority; + priority = 0; queue = &mutex->queue; - if (!(queue->head == NULL || queue->head->link.prev == NULL)) - return FALSE; - if (!(queue->tail == NULL || queue->tail->link.next == NULL)) - return FALSE; - for (thread = queue->head; thread; thread = thread->link.next) { - if (!(thread->link.next == NULL || thread == thread->link.next->link.prev)) - return FALSE; - if (!(thread->link.prev == NULL || thread == thread->link.prev->link.next)) - return FALSE; - if (thread->state != OS_THREAD_STATE_WAITING) - return FALSE; - - if (thread->effective_priority < priority) - return FALSE; - priority = thread->effective_priority; + if (queue->head != NULL && queue->head->link.prev != NULL) { + return 0; + } + if (queue->tail != NULL && queue->tail->link.next != NULL) { + return 0; + } + thread = queue->head; + while (thread) { + if (thread->link.next != NULL && (thread != thread->link.next->link.prev)) { + return 0; + } + if (thread->link.prev != NULL && (thread != thread->link.prev->link.next)) { + return 0; + } + if (thread->state != 4) { + return 0; + } + if (thread->priority < priority) { + return 0; + } + priority = thread->priority; + thread = thread->link.next; } - if (mutex->thread) { - if (mutex->count <= 0) - return FALSE; - } else { - if (0 != mutex->count) - return FALSE; + if (mutex->count <= 0) { + return 0; + } + } else if (mutex->count != 0) { + return 0; } - - return TRUE; + return 1; } -/* 8033F524-8033F55C 339E64 0038+00 0/0 1/1 0/0 .text __OSCheckDeadLock */ -BOOL __OSCheckDeadLock(OSThread* thread) { - OSMutex* mutex; +int __OSCheckDeadLock(OSThread* thread) { + OSMutex* mutex = thread->mutex; - mutex = thread->mutex; while (mutex && mutex->thread) { - if (mutex->thread == thread) - return TRUE; + if (mutex->thread == thread) { + return 1; + } mutex = mutex->thread->mutex; } - return FALSE; + return 0; } -/* 8033F55C-8033F5D0 339E9C 0074+00 0/0 1/1 0/0 .text __OSCheckMutexes */ -BOOL __OSCheckMutexes(OSThread* thread) { - OSMutex* mutex; +int __OSCheckMutexes(OSThread* thread) { + OSMutex* mutex = thread->queueMutex.head; - for (mutex = thread->owned_mutexes.head; mutex; mutex = mutex->link.next) { - if (mutex->thread != thread) - return FALSE; - if (!__OSCheckMutex(mutex)) - return FALSE; + while (mutex) { + if (mutex->thread != thread) { + return 0; + } + if (__OSCheckMutex(mutex) == 0) { + return 0; + } + mutex = mutex->link.next; } - return TRUE; -} \ No newline at end of file + return 1; +} diff --git a/src/dolphin/os/OSReboot.c b/src/dolphin/os/OSReboot.c index 3a7540dd78..c921b4d8a7 100644 --- a/src/dolphin/os/OSReboot.c +++ b/src/dolphin/os/OSReboot.c @@ -1,34 +1,39 @@ -#include "dolphin/os/OSReboot.h" -#include "dolphin/os/OSContext.h" -#include "dolphin/os/OSExec.h" +#include +#include + +#include "__os.h" + +static void* SaveStart; +static void* SaveEnd; -/* 8033F5D0-8033F640 339F10 0070+00 0/0 1/1 0/0 .text __OSReboot */ void __OSReboot(u32 resetCode, u32 bootDol) { - struct OSContext context; - char* iVar1; + OSContext exceptionContext; + char* argvToPass; + OSDisableInterrupts(); OSSetArenaLo((void*)0x81280000); OSSetArenaHi((void*)0x812f0000); - OSClearContext(&context); - OSSetCurrentContext(&context); - iVar1 = NULL; - __OSBootDol(bootDol, resetCode | 0x80000000, &iVar1); + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + argvToPass = NULL; + __OSBootDol(bootDol, resetCode | 0x80000000, &argvToPass); } -/* 80451688-8045168C 000B88 0004+00 2/2 0/0 0/0 .sbss SaveStart */ -static void* SaveStart; - -/* 8045168C-80451690 000B8C 0004+00 2/2 0/0 0/0 .sbss SaveEnd */ -static void* SaveEnd; - -/* 8033F640-8033F64C 339F80 000C+00 0/0 1/1 0/0 .text OSSetSaveRegion */ void OSSetSaveRegion(void* start, void* end) { + ASSERTMSGLINE(134, (u32)start >= 0x80700000 || start == NULL, "OSSetSaveRegion(): start address should be NULL or higher than 0x80700000\n"); + ASSERTMSGLINE(135, 0x81200000 >= (u32)end || end == NULL, "OSSetSaveRegion(): end address should be NULL or lower than 0x81200000\n"); + ASSERTMSGLINE(136, ((start == NULL) ^ (end == NULL)) == 0, "OSSetSaveRegion(): if either start or end is NULL, both should be NULL\n"); + SaveStart = start; SaveEnd = end; } -/* 8033F64C-8033F660 339F8C 0014+00 0/0 1/1 0/0 .text OSGetSaveRegion */ void OSGetSaveRegion(void** start, void** end) { *start = SaveStart; *end = SaveEnd; -} \ No newline at end of file +} + +void OSGetSavedRegion(void** start, void** end) { + *start = __OSRebootParams.regionStart; + *end = __OSRebootParams.regionEnd; +} diff --git a/src/dolphin/os/OSReset.c b/src/dolphin/os/OSReset.c index c9a5054e60..21953da870 100644 --- a/src/dolphin/os/OSReset.c +++ b/src/dolphin/os/OSReset.c @@ -1,131 +1,151 @@ -#include "dolphin/os/OSReset.h" -#include "dolphin/os.h" +#include +#include -vu16 __VIRegs[59] AT_ADDRESS(0xCC002000); -OSThreadQueue __OSActiveThreadQueue : (OS_BASE_CACHED | 0x00DC); +#include "__os.h" -extern OSExecParams __OSRebootParams; +// These macros are copied from OSThread.c. Or ARE they the same +// macros? They dont seem to be in the SDK headers. +#define ENQUEUE_INFO(info, queue) \ + do { \ + OSResetFunctionInfo* __prev = (queue)->tail; \ + if (__prev == 0) { \ + (queue)->head = (info); \ + } else { \ + __prev->next = (info); \ + } \ + (info)->prev = __prev; \ + (info)->next = 0; \ + (queue)->tail = (info); \ + } while(0); -/* 80451690-80451698 000B90 0008+00 2/2 0/0 0/0 .sbss ResetFunctionQueue */ -static OSResetQueue ResetFunctionQueue; +#define DEQUEUE_INFO(info, queue) \ + do { \ + OSResetFunctionInfo* __next = (info)->next; \ + OSResetFunctionInfo* __prev = (info)->prev; \ + if (__next == 0) { \ + (queue)->tail = __prev; \ + } else { \ + __next->prev = __prev; \ + } \ + if (__prev == 0) { \ + (queue)->head = __next; \ + } else { \ + __prev->next = __next; \ + } \ + } while(0); -/* 8033F660-8033F6E4 339FA0 0084+00 0/0 5/5 0/0 .text OSRegisterResetFunction */ -void OSRegisterResetFunction(OSResetFunctionInfo* func) { - OSResetFunctionInfo* tmp; - OSResetFunctionInfo* iter; +#define ENQUEUE_INFO_PRIO(info, queue) \ + do { \ + OSResetFunctionInfo* __prev; \ + OSResetFunctionInfo* __next; \ + for(__next = (queue)->head; __next \ + && (__next->priority <= (info)->priority); \ + __next = __next->next) ; \ + \ + if (__next == 0) { \ + ENQUEUE_INFO(info, queue); \ + } else { \ + (info)->next = __next; \ + __prev = __next->prev; \ + __next->prev = (info); \ + (info)->prev = __prev; \ + if (__prev == 0) { \ + (queue)->head = (info); \ + } else { \ + __prev->next = (info); \ + } \ + } \ + } while(0); - for (iter = ResetFunctionQueue.first; iter && iter->priority <= func->priority; - iter = iter->next) - ; +static OSResetFunctionQueue ResetFunctionQueue; +static u32 bootThisDol; - if (iter == NULL) { - tmp = ResetFunctionQueue.last; - if (tmp == NULL) { - ResetFunctionQueue.first = func; - } else { - tmp->next = func; - } - func->prev = tmp; - func->next = NULL; - ResetFunctionQueue.last = func; - return; - } +// prototypes +static int CallResetFunctions(int final); +static void Reset(u32 resetCode); - func->next = iter; - tmp = iter->prev; - iter->prev = func; - func->prev = tmp; - if (tmp == NULL) { - ResetFunctionQueue.first = func; - return; - } - tmp->next = func; +void OSRegisterResetFunction(OSResetFunctionInfo* info) { + ASSERTLINE(208, info->func); + + ENQUEUE_INFO_PRIO(info, &ResetFunctionQueue); } -/* 8033F6E4-8033F78C 33A024 00A8+00 1/1 0/0 0/0 .text __OSCallResetFunctions */ -BOOL __OSCallResetFunctions(u32 arg0) { - OSResetFunctionInfo* iter; - s32 retCode = 0; - u32 priority = 0; - s32 temp; +void OSUnregisterResetFunction(OSResetFunctionInfo* info) { + DEQUEUE_INFO(info, &ResetFunctionQueue); +} - for (iter = ResetFunctionQueue.first; iter != NULL;) { - if (retCode != 0 && priority != iter->priority) +int __OSCallResetFunctions(BOOL final) { + OSResetFunctionInfo* info; + int err; + u32 priority; + + priority = 0; + err = 0; + + for (info = ResetFunctionQueue.head; info != 0;) { + if (err != 0 && priority != info->priority) break; - temp = !iter->func(arg0); - priority = iter->priority; - iter = iter->next; - retCode |= temp; + err |= !info->func(final); + priority = info->priority; + info = info->next; } - retCode |= !__OSSyncSram(); - if (retCode) { + + err |= !__OSSyncSram(); + if (err) { return 0; } return 1; } -/* 8033F78C-8033F7FC 33A0CC 0070+00 2/2 0/0 0/0 .text Reset */ -static asm void Reset(register s32 param_0) { - // clang-format off +#ifdef __GEKKO__ +static asm void Reset(u32 resetCode) { nofralloc - - b lbl_8033F7AC - -lbl_8033F790: - mfspr r8, 0x3f0 - ori r8, r8, 8 - mtspr 0x3f0, r8 - isync + b L_000001BC +L_000001A0: + mfspr r8, HID0 + ori r8, r8, 0x8 + mtspr HID0, r8 + isync sync nop - b lbl_8033F7B0 - -lbl_8033F7AC: - b lbl_8033F7CC - -lbl_8033F7B0: - mftb r5, 0x10c - -lbl_8033F7B4: - mftb r6, 0x10c + b L_000001C0 +L_000001BC: + b L_000001DC +L_000001C0: + mftb r5, 268 +L_000001C4: + mftb r6, 268 subf r7, r5, r6 cmplwi r7, 0x1124 - blt lbl_8033F7B4 - nop - b lbl_8033F7D0 - -lbl_8033F7CC: - b lbl_8033F7EC - -lbl_8033F7D0: - lis r8, 0xCC00 + blt L_000001C4 + nop + b L_000001E0 +L_000001DC: + b L_000001FC +L_000001E0: + lis r8, 0xcc00 ori r8, r8, 0x3000 - li r4, 3 + li r4, 0x3 stw r4, 0x24(r8) - stw param_0, 0x24(r8) - nop - b lbl_8033F7F0 - -lbl_8033F7EC: - b lbl_8033F7F8 - -lbl_8033F7F0: - nop - b lbl_8033F7F0 - -lbl_8033F7F8: - b lbl_8033F790 - // clang-format on + stw r3, 0x24(r8) + nop + b L_00000200 +L_000001FC: + b L_00000208 +L_00000200: + nop + b L_00000200 +L_00000208: + b L_000001A0 } +#endif -/* 8033F7FC-8033F864 33A13C 0068+00 1/1 0/0 0/0 .text KillThreads */ -#pragma dont_inline on static void KillThreads(void) { OSThread* thread; OSThread* next; for (thread = __OSActiveThreadQueue.head; thread; thread = next) { - next = thread->active_threads_link.next; + next = thread->linkActive.next; switch (thread->state) { case 1: case 4: @@ -136,33 +156,49 @@ static void KillThreads(void) { } } } -#pragma dont_inline reset -/* 8033F864-8033F8AC 33A1A4 0048+00 0/0 3/3 0/0 .text __OSDoHotReset */ -void __OSDoHotReset(s32 arg0) { +void __OSDoHotReset(u32 resetCode) { OSDisableInterrupts(); __VIRegs[1] = 0; ICFlashInvalidate(); - Reset(arg0 * 8); + Reset(resetCode * 8); } -/* ############################################################################################## */ -/* 80451698-804516A0 000B98 0004+04 1/1 0/0 0/0 .sbss bootThisDol */ -static u32 bootThisDol; - -/* 8033F8AC-8033FAAC 33A1EC 0200+00 0/0 5/5 0/0 .text OSResetSystem */ -void OSResetSystem(int reset, u32 resetCode, BOOL forceMenu) { - BOOL rc; +void __OSShutdownDevices(BOOL doRecal) { + int rc; BOOL disableRecalibration; - u32 unk; + + __OSStopAudioSystem(); + + if (!doRecal) { + disableRecalibration = __PADDisableRecalibration(TRUE); + } + + do {} while (!__OSCallResetFunctions(FALSE)); + do {} while (!__OSSyncSram()); + + OSDisableInterrupts(); + + rc = __OSCallResetFunctions(TRUE); + ASSERTLINE(408, rc); + + LCDisable(); + if (!doRecal) { + __PADDisableRecalibration(disableRecalibration); + } + + KillThreads(); +} + +void OSResetSystem(BOOL reset, u32 resetCode, BOOL forceMenu) { + OSSram* sram; + OSDisableScheduler(); - if (reset == OS_RESET_HOTRESET && forceMenu) { - OSSram* sram; - + if (reset == TRUE && forceMenu) { sram = __OSLockSram(); sram->flags |= 0x40; - __OSUnlockSram(TRUE); + __OSUnlockSram(1); resetCode = 0; } @@ -170,39 +206,21 @@ void OSResetSystem(int reset, u32 resetCode, BOOL forceMenu) { if (reset == OS_RESET_SHUTDOWN || (reset == OS_RESET_RESTART && (bootThisDol || resetCode + 0x3fff0000 == 0))) { - __OSStopAudioSystem(); - disableRecalibration = __PADDisableRecalibration(TRUE); - while (!__OSCallResetFunctions(FALSE)) - ; - while (!__OSSyncSram()) - ; - OSDisableInterrupts(); - __OSCallResetFunctions(TRUE); - LCDisable(); - __PADDisableRecalibration(disableRecalibration); - KillThreads(); + __OSShutdownDevices(FALSE); } else { - __OSStopAudioSystem(); - while (!__OSCallResetFunctions(FALSE)) - ; - while (!__OSSyncSram()) - ; - OSDisableInterrupts(); - __OSCallResetFunctions(TRUE); - LCDisable(); - KillThreads(); + __OSShutdownDevices(TRUE); } if (reset == OS_RESET_HOTRESET) { __OSDoHotReset(resetCode); } else if (reset == OS_RESET_RESTART) { if (forceMenu == TRUE) { - OSReport( - "OSResetSystem(): You can't specify TRUE to forceMenu if you restart. Ignored\n"); + OSReport("OSResetSystem(): You can't specify TRUE to forceMenu if you restart. Ignored\n"); } OSEnableScheduler(); __OSReboot(resetCode, bootThisDol); } + memset(OSPhysicalToCached(0x40), 0, 0xcc - 0x40); memset(OSPhysicalToCached(0xd4), 0, 0xe8 - 0xd4); memset(OSPhysicalToCached(0xf4), 0, 0xf8 - 0xf4); @@ -211,10 +229,20 @@ void OSResetSystem(int reset, u32 resetCode, BOOL forceMenu) { memset(OSPhysicalToCached(0x30e2), 0, 1); } -/* 8033FAAC-8033FAE4 33A3EC 0038+00 0/0 3/3 0/0 .text OSGetResetCode */ -u32 OSGetResetCode(void) { +u32 OSGetResetCode() { + u32 resetCode; if (__OSRebootParams.valid) - return 0x80000000 | __OSRebootParams.restartCode; + resetCode = 0x80000000 | __OSRebootParams.restartCode; + else + resetCode = (__PIRegs[9] & 0xFFFFFFF8) / 8; - return ((__PIRegs[9] & ~7) >> 3); + return resetCode; +} + +u32 OSSetBootDol(u32 dolOffset) { + u32 oldDol; + + oldDol = bootThisDol; + bootThisDol = dolOffset; + return oldDol; } diff --git a/src/dolphin/os/OSResetSW.c b/src/dolphin/os/OSResetSW.c index b119107964..bbc5d2d161 100644 --- a/src/dolphin/os/OSResetSW.c +++ b/src/dolphin/os/OSResetSW.c @@ -1,28 +1,15 @@ -#include "dolphin/os/OSResetSW.h" -#include "dolphin/os.h" -#include "dolphin/os/OSReset.h" +#include +#include -u8 GameChoice : (OS_BASE_CACHED | 0x30E3); +#include "__os.h" -void __OSResetSWInterruptHandler(__OSInterrupt interrupt, OSContext* context); - -/* 804516A0-804516A4 000BA0 0004+00 1/1 0/0 0/0 .sbss ResetCallback */ static OSResetCallback ResetCallback; - -/* 804516A4-804516A8 000BA4 0004+00 2/2 0/0 0/0 .sbss Down */ static BOOL Down; - -/* 804516A8-804516B0 000BA8 0004+04 2/2 0/0 0/0 .sbss LastState */ static BOOL LastState; - -/* 804516B0-804516B4 000BB0 0004+00 1/1 0/0 0/0 .sbss HoldUp */ static OSTime HoldUp; - -/* 804516B8-804516BC 000BB8 0004+00 2/2 0/0 0/0 .sbss HoldDown */ static OSTime HoldDown; -/* 8033FAE4-8033FBD8 33A424 00F4+00 0/0 1/1 0/0 .text __OSResetSWInterruptHandler */ -void __OSResetSWInterruptHandler(__OSInterrupt interrupt, OSContext* context) { +void __OSResetSWInterruptHandler(s16 exception, OSContext* context) { OSResetCallback callback; HoldDown = __OSGetSystemTime(); @@ -42,13 +29,36 @@ void __OSResetSWInterruptHandler(__OSInterrupt interrupt, OSContext* context) { __PIRegs[0] = 2; } -/* 8033FBD8-8033FE70 33A518 0298+00 1/1 0/0 0/0 .text OSGetResetButtonState */ +OSResetCallback OSSetResetCallback(OSResetCallback callback) { + BOOL enabled; + OSResetCallback prevCallback; + + enabled = OSDisableInterrupts(); + prevCallback = ResetCallback; + ResetCallback = callback; + + if (callback) { + __PIRegs[0] = 2; + __OSUnmaskInterrupts(0x200); + } else { + __OSMaskInterrupts(0x200); + } + OSRestoreInterrupts(enabled); + return prevCallback; +} + BOOL OSGetResetButtonState(void) { BOOL enabled = OSDisableInterrupts(); - BOOL state; - OSTime now = __OSGetSystemTime(); - u32 reg = __PIRegs[0]; + int state; + u32 reg; + OSTime now; + now = __OSGetSystemTime(); + ASSERTLINE(158, 0 <= now); + ASSERTLINE(159, HoldUp == 0 || HoldUp < now); + ASSERTLINE(160, HoldDown == 0 || HoldDown < now); + + reg = __PIRegs[0]; if (!(reg & 0x00010000)) { if (!Down) { Down = TRUE; @@ -76,8 +86,8 @@ BOOL OSGetResetButtonState(void) { LastState = state; - if (GameChoice & 0x1F) { - OSTime fire = (GameChoice & 0x1F) * 60; + if (__gUnknown800030E3 & 0x1F) { + OSTime fire = (__gUnknown800030E3 & 0x1F) * 60; fire = __OSStartTime + OSSecondsToTicks(fire); if (fire < now) { now -= fire; @@ -94,7 +104,17 @@ BOOL OSGetResetButtonState(void) { return state; } -/* 8033FE70-8033FE90 33A7B0 0020+00 0/0 1/1 0/0 .text OSGetResetSwitchState */ -BOOL OSGetResetSwitchState(void) { +int OSGetResetSwitchState(void) { return OSGetResetButtonState(); -} \ No newline at end of file +} + +void __OSSetResetButtonTimer(u8 min) { + BOOL enabled = OSDisableInterrupts(); + if (min > 0x1F) { + min = 0x1F; + } + + __gUnknown800030E3 &= ~0x1F; + __gUnknown800030E3 |= min; + OSRestoreInterrupts(enabled); +} diff --git a/src/dolphin/os/OSRtc.c b/src/dolphin/os/OSRtc.c index 1e480fb79a..7b37b4cae0 100644 --- a/src/dolphin/os/OSRtc.c +++ b/src/dolphin/os/OSRtc.c @@ -1,124 +1,187 @@ -#include "dolphin/os/OSRtc.h" -#include "dolphin/os/OSInterrupt.h" +#include +#include -static void WriteSramCallback(s32 chan, OSContext* context); -static BOOL WriteSram(void* buffer, u32 offset, u32 size); -static BOOL UnlockSram(BOOL commit, u32 offset); +#include "__os.h" -/* 8044BB20-8044BB78 078840 0054+04 14/14 0/0 0/0 .bss Scb */ -static SramControlBlock Scb ALIGN_DECL(32); +static SramControl Scb ATTRIBUTE_ALIGN(DOLPHIN_ALIGNMENT); -/* 8033FE90-8033FEF0 33A7D0 0060+00 2/2 0/0 0/0 .text WriteSramCallback */ -static void WriteSramCallback(s32 chan, OSContext* context) { - Scb.sync = WriteSram(Scb.sram + Scb.offset, Scb.offset, RTC_SRAM_SIZE - Scb.offset); - if (Scb.sync) { - Scb.offset = RTC_SRAM_SIZE; - } -} +// prototypes +static int GetRTC(u32* rtc); +static int ReadSram(void* buffer); +static void WriteSramCallback(s32, OSContext*); +static int WriteSram(void* buffer, u32 offset, u32 size); +static void* LockSram(u32 offset); +static int UnlockSram(int commit, u32 offset); +static void __OSReadROMCallback(s32 chan); -static inline BOOL ReadSram(void* buffer) { - BOOL err; +static int GetRTC(u32* rtc) { + int err; u32 cmd; - DCInvalidateRange(buffer, RTC_SRAM_SIZE); - - if (!EXILock(RTC_CHAN, RTC_DEV, 0)) { - return FALSE; + if (EXILock(0, 1, NULL) == 0) { + return 0; } - if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { - EXIUnlock(RTC_CHAN); - return FALSE; + if (EXISelect(0, 1, 3) == 0) { + EXIUnlock(0); + return 0; } - - cmd = RTC_CMD_READ | RTC_SRAM_ADDR; - err = FALSE; - err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL); - err |= !EXISync(RTC_CHAN); - err |= !EXIDma(RTC_CHAN, buffer, RTC_SRAM_SIZE, 0, NULL); - err |= !EXISync(RTC_CHAN); - err |= !EXIDeselect(RTC_CHAN); - EXIUnlock(RTC_CHAN); - + cmd = 0x20000000; + err = 0; + err |= !EXIImm(0, &cmd, 4, 1, 0); + err |= !EXISync(0); + err |= !EXIImm(0, &cmd, 4, 0, 0); + err |= !EXISync(0); + err |= !EXIDeselect(0); + EXIUnlock(0); + rtc[0] = cmd; return !err; } -/* 8033FEF0-80340008 33A830 0118+00 1/1 0/0 0/0 .text WriteSram */ -BOOL WriteSram(void* buffer, u32 offset, u32 size) { - BOOL err; +int __OSGetRTC(u32* rtc) { + int err; + u32 t0; + u32 t1; + int i; + + for(i = 0; i < 16; i++) { + err = 0; + err |= !GetRTC(&t0); + err |= !GetRTC(&t1); + if (err) { + break; + } + if (t0 == t1) { + rtc[0] = t0; + return 1; + } + } + return 0; +} + +int __OSSetRTC(u32 rtc) { + int err; u32 cmd; - if (!EXILock(RTC_CHAN, RTC_DEV, WriteSramCallback)) { - return FALSE; + if (EXILock(0, 1, NULL) == 0) { + return 0; } - if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { - EXIUnlock(RTC_CHAN); - return FALSE; + if (EXISelect(0, 1, 3) == 0) { + EXIUnlock(0); + return 0; } + cmd = 0xA0000000; + err = 0; + err |= !EXIImm(0, &cmd, 4, 1, 0); + err |= !EXISync(0); + err |= !EXIImm(0, &rtc, 4, 1, 0); + err |= !EXISync(0); + err |= !EXIDeselect(0); + EXIUnlock(0); + return !err; +} +static int ReadSram(void* buffer) { + int err; + u32 cmd; + + DCInvalidateRange(buffer, SRAM_SIZE); + if (!EXILock(0, 1, NULL) ) { + return 0; + } + if (!EXISelect(0, 1, 3)) { + EXIUnlock(0); + return 0; + } + cmd = 0x20000100; + err = 0; + err |= !EXIImm(0, &cmd, 4, 1, 0); + err |= !EXISync(0); + err |= !EXIDma(0, buffer, SRAM_SIZE, 0, NULL); + err |= !EXISync(0); + err |= !EXIDeselect(0); + EXIUnlock(0); + return !err; +} + +static void WriteSramCallback(s32, OSContext*) { + ASSERTLINE(258, !Scb.locked); + Scb.sync = WriteSram(&Scb.sram[Scb.offset], Scb.offset, SRAM_SIZE - Scb.offset); + if (Scb.sync != 0) { + Scb.offset = SRAM_SIZE; + } + ASSERTLINE(264, Scb.sync); +} + +static int WriteSram(void* buffer, u32 offset, u32 size) { + int err; + u32 cmd; + + if (!EXILock(0, 1, WriteSramCallback)) { + return 0; + } + if (!EXISelect(0, 1, 3)) { + EXIUnlock(0); + return 0; + } offset <<= 6; - cmd = RTC_CMD_WRITE | RTC_SRAM_ADDR + offset; - err = FALSE; - err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL); - err |= !EXISync(RTC_CHAN); - err |= !EXIImmEx(RTC_CHAN, buffer, (s32)size, 1); - err |= !EXIDeselect(RTC_CHAN); - EXIUnlock(RTC_CHAN); - + cmd = ((offset + 0x100) | 0xA0000000); + err = 0; + err |= !EXIImm(0, &cmd, 4, 1, 0); + err |= !EXISync(0); + err |= !EXIImmEx(0, buffer, size, 1); + err |= !EXIDeselect(0); + EXIUnlock(0); return !err; } -/* 80340008-80340144 33A948 013C+00 0/0 1/1 0/0 .text __OSInitSram */ void __OSInitSram(void) { Scb.locked = Scb.enabled = FALSE; - Scb.sync = ReadSram(Scb.sram); - Scb.offset = RTC_SRAM_SIZE; + Scb.sync = ReadSram(&Scb); + ASSERTLINE(318, Scb.sync); + Scb.offset = SRAM_SIZE; + OSSetGbsMode(OSGetGbsMode()); } static void* LockSram(u32 offset) { BOOL enabled; - enabled = OSDisableInterrupts(); - if (Scb.locked != FALSE) { + enabled = OSDisableInterrupts(); + ASSERTLINE(341, !Scb.locked); + if (Scb.locked) { OSRestoreInterrupts(enabled); return NULL; } - Scb.enabled = enabled; Scb.locked = TRUE; - - return Scb.sram + offset; + return &Scb.sram[offset]; } -/* 80340144-803401A0 33AA84 005C+00 0/0 3/3 0/0 .text __OSLockSram */ -OSSram* __OSLockSram() { - return LockSram(0); +OSSram* __OSLockSram(void) { + return (OSSram*)LockSram(0); } -/* 803401A0-803401FC 33AAE0 005C+00 0/0 4/4 0/0 .text __OSLockSramEx */ -OSSramEx* __OSLockSramEx() { - return LockSram(sizeof(OSSram)); +OSSramEx* __OSLockSramEx(void) { + return (OSSramEx*)LockSram(sizeof(OSSram)); } -/* 803401FC-80340538 33AB3C 033C+00 10/10 0/0 0/0 .text UnlockSram */ -static BOOL UnlockSram(BOOL commit, u32 offset) { +static int UnlockSram(int commit, u32 offset) { u16* p; - if (commit) { + ASSERTLINE(375, Scb.locked); + if (commit != 0) { if (offset == 0) { - OSSram* sram = (OSSram*)Scb.sram; - + OSSram* sram = (OSSram*)Scb.sram; if (2u < (sram->flags & 3)) { sram->flags &= ~3; } sram->checkSum = sram->checkSumInv = 0; - for (p = (u16*)&sram->counterBias; p < (u16*)(Scb.sram + sizeof(OSSram)); p++) { + for(p = (u16*)&sram->counterBias; p < ((u16*)&Scb.sram[0x14]); p++) { sram->checkSum += *p; - sram->checkSumInv += ~*p; + sram->checkSumInv += ~(*p); } } - if (offset < Scb.offset) { Scb.offset = offset; } @@ -130,9 +193,9 @@ static BOOL UnlockSram(BOOL commit, u32 offset) { } } - Scb.sync = WriteSram(Scb.sram + Scb.offset, Scb.offset, RTC_SRAM_SIZE - Scb.offset); - if (Scb.sync) { - Scb.offset = RTC_SRAM_SIZE; + Scb.sync = WriteSram(&Scb.sram[Scb.offset], Scb.offset, SRAM_SIZE - Scb.offset); + if (Scb.sync != 0) { + Scb.offset = SRAM_SIZE; } } Scb.locked = FALSE; @@ -140,96 +203,277 @@ static BOOL UnlockSram(BOOL commit, u32 offset) { return Scb.sync; } -/* 80340538-8034055C 33AE78 0024+00 0/0 3/3 0/0 .text __OSUnlockSram */ -BOOL __OSUnlockSram(BOOL commit) { - return UnlockSram(commit, 0); +int __OSUnlockSram(int commit) { + UnlockSram(commit, 0); } -/* 8034055C-80340580 33AE9C 0024+00 0/0 4/4 0/0 .text __OSUnlockSramEx */ -BOOL __OSUnlockSramEx(BOOL commit) { - return UnlockSram(commit, sizeof(OSSram)); +int __OSUnlockSramEx(int commit) { + UnlockSram(commit, sizeof(OSSram)); } -/* 80340580-80340590 33AEC0 0010+00 0/0 2/2 0/0 .text __OSSyncSram */ -BOOL __OSSyncSram(void) { +int __OSSyncSram(void) { return Scb.sync; } -/* 80340590-80340610 33AED0 0080+00 0/0 4/4 0/0 .text OSGetSoundMode */ -u32 OSGetSoundMode() { +int __OSCheckSram(void) { + u16* p; + u16 checkSum; + u16 checkSumInv; OSSram* sram; - u32 mode; + int unused; - sram = __OSLockSram(); - mode = (sram->flags & 0x4) ? OS_SOUND_MODE_STEREO : OS_SOUND_MODE_MONO; - __OSUnlockSram(FALSE); - return mode; -} + ASSERTLINE(466, Scb.locked); -/* 80340610-803406B4 33AF50 00A4+00 0/0 1/1 0/0 .text OSSetSoundMode */ -void OSSetSoundMode(u32 mode) { - OSSram* sram; - mode <<= 2; - mode &= 4; + checkSum = checkSumInv = 0; - sram = __OSLockSram(); - if (mode == (sram->flags & 4)) { - __OSUnlockSram(FALSE); - return; + sram = (OSSram*)Scb.sram; + + for (p = (void*)&sram->counterBias; p < (u16*)&Scb.sram[0x14]; p++) { + checkSum += *p; + checkSumInv += ~(*p); } - sram->flags &= ~4; - sram->flags |= mode; - __OSUnlockSram(TRUE); + return (sram->checkSum == checkSum && sram->checkSumInv == checkSumInv); } -/* 803406B4-80340724 33AFF4 0070+00 0/0 3/3 0/0 .text OSGetProgressiveMode */ -u32 OSGetProgressiveMode() { - OSSram* sram; - u32 mode; +int __OSReadROM(void * buffer, s32 length, s32 offset) { + int err; + u32 cmd; - sram = __OSLockSram(); - mode = (sram->flags & 0x80) >> 7; - __OSUnlockSram(FALSE); + ASSERTLINE(497, length <= 1024); + DCInvalidateRange(buffer, length); + if (EXILock(0, 1, NULL) == 0) { + return 0; + } + if (EXISelect(0, 1, 3) == 0) { + EXIUnlock(0); + return 0; + } + cmd = offset << 6; + err = 0; + err |= !EXIImm(0, &cmd, 4, 1, 0); + err |= !EXISync(0); + err |= !EXIDma(0, buffer, length, 0, NULL); + err |= !EXISync(0); + err |= !EXIDeselect(0); + EXIUnlock(0); + return !err; +} + +static void __OSReadROMCallback(s32 chan) { + void (*callback)(); + + EXIDeselect(chan); + EXIUnlock(chan); + callback = Scb.callback; + if (callback) { + Scb.callback = NULL; + callback(); + } +} + +int __OSReadROMAsync(void* buffer, s32 length, s32 offset, void (*callback)()) { + int err; + u32 cmd; + + ASSERTLINE(556, length <= 1024); + ASSERTLINE(557, callback); + DCInvalidateRange(buffer, length); + Scb.callback = callback; + if (EXILock(0, 1, NULL) == 0) { + return 0; + } + if (EXISelect(0, 1, 3) == 0) { + EXIUnlock(0); + return 0; + } + cmd = offset << 6; + err = 0; + err |= !EXIImm(0, &cmd, 4, 1, 0); + err |= !EXISync(0); + err |= !EXIDma(0, buffer, length, 0, (void*)__OSReadROMCallback); + return !err; +} + +u32 OSGetSoundMode(void) { + OSSram* sram = __OSLockSram(); + u32 mode = (sram->flags & 4) ? 1 : 0; + + __OSUnlockSram(0); return mode; } -/* 80340724-803407C8 33B064 00A4+00 0/0 2/2 0/0 .text OSSetProgressiveMode */ - -void OSSetProgressiveMode(u32 mode) { +void OSSetSoundMode(u32 mode) { OSSram* sram; - mode <<= 7; - mode &= 0x80; + int unused; + + ASSERTLINE(617, mode == OS_SOUND_MODE_MONO || mode == OS_SOUND_MODE_STEREO); + mode *= 4; + mode &= 4; + sram = __OSLockSram(); + if (mode == (sram->flags & 4)) { + __OSUnlockSram(0); + return; + } + sram->flags &= 0xFFFFFFFB; + sram->flags |= mode; + __OSUnlockSram(1); +} + +u32 OSGetProgressiveMode(void) { + OSSram* sram; + u32 on; sram = __OSLockSram(); - if (mode == (sram->flags & 0x80)) { + on = (sram->flags & 0x80) >> 7; + __OSUnlockSram(FALSE); + return on; +} + +void OSSetProgressiveMode(u32 on) { +#ifndef DEBUG + u32 padding[1]; +#endif + OSSram* sram; + + ASSERTLINE(670, on == OS_PROGRESSIVE_MODE_OFF || on == OS_PROGRESSIVE_MODE_ON); + + on <<= 7; + on &= 0x80; + + sram = __OSLockSram(); + if (on == (sram->flags & 0x80)) { __OSUnlockSram(FALSE); return; } sram->flags &= ~0x80; - sram->flags |= mode; + sram->flags |= on; __OSUnlockSram(TRUE); } -/* 803407C8-8034084C 33B108 0084+00 0/0 1/1 0/0 .text OSGetWirelessID */ -u16 OSGetWirelessID(s32 channel) { +u32 OSGetVideoMode(void) { + OSSram* sram = __OSLockSram(); + u32 mode = sram->flags & 3; + + __OSUnlockSram(0); + + if (mode > 2) { + mode = 0; + } + + return mode; +} + +void OSSetVideoMode(u32 mode) { + OSSram* sram; + int unused; + + ASSERTLINE(731, OS_VIDEO_MODE_NTSC <= mode && mode <= OS_VIDEO_MODE_MPAL); + + if (mode > 2) { + mode = 0; + } + + sram = __OSLockSram(); + + if (mode == (sram->flags & 3)) { + __OSUnlockSram(0); + return; + } + sram->flags &= 0xFFFFFFFC; + sram->flags |= mode; + __OSUnlockSram(1); +} + +u8 OSGetLanguage(void) { + OSSram* sram = __OSLockSram(); + u8 language = sram->language; + + __OSUnlockSram(0); + return language; +} + +void OSSetLanguage(u8 language) { + OSSram* sram = __OSLockSram(); + int unused; + + if (language == sram->language) { + __OSUnlockSram(0); + return; + } + sram->language = language; + __OSUnlockSram(1); +} + +u8 __OSGetBootMode(void) { + OSSram* sram = __OSLockSram(); + u8 ntd = sram->ntd; + __OSUnlockSram(0); + return ntd & 0x80; +} + +void __OSSetBootMode(u8 ntd) { + OSSram* sram; + int unused; + + ntd &= 0x80; + sram = __OSLockSram(); + if (ntd == (sram->ntd & 0x80U)) { + __OSUnlockSram(0); + return; + } + sram->ntd &= 0xFFFFFF7F; + sram->ntd |= ntd; + __OSUnlockSram(1); +} + +u32 OSGetEuRgb60Mode(void) { + OSSram* sram; + u32 on; + + sram = __OSLockSram(); + on = (sram->ntd & 0x40) >> 6; + __OSUnlockSram(0); + return on; +} + +void OSSetEuRgb60Mode(u32 on) { +#ifndef DEBUG + u32 padding[1]; +#endif + OSSram* sram; + + ASSERTLINE(895, on == OS_EURGB60_OFF || on == OS_EURGB60_ON); + on <<= 6; + on &= 0x40; + + sram = __OSLockSram(); + if (on == (sram->ntd & 0x40)) { + __OSUnlockSram(0); + } else { + sram->ntd &= ~0x40; + sram->ntd |= on; + __OSUnlockSram(1); + } +} + +u16 OSGetWirelessID(s32 chan) { OSSramEx* sram; u16 id; sram = __OSLockSramEx(); - id = sram->wirelessPadID[channel]; + id = sram->wirelessPadID[chan]; __OSUnlockSramEx(FALSE); return id; } -/* 8034084C-803408F8 33B18C 00AC+00 0/0 4/4 0/0 .text OSSetWirelessID */ -void OSSetWirelessID(s32 channel, u16 id) { +void OSSetWirelessID(s32 chan, u16 id) { OSSramEx* sram; sram = __OSLockSramEx(); - if (sram->wirelessPadID[channel] != id) { - sram->wirelessPadID[channel] = id; + if (sram->wirelessPadID[chan] != id) { + sram->wirelessPadID[chan] = id; __OSUnlockSramEx(TRUE); return; } @@ -237,19 +481,20 @@ void OSSetWirelessID(s32 channel, u16 id) { __OSUnlockSramEx(FALSE); } -/* 803408F8-80340968 33B238 0070+00 1/1 0/0 0/0 .text OSGetGbsMode */ -u16 OSGetGbsMode() { +u16 OSGetGbsMode(void) { OSSramEx* sram; - u16 gbs; + u16 mode; sram = __OSLockSramEx(); - gbs = sram->gbs; + mode = sram->gbs; __OSUnlockSramEx(FALSE); - return gbs; + return mode; } -/* 80340968-80340A20 33B2A8 00B8+00 1/1 0/0 0/0 .text OSSetGbsMode */ void OSSetGbsMode(u16 mode) { +#ifndef DEBUG + u32 padding[1]; +#endif OSSramEx* sram; if (((u32)mode & 0x7c00) == 0x5000 || ((u32)mode & 0xc0) == 0xc0) { @@ -265,4 +510,4 @@ void OSSetGbsMode(u16 mode) { sram->gbs = mode; __OSUnlockSramEx(TRUE); -} \ No newline at end of file +} diff --git a/src/dolphin/os/OSSemaphore.c b/src/dolphin/os/OSSemaphore.c new file mode 100644 index 0000000000..c58e20dd51 --- /dev/null +++ b/src/dolphin/os/OSSemaphore.c @@ -0,0 +1,56 @@ +#include +#include + +void OSInitSemaphore(OSSemaphore* sem, s32 count) { + BOOL enabled = OSDisableInterrupts(); + + OSInitThreadQueue(&sem->queue); + sem->count = count; + OSRestoreInterrupts(enabled); +} + +s32 OSWaitSemaphore(OSSemaphore* sem) { + BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + + while((sem->count = (count = sem->count)) <= 0) { + OSSleepThread(&sem->queue); + } + + sem->count--; + OSRestoreInterrupts(enabled); + return count; +} + +s32 OSTryWaitSemaphore(OSSemaphore* sem) { + BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + count = sem->count; + if (sem->count > 0) { + sem->count = sem->count - 1; + } + + OSRestoreInterrupts(enabled); + return count; +} + +s32 OSSignalSemaphore(OSSemaphore* sem) { + BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + count = sem->count; + sem->count++; + + OSWakeupThread(&sem->queue); + OSRestoreInterrupts(enabled); + return count; +} + +s32 OSGetSemaphoreCount(OSSemaphore* sem) { + return sem->count; +} diff --git a/src/dolphin/os/OSStopwatch.c b/src/dolphin/os/OSStopwatch.c new file mode 100644 index 0000000000..c53c1689e5 --- /dev/null +++ b/src/dolphin/os/OSStopwatch.c @@ -0,0 +1,55 @@ +#include +#include + +void OSInitStopwatch(OSStopwatch* sw, char* name) { + sw->name = name; + sw->total = 0; + sw->hits = 0; + sw->min = 0x00000000FFFFFFFF; + sw->max = 0; +} + +void OSStartStopwatch(OSStopwatch* sw) { + sw->running = TRUE; + sw->last = OSGetTime(); +} + +void OSStopStopwatch(OSStopwatch* sw) { + OSTime interval; + + if (sw->running) { + interval = OSGetTime() - sw->last; + sw->total += interval; + sw->running = FALSE; + sw->hits++; + if (sw->max < interval) { + sw->max = interval; + } + if (interval < sw->min) { + sw->min = interval; + } + } +} + +OSTime OSCheckStopwatch(OSStopwatch* sw) { + OSTime currTotal; + + currTotal = sw->total; + if (sw->running) { + currTotal += OSGetTime() - sw->last; + } + return currTotal; +} + +void OSResetStopwatch(OSStopwatch* sw) { + OSInitStopwatch(sw, sw->name); +} + +void OSDumpStopwatch(OSStopwatch* sw) { + OSReport("Stopwatch [%s] :\n", sw->name); + OSReport("\tTotal= %lld us\n", OSTicksToMicroseconds(sw->total)); + OSReport("\tHits = %d \n", sw->hits); + OSReport("\tMin = %lld us\n", OSTicksToMicroseconds(sw->min)); + OSReport("\tMax = %lld us\n", OSTicksToMicroseconds(sw->max)); + OSReport("\tMean = %lld us\n", OSTicksToMicroseconds(sw->total/sw->hits)); +} diff --git a/src/dolphin/os/OSSync.c b/src/dolphin/os/OSSync.c index 2bbf4301e0..0f91a19fce 100644 --- a/src/dolphin/os/OSSync.c +++ b/src/dolphin/os/OSSync.c @@ -1,34 +1,33 @@ -#include "dolphin/os/OSSync.h" -#include "dolphin/os.h" +#include +#include -void __OSSystemCallVectorStart(); -void __OSSystemCallVectorEnd(); +#include "__os.h" -/* 80340A20-80340A3C 33B360 001C+00 1/1 0/0 0/0 .text SystemCallVector */ +// prototypes +void __OSSystemCallVectorStart(void); +void __OSSystemCallVectorEnd(void); + +#ifdef __GEKKO__ static asm void SystemCallVector(void) { - // clang-format off - nofralloc - entry __OSSystemCallVectorStart + nofralloc mfspr r9, HID0 - ori r10, r9, 8 + ori r10, r9, 0x8 mtspr HID0, r10 isync sync mtspr HID0, r9 rfi - entry __OSSystemCallVectorEnd nop - // clang-format on } +#endif -/* 80340A40-80340AA4 33B380 0064+00 0/0 1/1 0/0 .text __OSInitSystemCall */ void __OSInitSystemCall(void) { - void* addr = OSPhysicalToCached(0x00C00); - memcpy(addr, __OSSystemCallVectorStart, - (size_t)__OSSystemCallVectorEnd - (size_t)__OSSystemCallVectorStart); + void* addr = (void*)OSPhysicalToCached(0xC00); + + memcpy(addr, __OSSystemCallVectorStart, (u32)&__OSSystemCallVectorEnd - (u32)&__OSSystemCallVectorStart); DCFlushRangeNoSync(addr, 0x100); __sync(); ICInvalidateRange(addr, 0x100); -} \ No newline at end of file +} diff --git a/src/dolphin/os/OSThread.c b/src/dolphin/os/OSThread.c index 730ea7485e..dcf25a36d1 100644 --- a/src/dolphin/os/OSThread.c +++ b/src/dolphin/os/OSThread.c @@ -1,110 +1,112 @@ -// -// Generated By: dol2asm -// Translation Unit: OSThread -// +#include +#include -#include "dolphin/os/OSThread.h" -#include "dolphin/os.h" +#include "__os.h" -OSThread* __OSCurrentThread : OS_BASE_CACHED + 0x00E4; -OSThreadQueue __OSActiveThreadQueue : OS_BASE_CACHED + 0x00DC; -volatile OSContext __OSCurrentContext : OS_BASE_CACHED + 0x00D4; -volatile OSContext* __OSFPUContext : OS_BASE_CACHED + 0x00D8; +#define ENQUEUE_THREAD(thread, queue, link) \ + do { \ + OSThread* __prev = (queue)->tail; \ + if (__prev == NULL) { \ + (queue)->head = (thread); \ + } else { \ + __prev->link.next = (thread); \ + } \ + (thread)->link.prev = __prev; \ + (thread)->link.next = 0; \ + (queue)->tail = (thread); \ + } while(0); -#define AddTail(queue, thread, link) \ - do { \ - OSThread* prev; \ - \ - prev = (queue)->tail; \ - if (prev == NULL) \ - (queue)->head = (thread); \ - else \ - prev->link.next = (thread); \ - (thread)->link.prev = prev; \ - (thread)->link.next = NULL; \ - (queue)->tail = (thread); \ - } while (0) +#define DEQUEUE_THREAD(thread, queue, link) \ + do { \ + OSThread* __next = (thread)->link.next; \ + OSThread* __prev = (thread)->link.prev; \ + if (__next == NULL) { \ + (queue)->tail = __prev; \ + } else { \ + __next->link.prev = __prev; \ + } \ + if (__prev == NULL) { \ + (queue)->head = __next; \ + } else { \ + __prev->link.next = __next; \ + } \ + } while(0); -#define AddPrio(queue, thread, link) \ - do { \ - OSThread *prev, *next; \ - \ - for (next = (queue)->head; next && next->effective_priority <= thread->effective_priority; \ - next = next->link.next) \ - ; \ - if (next == NULL) \ - AddTail(queue, thread, link); \ - else { \ - (thread)->link.next = next; \ - prev = next->link.prev; \ - next->link.prev = (thread); \ - (thread)->link.prev = prev; \ - if (prev == NULL) \ - (queue)->head = (thread); \ - else \ - prev->link.next = (thread); \ - } \ - } while (0) +#define ENQUEUE_THREAD_PRIO(thread, queue, link) \ + do { \ + OSThread* __prev; \ + OSThread* __next; \ + for(__next = (queue)->head; __next \ + && (__next->priority <= (thread)->priority); \ + __next = __next->link.next) ; \ + \ + if (__next == NULL) { \ + ENQUEUE_THREAD(thread, queue, link); \ + } else { \ + (thread)->link.next = __next; \ + __prev = __next->link.prev; \ + __next->link.prev = (thread); \ + (thread)->link.prev = __prev; \ + if (__prev == NULL) { \ + (queue)->head = (thread); \ + } else { \ + __prev->link.next = (thread); \ + } \ + } \ + } while(0); -#define RemoveItem(queue, thread, link) \ - do { \ - OSThread *next, *prev; \ - next = (thread)->link.next; \ - prev = (thread)->link.prev; \ - if (next == NULL) \ - (queue)->tail = prev; \ - else \ - next->link.prev = prev; \ - if (prev == NULL) \ - (queue)->head = next; \ - else \ - prev->link.next = next; \ - } while (0) +#define DEQUEUE_HEAD(thread, queue, link) \ + do { \ + OSThread* __next = thread->link.next; \ + if (__next == NULL) { \ + (queue)->tail = 0; \ + } else { \ + __next->link.prev = 0; \ + } \ + (queue)->head = __next; \ + } while(0); -#define RemoveHead(queue, thread, link) \ - do { \ - OSThread* __next; \ - (thread) = (queue)->head; \ - __next = (thread)->link.next; \ - if (__next == NULL) \ - (queue)->tail = NULL; \ - else \ - __next->link.prev = NULL; \ - (queue)->head = __next; \ - } while (0) +// defined in linkscript +extern u8 _stack_end[]; +extern u8 _stack_addr[]; -// -// External References: -// +static OSThreadQueue RunQueue[32]; +static OSThread IdleThread; +static OSThread DefaultThread; +static OSContext IdleContext; +static volatile u32 RunQueueBits; +static volatile int RunQueueHint; +static s32 Reschedule; -extern OSErrorHandlerEx __OSErrorTable[17]; -extern u32 __OSFpscrEnableBits; -void _epilog(); +#define ALIGN4(val) (((val) + 0x3) & ~0x3) +#define ALIGN8(val) (((val) + 0x7) & ~0x7) -// -// Declarations: -// +// prototypes +static void OSInitMutexQueue(OSMutexQueue* queue); +static void __OSSwitchThread(OSThread* nextThread); +static int __OSIsThreadActive(OSThread* thread); +static void SetRun(OSThread* thread); +static void UnsetRun(OSThread* thread); +static OSThread* SetEffectivePriority(OSThread* thread, s32 priority); +static void UpdatePriority(OSThread* thread); +static OSThread* SelectThread(int yield); +static int CheckThreadQueue(OSThreadQueue* queue); +static int IsMember(OSThreadQueue* queue, OSThread* thread); +static void OSSetCurrentThread(OSThread* thread); -/* 80340AA4-80340AA8 33B3E4 0004+00 2/1 0/0 0/0 .text DefaultSwitchThreadCallback */ static void DefaultSwitchThreadCallback(OSThread* from, OSThread* to) {} - -/* ############################################################################################## */ -/* 804509B8-804509BC -00001 0004+00 3/3 0/0 0/0 .sdata SwitchThreadCallback */ static OSSwitchThreadCallback SwitchThreadCallback = DefaultSwitchThreadCallback; -/* 80340AA8-80340B1C 33B3E8 0074+00 0/0 1/1 0/0 .text OSSetSwitchThreadCallback */ -OSSwitchThreadCallback OSSetSwitchThreadCallback(OSSwitchThreadCallback func) { - BOOL enable = OSDisableInterrupts(); - OSSwitchThreadCallback prev = SwitchThreadCallback; - OSSwitchThreadCallback temp; - if (func) { - temp = func; - } else { - temp = DefaultSwitchThreadCallback; - } - SwitchThreadCallback = temp; +OSSwitchThreadCallback OSSetSwitchThreadCallback(OSSwitchThreadCallback callback) { + OSSwitchThreadCallback prev; + BOOL enabled; + + enabled = OSDisableInterrupts(); + prev = SwitchThreadCallback; + + SwitchThreadCallback = callback ? callback : DefaultSwitchThreadCallback; + OSRestoreInterrupts(enabled); - OSRestoreInterrupts(enable); if (prev == DefaultSwitchThreadCallback) { return NULL; } @@ -112,267 +114,254 @@ OSSwitchThreadCallback OSSetSwitchThreadCallback(OSSwitchThreadCallback func) { return prev; } -/* ############################################################################################## */ -/* 8044BB78-8044BC78 078898 0100+00 6/6 0/0 0/0 .bss RunQueue */ -static OSThreadQueue RunQueue[32]; - -/* 8044BC78-8044BF90 078998 0318+00 0/0 0/0 0/0 .bss IdleThread */ -#pragma push -#pragma force_active on -static OSThread IdleThread; -#pragma pop - -/* 8044BF90-8044C2A8 078CB0 0318+00 0/1 0/0 0/0 .bss DefaultThread */ -#pragma push -#pragma force_active on -static OSThread DefaultThread; -#pragma pop - -/* 8044C2A8-8044C570 078FC8 02C8+00 0/2 0/0 0/0 .bss IdleContext */ -#pragma push -#pragma force_active on -static OSContext IdleContext; -#pragma pop - -/* 804516C0-804516C4 000BC0 0004+00 7/7 0/0 0/0 .sbss RunQueueBits */ -static vu32 RunQueueBits; - -/* 804516C4-804516C8 000BC4 0004+00 11/11 0/0 0/0 .sbss RunQueueHint */ -static volatile BOOL RunQueueHint; - -/* 804516C8-804516D0 000BC8 0004+04 4/4 0/0 0/0 .sbss Reschedule */ -static volatile s32 Reschedule; - -extern u8 _stack_end[]; -extern u8 _stack_addr[]; - -static inline void OSInitMutexQueue(OSMutexQueue* queue) { - queue->head = queue->tail = NULL; -} - static inline void OSSetCurrentThread(OSThread* thread) { SwitchThreadCallback(__OSCurrentThread, thread); __OSCurrentThread = thread; } -/* 80340B1C-80340C74 33B45C 0158+00 0/0 1/1 0/0 .text __OSThreadInit */ void __OSThreadInit() { OSThread* thread = &DefaultThread; - int prio; + OSPriority prio; thread->state = OS_THREAD_STATE_RUNNING; - thread->attributes = OS_THREAD_ATTR_DETACH; - thread->effective_priority = thread->base_priority = 16; - thread->suspend_count = 0; - thread->exit_value = (void*)-1; - thread->mutex = NULL; - OSInitThreadQueue(&thread->join_queue); - OSInitMutexQueue(&thread->owned_mutexes); + thread->attr = 1; + thread->priority = thread->base = 0x10; + thread->suspend = 0; + thread->val = (void*)-1; // wut + thread->mutex = 0; - __OSFPUContext = &thread->context; + OSInitThreadQueue(&thread->queueJoin); +#ifdef DEBUG + OSInitMutexQueue(&thread->queueMutex); +#else + thread->queueMutex.head = thread->queueMutex.tail = 0; // it got inlined? cant reproduce the inline... +#endif + ASSERTLINE(LINE(348, 357, 357), PPCMfmsr() & MSR_FP); + + __gUnkThread1 = thread; OSClearContext(&thread->context); OSSetCurrentContext(&thread->context); - thread->stack_base = (void*)_stack_addr; - thread->stack_end = (void*)_stack_end; - *(thread->stack_end) = OS_THREAD_STACK_MAGIC; - + thread->stackBase = (u8*)&_stack_addr; + thread->stackEnd = (u32*)&_stack_end; + *(u32*)thread->stackEnd = OS_THREAD_STACK_MAGIC; OSSetCurrentThread(thread); OSClearStack(0); - RunQueueBits = 0; - RunQueueHint = FALSE; - for (prio = OS_PRIORITY_MIN; prio <= OS_PRIORITY_MAX; ++prio) { + RunQueueHint = 0; + + for (prio = 0; prio <= 31; prio++) { OSInitThreadQueue(&RunQueue[prio]); } - OSInitThreadQueue(&__OSActiveThreadQueue); - AddTail(&__OSActiveThreadQueue, thread, active_threads_link); + + ENQUEUE_THREAD(thread, &__OSActiveThreadQueue, linkActive); + OSClearContext(&IdleContext); Reschedule = 0; } -/* 80340C74-80340C84 33B5B4 0010+00 1/1 9/9 0/0 .text OSInitThreadQueue */ +#if DEBUG +static void OSInitMutexQueue(OSMutexQueue* queue) { + queue->head = queue->tail = 0; +} +#endif + void OSInitThreadQueue(OSThreadQueue* queue) { - queue->tail = NULL; - queue->head = NULL; + queue->head = queue->tail = 0; } -/* 80340C84-80340C90 33B5C4 000C+00 0/0 20/20 0/0 .text OSGetCurrentThread */ -OSThread* OSGetCurrentThread(void) { - return OS_CURRENT_THREAD; +OSThread* OSGetCurrentThread() { + return __OSCurrentThread; } -/* 80340C90-80340CC4 33B5D0 0034+00 0/0 1/1 0/0 .text OSIsThreadTerminated */ -BOOL OSIsThreadTerminated(OSThread* thread) { - return thread->state == OS_THREAD_STATE_DEAD || thread->state == OS_THREAD_STATE_UNINITIALIZED ? - TRUE : - FALSE; -} - -/* 80340CC4-80340D04 33B604 0040+00 0/0 8/8 0/0 .text OSDisableScheduler */ -s32 OSDisableScheduler(void) { - BOOL intr = OSDisableInterrupts(); - s32 ret = Reschedule++; - OSRestoreInterrupts(intr); - return ret; -} - -/* 80340D04-80340D44 33B644 0040+00 0/0 10/10 0/0 .text OSEnableScheduler */ -s32 OSEnableScheduler(void) { - BOOL intr = OSDisableInterrupts(); - s32 ret = Reschedule--; - OSRestoreInterrupts(intr); - return ret; -} - -static inline void SetRun(OSThread* thread) { - thread->queue = &RunQueue[thread->effective_priority]; - AddTail(thread->queue, thread, link); - RunQueueBits |= 1u << (OS_PRIORITY_MAX - thread->effective_priority); - RunQueueHint = TRUE; -} - -/* 80340D44-80340DAC 33B684 0068+00 3/3 0/0 0/0 .text UnsetRun */ -#pragma dont_inline on -static void UnsetRun(OSThread* thread) { - OSThreadQueue* queue; - OSThread* next; - OSThread* prev; - - prev = thread->link.next; - queue = thread->queue; - next = thread->link.prev; - - if (prev == NULL) { - queue->tail = next; - } else { - prev->link.prev = next; - } - - if (next == NULL) { - queue->head = prev; - } else { - next->link.next = prev; - } - - if (queue->head == NULL) { - RunQueueBits &= ~(1 << 31 - thread->effective_priority); - } - - thread->queue = NULL; -} -#pragma dont_inline reset - -/* 80340DAC-80340DE8 33B6EC 003C+00 4/4 2/2 0/0 .text __OSGetEffectivePriority */ -s32 __OSGetEffectivePriority(OSThread* thread) { - s32 prio = thread->base_priority; - - OSMutex* mutex; - for (mutex = thread->owned_mutexes.head; mutex != NULL; mutex = mutex->link.next) { - OSThread* mutexThread = mutex->queue.head; - if (mutexThread != NULL && mutexThread->effective_priority < prio) { - prio = mutexThread->effective_priority; - } - } - - return prio; -} - -/* 80340DE8-80340FA8 33B728 01C0+00 5/5 0/0 0/0 .text SetEffectivePriority */ -static OSThread* SetEffectivePriority(OSThread* thread, s32 priority) { - switch (thread->state) { - case OS_THREAD_STATE_READY: - UnsetRun(thread); - thread->effective_priority = priority; - SetRun(thread); - break; - case OS_THREAD_STATE_WAITING: - RemoveItem(thread->queue, thread, link); - thread->effective_priority = priority; - AddPrio(thread->queue, thread, link); - if (thread->mutex) { - return thread->mutex->thread; - } - break; - case OS_THREAD_STATE_RUNNING: - RunQueueHint = TRUE; - thread->effective_priority = priority; - break; - } - return NULL; -} - -static void UpdatePriority(OSThread* thread) { - OSPriority priority; - - do { - if (0 < thread->suspend_count) { - break; - } - priority = __OSGetEffectivePriority(thread); - if (thread->effective_priority == priority) { - break; - } - thread = SetEffectivePriority(thread, priority); - } while (thread); -} - -/* 80340FA8-80340FF8 33B8E8 0050+00 0/0 1/1 0/0 .text __OSPromoteThread */ -void __OSPromoteThread(OSThread* thread, s32 priority) { - do { - if (thread->suspend_count > 0 || thread->effective_priority <= priority) { - break; - } - - thread = SetEffectivePriority(thread, priority); - } while (thread != NULL); -} - -static inline void __OSSwitchThread(OSThread* nextThread) { +static void __OSSwitchThread(OSThread* nextThread) { OSSetCurrentThread(nextThread); OSSetCurrentContext(&nextThread->context); OSLoadContext(&nextThread->context); } -/* 80340FF8-80341220 33B938 0228+00 9/9 0/0 0/0 .text SelectThread */ -inline OSThread* i_OSGetCurrentThread(void) { - return OS_CURRENT_THREAD; +BOOL OSIsThreadSuspended(OSThread* thread) { + if (thread->suspend > 0) { + return TRUE; + } + return FALSE; } -static OSThread* SelectThread(BOOL yield) { +BOOL OSIsThreadTerminated(OSThread* thread) { + return (thread->state == OS_THREAD_STATE_MORIBUND || thread->state == 0) ? TRUE : FALSE; +} + +static BOOL __OSIsThreadActive(OSThread* thread) { + OSThread* active; + + if (thread->state == 0) { + return FALSE; + } + + for (active = __OSActiveThreadQueue.head; active; active = active->linkActive.next) { + if (thread == active) { + return TRUE; + } + } + return FALSE; +} + +s32 OSDisableScheduler(void) { + register BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + count = Reschedule; + Reschedule = count + 1; + OSRestoreInterrupts(enabled); + return count; +} + +s32 OSEnableScheduler(void) { + register BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + count = Reschedule; + Reschedule = count - 1; + OSRestoreInterrupts(enabled); + return count; +} + +static void SetRun(OSThread* thread) { + ASSERTLINE(LINE(536, 554, 554), !IsSuspended(thread->suspend)); + ASSERTLINE(LINE(537, 555, 555), thread->state == OS_THREAD_STATE_READY); + + ASSERTLINE(LINE(539, 557, 557), OS_PRIORITY_MIN <= thread->priority && thread->priority <= OS_PRIORITY_MAX); + + thread->queue = &RunQueue[thread->priority]; + + ENQUEUE_THREAD(thread, thread->queue, link); + + RunQueueBits |= 1 << (OS_PRIORITY_MAX - thread->priority); + RunQueueHint = 1; +} + +static void UnsetRun(OSThread* thread) { + OSThreadQueue* queue; + + ASSERTLINE(LINE(560, 578, 578), thread->state == OS_THREAD_STATE_READY); + + ASSERTLINE(LINE(562, 580, 580), OS_PRIORITY_MIN <= thread->priority && thread->priority <= OS_PRIORITY_MAX); + ASSERTLINE(LINE(563, 581, 581), thread->queue == &RunQueue[thread->priority]); + + queue = thread->queue; + + DEQUEUE_THREAD(thread, queue, link); + + if (!queue->head) { + RunQueueBits &= ~(1 << (OS_PRIORITY_MAX - thread->priority)); + } + thread->queue = NULL; +} + +s32 __OSGetEffectivePriority(OSThread* thread) { + s32 priority = thread->base; + OSMutex* mutex; + + for (mutex = thread->queueMutex.head; mutex; mutex = mutex->link.next) { + OSThread* blocked = mutex->queue.head; + if (blocked && blocked->priority < priority) { + priority = blocked->priority; + } + } + return priority; +} + +static OSThread* SetEffectivePriority(OSThread* thread, s32 priority) { + ASSERTLINE(LINE(614, 632, 632), !IsSuspended(thread->suspend)); + + switch(thread->state) { + case OS_THREAD_STATE_READY: + UnsetRun(thread); + thread->priority = priority; + SetRun(thread); + break; + case OS_THREAD_STATE_WAITING: + DEQUEUE_THREAD(thread, thread->queue, link); + thread->priority = priority; + + ENQUEUE_THREAD_PRIO(thread, thread->queue, link); + + if (thread->mutex) { + ASSERTLINE(LINE(629, 647, 647), thread->mutex->thread); + return thread->mutex->thread; + } + break; + case OS_THREAD_STATE_RUNNING: + RunQueueHint = 1; + thread->priority = priority; + break; + } + return 0; +} + +static void UpdatePriority(OSThread* thread) { + s32 priority; + + while (1) { + if(thread->suspend > 0) { + break; + } + priority = __OSGetEffectivePriority(thread); + if (thread->priority == priority) { + break; + } + thread = SetEffectivePriority(thread, priority); + if (thread == 0) { + break; + } + } +} + +void __OSPromoteThread(OSThread* thread, s32 priority) { + while (1) { + if (thread->suspend > 0 || thread->priority <= priority) { + break; + } + thread = SetEffectivePriority(thread, priority); + if (thread == 0) { + break; + } + } +} + +static OSThread* SelectThread(int yield) { OSContext* currentContext; OSThread* currentThread; OSThread* nextThread; OSPriority priority; OSThreadQueue* queue; - if (0 < Reschedule) { - return 0; + if (Reschedule > 0) { + return NULL; } currentContext = OSGetCurrentContext(); - currentThread = i_OSGetCurrentThread(); + currentThread = OSGetCurrentThread(); + if (currentContext != ¤tThread->context) { - return 0; + return NULL; } if (currentThread) { - if (currentThread->state == OS_THREAD_STATE_RUNNING) { - if (!yield) { + if (currentThread->state == 2) { + if (yield == 0) { priority = __cntlzw(RunQueueBits); - if (currentThread->effective_priority <= priority) { - return 0; - } + if (currentThread->priority <= priority) + return NULL; } currentThread->state = OS_THREAD_STATE_READY; SetRun(currentThread); } - - if (!(currentThread->context.state & OS_CONTEXT_STATE_EXC) && - OSSaveContext(¤tThread->context)) - { - return 0; + if (!(currentThread->context.state & 2) && (OSSaveContext(¤tThread->context) != 0)) { + return NULL; } } @@ -381,146 +370,158 @@ static OSThread* SelectThread(BOOL yield) { OSSetCurrentContext(&IdleContext); do { OSEnableInterrupts(); - while (RunQueueBits == 0) - ; + while (RunQueueBits == 0) ; OSDisableInterrupts(); } while (RunQueueBits == 0); - OSClearContext(&IdleContext); } - RunQueueHint = FALSE; - + RunQueueHint = 0; priority = __cntlzw(RunQueueBits); + + ASSERTLINE(LINE(777, 808, 808), OS_PRIORITY_MIN <= priority && priority <= OS_PRIORITY_MAX); + queue = &RunQueue[priority]; - RemoveHead(queue, nextThread, link); - if (queue->head == 0) { - RunQueueBits &= ~(1u << (OS_PRIORITY_MAX - priority)); + nextThread = queue->head; + + DEQUEUE_HEAD(nextThread, queue, link); + + ASSERTLINE(LINE(780, 811, 811), nextThread->priority == priority); + + if (!queue->head) { + RunQueueBits &= ~(1 << (OS_PRIORITY_MAX - priority)); } - nextThread->queue = NULL; + nextThread->queue = 0; nextThread->state = OS_THREAD_STATE_RUNNING; __OSSwitchThread(nextThread); return nextThread; } -/* 80341220-80341250 33BB60 0030+00 0/0 3/3 0/0 .text __OSReschedule */ void __OSReschedule(void) { - if (!RunQueueHint) { - return; + if (RunQueueHint != 0) { + SelectThread(0); } - - SelectThread(FALSE); } -/* 80341250-8034128C 33BB90 003C+00 0/0 2/2 0/0 .text OSYieldThread */ void OSYieldThread(void) { - BOOL enabled; + BOOL enabled = OSDisableInterrupts(); - enabled = OSDisableInterrupts(); - SelectThread(TRUE); + SelectThread(1); OSRestoreInterrupts(enabled); } -/* 8034128C-80341474 33BBCC 01E8+00 0/0 5/5 3/3 .text OSCreateThread */ -BOOL OSCreateThread(OSThread* thread_, void* func, void* param, void* stackBase, u32 stackSize, - s32 priority, u16 attribute) { +int OSCreateThread(OSThread* thread, void* (*func)(void*), void* param, void* stack, u32 stackSize, OSPriority priority, u16 attr) { BOOL enabled; - u32 i; - u32* stack; - OSThread* thread; - u32 stack1, stack2; + u32 sp; + int i; - if (priority < 0 || priority > 31) { - return FALSE; + ASSERTMSGLINE(LINE(864, 895, 895), ((priority >= OS_PRIORITY_MIN) && (priority <= OS_PRIORITY_MAX)), "OSCreateThread(): priority out of range (0 <= priority <= 31)."); + + // why check this for an assert just to check it again right after? + if ((priority < OS_PRIORITY_MIN) || (priority > OS_PRIORITY_MAX)) { + return 0; } - thread = thread_; - thread->state = OS_THREAD_STATE_READY; - thread->attributes = attribute & 1; - thread->base_priority = priority; - thread->effective_priority = priority; - thread->suspend_count = 1; - thread->exit_value = (void*)-1; - thread->mutex = NULL; - thread->join_queue.tail = NULL; - thread->join_queue.head = NULL; - thread->owned_mutexes.tail = NULL; - thread->owned_mutexes.head = NULL; - stack = (u32*)((u32)stackBase & 0xfffffff8); - stack[-2] = 0; - stack[-1] = 0; - OSInitContext(&thread->context, (u32)func, (u32)stack - 8); - thread->context.lr = (u32)OSExitThread; + thread->attr = attr & 1U; + thread->base = priority; + thread->priority = priority; + thread->suspend = 1; + thread->val = (void*)-1; + thread->mutex = 0; + OSInitThreadQueue(&thread->queueJoin); +#ifdef DEBUG + OSInitMutexQueue(&thread->queueMutex); +#else + OSInitThreadQueue((void*)&thread->queueMutex); // why +#endif + sp = (u32)stack; + sp &= ~7; + sp -= 8; + ((u32*)sp)[0] = 0; + ((u32*)sp)[1] = 0; + OSInitContext(&thread->context, (u32)func, sp); + thread->context.lr = (u32)&OSExitThread; thread->context.gpr[3] = (u32)param; - thread->stack_base = (u8*)stackBase; - thread->stack_end = (void*)((u32)stackBase - stackSize); - *(u32*)thread->stack_end = OS_THREAD_STACK_MAGIC; - thread->error_code = NULL; - thread->data[0] = NULL; - thread->data[1] = NULL; + thread->stackBase = stack; + thread->stackEnd = (void*)((unsigned int)stack - stackSize); + *thread->stackEnd = OS_THREAD_STACK_MAGIC; + thread->error = 0; + for (i = 0; i < 2; i++) { + thread->specific[i] = NULL; + } enabled = OSDisableInterrupts(); - if (__OSErrorTable[16]) { + + if (__OSErrorTable[16] != NULL) { thread->context.srr1 |= 0x900; thread->context.state |= 1; thread->context.fpscr = (__OSFpscrEnableBits & 0xf8) | 4; for (i = 0; i < 32; ++i) { *(u64*)&thread->context.fpr[i] = (u64)0xffffffffffffffffLL; - *(u64*)&thread->context.ps[i] = (u64)0xffffffffffffffffLL; + *(u64*)&thread->context.psf[i] = (u64)0xffffffffffffffffLL; } } - AddTail(&OS_THREAD_QUEUE, thread, active_threads_link); + ASSERTMSG1LINE(LINE(918, 949, 949), __OSIsThreadActive(thread) == 0L, "OSCreateThread(): thread %p is still active.", thread); + + ENQUEUE_THREAD(thread, &__OSActiveThreadQueue, linkActive); + OSRestoreInterrupts(enabled); - return TRUE; + return 1; } -/* 80341474-80341558 33BDB4 00E4+00 1/1 1/1 0/0 .text OSExitThread */ -void OSExitThread(void* exitValue) { - OSThread* currentThread; - BOOL enabled; - enabled = OSDisableInterrupts(); - currentThread = OS_CURRENT_THREAD; +void OSExitThread(void* val) { + BOOL enabled = OSDisableInterrupts(); + OSThread* currentThread = OSGetCurrentThread(); + + ASSERTMSGLINE(LINE(943, 974, 974), currentThread, + "OSExitThread(): current thread does not exist."); + ASSERTMSGLINE(LINE(945, 976, 976), currentThread->state == OS_THREAD_STATE_RUNNING, + "OSExitThread(): current thread is not running."); + ASSERTMSGLINE(LINE(947, 978, 978), __OSIsThreadActive(currentThread) != 0, + "OSExitThread(): current thread is not active."); + OSClearContext(¤tThread->context); - - if (currentThread->attributes & OS_THREAD_ATTR_DETACH) { - RemoveItem(&OS_THREAD_QUEUE, currentThread, active_threads_link); - currentThread->state = OS_THREAD_STATE_UNINITIALIZED; + if (currentThread->attr & 1) { + DEQUEUE_THREAD(currentThread, &__OSActiveThreadQueue, linkActive); + currentThread->state = 0; } else { - currentThread->state = OS_THREAD_STATE_DEAD; - currentThread->exit_value = exitValue; + currentThread->state = 8; + currentThread->val = val; } - __OSUnlockAllMutex(currentThread); - OSWakeupThread(¤tThread->join_queue); - RunQueueHint = TRUE; - - if (RunQueueHint) { - SelectThread(FALSE); + OSWakeupThread(¤tThread->queueJoin); + RunQueueHint = 1; +#ifdef DEBUG + __OSReschedule(); +#else + if (RunQueueHint != 0) { + SelectThread(0); } - +#endif OSRestoreInterrupts(enabled); } -/* 80341558-80341714 33BE98 01BC+00 0/0 4/4 3/3 .text OSCancelThread */ void OSCancelThread(OSThread* thread) { - BOOL enabled; + BOOL enabled = OSDisableInterrupts(); - enabled = OSDisableInterrupts(); + ASSERTMSG1LINE(LINE(985, 1016, 1016), __OSIsThreadActive(thread) != 0, + "OSExitThread(): thread %p is not active.", thread); - switch (thread->state) { + switch(thread->state) { case OS_THREAD_STATE_READY: - if (!(0 < thread->suspend_count)) { + if (thread->suspend <= 0) { UnsetRun(thread); } break; case OS_THREAD_STATE_RUNNING: - RunQueueHint = TRUE; + RunQueueHint = 1; break; case OS_THREAD_STATE_WAITING: - RemoveItem(thread->queue, thread, link); - thread->queue = NULL; - if (!(0 < thread->suspend_count) && thread->mutex) { + DEQUEUE_THREAD(thread, thread->queue, link); + thread->queue = 0; + if ((thread->suspend <= 0) && (thread->mutex)) { + ASSERTLINE(LINE(1004, 1035, 1035), thread->mutex->thread); UpdatePriority(thread->mutex->thread); } break; @@ -528,62 +529,82 @@ void OSCancelThread(OSThread* thread) { OSRestoreInterrupts(enabled); return; } - OSClearContext(&thread->context); - if (thread->attributes & OS_THREAD_ATTR_DETACH) { - RemoveItem(&__OSActiveThreadQueue, thread, active_threads_link); + if (thread->attr & 1) { + DEQUEUE_THREAD(thread, &__OSActiveThreadQueue, linkActive); thread->state = 0; } else { - thread->state = OS_THREAD_STATE_DEAD; + thread->state = 8; } - __OSUnlockAllMutex(thread); - - OSWakeupThread(&thread->join_queue); - + OSWakeupThread(&thread->queueJoin); __OSReschedule(); OSRestoreInterrupts(enabled); } -/* 80341714-803417B4 33C054 00A0+00 0/0 2/2 0/0 .text OSDetachThread */ -void OSDetachThread(OSThread* thread) { - BOOL enabled; +int OSJoinThread(OSThread* thread, void* val) { + BOOL enabled = OSDisableInterrupts(); - enabled = OSDisableInterrupts(); - thread->attributes |= OS_THREAD_ATTR_DETACH; + ASSERTMSG1LINE(LINE(1061, 1092, 1092), __OSIsThreadActive(thread) != 0, "OSJoinThread(): thread %p is not active.", thread); - if (thread->state == OS_THREAD_STATE_DEAD) { - RemoveItem(&__OSActiveThreadQueue, thread, active_threads_link); - thread->state = OS_THREAD_STATE_UNINITIALIZED; + if (!(thread->attr & 1) && (thread->state != OS_THREAD_STATE_MORIBUND) && (thread->queueJoin.head == NULL)) { + OSSleepThread(&thread->queueJoin); + if (__OSIsThreadActive(thread) == 0) { + OSRestoreInterrupts(enabled); + return 0; + } } + if (thread->state == OS_THREAD_STATE_MORIBUND) { + if (val) { + *(s32*)val = (s32)thread->val; + } + DEQUEUE_THREAD(thread, &__OSActiveThreadQueue, linkActive); + thread->state = 0; + OSRestoreInterrupts(enabled); + return 1; + } + OSRestoreInterrupts(enabled); + return 0; +} - OSWakeupThread(&thread->join_queue); +void OSDetachThread(OSThread* thread) { + BOOL enabled = OSDisableInterrupts(); + + ASSERTMSG1LINE(LINE(1111, 1142, 1142), __OSIsThreadActive(thread) != 0, "OSDetachThread(): thread %p is not active.", thread); + + thread->attr |= 1; + if (thread->state == OS_THREAD_STATE_MORIBUND) { + DEQUEUE_THREAD(thread, &__OSActiveThreadQueue, linkActive); + thread->state = 0; + } + OSWakeupThread(&thread->queueJoin); OSRestoreInterrupts(enabled); } -/* 803417B4-80341A3C 33C0F4 0288+00 0/0 13/13 3/3 .text OSResumeThread */ s32 OSResumeThread(OSThread* thread) { - BOOL enabled; + BOOL enabled = OSDisableInterrupts(); s32 suspendCount; - enabled = OSDisableInterrupts(); - suspendCount = thread->suspend_count--; - if (thread->suspend_count < 0) { - thread->suspend_count = 0; - } else if (thread->suspend_count == 0) { - switch (thread->state) { + ASSERTMSG1LINE(LINE(1140, 1171, 1171), __OSIsThreadActive(thread) != 0, "OSResumeThread(): thread %p is not active.", thread); + ASSERTMSG1LINE(LINE(1142, 1173, 1173), thread->state != OS_THREAD_STATE_MORIBUND, "OSResumeThread(): thread %p is terminated.", thread); + + suspendCount = thread->suspend--; + if (thread->suspend < 0) { + thread->suspend = 0; + } else if (thread->suspend == 0) { + switch(thread->state) { case OS_THREAD_STATE_READY: - thread->effective_priority = __OSGetEffectivePriority(thread); + thread->priority = __OSGetEffectivePriority(thread); SetRun(thread); break; case OS_THREAD_STATE_WAITING: - RemoveItem(thread->queue, thread, link); - thread->effective_priority = __OSGetEffectivePriority(thread); - AddPrio(thread->queue, thread, link); + ASSERTLINE(LINE(1157, 1188, 1188), thread->queue); + DEQUEUE_THREAD(thread, thread->queue, link); + thread->priority = __OSGetEffectivePriority(thread); + ENQUEUE_THREAD_PRIO(thread, thread->queue, link); if (thread->mutex) { UpdatePriority(thread->mutex->thread); } - break; } __OSReschedule(); } @@ -591,64 +612,69 @@ s32 OSResumeThread(OSThread* thread) { return suspendCount; } -/* 80341A3C-80341BAC 33C37C 0170+00 0/0 7/7 4/4 .text OSSuspendThread */ s32 OSSuspendThread(OSThread* thread) { - BOOL enabled; + BOOL enabled = OSDisableInterrupts(); s32 suspendCount; - enabled = OSDisableInterrupts(); - suspendCount = thread->suspend_count++; + ASSERTMSG1LINE(LINE(1191, 1222, 1222), __OSIsThreadActive(thread) != 0, "OSSuspendThread(): thread %p is not active.", thread); + ASSERTMSG1LINE(LINE(1193, 1224, 1224), thread->state != OS_THREAD_STATE_MORIBUND, "OSSuspendThread(): thread %p is terminated.", thread); + + suspendCount = thread->suspend++; if (suspendCount == 0) { - switch (thread->state) { + switch(thread->state) { case OS_THREAD_STATE_RUNNING: - RunQueueHint = TRUE; - thread->state = OS_THREAD_STATE_READY; + RunQueueHint = 1; + thread->state = 1; break; case OS_THREAD_STATE_READY: UnsetRun(thread); break; case OS_THREAD_STATE_WAITING: - RemoveItem(thread->queue, thread, link); - thread->effective_priority = 32; - AddTail(thread->queue, thread, link); + DEQUEUE_THREAD(thread, thread->queue, link); + thread->priority = 0x20; + ENQUEUE_THREAD(thread, thread->queue, link); if (thread->mutex) { + ASSERTLINE(LINE(1214, 1245, 1245), thread->mutex->thread); UpdatePriority(thread->mutex->thread); } break; } - __OSReschedule(); } OSRestoreInterrupts(enabled); return suspendCount; } -/* 80341BAC-80341C98 33C4EC 00EC+00 0/0 12/12 0/0 .text OSSleepThread */ void OSSleepThread(OSThreadQueue* queue) { - BOOL enabled; - OSThread* currentThread; + BOOL enabled = OSDisableInterrupts(); + OSThread* currentThread = OSGetCurrentThread(); - enabled = OSDisableInterrupts(); - currentThread = OSGetCurrentThread(); + ASSERTMSGLINE(LINE(1247, 1278, 1278), currentThread, "OSSleepThread(): current thread does not exist."); + ASSERTMSG1LINE(LINE(1249, 1280, 1280), __OSIsThreadActive(currentThread) != 0, "OSSleepThread(): current thread %p is not active.", currentThread); + ASSERTMSG1LINE(LINE(1251, 1282, 1282), currentThread->state == OS_THREAD_STATE_RUNNING, "OSSleepThread(): current thread %p is not running.", currentThread); + ASSERTMSG1LINE(LINE(1253, 1284, 1284), currentThread->suspend <= 0, "OSSleepThread(): current thread %p is suspended.", currentThread); currentThread->state = OS_THREAD_STATE_WAITING; currentThread->queue = queue; - AddPrio(queue, currentThread, link); - RunQueueHint = TRUE; + ENQUEUE_THREAD_PRIO(currentThread, queue, link); + RunQueueHint = 1; __OSReschedule(); OSRestoreInterrupts(enabled); } -/* 80341C98-80341D9C 33C5D8 0104+00 3/3 13/13 0/0 .text OSWakeupThread */ void OSWakeupThread(OSThreadQueue* queue) { - BOOL enabled; - OSThread* thread; + BOOL enabled = OSDisableInterrupts(); - enabled = OSDisableInterrupts(); while (queue->head) { - RemoveHead(queue, thread, link); + OSThread* thread = queue->head; + + DEQUEUE_HEAD(thread, queue, link); + + ASSERTLINE(LINE(1282, 1313, 1313), __OSIsThreadActive(thread)); + ASSERTLINE(LINE(1283, 1314, 1314), thread->state != OS_THREAD_STATE_MORIBUND); + ASSERTLINE(LINE(1284, 1315, 1315), thread->queue == queue); thread->state = OS_THREAD_STATE_READY; - if (!(0 < thread->suspend_count)) { + if (thread->suspend <= 0) { SetRun(thread); } } @@ -656,285 +682,199 @@ void OSWakeupThread(OSThreadQueue* queue) { OSRestoreInterrupts(enabled); } -/* 80341D9C-80341E5C 33C6DC 00C0+00 0/0 1/1 0/0 .text OSSetThreadPriority */ -s32 OSSetThreadPriority(OSThread* thread, s32 priority) { +int OSSetThreadPriority(OSThread* thread, s32 priority) { BOOL enabled; - if (priority < 0 || priority > 31) { - return FALSE; + ASSERTMSGLINE(LINE(1310, 1341, 1341), (priority >= OS_PRIORITY_MIN) && (priority <= OS_PRIORITY_MAX), "OSSetThreadPriority(): priority out of range (0 <= priority <= 31)."); + + if ((priority < OS_PRIORITY_MIN) || (priority > OS_PRIORITY_MAX)) { + return 0; } - enabled = OSDisableInterrupts(); - if ((s32)thread->base_priority != priority) { - thread->base_priority = priority; + ASSERTMSG1LINE(LINE(1317, 1348, 1348), __OSIsThreadActive(thread) != 0, "OSSetThreadPriority(): thread %p is not active.", thread); + ASSERTMSG1LINE(LINE(1319, 1350, 1350), thread->state != 8, "OSSetThreadPriority(): thread %p is terminated.", thread); + + if (thread->base != priority) { + thread->base = priority; UpdatePriority(thread); __OSReschedule(); } OSRestoreInterrupts(enabled); - return TRUE; -} - -/* 80341E5C-80341E64 33C79C 0008+00 0/0 4/4 0/0 .text OSGetThreadPriority */ -s32 OSGetThreadPriority(OSThread* thread) { - return thread->base_priority; -} - -/* 80341E64-80341F00 33C7A4 009C+00 1/1 0/0 0/0 .text CheckThreadQueue */ -s32 CheckThreadQueue(OSThreadQueue* thread) { - OSThread* current; - if (thread->head && thread->head->link.prev) { - return 0; - } - - if (thread->tail && thread->tail->link.next) { - return 0; - } - - current = thread->head; - - while (current) { - if (current->link.next && current != current->link.next->link.prev) { - return 0; - } - - if (current->link.prev && current != current->link.prev->link.next) { - return 0; - } - - current = current->link.next; - } - return 1; } -static BOOL isMember(OSThreadQueue* queue, OSThread* thread) { - OSThread* current = queue->head; - while (current != NULL) { - if (thread == current) { +s32 OSGetThreadPriority(OSThread* thread) { + return thread->base; +} + +OSThread* OSSetIdleFunction(OSIdleFunction idleFunction, void* param, void* stack, u32 stackSize) { + if (idleFunction) { + if (IdleThread.state == 0) { + OSCreateThread(&IdleThread, (void*)idleFunction, param, stack, stackSize, OS_PRIORITY_MAX, 1); + OSResumeThread(&IdleThread); + return &IdleThread; + } + } else if (IdleThread.state != 0) { + OSCancelThread(&IdleThread); + } + return NULL; +} + +OSThread* OSGetIdleFunction(void) { + if (IdleThread.state != 0) { + return &IdleThread; + } + return NULL; +} + +static int CheckThreadQueue(OSThreadQueue* queue) { + OSThread* thread; + + if ((queue->head != NULL) && (queue->head->link.prev != NULL)) { + return 0; + } + if ((queue->tail != NULL) && (queue->tail->link.next != NULL)) { + return 0; + } + thread = queue->head; + while (thread) { + if ((thread->link.next != NULL) && (thread != thread->link.next->link.prev)) { + return 0; + } + if ((thread->link.prev != NULL) && (thread != thread->link.prev->link.next)) { + return 0; + } + thread = thread->link.next; + } + return 1; +} + +static BOOL IsMember(OSThreadQueue* queue, OSThread* thread) { + OSThread* member = queue->head; + + while (member) { + if (thread == member) { return TRUE; } - - current = current->link.next; + member = member->link.next; } return FALSE; } -/* 80341F00-80342650 33C840 0750+00 0/0 1/1 0/0 .text OSCheckActiveThreads */ +// custom macro for OSCheckActiveThreads? +#define ASSERTREPORT(line, cond) \ + if (!(cond)) { \ + OSReport("OSCheckActiveThreads: Failed " #cond " in %d\n", line); \ + OSPanic(__FILE__, line, ""); \ + } + s32 OSCheckActiveThreads(void) { - s32 i; OSThread* thread; - s32 rv = 0; + s32 prio; + s32 cThread; BOOL enabled; + + cThread = 0; enabled = OSDisableInterrupts(); - - for (i = 0; i <= 31; i++) { - if (RunQueueBits & (1 << (31 - i))) { - if (RunQueue[i].head == NULL || RunQueue[i].tail == NULL) { - OSReport("OSCheckActiveThreads: Failed RunQueue[prio].head != NULL && " - "RunQueue[prio].tail != NULL in %d\n", - 0x5e0); - OSPanic(__FILE__, 0x5e0, ""); - } + + for (prio = 0; prio <= OS_PRIORITY_MAX; prio++) { + if (RunQueueBits & (1 << (OS_PRIORITY_MAX - prio))) { + ASSERTREPORT(LINE(1473, 1504, 1504), RunQueue[prio].head != NULL && RunQueue[prio].tail != NULL); } else { - if (RunQueue[i].head != NULL || RunQueue[i].tail != NULL) { - OSReport("OSCheckActiveThreads: Failed RunQueue[prio].head == NULL && " - "RunQueue[prio].tail == NULL in %d\n", - 0x5e5); - OSPanic(__FILE__, 0x5e5, ""); - } - } - - if (CheckThreadQueue(&RunQueue[i]) == 0) { - OSReport("OSCheckActiveThreads: Failed CheckThreadQueue(&RunQueue[prio]) in %d\n", - 0x5e7); - OSPanic(__FILE__, 0x5e7, ""); + ASSERTREPORT(LINE(1478, 1509, 1509), RunQueue[prio].head == NULL && RunQueue[prio].tail == NULL); } + ASSERTREPORT(LINE(1480, 1511, 1511), CheckThreadQueue(&RunQueue[prio])); } - if (OS_THREAD_QUEUE.head != NULL && OS_THREAD_QUEUE.head->active_threads_link.prev != NULL) { - OSReport("OSCheckActiveThreads: Failed __OSActiveThreadQueue.head == NULL || " - "__OSActiveThreadQueue.head->linkActive.prev == NULL in %d\n", - 0x5ec); - OSPanic(__FILE__, 0x5ec, ""); - } + ASSERTREPORT(LINE(1485, 1516, 1516), __OSActiveThreadQueue.head == NULL || __OSActiveThreadQueue.head->linkActive.prev == NULL); + ASSERTREPORT(LINE(1487, 1518, 1518), __OSActiveThreadQueue.tail == NULL || __OSActiveThreadQueue.tail->linkActive.next == NULL); - if (OS_THREAD_QUEUE.tail != NULL && OS_THREAD_QUEUE.tail->active_threads_link.next != NULL) { - OSReport("OSCheckActiveThreads: Failed __OSActiveThreadQueue.tail == NULL || " - "__OSActiveThreadQueue.tail->linkActive.next == NULL in %d\n", - 0x5ee); - OSPanic(__FILE__, 0x5ee, ""); - } + thread = __OSActiveThreadQueue.head; + while (thread) { + cThread++; + ASSERTREPORT(LINE(1495, 1526, 1526), thread->linkActive.next == NULL || thread == thread->linkActive.next->linkActive.prev); + ASSERTREPORT(LINE(1497, 1528, 1528), thread->linkActive.prev == NULL || thread == thread->linkActive.prev->linkActive.next); + ASSERTREPORT(LINE(1500, 1531, 1531), *(thread->stackEnd) == OS_THREAD_STACK_MAGIC); + ASSERTREPORT(LINE(1503, 1534, 1534), OS_PRIORITY_MIN <= thread->priority && thread->priority <= OS_PRIORITY_MAX+1); + ASSERTREPORT(LINE(1504, 1535, 1535), 0 <= thread->suspend); + ASSERTREPORT(LINE(1505, 1536, 1536), CheckThreadQueue(&thread->queueJoin)); - thread = OS_THREAD_QUEUE.head; - - while (thread != NULL) { - rv++; - if (thread->active_threads_link.next != NULL && - thread != thread->active_threads_link.next->active_threads_link.prev) - { - OSReport("OSCheckActiveThreads: Failed thread->linkActive.next == NULL || thread == " - "thread->linkActive.next->linkActive.prev in %d\n", - 0x5f6); - OSPanic(__FILE__, 0x5f6, ""); - } - - if (thread->active_threads_link.prev != NULL && - thread != thread->active_threads_link.prev->active_threads_link.next) - { - OSReport("OSCheckActiveThreads: Failed thread->linkActive.prev == NULL || thread == " - "thread->linkActive.prev->linkActive.next in %d\n", - 0x5f8); - OSPanic(__FILE__, 0x5f8, ""); - } - - if (*(u32*)thread->stack_end != OS_THREAD_STACK_MAGIC) { - OSReport( - "OSCheckActiveThreads: Failed *(thread->stackEnd) == OS_THREAD_STACK_MAGIC in %d\n", - 0x5fb); - OSPanic(__FILE__, 0x5fb, ""); - } - - if (OS_PRIORITY_MIN > thread->effective_priority || - thread->effective_priority > OS_PRIORITY_MAX + 1) - { - OSReport("OSCheckActiveThreads: Failed OS_PRIORITY_MIN <= thread->priority && " - "thread->priority <= OS_PRIORITY_MAX+1 in %d\n", - 0x5fe); - OSPanic(__FILE__, 0x5fe, ""); - } - - if (thread->suspend_count < 0) { - OSReport("OSCheckActiveThreads: Failed 0 <= thread->suspend in %d\n", 0x5ff); - OSPanic(__FILE__, 0x5ff, ""); - } - - if (!CheckThreadQueue(&thread->join_queue)) { - OSReport("OSCheckActiveThreads: Failed CheckThreadQueue(&thread->queueJoin) in %d\n", - 0x600); - OSPanic(__FILE__, 0x600, ""); - } - - switch (thread->state) { + switch(thread->state) { case OS_THREAD_STATE_READY: - if (thread->suspend_count <= 0) { - if (thread->queue != &RunQueue[thread->effective_priority]) { - OSReport("OSCheckActiveThreads: Failed thread->queue == " - "&RunQueue[thread->priority] in %d\n", - 0x606); - OSPanic(__FILE__, 0x606, ""); - } - - if (!isMember(&RunQueue[thread->effective_priority], thread)) { - OSReport("OSCheckActiveThreads: Failed IsMember(&RunQueue[thread->priority], " - "thread) in %d\n", - 0x607); - OSPanic(__FILE__, 0x607, ""); - } - - if (thread->effective_priority != __OSGetEffectivePriority(thread)) { - OSReport("OSCheckActiveThreads: Failed thread->priority == " - "__OSGetEffectivePriority(thread) in %d\n", - 0x608); - OSPanic(__FILE__, 0x608, ""); - } + if (thread->suspend <= 0) { + ASSERTREPORT(LINE(1511, 1542, 1542), thread->queue == &RunQueue[thread->priority]); + ASSERTREPORT(LINE(1512, 1543, 1543), IsMember(&RunQueue[thread->priority], thread)); + ASSERTREPORT(LINE(1513, 1544, 1544), thread->priority == __OSGetEffectivePriority(thread)); } break; case OS_THREAD_STATE_RUNNING: - if (thread->suspend_count > 0) { - OSReport("OSCheckActiveThreads: Failed !IsSuspended(thread->suspend) in %d\n", - 0x60c); - OSPanic(__FILE__, 0x60c, ""); - } - - if (thread->queue != NULL) { - OSReport("OSCheckActiveThreads: Failed thread->queue == NULL in %d\n", 0x60d); - OSPanic(__FILE__, 0x60d, ""); - } - - if (thread->effective_priority != __OSGetEffectivePriority(thread)) { - OSReport("OSCheckActiveThreads: Failed thread->priority == " - "__OSGetEffectivePriority(thread) in %d\n", - 0x60e); - OSPanic(__FILE__, 0x60e, ""); - } + ASSERTREPORT(LINE(1517, 1548, 1548), !IsSuspended(thread->suspend)); + ASSERTREPORT(LINE(1518, 1549, 1549), thread->queue == NULL); + ASSERTREPORT(LINE(1519, 1550, 1550), thread->priority == __OSGetEffectivePriority(thread)); break; case OS_THREAD_STATE_WAITING: - if (thread->queue == NULL) { - OSReport("OSCheckActiveThreads: Failed thread->queue != NULL in %d\n", 0x611); - OSPanic(__FILE__, 0x611, ""); - } - - if (CheckThreadQueue(thread->queue) == 0) { - OSReport("OSCheckActiveThreads: Failed CheckThreadQueue(thread->queue) in %d\n", - 0x612); - OSPanic(__FILE__, 0x612, ""); - } - - if (!isMember(thread->queue, thread)) { - OSReport("OSCheckActiveThreads: Failed IsMember(thread->queue, thread) in %d\n", - 0x613); - OSPanic(__FILE__, 0x613, ""); - } - - if (thread->suspend_count <= 0) { - if (thread->effective_priority != __OSGetEffectivePriority(thread)) { - OSReport("OSCheckActiveThreads: Failed thread->priority == " - "__OSGetEffectivePriority(thread) in %d\n", - 0x616); - OSPanic(__FILE__, 0x616, ""); - } - } else if (thread->effective_priority != 32) { - OSReport("OSCheckActiveThreads: Failed thread->priority == 32 in %d\n", 0x61a); - OSPanic(__FILE__, 0x61a, ""); - } - - if (__OSCheckDeadLock(thread)) { - OSReport("OSCheckActiveThreads: Failed !__OSCheckDeadLock(thread) in %d\n", 0x61c); - OSPanic(__FILE__, 0x61c, ""); + ASSERTREPORT(LINE(1522, 1553, 1553), thread->queue != NULL); + ASSERTREPORT(LINE(1523, 1554, 1554), CheckThreadQueue(thread->queue)); + ASSERTREPORT(LINE(1524, 1555, 1555), IsMember(thread->queue, thread)); + if (thread->suspend <= 0) { + ASSERTREPORT(LINE(1527, 1558, 1558), thread->priority == __OSGetEffectivePriority(thread)); + } else { + ASSERTREPORT(LINE(1531, 1562, 1562), thread->priority == 32); } + ASSERTREPORT(LINE(1533, 1564, 1564), !__OSCheckDeadLock(thread)); break; - case OS_THREAD_STATE_DEAD: - if (thread->owned_mutexes.head != NULL || thread->owned_mutexes.tail != NULL) { - OSReport("OSCheckActiveThreads: Failed thread->queueMutex.head == NULL && " - "thread->queueMutex.tail == NULL in %d\n", - 0x620); - OSPanic(__FILE__, 0x620, ""); - } + case OS_THREAD_STATE_MORIBUND: + ASSERTREPORT(LINE(1537, 1568, 1568), thread->queueMutex.head == NULL && thread->queueMutex.tail == NULL); break; default: - OSReport("OSCheckActiveThreads: Failed. unkown thread state (%d) of thread %p\n", - thread->state, thread); - OSPanic(__FILE__, 0x626, ""); - break; + OSReport("OSCheckActiveThreads: Failed. unkown thread state (%d) of thread %p\n", thread->state, thread); + OSPanic(__FILE__, LINE(1543, 1574, 1574), ""); } - - if (!__OSCheckMutexes(thread)) { - OSReport("OSCheckActiveThreads: Failed __OSCheckMutexes(thread) in %d\n", 0x62b); - OSPanic(__FILE__, 0x62b, ""); - } - - thread = thread->active_threads_link.next; + ASSERTREPORT(LINE(1548, 1579, 1579), __OSCheckMutexes(thread)); + thread = thread->linkActive.next; } - OSRestoreInterrupts(enabled); - return rv; + return cThread; } -/* 80342650-803426FC 33CF90 00AC+00 1/1 0/0 0/0 .text OSClearStack */ void OSClearStack(u8 val) { - u32* sp; - u32* p; - u32 pattern; - - pattern = ((u32)val << 24) | ((u32)val << 16) | ((u32)val << 8) | (u32)val; - sp = (u32*)OSGetStackPointer(); - for (p = ((u32*)__OSCurrentThread->stack_end) + 1; p < sp; ++p) { + register u32 sp; + register u32* p; + register u32 pattern; + + pattern = (val << 24) | (val << 16) | (val << 8) | val; + sp = OSGetStackPointer(); + for (p = __OSCurrentThread->stackEnd + 1; (u32)p < sp; ++p) { *p = pattern; } } -/* ############################################################################################## */ +void OSSetThreadSpecific(s32 index, void* ptr) { + OSThread* thread; + + thread = __OSCurrentThread; + ASSERTLINE(LINE(1573, 1604, 1604), 0 <= index && index < OS_THREAD_SPECIFIC_MAX); + + if (thread != 0 && index >= 0 && index < OS_THREAD_SPECIFIC_MAX) { + thread->specific[index] = ptr; + } +} + +void* OSGetThreadSpecific(s32 index) { + OSThread* thread; + + thread = __OSCurrentThread; + ASSERTLINE(LINE(1584, 1615, 1615), 0 <= index && index < OS_THREAD_SPECIFIC_MAX); + + if (thread != 0 && index >= 0 && index < OS_THREAD_SPECIFIC_MAX) { + return thread->specific[index]; + } + + return NULL; +} + /* 804516D0-804516D8 000BD0 0008+00 0/0 2/1 0/0 .sbss None */ +#include "global.h" extern u8 Debug_BBA_804516D0; -u8 Debug_BBA_804516D0 ALIGN_DECL(8); \ No newline at end of file +u8 Debug_BBA_804516D0 ALIGN_DECL(8); diff --git a/src/dolphin/os/OSTime.c b/src/dolphin/os/OSTime.c index e22c845b7c..5813615e14 100644 --- a/src/dolphin/os/OSTime.c +++ b/src/dolphin/os/OSTime.c @@ -1,146 +1,200 @@ -#include "dolphin/os/OSTime.h" -#include "dolphin/os.h" +#include +#include -#define OS_TIME_MONTH_MAX 12 -#define OS_TIME_WEEK_DAY_MAX 7 -#define OS_TIME_YEAR_DAY_MAX 365 +#include "__os.h" -/* 803426FC-80342714 33D03C 0018+00 1/1 33/33 0/0 .text OSGetTime */ +// End of each month in standard year +static int YearDays[MONTH_MAX] = {0, 31, 59, 90, 120, 151, + 181, 212, 243, 273, 304, 334}; +// End of each month in leap year +static int LeapYearDays[MONTH_MAX] = {0, 31, 60, 91, 121, 152, + 182, 213, 244, 274, 305, 335}; + +#ifdef __GEKKO__ asm OSTime OSGetTime(void) { - // clang-format off - nofralloc +jump: + nofralloc - mftbu r3 - mftb r4, 0x10C - + mftbu r3 + mftb r4 + + // Check for possible carry from TBL to TBU mftbu r5 cmpw r3, r5 - bne OSGetTime - + bne jump + blr - // clang-format on } -/* 80342714-8034271C -00001 0008+00 0/0 0/0 0/0 .text OSGetTick */ -asm OSTick OSGetTick(void) { - // clang-format off - nofralloc +asm OSTick OSGetTick(void){ + nofralloc - mftb r3, 0x10C - blr - // clang-format on + mftb r3 + blr } -#define OS_SYSTEMTIME_BASE 0x30D8 +asm static void __SetTime(OSTime time) { + nofralloc + li r5, 0 + mttbl r5 + mttbu r3 + mttbl r4 + blr +} +#endif -/* 8034271C-80342780 33D05C 0064+00 0/0 16/16 0/0 .text __OSGetSystemTime */ -OSTime __OSGetSystemTime(void) { +void __OSSetTime(OSTime time) { BOOL enabled; - OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE); + OSTime * timeAdjustAddr; + + timeAdjustAddr = __OSSystemTime; + enabled = OSDisableInterrupts(); + + *timeAdjustAddr += OSGetTime() - time; + __SetTime(time); + EXIProbeReset(); + OSRestoreInterrupts(enabled); +} + +OSTime __OSGetSystemTime() { + BOOL enabled; + OSTime* timeAdjustAddr; OSTime result; + timeAdjustAddr = __OSSystemTime; enabled = OSDisableInterrupts(); - result = *timeAdjustAddr + OSGetTime(); - OSRestoreInterrupts(enabled); + result = OSGetTime() + *timeAdjustAddr; + OSRestoreInterrupts(enabled); return result; } -/* 80342780-803427D8 33D0C0 0058+00 0/0 1/1 0/0 .text __OSTimeToSystemTime */ OSTime __OSTimeToSystemTime(OSTime time) { BOOL enabled; - OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE); + OSTime* timeAdjustAddr = __OSSystemTime; OSTime result; enabled = OSDisableInterrupts(); result = *timeAdjustAddr + time; OSRestoreInterrupts(enabled); - return result; } -/* 803D1048-803D1078 02E168 0030+00 1/1 0/0 0/0 .data YearDays */ -// End of each month in standard year -static s32 YearDays[] = { - 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, -}; +#ifdef __GEKKO__ +asm void __OSSetTick(register OSTick newTicks) { + nofralloc + mttbl newTicks + blr +} +#endif -/* 803D1078-803D10A8 02E198 0030+00 1/1 0/0 0/0 .data LeapYearDays */ -// End of each month in leap year -static s32 LeapYearDays[] = { - 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, -}; - -static inline BOOL IsLeapYear(s32 year) { +static int IsLeapYear(int year) { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); } -static inline s32 GetYearDays(s32 year, s32 mon) { - return (IsLeapYear(year) ? LeapYearDays : YearDays)[mon]; +static int GetYearDays(int year, int mon) { + int* md = (IsLeapYear(year)) ? LeapYearDays : YearDays; + + return md[mon]; } -static inline s32 GetLeapDays(s32 year) { +static int GetLeapDays(int year) { + ASSERTLINE(286, 0 <= year); + if (year < 1) { return 0; } return (year + 3) / 4 - (year - 1) / 100 + (year - 1) / 400; } -/* 803427D8-80342974 33D118 019C+00 1/1 0/0 0/0 .text GetDates */ -static void GetDates(s32 days, OSCalendarTime* cal) { - s32 year; - s32 totalDays; - s32* p_days; - s32 month; - cal->week_day = (days + 6) % OS_TIME_WEEK_DAY_MAX; +static void GetDates(int days, OSCalendarTime* td) { + int year; + int n; + int month; + int * md; - for (year = days / OS_TIME_YEAR_DAY_MAX; - days < (totalDays = year * OS_TIME_YEAR_DAY_MAX + GetLeapDays(year));) - { - year--; - } + ASSERTLINE(311, 0 <= days); - days -= totalDays; - cal->year = year; - cal->year_day = days; + td->wday = (days + 6) % WEEK_DAY_MAX; - p_days = IsLeapYear(year) ? LeapYearDays : YearDays; - month = OS_TIME_MONTH_MAX; - while (days < p_days[--month]) { + for (year = days / YEAR_DAY_MAX; + days < (n = year * YEAR_DAY_MAX + GetLeapDays(year)); year--) { ; } - cal->month = month; - cal->day_of_month = days - p_days[month] + 1; + + days -= n; + td->year = year; + td->yday = days; + + md = IsLeapYear(year) ? LeapYearDays : YearDays; + for (month = MONTH_MAX; days < md[--month];) { + ; + } + td->mon = month; + td->mday = days - md[month] + 1; } -#define BIAS (2000 * 365 + (2000 + 3) / 4 - (2000 - 1) / 100 + (2000 - 1) / 400) - -/* 80342974-80342B78 33D2B4 0204+00 0/0 4/4 0/0 .text OSTicksToCalendarTime */ -#pragma dont_inline on void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* td) { int days; int secs; OSTime d; - d = ticks % OSSecondsToTicks(1); + d = ticks % OS_SEC_TO_TICKS(1); if (d < 0) { - d += OSSecondsToTicks(1); + d += OS_SEC_TO_TICKS(1); + ASSERTLINE(356, 0 <= d); } - td->microseconds = (int)(OSTicksToMicroseconds(d) % 1000); - td->milliseconds = (int)(OSTicksToMilliseconds(d) % 1000); + + td->usec = OS_TICKS_TO_USEC(d) % USEC_MAX; + td->msec = OS_TICKS_TO_MSEC(d) % MSEC_MAX; + + ASSERTLINE(360, 0 <= td->usec); + ASSERTLINE(361, 0 <= td->msec); ticks -= d; - days = (int)(OSTicksToSeconds(ticks) / 86400 + BIAS); - secs = (int)(OSTicksToSeconds(ticks) % 86400); + + ASSERTLINE(364, ticks % OSSecondsToTicks(1) == 0); + ASSERTLINE(368, 0 <= OSTicksToSeconds(ticks) / 86400 + BIAS && OSTicksToSeconds(ticks) / 86400 + BIAS <= INT_MAX); + + days = (OS_TICKS_TO_SEC(ticks) / SECS_IN_DAY) + BIAS; + secs = OS_TICKS_TO_SEC(ticks) % SECS_IN_DAY; if (secs < 0) { days -= 1; - secs += 24 * 60 * 60; + secs += SECS_IN_DAY; + ASSERTLINE(375, 0 <= secs); } GetDates(days, td); - - td->hours = secs / 60 / 60; - td->minutes = (secs / 60) % 60; - td->seconds = secs % 60; + td->hour = secs / 60 / 60; + td->min = secs / 60 % 60; + td->sec = secs % 60; +} + +OSTime OSCalendarTimeToTicks(OSCalendarTime* td) { + OSTime secs; + int ov_mon; + int mon; + int year; + + ov_mon = td->mon / MONTH_MAX; + mon = td->mon - (ov_mon * MONTH_MAX); + + if (mon < 0) { + mon += MONTH_MAX; + ov_mon--; + } + + ASSERTLINE(412, (ov_mon <= 0 && 0 <= td->year + ov_mon) || (0 < ov_mon && td->year <= INT_MAX - ov_mon)); + + year = td->year + ov_mon; + + secs = (OSTime)SECS_IN_YEAR * year + + (OSTime)SECS_IN_DAY * (GetLeapDays(year) + GetYearDays(year, mon) + td->mday - 1) + + (OSTime)SECS_IN_HOUR * td->hour + + (OSTime)SECS_IN_MIN * td->min + + td->sec - + (OSTime)0xEB1E1BF80ULL; + + return OS_SEC_TO_TICKS(secs) + OS_MSEC_TO_TICKS((OSTime)td->msec) + + OS_USEC_TO_TICKS((OSTime)td->usec); } -#pragma dont_inline reset \ No newline at end of file diff --git a/src/dolphin/os/OSTimer.c b/src/dolphin/os/OSTimer.c new file mode 100644 index 0000000000..99c13a62f5 --- /dev/null +++ b/src/dolphin/os/OSTimer.c @@ -0,0 +1,140 @@ +#include +#include + +#include "__os.h" + +struct Timer { + OSTimerCallback callback; + u32 currval; + u32 startval; + u32 mode; + BOOL stopped; + BOOL initialized; +}; +static struct Timer Timer; + +// prototypes +static void DecrementerExceptionHandler(__OSException exception, OSContext* context); + +OSTimerCallback OSSetTimerCallback(OSTimerCallback callback) { + OSTimerCallback prevCallback; + +#if DEBUG + if(!Timer.initialized) { + OSPanic(__FILE__, 135, "OSSetTimerCallback(): timer is not initialized."); + } +#endif + + Timer.stopped = TRUE; + prevCallback = Timer.callback; + Timer.callback = callback; + return prevCallback; +} + +void OSInitTimer(u32 time, u32 mode) { +#if DEBUG + if (time >= 0x80000000) { + OSPanic(__FILE__, 159, "OSInitTimer(): time param must be less than 0x80000000."); + } +#endif + + Timer.stopped = TRUE; + Timer.currval = time; + Timer.startval = time; + Timer.mode = mode; + + if (!Timer.initialized) { + __OSSetExceptionHandler(8, &DecrementerExceptionHandler); + Timer.initialized = TRUE; + Timer.callback = 0; +#if DEBUG + OSReport("Timer initialized\n"); +#endif + } +} + +void OSStartTimer(void) { + BOOL enabled; + +#if DEBUG + if (!Timer.initialized) { + OSPanic(__FILE__, 192, "OSStartTimer(): timer is not initialized."); + } +#endif + enabled = OSDisableInterrupts(); + PPCMtdec(Timer.currval); + Timer.stopped = FALSE; + OSRestoreInterrupts(enabled); +} + +void OSStopTimer(void) { + BOOL enabled; + +#if DEBUG + if (!Timer.initialized) { + OSPanic(__FILE__, 216, "OSStopTimer(): timer is not initialized."); + } +#endif + + enabled = OSDisableInterrupts(); + if (!Timer.stopped) { + Timer.stopped = TRUE; + Timer.currval = PPCMfdec(); + if (Timer.currval & 0x80000000) { + Timer.currval = 0; + } + } + OSRestoreInterrupts(enabled); +} + +static void DecrementerExceptionCallback(__OSException exception, OSContext* context) { + OSContext exceptionContext; + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + if (!Timer.stopped) { + if (Timer.mode == 1) { + PPCMtdec(Timer.startval); + } + if (Timer.mode == 2) { + Timer.stopped = TRUE; + } + if (Timer.callback) { + Timer.callback(); + } + } + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + OSLoadContext(context); +} + +#ifdef __GEKKO__ +static asm void DecrementerExceptionHandler(__OSException exception, + register OSContext* context) { + nofralloc + + stw r0, context->gpr[0] + stw r1, context->gpr[1] + stw r2, context->gpr[2] + stmw r6, context->gpr[6] + + mfspr r0, GQR1 + stw r0, context->gqr[1] + mfspr r0, GQR2 + stw r0, context->gqr[2] + mfspr r0, GQR3 + stw r0, context->gqr[3] + mfspr r0, GQR4 + stw r0, context->gqr[4] + mfspr r0, GQR5 + stw r0, context->gqr[5] + mfspr r0, GQR6 + stw r0, context->gqr[6] + mfspr r0, GQR7 + stw r0, context->gqr[7] + + stwu r1, -0x8(r1) + b DecrementerExceptionCallback +} +#endif diff --git a/src/dolphin/os/OSUtf.c b/src/dolphin/os/OSUtf.c new file mode 100644 index 0000000000..ddfa23dde4 --- /dev/null +++ b/src/dolphin/os/OSUtf.c @@ -0,0 +1,6341 @@ +#include +#include + +char* OSUTF8to32(const char* utf8, u32* utf32) { + u32 u; + u8 c; + unsigned int len; + unsigned int i; + + c = *utf8; + if (c != 0) { + utf8++; + } + + if ((c & 0x80) == 0) { + u = c; + len = 0; + } else if ((c & 0xE0) == 0xC0u) { + u = c & 0x1F; + len = 1; + } else if ((c & 0xF0) == 0xE0u) { + u = c & 0xF; + len = 2; + } else if ((c & 0xF8) == 0xF0u) { + u = c & 0x7; + len = 3; + } else { + return NULL; + } + + for (i = 0; i < len; i++) { + u = u << 6; + c = *utf8++; + if ((c & 0xC0) != 0x80u) { + return NULL; + } + + u |= (c & 0x3F); + } + + if (u <= 0x7Fu) { + if (len != 0) { + return NULL; + } + } else if (u <= 0x7FFu) { + if (len != 1) { + return NULL; + } + } else if (u <= 0xFFFFu) { + if (len != 2) { + return NULL; + } + } + + if (u >= 0xD800u && u <= 0xDFFFu) { + return NULL; + } + + *utf32 = u; + return (char*)utf8; +} + +char* OSUTF32to8(u32 utf32, char* utf8) { + int len; + + if (utf32 >= 0xD800u && utf32 <= 0xDFFFu) { + return NULL; + } + + if (utf32 < 0x80u) { + *utf8 = (s8)utf32; + utf8++; + } else if (utf32 < 0x800u) { + *utf8 = (utf32 >> 6) | 0xC0; + utf8++; + len = 1; + } else if (utf32 < 0x10000u) { + *utf8 = (utf32 >> 0xC) | 0xE0; + utf8++; + len = 2; + } else if (utf32 < 0x110000u) { + *utf8 = (utf32 >> 0x12) | 0xF0; + utf8++; + len = 3; + } else { + return NULL; + } + + while (len-- > 0) { + *utf8 = ((utf32 >> (len * 6)) & 0x3F) | 0x80; + utf8++; + } + + return utf8; +} + +u16* OSUTF16to32(const u16* utf16, u32* utf32) { + u16 w1; + u16 w2; + u32 u; + + w1 = *utf16; + if (w1 != 0) { + utf16++; + } + + if (w1 < 0xD800 || w1 > 0xDFFF) { + u = w1; + } else if (w1 <= 0xDBFF) { + w2 = *utf16; + utf16++; + + if (w2 >= 0xDC00 && w2 <= 0xDFFF) { + u = ((w1 << 10) & 0xFFC00) | ((w2 & 0x3FF) & ~0xFFC00); + u = u + 0x10000; + } else { + return NULL; + } + } else { + return NULL; + } + + *utf32 = u; + return (u16*)utf16; +} + +u16* OSUTF32to16(u32 utf32, u16* utf16) { + u16 w1; + u16 w2; + + if (utf32 >= 0xD800u && utf32 <= 0xDFFFu) { + return NULL; + } + + if (utf32 < 0x10000u) { + *utf16 = utf32; + utf16++; + } else if (utf32 <= 0x10FFFFu) { + w1 = -0x122800; + w2 = -0x122400; + utf32 -= 0x10000; + ASSERTLINE(0xD1, utf32 <= 0xFFFFF); + + w1 |= utf32 >> 10; + w2 |= utf32 & 0x3FF; + + *utf16++ = w1; + *utf16++ = w2; + } else { + return NULL; + } + + return utf16; +} + +static u16 UcsAnsiTable[32] = { + 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, + 0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, + 0x0152, 0x0000, 0x017D, 0x0000, 0x0000, 0x2018, + 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, + 0x017E, 0x0178, +}; + +u8 OSUTF32toANSI(u32 utf32) { + int i; + + if (utf32 > 0xFF) { + return 0; + } + + if (utf32 < 0x80 || utf32 > 0x9F) { + return utf32; + } + + if (utf32 >= 0x152 && utf32 <= 0x2122) { + for (i = 0; i <= 31; i++) { + if (utf32 == UcsAnsiTable[i]) { + return i + 0x80; + } + } + } + + return 0; +} + +u32 OSANSItoUTF32(u8 ansi) { + if (ansi >= 0x80 && ansi <= 0x9F) { + return UcsAnsiTable[ansi - 0x80]; + } + + return ansi; +} + +static u16 Ucs00[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, + 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, + 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, + 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, + 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, + 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, + 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005A, 0x005B, 0x815F, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, + 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, + 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, + 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8191, 0x8192, 0x0000, 0x005C, 0x0000, 0x8198, + 0x814E, 0x0000, 0x0000, 0x0000, 0x81CA, 0x0000, + 0x0000, 0x0000, 0x818B, 0x817D, 0x0000, 0x0000, + 0x814C, 0x0000, 0x81F7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x817E, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8180, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs03[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x839F, 0x83A0, 0x83A1, 0x83A2, 0x83A3, + 0x83A4, 0x83A5, 0x83A6, 0x83A7, 0x83A8, 0x83A9, + 0x83AA, 0x83AB, 0x83AC, 0x83AD, 0x83AE, 0x83AF, + 0x0000, 0x83B0, 0x83B1, 0x83B2, 0x83B3, 0x83B4, + 0x83B5, 0x83B6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x83BF, 0x83C0, 0x83C1, + 0x83C2, 0x83C3, 0x83C4, 0x83C5, 0x83C6, 0x83C7, + 0x83C8, 0x83C9, 0x83CA, 0x83CB, 0x83CC, 0x83CD, + 0x83CE, 0x83CF, 0x0000, 0x83D0, 0x83D1, 0x83D2, + 0x83D3, 0x83D4, 0x83D5, 0x83D6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs04[256] = { + 0x0000, 0x8446, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8440, 0x8441, + 0x8442, 0x8443, 0x8444, 0x8445, 0x8447, 0x8448, + 0x8449, 0x844A, 0x844B, 0x844C, 0x844D, 0x844E, + 0x844F, 0x8450, 0x8451, 0x8452, 0x8453, 0x8454, + 0x8455, 0x8456, 0x8457, 0x8458, 0x8459, 0x845A, + 0x845B, 0x845C, 0x845D, 0x845E, 0x845F, 0x8460, + 0x8470, 0x8471, 0x8472, 0x8473, 0x8474, 0x8475, + 0x8477, 0x8478, 0x8479, 0x847A, 0x847B, 0x847C, + 0x847D, 0x847E, 0x8480, 0x8481, 0x8482, 0x8483, + 0x8484, 0x8485, 0x8486, 0x8487, 0x8488, 0x8489, + 0x848A, 0x848B, 0x848C, 0x848D, 0x848E, 0x848F, + 0x8490, 0x8491, 0x0000, 0x8476, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs20[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x815D, 0x0000, + 0x0000, 0x0000, 0x0000, 0x815C, 0x8161, 0x0000, + 0x8165, 0x8166, 0x0000, 0x0000, 0x8167, 0x8168, + 0x0000, 0x0000, 0x81F5, 0x81F6, 0x0000, 0x0000, + 0x0000, 0x8164, 0x8163, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x81F1, 0x0000, 0x818C, 0x818D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x81A6, + 0x0000, 0x0000, 0x007E, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs21[256] = { + 0x0000, 0x0000, 0x0000, 0x818E, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x81F0, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x81A9, 0x81AA, 0x81A8, 0x81AB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x81CB, 0x0000, 0x81CC, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs22[256] = { + 0x81CD, 0x0000, 0x81DD, 0x81CE, 0x0000, 0x0000, + 0x0000, 0x81DE, 0x81B8, 0x0000, 0x0000, 0x81B9, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x817C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x81E3, 0x0000, 0x0000, 0x81E5, + 0x8187, 0x0000, 0x81DA, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x81C8, 0x81C9, 0x81BF, + 0x81BE, 0x81E7, 0x81E8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8188, 0x81E6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x81E4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x81E0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8182, 0x81DF, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8185, 0x8186, 0x0000, 0x0000, 0x81E1, 0x81E2, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x81BC, 0x81BD, + 0x0000, 0x0000, 0x81BA, 0x81BB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x81DB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs23[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x81DC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs25[256] = { + 0x849F, 0x84AA, 0x84A0, 0x84AB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x84A1, 0x0000, 0x0000, 0x84AC, 0x84A2, 0x0000, + 0x0000, 0x84AD, 0x84A4, 0x0000, 0x0000, 0x84AF, + 0x84A3, 0x0000, 0x0000, 0x84AE, 0x84A5, 0x84BA, + 0x0000, 0x0000, 0x84B5, 0x0000, 0x0000, 0x84B0, + 0x84A7, 0x84BC, 0x0000, 0x0000, 0x84B7, 0x0000, + 0x0000, 0x84B2, 0x84A6, 0x0000, 0x0000, 0x84B6, + 0x84BB, 0x0000, 0x0000, 0x84B1, 0x84A8, 0x0000, + 0x0000, 0x84B8, 0x84BD, 0x0000, 0x0000, 0x84B3, + 0x84A9, 0x0000, 0x0000, 0x84B9, 0x0000, 0x0000, + 0x84BE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x84B4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x81A1, 0x81A0, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x81A3, 0x81A2, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x81A5, 0x81A4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x819F, 0x819E, 0x0000, 0x0000, 0x0000, 0x819B, + 0x0000, 0x0000, 0x819D, 0x819C, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x81FC, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs26[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x819A, + 0x8199, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x818A, 0x0000, + 0x8189, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x81F4, 0x0000, + 0x0000, 0x81F3, 0x0000, 0x81F2, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs30[256] = { + 0x8140, 0x8141, 0x8142, 0x8156, 0x0000, 0x8158, + 0x8159, 0x815A, 0x8171, 0x8172, 0x8173, 0x8174, + 0x8175, 0x8176, 0x8177, 0x8178, 0x8179, 0x817A, + 0x81A7, 0x81AC, 0x816B, 0x816C, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8160, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x829F, + 0x82A0, 0x82A1, 0x82A2, 0x82A3, 0x82A4, 0x82A5, + 0x82A6, 0x82A7, 0x82A8, 0x82A9, 0x82AA, 0x82AB, + 0x82AC, 0x82AD, 0x82AE, 0x82AF, 0x82B0, 0x82B1, + 0x82B2, 0x82B3, 0x82B4, 0x82B5, 0x82B6, 0x82B7, + 0x82B8, 0x82B9, 0x82BA, 0x82BB, 0x82BC, 0x82BD, + 0x82BE, 0x82BF, 0x82C0, 0x82C1, 0x82C2, 0x82C3, + 0x82C4, 0x82C5, 0x82C6, 0x82C7, 0x82C8, 0x82C9, + 0x82CA, 0x82CB, 0x82CC, 0x82CD, 0x82CE, 0x82CF, + 0x82D0, 0x82D1, 0x82D2, 0x82D3, 0x82D4, 0x82D5, + 0x82D6, 0x82D7, 0x82D8, 0x82D9, 0x82DA, 0x82DB, + 0x82DC, 0x82DD, 0x82DE, 0x82DF, 0x82E0, 0x82E1, + 0x82E2, 0x82E3, 0x82E4, 0x82E5, 0x82E6, 0x82E7, + 0x82E8, 0x82E9, 0x82EA, 0x82EB, 0x82EC, 0x82ED, + 0x82EE, 0x82EF, 0x82F0, 0x82F1, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x814A, + 0x814B, 0x8154, 0x8155, 0x0000, 0x0000, 0x8340, + 0x8341, 0x8342, 0x8343, 0x8344, 0x8345, 0x8346, + 0x8347, 0x8348, 0x8349, 0x834A, 0x834B, 0x834C, + 0x834D, 0x834E, 0x834F, 0x8350, 0x8351, 0x8352, + 0x8353, 0x8354, 0x8355, 0x8356, 0x8357, 0x8358, + 0x8359, 0x835A, 0x835B, 0x835C, 0x835D, 0x835E, + 0x835F, 0x8360, 0x8361, 0x8362, 0x8363, 0x8364, + 0x8365, 0x8366, 0x8367, 0x8368, 0x8369, 0x836A, + 0x836B, 0x836C, 0x836D, 0x836E, 0x836F, 0x8370, + 0x8371, 0x8372, 0x8373, 0x8374, 0x8375, 0x8376, + 0x8377, 0x8378, 0x8379, 0x837A, 0x837B, 0x837C, + 0x837D, 0x837E, 0x8380, 0x8381, 0x8382, 0x8383, + 0x8384, 0x8385, 0x8386, 0x8387, 0x8388, 0x8389, + 0x838A, 0x838B, 0x838C, 0x838D, 0x838E, 0x838F, + 0x8390, 0x8391, 0x8392, 0x8393, 0x8394, 0x8395, + 0x8396, 0x0000, 0x0000, 0x0000, 0x0000, 0x8145, + 0x815B, 0x8152, 0x8153, 0x0000 +}; + +static u16 Ucs4E[256] = { + 0x88EA, 0x929A, 0x0000, 0x8EB5, 0x0000, 0x0000, + 0x0000, 0x969C, 0x8FE4, 0x8E4F, 0x8FE3, 0x89BA, + 0x0000, 0x9573, 0x975E, 0x0000, 0x98A0, 0x894E, + 0x0000, 0x0000, 0x8A8E, 0x98A1, 0x90A2, 0x99C0, + 0x8B75, 0x95B8, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8FE5, 0x0000, 0x0000, 0x97BC, 0x0000, 0x0000, + 0x0000, 0x0000, 0x95C0, 0x0000, 0x0000, 0x0000, + 0x98A2, 0x0000, 0x0000, 0x9286, 0x0000, 0x0000, + 0x0000, 0x98A3, 0x8BF8, 0x0000, 0x0000, 0x0000, + 0x98A4, 0x0000, 0x8ADB, 0x924F, 0x0000, 0x8EE5, + 0x98A5, 0x0000, 0x0000, 0x98A6, 0x0000, 0x0000, + 0x98A7, 0x9454, 0x0000, 0x8B76, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9456, 0x0000, 0x93E1, + 0x8CC1, 0x9652, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE568, 0x98A8, 0x8FE6, 0x98A9, 0x89B3, + 0x0000, 0x0000, 0x0000, 0x8BE3, 0x8CEE, 0x96E7, + 0x0000, 0x0000, 0x9BA4, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9790, + 0x0000, 0x93FB, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8AA3, 0x0000, 0x8B54, 0x0000, 0x98AA, 0x0000, + 0x0000, 0x98AB, 0x97B9, 0x0000, 0x975C, 0x9188, + 0x98AD, 0x8E96, 0x93F1, 0x0000, 0x98B0, 0x0000, + 0x0000, 0x895D, 0x8CDD, 0x0000, 0x8CDC, 0x88E4, + 0x0000, 0x0000, 0x986A, 0x9869, 0x0000, 0x8DB1, + 0x889F, 0x0000, 0x98B1, 0x98B2, 0x98B3, 0x9653, + 0x98B4, 0x0000, 0x8CF0, 0x88E5, 0x9692, 0x0000, + 0x8B9C, 0x0000, 0x0000, 0x8B9D, 0x8B9E, 0x92E0, + 0x97BA, 0x0000, 0x98B5, 0x0000, 0x0000, 0x98B6, + 0x0000, 0x0000, 0x98B7, 0x0000, 0x0000, 0x0000, + 0x906C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8F59, 0x906D, 0x98BC, 0x0000, 0x98BA, 0x0000, + 0x98BB, 0x8B77, 0x0000, 0x0000, 0x8DA1, 0x89EE, + 0x0000, 0x98B9, 0x98B8, 0x95A7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8E65, 0x8E64, 0x91BC, 0x98BD, + 0x9574, 0x90E5, 0x0000, 0x0000, 0x0000, 0x8157, + 0x98BE, 0x98C0, 0x0000, 0x0000, 0x0000, 0x91E3, + 0x97DF, 0x88C8, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x98BF, 0x89BC, 0x0000, + 0x8BC2, 0x0000, 0x9287, 0x0000, 0x0000, 0x0000, + 0x8C8F, 0x98C1, 0x0000, 0x0000, 0x0000, 0x9443, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs4F[256] = { + 0x0000, 0x8AE9, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x98C2, 0x88C9, 0x0000, + 0x0000, 0x8CDE, 0x8AEA, 0x959A, 0x94B0, 0x8B78, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x89EF, 0x0000, 0x98E5, 0x9360, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x948C, + 0x98C4, 0x0000, 0x0000, 0x0000, 0x94BA, 0x0000, + 0x97E0, 0x0000, 0x904C, 0x0000, 0x8E66, 0x0000, + 0x8E97, 0x89BE, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x92CF, 0x0000, 0x0000, 0x9241, 0x98C8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x88CA, + 0x92E1, 0x8F5A, 0x8DB2, 0x9743, 0x0000, 0x91CC, + 0x0000, 0x89BD, 0x0000, 0x98C7, 0x0000, 0x975D, + 0x98C3, 0x98C5, 0x8DEC, 0x98C6, 0x9B43, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x98CE, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x98D1, 0x98CF, 0x0000, + 0x0000, 0x89C0, 0x0000, 0x95B9, 0x98C9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x98CD, 0x8CF1, 0x0000, + 0x0000, 0x8E67, 0x0000, 0x0000, 0x0000, 0x8AA4, + 0x0000, 0x0000, 0x98D2, 0x0000, 0x98CA, 0x0000, + 0x0000, 0x97E1, 0x0000, 0x8E98, 0x0000, 0x98CB, + 0x0000, 0x98D0, 0x0000, 0x0000, 0x0000, 0x0000, + 0x98D3, 0x0000, 0x98CC, 0x0000, 0x0000, 0x8B9F, + 0x0000, 0x88CB, 0x0000, 0x0000, 0x8BA0, 0x89BF, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9B44, 0x0000, 0x9699, + 0x958E, 0x8CF2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x904E, 0x97B5, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x95D6, + 0x0000, 0x0000, 0x8C57, 0x91A3, 0x89E2, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8F72, 0x0000, + 0x0000, 0x0000, 0x98D7, 0x0000, 0x98DC, 0x98DA, + 0x0000, 0x0000, 0x98D5, 0x0000, 0x0000, 0x91AD, + 0x98D8, 0x0000, 0x98DB, 0x98D9, 0x0000, 0x95DB, + 0x0000, 0x98D6, 0x0000, 0x904D, 0x0000, 0x9693, + 0x98DD, 0x98DE, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8F43, 0x98EB, + 0x0000, 0x0000, 0x0000, 0x946F, 0x0000, 0x9555, + 0x98E6, 0x0000, 0x95EE, 0x0000, 0x89B4, 0x0000, + 0x0000, 0x0000, 0x98EA, 0x0000 +}; + +static u16 Ucs50[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x98E4, + 0x98ED, 0x0000, 0x0000, 0x9171, 0x0000, 0x8CC2, + 0x0000, 0x947B, 0x0000, 0xE0C5, 0x0000, 0x98EC, + 0x937C, 0x0000, 0x98E1, 0x0000, 0x8CF4, 0x0000, + 0x0000, 0x8CF3, 0x98DF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8ED8, 0x0000, 0x98E7, 0x0000, 0x95ED, + 0x926C, 0x98E3, 0x8C91, 0x0000, 0x98E0, 0x98E8, + 0x98E2, 0x97CF, 0x98E9, 0x9860, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8BE4, 0x0000, 0x0000, 0x8C90, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x98EE, 0x0000, 0x0000, 0x0000, 0x98EF, + 0x98F3, 0x88CC, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x95CE, 0x98F2, 0x0000, 0x0000, 0x0000, + 0x0000, 0x98F1, 0x98F5, 0x0000, 0x0000, 0x0000, + 0x98F4, 0x0000, 0x92E2, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8C92, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x98F6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8EC3, 0x0000, 0x91A4, 0x92E3, 0x8BF4, 0x0000, + 0x98F7, 0x0000, 0x0000, 0x0000, 0x0000, 0x8B55, + 0x0000, 0x0000, 0x98F8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x98FA, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9654, 0x0000, 0x0000, + 0x0000, 0x8C86, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8E50, 0x94F5, 0x98F9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8DC3, 0x9762, + 0x0000, 0x0000, 0x0000, 0x0000, 0x98FC, 0x9942, + 0x98FB, 0x8DC2, 0x0000, 0x8F9D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8C58, 0x0000, + 0x0000, 0x0000, 0x9943, 0x0000, 0x0000, 0x8BCD, + 0x0000, 0x0000, 0x0000, 0x9940, 0x9941, 0x0000, + 0x0000, 0x93AD, 0x0000, 0x919C, 0x0000, 0x8BA1, + 0x0000, 0x0000, 0x0000, 0x966C, 0x9944, 0x0000, + 0x0000, 0x0000, 0x97BB, 0x0000, 0x0000, 0x0000, + 0x9945, 0x0000, 0x0000, 0x0000, 0x0000, 0x9948, + 0x0000, 0x9946, 0x0000, 0x916D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9947, 0x9949, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x994B, + 0x0000, 0x0000, 0x0000, 0x994A, 0x0000, 0x95C6, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs51[256] = { + 0x8B56, 0x994D, 0x994E, 0x0000, 0x89AD, 0x0000, + 0x0000, 0x0000, 0x0000, 0x994C, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8EF2, 0x0000, 0x9951, 0x9950, 0x994F, 0x0000, + 0x98D4, 0x0000, 0x9952, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8F9E, 0x0000, 0x9953, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9744, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x96D7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9955, 0x0000, 0x0000, 0x9954, 0x9957, + 0x9956, 0x0000, 0x0000, 0x9958, 0x9959, 0x88F2, + 0x0000, 0x8CB3, 0x8C5A, 0x8F5B, 0x929B, 0x8BA2, + 0x90E6, 0x8CF5, 0x0000, 0x8D8E, 0x995B, 0x96C6, + 0x9365, 0x0000, 0x8E99, 0x0000, 0x995A, 0x0000, + 0x995C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x937D, 0x0000, 0x8A95, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x995D, 0x0000, 0x0000, 0x93FC, + 0x0000, 0x0000, 0x9153, 0x995F, 0x9960, 0x94AA, + 0x8CF6, 0x985A, 0x9961, 0x0000, 0x0000, 0x8BA4, + 0x0000, 0x0000, 0x0000, 0x95BA, 0x91B4, 0x8BEF, + 0x9354, 0x0000, 0x0000, 0x0000, 0x8C93, 0x0000, + 0x0000, 0x0000, 0x9962, 0x0000, 0x9963, 0x0000, + 0x0000, 0x93E0, 0x897E, 0x0000, 0x0000, 0x9966, + 0x8DFB, 0x0000, 0x9965, 0x8DC4, 0x0000, 0x9967, + 0xE3EC, 0x9968, 0x9660, 0x9969, 0x0000, 0x996A, + 0x996B, 0x8FE7, 0x0000, 0x8ECA, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8AA5, 0x0000, + 0x996E, 0x0000, 0x996C, 0x96BB, 0x996D, 0x0000, + 0x9579, 0x996F, 0x9970, 0x9971, 0x937E, 0x0000, + 0x0000, 0x0000, 0x9975, 0x9973, 0x9974, 0x9972, + 0x8DE1, 0x9976, 0x96E8, 0x97E2, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9977, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x90A6, 0x9978, + 0x8F79, 0x0000, 0x0000, 0x9979, 0x0000, 0x929C, + 0x97BD, 0x9380, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x99C3, 0x0000, + 0x0000, 0x0000, 0x0000, 0x997A, 0xEAA3, 0x8BC3, + 0x0000, 0x0000, 0x997B, 0x967D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8F88, 0x91FA, 0x0000, 0x997D, + 0x93E2, 0x0000, 0x0000, 0x997E, 0x0000, 0x0000, + 0x9980, 0x8A4D, 0x0000, 0x0000, 0x0000, 0x9981, + 0x8BA5, 0x0000, 0x93CA, 0x899A, 0x8F6F, 0x0000, + 0x0000, 0x949F, 0x9982, 0x0000 +}; + +static u16 Ucs52[256] = { + 0x9381, 0x0000, 0x0000, 0x906E, 0x9983, 0x0000, + 0x95AA, 0x90D8, 0x8AA0, 0x0000, 0x8AA7, 0x9984, + 0x0000, 0x0000, 0x9986, 0x0000, 0x0000, 0x8C59, + 0x0000, 0x0000, 0x9985, 0x0000, 0x0000, 0x97F1, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8F89, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x94BB, 0x95CA, 0x0000, 0x9987, 0x0000, 0x9798, + 0x9988, 0x0000, 0x0000, 0x0000, 0x9989, 0x0000, + 0x939E, 0x0000, 0x0000, 0x998A, 0x0000, 0x0000, + 0x90A7, 0x8DFC, 0x8C94, 0x998B, 0x8E68, 0x8D8F, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x92E4, 0x998D, 0x0000, 0x0000, 0x91A5, + 0x0000, 0x0000, 0x8DED, 0x998E, 0x998F, 0x914F, + 0x0000, 0x998C, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9991, 0x0000, 0x9655, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8D84, 0x0000, 0x0000, 0x9990, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8C95, 0x8DDC, 0x948D, + 0x0000, 0x0000, 0x0000, 0x9994, 0x9992, 0x0000, + 0x0000, 0x0000, 0x0000, 0x959B, 0x8FE8, 0x999B, + 0x8A84, 0x9995, 0x9993, 0x916E, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9997, + 0x0000, 0x9996, 0x0000, 0x0000, 0x0000, 0x8A63, + 0x0000, 0x0000, 0x0000, 0x8C80, 0x999C, 0x97AB, + 0x0000, 0x0000, 0x0000, 0x9998, 0x0000, 0x0000, + 0x0000, 0x999D, 0x999A, 0x0000, 0x9999, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x97CD, + 0x0000, 0x0000, 0x0000, 0x8CF7, 0x89C1, 0x0000, + 0x0000, 0x97F2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8F95, 0x9377, 0x8D85, 0x99A0, 0x99A1, + 0x0000, 0x0000, 0x0000, 0x97E3, 0x0000, 0x0000, + 0x984A, 0x99A3, 0x0000, 0x0000, 0x0000, 0x8CF8, + 0x0000, 0x0000, 0x99A2, 0x0000, 0x8A4E, 0x0000, + 0x0000, 0x99A4, 0x0000, 0x9675, 0x0000, 0x92BA, + 0x0000, 0x9745, 0x0000, 0x95D7, 0x0000, 0x0000, + 0x0000, 0x99A5, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE8D3, 0x0000, 0x0000, 0x93AE, 0x0000, 0x99A6, + 0x8AA8, 0x96B1, 0x0000, 0x0000, 0x0000, 0x8F9F, + 0x99A7, 0x95E5, 0x99AB, 0x0000, 0x90A8, 0x99A8, + 0x8BCE, 0x0000, 0x99A9, 0x8AA9, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8C4D, 0x99AC, 0x0000, 0x99AD, + 0x0000, 0x0000, 0x99AE, 0x99AF, 0x8ED9, 0x0000, + 0x0000, 0x0000, 0x8CF9, 0x96DC +}; + +static u16 Ucs53[256] = { + 0x0000, 0x96E6, 0x93F5, 0x0000, 0x0000, 0x95EF, + 0x99B0, 0x0000, 0x99B1, 0x0000, 0x0000, 0x0000, + 0x0000, 0x99B3, 0x0000, 0x99B5, 0x99B4, 0x0000, + 0x0000, 0x0000, 0x0000, 0x99B6, 0x89BB, 0x966B, + 0x0000, 0x8DFA, 0x99B7, 0x0000, 0x0000, 0x9178, + 0x0000, 0x0000, 0x8FA0, 0x8BA7, 0x0000, 0x99B8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x94D9, 0x0000, 0x0000, 0x0000, 0x0000, 0x99B9, + 0x0000, 0x99BA, 0x0000, 0x99BB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x99BC, 0x9543, 0x8BE6, 0x88E3, + 0x0000, 0x0000, 0x0000, 0x93BD, 0x99BD, 0x8F5C, + 0x0000, 0x90E7, 0x0000, 0x99BF, 0x99BE, 0x8FA1, + 0x8CDF, 0x99C1, 0x94BC, 0x0000, 0x0000, 0x99C2, + 0x0000, 0x0000, 0x0000, 0x94DA, 0x91B2, 0x91EC, + 0x8BA6, 0x0000, 0x0000, 0x93EC, 0x9250, 0x0000, + 0x948E, 0x0000, 0x966D, 0x0000, 0x99C4, 0x0000, + 0x90E8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8C54, 0x0000, 0x0000, 0x99C5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x99C6, 0x894B, 0x88F3, 0x8AEB, + 0x0000, 0x91A6, 0x8B70, 0x9791, 0x0000, 0x99C9, + 0x89B5, 0x0000, 0x0000, 0x99C8, 0x0000, 0x0000, + 0x0000, 0x8BA8, 0x0000, 0x0000, 0x99CA, 0x0000, + 0x96EF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x99CB, 0x0000, 0x97D0, 0x0000, 0x8CFA, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8CB4, 0x99CC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x99CE, 0x99CD, 0x0000, + 0x907E, 0x8958, 0x0000, 0x0000, 0x0000, 0x897D, + 0x99CF, 0x0000, 0x99D0, 0x0000, 0x0000, 0x8CB5, + 0x0000, 0x0000, 0x99D1, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8B8E, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8E51, 0x99D2, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9694, 0x8DB3, 0x8B79, 0x9746, + 0x916F, 0x94BD, 0x8EFB, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8F66, 0x0000, 0x8EE6, 0x8EF3, + 0x0000, 0x8F96, 0x0000, 0x94BE, 0x0000, 0x0000, + 0x0000, 0x99D5, 0x0000, 0x8962, 0x9170, 0x8CFB, + 0x8CC3, 0x8BE5, 0x0000, 0x0000, 0x99D9, 0x9240, + 0x91FC, 0x8BA9, 0x8FA2, 0x99DA, 0x99D8, 0x89C2, + 0x91E4, 0x8EB6, 0x8E6A, 0x8945, 0x0000, 0x0000, + 0x8A90, 0x8D86, 0x8E69, 0x0000, 0x99DB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs54[256] = { + 0x0000, 0x99DC, 0x0000, 0x8B68, 0x8A65, 0x0000, + 0x0000, 0x0000, 0x8D87, 0x8B67, 0x92DD, 0x8944, + 0x93AF, 0x96BC, 0x8D40, 0x9799, 0x9366, 0x8CFC, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8C4E, 0x0000, 0x99E5, + 0x0000, 0x8BE1, 0x9669, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x94DB, 0x0000, 0x0000, 0x99E4, + 0x0000, 0x8ADC, 0x99DF, 0x99E0, 0x99E2, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x99E3, 0x0000, 0x8B7A, 0x9081, 0x0000, 0x95AB, + 0x99E1, 0x99DD, 0x8CE1, 0x0000, 0x99DE, 0x0000, + 0x9843, 0x0000, 0x0000, 0x0000, 0x95F0, 0x0000, + 0x92E6, 0x8CE0, 0x8D90, 0x0000, 0x0000, 0x0000, + 0x99E6, 0x0000, 0x0000, 0x93DB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x99EA, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8EFC, 0x0000, 0x8EF4, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x99ED, 0x99EB, + 0x0000, 0x96A1, 0x0000, 0x99E8, 0x99F1, 0x99EC, + 0x0000, 0x0000, 0x0000, 0x99EF, 0x8CC4, 0x96BD, + 0x0000, 0x0000, 0x99F0, 0x0000, 0x0000, 0x0000, + 0x99F2, 0x0000, 0x99F4, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8DEE, 0x9861, 0x0000, 0x99E9, 0x99E7, + 0x99F3, 0x0000, 0x99EE, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x99F6, 0x0000, 0x9A42, 0x99F8, 0x0000, 0x0000, + 0x99FC, 0x0000, 0x0000, 0x9A40, 0x99F9, 0x0000, + 0x0000, 0x9A5D, 0x0000, 0x0000, 0x8DE7, 0x8A50, + 0x0000, 0x0000, 0x0000, 0x0000, 0x99F7, 0x0000, + 0x0000, 0x0000, 0x9A44, 0x88F4, 0x9A43, 0x0000, + 0x88A3, 0x9569, 0x9A41, 0x0000, 0x99FA, 0x0000, + 0x0000, 0x99F5, 0x99FB, 0x8DC6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9A45, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x88F5, 0x9A4E, 0x0000, + 0x0000, 0x9A46, 0x9A47, 0x0000, 0x8FA3, 0x9689, + 0x0000, 0x0000, 0x0000, 0x9A4C, 0x9A4B, 0x0000, + 0x0000, 0x0000, 0x934E, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9A4D, 0x0000, + 0x0000, 0x9A4A, 0x0000, 0x0000 +}; + +static u16 Ucs55[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x8953, 0x0000, + 0x8DB4, 0x904F, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9A48, 0x9382, 0x0000, + 0x0000, 0x0000, 0x9A49, 0x0000, 0x88A0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9A53, 0x9742, + 0x0000, 0x8FA5, 0x0000, 0x9A59, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A58, 0x9A4F, 0x0000, 0x0000, + 0x0000, 0x0000, 0x91C1, 0x0000, 0x9A50, 0x0000, + 0x0000, 0x0000, 0x91ED, 0x9A55, 0x8FA4, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9A52, 0x0000, + 0x0000, 0x96E2, 0x0000, 0x0000, 0x0000, 0x8C5B, + 0x0000, 0x0000, 0x9A56, 0x9A57, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A54, 0x9A5A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9A51, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9A60, 0x9A65, 0x0000, + 0x9A61, 0x0000, 0x9A5C, 0x0000, 0x0000, 0x9A66, + 0x9150, 0x0000, 0x0000, 0x9A68, 0x0000, 0x8D41, + 0x9A5E, 0x929D, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A62, 0x9A5B, 0x8AAB, 0x0000, + 0x8AEC, 0x8A85, 0x9A63, 0x9A5F, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8C96, + 0x9A69, 0x9A67, 0x9172, 0x8B69, 0x8BAA, 0x0000, + 0x9A64, 0x0000, 0x8BF2, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8963, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9A6D, 0x9A6B, + 0x0000, 0x9AA5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A70, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A6A, 0x0000, 0x9A6E, 0x0000, + 0x0000, 0x9A6C, 0x0000, 0x0000, 0x0000, 0x8E6B, + 0x9A6F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9A72, 0x0000, 0x9A77, 0x0000, 0x0000, + 0x0000, 0x9A75, 0x9A74, 0x0000 +}; + +static u16 Ucs56[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9251, 0x0000, 0x0000, 0x89C3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A71, 0x0000, 0x9A73, 0x8FA6, + 0x8952, 0x0000, 0x0000, 0x9A76, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x89DC, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9A82, + 0x0000, 0x8FFA, 0x9A7D, 0x0000, 0x9A7B, 0x0000, + 0x9A7C, 0x0000, 0x9A7E, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x895C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9158, 0x0000, + 0x9A78, 0x0000, 0x9A79, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8A9A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9A81, 0x0000, + 0x0000, 0x0000, 0x8AED, 0x0000, 0x9A84, 0x9A80, + 0x9A83, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x95AC, 0x0000, 0x0000, 0x0000, + 0x93D3, 0x0000, 0x94B6, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A86, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A85, 0x8A64, 0x0000, 0x0000, + 0x9A87, 0x0000, 0x0000, 0x0000, 0x0000, 0x9A8A, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9A89, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9A88, 0x0000, + 0x9458, 0x0000, 0x0000, 0x9A8B, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9A8C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9A8E, 0x0000, 0x9A8D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A90, 0x0000, 0x0000, 0x0000, + 0x9A93, 0x9A91, 0x9A8F, 0x9A92, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A94, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9A95, 0x0000, 0x0000, 0x9A96, + 0x0000, 0x9A97, 0x0000, 0x0000, 0x0000, 0x9A98, + 0x9964, 0x0000, 0x8EFA, 0x8E6C, 0x0000, 0x0000, + 0x89F1, 0x0000, 0x88F6, 0x0000, 0x0000, 0x9263, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9A99, 0x0000, + 0x8DA2, 0x0000, 0x88CD, 0x907D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9A9A, 0x8CC5, 0x0000, + 0x0000, 0x8D91, 0x0000, 0x9A9C +}; + +static u16 Ucs57[256] = { + 0x9A9B, 0x0000, 0x0000, 0x95DE, 0x9A9D, 0x0000, + 0x0000, 0x0000, 0x9A9F, 0x9A9E, 0x0000, 0x9AA0, + 0x0000, 0x9AA1, 0x0000, 0x8C97, 0x0000, 0x0000, + 0x8980, 0x9AA2, 0x0000, 0x0000, 0x9AA4, 0x0000, + 0x9AA3, 0x0000, 0x0000, 0x0000, 0x9AA6, 0x0000, + 0x0000, 0x9379, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9AA7, 0x88B3, 0x8DDD, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8C5C, 0x0000, 0x0000, + 0x926E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9AA8, 0x9AA9, 0x0000, 0x0000, 0x9AAB, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9AAC, 0x0000, + 0x8DE2, 0x0000, 0x0000, 0x0000, 0x0000, 0x8BCF, + 0x0000, 0x0000, 0x9656, 0x0000, 0x0000, 0x0000, + 0x9AAA, 0x9AAD, 0x8DBF, 0x8D42, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9AB1, 0x0000, 0x0000, 0x8DA3, 0x0000, + 0x9252, 0x0000, 0x0000, 0x9AAE, 0x92D8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9AB2, 0x0000, 0x0000, 0x9082, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9AB0, 0x9AB3, + 0x0000, 0x8C5E, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9AB4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9AB5, 0x0000, + 0x8D43, 0x8A5F, 0x9AB7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9AB8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9AB9, 0x0000, 0x0000, 0x9AB6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9AAF, 0x0000, 0x0000, 0x9ABA, 0x0000, 0x0000, + 0x9ABB, 0x0000, 0x0000, 0x0000, 0x0000, 0x9684, + 0x0000, 0x0000, 0x8FE9, 0x0000, 0x0000, 0x0000, + 0x9ABD, 0x9ABE, 0x9ABC, 0x0000, 0x9AC0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9457, 0x0000, + 0x0000, 0x88E6, 0x9575, 0x0000, 0x0000, 0x9AC1, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8FFB, 0x0000, + 0x0000, 0x8EB7, 0x0000, 0x947C, 0x8AEE, 0x0000, + 0x8DE9, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs58[256] = { + 0x9678, 0x0000, 0x93B0, 0x0000, 0x0000, 0x8C98, + 0x91CD, 0x0000, 0x0000, 0x0000, 0x9ABF, 0x9AC2, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x91C2, 0x0000, 0x0000, + 0x0000, 0x9AC3, 0x0000, 0x0000, 0x0000, 0x9AC4, + 0x0000, 0x0000, 0x0000, 0x9AC6, 0x0000, 0x0000, + 0x92E7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8AAC, 0x0000, 0x0000, 0x0000, 0x0000, 0xEA9F, + 0x8981, 0x95F1, 0x0000, 0x0000, 0x8FEA, 0x9367, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8DE4, 0x0000, + 0x0000, 0x9ACC, 0x0000, 0x0000, 0x95BB, 0x97DB, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x89F2, 0x9AC8, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9159, 0x9ACB, 0x0000, + 0x9383, 0x0000, 0x0000, 0x9368, 0x9384, 0x94B7, + 0x92CB, 0x0000, 0x0000, 0x0000, 0x8DC7, 0x0000, + 0x0000, 0x0000, 0x9AC7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8996, 0x0000, 0x9355, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9AC9, 0x0000, + 0x9AC5, 0x0000, 0x0000, 0x906F, 0x0000, 0x0000, + 0x0000, 0x9ACD, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8F6D, 0x0000, 0x0000, 0x0000, 0x0000, 0x8BAB, + 0x0000, 0x9ACE, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x95E6, 0x0000, 0x0000, + 0x0000, 0x919D, 0x0000, 0x0000, 0x0000, 0x0000, + 0x92C4, 0x0000, 0x0000, 0x9AD0, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x966E, 0x0000, 0x0000, 0x9AD1, 0x0000, 0x0000, + 0x9AD6, 0x0000, 0x0000, 0x0000, 0x0000, 0x95AD, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9AD5, 0x9ACF, + 0x9AD2, 0x9AD4, 0x0000, 0x0000, 0x8DA4, 0x0000, + 0x0000, 0x95C7, 0x0000, 0x0000, 0x0000, 0x9AD7, + 0x0000, 0x9264, 0x0000, 0x0000, 0x89F3, 0x0000, + 0x8FEB, 0x0000, 0x0000, 0x0000, 0x0000, 0x9AD9, + 0x0000, 0x9AD8, 0x0000, 0x8D88, 0x0000, 0x9ADA, + 0x9ADC, 0x9ADB, 0x0000, 0x0000, 0x9ADE, 0x0000, + 0x9AD3, 0x9AE0, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9ADF, 0x9ADD, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8E6D, 0x9070, 0x0000, 0x9173, 0x9AE1, + 0x90BA, 0x88EB, 0x9484, 0x0000, 0x0000, 0x0000, + 0x0000, 0x92D9, 0x0000, 0x9AE3, 0x9AE2, 0x9AE4, + 0x9AE5, 0x9AE6, 0x0000, 0x0000 +}; + +static u16 Ucs59[256] = { + 0x0000, 0x0000, 0x9AE7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x95CF, 0x9AE8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x89C4, 0x9AE9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x975B, 0x8A4F, 0x0000, + 0x99C7, 0x8F67, 0x91BD, 0x9AEA, 0x96E9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x96B2, 0x0000, + 0x0000, 0x9AEC, 0x0000, 0x91E5, 0x0000, 0x9356, + 0x91BE, 0x9576, 0x9AED, 0x9AEE, 0x899B, 0x0000, + 0x0000, 0x8EB8, 0x9AEF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x88CE, 0x9AF0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9AF1, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8982, 0x0000, 0x0000, 0x8AEF, + 0x93DE, 0x95F2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9AF5, 0x9174, 0x9AF4, 0x8C5F, 0x0000, 0x0000, + 0x967A, 0x9AF3, 0x0000, 0x9385, 0x9AF7, 0x0000, + 0x9AF6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9AF9, 0x0000, 0x9AF8, 0x0000, 0x0000, 0x899C, + 0x0000, 0x9AFA, 0x8FA7, 0x9AFC, 0x9244, 0x0000, + 0x9AFB, 0x0000, 0x95B1, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8F97, 0x937A, 0x0000, 0x0000, 0x0000, + 0x9B40, 0x0000, 0x0000, 0x0000, 0x0000, 0x8D44, + 0x0000, 0x0000, 0x0000, 0x9B41, 0x9440, 0x94DC, + 0x96CF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9444, 0x0000, 0x0000, 0x9B4A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8B57, 0x0000, 0x0000, + 0x9764, 0x0000, 0x0000, 0x96AD, 0x0000, 0x9BAA, + 0x0000, 0x9B42, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9B45, 0x0000, 0x91C3, 0x0000, 0x0000, + 0x9657, 0x0000, 0x0000, 0x0000, 0x9369, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9B46, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9685, + 0x0000, 0x8DC8, 0x0000, 0x0000, 0x8FA8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9B47, 0x0000, 0x0000, 0x8E6F, 0x0000, 0x8E6E, + 0x0000, 0x0000, 0x0000, 0x0000, 0x88B7, 0x8CC6, + 0x0000, 0x90A9, 0x88CF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9B4B, 0x9B4C, 0x0000, 0x9B49, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8957, 0x8AAD, 0x0000, 0x9B48, 0x0000, + 0x96C3, 0x9550, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x88A6, 0x0000, 0x0000, 0x0000, 0x0000, 0x88F7, + 0x0000, 0x0000, 0x0000, 0x8E70 +}; + +static u16 Ucs5A[256] = { + 0x0000, 0x88D0, 0x0000, 0x88A1, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9B51, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9B4F, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x96BA, 0x0000, 0x9B52, 0x0000, 0x9B50, 0x0000, + 0x0000, 0x9B4E, 0x9050, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9B4D, 0x0000, 0x0000, 0x0000, 0x95D8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8CE2, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9B56, + 0x9B57, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8FA9, 0x0000, 0x0000, 0x0000, 0x9B53, 0x984B, + 0x0000, 0x0000, 0x0000, 0x0000, 0x946B, 0x0000, + 0x0000, 0x9B55, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8DA5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9B58, 0x0000, 0x0000, 0x0000, + 0x9577, 0x0000, 0x0000, 0x0000, 0x9B59, 0x0000, + 0x9B54, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x96B9, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x947D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9B5A, 0x9551, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9B5B, 0x9B5F, 0x9B5C, 0x0000, + 0x0000, 0x89C5, 0x9B5E, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8EB9, 0x0000, 0x9B5D, + 0x8C99, 0x0000, 0x0000, 0x0000, 0x9B6B, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9B64, 0x9B61, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9284, 0x0000, 0x9B60, + 0x0000, 0x0000, 0x9B62, 0x0000, 0x0000, 0x9B63, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9B65, 0x9B66, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs5B[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8AF0, 0x0000, 0x9B68, + 0x9B67, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9B69, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8FEC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9B6C, 0x0000, 0x92DA, 0x0000, 0x0000, 0x0000, + 0x8964, 0x0000, 0x9B6A, 0x0000, 0x0000, 0x0000, + 0x9B6D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9B6E, 0x0000, 0x9B71, 0x0000, + 0x0000, 0x9B6F, 0x0000, 0x9B70, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8E71, 0x9B72, 0x0000, 0x0000, + 0x8D45, 0x9B73, 0x0000, 0x8E9A, 0x91B6, 0x0000, + 0x9B74, 0x9B75, 0x8E79, 0x8D46, 0x0000, 0x96D0, + 0x0000, 0x0000, 0x0000, 0x8B47, 0x8CC7, 0x9B76, + 0x8A77, 0x0000, 0x0000, 0x9B77, 0x0000, 0x91B7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9B78, 0x9BA1, + 0x0000, 0x9B79, 0x0000, 0x9B7A, 0x0000, 0x0000, + 0x9B7B, 0x0000, 0x9B7D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9B7E, 0x0000, 0x0000, 0x9B80, + 0x0000, 0x91EE, 0x0000, 0x8946, 0x8EE7, 0x88C0, + 0x0000, 0x9176, 0x8AAE, 0x8EB3, 0x0000, 0x8D47, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9386, + 0x0000, 0x8F40, 0x8AAF, 0x9288, 0x92E8, 0x88B6, + 0x8B58, 0x95F3, 0x0000, 0x8EC0, 0x0000, 0x0000, + 0x8B71, 0x90E9, 0x8EBA, 0x9747, 0x9B81, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8B7B, 0x0000, 0x8DC9, 0x0000, 0x0000, 0x8A51, + 0x8983, 0x8FAA, 0x89C6, 0x0000, 0x9B82, 0x9765, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8F68, + 0x0000, 0x0000, 0x8EE2, 0x9B83, 0x8AF1, 0x93D0, + 0x96A7, 0x9B84, 0x0000, 0x9B85, 0x0000, 0x0000, + 0x9578, 0x0000, 0x0000, 0x0000, 0x9B87, 0x0000, + 0x8AA6, 0x8BF5, 0x9B86, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8AB0, 0x0000, 0x9051, + 0x9B8B, 0x8E40, 0x0000, 0x89C7, 0x9B8A, 0x0000, + 0x9B88, 0x9B8C, 0x9B89, 0x944A, 0x9ECB, 0x9052, + 0x0000, 0x9B8D, 0x0000, 0x0000, 0x97BE, 0x0000, + 0x9B8E, 0x0000, 0x0000, 0x9B90, 0x0000, 0x929E, + 0x9B8F, 0x0000, 0x90A1, 0x0000, 0x8E9B, 0x0000, + 0x0000, 0x0000, 0x91CE, 0x8EF5 +}; + +static u16 Ucs5C[256] = { + 0x0000, 0x9595, 0x90EA, 0x0000, 0x8ECB, 0x9B91, + 0x8FAB, 0x9B92, 0x9B93, 0x88D1, 0x91B8, 0x9071, + 0x0000, 0x9B94, 0x93B1, 0x8FAC, 0x0000, 0x8FAD, + 0x0000, 0x9B95, 0x0000, 0x0000, 0x90EB, 0x0000, + 0x0000, 0x0000, 0x8FAE, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9B96, 0x0000, 0x9B97, 0x0000, + 0x96DE, 0x0000, 0x0000, 0x0000, 0x9B98, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8BC4, 0x0000, 0x0000, + 0x0000, 0x8F41, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9B99, 0x9B9A, 0x8EDA, 0x904B, + 0x93F2, 0x9073, 0x94F6, 0x9441, 0x8BC7, 0x9B9B, + 0x0000, 0x0000, 0x0000, 0x8B8F, 0x9B9C, 0x0000, + 0x8BFC, 0x0000, 0x93CD, 0x89AE, 0x0000, 0x8E72, + 0x9B9D, 0x9BA0, 0x9B9F, 0x8BFB, 0x0000, 0x9B9E, + 0x0000, 0x9357, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x91AE, 0x0000, + 0x936A, 0x8EC6, 0x0000, 0x0000, 0x9177, 0x979A, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9BA2, 0x0000, 0x9BA3, 0x93D4, 0x0000, 0x8E52, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9BA5, 0x0000, + 0x0000, 0x9BA6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9BA7, 0x0000, 0x0000, 0x0000, + 0x8AF2, 0x9BA8, 0x0000, 0x0000, 0x9BA9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x89AA, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x915A, 0x8AE2, 0x0000, 0x9BAB, 0x96A6, 0x0000, + 0x0000, 0x0000, 0x0000, 0x91D0, 0x0000, 0x8A78, + 0x0000, 0x0000, 0x9BAD, 0x9BAF, 0x8ADD, 0x0000, + 0x0000, 0x9BAC, 0x9BAE, 0x0000, 0x9BB1, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9BB0, + 0x0000, 0x9BB2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9BB3, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x93BB, 0x8BAC, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x89E3, 0x9BB4, + 0x9BB9, 0x0000, 0x0000, 0x9BB7, 0x0000, 0x95F5, + 0x95F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9387, 0x0000, 0x0000, 0x0000, 0x9BB6, 0x8F73, + 0x0000, 0x9BB5, 0x0000, 0x0000 +}; + +static u16 Ucs5D[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9092, 0x0000, 0x0000, 0x0000, 0x9BBA, + 0x0000, 0x0000, 0x8DE8, 0x0000, 0x0000, 0x9BC0, + 0x0000, 0x0000, 0x9BC1, 0x9BBB, 0x8A52, 0x9BBC, + 0x9BC5, 0x9BC4, 0x9BC3, 0x9BBF, 0x0000, 0x0000, + 0x0000, 0x9BBE, 0x0000, 0x0000, 0x9BC2, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x95F6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9BC9, 0x9BC6, 0x0000, + 0x9BC8, 0x0000, 0x9792, 0x0000, 0x9BC7, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9BBD, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9093, 0x0000, 0x0000, + 0x9BCA, 0x0000, 0x0000, 0x8DB5, 0x0000, 0x0000, + 0x0000, 0x9BCB, 0x0000, 0x0000, 0x9BCC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9BCF, 0x0000, + 0x9BCE, 0x0000, 0x0000, 0x9BCD, 0x0000, 0x0000, + 0x0000, 0x9388, 0x9BB8, 0x0000, 0x0000, 0x0000, + 0x9BD5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9BD1, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9BD0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9BD2, 0x0000, + 0x9BD3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9BD6, 0x0000, 0x0000, + 0x97E4, 0x0000, 0x9BD7, 0x9BD4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9BD8, 0x0000, 0x0000, + 0x8ADE, 0x9BD9, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9BDB, 0x9BDA, 0x0000, 0x0000, 0x9BDC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9BDD, 0x0000, 0x90EC, + 0x8F42, 0x0000, 0x0000, 0x8F84, 0x0000, 0x9183, + 0x0000, 0x8D48, 0x8DB6, 0x8D49, 0x8B90, 0x0000, + 0x0000, 0x9BDE, 0x0000, 0x0000, 0x8DB7, 0x0000, + 0x0000, 0x8CC8, 0x9BDF, 0x96A4, 0x9462, 0x9BE0, + 0x0000, 0x8D4A, 0x0000, 0x0000, 0x0000, 0x8AAA, + 0x0000, 0x9246, 0x8BD0, 0x0000 +}; + +static u16 Ucs5E[256] = { + 0x0000, 0x0000, 0x8E73, 0x957A, 0x0000, 0x0000, + 0x94BF, 0x0000, 0x0000, 0x0000, 0x0000, 0x9BE1, + 0x8AF3, 0x0000, 0x0000, 0x0000, 0x0000, 0x9BE4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x929F, 0x0000, + 0x0000, 0x9BE3, 0x9BE2, 0x9BE5, 0x0000, 0x92E9, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9083, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8E74, 0x0000, 0x90C8, 0x0000, 0x91D1, + 0x8B41, 0x0000, 0x0000, 0x92A0, 0x0000, 0x0000, + 0x9BE6, 0x9BE7, 0x8FED, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9658, 0x0000, 0x0000, 0x9BEA, 0x0000, + 0x0000, 0x9BE9, 0x9BE8, 0x959D, 0x0000, 0x9BF1, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9679, 0x0000, + 0x9BEB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9BED, 0x968B, 0x0000, 0x9BEC, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9BEE, + 0x0000, 0x94A6, 0x9BEF, 0x95BC, 0x9BF0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8AB1, 0x95BD, 0x944E, 0x9BF2, 0x9BF3, 0x0000, + 0x8D4B, 0x8AB2, 0x9BF4, 0x8CB6, 0x9763, 0x9748, + 0x8AF4, 0x9BF6, 0x0000, 0x92A1, 0x0000, 0x8D4C, + 0x8FAF, 0x0000, 0x0000, 0x94DD, 0x0000, 0x0000, + 0x8FB0, 0x0000, 0x0000, 0x0000, 0x0000, 0x8F98, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x92EA, + 0x95F7, 0x9358, 0x0000, 0x0000, 0x8D4D, 0x0000, + 0x957B, 0x0000, 0x0000, 0x0000, 0x9BF7, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9378, 0x8DC0, + 0x0000, 0x0000, 0x0000, 0x8CC9, 0x0000, 0x92EB, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x88C1, 0x8F8E, 0x8D4E, 0x9766, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9BF8, 0x9BF9, 0x9470, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9BFA, 0x97F5, 0x984C, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9BFC, 0x9BFB, 0x0000, + 0x0000, 0x8A66, 0x0000, 0x0000, 0x9C40, 0x0000, + 0x0000, 0x0000, 0x9C43, 0x9C44, 0x0000, 0x9C42, + 0x0000, 0x955F, 0x8FB1, 0x9C46, 0x9C45, 0x9C41, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9C47, 0x9C48, + 0x0000, 0x0000, 0x9C49, 0x0000, 0x0000, 0x0000, + 0x9C4C, 0x9C4A, 0x0000, 0x9C4B, 0x9C4D, 0x0000, + 0x8984, 0x92EC, 0x9C4E, 0x0000, 0x8C9A, 0x89F4, + 0x9455, 0x0000, 0x9C4F, 0x93F9 +}; + +static u16 Ucs5F[256] = { + 0x0000, 0x95D9, 0x0000, 0x9C50, 0x984D, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9C51, 0x95BE, 0x9C54, + 0x989F, 0x98AF, 0x0000, 0x8EAE, 0x93F3, 0x9C55, + 0x0000, 0x8B7C, 0x92A2, 0x88F8, 0x9C56, 0x95A4, + 0x8D4F, 0x0000, 0x0000, 0x926F, 0x0000, 0x0000, + 0x0000, 0x92ED, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x96ED, 0x8CB7, 0x8CCA, 0x0000, 0x9C57, + 0x0000, 0x0000, 0x0000, 0x9C58, 0x0000, 0x9C5E, + 0x0000, 0x8EE3, 0x0000, 0x0000, 0x0000, 0x92A3, + 0x0000, 0x8BAD, 0x9C59, 0x0000, 0x0000, 0x0000, + 0x954A, 0x0000, 0x9265, 0x0000, 0x0000, 0x9C5A, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9C5B, 0x0000, 0x8BAE, 0x0000, 0x9C5C, 0x0000, + 0x9C5D, 0x0000, 0x0000, 0x9C5F, 0x0000, 0x9396, + 0x0000, 0x0000, 0x9C60, 0x9C61, 0x0000, 0x9C62, + 0x0000, 0x0000, 0x9C53, 0x9C52, 0x0000, 0x0000, + 0x0000, 0x9C63, 0x8C60, 0x0000, 0x0000, 0x0000, + 0x9546, 0x0000, 0x0000, 0x8DCA, 0x9556, 0x92A4, + 0x956A, 0x9C64, 0x0000, 0x0000, 0x8FB2, 0x8965, + 0x0000, 0x9C65, 0x0000, 0x0000, 0x0000, 0x9C66, + 0x0000, 0x96F0, 0x0000, 0x0000, 0x94DE, 0x0000, + 0x0000, 0x9C69, 0x899D, 0x90AA, 0x9C68, 0x9C67, + 0x8C61, 0x91D2, 0x0000, 0x9C6D, 0x9C6B, 0x0000, + 0x9C6A, 0x97A5, 0x8CE3, 0x0000, 0x0000, 0x0000, + 0x8F99, 0x9C6C, 0x936B, 0x8F5D, 0x0000, 0x0000, + 0x0000, 0x93BE, 0x9C70, 0x9C6F, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9C6E, 0x0000, 0x9C71, 0x8CE4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9C72, 0x959C, 0x8F7A, 0x0000, 0x0000, 0x9C73, + 0x94F7, 0x0000, 0x0000, 0x0000, 0x0000, 0x93BF, + 0x92A5, 0x0000, 0x0000, 0x0000, 0x0000, 0x934F, + 0x0000, 0x0000, 0x9C74, 0x8B4A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9053, 0x0000, 0x954B, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8AF5, 0x9445, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9C75, 0x8E75, + 0x9659, 0x965A, 0x0000, 0x0000, 0x899E, 0x9C7A, + 0x0000, 0x0000, 0x9289, 0x0000, 0x0000, 0x0000, + 0x9C77, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x89F5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9CAB, 0x9C79, 0x0000, 0x0000, 0x0000, 0x944F, + 0x0000, 0x0000, 0x9C78, 0x0000, 0x0000, 0x9C76, + 0x0000, 0x8D9A, 0x0000, 0x9C7C +}; + +static u16 Ucs60[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9C83, 0x9C89, 0x9C81, 0x0000, + 0x937B, 0x0000, 0x0000, 0x9C86, 0x957C, 0x0000, + 0x0000, 0x9C80, 0x0000, 0x9C85, 0x97E5, 0x8E76, + 0x0000, 0x0000, 0x91D3, 0x9C7D, 0x0000, 0x0000, + 0x0000, 0x8B7D, 0x9C88, 0x90AB, 0x8985, 0x9C82, + 0x89F6, 0x9C87, 0x0000, 0x0000, 0x0000, 0x8BAF, + 0x0000, 0x9C84, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9C8A, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9C8C, + 0x9C96, 0x9C94, 0x0000, 0x0000, 0x9C91, 0x0000, + 0x0000, 0x0000, 0x9C90, 0x97F6, 0x0000, 0x9C92, + 0x0000, 0x0000, 0x8BB0, 0x0000, 0x8D50, 0x0000, + 0x0000, 0x8F9A, 0x0000, 0x0000, 0x0000, 0x9C99, + 0x9C8B, 0x0000, 0x0000, 0x0000, 0x0000, 0x9C8F, + 0x9C7E, 0x0000, 0x89F8, 0x9C93, 0x9C95, 0x9270, + 0x0000, 0x0000, 0x8DA6, 0x89B6, 0x9C8D, 0x9C98, + 0x9C97, 0x8BB1, 0x0000, 0x91A7, 0x8A86, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8C62, 0x0000, 0x9C8E, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9C9A, 0x0000, 0x9C9D, + 0x9C9F, 0x0000, 0x0000, 0x0000, 0x0000, 0x8EBB, + 0x0000, 0x9CA5, 0x92EE, 0x9C9B, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9CA3, 0x0000, 0x89F7, 0x0000, + 0x9CA1, 0x9CA2, 0x0000, 0x0000, 0x9C9E, 0x9CA0, + 0x0000, 0x0000, 0x0000, 0x8CE5, 0x9749, 0x0000, + 0x0000, 0x8AB3, 0x0000, 0x0000, 0x8978, 0x9CA4, + 0x0000, 0x9459, 0x88AB, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x94DF, 0x9C7B, + 0x9CAA, 0x9CAE, 0x96E3, 0x0000, 0x9CA7, 0x0000, + 0x0000, 0x0000, 0x9389, 0x9CAC, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8FEE, + 0x9CAD, 0x93D5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9866, + 0x0000, 0x9CA9, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9CAF, 0x0000, 0x8D9B, 0x0000, 0x90C9, 0x0000, + 0x0000, 0x88D2, 0x9CA8, 0x9CA6, 0x0000, 0x9179, + 0x0000, 0x0000, 0x0000, 0x9C9C, 0x8E53, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x91C4, 0x9CBB, 0x0000, 0x917A, 0x9CB6, 0x0000, + 0x9CB3, 0x9CB4, 0x0000, 0x8EE4, 0x9CB7, 0x9CBA, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs61[256] = { + 0x9CB5, 0x8F44, 0x0000, 0x9CB8, 0x0000, 0x0000, + 0x9CB2, 0x0000, 0x96FA, 0x96F9, 0x0000, 0x0000, + 0x0000, 0x9CBC, 0x9CBD, 0x88D3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9CB1, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8BF0, 0x88A4, 0x0000, 0x0000, + 0x0000, 0x8AB4, 0x0000, 0x9CB9, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9CC1, 0x9CC0, 0x0000, + 0x0000, 0x0000, 0x9CC5, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9CC6, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9CC4, 0x9CC7, 0x9CBF, 0x9CC3, 0x0000, 0x0000, + 0x9CC8, 0x0000, 0x9CC9, 0x0000, 0x0000, 0x9CBE, + 0x8E9C, 0x0000, 0x9CC2, 0x91D4, 0x8D51, 0x9CB0, + 0x9054, 0x0000, 0x0000, 0x0000, 0x0000, 0x9CD6, + 0x0000, 0x95E7, 0x0000, 0x0000, 0x9CCC, 0x9CCD, + 0x9CCE, 0x0000, 0x0000, 0x9CD5, 0x0000, 0x9CD4, + 0x0000, 0x0000, 0x969D, 0x8AB5, 0x0000, 0x9CD2, + 0x0000, 0x8C64, 0x8A53, 0x0000, 0x0000, 0x9CCF, + 0x0000, 0x0000, 0x97B6, 0x9CD1, 0x88D4, 0x9CD3, + 0x0000, 0x9CCA, 0x9CD0, 0x9CD7, 0x8C63, 0x9CCB, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x977C, 0x0000, 0x0000, 0x0000, 0x974A, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9CDA, 0x0000, 0x0000, + 0x9CDE, 0x0000, 0x0000, 0x0000, 0x919E, 0x0000, + 0x97F7, 0x9CDF, 0x0000, 0x0000, 0x9CDC, 0x0000, + 0x9CD9, 0x0000, 0x0000, 0x9CD8, 0x9CDD, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x95AE, 0x0000, 0x0000, 0x93B2, + 0x0000, 0x8C65, 0x0000, 0x9CE0, 0x9CDB, 0x0000, + 0x9CE1, 0x0000, 0x0000, 0x0000, 0x8C9B, 0x0000, + 0x0000, 0x0000, 0x89AF, 0x0000, 0x0000, 0x0000, + 0x9CE9, 0x0000, 0x0000, 0x0000, 0x8AB6, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9CE7, 0x0000, 0x0000, + 0x9CE8, 0x8DA7, 0x9CE6, 0x9CE4, 0x9CE3, 0x9CEA, + 0x9CE2, 0x9CEC, 0x0000, 0x0000, 0x89F9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9CEE, + 0x0000, 0x0000, 0x9CED, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x92A6, 0x0000, 0x9CF1, 0x0000, + 0x9CEF, 0x9CE5, 0x8C9C, 0x0000, 0x9CF0, 0x0000, + 0x9CF4, 0x9CF3, 0x9CF5, 0x9CF2 +}; + +static u16 Ucs62[256] = { + 0x9CF6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9CF7, 0x9CF8, 0x95E8, 0x0000, + 0x9CFA, 0x9CF9, 0x8F5E, 0x0000, 0x90AC, 0x89E4, + 0x89FA, 0x0000, 0x9CFB, 0x0000, 0x88BD, 0x0000, + 0x0000, 0x0000, 0x90CA, 0x9CFC, 0x0000, 0xE6C1, + 0x9D40, 0x8C81, 0x0000, 0x9D41, 0x0000, 0x0000, + 0x0000, 0x0000, 0x90ED, 0x0000, 0x0000, 0x0000, + 0x9D42, 0x0000, 0x0000, 0x0000, 0x9D43, 0x8B59, + 0x9D44, 0x0000, 0x9D45, 0x9D46, 0x91D5, 0x0000, + 0x0000, 0x0000, 0x8CCB, 0x0000, 0x0000, 0x96DF, + 0x0000, 0x0000, 0x0000, 0x965B, 0x8F8A, 0x9D47, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x90EE, + 0xE7BB, 0x94E0, 0x0000, 0x8EE8, 0x0000, 0x8DCB, + 0x9D48, 0x0000, 0x0000, 0x0000, 0x0000, 0x91C5, + 0x0000, 0x95A5, 0x0000, 0x0000, 0x91EF, 0x0000, + 0x0000, 0x9D4B, 0x0000, 0x0000, 0x9D49, 0x0000, + 0x9D4C, 0x0000, 0x0000, 0x9D4A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9D4D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x95AF, 0x0000, 0x0000, 0x88B5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x957D, 0x0000, + 0x0000, 0x94E1, 0x0000, 0x0000, 0x9D4E, 0x0000, + 0x9D51, 0x8FB3, 0x8B5A, 0x0000, 0x9D4F, 0x9D56, + 0x8FB4, 0x0000, 0x0000, 0x0000, 0x0000, 0x9D50, + 0x9463, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x977D, 0x9D52, 0x9D53, 0x9D57, 0x938A, + 0x9D54, 0x8D52, 0x90DC, 0x0000, 0x0000, 0x9D65, + 0x94B2, 0x0000, 0x91F0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x94E2, 0x9DAB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x95F8, 0x0000, 0x0000, + 0x0000, 0x92EF, 0x0000, 0x0000, 0x0000, 0x9695, + 0x0000, 0x9D5A, 0x899F, 0x928A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9D63, 0x0000, 0x0000, 0x9253, + 0x9D5D, 0x9D64, 0x9D5F, 0x9D66, 0x9D62, 0x0000, + 0x9D61, 0x948F, 0x0000, 0x9D5B, 0x89FB, 0x9D59, + 0x8B91, 0x91F1, 0x9D55, 0x0000, 0x0000, 0x9D58, + 0x8D53, 0x90D9, 0x0000, 0x8FB5, 0x9D60, 0x9471, + 0x0000, 0x0000, 0x8B92, 0x8A67, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8A87, 0x9040, 0x9D68, 0x9D6D, + 0x0000, 0x9D69, 0x0000, 0x8C9D, 0x0000, 0x9D6E, + 0x8E41, 0x8D89, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8F45, 0x9D5C +}; + +static u16 Ucs63[256] = { + 0x0000, 0x8E9D, 0x9D6B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8E77, 0x9D6C, 0x88C2, 0x0000, 0x0000, + 0x9D67, 0x0000, 0x0000, 0x0000, 0x0000, 0x92A7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8B93, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8BB2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9D6A, 0x88A5, 0x0000, + 0x0000, 0x8DC1, 0x0000, 0x0000, 0x0000, 0x9055, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x92F0, 0x0000, + 0x0000, 0x94D2, 0x9D70, 0x917D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x91A8, 0x0000, 0x0000, 0x8E4A, 0x9D71, + 0x0000, 0x9D73, 0x9D6F, 0x0000, 0x0000, 0x0000, + 0x0000, 0x95DF, 0x0000, 0x92BB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x917B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x95F9, 0x8ECC, 0x9D80, 0x0000, 0x9D7E, + 0x0000, 0x0000, 0x9098, 0x0000, 0x0000, 0x0000, + 0x8C9E, 0x0000, 0x0000, 0x0000, 0x9D78, 0x8FB7, + 0x0000, 0x0000, 0x93E6, 0x9450, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9D76, 0x0000, 0x0000, 0x917C, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8EF6, 0x9D7B, + 0x0000, 0x0000, 0x8FB6, 0x0000, 0x9D75, 0x9D7A, + 0x0000, 0x0000, 0x9472, 0x0000, 0x0000, 0x0000, + 0x9D74, 0x0000, 0x8C40, 0x0000, 0x0000, 0x8A7C, + 0x0000, 0x0000, 0x0000, 0x9D7C, 0x97A9, 0x8DCC, + 0x9254, 0x9D79, 0x0000, 0x90DA, 0x0000, 0x8D54, + 0x9084, 0x8986, 0x915B, 0x9D77, 0x8B64, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8C66, 0x0000, + 0x92CD, 0x9D7D, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x917E, 0x0000, 0x0000, 0x9D81, 0x0000, + 0x9D83, 0x0000, 0x0000, 0x91B5, 0x9D89, 0x0000, + 0x9D84, 0x0000, 0x0000, 0x9D86, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9560, 0x92F1, 0x0000, + 0x9D87, 0x0000, 0x0000, 0x0000, 0x974B, 0x0000, + 0x0000, 0x0000, 0x9767, 0x8AB7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x88AC, 0x0000, 0x9D85, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9D82, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8AF6, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8987, 0x0000, + 0x9D88, 0x0000, 0x0000, 0x0000, 0x9768, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs64[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9D8C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x91B9, 0x0000, 0x9D93, 0x0000, 0x0000, + 0x0000, 0x9D8D, 0x0000, 0x0000, 0x9D8A, 0x9D91, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9D72, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9D8E, 0x0000, 0x9D92, 0x0000, + 0x0000, 0x0000, 0x94C0, 0x938B, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9D8B, 0x0000, + 0x9D8F, 0x0000, 0x0000, 0x0000, 0x8C67, 0x0000, + 0x0000, 0x0000, 0x8DEF, 0x0000, 0x0000, 0x0000, + 0x90DB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9D97, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9345, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9D94, 0x0000, 0x9680, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9D95, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9D96, 0x0000, + 0x96CC, 0x0000, 0x90A0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8C82, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9D9D, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8E54, 0x9D9A, 0x0000, 0x9D99, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9451, 0x0000, + 0x0000, 0x0000, 0x93B3, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9350, 0x9D9B, 0x0000, 0x0000, + 0x0000, 0x9D9C, 0x0000, 0x958F, 0x0000, 0x9464, + 0x8E42, 0x0000, 0x90EF, 0x0000, 0x966F, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8A68, + 0x0000, 0x9DA3, 0x9D9E, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9769, 0x9DA5, 0x0000, 0x0000, 0x9DA1, + 0x0000, 0x9DA2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9180, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9DA0, 0x0000, 0x9D5E, 0x0000, 0x0000, 0x0000, + 0x9DA4, 0x0000, 0x9D9F, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9DA9, 0x9DAA, 0x9346, 0x9DAC, + 0x0000, 0x0000, 0x8E43, 0x9DA7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8B5B, 0x0000, 0x0000, 0x9DAD, + 0x0000, 0x9DA6, 0x9DB1, 0x0000, 0x9DB0, 0x0000, + 0x9DAF, 0x0000, 0x0000, 0x0000, 0x9DB2, 0x0000, + 0x0000, 0x9DB4, 0x8FEF, 0x0000 +}; + +static u16 Ucs65[256] = { + 0x9DB3, 0x0000, 0x0000, 0x0000, 0x0000, 0x9DB7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9DB5, 0x0000, 0x0000, 0x0000, 0x9DB6, 0x9D90, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9DB9, + 0x9DB8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9D98, 0x9DBA, 0x9DAE, 0x0000, 0x0000, 0x8E78, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9DBB, 0x9DBC, + 0x9DBE, 0x9DBD, 0x9DBF, 0x89FC, 0x0000, 0x8D55, + 0x0000, 0x0000, 0x95FA, 0x90AD, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8CCC, 0x0000, 0x0000, + 0x9DC1, 0x0000, 0x0000, 0x0000, 0x0000, 0x9DC4, + 0x0000, 0x9571, 0x0000, 0x8B7E, 0x0000, 0x0000, + 0x0000, 0x9DC3, 0x9DC2, 0x9473, 0x9DC5, 0x8BB3, + 0x0000, 0x0000, 0x0000, 0x9DC7, 0x9DC6, 0x0000, + 0x0000, 0x0000, 0x8AB8, 0x8E55, 0x0000, 0x0000, + 0x93D6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8C68, 0x0000, 0x0000, 0x0000, 0x9094, 0x0000, + 0x9DC8, 0x0000, 0x90AE, 0x9347, 0x0000, 0x957E, + 0x9DC9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9DCA, 0x9DCB, + 0x0000, 0x0000, 0x0000, 0x95B6, 0x9B7C, 0x90C4, + 0x0000, 0x0000, 0x956B, 0x0000, 0x8DD6, 0x0000, + 0x94E3, 0x94C1, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x936C, 0x0000, 0x97BF, 0x0000, 0x9DCD, + 0x8ECE, 0x0000, 0x0000, 0x9DCE, 0x0000, 0x88B4, + 0x0000, 0x0000, 0x8BD2, 0x90CB, 0x0000, 0x9580, + 0x0000, 0x0000, 0x0000, 0x9DCF, 0x8E61, 0x9266, + 0x0000, 0x8E7A, 0x9056, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9DD0, 0x0000, 0x95FB, + 0x0000, 0x0000, 0x8997, 0x8E7B, 0x0000, 0x0000, + 0x0000, 0x9DD3, 0x0000, 0x9DD1, 0x9DD4, 0x97B7, + 0x9DD2, 0x0000, 0x0000, 0x0000, 0x0000, 0x90F9, + 0x9DD5, 0x0000, 0x0000, 0x91B0, 0x0000, 0x0000, + 0x9DD6, 0x0000, 0x0000, 0x0000, 0x0000, 0x8AF8, + 0x0000, 0x9DD8, 0x0000, 0x9DD7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9DD9, 0x9DDA, 0x8AF9, 0x0000, + 0x0000, 0x93FA, 0x9255, 0x8B8C, 0x8E7C, 0x9181, + 0x0000, 0x0000, 0x8F7B, 0x88AE, 0x0000, 0x0000, + 0x0000, 0x9DDB, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x89A0, 0x9DDF, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs66[256] = { + 0x0000, 0x0000, 0x8D56, 0x9DDE, 0x0000, 0x0000, + 0x8DA9, 0x8FB8, 0x0000, 0x0000, 0x9DDD, 0x0000, + 0x8FB9, 0x0000, 0x96BE, 0x8DA8, 0x0000, 0x0000, + 0x0000, 0x88D5, 0x90CC, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9DE4, 0x0000, + 0x0000, 0x90AF, 0x8966, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8F74, 0x0000, 0x9686, 0x8DF0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8FBA, 0x0000, 0x90A5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9DE3, 0x9DE1, + 0x9DE2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x928B, 0x0000, 0x0000, 0x9E45, 0x0000, 0x9DE8, + 0x8E9E, 0x8D57, 0x9DE6, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9DE7, 0x0000, 0x9057, 0x0000, 0x0000, + 0x0000, 0x9DE5, 0x0000, 0x0000, 0x8E4E, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9DEA, 0x9DE9, 0x9DEE, + 0x0000, 0x0000, 0x9DEF, 0x0000, 0x9DEB, 0x0000, + 0x8A41, 0x9DEC, 0x9DED, 0x94D3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9581, 0x8C69, 0x9DF0, 0x0000, + 0x0000, 0x0000, 0x90B0, 0x0000, 0x8FBB, 0x0000, + 0x0000, 0x0000, 0x9271, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8BC5, 0x0000, 0x9DF1, + 0x9DF5, 0x0000, 0x0000, 0x89C9, 0x9DF2, 0x9DF4, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9DF3, 0x0000, + 0x0000, 0x8F8B, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9267, 0x88C3, 0x9DF6, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9DF7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x92A8, 0x0000, 0x0000, 0x0000, 0x97EF, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8E62, 0x0000, 0x0000, + 0x95E9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x965C, 0x0000, 0x0000, 0x0000, 0x9E41, 0x9DF9, + 0x0000, 0x0000, 0x9DFC, 0x0000, 0x9DFB, 0x0000, + 0x0000, 0x9DF8, 0x0000, 0x0000, 0x9E40, 0x0000, + 0x0000, 0x93DC, 0x0000, 0x9DFA, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9E42, 0x0000, + 0x0000, 0x8F8C, 0x9E43, 0x0000, 0x976A, 0x9498, + 0x0000, 0x0000, 0x9E44, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9E46, 0x0000, 0x0000, 0x9E47, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9E48, 0x0000, 0x8BC8, 0x8967, 0x8D58, 0x9E49, + 0x0000, 0x9E4A, 0x8F91, 0x9182, 0x0000, 0x0000, + 0x99D6, 0x915D, 0x915C, 0x91D6 +}; + +static u16 Ucs67[256] = { + 0x8DC5, 0x0000, 0x0000, 0x98F0, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8C8E, 0x974C, 0x0000, 0x95FC, + 0x0000, 0x959E, 0x0000, 0x9E4B, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8DF1, 0x92BD, 0x9E4C, 0x984E, + 0x0000, 0x0000, 0x0000, 0x965D, 0x0000, 0x92A9, + 0x9E4D, 0x8AFA, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9E4E, 0x9E4F, 0x96D8, 0x0000, + 0x96A2, 0x9696, 0x967B, 0x8E44, 0x9E51, 0x0000, + 0x0000, 0x8EE9, 0x0000, 0x0000, 0x9670, 0x0000, + 0x9E53, 0x9E56, 0x9E55, 0x0000, 0x8AF7, 0x0000, + 0x0000, 0x8B80, 0x0000, 0x9E52, 0x0000, 0x9E54, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9E57, 0x0000, + 0x0000, 0x9099, 0x0000, 0x0000, 0x0000, 0x0000, + 0x979B, 0x88C7, 0x8DDE, 0x91BA, 0x0000, 0x8EDB, + 0x0000, 0x0000, 0x8FF1, 0x0000, 0x0000, 0x9E5A, + 0x0000, 0x0000, 0x936D, 0x0000, 0x9E58, 0x91A9, + 0x9E59, 0x8FF0, 0x96DB, 0x9E5B, 0x9E5C, 0x9788, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9E61, 0x0000, + 0x0000, 0x8D59, 0x0000, 0x9474, 0x9E5E, 0x938C, + 0x9DDC, 0x9DE0, 0x0000, 0x8B6E, 0x0000, 0x9466, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9E60, 0x0000, + 0x8FBC, 0x94C2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9E66, 0x0000, 0x94F8, 0x0000, 0x9E5D, + 0x0000, 0x9E63, 0x9E62, 0x0000, 0x0000, 0x0000, + 0x90CD, 0x0000, 0x0000, 0x0000, 0x0000, 0x968D, + 0x0000, 0x97D1, 0x0000, 0x0000, 0x9687, 0x0000, + 0x89CA, 0x8E7D, 0x0000, 0x0000, 0x9867, 0x9E65, + 0x9095, 0x0000, 0x0000, 0x0000, 0x9E64, 0x0000, + 0x0000, 0x9E5F, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8CCD, 0x0000, 0x0000, 0x0000, 0x9E6B, + 0x9E69, 0x0000, 0x89CB, 0x9E67, 0x9E6D, 0x9E73, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x91C6, 0x0000, 0x0000, 0x95BF, 0x0000, + 0x9E75, 0x0000, 0x0000, 0x0000, 0x9541, 0x0000, + 0x0000, 0x0000, 0x9E74, 0x9490, 0x965E, 0x8AB9, + 0x0000, 0x90F5, 0x8F5F, 0x0000, 0x0000, 0x0000, + 0x92D1, 0x0000, 0x974D, 0x0000, 0x0000, 0x9E70, + 0x9E6F, 0x0000, 0x0000, 0x0000, 0x9E71, 0x0000, + 0x9E6E, 0x0000, 0x0000, 0x9E76, 0x0000, 0x9E6C, + 0x0000, 0x0000, 0x9E6A, 0x0000, 0x9E72, 0x9E68, + 0x0000, 0x928C, 0x0000, 0x96F6, 0x8EC4, 0x8DF2, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8DB8, + 0x0000, 0x0000, 0x968F, 0x8A60 +}; + +static u16 Ucs68[256] = { + 0x0000, 0x0000, 0x92CC, 0x93C8, 0x8968, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x90F0, 0x0000, 0x0000, 0x90B2, 0x8C49, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9E78, 0x0000, 0x0000, 0x8D5A, 0x8A9C, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9E7A, + 0x8A94, 0x9E81, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9E7D, 0x0000, 0x90F1, 0x0000, + 0x0000, 0x0000, 0x8A6A, 0x8DAA, 0x0000, 0x0000, + 0x8A69, 0x8DCD, 0x0000, 0x0000, 0x9E7B, 0x8C85, + 0x8C6A, 0x938D, 0x0000, 0x0000, 0x9E79, 0x0000, + 0x88C4, 0x0000, 0x0000, 0x0000, 0x0000, 0x9E7C, + 0x9E7E, 0x0000, 0x8BCB, 0x8C4B, 0x0000, 0x8ABA, + 0x8B6A, 0x0000, 0x0000, 0x0000, 0x0000, 0x9E82, + 0x0000, 0x0000, 0x8DF7, 0x9691, 0x0000, 0x8E56, + 0x0000, 0x0000, 0x0000, 0x9E83, 0x0000, 0x0000, + 0x0000, 0x954F, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9E8F, 0x0000, 0x89B1, 0x9E84, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9E95, 0x9E85, 0x0000, 0x97C0, 0x0000, 0x9E8C, + 0x0000, 0x947E, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9E94, 0x0000, 0x9E87, + 0x0000, 0x0000, 0x0000, 0x88B2, 0x9E89, 0x0000, + 0x0000, 0x8D5B, 0x0000, 0x0000, 0x0000, 0x9E8B, + 0x0000, 0x9E8A, 0x0000, 0x9E86, 0x9E91, 0x0000, + 0x8FBD, 0x0000, 0x0000, 0x0000, 0x9AEB, 0x8CE6, + 0x979C, 0x0000, 0x0000, 0x0000, 0x0000, 0x9E88, + 0x0000, 0x92F2, 0x8A42, 0x8DAB, 0x0000, 0x9E80, + 0x0000, 0x9E90, 0x8A81, 0x0000, 0x0000, 0x9E8E, + 0x9E92, 0x0000, 0x938E, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8AFC, 0x0000, + 0x9EB0, 0x0000, 0x0000, 0x96C7, 0x9E97, 0x8AFB, + 0x0000, 0x9E9E, 0x0000, 0x0000, 0x0000, 0x0000, + 0x965F, 0x0000, 0x9E9F, 0x9EA1, 0x0000, 0x9EA5, + 0x9E99, 0x0000, 0x9249, 0x0000, 0x0000, 0x0000, + 0x0000, 0x938F, 0x9EA9, 0x9E9C, 0x0000, 0x9EA6, + 0x0000, 0x0000, 0x0000, 0x9EA0, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9058, 0x9EAA, + 0x0000, 0x0000, 0x90B1, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9EA8, 0x8ABB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs69[256] = { + 0x986F, 0x9E96, 0x0000, 0x0000, 0x9EA4, 0x88D6, + 0x0000, 0x0000, 0x9E98, 0x0000, 0x0000, 0x96B8, + 0x9E9D, 0x9041, 0x92C5, 0x9E93, 0x0000, 0x0000, + 0x9EA3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x909A, 0x9EAD, 0x8A91, 0x8C9F, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9EAF, 0x9E9A, 0x9EAE, + 0x0000, 0x9EA7, 0x9E9B, 0x0000, 0x9EAB, 0x0000, + 0x9EAC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9EBD, 0x0000, 0x0000, 0x0000, 0x93CC, 0x0000, + 0x9EA2, 0x0000, 0x0000, 0x9EB9, 0x0000, 0x0000, + 0x0000, 0x9EBB, 0x0000, 0x92D6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x976B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9596, + 0x9EB6, 0x91C8, 0x0000, 0x0000, 0x0000, 0x9EBC, + 0x915E, 0x0000, 0x9EB3, 0x9EC0, 0x9EBF, 0x0000, + 0x93ED, 0x9EBE, 0x93E8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9EC2, 0x9EB5, + 0x0000, 0x8BC6, 0x9EB8, 0x8F7C, 0x0000, 0x0000, + 0x0000, 0x9480, 0x9EBA, 0x8BC9, 0x0000, 0x9EB2, + 0x9EB4, 0x9EB1, 0x0000, 0x0000, 0x984F, 0x8A79, + 0x9EB7, 0x0000, 0x0000, 0x9EC1, 0x8A54, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8DE5, 0x0000, 0x0000, 0x0000, 0x897C, 0x0000, + 0x0000, 0x9ED2, 0x0000, 0x0000, 0x9850, 0x9ED5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9059, + 0x9ED4, 0x0000, 0x0000, 0x0000, 0x9ED3, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9ED0, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9EC4, 0x0000, 0x0000, 0x9EE1, 0x9EC3, 0x0000, + 0x9ED6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9ECE, 0x0000, 0x0000, 0x9EC9, 0x9EC6, + 0x0000, 0x9EC7, 0x0000, 0x9ECF, 0x0000, 0x0000, + 0x0000, 0xEAA0, 0x0000, 0x0000, 0x9ECC, 0x8D5C, + 0x92C6, 0x9184, 0x9ECA, 0x0000, 0x9EC5, 0x0000, + 0x0000, 0x9EC8, 0x0000, 0x0000, 0x0000, 0x0000, + 0x976C, 0x968A, 0x0000, 0x0000, 0x0000, 0x9ECD, + 0x9ED7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9EDF, 0x9ED8, 0x0000, + 0x0000, 0x9EE5, 0x0000, 0x9EE3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9EDE, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9EDD, 0x0000, 0x92CE, + 0x0000, 0x9185, 0x0000, 0x9EDB +}; + +static u16 Ucs6A[256] = { + 0x0000, 0x0000, 0x9ED9, 0x0000, 0x0000, 0x9EE0, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9EE6, 0x94F3, + 0x9EEC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9EE7, 0x9EEA, 0x9EE4, 0x0000, 0x0000, 0x9294, + 0x0000, 0x9557, 0x0000, 0x9EDA, 0x0000, 0x0000, + 0x9EE2, 0x8FBE, 0x0000, 0x96CD, 0x9EF6, 0x9EE9, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8CA0, + 0x89A1, 0x8A7E, 0x0000, 0x0000, 0x9ED1, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8FBF, + 0x9EEE, 0x0000, 0x9EF5, 0x8EF7, 0x8A92, 0x0000, + 0x0000, 0x924D, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9EEB, 0x0000, 0x0000, 0x9EF0, + 0x9EF4, 0x0000, 0x0000, 0x8BB4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8B6B, 0x9EF2, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8B40, + 0x0000, 0x93C9, 0x9EF1, 0x0000, 0x0000, 0x0000, + 0x9EF3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9EED, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9EEF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8A80, 0x9268, 0x0000, 0x0000, 0x0000, + 0x9EFA, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9EF8, 0x8CE7, 0x0000, + 0x9EF7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9F40, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9E77, 0x0000, 0x0000, 0x0000, 0x9EF9, 0x0000, + 0x9EFB, 0x9EFC, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9F4B, 0x0000, 0x9F47, 0x0000, + 0x9E8D, 0x0000, 0x0000, 0x0000, 0x0000, 0x9F46, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9F45, 0x0000, + 0x0000, 0x9F42, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9EE8, 0x9F44, 0x9F43, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9F49, + 0x0000, 0x9845, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9F4C, 0x8BF9, 0x0000, 0x0000, + 0x9F48, 0x9F4A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x94A5, 0x0000, + 0x9F4D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9F51, 0x9F4E, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs6B[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x9793, 0x9F4F, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9EDC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9F52, 0x0000, 0x0000, 0x0000, 0x9F53, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8954, + 0x0000, 0x9F55, 0x8C87, 0x8E9F, 0x0000, 0x8BD3, + 0x0000, 0x0000, 0x0000, 0x89A2, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x977E, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9F57, 0x9F56, 0x9F59, 0x8B5C, 0x0000, + 0x0000, 0x8BD4, 0x8ABC, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9F5C, 0x0000, 0x0000, 0x0000, 0x9F5B, + 0x0000, 0x9F5D, 0x0000, 0x0000, 0x89CC, 0x0000, + 0x9256, 0x0000, 0x9F5E, 0x0000, 0x0000, 0x8ABD, + 0x9F60, 0x0000, 0x0000, 0x0000, 0x0000, 0x9F5F, + 0x0000, 0x9F61, 0x0000, 0x0000, 0x0000, 0x9F62, + 0x0000, 0x9F63, 0x8E7E, 0x90B3, 0x8D9F, 0x0000, + 0x9590, 0x0000, 0x0000, 0x95E0, 0x9863, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8E95, 0x0000, 0x0000, + 0x0000, 0x8DCE, 0x97F0, 0x0000, 0x0000, 0x0000, + 0x9F64, 0x9F65, 0x0000, 0x8E80, 0x0000, 0x0000, + 0x0000, 0x9F66, 0x9F67, 0x0000, 0x0000, 0x9F69, + 0x9F68, 0x0000, 0x9677, 0x0000, 0x0000, 0x8F7D, + 0x8EEA, 0x8E63, 0x0000, 0x9F6A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9F6C, + 0x9042, 0x0000, 0x9F6B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9F6D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9F6E, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9F6F, 0x9F70, 0x0000, 0x0000, + 0x0000, 0x9F71, 0x0000, 0x9F73, 0x9F72, 0x9F74, + 0x89A3, 0x9269, 0x0000, 0x9F75, 0x0000, 0x0000, + 0x8E45, 0x8A6B, 0x9F76, 0x0000, 0x0000, 0x9361, + 0x9ACA, 0x0000, 0x0000, 0x0000, 0x0000, 0x8B42, + 0x9F77, 0x0000, 0x0000, 0x0000, 0x0000, 0x9F78, + 0x0000, 0x95EA, 0x9688, 0x0000, 0x0000, 0x0000, + 0x93C5, 0x9F79, 0x94E4, 0x0000, 0x0000, 0x0000, + 0x94F9, 0x0000, 0x0000, 0x96D1, 0x0000, 0x0000, + 0x0000, 0x9F7A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9F7C, 0x9F7B, 0x0000, 0x0000, 0x9F7E, + 0x0000, 0x0000, 0x0000, 0x9F7D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs6C[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9F81, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8E81, 0x0000, 0x96AF, + 0x0000, 0x9F82, 0x9F83, 0x0000, 0x0000, 0x8B43, + 0x0000, 0x0000, 0x0000, 0x9F84, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9F86, + 0x9F85, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9085, 0x0000, + 0x0000, 0x9558, 0x8969, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x94C3, 0x0000, 0x92F3, 0x8F60, + 0x8B81, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x94C4, 0x0000, 0x8EAC, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9F88, 0x0000, 0x8ABE, 0x0000, 0x0000, + 0x8998, 0x0000, 0x0000, 0x93F0, 0x9F87, 0x8D5D, + 0x9272, 0x0000, 0x9F89, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9F91, 0x0000, 0x9F8A, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x91BF, 0x0000, + 0x8B82, 0x9F92, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8C88, 0x0000, 0x0000, 0x8B44, + 0x9F90, 0x0000, 0x0000, 0x9F8E, 0x9F8B, 0x9780, + 0x0000, 0x0000, 0x0000, 0x0000, 0x92BE, 0x0000, + 0x0000, 0x0000, 0x93D7, 0x9F8C, 0x0000, 0x0000, + 0x9F94, 0x0000, 0x9F93, 0x8C42, 0x0000, 0x0000, + 0x89AB, 0x0000, 0x0000, 0x8DB9, 0x9F8D, 0x9F8F, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9676, + 0x91F2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9697, 0x0000, 0x0000, + 0x9F9C, 0x0000, 0x0000, 0x9F9D, 0x0000, 0x89CD, + 0x0000, 0x0000, 0x0000, 0x0000, 0x95A6, 0x96FB, + 0x9F9F, 0x8EA1, 0x8FC0, 0x9F98, 0x9F9E, 0x8988, + 0x0000, 0x8BB5, 0x0000, 0x0000, 0x9F95, 0x9F9A, + 0x0000, 0x0000, 0x0000, 0x90F2, 0x9491, 0x0000, + 0x94E5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9F97, 0x0000, 0x9640, 0x0000, 0x9F99, + 0x0000, 0x9FA2, 0x0000, 0x9FA0, 0x0000, 0x9F9B, + 0x0000, 0x0000, 0x0000, 0x9641, 0x9467, 0x8B83, + 0x0000, 0x9344, 0x0000, 0x0000, 0x928D, 0x0000, + 0x9FA3, 0x0000, 0x0000, 0x0000, 0x0000, 0x9FA1, + 0x91D7, 0x9F96, 0x0000, 0x896A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs6D[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x976D, + 0x9FAE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9FAD, 0x0000, 0x0000, 0x0000, 0x0000, 0x90F4, + 0x0000, 0x9FAA, 0x0000, 0x978C, 0x0000, 0x0000, + 0x93B4, 0x9FA4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x92C3, 0x0000, 0x0000, 0x0000, 0x896B, + 0x8D5E, 0x9FA7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8F46, 0x9FAC, 0x0000, 0x9FAB, + 0x9FA6, 0x0000, 0x9FA9, 0x0000, 0x0000, 0x8A88, + 0x0000, 0x9FA8, 0x9468, 0x0000, 0x0000, 0x97AC, + 0x0000, 0x0000, 0x8FF2, 0x90F3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9FB4, + 0x9FB2, 0x0000, 0x956C, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9FAF, 0x9FB1, 0x0000, + 0x8959, 0x0000, 0x0000, 0x8D5F, 0x9851, 0x0000, + 0x8A5C, 0x0000, 0x9582, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9781, 0x0000, 0x0000, 0x8A43, + 0x905A, 0x9FB3, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9FB8, 0x0000, 0x0000, 0x8FC1, 0x0000, + 0x0000, 0x0000, 0x974F, 0x0000, 0x9FB5, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9FB0, 0x0000, 0x9FB6, + 0x0000, 0x0000, 0x0000, 0x97DC, 0x0000, 0x9393, + 0x93C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8A55, 0x0000, 0x0000, 0x8974, 0x0000, + 0x0000, 0x9FBC, 0x0000, 0x0000, 0x9FBF, 0x0000, + 0x0000, 0x0000, 0x97C1, 0x0000, 0x0000, 0x0000, + 0x9784, 0x0000, 0x0000, 0x0000, 0x0000, 0x9FC6, + 0x9FC0, 0x9FBD, 0x0000, 0x0000, 0x0000, 0x97D2, + 0x9FC3, 0x0000, 0x0000, 0x0000, 0x0000, 0x8F69, + 0x9FC5, 0x0000, 0x0000, 0x9FCA, 0x0000, 0x0000, + 0x9391, 0x9FC8, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9FC2, 0x0000, 0x0000, 0x9257, 0x0000, 0x0000, + 0x9FC9, 0x0000, 0x9FBE, 0x0000, 0x9FC4, 0x0000, + 0x9FCB, 0x88FA, 0x9FC1, 0x0000, 0x9FCC, 0x0000, + 0x0000, 0x905B, 0x0000, 0x8F7E, 0x0000, 0x95A3, + 0x0000, 0x8DAC, 0x0000, 0x9FB9, 0x9FC7, 0x9359, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs6E[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x90B4, + 0x0000, 0x8A89, 0x8DCF, 0x8FC2, 0x9FBB, 0x8F61, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8C6B, 0x0000, 0x9FBA, 0x0000, 0x0000, + 0x0000, 0x9FD0, 0x8F8D, 0x8CB8, 0x0000, 0x9FDF, + 0x0000, 0x9FD9, 0x8B94, 0x936E, 0x0000, 0x9FD4, + 0x9FDD, 0x88AD, 0x8951, 0x0000, 0x0000, 0x89B7, + 0x0000, 0x9FD6, 0x91AA, 0x9FCD, 0x9FCF, 0x8D60, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9FE0, 0x0000, 0x9FDB, 0x0000, + 0x0000, 0x0000, 0x9FD3, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9FDA, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x96A9, 0x0000, 0x0000, 0x9FD8, + 0x9FDC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8CCE, 0x0000, 0x8FC3, 0x0000, + 0x0000, 0x9258, 0x0000, 0x0000, 0x0000, 0x9FD2, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x974E, 0x0000, 0x0000, 0x0000, 0x9FD5, + 0x0000, 0x0000, 0x9FCE, 0x9392, 0x0000, 0x0000, + 0x9FD1, 0x0000, 0x0000, 0x0000, 0x9FD7, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9870, 0x8EBC, 0x969E, 0x0000, 0x9FE1, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x94AC, 0x0000, 0x0000, 0x9FED, + 0x8CB9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8F80, 0x0000, 0x9FE3, 0x0000, 0x0000, 0x0000, + 0x97AD, 0x8D61, 0x0000, 0x9FF0, 0x0000, 0x0000, + 0x88EC, 0x0000, 0x0000, 0x9FEE, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9FE2, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9FE8, 0x0000, 0x0000, 0x9FEA, 0x0000, + 0x0000, 0x0000, 0x976E, 0x9FE5, 0x0000, 0x0000, + 0x934D, 0x0000, 0x0000, 0x9FE7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9FEF, 0x0000, 0x9FE9, 0x96C5, + 0x0000, 0x0000, 0x0000, 0x9FE4, 0x0000, 0x8EA0, + 0x9FFC, 0x0000, 0x0000, 0x0000, 0x0000, 0x8A8A, + 0x0000, 0x9FE6, 0x9FEB, 0x9FEC, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x91EA, + 0x91D8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9FF4, 0x0000, 0x0000, 0x9FFA, + 0x0000, 0x0000, 0x9FF8, 0x0000, 0x9348, 0x0000, + 0x0000, 0xE042, 0x9FF5, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9FF6, 0x9FDE +}; + +static u16 Ucs6F[256] = { + 0x0000, 0x8B99, 0x9559, 0x0000, 0x0000, 0x0000, + 0x8EBD, 0x0000, 0x0000, 0x8D97, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9852, 0x0000, 0x9FF2, + 0x0000, 0xE041, 0x8989, 0x9186, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9499, 0x0000, 0x8ABF, 0x97F8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x969F, 0x92D0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9FF9, 0x9FFB, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9151, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE040, 0x9FF7, 0x0000, 0x9FF1, + 0x0000, 0x0000, 0x0000, 0x8AC1, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8C89, 0x0000, 0x0000, 0x0000, 0xE04E, 0x0000, + 0x0000, 0xE049, 0x90F6, 0x0000, 0x0000, 0x8A83, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8F81, 0x0000, + 0xE052, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE04B, 0x92AA, 0xE048, 0x92D7, 0x0000, + 0x0000, 0x0000, 0xE06B, 0x0000, 0x0000, 0x0000, + 0xE045, 0x0000, 0xE044, 0x0000, 0xE04D, 0x0000, + 0x0000, 0x0000, 0xE047, 0xE046, 0xE04C, 0x0000, + 0x909F, 0x0000, 0xE043, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE04F, 0x0000, + 0x0000, 0xE050, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8AC0, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE055, + 0x0000, 0xE054, 0xE056, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE059, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9362, 0x0000, 0xE053, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE057, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8C83, 0x91F7, 0xE051, 0x945A, 0x0000, 0x0000, + 0xE058, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE05D, 0xE05B, 0x0000, 0x0000, + 0xE05E, 0x0000, 0x0000, 0xE061, 0x0000, 0x0000, + 0x0000, 0xE05A, 0x8D8A, 0x9447, 0x0000, 0x0000, + 0x9FB7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9794, 0xE05C, 0x0000, 0xE060, 0x91F3, + 0x0000, 0xE05F, 0x0000, 0xE04A, 0x0000, 0x0000, + 0xE889, 0x0000, 0x0000, 0x0000, 0xE064, 0x0000, + 0x0000, 0x0000, 0xE068, 0x0000 +}; + +static u16 Ucs70[256] = { + 0x0000, 0xE066, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE062, 0x0000, 0xE063, + 0x0000, 0x0000, 0x0000, 0xE067, 0x0000, 0xE065, + 0x0000, 0x0000, 0x0000, 0x956D, 0x0000, 0x0000, + 0xE06D, 0x0000, 0xE06A, 0xE069, 0x0000, 0xE06C, + 0x93D2, 0xE06E, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9295, 0x91EB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x90A3, 0x0000, 0x0000, 0x0000, + 0xE06F, 0x0000, 0xE071, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE070, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9FF3, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE072, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x93E5, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE073, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x89CE, + 0x0000, 0x0000, 0x0000, 0x9394, 0x8A44, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8B84, 0x0000, 0x0000, 0x0000, 0x8EDC, 0x8DD0, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9846, + 0x9086, 0x0000, 0x0000, 0x0000, 0x898A, 0x0000, + 0x0000, 0x0000, 0xE075, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE074, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE078, 0x9259, + 0xE07B, 0xE076, 0x0000, 0x0000, 0x0000, 0xE07A, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE079, 0x935F, + 0x88D7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x97F3, 0x0000, 0x0000, 0xE07D, + 0x0000, 0x0000, 0x0000, 0x8947, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE080, 0x0000, 0x0000, 0x0000, 0xE07E, + 0x0000, 0xE07C, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE077, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9642, 0x0000, 0x0000, + 0x0000, 0xE082, 0x0000, 0x0000 +}; + +static u16 Ucs71[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE081, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x898B, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE084, 0x95B0, 0x0000, 0xE083, 0x0000, + 0x0000, 0x0000, 0x0000, 0x96B3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8FC5, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9152, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8FC4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x97F9, 0x0000, 0x0000, 0xE08A, 0x0000, + 0x90F7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE086, 0xE08B, 0x0000, 0x0000, 0x898C, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE089, 0x0000, 0x9481, 0xE085, + 0xE088, 0x8FC6, 0x0000, 0x94CF, 0x0000, 0x0000, + 0xE08C, 0x0000, 0x8ECF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x90F8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE08F, 0x0000, 0x0000, 0x0000, 0xE087, 0x0000, + 0x8C46, 0x0000, 0x0000, 0x0000, 0x0000, 0xE08D, + 0x0000, 0x0000, 0x0000, 0x0000, 0x976F, 0xE090, + 0x0000, 0x0000, 0x0000, 0xEAA4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8F6E, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE091, 0x0000, 0x0000, 0x0000, 0xE092, 0x0000, + 0x0000, 0x0000, 0x0000, 0x944D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE094, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE095, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9452, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9395, 0xE097, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE099, 0x0000, 0x97D3, 0x0000, + 0xE096, 0x0000, 0xE098, 0x898D, 0x0000, 0xE093, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9A7A, 0xE09A, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9187, 0x8E57, 0xE09C, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE09B, 0x9043, 0x99D7, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE09D, + 0x0000, 0x0000, 0x0000, 0xE09F, 0x0000, 0xE08E, + 0xE09E, 0x0000, 0x0000, 0xE0A0 +}; + +static u16 Ucs72[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x949A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE0A1, 0x0000, 0x0000, 0xE0A2, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE0A3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE0A4, 0x0000, + 0x92DC, 0x0000, 0xE0A6, 0xE0A5, 0x0000, 0x0000, + 0xE0A7, 0x0000, 0xE0A8, 0x0000, 0x0000, 0x8EDD, + 0x9583, 0x0000, 0x0000, 0x0000, 0x96EA, 0xE0A9, + 0xE0AA, 0x9175, 0x8EA2, 0xE0AB, 0xE0AC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE0AD, 0x95D0, + 0x94C5, 0x0000, 0x0000, 0xE0AE, 0x9476, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x92AB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE0AF, 0x89E5, + 0x0000, 0x8B8D, 0x0000, 0x96C4, 0x0000, 0x96B4, + 0x0000, 0x89B2, 0x9853, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9671, 0x0000, 0x95A8, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x90B5, 0x0000, 0xE0B0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x93C1, 0x0000, 0x0000, 0x0000, 0x8CA1, + 0xE0B1, 0x0000, 0x8DD2, 0xE0B3, 0xE0B2, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE0B4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0B5, 0x0000, 0x0000, 0x0000, + 0xE0B6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8B5D, 0x0000, + 0xE0B7, 0x0000, 0x0000, 0x0000, 0x0000, 0xE0B8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8CA2, 0x0000, + 0x0000, 0x94C6, 0x0000, 0x0000, 0xE0BA, 0x0000, + 0x0000, 0x0000, 0x8FF3, 0x0000, 0x0000, 0xE0B9, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8BB6, 0xE0BB, 0xE0BD, 0x0000, + 0xE0BC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0BE, 0x0000, 0x8CCF, 0x0000, + 0xE0BF, 0x0000, 0x0000, 0x0000, 0x0000, 0x8BE7, + 0x0000, 0x915F, 0x0000, 0x8D9D, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0C1, 0xE0C2, 0xE0C0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8EEB, + 0x0000, 0x0000, 0x93C6, 0x8BB7, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE0C4, 0x924B, 0xE0C3, 0x0000, 0x0000, + 0x9854, 0x9482, 0x0000, 0x0000 +}; + +static u16 Ucs73[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE0C7, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE0C9, 0xE0C6, + 0x0000, 0x0000, 0x0000, 0x96D2, 0xE0C8, 0xE0CA, + 0x0000, 0x97C2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE0CE, 0x0000, 0x0000, 0x0000, 0xE0CD, + 0x9296, 0x944C, 0x0000, 0x0000, 0x8CA3, 0xE0CC, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE0CB, 0x0000, + 0x9750, 0x9751, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0CF, 0x898E, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8D96, 0x8E82, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE0D0, 0xE0D1, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE0D3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8F62, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0D5, 0x0000, 0xE0D4, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE0D6, 0x0000, + 0x8A6C, 0x0000, 0x0000, 0xE0D8, 0x0000, 0x0000, + 0xE0D7, 0x0000, 0xE0DA, 0xE0D9, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8CBA, 0x0000, 0x0000, 0x97A6, 0x0000, 0x8BCA, + 0x0000, 0x89A4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8BE8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8ADF, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x97E6, 0xE0DC, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE0DE, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE0DF, 0x0000, 0x89CF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0DB, 0x0000, 0x8E58, 0x0000, + 0x0000, 0x92BF, 0xE0DD, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE0E2, 0x0000, 0x8EEC, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE0E0, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8C5D, 0x0000, 0x0000, 0x94C7, 0xE0E1, 0x0000, + 0x0000, 0xE0FC, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0E7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8CBB, 0x0000 +}; + +static u16 Ucs74[256] = { + 0x0000, 0x0000, 0x0000, 0x8B85, 0x0000, 0xE0E4, + 0x979D, 0x0000, 0x0000, 0x97AE, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x91F4, 0x0000, + 0x0000, 0xE0E6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0E8, 0x97D4, 0x8BD5, 0x94FA, + 0x9469, 0x0000, 0x0000, 0x0000, 0xE0E9, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE0EB, 0x0000, 0xE0EE, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE0EA, 0x0000, 0x0000, 0x0000, 0xE0ED, + 0x8CE8, 0x896C, 0xE0EF, 0x0000, 0x9090, 0xE0EC, + 0x97DA, 0x0000, 0x0000, 0xE0F2, 0xEAA2, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE0F0, 0xE0F3, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE0E5, 0xE0F1, 0x0000, + 0x0000, 0x8DBA, 0x0000, 0x0000, 0xE0F4, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE0F5, 0x0000, 0x0000, 0x0000, 0x0000, 0x979E, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE0F6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0F7, 0x0000, 0x0000, 0x0000, + 0xE0E3, 0x0000, 0x0000, 0x0000, 0x0000, 0xE0F8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8AC2, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8EA3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE0F9, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE0FA, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE0FB, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x895A, 0x0000, + 0x0000, 0x0000, 0xE140, 0x0000, 0x955A, 0xE141, + 0x0000, 0x0000, 0x8AA2, 0xE142, 0x0000, 0xE143, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE144, 0x0000, + 0xE146, 0xE147, 0xE145, 0x0000, 0x0000, 0x0000, + 0x9572, 0xE149, 0xE148, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs75[256] = { + 0x0000, 0x0000, 0x0000, 0xE14B, 0xE14A, 0xE14C, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE14D, 0xE14F, 0xE14E, 0x0000, 0x0000, 0x8D99, + 0x0000, 0xE151, 0x0000, 0xE150, 0x0000, 0x0000, + 0x8AC3, 0x0000, 0x9072, 0x0000, 0x935B, 0x0000, + 0xE152, 0x90B6, 0x0000, 0x0000, 0x0000, 0x8E59, + 0x0000, 0x8999, 0xE153, 0x0000, 0x9770, 0x0000, + 0x0000, 0x95E1, 0xE154, 0x0000, 0x0000, 0x0000, + 0x9363, 0x9752, 0x8D62, 0x905C, 0x0000, 0x0000, + 0x0000, 0x926A, 0x99B2, 0x0000, 0x92AC, 0x89E6, + 0xE155, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE156, 0x0000, 0xE15B, 0x0000, + 0x0000, 0xE159, 0xE158, 0x9DC0, 0x8A45, 0xE157, + 0x0000, 0x88D8, 0x0000, 0x94A8, 0x0000, 0x0000, + 0x94C8, 0x0000, 0x0000, 0x0000, 0x0000, 0x97AF, + 0xE15C, 0xE15A, 0x927B, 0x90A4, 0x0000, 0x0000, + 0x94A9, 0x0000, 0x954C, 0x0000, 0xE15E, 0x97AA, + 0x8C6C, 0xE15F, 0x0000, 0xE15D, 0x94D4, 0xE160, + 0x0000, 0xE161, 0x0000, 0x0000, 0x88D9, 0x0000, + 0x0000, 0x8FF4, 0xE166, 0x0000, 0xE163, 0x93EB, + 0xE162, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8B45, 0x0000, 0x0000, 0xE169, 0x0000, + 0x0000, 0x0000, 0xE164, 0xE165, 0x0000, 0xE168, + 0xE167, 0x9544, 0x0000, 0x0000, 0x9161, 0x9160, + 0x0000, 0x8B5E, 0x0000, 0x0000, 0xE16A, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE16B, 0x0000, + 0x0000, 0xE16C, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE16E, 0x0000, 0xE16D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8975, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE176, 0x94E6, 0xE170, + 0x0000, 0xE172, 0x0000, 0x0000, 0xE174, 0x905D, + 0x0000, 0x0000, 0xE175, 0xE173, 0x8EBE, 0x0000, + 0x0000, 0x0000, 0xE16F, 0xE171, 0x0000, 0x9561, + 0x0000, 0x8FC7, 0x0000, 0x0000, 0xE178, 0x0000, + 0x0000, 0xE177, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE179, 0x0000, 0x8EA4, 0x8DAD, 0x0000, 0x0000, + 0x9397, 0xE17A, 0x0000, 0x92C9, 0x0000, 0x0000, + 0xE17C, 0x0000, 0x0000, 0x0000, 0x979F, 0xE17B, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9189, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE182, 0x0000, 0xE184, 0xE185, 0x9273, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE183, 0x0000, + 0xE180, 0x0000, 0xE17D, 0xE17E +}; + +static u16 Ucs76[256] = { + 0x0000, 0xE181, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE188, 0x0000, 0xE186, + 0x0000, 0xE187, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE189, 0xE18B, 0xE18C, 0xE18D, 0x0000, + 0xE18E, 0x0000, 0x0000, 0xE18A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE190, 0x0000, 0x0000, 0x0000, 0xE18F, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE191, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x97C3, 0x0000, 0x0000, 0x0000, 0xE194, 0xE192, + 0xE193, 0x0000, 0x0000, 0x0000, 0x8AE0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x96FC, 0x0000, + 0x0000, 0x0000, 0x95C8, 0x0000, 0xE196, 0x0000, + 0x0000, 0x0000, 0xE195, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE197, 0xE198, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE19C, 0xE199, 0xE19A, 0xE19B, 0x0000, + 0xE19D, 0x0000, 0x0000, 0x0000, 0xE19E, 0x0000, + 0xE19F, 0x0000, 0x0000, 0x0000, 0xE1A0, 0x0000, + 0xE1A1, 0x0000, 0x94AD, 0x936F, 0xE1A2, 0x9492, + 0x9553, 0x0000, 0xE1A3, 0x0000, 0x0000, 0xE1A4, + 0x9349, 0x0000, 0x8A46, 0x8D63, 0xE1A5, 0x0000, + 0x0000, 0xE1A6, 0x0000, 0x0000, 0xE1A7, 0x0000, + 0x8E48, 0x0000, 0x0000, 0xE1A9, 0x0000, 0x0000, + 0xE1A8, 0x0000, 0x0000, 0xE1AA, 0xE1AB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x94E7, 0x0000, 0xE1AC, 0x0000, 0x0000, 0x0000, + 0xE1AD, 0x0000, 0x0000, 0xEA89, 0xE1AE, 0xE1AF, + 0xE1B0, 0x0000, 0x0000, 0x0000, 0x0000, 0x8E4D, + 0x0000, 0x0000, 0xE1B1, 0x9475, 0x0000, 0x0000, + 0x967E, 0x0000, 0x896D, 0x0000, 0x8976, 0x0000, + 0x0000, 0xE1B2, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE1B4, 0x0000, 0x0000, 0x0000, 0xE1B3, 0x9390, + 0x0000, 0x0000, 0x0000, 0x90B7, 0x9F58, 0x0000, + 0xE1B5, 0x96BF, 0x0000, 0xE1B6, 0x0000, 0x8AC4, + 0x94D5, 0xE1B7, 0x0000, 0xE1B8, 0x0000, 0x0000, + 0xE1B9, 0x0000, 0x0000, 0x0000, 0x96DA, 0x0000, + 0x0000, 0x0000, 0x96D3, 0x0000, 0x92BC, 0x0000, + 0x0000, 0x0000, 0x918A, 0x0000, 0x0000, 0xE1BB, + 0x0000, 0x0000, 0x8F82, 0x0000 +}; + +static u16 Ucs77[256] = { + 0x0000, 0x8FC8, 0x0000, 0x0000, 0xE1BE, 0x0000, + 0x0000, 0xE1BD, 0xE1BC, 0x94FB, 0x0000, 0x8AC5, + 0x8CA7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE1C4, 0x0000, 0x0000, + 0xE1C1, 0x905E, 0x96B0, 0x0000, 0x0000, 0x0000, + 0xE1C0, 0xE1C2, 0xE1C3, 0x0000, 0x0000, 0xE1BF, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE1C5, 0xE1C6, 0x0000, 0x92AD, 0x0000, + 0x8AE1, 0x0000, 0x0000, 0x0000, 0x9285, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE1C7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE1C8, 0xE1CB, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9087, 0x0000, 0x93C2, 0x0000, 0xE1CC, + 0x9672, 0x0000, 0xE1C9, 0x0000, 0x0000, 0xE1CA, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE1CF, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE1CE, 0xE1CD, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE1D1, 0x0000, 0x0000, 0xE1D0, 0x0000, + 0x0000, 0xE1D2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE1D4, 0x0000, 0xE1D3, 0x0000, + 0x0000, 0x0000, 0x0000, 0x95CB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8F75, 0x97C4, + 0x0000, 0x0000, 0xE1D5, 0x0000, 0x0000, 0x93B5, + 0x0000, 0x0000, 0xE1D6, 0x0000, 0x0000, 0xE1D7, + 0x0000, 0xE1DB, 0xE1D9, 0xE1DA, 0x0000, 0xE1D8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE1DC, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE1DD, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE1DE, + 0x0000, 0x0000, 0xE1DF, 0x96B5, 0xE1E0, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x96EE, 0xE1E1, + 0x0000, 0x926D, 0x0000, 0x948A, 0x0000, 0x8BE9, + 0x0000, 0x0000, 0x0000, 0x925A, 0xE1E2, 0x8BB8, + 0x0000, 0x0000, 0x0000, 0x90CE, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE1E3, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs78[256] = { + 0x0000, 0x0000, 0x8DBB, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE1E4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE1E5, 0x0000, 0x8CA4, 0x8DD3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE1E7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9375, 0x8DD4, 0x8B6D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9643, 0x0000, 0x946A, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9376, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8D7B, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE1E9, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8FC9, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x97B0, + 0x8D64, 0x0000, 0x0000, 0x8CA5, 0x0000, 0x0000, + 0x94A1, 0x0000, 0xE1EB, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE1ED, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8CE9, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE1EC, 0x92F4, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE1EF, 0x8A56, 0xE1EA, 0x0000, + 0x0000, 0x94E8, 0x0000, 0x894F, 0x0000, 0x8DEA, + 0x0000, 0x9871, 0x0000, 0x0000, 0xE1EE, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE1F0, 0x0000, 0x0000, 0x0000, 0x95C9, + 0x0000, 0x90D7, 0xE1F2, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE1F3, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE1F1, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8A6D, 0x0000, 0xE1F9, 0x0000, 0xE1F8, 0x0000, + 0x0000, 0x8EA5, 0x0000, 0x0000, 0x0000, 0xE1FA, + 0xE1F5, 0x0000, 0x0000, 0x0000, 0xE1FB, 0xE1F6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x94D6, 0xE1F4, + 0x0000, 0x0000, 0xE1F7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE241, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE240, 0x9681, 0x0000, + 0x0000, 0x0000, 0xE1FC, 0x0000, 0x0000, 0x88E9, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE243, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE242, 0x0000, 0x0000 +}; + +static u16 Ucs79[256] = { + 0x0000, 0x8FCA, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE244, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9162, 0x0000, 0x0000, 0xE246, + 0xE245, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE247, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE1E6, 0x0000, 0x0000, 0x0000, + 0xE1E8, 0xE249, 0xE248, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8EA6, 0x0000, + 0x97E7, 0x0000, 0x8ED0, 0x0000, 0xE24A, 0x8C56, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8B5F, + 0x8B46, 0x8E83, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9753, 0x0000, 0x0000, 0xE250, + 0x0000, 0xE24F, 0x9163, 0xE24C, 0x0000, 0x0000, + 0xE24E, 0x0000, 0x0000, 0x8F6A, 0x905F, 0xE24D, + 0xE24B, 0x0000, 0x9449, 0x0000, 0x0000, 0x8FCB, + 0x0000, 0x0000, 0x955B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8DD5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9398, + 0x0000, 0x0000, 0xE251, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE252, 0xE268, 0x8BD6, 0x0000, 0x0000, + 0x985C, 0x9154, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE253, 0x0000, 0x0000, 0x89D0, 0x92F5, 0x959F, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE254, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8B9A, 0xE255, + 0x0000, 0x0000, 0xE257, 0x0000, 0x0000, 0x0000, + 0xE258, 0x0000, 0x9448, 0x0000, 0x0000, 0xE259, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE25A, + 0xE25B, 0x0000, 0x0000, 0x8BD7, 0x89D1, 0x93C3, + 0x8F47, 0x8E84, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE25C, 0x0000, 0x8F48, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x89C8, + 0x9562, 0x0000, 0x0000, 0xE25D, 0x0000, 0x0000, + 0x94E9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9164, 0x0000, 0xE260, 0x0000, 0xE261, + 0x9489, 0x0000, 0x9060, 0xE25E, 0x0000, 0x9281, + 0x0000, 0x0000, 0xE25F, 0x0000, 0x0000, 0x0000, + 0x8FCC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x88DA, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs7A[256] = { + 0x8B48, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE262, 0x0000, 0x0000, 0x92F6, + 0x0000, 0xE263, 0x90C5, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x96AB, 0x0000, 0x0000, 0x9542, + 0xE264, 0xE265, 0x9274, 0x0000, 0x97C5, 0x0000, + 0x0000, 0xE267, 0xE266, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8EED, 0x0000, + 0x0000, 0xE269, 0x88EE, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE26C, 0x0000, 0x0000, 0x0000, 0xE26A, + 0x89D2, 0x8C6D, 0xE26B, 0x8D65, 0x8D92, 0x0000, + 0x95E4, 0xE26D, 0x0000, 0x0000, 0x9673, 0x0000, + 0x0000, 0xE26F, 0x0000, 0x0000, 0x0000, 0x90CF, + 0x896E, 0x89B8, 0x88AA, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE26E, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE270, 0xE271, 0x8FF5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE272, 0x0000, 0x8A6E, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE274, 0x0000, + 0x0000, 0x0000, 0x8C8A, 0x0000, 0x8B86, 0x0000, + 0x0000, 0xE275, 0x8BF3, 0x0000, 0x0000, 0xE276, + 0x0000, 0x90FA, 0x0000, 0x93CB, 0x0000, 0x90DE, + 0x8DF3, 0x0000, 0x0000, 0x0000, 0xE277, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9282, 0x918B, 0x0000, 0xE279, + 0xE27B, 0xE278, 0xE27A, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8C41, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE27C, 0x8C45, 0x0000, 0x0000, 0x0000, + 0x8B87, 0x9771, 0xE27E, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE280, 0x0000, 0x0000, 0x0000, + 0x894D, 0x0000, 0x0000, 0x0000, 0x0000, 0xE283, + 0x0000, 0x0000, 0x0000, 0x8A96, 0xE282, 0xE281, + 0x0000, 0xE285, 0xE27D, 0x0000, 0xE286, 0x97A7, + 0x0000, 0xE287, 0x0000, 0xE288, 0x0000, 0x0000, + 0x9AF2, 0xE28A, 0x0000, 0xE289, 0x0000, 0x0000, + 0x0000, 0xE28B, 0xE28C, 0x0000, 0x97B3, 0xE28D, + 0x0000, 0xE8ED, 0x8FCD, 0xE28E, 0xE28F, 0x8F76, + 0x0000, 0x93B6, 0xE290, 0x0000, 0x0000, 0x0000, + 0x9247, 0x0000, 0x0000, 0xE291, 0x0000, 0x925B, + 0xE292, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8BA3, 0x0000, 0x995E, 0x927C, 0x8EB1, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8AC6 +}; + +static u16 Ucs7B[256] = { + 0x0000, 0x0000, 0xE293, 0x0000, 0xE2A0, 0x0000, + 0xE296, 0x0000, 0x8B88, 0x0000, 0xE295, 0xE2A2, + 0x0000, 0x0000, 0x0000, 0xE294, 0x0000, 0x8FCE, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE298, 0xE299, 0x0000, 0x934A, 0x0000, 0x0000, + 0xE29A, 0x0000, 0x8A7D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9079, 0x9584, 0x0000, 0xE29C, 0x0000, + 0x0000, 0x0000, 0x91E6, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE297, 0x0000, 0xE29B, + 0xE29D, 0x0000, 0x0000, 0x8DF9, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE2A4, 0x954D, 0x0000, + 0x94A4, 0x9399, 0x0000, 0x8BD8, 0xE2A3, 0xE2A1, + 0x0000, 0x94B3, 0xE29E, 0x927D, 0x939B, 0x0000, + 0x939A, 0x0000, 0x8DF4, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE2B6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE2A6, + 0x0000, 0xE2A8, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE2AB, 0x0000, 0xE2AC, 0x0000, 0xE2A9, 0xE2AA, + 0x0000, 0x0000, 0xE2A7, 0xE2A5, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE29F, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x95CD, 0x89D3, 0x0000, 0x0000, + 0x0000, 0xE2B3, 0x0000, 0xE2B0, 0x0000, 0xE2B5, + 0x0000, 0x0000, 0xE2B4, 0x0000, 0x9493, 0x96A5, + 0x0000, 0x8E5A, 0xE2AE, 0xE2B7, 0xE2B2, 0x0000, + 0xE2B1, 0xE2AD, 0x0000, 0xE2AF, 0x0000, 0x8AC7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x925C, 0x0000, 0x0000, 0x90FB, + 0x0000, 0x0000, 0x0000, 0x94A0, 0x0000, 0x0000, + 0xE2BC, 0x0000, 0x0000, 0x0000, 0x94A2, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x90DF, 0xE2B9, 0x0000, 0x0000, 0x94CD, 0x0000, + 0xE2BD, 0x95D1, 0x0000, 0x927A, 0x0000, 0xE2B8, + 0xE2BA, 0x0000, 0x0000, 0xE2BB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE2BE, + 0x0000, 0x0000, 0x8EC2, 0x0000, 0x0000, 0x0000, + 0x93C4, 0xE2C3, 0xE2C2, 0x0000, 0x0000, 0xE2BF, + 0x0000, 0x0000, 0x0000, 0x9855, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE2C8, 0x0000, 0x0000, + 0xE2CC, 0xE2C9, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs7C[256] = { + 0xE2C5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE2C6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE2CB, 0x0000, 0x0000, 0x0000, 0xE2C0, + 0x99D3, 0xE2C7, 0xE2C1, 0x0000, 0x0000, 0xE2CA, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE2D0, 0x0000, 0x8AC8, 0x0000, 0xE2CD, + 0x0000, 0x0000, 0x0000, 0xE2CE, 0x0000, 0x0000, + 0xE2CF, 0xE2D2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE2D1, 0x94F4, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE2D3, 0x97FA, 0x95EB, 0xE2D8, 0x0000, + 0x0000, 0xE2D5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE2D4, 0x90D0, + 0x0000, 0xE2D7, 0xE2D9, 0x0000, 0x0000, 0x0000, + 0xE2D6, 0x0000, 0xE2DD, 0x0000, 0xE2DA, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE2DB, + 0xE2C4, 0x0000, 0x0000, 0x0000, 0xE2DC, 0xE2DE, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE2DF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x95C4, 0x0000, 0xE2E0, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x96E0, 0x0000, 0x0000, 0x8BCC, 0x8C48, 0xE2E1, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x95B2, + 0x0000, 0x9088, 0x0000, 0x96AE, 0x0000, 0x0000, + 0xE2E2, 0x0000, 0x97B1, 0x0000, 0x0000, 0x9494, + 0x0000, 0x9165, 0x9453, 0x0000, 0x0000, 0x8F6C, + 0x0000, 0x0000, 0x0000, 0x88BE, 0x0000, 0xE2E7, + 0xE2E5, 0x0000, 0xE2E3, 0x8A9F, 0x0000, 0x8FCF, + 0xE2E8, 0x0000, 0x0000, 0xE2E6, 0x0000, 0xE2E4, + 0xE2EC, 0x0000, 0x0000, 0xE2EB, 0xE2EA, 0xE2E9, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE2ED, + 0x0000, 0x0000, 0x0000, 0xE2EE, 0x90B8, 0x0000, + 0xE2EF, 0x0000, 0xE2F1, 0x0000, 0x0000, 0xE2F0, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8CD0, 0x0000, + 0x0000, 0x0000, 0x9157, 0x0000, 0x0000, 0x0000, + 0xE2F3, 0x0000, 0x0000, 0x0000, 0x939C, 0x0000, + 0xE2F2, 0x0000, 0x0000, 0x0000, 0xE2F4, 0x0000, + 0x95B3, 0x918C, 0x8D66, 0x0000, 0xE2F5, 0x0000, + 0x0000, 0x0000, 0x0000, 0x97C6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE2F7, + 0x0000, 0x0000, 0xE2F8, 0x0000, 0xE2F9, 0x0000, + 0xE2FA, 0x0000, 0x8E85, 0x0000, 0xE2FB, 0x8C6E, + 0x0000, 0x0000, 0x8B8A, 0x0000 +}; + +static u16 Ucs7D[256] = { + 0x8B49, 0x0000, 0xE340, 0x0000, 0x96F1, 0x8D67, + 0xE2FC, 0x0000, 0x0000, 0x0000, 0xE343, 0x96E4, + 0x0000, 0x945B, 0x0000, 0x0000, 0x9552, 0x0000, + 0x0000, 0x0000, 0x8F83, 0xE342, 0x0000, 0x8ED1, + 0x8D68, 0x8E86, 0x8B89, 0x95B4, 0xE341, 0x0000, + 0x0000, 0x0000, 0x9166, 0x9661, 0x8DF5, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8E87, 0x92DB, 0x0000, 0xE346, 0x97DD, + 0x8DD7, 0x0000, 0xE347, 0x9061, 0x0000, 0xE349, + 0x0000, 0x0000, 0x0000, 0x8FD0, 0x8DAE, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE348, 0x0000, 0x0000, + 0x8F49, 0x8CBC, 0x9167, 0xE344, 0xE34A, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE345, 0x8C6F, 0x0000, + 0xE34D, 0xE351, 0x8C8B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE34C, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE355, 0x0000, 0x0000, 0x8D69, 0x0000, + 0x0000, 0x978D, 0x88BA, 0xE352, 0x0000, 0x0000, + 0x8B8B, 0x0000, 0xE34F, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE350, 0x0000, 0x0000, 0x939D, + 0xE34E, 0xE34B, 0x0000, 0x8A47, 0x90E2, 0x0000, + 0x0000, 0x8CA6, 0x0000, 0x0000, 0x0000, 0xE357, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE354, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE356, + 0x0000, 0x0000, 0x0000, 0xE353, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8C70, 0x91B1, 0xE358, + 0x918E, 0x0000, 0x0000, 0xE365, 0x0000, 0x0000, + 0xE361, 0xE35B, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE35F, 0x8EF8, 0x88DB, + 0xE35A, 0xE362, 0xE366, 0x8D6A, 0x96D4, 0x0000, + 0x92D4, 0xE35C, 0x0000, 0x0000, 0xE364, 0x0000, + 0xE359, 0x925D, 0x0000, 0xE35E, 0x88BB, 0x96C8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE35D, 0x0000, 0x0000, 0x8BD9, 0x94EA, + 0x0000, 0x0000, 0x0000, 0x918D, 0x0000, 0x97CE, + 0x8F8F, 0x0000, 0x0000, 0xE38E, 0x0000, 0x0000, + 0xE367, 0x0000, 0x90FC, 0x0000, 0xE363, 0xE368, + 0xE36A, 0x0000, 0x92F7, 0xE36D, 0x0000, 0x0000, + 0xE369, 0x0000, 0x0000, 0x0000, 0x95D2, 0x8AC9, + 0x0000, 0x0000, 0x96C9, 0x0000, 0x0000, 0x88DC, + 0x0000, 0x0000, 0xE36C, 0x0000, 0x97FB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE36B, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs7E[256] = { + 0x0000, 0x898F, 0x0000, 0x0000, 0x93EA, 0xE36E, + 0x0000, 0x0000, 0x0000, 0xE375, 0xE36F, 0xE376, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE372, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x949B, 0x0000, 0x0000, + 0x8EC8, 0xE374, 0x0000, 0xE371, 0xE377, 0xE370, + 0x0000, 0x0000, 0x8F63, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9644, 0x0000, 0x0000, 0x8F6B, 0x0000, + 0x0000, 0xE373, 0xE380, 0x0000, 0x0000, 0xE37B, + 0x0000, 0xE37E, 0x0000, 0xE37C, 0xE381, 0xE37A, + 0x0000, 0xE360, 0x90D1, 0x0000, 0x0000, 0x94C9, + 0x0000, 0xE37D, 0x0000, 0x0000, 0xE378, 0x0000, + 0x0000, 0x0000, 0x9140, 0x8C71, 0x0000, 0x8F4A, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9044, 0x9155, 0xE384, 0x0000, 0x0000, 0xE386, + 0xE387, 0x0000, 0x0000, 0xE383, 0xE385, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE379, 0xE382, 0x0000, 0xE38A, 0xE389, 0x0000, + 0x0000, 0x969A, 0x0000, 0x0000, 0x8C4A, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE388, 0x0000, 0xE38C, 0xE38B, 0xE38F, + 0x0000, 0xE391, 0x0000, 0x0000, 0x8E5B, 0xE38D, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE392, 0xE393, + 0x0000, 0x0000, 0xE394, 0x0000, 0xE39A, 0x935A, + 0xE396, 0x0000, 0xE395, 0xE397, 0xE398, 0x0000, + 0xE399, 0x0000, 0x0000, 0x0000, 0x0000, 0xE39B, + 0xE39C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs7F[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8ACA, 0x0000, 0xE39D, 0x0000, 0xE39E, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE39F, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE3A0, 0xE3A1, + 0xE3A2, 0x0000, 0xE3A3, 0xE3A4, 0x0000, 0x0000, + 0xE3A6, 0xE3A5, 0x0000, 0x0000, 0xE3A7, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3A8, + 0xE3A9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE3AC, 0xE3AA, 0xE3AB, 0x8DDF, 0x8C72, + 0x0000, 0x0000, 0x9275, 0x0000, 0x94B1, 0x0000, + 0x8F90, 0x0000, 0x0000, 0x946C, 0x0000, 0x94EB, + 0xE3AD, 0x9CEB, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE3AE, 0xE3B0, + 0x0000, 0x9785, 0xE3AF, 0xE3B2, 0xE3B1, 0x0000, + 0x9772, 0x0000, 0xE3B3, 0x0000, 0x94FC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE3B4, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE3B7, 0x0000, + 0x0000, 0xE3B6, 0xE3B5, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE3B8, 0x8C51, 0x0000, 0x0000, 0x0000, + 0x9141, 0x8B60, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE3BC, 0xE3B9, 0x0000, 0x0000, 0xE3BA, 0x0000, + 0x0000, 0x0000, 0xE3BD, 0x0000, 0xE3BE, 0xE3BB, + 0x0000, 0x0000, 0x0000, 0x8948, 0x0000, 0x0000, + 0x0000, 0x89A5, 0x0000, 0x0000, 0x0000, 0xE3C0, + 0xE3C1, 0x0000, 0x0000, 0x0000, 0xE3C2, 0x0000, + 0x9782, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8F4B, 0x0000, 0xE3C4, 0xE3C3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9089, 0xE3C5, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE3C6, 0x0000, 0x0000, 0xE3C7, + 0x0000, 0x8AE3, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8ACB, 0x0000, 0x0000, 0xE3C8, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE3C9, 0x0000, 0x967C, + 0x9783, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs80[256] = { + 0x9773, 0x9856, 0x0000, 0x8D6C, 0xE3CC, 0x8ED2, + 0xE3CB, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3CD, + 0x8EA7, 0x0000, 0x0000, 0x0000, 0x91CF, 0x0000, + 0xE3CE, 0x0000, 0x0000, 0x8D6B, 0x0000, 0x96D5, + 0xE3CF, 0xE3D0, 0x0000, 0x0000, 0xE3D1, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE3D2, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE3D3, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8EA8, 0x0000, 0x0000, + 0x96EB, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3D5, + 0x0000, 0x925E, 0x0000, 0xE3D4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE3D7, 0x0000, + 0x0000, 0x0000, 0xE3D6, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE3D8, 0x0000, + 0x0000, 0x0000, 0x90B9, 0x0000, 0xE3D9, 0x0000, + 0xE3DA, 0x0000, 0x0000, 0x0000, 0x95B7, 0xE3DB, + 0x0000, 0x918F, 0xE3DC, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE3DD, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x97FC, 0xE3E0, 0x0000, + 0xE3DF, 0xE3DE, 0x92AE, 0x0000, 0xE3E1, 0x9045, + 0x0000, 0xE3E2, 0x0000, 0x0000, 0x0000, 0xE3E3, + 0x9857, 0xE3E4, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE3E5, 0xE3E7, 0xE3E6, 0x94A3, 0x0000, 0x93F7, + 0x0000, 0x985D, 0x94A7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE3E9, 0x0000, 0x0000, + 0x8FD1, 0x0000, 0x9549, 0x0000, 0xE3EA, 0xE3E8, + 0x0000, 0x8ACC, 0x0000, 0x0000, 0x0000, 0x8CD2, + 0x8E88, 0x0000, 0x0000, 0x94EC, 0x0000, 0x0000, + 0x0000, 0x8CA8, 0x9662, 0x0000, 0xE3ED, 0xE3EB, + 0x0000, 0x8D6D, 0x0000, 0x8D6E, 0x88E7, 0x0000, + 0x8DE6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9478, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x88DD, 0xE3F2, 0x0000, + 0x925F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9477, 0x0000, 0x91D9, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE3F4, 0x0000, + 0x0000, 0xE3F0, 0xE3F3, 0xE3EE, 0x0000, 0xE3F1, + 0x9645, 0x0000, 0x0000, 0x8CD3, 0x0000, 0x0000, + 0x88FB, 0xE3EF, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3F6, + 0x0000, 0xE3F7, 0x0000, 0x0000, 0x93B7, 0x0000, + 0x0000, 0x0000, 0x8BB9, 0x0000, 0x0000, 0x0000, + 0xE445, 0x945C, 0x0000, 0x0000 +}; + +static u16 Ucs81[256] = { + 0x0000, 0x0000, 0x8E89, 0x0000, 0x0000, 0x8BBA, + 0x90C6, 0x9865, 0x96AC, 0xE3F5, 0x90D2, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8B72, 0xE3F8, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3FA, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3F9, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE3FB, + 0x0000, 0x9245, 0x0000, 0x945D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x92AF, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE442, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE441, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE3FC, 0x0000, 0x0000, + 0x9074, 0x0000, 0x9585, 0xE444, 0x0000, 0xE443, + 0x8D6F, 0x9872, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE454, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE448, + 0xE449, 0x0000, 0x0000, 0x0000, 0x0000, 0x8EEE, + 0x0000, 0x0000, 0xE447, 0x0000, 0x8D98, 0xE446, + 0x0000, 0x0000, 0xE44A, 0x0000, 0x0000, 0x0000, + 0x92B0, 0x95A0, 0x9142, 0x0000, 0x0000, 0x0000, + 0x0000, 0x91DA, 0xE44E, 0x0000, 0xE44F, 0xE44B, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE44C, 0x0000, + 0xE44D, 0x0000, 0x0000, 0x0000, 0x0000, 0x8D70, + 0x0000, 0x0000, 0x0000, 0xE455, 0x0000, 0xE451, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9586, 0x0000, + 0x968C, 0x9547, 0x0000, 0x0000, 0xE450, 0x0000, + 0x0000, 0xE453, 0xE452, 0x0000, 0x0000, 0x0000, + 0x9663, 0xE456, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE457, 0x0000, 0x0000, 0x9156, + 0x0000, 0xE458, 0x0000, 0x0000, 0xE45A, 0x0000, + 0xE45E, 0x0000, 0x0000, 0xE45B, 0xE459, 0x945E, + 0xE45C, 0x0000, 0xE45D, 0x0000, 0x0000, 0x0000, + 0x89B0, 0x0000, 0xE464, 0xE45F, 0x0000, 0x0000, + 0x0000, 0xE460, 0x0000, 0x0000, 0x0000, 0xE461, + 0x0000, 0x919F, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE463, 0xE462, 0xE465, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE466, 0xE467, 0x0000, 0x0000, 0x9062, + 0x0000, 0x89E7, 0x0000, 0xE468, 0x97D5, 0x0000, + 0x8EA9, 0x0000, 0x0000, 0x8F4C, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8E8A, 0x9276, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE469, 0xE46A, + 0x8950, 0x0000, 0xE46B, 0x0000 +}; + +static u16 Ucs82[256] = { + 0x0000, 0xE46C, 0xE46D, 0x0000, 0x0000, 0xE46E, + 0x0000, 0xE46F, 0x8BBB, 0x9DA8, 0xE470, 0x0000, + 0x90E3, 0xE471, 0x8EC9, 0x0000, 0xE472, 0x0000, + 0x98AE, 0x0000, 0x0000, 0x0000, 0xE473, 0x95DC, + 0x8ADA, 0x0000, 0x0000, 0x9143, 0x8F77, 0x0000, + 0x9591, 0x8F4D, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE474, + 0x8D71, 0xE475, 0x94CA, 0x0000, 0xE484, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE477, 0x0000, 0x91C7, + 0x9495, 0x8CBD, 0xE476, 0x9144, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE478, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x92F8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE47A, 0xE479, + 0xE47C, 0x0000, 0x0000, 0xE47B, 0x0000, 0xE47D, + 0x0000, 0x0000, 0xE480, 0x0000, 0xE47E, 0x0000, + 0x8ACD, 0x0000, 0xE481, 0x0000, 0xE482, 0xE483, + 0x0000, 0x0000, 0x8DAF, 0x97C7, 0x0000, 0xE485, + 0x9046, 0x0000, 0x0000, 0x0000, 0x8990, 0xE486, + 0xE487, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE488, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x88F0, 0x0000, 0xE489, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE48A, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9587, 0x0000, 0x0000, + 0x0000, 0x8EC5, 0x0000, 0xE48C, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8A48, 0x88B0, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE48B, 0xE48E, 0x946D, + 0x0000, 0x9063, 0x0000, 0x89D4, 0x0000, 0x9646, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8C7C, 0x8BDA, + 0x0000, 0xE48D, 0x0000, 0x89E8, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8AA1, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8991, + 0xE492, 0x97E8, 0x91DB, 0x0000, 0x0000, 0x9563, + 0x0000, 0xE49E, 0x0000, 0x89D5, 0xE49C, 0x0000, + 0xE49A, 0xE491, 0x0000, 0xE48F, 0x0000, 0xE490, + 0x0000, 0x8EE1, 0x8BEA, 0x9297, 0x0000, 0x0000, + 0x0000, 0x93CF, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8970, 0x0000, 0xE494, 0xE493, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE499, 0xE495, 0xE498, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs83[256] = { + 0x0000, 0x0000, 0x96CE, 0xE497, 0x89D6, 0x8A9D, + 0xE49B, 0x0000, 0x0000, 0xE49D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8C73, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE4A1, 0xE4AA, + 0xE4AB, 0x0000, 0x0000, 0x0000, 0x88A9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE4B2, + 0x0000, 0x0000, 0x0000, 0x0000, 0x88EF, 0x0000, + 0x0000, 0xE4A9, 0x0000, 0x0000, 0x0000, 0xE4A8, + 0x0000, 0xE4A3, 0xE4A2, 0x0000, 0xE4A0, 0xE49F, + 0x9283, 0x0000, 0x91F9, 0xE4A5, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE4A4, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE4A7, 0x0000, 0x0000, + 0x0000, 0x9190, 0x8C74, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8960, 0xE4A6, 0x0000, 0x8D72, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9191, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE4B8, 0x0000, 0xE4B9, 0x0000, 0x89D7, + 0x0000, 0x0000, 0x0000, 0x89AC, 0xE4B6, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE4AC, 0x0000, 0xE4B4, 0x0000, 0xE4BB, + 0xE4B5, 0x0000, 0x0000, 0x0000, 0xE4B3, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE496, 0x0000, 0x0000, + 0xE4B1, 0x0000, 0x0000, 0x0000, 0xE4AD, 0x0000, + 0x0000, 0x0000, 0x8ACE, 0xE4AF, 0xE4BA, 0x0000, + 0xE4B0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE4BC, 0x0000, 0xE4AE, 0x949C, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9789, 0x0000, 0x0000, + 0x0000, 0xE4B7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE4CD, 0x0000, 0x0000, + 0x0000, 0xE4C5, 0x0000, 0x0000, 0x0000, 0x909B, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8B65, 0x0000, + 0x8BDB, 0x0000, 0xE4C0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x89D9, 0x0000, 0x0000, 0x8FD2, 0x0000, + 0xE4C3, 0x0000, 0x0000, 0x0000, 0x8DD8, 0x0000, + 0x0000, 0x9370, 0xE4C8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x95EC, + 0x0000, 0xE4BF, 0x0000, 0x0000, 0x0000, 0x89D8, + 0x8CD4, 0x9548, 0xE4C9, 0x0000, 0xE4BD, 0x0000, + 0x0000, 0xE4C6, 0x0000, 0x0000, 0x0000, 0xE4D0, + 0x0000, 0xE4C1, 0x0000, 0x0000 +}; + +static u16 Ucs84[256] = { + 0x0000, 0x0000, 0x0000, 0xE4C2, 0x93B8, 0x0000, + 0x0000, 0xE4C7, 0x0000, 0x0000, 0x0000, 0xE4C4, + 0x9647, 0xE4CA, 0x88DE, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE4BE, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE4CC, 0x0000, 0xE4CB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x948B, + 0xE4D2, 0x0000, 0xE4DD, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8A9E, 0x0000, 0x0000, 0x0000, 0xE4E0, + 0x0000, 0x0000, 0xE4CE, 0x0000, 0x0000, 0x0000, + 0xE4D3, 0x978E, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE4DC, 0x0000, + 0x0000, 0x9774, 0x0000, 0x0000, 0x0000, 0x0000, + 0x97A8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9298, 0x0000, 0x0000, + 0x0000, 0x8A8B, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9592, 0xE4E2, 0x939F, 0x0000, 0x0000, + 0x88AF, 0x0000, 0x0000, 0xE4DB, 0x0000, 0xE4D7, + 0x9192, 0xE4D1, 0xE4D9, 0xE4DE, 0x0000, 0x944B, + 0x0000, 0x0000, 0x0000, 0x88A8, 0x0000, 0xE4D6, + 0x0000, 0xE4DF, 0x9598, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE4DA, 0x0000, + 0xE4D5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8FD3, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8F4E, 0x0000, 0x0000, 0x0000, 0x8EAA, 0x0000, + 0x0000, 0x0000, 0x0000, 0x96D6, 0x0000, 0x0000, + 0x9566, 0x0000, 0x0000, 0xE4E5, 0x0000, 0xE4EE, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE4D8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8A97, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8FF6, 0xE4E3, + 0x0000, 0xE4E8, 0x9193, 0x0000, 0x0000, 0xE4E4, + 0x0000, 0xE4EB, 0x0000, 0x0000, 0x927E, 0x0000, + 0xE4EC, 0x0000, 0x0000, 0x9775, 0xE4E1, 0x8A57, + 0x0000, 0xE4E7, 0x0000, 0x0000, 0xE4EA, 0x96AA, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE4ED, 0x0000, + 0x0000, 0xE4E6, 0xE4E9, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9648, 0x0000, 0x9840, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE4F1, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE4F8, 0x0000, 0x0000, 0xE4F0 +}; + +static u16 Ucs85[256] = { + 0x8EC1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE4CF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x95CC, + 0x0000, 0x96A0, 0xE4F7, 0xE4F6, 0x0000, 0xE4F2, + 0xE4F3, 0x0000, 0x8955, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE4F5, 0x0000, 0xE4EF, 0x0000, 0x0000, + 0x0000, 0x0000, 0x92D3, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE4F4, 0x88FC, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x91A0, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x95C1, 0x0000, 0x0000, 0xE4F9, 0xE540, + 0x0000, 0x94D7, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE4FC, 0x8FD4, 0x8EC7, 0xE542, 0x0000, 0x0000, + 0x8BBC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE543, 0x0000, 0x9599, 0xE4FB, 0x0000, + 0xE4D4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE4FA, 0x0000, 0x0000, + 0x0000, 0x0000, 0x986E, 0x93A0, 0x9593, 0x0000, + 0x0000, 0xE54A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE550, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE551, 0x0000, 0xE544, 0x0000, 0x0000, 0x0000, + 0x9496, 0x0000, 0x0000, 0xE54E, 0xE546, 0x0000, + 0xE548, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE552, 0xE547, 0x0000, 0x0000, 0xE54B, 0x0000, + 0x0000, 0x8992, 0x0000, 0x93E3, 0x0000, 0xE54C, + 0xE54F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE545, 0x0000, 0x9145, 0x0000, + 0xE549, 0x8E46, 0x9064, 0x8C4F, 0x96F2, 0x0000, + 0x96F7, 0x8F92, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE556, + 0xE554, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x986D, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE553, 0x0000, 0x0000, + 0x0000, 0x9795, 0x0000, 0xE555, 0xE557, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE558, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE55B, 0xE559, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x93A1, 0xE55A, 0x0000, 0x0000, 0x0000, 0x94CB, + 0xE54D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8F93, 0x0000, 0xE55C, 0xE561, 0x9194, + 0x0000, 0x0000, 0xE560, 0x0000 +}; + +static u16 Ucs86[256] = { + 0x0000, 0x0000, 0xE541, 0x0000, 0x0000, 0x0000, + 0xE562, 0x9168, 0x0000, 0x0000, 0xE55D, 0xE55F, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE55E, 0x0000, 0x0000, 0x9F50, 0x9F41, + 0x0000, 0x0000, 0xE564, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE563, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9796, 0x0000, 0xE1BA, + 0xE565, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE566, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE567, + 0x8CD5, 0x0000, 0x8B73, 0x0000, 0x0000, 0x0000, + 0xE569, 0x997C, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8B95, 0x0000, 0x97B8, 0x0000, 0x8BF1, 0xE56A, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE56B, 0x0000, 0x0000, 0x0000, 0x928E, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE56C, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x93F8, 0x0000, 0x88B8, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x89E1, 0xE571, 0xE572, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE56D, 0x0000, 0x8E5C, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE56E, 0x9461, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE56F, 0xE570, 0xE57A, 0x0000, 0x0000, + 0x0000, 0xE574, 0xE577, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE573, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE575, 0x0000, + 0xE576, 0x8ED6, 0x0000, 0xE578, 0x0000, 0x9260, + 0x0000, 0x8C75, 0x8A61, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE57B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8A5E, 0x0000, 0xE581, 0x0000, 0x0000, + 0xE57C, 0xE580, 0x0000, 0x0000, 0x0000, 0x0000, + 0x94B8, 0x0000, 0x0000, 0x0000, 0x0000, 0xE57D, + 0x0000, 0x0000, 0xE57E, 0x9567, 0x94D8, 0xE582, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x91FB, 0xE58C, 0x0000, 0xE588, + 0x0000, 0x0000, 0x89E9, 0x0000 +}; + +static u16 Ucs87[256] = { + 0xE586, 0x0000, 0x9649, 0xE587, 0x0000, 0x0000, + 0xE584, 0x0000, 0xE585, 0xE58A, 0xE58D, 0x0000, + 0x0000, 0xE58B, 0x0000, 0x0000, 0x0000, 0xE589, + 0xE583, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9277, 0x0000, 0xE594, 0x0000, 0x96A8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE592, 0x0000, 0x0000, 0x0000, 0xE593, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE58E, 0x0000, + 0x0000, 0xE590, 0x0000, 0x0000, 0x0000, 0xE591, + 0x0000, 0x0000, 0x0000, 0xE58F, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x90E4, 0x0000, 0x9858, 0xE598, 0x0000, + 0xE599, 0x0000, 0x0000, 0x0000, 0x0000, 0xE59F, + 0x0000, 0x9049, 0x0000, 0xE59B, 0x0000, 0xE59E, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE596, + 0xE595, 0x0000, 0x0000, 0xE5A0, 0x0000, 0x0000, + 0x89DA, 0x0000, 0xE59C, 0x0000, 0xE5A1, 0x0000, + 0x0000, 0x0000, 0xE59D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE59A, 0x0000, 0x92B1, 0x0000, + 0xE597, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9488, 0x0000, 0x0000, 0xE5A5, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x975A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE5A4, 0x0000, 0x0000, + 0xE5A3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE5AC, 0x0000, 0x0000, + 0x0000, 0xE5A6, 0x0000, 0x0000, 0x0000, 0xE5AE, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9786, 0xE5B1, 0x0000, 0xE5A8, 0x0000, 0x0000, + 0xE5A9, 0x0000, 0x0000, 0x0000, 0xE5AD, 0x0000, + 0xE5B0, 0xE5AF, 0x0000, 0x0000, 0x0000, 0xE5A7, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE5AA, 0x0000, + 0xE5BB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE5B4, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE5B2, + 0x0000, 0x0000, 0xE5B3, 0x0000, 0x0000, 0x0000, + 0xE5B8, 0xE5B9, 0x0000, 0x8A49, 0x0000, 0x8B61, + 0x0000, 0x0000, 0xE5B7, 0x0000 +}; + +static u16 Ucs88[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE5A2, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE5B6, 0xE5BA, 0xE5B5, 0x0000, 0xE5BC, + 0x0000, 0x0000, 0x0000, 0xE5BE, 0xE5BD, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE5C0, 0xE5BF, 0xE579, + 0x0000, 0x0000, 0x0000, 0xE5C4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE5C1, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE5C2, 0x0000, 0x0000, 0xE5C3, 0x0000, 0xE5C5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8C8C, 0x0000, + 0xE5C7, 0x0000, 0xE5C6, 0x0000, 0x8F4F, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8D73, 0x9FA5, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE5C8, 0x8F70, + 0x0000, 0x0000, 0x0000, 0x8A58, 0x0000, 0xE5C9, + 0x0000, 0x8971, 0x0000, 0x8FD5, 0xE5CA, 0x0000, + 0x0000, 0x8D74, 0xE5CB, 0x88DF, 0x0000, 0x0000, + 0x0000, 0x0000, 0x955C, 0x0000, 0x0000, 0xE5CC, + 0x0000, 0x0000, 0x0000, 0x0000, 0x908A, 0x0000, + 0xE5D3, 0x0000, 0x0000, 0xE5D0, 0x0000, 0x928F, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE5D1, + 0xE5CE, 0x8BDC, 0x0000, 0xE5CD, 0xE5D4, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8C55, 0x0000, + 0x0000, 0x91DC, 0x0000, 0xE5DA, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE5D6, 0x0000, 0x0000, 0x0000, + 0x91B3, 0xE5D5, 0x0000, 0xE5D8, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE5CF, 0x0000, 0x0000, 0x0000, + 0xE5D9, 0x0000, 0xE5DB, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x94ED, 0x0000, 0x0000, + 0xE5D7, 0x0000, 0xE5DC, 0xE5DE, 0x0000, 0x0000, + 0x8CD1, 0xE5D2, 0x0000, 0x88BF, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE5DD, + 0x0000, 0x8DD9, 0x97F4, 0xE5DF, 0xE5E0, 0x9195, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x97A0, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE5E1, 0x9754, 0x0000, 0x0000, + 0xE5E2, 0xE5E3, 0x0000, 0x0000, 0x95E2, 0xE5E4, + 0x0000, 0x8DBE, 0x0000, 0x97A1, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE5E9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE5EA, 0x8FD6, 0xE5E8, 0x0000, + 0x0000, 0x0000, 0x9787, 0xE5E5, 0x0000, 0x0000, + 0xE5E7, 0x90BB, 0x909E, 0x0000 +}; + +static u16 Ucs89[256] = { + 0x0000, 0x0000, 0xE5E6, 0x0000, 0xE5EB, 0x0000, + 0x0000, 0x95A1, 0x0000, 0x0000, 0xE5ED, 0x0000, + 0xE5EC, 0x0000, 0x0000, 0x0000, 0x8A8C, 0x0000, + 0x964A, 0xE5EE, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE5FA, + 0xE5F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE5F1, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE5F2, 0xE5F3, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE5F7, 0x0000, 0xE5F8, 0x0000, 0x0000, 0xE5F6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE5F4, + 0x0000, 0xE5EF, 0xE5F5, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE5F9, 0xE8B5, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x89A6, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE5FC, 0x8BDD, + 0xE5FB, 0x0000, 0x0000, 0x0000, 0xE641, 0x0000, + 0xE640, 0x0000, 0x0000, 0x0000, 0xE643, 0x0000, + 0x0000, 0xE642, 0x0000, 0xE644, 0x0000, 0x0000, + 0x8F50, 0x0000, 0xE645, 0x0000, 0x0000, 0xE646, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE647, 0x90BC, 0x0000, 0x9776, 0x0000, 0xE648, + 0x0000, 0x0000, 0x95A2, 0x9465, 0xE649, 0x0000, + 0xE64A, 0x8CA9, 0x0000, 0x0000, 0x0000, 0x8B4B, + 0x0000, 0x0000, 0x0000, 0xE64B, 0x0000, 0x0000, + 0x8E8B, 0x9460, 0xE64C, 0x0000, 0x8A6F, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE64D, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE64F, 0x9797, + 0x0000, 0xE64E, 0x9065, 0x0000, 0xE650, 0x0000, + 0x0000, 0xE651, 0x0000, 0x0000, 0xE652, 0x8ACF, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE653, 0x0000, 0x0000, 0xE654, 0x0000, 0xE655, + 0xE656, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8A70, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE657, 0x0000, 0xE658, 0xE659, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x89F0, + 0x0000, 0x0000, 0x9047, 0xE65A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE65B, 0x0000, + 0x0000, 0x0000, 0xE65C, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs8A[256] = { + 0x8CBE, 0x0000, 0x92F9, 0xE65D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8C76, 0x0000, 0x9075, 0x0000, + 0xE660, 0x0000, 0x93A2, 0x0000, 0xE65F, 0x0000, + 0x0000, 0x8C50, 0x0000, 0x0000, 0xE65E, 0x91F5, + 0x8B4C, 0x0000, 0x0000, 0xE661, 0x0000, 0xE662, + 0x0000, 0x8FD7, 0x0000, 0x0000, 0x0000, 0x8C8D, + 0x0000, 0xE663, 0x0000, 0x0000, 0x0000, 0x0000, + 0x964B, 0x0000, 0x0000, 0x90DD, 0x0000, 0x0000, + 0x0000, 0x8B96, 0x0000, 0x96F3, 0x9169, 0x0000, + 0xE664, 0x0000, 0x0000, 0x0000, 0x9066, 0x9290, + 0x8FD8, 0x0000, 0x0000, 0x0000, 0x0000, 0xE665, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE668, 0x0000, + 0xE669, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8DBC, 0x91C0, 0xE667, 0x0000, + 0x8FD9, 0x955D, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE666, 0x0000, 0x0000, 0x8E8C, 0x0000, + 0x8972, 0x0000, 0xE66D, 0x8C77, 0x0000, 0x0000, + 0x8E8E, 0x0000, 0x0000, 0x8E8D, 0x0000, 0x986C, + 0xE66C, 0xE66B, 0x9146, 0x0000, 0x8B6C, 0x9862, + 0x8A59, 0x8FDA, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE66A, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE66F, 0x0000, + 0xE670, 0xE66E, 0x0000, 0x8CD6, 0x0000, 0x975F, + 0x0000, 0x0000, 0x8E8F, 0x9446, 0x0000, 0x0000, + 0x0000, 0xE673, 0x0000, 0x90BE, 0x0000, 0x9261, + 0x0000, 0x0000, 0x9755, 0x0000, 0xE676, 0x0000, + 0x0000, 0x0000, 0x8CEA, 0x0000, 0x90BD, 0xE672, + 0x0000, 0xE677, 0x8CEB, 0xE674, 0xE675, 0x0000, + 0xE671, 0x0000, 0x0000, 0x0000, 0x90E0, 0x93C7, + 0x0000, 0x0000, 0x924E, 0x0000, 0x89DB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x94EE, + 0x0000, 0x0000, 0x8B62, 0x0000, 0x0000, 0x92B2, + 0x0000, 0x0000, 0xE67A, 0x0000, 0xE678, 0x0000, + 0x0000, 0x926B, 0x0000, 0x0000, 0x0000, 0x90BF, + 0x8AD0, 0xE679, 0x0000, 0x907A, 0x0000, 0x0000, + 0x97C8, 0x0000, 0x0000, 0x0000, 0x985F, 0x0000, + 0x0000, 0x0000, 0xE67B, 0xE687, 0x92B3, 0x0000, + 0xE686, 0x0000, 0xE683, 0xE68B, 0xE684, 0x0000, + 0xE680, 0x0000, 0x92FA, 0xE67E, 0x0000, 0x0000, + 0x0000, 0xE67C, 0x0000, 0x9740, 0x8E90, 0x0000, + 0x0000, 0xE681, 0x0000, 0xE67D, 0x0000, 0x0000, + 0x0000, 0xE685, 0x8F94, 0x0000, 0x8CBF, 0x0000, + 0x0000, 0x0000, 0x91F8, 0x0000 +}; + +static u16 Ucs8B[256] = { + 0x9664, 0x8979, 0x88E0, 0x0000, 0x93A3, 0x0000, + 0x0000, 0xE689, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE688, 0x0000, 0x93E4, 0x0000, 0xE68D, 0x0000, + 0x0000, 0x0000, 0xE682, 0x0000, 0xE68C, 0xE68E, + 0x0000, 0x8CAA, 0xE68A, 0x8D75, 0x0000, 0x8ED3, + 0x0000, 0x0000, 0xE68F, 0x9777, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE692, 0x0000, 0xE695, 0x0000, + 0x0000, 0xE693, 0x9554, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE690, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8BDE, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE694, 0x0000, 0x0000, 0xE696, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE69A, 0x0000, 0x0000, 0xE697, 0x0000, + 0xE699, 0xE698, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE69B, 0x0000, 0x8EAF, 0x0000, + 0xE69D, 0xE69C, 0x9588, 0x0000, 0x0000, 0xE69F, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8C78, 0x0000, 0x0000, 0x0000, 0x0000, 0xE69E, + 0xE6A0, 0x0000, 0x0000, 0xE6A1, 0x8B63, 0xE3BF, + 0x8FF7, 0x0000, 0xE6A2, 0x0000, 0x0000, 0x8CEC, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE6A3, + 0x0000, 0x0000, 0xE6A4, 0x0000, 0x0000, 0x8E5D, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9DCC, 0x0000, 0xE6A5, 0x0000, 0xE6A6, 0x0000, + 0x8F51, 0x0000, 0xE6A7, 0xE6A8, 0x0000, 0x0000, + 0xE6A9, 0x0000, 0x0000, 0xE6AA, 0xE6AB, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs8C[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x924A, 0x0000, 0x0000, 0xE6AC, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE6AE, 0x0000, 0xE6AD, + 0x0000, 0x0000, 0x0000, 0x0000, 0x93A4, 0x0000, + 0xE6AF, 0x0000, 0x964C, 0x0000, 0xE6B0, 0x0000, + 0xE6B1, 0x0000, 0xE6B2, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE6B3, 0x0000, 0x0000, 0x0000, 0x0000, + 0x93D8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8FDB, 0xE6B4, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8D8B, 0x98AC, + 0xE6B5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE6B6, 0x955E, 0xE6B7, 0x0000, 0xE6BF, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE6B8, 0x0000, + 0x0000, 0xE6BA, 0x0000, 0x0000, 0x0000, 0xE6B9, + 0xE6BB, 0x0000, 0x9665, 0xE6BC, 0xE6BD, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE6BE, 0x0000, + 0x0000, 0x0000, 0xE6C0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8A4C, 0x92E5, 0x0000, 0x9589, 0x8DE0, + 0x8D76, 0x0000, 0x0000, 0x0000, 0x0000, 0x956E, + 0x89DD, 0x94CC, 0xE6C3, 0x8AD1, 0x90D3, 0xE6C2, + 0xE6C7, 0x9299, 0x96E1, 0x0000, 0xE6C5, 0xE6C6, + 0x8B4D, 0x0000, 0xE6C8, 0x9483, 0x91DD, 0x0000, + 0x0000, 0x94EF, 0x935C, 0xE6C4, 0x0000, 0x9666, + 0x89EA, 0xE6CA, 0x9847, 0x92C0, 0x9864, 0x0000, + 0x0000, 0x8E91, 0xE6C9, 0x0000, 0x91AF, 0x0000, + 0x0000, 0xE6DA, 0x9147, 0x0000, 0x0000, 0x93F6, + 0x0000, 0x956F, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE6CD, 0x8E5E, 0x8E92, 0x0000, + 0x8FDC, 0x0000, 0x9485, 0x0000, 0x8CAB, 0xE6CC, + 0xE6CB, 0x0000, 0x958A, 0x0000, 0x0000, 0x0000, + 0x8EBF, 0x0000, 0x0000, 0x9371, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE6CF, 0xE6D0, + 0x8D77, 0xE6CE, 0x0000, 0x0000 +}; + +static u16 Ucs8D[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0xE6D1, 0xE6D2, + 0x0000, 0xE6D4, 0x91A1, 0x0000, 0xE6D3, 0x8AE4, + 0x0000, 0xE6D6, 0x0000, 0xE6D5, 0xE6D7, 0x0000, + 0x0000, 0xE6D9, 0xE6DB, 0x0000, 0xE6DC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x90D4, 0x0000, + 0x8ECD, 0xE6DD, 0x0000, 0x0000, 0x0000, 0x8A71, + 0x0000, 0xE6DE, 0x0000, 0x0000, 0x9196, 0xE6DF, + 0x0000, 0xE6E0, 0x958B, 0x0000, 0x0000, 0x8B4E, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE6E1, 0x0000, 0x0000, + 0x0000, 0x92B4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x897A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE6E2, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8EEF, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9096, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x91AB, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE6E5, 0x0000, 0x0000, 0x0000, 0xE6E4, 0x0000, + 0x0000, 0x0000, 0xE6E3, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE6EB, + 0xE6E9, 0x0000, 0x0000, 0xE6E6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE6E8, 0x0000, + 0x0000, 0x0000, 0xE6E7, 0xE6EA, 0x0000, 0x8B97, + 0x0000, 0xE6EE, 0x0000, 0x90D5, 0x0000, 0xE6EF, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8CD7, 0x0000, + 0xE6EC, 0xE6ED, 0x0000, 0x0000, 0x0000, 0x9848, + 0x0000, 0x0000, 0x0000, 0x92B5, 0x0000, 0x9148, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE6F0, 0x0000, 0x0000, 0xE6F3 +}; + +static u16 Ucs8E[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE6F1, 0xE6F2, 0x9778, 0x0000, + 0x0000, 0x0000, 0x0000, 0x93A5, 0xE6F6, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE6F4, + 0xE6F5, 0xE6F7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE748, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE6FA, 0x0000, 0x0000, 0x0000, 0xE6FB, 0xE6F9, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE6F8, 0x0000, 0x92FB, 0x0000, 0x0000, 0xE740, + 0xE744, 0xE741, 0xE6FC, 0x0000, 0xE742, 0x0000, + 0x0000, 0x0000, 0xE743, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE74A, 0x0000, 0x0000, 0x0000, 0xE745, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x90D6, + 0xE747, 0x0000, 0x0000, 0xE749, 0xE746, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE74C, 0x0000, 0x8F52, 0x0000, 0xE74B, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE74D, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE74E, 0x0000, 0x0000, + 0xE751, 0xE750, 0x0000, 0xE74F, 0x0000, 0x0000, + 0xE753, 0xE752, 0x0000, 0x96F4, 0x0000, 0x0000, + 0x0000, 0xE755, 0x0000, 0xE754, 0xE756, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE757, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE759, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE758, 0x9067, 0xE75A, 0x0000, + 0x0000, 0x8BEB, 0xE75B, 0xE75D, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE75E, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE75F, + 0xE75C, 0x0000, 0xE760, 0x0000, 0x8ED4, 0xE761, + 0x8B4F, 0x8C52, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8CAC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE762, 0x0000, 0x0000, + 0x0000, 0x93EE, 0x0000, 0x0000, 0x935D, 0xE763, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE766, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8EB2, 0x0000, 0x0000, 0xE765, + 0xE764, 0x8C79, 0xE767, 0x0000 +}; + +static u16 Ucs8F[256] = { + 0x0000, 0x0000, 0x0000, 0x8A72, 0x0000, 0xE769, + 0x0000, 0x0000, 0x0000, 0x8DDA, 0xE768, 0x0000, + 0xE771, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE76B, 0xE76D, 0x95E3, 0xE76A, 0x0000, 0x0000, + 0x0000, 0xE76C, 0x0000, 0xE770, 0xE76E, 0x8B50, + 0x0000, 0xE76F, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE772, 0x0000, 0x0000, 0x9479, + 0x97D6, 0x0000, 0x0000, 0x0000, 0x0000, 0x8F53, + 0x0000, 0x0000, 0x0000, 0xE773, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9741, 0xE775, 0x0000, 0xE774, + 0x0000, 0x0000, 0xE778, 0x9760, 0x0000, 0x0000, + 0xE777, 0x0000, 0x8A8D, 0xE776, 0xE77B, 0x0000, + 0x0000, 0xE77A, 0x0000, 0x0000, 0xE779, 0x9351, + 0xE77C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE77D, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE77E, 0x0000, 0x0000, 0x8D8C, + 0x0000, 0x8C44, 0xE780, 0xE781, 0xE782, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9068, + 0xE783, 0x0000, 0x8EAB, 0xE784, 0x0000, 0x0000, + 0x0000, 0xE785, 0x0000, 0x0000, 0x0000, 0x999F, + 0x999E, 0x0000, 0x0000, 0x0000, 0x0000, 0xE786, + 0xE390, 0xE787, 0x9243, 0x904A, 0x945F, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE788, 0x0000, 0x0000, + 0x95D3, 0x92D2, 0x8D9E, 0x0000, 0x0000, 0x9248, + 0x0000, 0x0000, 0x8949, 0x0000, 0x9698, 0x9076, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8C7D, 0x0000, 0x0000, 0x8BDF, + 0x0000, 0x0000, 0x95D4, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE789, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE78B, 0x0000, + 0x0000, 0xE78A, 0x89DE, 0x0000, 0x0000, 0x93F4, + 0xE78C, 0x9497, 0x0000, 0x9352, 0x0000, 0xE78D, + 0x8F71, 0x0000, 0x0000, 0x0000, 0xE78F, 0x0000, + 0x0000, 0x96C0, 0xE79E, 0xE791, 0xE792, 0x0000, + 0x0000, 0x92C7, 0x0000, 0x0000 +}; + +static u16 Ucs90[256] = { + 0x91DE, 0x9197, 0x0000, 0x93A6, 0x0000, 0xE790, + 0x8B74, 0x0000, 0x0000, 0x0000, 0x0000, 0xE799, + 0x0000, 0xE796, 0xE7A3, 0x93A7, 0x9280, 0xE793, + 0x0000, 0x92FC, 0x9372, 0xE794, 0xE798, 0x9080, + 0x0000, 0x9487, 0x92CA, 0x0000, 0x0000, 0x90C0, + 0xE797, 0x91AC, 0x91A2, 0xE795, 0x88A7, 0x9841, + 0x0000, 0x0000, 0x0000, 0xE79A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x91DF, 0x0000, + 0x0000, 0x8F54, 0x9069, 0x0000, 0x0000, 0xE79C, + 0xE79B, 0x0000, 0x88ED, 0xE79D, 0x0000, 0x0000, + 0x954E, 0x0000, 0xE7A5, 0x0000, 0x0000, 0x93D9, + 0x908B, 0x0000, 0x0000, 0x9278, 0x0000, 0x8BF6, + 0x0000, 0xE7A4, 0x9756, 0x895E, 0x0000, 0x95D5, + 0x89DF, 0xE79F, 0xE7A0, 0xE7A1, 0xE7A2, 0x93B9, + 0x9242, 0x88E1, 0xE7A6, 0x0000, 0xE7A7, 0xEAA1, + 0x0000, 0x0000, 0x91BB, 0x0000, 0xE7A8, 0x0000, + 0x8993, 0x916B, 0x0000, 0x8CAD, 0x0000, 0x9779, + 0x0000, 0x0000, 0xE7A9, 0x934B, 0x0000, 0x0000, + 0x0000, 0x9198, 0x8ED5, 0xE7AA, 0x0000, 0x0000, + 0xE7AD, 0x0000, 0x0000, 0x8F85, 0xE7AB, 0x914A, + 0x9149, 0x0000, 0x88E2, 0x0000, 0x97C9, 0xE7AF, + 0x0000, 0x94F0, 0xE7B1, 0xE7B0, 0xE7AE, 0xE284, + 0x8AD2, 0x0000, 0x0000, 0xE78E, 0x0000, 0xE7B3, + 0xE7B2, 0x0000, 0x0000, 0x0000, 0x0000, 0xE7B4, + 0x0000, 0x9757, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x93DF, 0x0000, 0x0000, 0x964D, 0x0000, + 0xE7B5, 0x0000, 0x8ED7, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE7B6, 0x0000, 0xE7B7, 0x0000, 0x0000, + 0x0000, 0xE7B8, 0x0000, 0x0000, 0x9340, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x88E8, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8D78, 0x0000, + 0x0000, 0x0000, 0x9859, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE7BC, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8C53, 0xE7B9, 0x0000, + 0xE7BA, 0x0000, 0x0000, 0x0000, 0x9594, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8A73, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9758, + 0x0000, 0x8BBD, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9373, 0x0000, 0x0000 +}; + +static u16 Ucs91[256] = { + 0x0000, 0x0000, 0xE7BD, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE7BE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE7BF, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9341, 0x0000, 0x0000, + 0xE7C1, 0x0000, 0xE7C0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x93D1, 0xE7C2, 0x8F55, 0x8EDE, 0x947A, + 0x9291, 0x0000, 0x0000, 0x0000, 0x8EF0, 0x0000, + 0x908C, 0x0000, 0xE7C3, 0x0000, 0xE7C4, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x907C, 0xE7C5, 0x0000, 0xE7C6, + 0x0000, 0x0000, 0x0000, 0xE7C7, 0x978F, 0x0000, + 0x8F56, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE7C9, 0xE7C8, 0x0000, 0x8D79, 0x0000, 0x8D93, + 0x8E5F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE7CC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8F86, 0x0000, 0xE7CB, + 0x0000, 0xE7CA, 0x0000, 0x91E7, 0x0000, 0x0000, + 0x8CED, 0x0000, 0x90C1, 0x0000, 0x0000, 0x0000, + 0x0000, 0x94AE, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8F58, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE7CD, 0x0000, 0x8FDD, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE7D0, 0xE7CE, 0x0000, 0x0000, + 0x0000, 0xE7CF, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE7D2, 0xE7D1, 0x0000, 0x0000, 0x8FF8, 0x0000, + 0xE7D3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE7D4, 0xE7D5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x94CE, 0x8DD1, 0x8EDF, 0xE7D6, 0x0000, 0xE7D7, + 0x97A2, 0x8F64, 0x96EC, 0x97CA, 0xE7D8, 0x8BE0, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE7D9, 0x0000, + 0x9342, 0x0000, 0x0000, 0xE7DC, 0x8A98, 0x906A, + 0x0000, 0xE7DA, 0x0000, 0xE7DB, 0x0000, 0x92DE, + 0x0000, 0x0000, 0x9674, 0x8BFA, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE7DE, + 0xE7DF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE7DD, 0x0000, 0x0000, 0xE7E1 +}; + +static u16 Ucs92[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x93DD, 0x8A62, 0x0000, 0x0000, 0xE7E5, + 0x0000, 0x0000, 0xE7E2, 0xE7E4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE7E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE86E, + 0x0000, 0x0000, 0xE7E3, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x97E9, 0x0000, + 0x0000, 0x8CD8, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE7ED, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9353, 0xE7E8, 0x0000, 0x0000, + 0xE7EB, 0xE7E9, 0x0000, 0xE7EE, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE7EF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE7E7, 0x0000, 0x0000, + 0xE7F4, 0x8994, 0x0000, 0x0000, 0xE7E6, 0x0000, + 0x0000, 0x0000, 0x94AB, 0x0000, 0xE7EA, 0x0000, + 0x8FDE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8D7A, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9667, 0x0000, 0x8BE2, 0x0000, 0x0000, 0x8F65, + 0x0000, 0x93BA, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x914C, 0x0000, 0xE7F2, 0x0000, 0xE7EC, + 0xE7F1, 0x0000, 0x96C1, 0x0000, 0x92B6, 0xE7F3, + 0xE7F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x914B, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE7F7, 0x0000, 0xE7F6, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE7F5, 0x0000, 0x0000, + 0x964E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8F9B, 0x0000, 0x0000, 0x0000, 0x0000, 0xE7F8, + 0x95DD, 0x0000, 0x0000, 0x8973, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9565, 0x9292, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8B98, 0x0000, 0xE7FA, 0x0000, + 0x8D7C, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs93[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8E4B, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE7F9, 0x908D, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x908E, 0xE840, 0xE842, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8FF9, 0x0000, 0xE841, 0xE843, + 0x0000, 0x0000, 0x8BD1, 0x0000, 0x9564, 0x0000, + 0x0000, 0x8EE0, 0x9842, 0x0000, 0xE7FC, 0x8DF6, + 0x0000, 0x0000, 0x985E, 0x0000, 0x0000, 0xE845, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE844, 0xE846, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE7FB, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x93E7, 0x0000, 0x9374, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x92D5, 0x0000, 0xE84B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x9262, 0xE847, 0x0000, 0x0000, 0x0000, + 0xE848, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8C4C, 0x0000, 0xE84A, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8CAE, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE849, 0x0000, + 0x8FDF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8A99, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE84F, 0x0000, + 0x8DBD, 0x9199, 0x0000, 0x0000, 0x92C8, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8A5A, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE84D, 0xE84E, + 0x92C1, 0x0000, 0xE84C, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE850, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE856, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE859, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE858, 0x934C, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE851, 0xE852, + 0xE855, 0x0000, 0x0000, 0x0000, 0x0000, 0xE857, + 0x0000, 0x0000, 0x0000, 0x8BBE, 0x0000, 0x0000, + 0xE85A, 0xE854, 0x0000, 0x0000, 0xE853, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs94[256] = { + 0x0000, 0x0000, 0x0000, 0xE85E, 0x0000, 0x0000, + 0x0000, 0xE85F, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE860, 0x0000, + 0x0000, 0xE85D, 0xE85C, 0x0000, 0x0000, 0x0000, + 0x8FE0, 0x93A8, 0xE85B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE864, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE862, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE863, + 0xE861, 0x0000, 0x91F6, 0x0000, 0xE865, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE866, + 0x0000, 0x0000, 0xE868, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8AD3, 0xE867, 0x96F8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE873, 0xE869, 0x0000, 0x0000, 0xE86C, 0x0000, + 0xE86A, 0x0000, 0xE86B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE86D, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE86F, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE870, 0x0000, 0xE871, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE874, 0xE872, + 0xE875, 0xE877, 0x0000, 0xE876, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs95[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x92B7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x96E5, 0x0000, 0xE878, 0x914D, + 0x0000, 0x0000, 0x0000, 0xE879, 0x0000, 0x95C2, + 0xE87A, 0x8A4A, 0x0000, 0x0000, 0x0000, 0x895B, + 0x0000, 0x8AD5, 0x0000, 0x8AD4, 0xE87B, 0x0000, + 0xE87C, 0x0000, 0xE87D, 0xE87E, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE880, 0x0000, + 0x8AD6, 0x8A74, 0x8D7D, 0x94B4, 0x0000, 0xE882, + 0xE881, 0x0000, 0x0000, 0x0000, 0x0000, 0xE883, + 0x0000, 0x0000, 0x0000, 0x0000, 0x897B, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE886, + 0x0000, 0xE885, 0xE884, 0x0000, 0xE887, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE88A, 0x0000, 0x0000, + 0x0000, 0x88C5, 0x0000, 0x0000, 0xE888, 0x0000, + 0xE88C, 0xE88B, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE88E, 0xE88D, 0xE88F, 0x0000, + 0x93AC, 0x0000, 0x0000, 0x0000, 0xE890, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE891, 0xE893, 0x0000, + 0x0000, 0xE892, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs96[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x958C, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE894, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE895, 0x0000, + 0x8DE3, 0x0000, 0x0000, 0x0000, 0xE896, 0xE897, + 0x0000, 0x0000, 0x9668, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x916A, + 0x0000, 0x0000, 0x0000, 0x88A2, 0x91C9, 0x0000, + 0xE898, 0x0000, 0x958D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE89B, 0xE899, 0x8D7E, + 0x0000, 0xE89A, 0x8CC0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x95C3, 0xE89D, 0xE89F, 0xE89E, 0xE8A0, + 0x0000, 0x0000, 0x8940, 0x9077, 0x8F9C, 0x8AD7, + 0xE8A1, 0x0000, 0x0000, 0x0000, 0x9486, 0x0000, + 0xE8A3, 0x0000, 0x0000, 0x0000, 0x8941, 0x0000, + 0xE8A2, 0x92C2, 0x0000, 0x97CB, 0x93A9, 0xE89C, + 0x97A4, 0x0000, 0x8CAF, 0x0000, 0x0000, 0x977A, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8BF7, 0x97B2, 0x0000, 0x8C47, 0x0000, + 0x91E0, 0xE440, 0x0000, 0xE8A4, 0x8A4B, 0x908F, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8A75, 0xE8A6, + 0x0000, 0xE8A7, 0xE8A5, 0x8C84, 0x0000, 0x8DDB, + 0x8FE1, 0x0000, 0x0000, 0x0000, 0x8942, 0x0000, + 0x0000, 0x97D7, 0x0000, 0x0000, 0x0000, 0xE8A9, + 0xE7AC, 0x0000, 0xE8A8, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE8AC, 0xE8AA, 0xE8AB, 0x0000, + 0xE8AD, 0x0000, 0xE8AE, 0x97EA, 0xE8AF, 0xE8B0, + 0x0000, 0x90C7, 0x94B9, 0x0000, 0x0000, 0x0000, + 0x909D, 0x8AE5, 0x0000, 0x0000, 0x9759, 0x89EB, + 0x8F57, 0x8CD9, 0x0000, 0xE8B3, 0x0000, 0xE8B2, + 0x8E93, 0xE8B4, 0xE8B1, 0x0000, 0x0000, 0x8E47, + 0x0000, 0x0000, 0x0000, 0xE8B8, 0xE5AB, 0x0000, + 0x0000, 0x99D4, 0x0000, 0x9097, 0xE8B6, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x97A3, 0x93EF, + 0x0000, 0x0000, 0x0000, 0x0000, 0x894A, 0x0000, + 0x90E1, 0x8EB4, 0x0000, 0x0000, 0x0000, 0x0000, + 0x95B5, 0x0000, 0x895F, 0x0000, 0x0000, 0x0000, + 0x97EB, 0x978B, 0x0000, 0xE8B9, 0x0000, 0x9364, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs97[256] = { + 0x8EF9, 0x0000, 0x0000, 0x0000, 0xE8BA, 0x0000, + 0xE8BB, 0x906B, 0xE8BC, 0x0000, 0x97EC, 0x0000, + 0x0000, 0xE8B7, 0xE8BE, 0xE8C0, 0x0000, 0xE8BF, + 0x0000, 0xE8BD, 0x0000, 0x0000, 0xE8C1, 0x0000, + 0x0000, 0xE8C2, 0x0000, 0x0000, 0x919A, 0x0000, + 0x89E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE8C3, 0x0000, 0x0000, 0x96B6, 0x0000, 0x0000, + 0xE8C4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE8C5, 0x0000, 0x9849, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9E50, 0xE8C6, 0x0000, 0x0000, + 0x0000, 0xE8C7, 0xE8C8, 0x0000, 0x0000, 0x0000, + 0xE8CC, 0x0000, 0xE8C9, 0x0000, 0xE8CA, 0x0000, + 0xE8CB, 0xE8CD, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x90C2, 0x0000, + 0x0000, 0x0000, 0x96F5, 0x0000, 0x0000, 0x90C3, + 0x0000, 0x0000, 0xE8CE, 0x0000, 0x94F1, 0x0000, + 0xE8CF, 0xEA72, 0x96CA, 0x0000, 0xE8D0, 0x0000, + 0xE8D1, 0x0000, 0xE8D2, 0x8A76, 0x0000, 0xE8D4, + 0x0000, 0x9078, 0x0000, 0x0000, 0x0000, 0xE8D5, + 0x0000, 0x0000, 0x8C43, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE8D6, 0xE8DA, 0x0000, 0xE8D8, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE8D9, 0x0000, 0x0000, + 0x8A93, 0xE8D7, 0xE8DB, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE8DC, 0x0000, 0x88C6, 0x0000, 0xE8DD, + 0xE8DE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8FE2, 0x0000, 0x0000, 0x0000, + 0xE8DF, 0x0000, 0x0000, 0x0000, 0x8B66, 0x0000, + 0x0000, 0xE8E2, 0x0000, 0x0000, 0xE8E1, 0x0000, + 0xE8E0, 0x0000, 0x0000, 0xE691, 0x0000, 0x95DA, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE8E3, + 0xE8E4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE8E5, 0x0000, 0x0000, + 0xE8E6, 0x0000, 0xE8E7, 0x0000, 0x0000, 0xE8E8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8AD8, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE8E9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE8EA, 0x9442, 0x0000, + 0x0000, 0x0000, 0xE8EC, 0x89B9, 0x0000, 0xE8EF, + 0xE8EE, 0x0000, 0x0000, 0x0000, 0x0000, 0x8943, + 0x0000, 0x0000, 0x0000, 0x8BBF +}; + +static u16 Ucs98[256] = { + 0x0000, 0x95C5, 0x92B8, 0x8DA0, 0x0000, 0x8D80, + 0x8F87, 0x0000, 0x907B, 0x0000, 0x0000, 0x0000, + 0xE8F1, 0x0000, 0x0000, 0xE8F0, 0x9761, 0x8AE6, + 0x94D0, 0x93DA, 0x0000, 0x0000, 0x0000, 0x909C, + 0x97CC, 0x0000, 0x8C7A, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE8F4, 0x0000, 0x0000, + 0xE8F3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x966A, 0x93AA, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x896F, 0x0000, + 0x0000, 0xE8F5, 0xE8F2, 0x0000, 0x0000, 0x9570, + 0x978A, 0xE8F6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE8F7, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE8F9, 0x91E8, 0x8A7A, + 0x8A7B, 0xE8F8, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8AE7, 0x8CB0, 0x0000, 0x0000, 0x8AE8, 0x0000, + 0x0000, 0x935E, 0x0000, 0x0000, 0x97DE, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8CDA, 0x0000, 0x0000, 0x0000, 0xE8FA, + 0x0000, 0x0000, 0x0000, 0xE8FB, 0xE8FC, 0xE940, + 0x0000, 0xE942, 0xE941, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9597, 0x0000, 0xE943, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE944, 0x0000, 0xE945, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE946, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE948, 0xE947, 0x0000, + 0xE949, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x94F2, 0xE3CA, 0x0000, + 0x0000, 0x9048, 0x0000, 0x0000, 0x8B51, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE94A, + 0x0000, 0xE94B, 0x0000, 0x99AA, 0x9F5A, 0x94D1, + 0x0000, 0x0000, 0x88F9, 0x0000, 0x88B9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8E94, 0x964F, 0x8FFC, 0x0000 +}; + +static u16 Ucs99[256] = { + 0x0000, 0x0000, 0x0000, 0xE94C, 0x0000, 0x96DD, + 0x0000, 0x0000, 0x0000, 0xE94D, 0x977B, 0x0000, + 0x8961, 0x0000, 0x0000, 0x0000, 0x8E60, 0x0000, + 0xE94E, 0x89EC, 0xE94F, 0x0000, 0x0000, 0x0000, + 0xE950, 0x0000, 0x0000, 0x0000, 0x0000, 0xE952, + 0xE953, 0x0000, 0xE955, 0xE951, 0x0000, 0x0000, + 0xE954, 0x0000, 0x0000, 0x0000, 0x8AD9, 0x0000, + 0x0000, 0x0000, 0xE956, 0x0000, 0xE957, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE958, 0xE959, 0x0000, 0x0000, 0x0000, + 0xE95A, 0x0000, 0x0000, 0xE95C, 0x0000, 0x0000, + 0x0000, 0xE95B, 0x0000, 0xE95E, 0xE961, 0x0000, + 0x0000, 0x0000, 0xE95D, 0xE95F, 0xE960, 0x0000, + 0x0000, 0xE962, 0x0000, 0x8BC0, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8EF1, 0xE963, 0xE964, 0x8D81, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE965, 0x0000, 0x0000, + 0x8A5D, 0x0000, 0x0000, 0x0000, 0x946E, 0xE966, + 0xE967, 0x0000, 0x0000, 0x0000, 0x0000, 0x9279, + 0x93E9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE968, 0x0000, 0x0000, 0x0000, + 0x0000, 0x949D, 0x0000, 0x0000, 0x91CA, 0x8977, + 0x8BEC, 0x0000, 0x8BED, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9293, 0xE96D, + 0x8BEE, 0x0000, 0x0000, 0x89ED, 0x0000, 0x0000, + 0xE96C, 0x0000, 0x0000, 0xE96A, 0x0000, 0xE96B, + 0x0000, 0xE969, 0x0000, 0x0000, 0xE977, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE96E, 0xE96F, 0x0000, + 0x0000, 0xE970, 0xE971, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE973, 0x0000, 0x0000, 0xE972, + 0x0000, 0x0000, 0x0000, 0x8F78 +}; + +static u16 Ucs9A[256] = { + 0x0000, 0xE974, 0x0000, 0x0000, 0x0000, 0xE976, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8B52, 0xE975, 0x0000, 0x0000, + 0x919B, 0x8CB1, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE978, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x91CB, 0x0000, + 0x0000, 0xE979, 0x0000, 0x0000, 0x0000, 0x0000, + 0x93AB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE97A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE980, 0x0000, 0xE97D, 0x0000, + 0xE97C, 0xE97E, 0x0000, 0xE97B, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE982, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE981, 0x0000, 0xE984, 0x0000, 0x0000, + 0x8BC1, 0xE983, 0x0000, 0x0000, 0x0000, 0xE985, + 0x0000, 0x0000, 0xE986, 0x0000, 0xE988, 0xE987, + 0x0000, 0x0000, 0x0000, 0xE989, 0xE98B, 0xE98A, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x8D9C, 0x0000, 0x0000, 0x0000, 0x0000, 0xE98C, + 0x0000, 0x0000, 0xE98D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8A5B, 0x0000, + 0x0000, 0x0000, 0xE98E, 0x0000, 0x0000, 0x0000, + 0xE98F, 0x0000, 0x0000, 0x0000, 0x9091, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE990, 0x0000, 0xE991, + 0x0000, 0xE992, 0xE993, 0x0000, 0x0000, 0x0000, + 0x8D82, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE994, 0xE995, 0x0000, 0x0000, 0xE996, 0xE997, + 0x0000, 0x0000, 0xE998, 0x0000, 0x0000, 0x0000, + 0x94AF, 0xE99A, 0x0000, 0x9545, 0xE99B, 0xE999, + 0x0000, 0xE99D, 0x0000, 0x0000, 0xE99C, 0x0000, + 0x0000, 0xE99E, 0x0000, 0x0000, 0x0000, 0xE99F, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs9B[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE9A0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE9A1, 0x0000, 0xE9A2, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE9A3, 0x0000, 0x0000, 0xE9A4, 0xE9A5, + 0x0000, 0xE9A6, 0x0000, 0xE9A7, 0xE9A8, 0xE9A9, + 0xE9AA, 0x0000, 0x0000, 0x0000, 0xE9AB, 0xE9AC, + 0x0000, 0x9F54, 0xE9AD, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE2F6, + 0x8B53, 0x0000, 0x0000, 0x0000, 0x0000, 0x8A40, + 0x8DB0, 0xE9AF, 0xE9AE, 0x96A3, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE9B1, + 0xE9B2, 0xE9B0, 0x0000, 0xE9B3, 0x0000, 0x0000, + 0x9682, 0x0000, 0x0000, 0x0000, 0xE9B4, 0x0000, + 0x8B9B, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9844, 0x0000, 0x0000, + 0x0000, 0x0000, 0xE9B5, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE9B7, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x88BC, 0x0000, + 0x0000, 0xE9B8, 0x95A9, 0xE9B6, 0x0000, 0x0000, + 0xE9B9, 0xE9BA, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE9BB, 0xE9BC, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE9BD, 0x0000, 0x968E, 0x8E4C, 0x0000, 0x8DF8, + 0x914E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE9BE, 0x0000, 0x0000, 0x0000, 0x0000, 0xE9C1, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE9BF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE9C2, 0x0000, 0x0000, 0x8CEF, 0xE9C0, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE9C3, 0x0000, 0xE9C4, + 0xE9C5, 0x0000, 0xE9C9, 0x0000, 0x8E49, 0x0000, + 0x0000, 0x0000, 0x0000, 0x91E2, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE9CA, 0xE9C7, 0xE9C6, + 0xE9C8, 0x0000, 0x0000, 0x0000, 0x8C7E, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE9CE, 0xE9CD, 0xE9CC, 0x0000, 0x0000, 0x88B1, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs9C[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0xE9D8, 0x0000, + 0xE9D4, 0x0000, 0xE9D5, 0xE9D1, 0xE9D7, 0x0000, + 0xE9D3, 0x8A82, 0x0000, 0x0000, 0x986B, 0x0000, + 0xE9D6, 0xE9D2, 0xE9D0, 0xE9CF, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE9DA, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xE9DD, 0x0000, 0x0000, + 0xE9DC, 0xE9DB, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x9568, 0xE9D9, 0x88F1, + 0xE9DE, 0x0000, 0xE9E0, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8A8F, 0xE9CB, 0x8956, + 0x0000, 0x0000, 0xE9E2, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE9E1, 0xE9DF, + 0x924C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9690, 0x0000, + 0x0000, 0x0000, 0x0000, 0x97D8, 0x0000, 0x0000, + 0xE9E3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xE9E4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xE9E5, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xE9E6, 0x0000, + 0xE9E7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x92B9, 0x0000, 0xE9E8, 0x0000, 0x94B5, + 0x0000, 0xE9ED, 0xE9E9, 0x0000, 0x0000, 0x0000, + 0xE9EA, 0x0000, 0x0000, 0x9650, 0x96C2, 0x0000, + 0x93CE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Ucs9D[256] = { + 0x0000, 0x0000, 0x0000, 0xE9EE, 0x0000, 0x0000, + 0xE9EF, 0x93BC, 0xE9EC, 0xE9EB, 0x0000, 0x0000, + 0x0000, 0x0000, 0x89A8, 0x0000, 0x0000, 0x0000, + 0xE9F7, 0x0000, 0x0000, 0xE9F6, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x8995, 0x0000, 0x0000, + 0x0000, 0xE9F4, 0x0000, 0x0000, 0x0000, 0xE9F3, + 0x0000, 0x0000, 0xE9F1, 0x0000, 0x8A9B, 0x0000, + 0xE9F0, 0x8EB0, 0x89A7, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8D83, + 0x0000, 0x0000, 0xE9FA, 0xE9F9, 0x0000, 0xE9F8, + 0x0000, 0x0000, 0xE9F5, 0x0000, 0xE9FB, 0x0000, + 0xE9FC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xEA44, 0xEA43, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xEA45, + 0x0000, 0x0000, 0x894C, 0xEA40, 0xEA41, 0x0000, + 0x8D94, 0x96B7, 0x0000, 0x0000, 0xEA42, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x9651, 0x0000, 0x0000, 0xEA4A, 0x0000, 0x0000, + 0xEA46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xEA4B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xEA48, 0x0000, 0xEA47, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8C7B, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xEA4C, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xEA4D, 0x0000, 0x0000, 0x0000, + 0x0000, 0xEA4E, 0x0000, 0xEA49, 0x0000, 0x0000, + 0x0000, 0xE9F2, 0x0000, 0x0000, 0xEA4F, 0x0000, + 0x92DF, 0x0000, 0x0000, 0x0000, 0xEA53, 0x0000, + 0xEA54, 0xEA52, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xEA51, 0xEA57, 0x0000, 0xEA50, 0x0000, + 0xEA55, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xEA56, 0x0000, 0x0000, + 0x0000, 0xEA59, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xEA58, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xEA5B, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xEA5C, 0x0000, 0xEA5D, + 0x0000, 0x0000, 0x9868, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xEA5A, 0x91E9, 0x8DEB, 0x0000, + 0x0000, 0xEA5E, 0x0000, 0x0000 +}; + +static u16 Ucs9E[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xEA5F, 0xEA60, 0x0000, 0x0000, + 0xEA61, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xEA62, 0x0000, 0x0000, + 0x8CB2, 0xEA63, 0x0000, 0x0000, 0x0000, 0xEA64, + 0x0000, 0x8EAD, 0x0000, 0xEA65, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xEA66, 0x0000, + 0x0000, 0xEA67, 0xEA68, 0x0000, 0x0000, 0x0000, + 0x0000, 0xEA6B, 0xEA69, 0x985B, 0x0000, 0xEA6A, + 0x0000, 0x97ED, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xEA6C, 0x0000, 0x97D9, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xEA6D, 0x949E, 0x0000, + 0x0000, 0xEA6E, 0xEA70, 0x0000, 0x0000, 0xEA71, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xEA6F, 0x8D8D, + 0x96CB, 0x9683, 0x9BF5, 0x0000, 0x9F80, 0x969B, + 0x0000, 0x0000, 0x0000, 0x0000, 0x89A9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xEA73, 0x8B6F, 0xEA74, 0xEA75, 0xEA76, 0x0000, + 0x8D95, 0x0000, 0xEA77, 0x0000, 0x0000, 0x0000, + 0xE0D2, 0x96D9, 0x0000, 0x91E1, 0xEA78, 0xEA7A, + 0xEA79, 0x0000, 0xEA7B, 0x0000, 0x0000, 0x0000, + 0x0000, 0xEA7C, 0x0000, 0x0000, 0xEA7D, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xEA7E, + 0x0000, 0x0000, 0x0000, 0x0000, 0xEA80, 0x0000, + 0xEA81, 0xEA82, 0x0000, 0xEA83, 0x0000, 0xEA84, + 0xEA85, 0xEA86, 0x0000, 0x0000 +}; + +static u16 Ucs9F[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xEA87, 0xEA88, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x9343, 0x0000, 0x0000, 0x0000, + 0x0000, 0x8CDB, 0x0000, 0xEA8A, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x916C, 0xEA8B, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xEA8C, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9540, + 0x0000, 0x0000, 0xEA8D, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xEA8E, 0xE256, 0x0000, 0x0000, + 0xE6D8, 0xE8EB, 0x0000, 0x0000, 0xEA8F, 0x0000, + 0xEA90, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xEA92, + 0xEA93, 0xEA94, 0x97EE, 0xEA91, 0x0000, 0x0000, + 0xEA95, 0xEA96, 0x0000, 0x0000, 0xEA98, 0x0000, + 0xEA97, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xEA9A, 0x0000, 0x0000, 0x0000, 0xEA9B, 0xEA99, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x97B4, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xEA9C, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xEA9D, 0xE273, 0x0000, 0x0000, 0xEA9E, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 UcsFF[256] = { + 0x0000, 0x8149, 0x0000, 0x8194, 0x8190, 0x8193, + 0x8195, 0x0000, 0x8169, 0x816A, 0x8196, 0x817B, + 0x8143, 0x0000, 0x8144, 0x815E, 0x824F, 0x8250, + 0x8251, 0x8252, 0x8253, 0x8254, 0x8255, 0x8256, + 0x8257, 0x8258, 0x8146, 0x8147, 0x8183, 0x8181, + 0x8184, 0x8148, 0x8197, 0x8260, 0x8261, 0x8262, + 0x8263, 0x8264, 0x8265, 0x8266, 0x8267, 0x8268, + 0x8269, 0x826A, 0x826B, 0x826C, 0x826D, 0x826E, + 0x826F, 0x8270, 0x8271, 0x8272, 0x8273, 0x8274, + 0x8275, 0x8276, 0x8277, 0x8278, 0x8279, 0x816D, + 0x0000, 0x816E, 0x814F, 0x8151, 0x814D, 0x8281, + 0x8282, 0x8283, 0x8284, 0x8285, 0x8286, 0x8287, + 0x8288, 0x8289, 0x828A, 0x828B, 0x828C, 0x828D, + 0x828E, 0x828F, 0x8290, 0x8291, 0x8292, 0x8293, + 0x8294, 0x8295, 0x8296, 0x8297, 0x8298, 0x8299, + 0x829A, 0x816F, 0x8162, 0x8170, 0x0000, 0x0000, + 0x0000, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, + 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, + 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, + 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, + 0x00BE, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, + 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, + 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, + 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, + 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8150, + 0x0000, 0x818F, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16* UcsSjisTable[256] = {0}; + +u16 OSUTF32toSJIS(u32 utf32) { + u16* table; + + if (0x10000 <= utf32) { + return 0; + } + + table = UcsSjisTable[(utf32 >> 8) & 0xFF]; + if (table != 0) { + return table[utf32 & 0xFF]; + } + + return 0; +} + +static u16 Sjis00[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, + 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, + 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, + 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, + 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, + 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, + 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005A, 0x005B, 0x00A5, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, + 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, + 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, + 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, + 0x203E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFF61, + 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67, + 0xFF68, 0xFF69, 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, + 0xFF6E, 0xFF6F, 0xFF70, 0xFF71, 0xFF72, 0xFF73, + 0xFF74, 0xFF75, 0xFF76, 0xFF77, 0xFF78, 0xFF79, + 0xFF7A, 0xFF7B, 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F, + 0xFF80, 0xFF81, 0xFF82, 0xFF83, 0xFF84, 0xFF85, + 0xFF86, 0xFF87, 0xFF88, 0xFF89, 0xFF8A, 0xFF8B, + 0xFF8C, 0xFF8D, 0xFF8E, 0xFF8F, 0xFF90, 0xFF91, + 0xFF92, 0xFF93, 0xFF94, 0xFF95, 0xFF96, 0xFF97, + 0xFF98, 0xFF99, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D, + 0xFF9E, 0xFF9F, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis81[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x3000, 0x3001, + 0x3002, 0xFF0C, 0xFF0E, 0x30FB, 0xFF1A, 0xFF1B, + 0xFF1F, 0xFF01, 0x309B, 0x309C, 0x00B4, 0xFF40, + 0x00A8, 0xFF3E, 0xFFE3, 0xFF3F, 0x30FD, 0x30FE, + 0x309D, 0x309E, 0x3003, 0x4EDD, 0x3005, 0x3006, + 0x3007, 0x30FC, 0x2015, 0x2010, 0xFF0F, 0x005C, + 0x301C, 0x2016, 0xFF5C, 0x2026, 0x2025, 0x2018, + 0x2019, 0x201C, 0x201D, 0xFF08, 0xFF09, 0x3014, + 0x3015, 0xFF3B, 0xFF3D, 0xFF5B, 0xFF5D, 0x3008, + 0x3009, 0x300A, 0x300B, 0x300C, 0x300D, 0x300E, + 0x300F, 0x3010, 0x3011, 0xFF0B, 0x2212, 0x00B1, + 0x00D7, 0x0000, 0x00F7, 0xFF1D, 0x2260, 0xFF1C, + 0xFF1E, 0x2266, 0x2267, 0x221E, 0x2234, 0x2642, + 0x2640, 0x00B0, 0x2032, 0x2033, 0x2103, 0xFFE5, + 0xFF04, 0x00A2, 0x00A3, 0xFF05, 0xFF03, 0xFF06, + 0xFF0A, 0xFF20, 0x00A7, 0x2606, 0x2605, 0x25CB, + 0x25CF, 0x25CE, 0x25C7, 0x25C6, 0x25A1, 0x25A0, + 0x25B3, 0x25B2, 0x25BD, 0x25BC, 0x203B, 0x3012, + 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2208, 0x220B, + 0x2286, 0x2287, 0x2282, 0x2283, 0x222A, 0x2229, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2227, 0x2228, 0x00AC, 0x21D2, + 0x21D4, 0x2200, 0x2203, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x2220, 0x22A5, 0x2312, 0x2202, + 0x2207, 0x2261, 0x2252, 0x226A, 0x226B, 0x221A, + 0x223D, 0x221D, 0x2235, 0x222B, 0x222C, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x212B, 0x2030, 0x266F, 0x266D, 0x266A, 0x2020, + 0x2021, 0x00B6, 0x0000, 0x0000, 0x0000, 0x0000, + 0x25EF, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis82[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, + 0xFF15, 0xFF16, 0xFF17, 0xFF18, 0xFF19, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, + 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, + 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, + 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, + 0xFF39, 0xFF3A, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xFF41, 0xFF42, 0xFF43, + 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, + 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, + 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, + 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0x0000, + 0x0000, 0x0000, 0x0000, 0x3041, 0x3042, 0x3043, + 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, 0x3049, + 0x304A, 0x304B, 0x304C, 0x304D, 0x304E, 0x304F, + 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, + 0x3056, 0x3057, 0x3058, 0x3059, 0x305A, 0x305B, + 0x305C, 0x305D, 0x305E, 0x305F, 0x3060, 0x3061, + 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, + 0x3068, 0x3069, 0x306A, 0x306B, 0x306C, 0x306D, + 0x306E, 0x306F, 0x3070, 0x3071, 0x3072, 0x3073, + 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, 0x3079, + 0x307A, 0x307B, 0x307C, 0x307D, 0x307E, 0x307F, + 0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, + 0x3086, 0x3087, 0x3088, 0x3089, 0x308A, 0x308B, + 0x308C, 0x308D, 0x308E, 0x308F, 0x3090, 0x3091, + 0x3092, 0x3093, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis83[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x30A1, 0x30A2, + 0x30A3, 0x30A4, 0x30A5, 0x30A6, 0x30A7, 0x30A8, + 0x30A9, 0x30AA, 0x30AB, 0x30AC, 0x30AD, 0x30AE, + 0x30AF, 0x30B0, 0x30B1, 0x30B2, 0x30B3, 0x30B4, + 0x30B5, 0x30B6, 0x30B7, 0x30B8, 0x30B9, 0x30BA, + 0x30BB, 0x30BC, 0x30BD, 0x30BE, 0x30BF, 0x30C0, + 0x30C1, 0x30C2, 0x30C3, 0x30C4, 0x30C5, 0x30C6, + 0x30C7, 0x30C8, 0x30C9, 0x30CA, 0x30CB, 0x30CC, + 0x30CD, 0x30CE, 0x30CF, 0x30D0, 0x30D1, 0x30D2, + 0x30D3, 0x30D4, 0x30D5, 0x30D6, 0x30D7, 0x30D8, + 0x30D9, 0x30DA, 0x30DB, 0x30DC, 0x30DD, 0x30DE, + 0x30DF, 0x0000, 0x30E0, 0x30E1, 0x30E2, 0x30E3, + 0x30E4, 0x30E5, 0x30E6, 0x30E7, 0x30E8, 0x30E9, + 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EE, 0x30EF, + 0x30F0, 0x30F1, 0x30F2, 0x30F3, 0x30F4, 0x30F5, + 0x30F6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0391, 0x0392, 0x0393, + 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, + 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, + 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, + 0x03A7, 0x03A8, 0x03A9, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03B1, + 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, + 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, + 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C4, + 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis84[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0410, 0x0411, + 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416, + 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, + 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, + 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, + 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, + 0x042F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0430, 0x0431, + 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, + 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, + 0x043D, 0x0000, 0x043E, 0x043F, 0x0440, 0x0441, + 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, + 0x044E, 0x044F, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x2500, 0x2502, 0x250C, + 0x2510, 0x2518, 0x2514, 0x251C, 0x252C, 0x2524, + 0x2534, 0x253C, 0x2501, 0x2503, 0x250F, 0x2513, + 0x251B, 0x2517, 0x2523, 0x2533, 0x252B, 0x253B, + 0x254B, 0x2520, 0x252F, 0x2528, 0x2537, 0x253F, + 0x251D, 0x2530, 0x2525, 0x2538, 0x2542, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis88[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x4E9C, 0x5516, 0x5A03, + 0x963F, 0x54C0, 0x611B, 0x6328, 0x59F6, 0x9022, + 0x8475, 0x831C, 0x7A50, 0x60AA, 0x63E1, 0x6E25, + 0x65ED, 0x8466, 0x82A6, 0x9BF5, 0x6893, 0x5727, + 0x65A1, 0x6271, 0x5B9B, 0x59D0, 0x867B, 0x98F4, + 0x7D62, 0x7DBE, 0x9B8E, 0x6216, 0x7C9F, 0x88B7, + 0x5B89, 0x5EB5, 0x6309, 0x6697, 0x6848, 0x95C7, + 0x978D, 0x674F, 0x4EE5, 0x4F0A, 0x4F4D, 0x4F9D, + 0x5049, 0x56F2, 0x5937, 0x59D4, 0x5A01, 0x5C09, + 0x60DF, 0x610F, 0x6170, 0x6613, 0x6905, 0x70BA, + 0x754F, 0x7570, 0x79FB, 0x7DAD, 0x7DEF, 0x80C3, + 0x840E, 0x8863, 0x8B02, 0x9055, 0x907A, 0x533B, + 0x4E95, 0x4EA5, 0x57DF, 0x80B2, 0x90C1, 0x78EF, + 0x4E00, 0x58F1, 0x6EA2, 0x9038, 0x7A32, 0x8328, + 0x828B, 0x9C2F, 0x5141, 0x5370, 0x54BD, 0x54E1, + 0x56E0, 0x59FB, 0x5F15, 0x98F2, 0x6DEB, 0x80E4, + 0x852D, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis89[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9662, 0x9670, + 0x96A0, 0x97FB, 0x540B, 0x53F3, 0x5B87, 0x70CF, + 0x7FBD, 0x8FC2, 0x96E8, 0x536F, 0x9D5C, 0x7ABA, + 0x4E11, 0x7893, 0x81FC, 0x6E26, 0x5618, 0x5504, + 0x6B1D, 0x851A, 0x9C3B, 0x59E5, 0x53A9, 0x6D66, + 0x74DC, 0x958F, 0x5642, 0x4E91, 0x904B, 0x96F2, + 0x834F, 0x990C, 0x53E1, 0x55B6, 0x5B30, 0x5F71, + 0x6620, 0x66F3, 0x6804, 0x6C38, 0x6CF3, 0x6D29, + 0x745B, 0x76C8, 0x7A4E, 0x9834, 0x82F1, 0x885B, + 0x8A60, 0x92ED, 0x6DB2, 0x75AB, 0x76CA, 0x99C5, + 0x60A6, 0x8B01, 0x8D8A, 0x95B2, 0x698E, 0x53AD, + 0x5186, 0x0000, 0x5712, 0x5830, 0x5944, 0x5BB4, + 0x5EF6, 0x6028, 0x63A9, 0x63F4, 0x6CBF, 0x6F14, + 0x708E, 0x7114, 0x7159, 0x71D5, 0x733F, 0x7E01, + 0x8276, 0x82D1, 0x8597, 0x9060, 0x925B, 0x9D1B, + 0x5869, 0x65BC, 0x6C5A, 0x7525, 0x51F9, 0x592E, + 0x5965, 0x5F80, 0x5FDC, 0x62BC, 0x65FA, 0x6A2A, + 0x6B27, 0x6BB4, 0x738B, 0x7FC1, 0x8956, 0x9D2C, + 0x9D0E, 0x9EC4, 0x5CA1, 0x6C96, 0x837B, 0x5104, + 0x5C4B, 0x61B6, 0x81C6, 0x6876, 0x7261, 0x4E59, + 0x4FFA, 0x5378, 0x6069, 0x6E29, 0x7A4F, 0x97F3, + 0x4E0B, 0x5316, 0x4EEE, 0x4F55, 0x4F3D, 0x4FA1, + 0x4F73, 0x52A0, 0x53EF, 0x5609, 0x590F, 0x5AC1, + 0x5BB6, 0x5BE1, 0x79D1, 0x6687, 0x679C, 0x67B6, + 0x6B4C, 0x6CB3, 0x706B, 0x73C2, 0x798D, 0x79BE, + 0x7A3C, 0x7B87, 0x82B1, 0x82DB, 0x8304, 0x8377, + 0x83EF, 0x83D3, 0x8766, 0x8AB2, 0x5629, 0x8CA8, + 0x8FE6, 0x904E, 0x971E, 0x868A, 0x4FC4, 0x5CE8, + 0x6211, 0x7259, 0x753B, 0x81E5, 0x82BD, 0x86FE, + 0x8CC0, 0x96C5, 0x9913, 0x99D5, 0x4ECB, 0x4F1A, + 0x89E3, 0x56DE, 0x584A, 0x58CA, 0x5EFB, 0x5FEB, + 0x602A, 0x6094, 0x6062, 0x61D0, 0x6212, 0x62D0, + 0x6539, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis8A[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9B41, 0x6666, + 0x68B0, 0x6D77, 0x7070, 0x754C, 0x7686, 0x7D75, + 0x82A5, 0x87F9, 0x958B, 0x968E, 0x8C9D, 0x51F1, + 0x52BE, 0x5916, 0x54B3, 0x5BB3, 0x5D16, 0x6168, + 0x6982, 0x6DAF, 0x788D, 0x84CB, 0x8857, 0x8A72, + 0x93A7, 0x9AB8, 0x6D6C, 0x99A8, 0x86D9, 0x57A3, + 0x67FF, 0x86CE, 0x920E, 0x5283, 0x5687, 0x5404, + 0x5ED3, 0x62E1, 0x64B9, 0x683C, 0x6838, 0x6BBB, + 0x7372, 0x78BA, 0x7A6B, 0x899A, 0x89D2, 0x8D6B, + 0x8F03, 0x90ED, 0x95A3, 0x9694, 0x9769, 0x5B66, + 0x5CB3, 0x697D, 0x984D, 0x984E, 0x639B, 0x7B20, + 0x6A2B, 0x0000, 0x6A7F, 0x68B6, 0x9C0D, 0x6F5F, + 0x5272, 0x559D, 0x6070, 0x62EC, 0x6D3B, 0x6E07, + 0x6ED1, 0x845B, 0x8910, 0x8F44, 0x4E14, 0x9C39, + 0x53F6, 0x691B, 0x6A3A, 0x9784, 0x682A, 0x515C, + 0x7AC3, 0x84B2, 0x91DC, 0x938C, 0x565B, 0x9D28, + 0x6822, 0x8305, 0x8431, 0x7CA5, 0x5208, 0x82C5, + 0x74E6, 0x4E7E, 0x4F83, 0x51A0, 0x5BD2, 0x520A, + 0x52D8, 0x52E7, 0x5DFB, 0x559A, 0x582A, 0x59E6, + 0x5B8C, 0x5B98, 0x5BDB, 0x5E72, 0x5E79, 0x60A3, + 0x611F, 0x6163, 0x61BE, 0x63DB, 0x6562, 0x67D1, + 0x6853, 0x68FA, 0x6B3E, 0x6B53, 0x6C57, 0x6F22, + 0x6F97, 0x6F45, 0x74B0, 0x7518, 0x76E3, 0x770B, + 0x7AFF, 0x7BA1, 0x7C21, 0x7DE9, 0x7F36, 0x7FF0, + 0x809D, 0x8266, 0x839E, 0x89B3, 0x8ACC, 0x8CAB, + 0x9084, 0x9451, 0x9593, 0x9591, 0x95A2, 0x9665, + 0x97D3, 0x9928, 0x8218, 0x4E38, 0x542B, 0x5CB8, + 0x5DCC, 0x73A9, 0x764C, 0x773C, 0x5CA9, 0x7FEB, + 0x8D0B, 0x96C1, 0x9811, 0x9854, 0x9858, 0x4F01, + 0x4F0E, 0x5371, 0x559C, 0x5668, 0x57FA, 0x5947, + 0x5B09, 0x5BC4, 0x5C90, 0x5E0C, 0x5E7E, 0x5FCC, + 0x63EE, 0x673A, 0x65D7, 0x65E2, 0x671F, 0x68CB, + 0x68C4, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis8B[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6A5F, 0x5E30, + 0x6BC5, 0x6C17, 0x6C7D, 0x757F, 0x7948, 0x5B63, + 0x7A00, 0x7D00, 0x5FBD, 0x898F, 0x8A18, 0x8CB4, + 0x8D77, 0x8ECC, 0x8F1D, 0x98E2, 0x9A0E, 0x9B3C, + 0x4E80, 0x507D, 0x5100, 0x5993, 0x5B9C, 0x622F, + 0x6280, 0x64EC, 0x6B3A, 0x72A0, 0x7591, 0x7947, + 0x7FA9, 0x87FB, 0x8ABC, 0x8B70, 0x63AC, 0x83CA, + 0x97A0, 0x5409, 0x5403, 0x55AB, 0x6854, 0x6A58, + 0x8A70, 0x7827, 0x6775, 0x9ECD, 0x5374, 0x5BA2, + 0x811A, 0x8650, 0x9006, 0x4E18, 0x4E45, 0x4EC7, + 0x4F11, 0x53CA, 0x5438, 0x5BAE, 0x5F13, 0x6025, + 0x6551, 0x0000, 0x673D, 0x6C42, 0x6C72, 0x6CE3, + 0x7078, 0x7403, 0x7A76, 0x7AAE, 0x7B08, 0x7D1A, + 0x7CFE, 0x7D66, 0x65E7, 0x725B, 0x53BB, 0x5C45, + 0x5DE8, 0x62D2, 0x62E0, 0x6319, 0x6E20, 0x865A, + 0x8A31, 0x8DDD, 0x92F8, 0x6F01, 0x79A6, 0x9B5A, + 0x4EA8, 0x4EAB, 0x4EAC, 0x4F9B, 0x4FA0, 0x50D1, + 0x5147, 0x7AF6, 0x5171, 0x51F6, 0x5354, 0x5321, + 0x537F, 0x53EB, 0x55AC, 0x5883, 0x5CE1, 0x5F37, + 0x5F4A, 0x602F, 0x6050, 0x606D, 0x631F, 0x6559, + 0x6A4B, 0x6CC1, 0x72C2, 0x72ED, 0x77EF, 0x80F8, + 0x8105, 0x8208, 0x854E, 0x90F7, 0x93E1, 0x97FF, + 0x9957, 0x9A5A, 0x4EF0, 0x51DD, 0x5C2D, 0x6681, + 0x696D, 0x5C40, 0x66F2, 0x6975, 0x7389, 0x6850, + 0x7C81, 0x50C5, 0x52E4, 0x5747, 0x5DFE, 0x9326, + 0x65A4, 0x6B23, 0x6B3D, 0x7434, 0x7981, 0x79BD, + 0x7B4B, 0x7DCA, 0x82B9, 0x83CC, 0x887F, 0x895F, + 0x8B39, 0x8FD1, 0x91D1, 0x541F, 0x9280, 0x4E5D, + 0x5036, 0x53E5, 0x533A, 0x72D7, 0x7396, 0x77E9, + 0x82E6, 0x8EAF, 0x99C6, 0x99C8, 0x99D2, 0x5177, + 0x611A, 0x865E, 0x55B0, 0x7A7A, 0x5076, 0x5BD3, + 0x9047, 0x9685, 0x4E32, 0x6ADB, 0x91E7, 0x5C51, + 0x5C48, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis8C[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6398, 0x7A9F, + 0x6C93, 0x9774, 0x8F61, 0x7AAA, 0x718A, 0x9688, + 0x7C82, 0x6817, 0x7E70, 0x6851, 0x936C, 0x52F2, + 0x541B, 0x85AB, 0x8A13, 0x7FA4, 0x8ECD, 0x90E1, + 0x5366, 0x8888, 0x7941, 0x4FC2, 0x50BE, 0x5211, + 0x5144, 0x5553, 0x572D, 0x73EA, 0x578B, 0x5951, + 0x5F62, 0x5F84, 0x6075, 0x6176, 0x6167, 0x61A9, + 0x63B2, 0x643A, 0x656C, 0x666F, 0x6842, 0x6E13, + 0x7566, 0x7A3D, 0x7CFB, 0x7D4C, 0x7D99, 0x7E4B, + 0x7F6B, 0x830E, 0x834A, 0x86CD, 0x8A08, 0x8A63, + 0x8B66, 0x8EFD, 0x981A, 0x9D8F, 0x82B8, 0x8FCE, + 0x9BE8, 0x0000, 0x5287, 0x621F, 0x6483, 0x6FC0, + 0x9699, 0x6841, 0x5091, 0x6B20, 0x6C7A, 0x6F54, + 0x7A74, 0x7D50, 0x8840, 0x8A23, 0x6708, 0x4EF6, + 0x5039, 0x5026, 0x5065, 0x517C, 0x5238, 0x5263, + 0x55A7, 0x570F, 0x5805, 0x5ACC, 0x5EFA, 0x61B2, + 0x61F8, 0x62F3, 0x6372, 0x691C, 0x6A29, 0x727D, + 0x72AC, 0x732E, 0x7814, 0x786F, 0x7D79, 0x770C, + 0x80A9, 0x898B, 0x8B19, 0x8CE2, 0x8ED2, 0x9063, + 0x9375, 0x967A, 0x9855, 0x9A13, 0x9E78, 0x5143, + 0x539F, 0x53B3, 0x5E7B, 0x5F26, 0x6E1B, 0x6E90, + 0x7384, 0x73FE, 0x7D43, 0x8237, 0x8A00, 0x8AFA, + 0x9650, 0x4E4E, 0x500B, 0x53E4, 0x547C, 0x56FA, + 0x59D1, 0x5B64, 0x5DF1, 0x5EAB, 0x5F27, 0x6238, + 0x6545, 0x67AF, 0x6E56, 0x72D0, 0x7CCA, 0x88B4, + 0x80A1, 0x80E1, 0x83F0, 0x864E, 0x8A87, 0x8DE8, + 0x9237, 0x96C7, 0x9867, 0x9F13, 0x4E94, 0x4E92, + 0x4F0D, 0x5348, 0x5449, 0x543E, 0x5A2F, 0x5F8C, + 0x5FA1, 0x609F, 0x68A7, 0x6A8E, 0x745A, 0x7881, + 0x8A9E, 0x8AA4, 0x8B77, 0x9190, 0x4E5E, 0x9BC9, + 0x4EA4, 0x4F7C, 0x4FAF, 0x5019, 0x5016, 0x5149, + 0x516C, 0x529F, 0x52B9, 0x52FE, 0x539A, 0x53E3, + 0x5411, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis8D[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x540E, 0x5589, + 0x5751, 0x57A2, 0x597D, 0x5B54, 0x5B5D, 0x5B8F, + 0x5DE5, 0x5DE7, 0x5DF7, 0x5E78, 0x5E83, 0x5E9A, + 0x5EB7, 0x5F18, 0x6052, 0x614C, 0x6297, 0x62D8, + 0x63A7, 0x653B, 0x6602, 0x6643, 0x66F4, 0x676D, + 0x6821, 0x6897, 0x69CB, 0x6C5F, 0x6D2A, 0x6D69, + 0x6E2F, 0x6E9D, 0x7532, 0x7687, 0x786C, 0x7A3F, + 0x7CE0, 0x7D05, 0x7D18, 0x7D5E, 0x7DB1, 0x8015, + 0x8003, 0x80AF, 0x80B1, 0x8154, 0x818F, 0x822A, + 0x8352, 0x884C, 0x8861, 0x8B1B, 0x8CA2, 0x8CFC, + 0x90CA, 0x9175, 0x9271, 0x783F, 0x92FC, 0x95A4, + 0x964D, 0x0000, 0x9805, 0x9999, 0x9AD8, 0x9D3B, + 0x525B, 0x52AB, 0x53F7, 0x5408, 0x58D5, 0x62F7, + 0x6FE0, 0x8C6A, 0x8F5F, 0x9EB9, 0x514B, 0x523B, + 0x544A, 0x56FD, 0x7A40, 0x9177, 0x9D60, 0x9ED2, + 0x7344, 0x6F09, 0x8170, 0x7511, 0x5FFD, 0x60DA, + 0x9AA8, 0x72DB, 0x8FBC, 0x6B64, 0x9803, 0x4ECA, + 0x56F0, 0x5764, 0x58BE, 0x5A5A, 0x6068, 0x61C7, + 0x660F, 0x6606, 0x6839, 0x68B1, 0x6DF7, 0x75D5, + 0x7D3A, 0x826E, 0x9B42, 0x4E9B, 0x4F50, 0x53C9, + 0x5506, 0x5D6F, 0x5DE6, 0x5DEE, 0x67FB, 0x6C99, + 0x7473, 0x7802, 0x8A50, 0x9396, 0x88DF, 0x5750, + 0x5EA7, 0x632B, 0x50B5, 0x50AC, 0x518D, 0x6700, + 0x54C9, 0x585E, 0x59BB, 0x5BB0, 0x5F69, 0x624D, + 0x63A1, 0x683D, 0x6B73, 0x6E08, 0x707D, 0x91C7, + 0x7280, 0x7815, 0x7826, 0x796D, 0x658E, 0x7D30, + 0x83DC, 0x88C1, 0x8F09, 0x969B, 0x5264, 0x5728, + 0x6750, 0x7F6A, 0x8CA1, 0x51B4, 0x5742, 0x962A, + 0x583A, 0x698A, 0x80B4, 0x54B2, 0x5D0E, 0x57FC, + 0x7895, 0x9DFA, 0x4F5C, 0x524A, 0x548B, 0x643E, + 0x6628, 0x6714, 0x67F5, 0x7A84, 0x7B56, 0x7D22, + 0x932F, 0x685C, 0x9BAD, 0x7B39, 0x5319, 0x518A, + 0x5237, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis8E[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5BDF, 0x62F6, + 0x64AE, 0x64E6, 0x672D, 0x6BBA, 0x85A9, 0x96D1, + 0x7690, 0x9BD6, 0x634C, 0x9306, 0x9BAB, 0x76BF, + 0x6652, 0x4E09, 0x5098, 0x53C2, 0x5C71, 0x60E8, + 0x6492, 0x6563, 0x685F, 0x71E6, 0x73CA, 0x7523, + 0x7B97, 0x7E82, 0x8695, 0x8B83, 0x8CDB, 0x9178, + 0x9910, 0x65AC, 0x66AB, 0x6B8B, 0x4ED5, 0x4ED4, + 0x4F3A, 0x4F7F, 0x523A, 0x53F8, 0x53F2, 0x55E3, + 0x56DB, 0x58EB, 0x59CB, 0x59C9, 0x59FF, 0x5B50, + 0x5C4D, 0x5E02, 0x5E2B, 0x5FD7, 0x601D, 0x6307, + 0x652F, 0x5B5C, 0x65AF, 0x65BD, 0x65E8, 0x679D, + 0x6B62, 0x0000, 0x6B7B, 0x6C0F, 0x7345, 0x7949, + 0x79C1, 0x7CF8, 0x7D19, 0x7D2B, 0x80A2, 0x8102, + 0x81F3, 0x8996, 0x8A5E, 0x8A69, 0x8A66, 0x8A8C, + 0x8AEE, 0x8CC7, 0x8CDC, 0x96CC, 0x98FC, 0x6B6F, + 0x4E8B, 0x4F3C, 0x4F8D, 0x5150, 0x5B57, 0x5BFA, + 0x6148, 0x6301, 0x6642, 0x6B21, 0x6ECB, 0x6CBB, + 0x723E, 0x74BD, 0x75D4, 0x78C1, 0x793A, 0x800C, + 0x8033, 0x81EA, 0x8494, 0x8F9E, 0x6C50, 0x9E7F, + 0x5F0F, 0x8B58, 0x9D2B, 0x7AFA, 0x8EF8, 0x5B8D, + 0x96EB, 0x4E03, 0x53F1, 0x57F7, 0x5931, 0x5AC9, + 0x5BA4, 0x6089, 0x6E7F, 0x6F06, 0x75BE, 0x8CEA, + 0x5B9F, 0x8500, 0x7BE0, 0x5072, 0x67F4, 0x829D, + 0x5C61, 0x854A, 0x7E1E, 0x820E, 0x5199, 0x5C04, + 0x6368, 0x8D66, 0x659C, 0x716E, 0x793E, 0x7D17, + 0x8005, 0x8B1D, 0x8ECA, 0x906E, 0x86C7, 0x90AA, + 0x501F, 0x52FA, 0x5C3A, 0x6753, 0x707C, 0x7235, + 0x914C, 0x91C8, 0x932B, 0x82E5, 0x5BC2, 0x5F31, + 0x60F9, 0x4E3B, 0x53D6, 0x5B88, 0x624B, 0x6731, + 0x6B8A, 0x72E9, 0x73E0, 0x7A2E, 0x816B, 0x8DA3, + 0x9152, 0x9996, 0x5112, 0x53D7, 0x546A, 0x5BFF, + 0x6388, 0x6A39, 0x7DAC, 0x9700, 0x56DA, 0x53CE, + 0x5468, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis8F[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5B97, 0x5C31, + 0x5DDE, 0x4FEE, 0x6101, 0x62FE, 0x6D32, 0x79C0, + 0x79CB, 0x7D42, 0x7E4D, 0x7FD2, 0x81ED, 0x821F, + 0x8490, 0x8846, 0x8972, 0x8B90, 0x8E74, 0x8F2F, + 0x9031, 0x914B, 0x916C, 0x96C6, 0x919C, 0x4EC0, + 0x4F4F, 0x5145, 0x5341, 0x5F93, 0x620E, 0x67D4, + 0x6C41, 0x6E0B, 0x7363, 0x7E26, 0x91CD, 0x9283, + 0x53D4, 0x5919, 0x5BBF, 0x6DD1, 0x795D, 0x7E2E, + 0x7C9B, 0x587E, 0x719F, 0x51FA, 0x8853, 0x8FF0, + 0x4FCA, 0x5CFB, 0x6625, 0x77AC, 0x7AE3, 0x821C, + 0x99FF, 0x51C6, 0x5FAA, 0x65EC, 0x696F, 0x6B89, + 0x6DF3, 0x0000, 0x6E96, 0x6F64, 0x76FE, 0x7D14, + 0x5DE1, 0x9075, 0x9187, 0x9806, 0x51E6, 0x521D, + 0x6240, 0x6691, 0x66D9, 0x6E1A, 0x5EB6, 0x7DD2, + 0x7F72, 0x66F8, 0x85AF, 0x85F7, 0x8AF8, 0x52A9, + 0x53D9, 0x5973, 0x5E8F, 0x5F90, 0x6055, 0x92E4, + 0x9664, 0x50B7, 0x511F, 0x52DD, 0x5320, 0x5347, + 0x53EC, 0x54E8, 0x5546, 0x5531, 0x5617, 0x5968, + 0x59BE, 0x5A3C, 0x5BB5, 0x5C06, 0x5C0F, 0x5C11, + 0x5C1A, 0x5E84, 0x5E8A, 0x5EE0, 0x5F70, 0x627F, + 0x6284, 0x62DB, 0x638C, 0x6377, 0x6607, 0x660C, + 0x662D, 0x6676, 0x677E, 0x68A2, 0x6A1F, 0x6A35, + 0x6CBC, 0x6D88, 0x6E09, 0x6E58, 0x713C, 0x7126, + 0x7167, 0x75C7, 0x7701, 0x785D, 0x7901, 0x7965, + 0x79F0, 0x7AE0, 0x7B11, 0x7CA7, 0x7D39, 0x8096, + 0x83D6, 0x848B, 0x8549, 0x885D, 0x88F3, 0x8A1F, + 0x8A3C, 0x8A54, 0x8A73, 0x8C61, 0x8CDE, 0x91A4, + 0x9266, 0x937E, 0x9418, 0x969C, 0x9798, 0x4E0A, + 0x4E08, 0x4E1E, 0x4E57, 0x5197, 0x5270, 0x57CE, + 0x5834, 0x58CC, 0x5B22, 0x5E38, 0x60C5, 0x64FE, + 0x6761, 0x6756, 0x6D44, 0x72B6, 0x7573, 0x7A63, + 0x84B8, 0x8B72, 0x91B8, 0x9320, 0x5631, 0x57F4, + 0x98FE, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis90[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x62ED, 0x690D, + 0x6B96, 0x71ED, 0x7E54, 0x8077, 0x8272, 0x89E6, + 0x98DF, 0x8755, 0x8FB1, 0x5C3B, 0x4F38, 0x4FE1, + 0x4FB5, 0x5507, 0x5A20, 0x5BDD, 0x5BE9, 0x5FC3, + 0x614E, 0x632F, 0x65B0, 0x664B, 0x68EE, 0x699B, + 0x6D78, 0x6DF1, 0x7533, 0x75B9, 0x771F, 0x795E, + 0x79E6, 0x7D33, 0x81E3, 0x82AF, 0x85AA, 0x89AA, + 0x8A3A, 0x8EAB, 0x8F9B, 0x9032, 0x91DD, 0x9707, + 0x4EBA, 0x4EC1, 0x5203, 0x5875, 0x58EC, 0x5C0B, + 0x751A, 0x5C3D, 0x814E, 0x8A0A, 0x8FC5, 0x9663, + 0x976D, 0x7B25, 0x8ACF, 0x9808, 0x9162, 0x56F3, + 0x53A8, 0x0000, 0x9017, 0x5439, 0x5782, 0x5E25, + 0x63A8, 0x6C34, 0x708A, 0x7761, 0x7C8B, 0x7FE0, + 0x8870, 0x9042, 0x9154, 0x9310, 0x9318, 0x968F, + 0x745E, 0x9AC4, 0x5D07, 0x5D69, 0x6570, 0x67A2, + 0x8DA8, 0x96DB, 0x636E, 0x6749, 0x6919, 0x83C5, + 0x9817, 0x96C0, 0x88FE, 0x6F84, 0x647A, 0x5BF8, + 0x4E16, 0x702C, 0x755D, 0x662F, 0x51C4, 0x5236, + 0x52E2, 0x59D3, 0x5F81, 0x6027, 0x6210, 0x653F, + 0x6574, 0x661F, 0x6674, 0x68F2, 0x6816, 0x6B63, + 0x6E05, 0x7272, 0x751F, 0x76DB, 0x7CBE, 0x8056, + 0x58F0, 0x88FD, 0x897F, 0x8AA0, 0x8A93, 0x8ACB, + 0x901D, 0x9192, 0x9752, 0x9759, 0x6589, 0x7A0E, + 0x8106, 0x96BB, 0x5E2D, 0x60DC, 0x621A, 0x65A5, + 0x6614, 0x6790, 0x77F3, 0x7A4D, 0x7C4D, 0x7E3E, + 0x810A, 0x8CAC, 0x8D64, 0x8DE1, 0x8E5F, 0x78A9, + 0x5207, 0x62D9, 0x63A5, 0x6442, 0x6298, 0x8A2D, + 0x7A83, 0x7BC0, 0x8AAC, 0x96EA, 0x7D76, 0x820C, + 0x8749, 0x4ED9, 0x5148, 0x5343, 0x5360, 0x5BA3, + 0x5C02, 0x5C16, 0x5DDD, 0x6226, 0x6247, 0x64B0, + 0x6813, 0x6834, 0x6CC9, 0x6D45, 0x6D17, 0x67D3, + 0x6F5C, 0x714E, 0x717D, 0x65CB, 0x7A7F, 0x7BAD, + 0x7DDA, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis91[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7E4A, 0x7FA8, + 0x817A, 0x821B, 0x8239, 0x85A6, 0x8A6E, 0x8CCE, + 0x8DF5, 0x9078, 0x9077, 0x92AD, 0x9291, 0x9583, + 0x9BAE, 0x524D, 0x5584, 0x6F38, 0x7136, 0x5168, + 0x7985, 0x7E55, 0x81B3, 0x7CCE, 0x564C, 0x5851, + 0x5CA8, 0x63AA, 0x66FE, 0x66FD, 0x695A, 0x72D9, + 0x758F, 0x758E, 0x790E, 0x7956, 0x79DF, 0x7C97, + 0x7D20, 0x7D44, 0x8607, 0x8A34, 0x963B, 0x9061, + 0x9F20, 0x50E7, 0x5275, 0x53CC, 0x53E2, 0x5009, + 0x55AA, 0x58EE, 0x594F, 0x723D, 0x5B8B, 0x5C64, + 0x531D, 0x60E3, 0x60F3, 0x635C, 0x6383, 0x633F, + 0x63BB, 0x0000, 0x64CD, 0x65E9, 0x66F9, 0x5DE3, + 0x69CD, 0x69FD, 0x6F15, 0x71E5, 0x4E89, 0x75E9, + 0x76F8, 0x7A93, 0x7CDF, 0x7DCF, 0x7D9C, 0x8061, + 0x8349, 0x8358, 0x846C, 0x84BC, 0x85FB, 0x88C5, + 0x8D70, 0x9001, 0x906D, 0x9397, 0x971C, 0x9A12, + 0x50CF, 0x5897, 0x618E, 0x81D3, 0x8535, 0x8D08, + 0x9020, 0x4FC3, 0x5074, 0x5247, 0x5373, 0x606F, + 0x6349, 0x675F, 0x6E2C, 0x8DB3, 0x901F, 0x4FD7, + 0x5C5E, 0x8CCA, 0x65CF, 0x7D9A, 0x5352, 0x8896, + 0x5176, 0x63C3, 0x5B58, 0x5B6B, 0x5C0A, 0x640D, + 0x6751, 0x905C, 0x4ED6, 0x591A, 0x592A, 0x6C70, + 0x8A51, 0x553E, 0x5815, 0x59A5, 0x60F0, 0x6253, + 0x67C1, 0x8235, 0x6955, 0x9640, 0x99C4, 0x9A28, + 0x4F53, 0x5806, 0x5BFE, 0x8010, 0x5CB1, 0x5E2F, + 0x5F85, 0x6020, 0x614B, 0x6234, 0x66FF, 0x6CF0, + 0x6EDE, 0x80CE, 0x817F, 0x82D4, 0x888B, 0x8CB8, + 0x9000, 0x902E, 0x968A, 0x9EDB, 0x9BDB, 0x4EE3, + 0x53F0, 0x5927, 0x7B2C, 0x918D, 0x984C, 0x9DF9, + 0x6EDD, 0x7027, 0x5353, 0x5544, 0x5B85, 0x6258, + 0x629E, 0x62D3, 0x6CA2, 0x6FEF, 0x7422, 0x8A17, + 0x9438, 0x6FC1, 0x8AFE, 0x8338, 0x51E7, 0x86F8, + 0x53EA, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis92[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x53E9, 0x4F46, + 0x9054, 0x8FB0, 0x596A, 0x8131, 0x5DFD, 0x7AEA, + 0x8FBF, 0x68DA, 0x8C37, 0x72F8, 0x9C48, 0x6A3D, + 0x8AB0, 0x4E39, 0x5358, 0x5606, 0x5766, 0x62C5, + 0x63A2, 0x65E6, 0x6B4E, 0x6DE1, 0x6E5B, 0x70AD, + 0x77ED, 0x7AEF, 0x7BAA, 0x7DBB, 0x803D, 0x80C6, + 0x86CB, 0x8A95, 0x935B, 0x56E3, 0x58C7, 0x5F3E, + 0x65AD, 0x6696, 0x6A80, 0x6BB5, 0x7537, 0x8AC7, + 0x5024, 0x77E5, 0x5730, 0x5F1B, 0x6065, 0x667A, + 0x6C60, 0x75F4, 0x7A1A, 0x7F6E, 0x81F4, 0x8718, + 0x9045, 0x99B3, 0x7BC9, 0x755C, 0x7AF9, 0x7B51, + 0x84C4, 0x0000, 0x9010, 0x79E9, 0x7A92, 0x8336, + 0x5AE1, 0x7740, 0x4E2D, 0x4EF2, 0x5B99, 0x5FE0, + 0x62BD, 0x663C, 0x67F1, 0x6CE8, 0x866B, 0x8877, + 0x8A3B, 0x914E, 0x92F3, 0x99D0, 0x6A17, 0x7026, + 0x732A, 0x82E7, 0x8457, 0x8CAF, 0x4E01, 0x5146, + 0x51CB, 0x558B, 0x5BF5, 0x5E16, 0x5E33, 0x5E81, + 0x5F14, 0x5F35, 0x5F6B, 0x5FB4, 0x61F2, 0x6311, + 0x66A2, 0x671D, 0x6F6E, 0x7252, 0x753A, 0x773A, + 0x8074, 0x8139, 0x8178, 0x8776, 0x8ABF, 0x8ADC, + 0x8D85, 0x8DF3, 0x929A, 0x9577, 0x9802, 0x9CE5, + 0x52C5, 0x6357, 0x76F4, 0x6715, 0x6C88, 0x73CD, + 0x8CC3, 0x93AE, 0x9673, 0x6D25, 0x589C, 0x690E, + 0x69CC, 0x8FFD, 0x939A, 0x75DB, 0x901A, 0x585A, + 0x6802, 0x63B4, 0x69FB, 0x4F43, 0x6F2C, 0x67D8, + 0x8FBB, 0x8526, 0x7DB4, 0x9354, 0x693F, 0x6F70, + 0x576A, 0x58F7, 0x5B2C, 0x7D2C, 0x722A, 0x540A, + 0x91E3, 0x9DB4, 0x4EAD, 0x4F4E, 0x505C, 0x5075, + 0x5243, 0x8C9E, 0x5448, 0x5824, 0x5B9A, 0x5E1D, + 0x5E95, 0x5EAD, 0x5EF7, 0x5F1F, 0x608C, 0x62B5, + 0x633A, 0x63D0, 0x68AF, 0x6C40, 0x7887, 0x798E, + 0x7A0B, 0x7DE0, 0x8247, 0x8A02, 0x8AE6, 0x8E44, + 0x9013, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis93[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x90B8, 0x912D, + 0x91D8, 0x9F0E, 0x6CE5, 0x6458, 0x64E2, 0x6575, + 0x6EF4, 0x7684, 0x7B1B, 0x9069, 0x93D1, 0x6EBA, + 0x54F2, 0x5FB9, 0x64A4, 0x8F4D, 0x8FED, 0x9244, + 0x5178, 0x586B, 0x5929, 0x5C55, 0x5E97, 0x6DFB, + 0x7E8F, 0x751C, 0x8CBC, 0x8EE2, 0x985B, 0x70B9, + 0x4F1D, 0x6BBF, 0x6FB1, 0x7530, 0x96FB, 0x514E, + 0x5410, 0x5835, 0x5857, 0x59AC, 0x5C60, 0x5F92, + 0x6597, 0x675C, 0x6E21, 0x767B, 0x83DF, 0x8CED, + 0x9014, 0x90FD, 0x934D, 0x7825, 0x783A, 0x52AA, + 0x5EA6, 0x571F, 0x5974, 0x6012, 0x5012, 0x515A, + 0x51AC, 0x0000, 0x51CD, 0x5200, 0x5510, 0x5854, + 0x5858, 0x5957, 0x5B95, 0x5CF6, 0x5D8B, 0x60BC, + 0x6295, 0x642D, 0x6771, 0x6843, 0x68BC, 0x68DF, + 0x76D7, 0x6DD8, 0x6E6F, 0x6D9B, 0x706F, 0x71C8, + 0x5F53, 0x75D8, 0x7977, 0x7B49, 0x7B54, 0x7B52, + 0x7CD6, 0x7D71, 0x5230, 0x8463, 0x8569, 0x85E4, + 0x8A0E, 0x8B04, 0x8C46, 0x8E0F, 0x9003, 0x900F, + 0x9419, 0x9676, 0x982D, 0x9A30, 0x95D8, 0x50CD, + 0x52D5, 0x540C, 0x5802, 0x5C0E, 0x61A7, 0x649E, + 0x6D1E, 0x77B3, 0x7AE5, 0x80F4, 0x8404, 0x9053, + 0x9285, 0x5CE0, 0x9D07, 0x533F, 0x5F97, 0x5FB3, + 0x6D9C, 0x7279, 0x7763, 0x79BF, 0x7BE4, 0x6BD2, + 0x72EC, 0x8AAD, 0x6803, 0x6A61, 0x51F8, 0x7A81, + 0x6934, 0x5C4A, 0x9CF6, 0x82EB, 0x5BC5, 0x9149, + 0x701E, 0x5678, 0x5C6F, 0x60C7, 0x6566, 0x6C8C, + 0x8C5A, 0x9041, 0x9813, 0x5451, 0x66C7, 0x920D, + 0x5948, 0x90A3, 0x5185, 0x4E4D, 0x51EA, 0x8599, + 0x8B0E, 0x7058, 0x637A, 0x934B, 0x6962, 0x99B4, + 0x7E04, 0x7577, 0x5357, 0x6960, 0x8EDF, 0x96E3, + 0x6C5D, 0x4E8C, 0x5C3C, 0x5F10, 0x8FE9, 0x5302, + 0x8CD1, 0x8089, 0x8679, 0x5EFF, 0x65E5, 0x4E73, + 0x5165, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis94[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5982, 0x5C3F, + 0x97EE, 0x4EFB, 0x598A, 0x5FCD, 0x8A8D, 0x6FE1, + 0x79B0, 0x7962, 0x5BE7, 0x8471, 0x732B, 0x71B1, + 0x5E74, 0x5FF5, 0x637B, 0x649A, 0x71C3, 0x7C98, + 0x4E43, 0x5EFC, 0x4E4B, 0x57DC, 0x56A2, 0x60A9, + 0x6FC3, 0x7D0D, 0x80FD, 0x8133, 0x81BF, 0x8FB2, + 0x8997, 0x86A4, 0x5DF4, 0x628A, 0x64AD, 0x8987, + 0x6777, 0x6CE2, 0x6D3E, 0x7436, 0x7834, 0x5A46, + 0x7F75, 0x82AD, 0x99AC, 0x4FF3, 0x5EC3, 0x62DD, + 0x6392, 0x6557, 0x676F, 0x76C3, 0x724C, 0x80CC, + 0x80BA, 0x8F29, 0x914D, 0x500D, 0x57F9, 0x5A92, + 0x6885, 0x0000, 0x6973, 0x7164, 0x72FD, 0x8CB7, + 0x58F2, 0x8CE0, 0x966A, 0x9019, 0x877F, 0x79E4, + 0x77E7, 0x8429, 0x4F2F, 0x5265, 0x535A, 0x62CD, + 0x67CF, 0x6CCA, 0x767D, 0x7B94, 0x7C95, 0x8236, + 0x8584, 0x8FEB, 0x66DD, 0x6F20, 0x7206, 0x7E1B, + 0x83AB, 0x99C1, 0x9EA6, 0x51FD, 0x7BB1, 0x7872, + 0x7BB8, 0x8087, 0x7B48, 0x6AE8, 0x5E61, 0x808C, + 0x7551, 0x7560, 0x516B, 0x9262, 0x6E8C, 0x767A, + 0x9197, 0x9AEA, 0x4F10, 0x7F70, 0x629C, 0x7B4F, + 0x95A5, 0x9CE9, 0x567A, 0x5859, 0x86E4, 0x96BC, + 0x4F34, 0x5224, 0x534A, 0x53CD, 0x53DB, 0x5E06, + 0x642C, 0x6591, 0x677F, 0x6C3E, 0x6C4E, 0x7248, + 0x72AF, 0x73ED, 0x7554, 0x7E41, 0x822C, 0x85E9, + 0x8CA9, 0x7BC4, 0x91C6, 0x7169, 0x9812, 0x98EF, + 0x633D, 0x6669, 0x756A, 0x76E4, 0x78D0, 0x8543, + 0x86EE, 0x532A, 0x5351, 0x5426, 0x5983, 0x5E87, + 0x5F7C, 0x60B2, 0x6249, 0x6279, 0x62AB, 0x6590, + 0x6BD4, 0x6CCC, 0x75B2, 0x76AE, 0x7891, 0x79D8, + 0x7DCB, 0x7F77, 0x80A5, 0x88AB, 0x8AB9, 0x8CBB, + 0x907F, 0x975E, 0x98DB, 0x6A0B, 0x7C38, 0x5099, + 0x5C3E, 0x5FAE, 0x6787, 0x6BD8, 0x7435, 0x7709, + 0x7F8E, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis95[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9F3B, 0x67CA, + 0x7A17, 0x5339, 0x758B, 0x9AED, 0x5F66, 0x819D, + 0x83F1, 0x8098, 0x5F3C, 0x5FC5, 0x7562, 0x7B46, + 0x903C, 0x6867, 0x59EB, 0x5A9B, 0x7D10, 0x767E, + 0x8B2C, 0x4FF5, 0x5F6A, 0x6A19, 0x6C37, 0x6F02, + 0x74E2, 0x7968, 0x8868, 0x8A55, 0x8C79, 0x5EDF, + 0x63CF, 0x75C5, 0x79D2, 0x82D7, 0x9328, 0x92F2, + 0x849C, 0x86ED, 0x9C2D, 0x54C1, 0x5F6C, 0x658C, + 0x6D5C, 0x7015, 0x8CA7, 0x8CD3, 0x983B, 0x654F, + 0x74F6, 0x4E0D, 0x4ED8, 0x57E0, 0x592B, 0x5A66, + 0x5BCC, 0x51A8, 0x5E03, 0x5E9C, 0x6016, 0x6276, + 0x6577, 0x0000, 0x65A7, 0x666E, 0x6D6E, 0x7236, + 0x7B26, 0x8150, 0x819A, 0x8299, 0x8B5C, 0x8CA0, + 0x8CE6, 0x8D74, 0x961C, 0x9644, 0x4FAE, 0x64AB, + 0x6B66, 0x821E, 0x8461, 0x856A, 0x90E8, 0x5C01, + 0x6953, 0x98A8, 0x847A, 0x8557, 0x4F0F, 0x526F, + 0x5FA9, 0x5E45, 0x670D, 0x798F, 0x8179, 0x8907, + 0x8986, 0x6DF5, 0x5F17, 0x6255, 0x6CB8, 0x4ECF, + 0x7269, 0x9B92, 0x5206, 0x543B, 0x5674, 0x58B3, + 0x61A4, 0x626E, 0x711A, 0x596E, 0x7C89, 0x7CDE, + 0x7D1B, 0x96F0, 0x6587, 0x805E, 0x4E19, 0x4F75, + 0x5175, 0x5840, 0x5E63, 0x5E73, 0x5F0A, 0x67C4, + 0x4E26, 0x853D, 0x9589, 0x965B, 0x7C73, 0x9801, + 0x50FB, 0x58C1, 0x7656, 0x78A7, 0x5225, 0x77A5, + 0x8511, 0x7B86, 0x504F, 0x5909, 0x7247, 0x7BC7, + 0x7DE8, 0x8FBA, 0x8FD4, 0x904D, 0x4FBF, 0x52C9, + 0x5A29, 0x5F01, 0x97AD, 0x4FDD, 0x8217, 0x92EA, + 0x5703, 0x6355, 0x6B69, 0x752B, 0x88DC, 0x8F14, + 0x7A42, 0x52DF, 0x5893, 0x6155, 0x620A, 0x66AE, + 0x6BCD, 0x7C3F, 0x83E9, 0x5023, 0x4FF8, 0x5305, + 0x5446, 0x5831, 0x5949, 0x5B9D, 0x5CF0, 0x5CEF, + 0x5D29, 0x5E96, 0x62B1, 0x6367, 0x653E, 0x65B9, + 0x670B, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis96[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6CD5, 0x6CE1, + 0x70F9, 0x7832, 0x7E2B, 0x80DE, 0x82B3, 0x840C, + 0x84EC, 0x8702, 0x8912, 0x8A2A, 0x8C4A, 0x90A6, + 0x92D2, 0x98FD, 0x9CF3, 0x9D6C, 0x4E4F, 0x4EA1, + 0x508D, 0x5256, 0x574A, 0x59A8, 0x5E3D, 0x5FD8, + 0x5FD9, 0x623F, 0x66B4, 0x671B, 0x67D0, 0x68D2, + 0x5192, 0x7D21, 0x80AA, 0x81A8, 0x8B00, 0x8C8C, + 0x8CBF, 0x927E, 0x9632, 0x5420, 0x982C, 0x5317, + 0x50D5, 0x535C, 0x58A8, 0x64B2, 0x6734, 0x7267, + 0x7766, 0x7A46, 0x91E6, 0x52C3, 0x6CA1, 0x6B86, + 0x5800, 0x5E4C, 0x5954, 0x672C, 0x7FFB, 0x51E1, + 0x76C6, 0x0000, 0x6469, 0x78E8, 0x9B54, 0x9EBB, + 0x57CB, 0x59B9, 0x6627, 0x679A, 0x6BCE, 0x54E9, + 0x69D9, 0x5E55, 0x819C, 0x6795, 0x9BAA, 0x67FE, + 0x9C52, 0x685D, 0x4EA6, 0x4FE3, 0x53C8, 0x62B9, + 0x672B, 0x6CAB, 0x8FC4, 0x4FAD, 0x7E6D, 0x9EBF, + 0x4E07, 0x6162, 0x6E80, 0x6F2B, 0x8513, 0x5473, + 0x672A, 0x9B45, 0x5DF3, 0x7B95, 0x5CAC, 0x5BC6, + 0x871C, 0x6E4A, 0x84D1, 0x7A14, 0x8108, 0x5999, + 0x7C8D, 0x6C11, 0x7720, 0x52D9, 0x5922, 0x7121, + 0x725F, 0x77DB, 0x9727, 0x9D61, 0x690B, 0x5A7F, + 0x5A18, 0x51A5, 0x540D, 0x547D, 0x660E, 0x76DF, + 0x8FF7, 0x9298, 0x9CF4, 0x59EA, 0x725D, 0x6EC5, + 0x514D, 0x68C9, 0x7DBF, 0x7DEC, 0x9762, 0x9EBA, + 0x6478, 0x6A21, 0x8302, 0x5984, 0x5B5F, 0x6BDB, + 0x731B, 0x76F2, 0x7DB2, 0x8017, 0x8499, 0x5132, + 0x6728, 0x9ED9, 0x76EE, 0x6762, 0x52FF, 0x9905, + 0x5C24, 0x623B, 0x7C7E, 0x8CB0, 0x554F, 0x60B6, + 0x7D0B, 0x9580, 0x5301, 0x4E5F, 0x51B6, 0x591C, + 0x723A, 0x8036, 0x91CE, 0x5F25, 0x77E2, 0x5384, + 0x5F79, 0x7D04, 0x85AC, 0x8A33, 0x8E8D, 0x9756, + 0x67F3, 0x85AE, 0x9453, 0x6109, 0x6108, 0x6CB9, + 0x7652, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis97[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8AED, 0x8F38, + 0x552F, 0x4F51, 0x512A, 0x52C7, 0x53CB, 0x5BA5, + 0x5E7D, 0x60A0, 0x6182, 0x63D6, 0x6709, 0x67DA, + 0x6E67, 0x6D8C, 0x7336, 0x7337, 0x7531, 0x7950, + 0x88D5, 0x8A98, 0x904A, 0x9091, 0x90F5, 0x96C4, + 0x878D, 0x5915, 0x4E88, 0x4F59, 0x4E0E, 0x8A89, + 0x8F3F, 0x9810, 0x50AD, 0x5E7C, 0x5996, 0x5BB9, + 0x5EB8, 0x63DA, 0x63FA, 0x64C1, 0x66DC, 0x694A, + 0x69D8, 0x6D0B, 0x6EB6, 0x7194, 0x7528, 0x7AAF, + 0x7F8A, 0x8000, 0x8449, 0x84C9, 0x8981, 0x8B21, + 0x8E0A, 0x9065, 0x967D, 0x990A, 0x617E, 0x6291, + 0x6B32, 0x0000, 0x6C83, 0x6D74, 0x7FCC, 0x7FFC, + 0x6DC0, 0x7F85, 0x87BA, 0x88F8, 0x6765, 0x83B1, + 0x983C, 0x96F7, 0x6D1B, 0x7D61, 0x843D, 0x916A, + 0x4E71, 0x5375, 0x5D50, 0x6B04, 0x6FEB, 0x85CD, + 0x862D, 0x89A7, 0x5229, 0x540F, 0x5C65, 0x674E, + 0x68A8, 0x7406, 0x7483, 0x75E2, 0x88CF, 0x88E1, + 0x91CC, 0x96E2, 0x9678, 0x5F8B, 0x7387, 0x7ACB, + 0x844E, 0x63A0, 0x7565, 0x5289, 0x6D41, 0x6E9C, + 0x7409, 0x7559, 0x786B, 0x7C92, 0x9686, 0x7ADC, + 0x9F8D, 0x4FB6, 0x616E, 0x65C5, 0x865C, 0x4E86, + 0x4EAE, 0x50DA, 0x4E21, 0x51CC, 0x5BEE, 0x6599, + 0x6881, 0x6DBC, 0x731F, 0x7642, 0x77AD, 0x7A1C, + 0x7CE7, 0x826F, 0x8AD2, 0x907C, 0x91CF, 0x9675, + 0x9818, 0x529B, 0x7DD1, 0x502B, 0x5398, 0x6797, + 0x6DCB, 0x71D0, 0x7433, 0x81E8, 0x8F2A, 0x96A3, + 0x9C57, 0x9E9F, 0x7460, 0x5841, 0x6D99, 0x7D2F, + 0x985E, 0x4EE4, 0x4F36, 0x4F8B, 0x51B7, 0x52B1, + 0x5DBA, 0x601C, 0x73B2, 0x793C, 0x82D3, 0x9234, + 0x96B7, 0x96F6, 0x970A, 0x9E97, 0x9F62, 0x66A6, + 0x6B74, 0x5217, 0x52A3, 0x70C8, 0x88C2, 0x5EC9, + 0x604B, 0x6190, 0x6F23, 0x7149, 0x7C3E, 0x7DF4, + 0x806F, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis98[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x84EE, 0x9023, + 0x932C, 0x5442, 0x9B6F, 0x6AD3, 0x7089, 0x8CC2, + 0x8DEF, 0x9732, 0x52B4, 0x5A41, 0x5ECA, 0x5F04, + 0x6717, 0x697C, 0x6994, 0x6D6A, 0x6F0F, 0x7262, + 0x72FC, 0x7BED, 0x8001, 0x807E, 0x874B, 0x90CE, + 0x516D, 0x9E93, 0x7984, 0x808B, 0x9332, 0x8AD6, + 0x502D, 0x548C, 0x8A71, 0x6B6A, 0x8CC4, 0x8107, + 0x60D1, 0x67A0, 0x9DF2, 0x4E99, 0x4E98, 0x9C10, + 0x8A6B, 0x85C1, 0x8568, 0x6900, 0x6E7E, 0x7897, + 0x8155, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x5F0C, 0x4E10, 0x4E15, + 0x4E2A, 0x4E31, 0x4E36, 0x4E3C, 0x4E3F, 0x4E42, + 0x4E56, 0x4E58, 0x4E82, 0x4E85, 0x8C6B, 0x4E8A, + 0x8212, 0x5F0D, 0x4E8E, 0x4E9E, 0x4E9F, 0x4EA0, + 0x4EA2, 0x4EB0, 0x4EB3, 0x4EB6, 0x4ECE, 0x4ECD, + 0x4EC4, 0x4EC6, 0x4EC2, 0x4ED7, 0x4EDE, 0x4EED, + 0x4EDF, 0x4EF7, 0x4F09, 0x4F5A, 0x4F30, 0x4F5B, + 0x4F5D, 0x4F57, 0x4F47, 0x4F76, 0x4F88, 0x4F8F, + 0x4F98, 0x4F7B, 0x4F69, 0x4F70, 0x4F91, 0x4F6F, + 0x4F86, 0x4F96, 0x5118, 0x4FD4, 0x4FDF, 0x4FCE, + 0x4FD8, 0x4FDB, 0x4FD1, 0x4FDA, 0x4FD0, 0x4FE4, + 0x4FE5, 0x501A, 0x5028, 0x5014, 0x502A, 0x5025, + 0x5005, 0x4F1C, 0x4FF6, 0x5021, 0x5029, 0x502C, + 0x4FFE, 0x4FEF, 0x5011, 0x5006, 0x5043, 0x5047, + 0x6703, 0x5055, 0x5050, 0x5048, 0x505A, 0x5056, + 0x506C, 0x5078, 0x5080, 0x509A, 0x5085, 0x50B4, + 0x50B2, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis99[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x50C9, 0x50CA, + 0x50B3, 0x50C2, 0x50D6, 0x50DE, 0x50E5, 0x50ED, + 0x50E3, 0x50EE, 0x50F9, 0x50F5, 0x5109, 0x5101, + 0x5102, 0x5116, 0x5115, 0x5114, 0x511A, 0x5121, + 0x513A, 0x5137, 0x513C, 0x513B, 0x513F, 0x5140, + 0x5152, 0x514C, 0x5154, 0x5162, 0x7AF8, 0x5169, + 0x516A, 0x516E, 0x5180, 0x5182, 0x56D8, 0x518C, + 0x5189, 0x518F, 0x5191, 0x5193, 0x5195, 0x5196, + 0x51A4, 0x51A6, 0x51A2, 0x51A9, 0x51AA, 0x51AB, + 0x51B3, 0x51B1, 0x51B2, 0x51B0, 0x51B5, 0x51BD, + 0x51C5, 0x51C9, 0x51DB, 0x51E0, 0x8655, 0x51E9, + 0x51ED, 0x0000, 0x51F0, 0x51F5, 0x51FE, 0x5204, + 0x520B, 0x5214, 0x520E, 0x5227, 0x522A, 0x522E, + 0x5233, 0x5239, 0x524F, 0x5244, 0x524B, 0x524C, + 0x525E, 0x5254, 0x526A, 0x5274, 0x5269, 0x5273, + 0x527F, 0x527D, 0x528D, 0x5294, 0x5292, 0x5271, + 0x5288, 0x5291, 0x8FA8, 0x8FA7, 0x52AC, 0x52AD, + 0x52BC, 0x52B5, 0x52C1, 0x52CD, 0x52D7, 0x52DE, + 0x52E3, 0x52E6, 0x98ED, 0x52E0, 0x52F3, 0x52F5, + 0x52F8, 0x52F9, 0x5306, 0x5308, 0x7538, 0x530D, + 0x5310, 0x530F, 0x5315, 0x531A, 0x5323, 0x532F, + 0x5331, 0x5333, 0x5338, 0x5340, 0x5346, 0x5345, + 0x4E17, 0x5349, 0x534D, 0x51D6, 0x535E, 0x5369, + 0x536E, 0x5918, 0x537B, 0x5377, 0x5382, 0x5396, + 0x53A0, 0x53A6, 0x53A5, 0x53AE, 0x53B0, 0x53B6, + 0x53C3, 0x7C12, 0x96D9, 0x53DF, 0x66FC, 0x71EE, + 0x53EE, 0x53E8, 0x53ED, 0x53FA, 0x5401, 0x543D, + 0x5440, 0x542C, 0x542D, 0x543C, 0x542E, 0x5436, + 0x5429, 0x541D, 0x544E, 0x548F, 0x5475, 0x548E, + 0x545F, 0x5471, 0x5477, 0x5470, 0x5492, 0x547B, + 0x5480, 0x5476, 0x5484, 0x5490, 0x5486, 0x54C7, + 0x54A2, 0x54B8, 0x54A5, 0x54AC, 0x54C4, 0x54C8, + 0x54A8, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis9A[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x54AB, 0x54C2, + 0x54A4, 0x54BE, 0x54BC, 0x54D8, 0x54E5, 0x54E6, + 0x550F, 0x5514, 0x54FD, 0x54EE, 0x54ED, 0x54FA, + 0x54E2, 0x5539, 0x5540, 0x5563, 0x554C, 0x552E, + 0x555C, 0x5545, 0x5556, 0x5557, 0x5538, 0x5533, + 0x555D, 0x5599, 0x5580, 0x54AF, 0x558A, 0x559F, + 0x557B, 0x557E, 0x5598, 0x559E, 0x55AE, 0x557C, + 0x5583, 0x55A9, 0x5587, 0x55A8, 0x55DA, 0x55C5, + 0x55DF, 0x55C4, 0x55DC, 0x55E4, 0x55D4, 0x5614, + 0x55F7, 0x5616, 0x55FE, 0x55FD, 0x561B, 0x55F9, + 0x564E, 0x5650, 0x71DF, 0x5634, 0x5636, 0x5632, + 0x5638, 0x0000, 0x566B, 0x5664, 0x562F, 0x566C, + 0x566A, 0x5686, 0x5680, 0x568A, 0x56A0, 0x5694, + 0x568F, 0x56A5, 0x56AE, 0x56B6, 0x56B4, 0x56C2, + 0x56BC, 0x56C1, 0x56C3, 0x56C0, 0x56C8, 0x56CE, + 0x56D1, 0x56D3, 0x56D7, 0x56EE, 0x56F9, 0x5700, + 0x56FF, 0x5704, 0x5709, 0x5708, 0x570B, 0x570D, + 0x5713, 0x5718, 0x5716, 0x55C7, 0x571C, 0x5726, + 0x5737, 0x5738, 0x574E, 0x573B, 0x5740, 0x574F, + 0x5769, 0x57C0, 0x5788, 0x5761, 0x577F, 0x5789, + 0x5793, 0x57A0, 0x57B3, 0x57A4, 0x57AA, 0x57B0, + 0x57C3, 0x57C6, 0x57D4, 0x57D2, 0x57D3, 0x580A, + 0x57D6, 0x57E3, 0x580B, 0x5819, 0x581D, 0x5872, + 0x5821, 0x5862, 0x584B, 0x5870, 0x6BC0, 0x5852, + 0x583D, 0x5879, 0x5885, 0x58B9, 0x589F, 0x58AB, + 0x58BA, 0x58DE, 0x58BB, 0x58B8, 0x58AE, 0x58C5, + 0x58D3, 0x58D1, 0x58D7, 0x58D9, 0x58D8, 0x58E5, + 0x58DC, 0x58E4, 0x58DF, 0x58EF, 0x58FA, 0x58F9, + 0x58FB, 0x58FC, 0x58FD, 0x5902, 0x590A, 0x5910, + 0x591B, 0x68A6, 0x5925, 0x592C, 0x592D, 0x5932, + 0x5938, 0x593E, 0x7AD2, 0x5955, 0x5950, 0x594E, + 0x595A, 0x5958, 0x5962, 0x5960, 0x5967, 0x596C, + 0x5969, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis9B[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5978, 0x5981, + 0x599D, 0x4F5E, 0x4FAB, 0x59A3, 0x59B2, 0x59C6, + 0x59E8, 0x59DC, 0x598D, 0x59D9, 0x59DA, 0x5A25, + 0x5A1F, 0x5A11, 0x5A1C, 0x5A09, 0x5A1A, 0x5A40, + 0x5A6C, 0x5A49, 0x5A35, 0x5A36, 0x5A62, 0x5A6A, + 0x5A9A, 0x5ABC, 0x5ABE, 0x5ACB, 0x5AC2, 0x5ABD, + 0x5AE3, 0x5AD7, 0x5AE6, 0x5AE9, 0x5AD6, 0x5AFA, + 0x5AFB, 0x5B0C, 0x5B0B, 0x5B16, 0x5B32, 0x5AD0, + 0x5B2A, 0x5B36, 0x5B3E, 0x5B43, 0x5B45, 0x5B40, + 0x5B51, 0x5B55, 0x5B5A, 0x5B5B, 0x5B65, 0x5B69, + 0x5B70, 0x5B73, 0x5B75, 0x5B78, 0x6588, 0x5B7A, + 0x5B80, 0x0000, 0x5B83, 0x5BA6, 0x5BB8, 0x5BC3, + 0x5BC7, 0x5BC9, 0x5BD4, 0x5BD0, 0x5BE4, 0x5BE6, + 0x5BE2, 0x5BDE, 0x5BE5, 0x5BEB, 0x5BF0, 0x5BF6, + 0x5BF3, 0x5C05, 0x5C07, 0x5C08, 0x5C0D, 0x5C13, + 0x5C20, 0x5C22, 0x5C28, 0x5C38, 0x5C39, 0x5C41, + 0x5C46, 0x5C4E, 0x5C53, 0x5C50, 0x5C4F, 0x5B71, + 0x5C6C, 0x5C6E, 0x4E62, 0x5C76, 0x5C79, 0x5C8C, + 0x5C91, 0x5C94, 0x599B, 0x5CAB, 0x5CBB, 0x5CB6, + 0x5CBC, 0x5CB7, 0x5CC5, 0x5CBE, 0x5CC7, 0x5CD9, + 0x5CE9, 0x5CFD, 0x5CFA, 0x5CED, 0x5D8C, 0x5CEA, + 0x5D0B, 0x5D15, 0x5D17, 0x5D5C, 0x5D1F, 0x5D1B, + 0x5D11, 0x5D14, 0x5D22, 0x5D1A, 0x5D19, 0x5D18, + 0x5D4C, 0x5D52, 0x5D4E, 0x5D4B, 0x5D6C, 0x5D73, + 0x5D76, 0x5D87, 0x5D84, 0x5D82, 0x5DA2, 0x5D9D, + 0x5DAC, 0x5DAE, 0x5DBD, 0x5D90, 0x5DB7, 0x5DBC, + 0x5DC9, 0x5DCD, 0x5DD3, 0x5DD2, 0x5DD6, 0x5DDB, + 0x5DEB, 0x5DF2, 0x5DF5, 0x5E0B, 0x5E1A, 0x5E19, + 0x5E11, 0x5E1B, 0x5E36, 0x5E37, 0x5E44, 0x5E43, + 0x5E40, 0x5E4E, 0x5E57, 0x5E54, 0x5E5F, 0x5E62, + 0x5E64, 0x5E47, 0x5E75, 0x5E76, 0x5E7A, 0x9EBC, + 0x5E7F, 0x5EA0, 0x5EC1, 0x5EC2, 0x5EC8, 0x5ED0, + 0x5ECF, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis9C[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x5ED6, 0x5EE3, + 0x5EDD, 0x5EDA, 0x5EDB, 0x5EE2, 0x5EE1, 0x5EE8, + 0x5EE9, 0x5EEC, 0x5EF1, 0x5EF3, 0x5EF0, 0x5EF4, + 0x5EF8, 0x5EFE, 0x5F03, 0x5F09, 0x5F5D, 0x5F5C, + 0x5F0B, 0x5F11, 0x5F16, 0x5F29, 0x5F2D, 0x5F38, + 0x5F41, 0x5F48, 0x5F4C, 0x5F4E, 0x5F2F, 0x5F51, + 0x5F56, 0x5F57, 0x5F59, 0x5F61, 0x5F6D, 0x5F73, + 0x5F77, 0x5F83, 0x5F82, 0x5F7F, 0x5F8A, 0x5F88, + 0x5F91, 0x5F87, 0x5F9E, 0x5F99, 0x5F98, 0x5FA0, + 0x5FA8, 0x5FAD, 0x5FBC, 0x5FD6, 0x5FFB, 0x5FE4, + 0x5FF8, 0x5FF1, 0x5FDD, 0x60B3, 0x5FFF, 0x6021, + 0x6060, 0x0000, 0x6019, 0x6010, 0x6029, 0x600E, + 0x6031, 0x601B, 0x6015, 0x602B, 0x6026, 0x600F, + 0x603A, 0x605A, 0x6041, 0x606A, 0x6077, 0x605F, + 0x604A, 0x6046, 0x604D, 0x6063, 0x6043, 0x6064, + 0x6042, 0x606C, 0x606B, 0x6059, 0x6081, 0x608D, + 0x60E7, 0x6083, 0x609A, 0x6084, 0x609B, 0x6096, + 0x6097, 0x6092, 0x60A7, 0x608B, 0x60E1, 0x60B8, + 0x60E0, 0x60D3, 0x60B4, 0x5FF0, 0x60BD, 0x60C6, + 0x60B5, 0x60D8, 0x614D, 0x6115, 0x6106, 0x60F6, + 0x60F7, 0x6100, 0x60F4, 0x60FA, 0x6103, 0x6121, + 0x60FB, 0x60F1, 0x610D, 0x610E, 0x6147, 0x613E, + 0x6128, 0x6127, 0x614A, 0x613F, 0x613C, 0x612C, + 0x6134, 0x613D, 0x6142, 0x6144, 0x6173, 0x6177, + 0x6158, 0x6159, 0x615A, 0x616B, 0x6174, 0x616F, + 0x6165, 0x6171, 0x615F, 0x615D, 0x6153, 0x6175, + 0x6199, 0x6196, 0x6187, 0x61AC, 0x6194, 0x619A, + 0x618A, 0x6191, 0x61AB, 0x61AE, 0x61CC, 0x61CA, + 0x61C9, 0x61F7, 0x61C8, 0x61C3, 0x61C6, 0x61BA, + 0x61CB, 0x7F79, 0x61CD, 0x61E6, 0x61E3, 0x61F6, + 0x61FA, 0x61F4, 0x61FF, 0x61FD, 0x61FC, 0x61FE, + 0x6200, 0x6208, 0x6209, 0x620D, 0x620C, 0x6214, + 0x621B, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis9D[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x621E, 0x6221, + 0x622A, 0x622E, 0x6230, 0x6232, 0x6233, 0x6241, + 0x624E, 0x625E, 0x6263, 0x625B, 0x6260, 0x6268, + 0x627C, 0x6282, 0x6289, 0x627E, 0x6292, 0x6293, + 0x6296, 0x62D4, 0x6283, 0x6294, 0x62D7, 0x62D1, + 0x62BB, 0x62CF, 0x62FF, 0x62C6, 0x64D4, 0x62C8, + 0x62DC, 0x62CC, 0x62CA, 0x62C2, 0x62C7, 0x629B, + 0x62C9, 0x630C, 0x62EE, 0x62F1, 0x6327, 0x6302, + 0x6308, 0x62EF, 0x62F5, 0x6350, 0x633E, 0x634D, + 0x641C, 0x634F, 0x6396, 0x638E, 0x6380, 0x63AB, + 0x6376, 0x63A3, 0x638F, 0x6389, 0x639F, 0x63B5, + 0x636B, 0x0000, 0x6369, 0x63BE, 0x63E9, 0x63C0, + 0x63C6, 0x63E3, 0x63C9, 0x63D2, 0x63F6, 0x63C4, + 0x6416, 0x6434, 0x6406, 0x6413, 0x6426, 0x6436, + 0x651D, 0x6417, 0x6428, 0x640F, 0x6467, 0x646F, + 0x6476, 0x644E, 0x652A, 0x6495, 0x6493, 0x64A5, + 0x64A9, 0x6488, 0x64BC, 0x64DA, 0x64D2, 0x64C5, + 0x64C7, 0x64BB, 0x64D8, 0x64C2, 0x64F1, 0x64E7, + 0x8209, 0x64E0, 0x64E1, 0x62AC, 0x64E3, 0x64EF, + 0x652C, 0x64F6, 0x64F4, 0x64F2, 0x64FA, 0x6500, + 0x64FD, 0x6518, 0x651C, 0x6505, 0x6524, 0x6523, + 0x652B, 0x6534, 0x6535, 0x6537, 0x6536, 0x6538, + 0x754B, 0x6548, 0x6556, 0x6555, 0x654D, 0x6558, + 0x655E, 0x655D, 0x6572, 0x6578, 0x6582, 0x6583, + 0x8B8A, 0x659B, 0x659F, 0x65AB, 0x65B7, 0x65C3, + 0x65C6, 0x65C1, 0x65C4, 0x65CC, 0x65D2, 0x65DB, + 0x65D9, 0x65E0, 0x65E1, 0x65F1, 0x6772, 0x660A, + 0x6603, 0x65FB, 0x6773, 0x6635, 0x6636, 0x6634, + 0x661C, 0x664F, 0x6644, 0x6649, 0x6641, 0x665E, + 0x665D, 0x6664, 0x6667, 0x6668, 0x665F, 0x6662, + 0x6670, 0x6683, 0x6688, 0x668E, 0x6689, 0x6684, + 0x6698, 0x669D, 0x66C1, 0x66B9, 0x66C9, 0x66BE, + 0x66BC, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis9E[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x66C4, 0x66B8, + 0x66D6, 0x66DA, 0x66E0, 0x663F, 0x66E6, 0x66E9, + 0x66F0, 0x66F5, 0x66F7, 0x670F, 0x6716, 0x671E, + 0x6726, 0x6727, 0x9738, 0x672E, 0x673F, 0x6736, + 0x6741, 0x6738, 0x6737, 0x6746, 0x675E, 0x6760, + 0x6759, 0x6763, 0x6764, 0x6789, 0x6770, 0x67A9, + 0x677C, 0x676A, 0x678C, 0x678B, 0x67A6, 0x67A1, + 0x6785, 0x67B7, 0x67EF, 0x67B4, 0x67EC, 0x67B3, + 0x67E9, 0x67B8, 0x67E4, 0x67DE, 0x67DD, 0x67E2, + 0x67EE, 0x67B9, 0x67CE, 0x67C6, 0x67E7, 0x6A9C, + 0x681E, 0x6846, 0x6829, 0x6840, 0x684D, 0x6832, + 0x684E, 0x0000, 0x68B3, 0x682B, 0x6859, 0x6863, + 0x6877, 0x687F, 0x689F, 0x688F, 0x68AD, 0x6894, + 0x689D, 0x689B, 0x6883, 0x6AAE, 0x68B9, 0x6874, + 0x68B5, 0x68A0, 0x68BA, 0x690F, 0x688D, 0x687E, + 0x6901, 0x68CA, 0x6908, 0x68D8, 0x6922, 0x6926, + 0x68E1, 0x690C, 0x68CD, 0x68D4, 0x68E7, 0x68D5, + 0x6936, 0x6912, 0x6904, 0x68D7, 0x68E3, 0x6925, + 0x68F9, 0x68E0, 0x68EF, 0x6928, 0x692A, 0x691A, + 0x6923, 0x6921, 0x68C6, 0x6979, 0x6977, 0x695C, + 0x6978, 0x696B, 0x6954, 0x697E, 0x696E, 0x6939, + 0x6974, 0x693D, 0x6959, 0x6930, 0x6961, 0x695E, + 0x695D, 0x6981, 0x696A, 0x69B2, 0x69AE, 0x69D0, + 0x69BF, 0x69C1, 0x69D3, 0x69BE, 0x69CE, 0x5BE8, + 0x69CA, 0x69DD, 0x69BB, 0x69C3, 0x69A7, 0x6A2E, + 0x6991, 0x69A0, 0x699C, 0x6995, 0x69B4, 0x69DE, + 0x69E8, 0x6A02, 0x6A1B, 0x69FF, 0x6B0A, 0x69F9, + 0x69F2, 0x69E7, 0x6A05, 0x69B1, 0x6A1E, 0x69ED, + 0x6A14, 0x69EB, 0x6A0A, 0x6A12, 0x6AC1, 0x6A23, + 0x6A13, 0x6A44, 0x6A0C, 0x6A72, 0x6A36, 0x6A78, + 0x6A47, 0x6A62, 0x6A59, 0x6A66, 0x6A48, 0x6A38, + 0x6A22, 0x6A90, 0x6A8D, 0x6AA0, 0x6A84, 0x6AA2, + 0x6AA3, 0x0000, 0x0000, 0x0000 +}; + +static u16 Sjis9F[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6A97, 0x8617, + 0x6ABB, 0x6AC3, 0x6AC2, 0x6AB8, 0x6AB3, 0x6AAC, + 0x6ADE, 0x6AD1, 0x6ADF, 0x6AAA, 0x6ADA, 0x6AEA, + 0x6AFB, 0x6B05, 0x8616, 0x6AFA, 0x6B12, 0x6B16, + 0x9B31, 0x6B1F, 0x6B38, 0x6B37, 0x76DC, 0x6B39, + 0x98EE, 0x6B47, 0x6B43, 0x6B49, 0x6B50, 0x6B59, + 0x6B54, 0x6B5B, 0x6B5F, 0x6B61, 0x6B78, 0x6B79, + 0x6B7F, 0x6B80, 0x6B84, 0x6B83, 0x6B8D, 0x6B98, + 0x6B95, 0x6B9E, 0x6BA4, 0x6BAA, 0x6BAB, 0x6BAF, + 0x6BB2, 0x6BB1, 0x6BB3, 0x6BB7, 0x6BBC, 0x6BC6, + 0x6BCB, 0x6BD3, 0x6BDF, 0x6BEC, 0x6BEB, 0x6BF3, + 0x6BEF, 0x0000, 0x9EBE, 0x6C08, 0x6C13, 0x6C14, + 0x6C1B, 0x6C24, 0x6C23, 0x6C5E, 0x6C55, 0x6C62, + 0x6C6A, 0x6C82, 0x6C8D, 0x6C9A, 0x6C81, 0x6C9B, + 0x6C7E, 0x6C68, 0x6C73, 0x6C92, 0x6C90, 0x6CC4, + 0x6CF1, 0x6CD3, 0x6CBD, 0x6CD7, 0x6CC5, 0x6CDD, + 0x6CAE, 0x6CB1, 0x6CBE, 0x6CBA, 0x6CDB, 0x6CEF, + 0x6CD9, 0x6CEA, 0x6D1F, 0x884D, 0x6D36, 0x6D2B, + 0x6D3D, 0x6D38, 0x6D19, 0x6D35, 0x6D33, 0x6D12, + 0x6D0C, 0x6D63, 0x6D93, 0x6D64, 0x6D5A, 0x6D79, + 0x6D59, 0x6D8E, 0x6D95, 0x6FE4, 0x6D85, 0x6DF9, + 0x6E15, 0x6E0A, 0x6DB5, 0x6DC7, 0x6DE6, 0x6DB8, + 0x6DC6, 0x6DEC, 0x6DDE, 0x6DCC, 0x6DE8, 0x6DD2, + 0x6DC5, 0x6DFA, 0x6DD9, 0x6DE4, 0x6DD5, 0x6DEA, + 0x6DEE, 0x6E2D, 0x6E6E, 0x6E2E, 0x6E19, 0x6E72, + 0x6E5F, 0x6E3E, 0x6E23, 0x6E6B, 0x6E2B, 0x6E76, + 0x6E4D, 0x6E1F, 0x6E43, 0x6E3A, 0x6E4E, 0x6E24, + 0x6EFF, 0x6E1D, 0x6E38, 0x6E82, 0x6EAA, 0x6E98, + 0x6EC9, 0x6EB7, 0x6ED3, 0x6EBD, 0x6EAF, 0x6EC4, + 0x6EB2, 0x6ED4, 0x6ED5, 0x6E8F, 0x6EA5, 0x6EC2, + 0x6E9F, 0x6F41, 0x6F11, 0x704C, 0x6EEC, 0x6EF8, + 0x6EFE, 0x6F3F, 0x6EF2, 0x6F31, 0x6EEF, 0x6F32, + 0x6ECC, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE0[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x6F3E, 0x6F13, + 0x6EF7, 0x6F86, 0x6F7A, 0x6F78, 0x6F81, 0x6F80, + 0x6F6F, 0x6F5B, 0x6FF3, 0x6F6D, 0x6F82, 0x6F7C, + 0x6F58, 0x6F8E, 0x6F91, 0x6FC2, 0x6F66, 0x6FB3, + 0x6FA3, 0x6FA1, 0x6FA4, 0x6FB9, 0x6FC6, 0x6FAA, + 0x6FDF, 0x6FD5, 0x6FEC, 0x6FD4, 0x6FD8, 0x6FF1, + 0x6FEE, 0x6FDB, 0x7009, 0x700B, 0x6FFA, 0x7011, + 0x7001, 0x700F, 0x6FFE, 0x701B, 0x701A, 0x6F74, + 0x701D, 0x7018, 0x701F, 0x7030, 0x703E, 0x7032, + 0x7051, 0x7063, 0x7099, 0x7092, 0x70AF, 0x70F1, + 0x70AC, 0x70B8, 0x70B3, 0x70AE, 0x70DF, 0x70CB, + 0x70DD, 0x0000, 0x70D9, 0x7109, 0x70FD, 0x711C, + 0x7119, 0x7165, 0x7155, 0x7188, 0x7166, 0x7162, + 0x714C, 0x7156, 0x716C, 0x718F, 0x71FB, 0x7184, + 0x7195, 0x71A8, 0x71AC, 0x71D7, 0x71B9, 0x71BE, + 0x71D2, 0x71C9, 0x71D4, 0x71CE, 0x71E0, 0x71EC, + 0x71E7, 0x71F5, 0x71FC, 0x71F9, 0x71FF, 0x720D, + 0x7210, 0x721B, 0x7228, 0x722D, 0x722C, 0x7230, + 0x7232, 0x723B, 0x723C, 0x723F, 0x7240, 0x7246, + 0x724B, 0x7258, 0x7274, 0x727E, 0x7282, 0x7281, + 0x7287, 0x7292, 0x7296, 0x72A2, 0x72A7, 0x72B9, + 0x72B2, 0x72C3, 0x72C6, 0x72C4, 0x72CE, 0x72D2, + 0x72E2, 0x72E0, 0x72E1, 0x72F9, 0x72F7, 0x500F, + 0x7317, 0x730A, 0x731C, 0x7316, 0x731D, 0x7334, + 0x732F, 0x7329, 0x7325, 0x733E, 0x734E, 0x734F, + 0x9ED8, 0x7357, 0x736A, 0x7368, 0x7370, 0x7378, + 0x7375, 0x737B, 0x737A, 0x73C8, 0x73B3, 0x73CE, + 0x73BB, 0x73C0, 0x73E5, 0x73EE, 0x73DE, 0x74A2, + 0x7405, 0x746F, 0x7425, 0x73F8, 0x7432, 0x743A, + 0x7455, 0x743F, 0x745F, 0x7459, 0x7441, 0x745C, + 0x7469, 0x7470, 0x7463, 0x746A, 0x7476, 0x747E, + 0x748B, 0x749E, 0x74A7, 0x74CA, 0x74CF, 0x74D4, + 0x73F1, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE1[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x74E0, 0x74E3, + 0x74E7, 0x74E9, 0x74EE, 0x74F2, 0x74F0, 0x74F1, + 0x74F8, 0x74F7, 0x7504, 0x7503, 0x7505, 0x750C, + 0x750E, 0x750D, 0x7515, 0x7513, 0x751E, 0x7526, + 0x752C, 0x753C, 0x7544, 0x754D, 0x754A, 0x7549, + 0x755B, 0x7546, 0x755A, 0x7569, 0x7564, 0x7567, + 0x756B, 0x756D, 0x7578, 0x7576, 0x7586, 0x7587, + 0x7574, 0x758A, 0x7589, 0x7582, 0x7594, 0x759A, + 0x759D, 0x75A5, 0x75A3, 0x75C2, 0x75B3, 0x75C3, + 0x75B5, 0x75BD, 0x75B8, 0x75BC, 0x75B1, 0x75CD, + 0x75CA, 0x75D2, 0x75D9, 0x75E3, 0x75DE, 0x75FE, + 0x75FF, 0x0000, 0x75FC, 0x7601, 0x75F0, 0x75FA, + 0x75F2, 0x75F3, 0x760B, 0x760D, 0x7609, 0x761F, + 0x7627, 0x7620, 0x7621, 0x7622, 0x7624, 0x7634, + 0x7630, 0x763B, 0x7647, 0x7648, 0x7646, 0x765C, + 0x7658, 0x7661, 0x7662, 0x7668, 0x7669, 0x766A, + 0x7667, 0x766C, 0x7670, 0x7672, 0x7676, 0x7678, + 0x767C, 0x7680, 0x7683, 0x7688, 0x768B, 0x768E, + 0x7696, 0x7693, 0x7699, 0x769A, 0x76B0, 0x76B4, + 0x76B8, 0x76B9, 0x76BA, 0x76C2, 0x76CD, 0x76D6, + 0x76D2, 0x76DE, 0x76E1, 0x76E5, 0x76E7, 0x76EA, + 0x862F, 0x76FB, 0x7708, 0x7707, 0x7704, 0x7729, + 0x7724, 0x771E, 0x7725, 0x7726, 0x771B, 0x7737, + 0x7738, 0x7747, 0x775A, 0x7768, 0x776B, 0x775B, + 0x7765, 0x777F, 0x777E, 0x7779, 0x778E, 0x778B, + 0x7791, 0x77A0, 0x779E, 0x77B0, 0x77B6, 0x77B9, + 0x77BF, 0x77BC, 0x77BD, 0x77BB, 0x77C7, 0x77CD, + 0x77D7, 0x77DA, 0x77DC, 0x77E3, 0x77EE, 0x77FC, + 0x780C, 0x7812, 0x7926, 0x7820, 0x792A, 0x7845, + 0x788E, 0x7874, 0x7886, 0x787C, 0x789A, 0x788C, + 0x78A3, 0x78B5, 0x78AA, 0x78AF, 0x78D1, 0x78C6, + 0x78CB, 0x78D4, 0x78BE, 0x78BC, 0x78C5, 0x78CA, + 0x78EC, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE2[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x78E7, 0x78DA, + 0x78FD, 0x78F4, 0x7907, 0x7912, 0x7911, 0x7919, + 0x792C, 0x792B, 0x7940, 0x7960, 0x7957, 0x795F, + 0x795A, 0x7955, 0x7953, 0x797A, 0x797F, 0x798A, + 0x799D, 0x79A7, 0x9F4B, 0x79AA, 0x79AE, 0x79B3, + 0x79B9, 0x79BA, 0x79C9, 0x79D5, 0x79E7, 0x79EC, + 0x79E1, 0x79E3, 0x7A08, 0x7A0D, 0x7A18, 0x7A19, + 0x7A20, 0x7A1F, 0x7980, 0x7A31, 0x7A3B, 0x7A3E, + 0x7A37, 0x7A43, 0x7A57, 0x7A49, 0x7A61, 0x7A62, + 0x7A69, 0x9F9D, 0x7A70, 0x7A79, 0x7A7D, 0x7A88, + 0x7A97, 0x7A95, 0x7A98, 0x7A96, 0x7AA9, 0x7AC8, + 0x7AB0, 0x0000, 0x7AB6, 0x7AC5, 0x7AC4, 0x7ABF, + 0x9083, 0x7AC7, 0x7ACA, 0x7ACD, 0x7ACF, 0x7AD5, + 0x7AD3, 0x7AD9, 0x7ADA, 0x7ADD, 0x7AE1, 0x7AE2, + 0x7AE6, 0x7AED, 0x7AF0, 0x7B02, 0x7B0F, 0x7B0A, + 0x7B06, 0x7B33, 0x7B18, 0x7B19, 0x7B1E, 0x7B35, + 0x7B28, 0x7B36, 0x7B50, 0x7B7A, 0x7B04, 0x7B4D, + 0x7B0B, 0x7B4C, 0x7B45, 0x7B75, 0x7B65, 0x7B74, + 0x7B67, 0x7B70, 0x7B71, 0x7B6C, 0x7B6E, 0x7B9D, + 0x7B98, 0x7B9F, 0x7B8D, 0x7B9C, 0x7B9A, 0x7B8B, + 0x7B92, 0x7B8F, 0x7B5D, 0x7B99, 0x7BCB, 0x7BC1, + 0x7BCC, 0x7BCF, 0x7BB4, 0x7BC6, 0x7BDD, 0x7BE9, + 0x7C11, 0x7C14, 0x7BE6, 0x7BE5, 0x7C60, 0x7C00, + 0x7C07, 0x7C13, 0x7BF3, 0x7BF7, 0x7C17, 0x7C0D, + 0x7BF6, 0x7C23, 0x7C27, 0x7C2A, 0x7C1F, 0x7C37, + 0x7C2B, 0x7C3D, 0x7C4C, 0x7C43, 0x7C54, 0x7C4F, + 0x7C40, 0x7C50, 0x7C58, 0x7C5F, 0x7C64, 0x7C56, + 0x7C65, 0x7C6C, 0x7C75, 0x7C83, 0x7C90, 0x7CA4, + 0x7CAD, 0x7CA2, 0x7CAB, 0x7CA1, 0x7CA8, 0x7CB3, + 0x7CB2, 0x7CB1, 0x7CAE, 0x7CB9, 0x7CBD, 0x7CC0, + 0x7CC5, 0x7CC2, 0x7CD8, 0x7CD2, 0x7CDC, 0x7CE2, + 0x9B3B, 0x7CEF, 0x7CF2, 0x7CF4, 0x7CF6, 0x7CFA, + 0x7D06, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE3[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x7D02, 0x7D1C, + 0x7D15, 0x7D0A, 0x7D45, 0x7D4B, 0x7D2E, 0x7D32, + 0x7D3F, 0x7D35, 0x7D46, 0x7D73, 0x7D56, 0x7D4E, + 0x7D72, 0x7D68, 0x7D6E, 0x7D4F, 0x7D63, 0x7D93, + 0x7D89, 0x7D5B, 0x7D8F, 0x7D7D, 0x7D9B, 0x7DBA, + 0x7DAE, 0x7DA3, 0x7DB5, 0x7DC7, 0x7DBD, 0x7DAB, + 0x7E3D, 0x7DA2, 0x7DAF, 0x7DDC, 0x7DB8, 0x7D9F, + 0x7DB0, 0x7DD8, 0x7DDD, 0x7DE4, 0x7DDE, 0x7DFB, + 0x7DF2, 0x7DE1, 0x7E05, 0x7E0A, 0x7E23, 0x7E21, + 0x7E12, 0x7E31, 0x7E1F, 0x7E09, 0x7E0B, 0x7E22, + 0x7E46, 0x7E66, 0x7E3B, 0x7E35, 0x7E39, 0x7E43, + 0x7E37, 0x0000, 0x7E32, 0x7E3A, 0x7E67, 0x7E5D, + 0x7E56, 0x7E5E, 0x7E59, 0x7E5A, 0x7E79, 0x7E6A, + 0x7E69, 0x7E7C, 0x7E7B, 0x7E83, 0x7DD5, 0x7E7D, + 0x8FAE, 0x7E7F, 0x7E88, 0x7E89, 0x7E8C, 0x7E92, + 0x7E90, 0x7E93, 0x7E94, 0x7E96, 0x7E8E, 0x7E9B, + 0x7E9C, 0x7F38, 0x7F3A, 0x7F45, 0x7F4C, 0x7F4D, + 0x7F4E, 0x7F50, 0x7F51, 0x7F55, 0x7F54, 0x7F58, + 0x7F5F, 0x7F60, 0x7F68, 0x7F69, 0x7F67, 0x7F78, + 0x7F82, 0x7F86, 0x7F83, 0x7F88, 0x7F87, 0x7F8C, + 0x7F94, 0x7F9E, 0x7F9D, 0x7F9A, 0x7FA3, 0x7FAF, + 0x7FB2, 0x7FB9, 0x7FAE, 0x7FB6, 0x7FB8, 0x8B71, + 0x7FC5, 0x7FC6, 0x7FCA, 0x7FD5, 0x7FD4, 0x7FE1, + 0x7FE6, 0x7FE9, 0x7FF3, 0x7FF9, 0x98DC, 0x8006, + 0x8004, 0x800B, 0x8012, 0x8018, 0x8019, 0x801C, + 0x8021, 0x8028, 0x803F, 0x803B, 0x804A, 0x8046, + 0x8052, 0x8058, 0x805A, 0x805F, 0x8062, 0x8068, + 0x8073, 0x8072, 0x8070, 0x8076, 0x8079, 0x807D, + 0x807F, 0x8084, 0x8086, 0x8085, 0x809B, 0x8093, + 0x809A, 0x80AD, 0x5190, 0x80AC, 0x80DB, 0x80E5, + 0x80D9, 0x80DD, 0x80C4, 0x80DA, 0x80D6, 0x8109, + 0x80EF, 0x80F1, 0x811B, 0x8129, 0x8123, 0x812F, + 0x814B, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE4[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x968B, 0x8146, + 0x813E, 0x8153, 0x8151, 0x80FC, 0x8171, 0x816E, + 0x8165, 0x8166, 0x8174, 0x8183, 0x8188, 0x818A, + 0x8180, 0x8182, 0x81A0, 0x8195, 0x81A4, 0x81A3, + 0x815F, 0x8193, 0x81A9, 0x81B0, 0x81B5, 0x81BE, + 0x81B8, 0x81BD, 0x81C0, 0x81C2, 0x81BA, 0x81C9, + 0x81CD, 0x81D1, 0x81D9, 0x81D8, 0x81C8, 0x81DA, + 0x81DF, 0x81E0, 0x81E7, 0x81FA, 0x81FB, 0x81FE, + 0x8201, 0x8202, 0x8205, 0x8207, 0x820A, 0x820D, + 0x8210, 0x8216, 0x8229, 0x822B, 0x8238, 0x8233, + 0x8240, 0x8259, 0x8258, 0x825D, 0x825A, 0x825F, + 0x8264, 0x0000, 0x8262, 0x8268, 0x826A, 0x826B, + 0x822E, 0x8271, 0x8277, 0x8278, 0x827E, 0x828D, + 0x8292, 0x82AB, 0x829F, 0x82BB, 0x82AC, 0x82E1, + 0x82E3, 0x82DF, 0x82D2, 0x82F4, 0x82F3, 0x82FA, + 0x8393, 0x8303, 0x82FB, 0x82F9, 0x82DE, 0x8306, + 0x82DC, 0x8309, 0x82D9, 0x8335, 0x8334, 0x8316, + 0x8332, 0x8331, 0x8340, 0x8339, 0x8350, 0x8345, + 0x832F, 0x832B, 0x8317, 0x8318, 0x8385, 0x839A, + 0x83AA, 0x839F, 0x83A2, 0x8396, 0x8323, 0x838E, + 0x8387, 0x838A, 0x837C, 0x83B5, 0x8373, 0x8375, + 0x83A0, 0x8389, 0x83A8, 0x83F4, 0x8413, 0x83EB, + 0x83CE, 0x83FD, 0x8403, 0x83D8, 0x840B, 0x83C1, + 0x83F7, 0x8407, 0x83E0, 0x83F2, 0x840D, 0x8422, + 0x8420, 0x83BD, 0x8438, 0x8506, 0x83FB, 0x846D, + 0x842A, 0x843C, 0x855A, 0x8484, 0x8477, 0x846B, + 0x84AD, 0x846E, 0x8482, 0x8469, 0x8446, 0x842C, + 0x846F, 0x8479, 0x8435, 0x84CA, 0x8462, 0x84B9, + 0x84BF, 0x849F, 0x84D9, 0x84CD, 0x84BB, 0x84DA, + 0x84D0, 0x84C1, 0x84C6, 0x84D6, 0x84A1, 0x8521, + 0x84FF, 0x84F4, 0x8517, 0x8518, 0x852C, 0x851F, + 0x8515, 0x8514, 0x84FC, 0x8540, 0x8563, 0x8558, + 0x8548, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE5[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8541, 0x8602, + 0x854B, 0x8555, 0x8580, 0x85A4, 0x8588, 0x8591, + 0x858A, 0x85A8, 0x856D, 0x8594, 0x859B, 0x85EA, + 0x8587, 0x859C, 0x8577, 0x857E, 0x8590, 0x85C9, + 0x85BA, 0x85CF, 0x85B9, 0x85D0, 0x85D5, 0x85DD, + 0x85E5, 0x85DC, 0x85F9, 0x860A, 0x8613, 0x860B, + 0x85FE, 0x85FA, 0x8606, 0x8622, 0x861A, 0x8630, + 0x863F, 0x864D, 0x4E55, 0x8654, 0x865F, 0x8667, + 0x8671, 0x8693, 0x86A3, 0x86A9, 0x86AA, 0x868B, + 0x868C, 0x86B6, 0x86AF, 0x86C4, 0x86C6, 0x86B0, + 0x86C9, 0x8823, 0x86AB, 0x86D4, 0x86DE, 0x86E9, + 0x86EC, 0x0000, 0x86DF, 0x86DB, 0x86EF, 0x8712, + 0x8706, 0x8708, 0x8700, 0x8703, 0x86FB, 0x8711, + 0x8709, 0x870D, 0x86F9, 0x870A, 0x8734, 0x873F, + 0x8737, 0x873B, 0x8725, 0x8729, 0x871A, 0x8760, + 0x875F, 0x8778, 0x874C, 0x874E, 0x8774, 0x8757, + 0x8768, 0x876E, 0x8759, 0x8753, 0x8763, 0x876A, + 0x8805, 0x87A2, 0x879F, 0x8782, 0x87AF, 0x87CB, + 0x87BD, 0x87C0, 0x87D0, 0x96D6, 0x87AB, 0x87C4, + 0x87B3, 0x87C7, 0x87C6, 0x87BB, 0x87EF, 0x87F2, + 0x87E0, 0x880F, 0x880D, 0x87FE, 0x87F6, 0x87F7, + 0x880E, 0x87D2, 0x8811, 0x8816, 0x8815, 0x8822, + 0x8821, 0x8831, 0x8836, 0x8839, 0x8827, 0x883B, + 0x8844, 0x8842, 0x8852, 0x8859, 0x885E, 0x8862, + 0x886B, 0x8881, 0x887E, 0x889E, 0x8875, 0x887D, + 0x88B5, 0x8872, 0x8882, 0x8897, 0x8892, 0x88AE, + 0x8899, 0x88A2, 0x888D, 0x88A4, 0x88B0, 0x88BF, + 0x88B1, 0x88C3, 0x88C4, 0x88D4, 0x88D8, 0x88D9, + 0x88DD, 0x88F9, 0x8902, 0x88FC, 0x88F4, 0x88E8, + 0x88F2, 0x8904, 0x890C, 0x890A, 0x8913, 0x8943, + 0x891E, 0x8925, 0x892A, 0x892B, 0x8941, 0x8944, + 0x893B, 0x8936, 0x8938, 0x894C, 0x891D, 0x8960, + 0x895E, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE6[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8966, 0x8964, + 0x896D, 0x896A, 0x896F, 0x8974, 0x8977, 0x897E, + 0x8983, 0x8988, 0x898A, 0x8993, 0x8998, 0x89A1, + 0x89A9, 0x89A6, 0x89AC, 0x89AF, 0x89B2, 0x89BA, + 0x89BD, 0x89BF, 0x89C0, 0x89DA, 0x89DC, 0x89DD, + 0x89E7, 0x89F4, 0x89F8, 0x8A03, 0x8A16, 0x8A10, + 0x8A0C, 0x8A1B, 0x8A1D, 0x8A25, 0x8A36, 0x8A41, + 0x8A5B, 0x8A52, 0x8A46, 0x8A48, 0x8A7C, 0x8A6D, + 0x8A6C, 0x8A62, 0x8A85, 0x8A82, 0x8A84, 0x8AA8, + 0x8AA1, 0x8A91, 0x8AA5, 0x8AA6, 0x8A9A, 0x8AA3, + 0x8AC4, 0x8ACD, 0x8AC2, 0x8ADA, 0x8AEB, 0x8AF3, + 0x8AE7, 0x0000, 0x8AE4, 0x8AF1, 0x8B14, 0x8AE0, + 0x8AE2, 0x8AF7, 0x8ADE, 0x8ADB, 0x8B0C, 0x8B07, + 0x8B1A, 0x8AE1, 0x8B16, 0x8B10, 0x8B17, 0x8B20, + 0x8B33, 0x97AB, 0x8B26, 0x8B2B, 0x8B3E, 0x8B28, + 0x8B41, 0x8B4C, 0x8B4F, 0x8B4E, 0x8B49, 0x8B56, + 0x8B5B, 0x8B5A, 0x8B6B, 0x8B5F, 0x8B6C, 0x8B6F, + 0x8B74, 0x8B7D, 0x8B80, 0x8B8C, 0x8B8E, 0x8B92, + 0x8B93, 0x8B96, 0x8B99, 0x8B9A, 0x8C3A, 0x8C41, + 0x8C3F, 0x8C48, 0x8C4C, 0x8C4E, 0x8C50, 0x8C55, + 0x8C62, 0x8C6C, 0x8C78, 0x8C7A, 0x8C82, 0x8C89, + 0x8C85, 0x8C8A, 0x8C8D, 0x8C8E, 0x8C94, 0x8C7C, + 0x8C98, 0x621D, 0x8CAD, 0x8CAA, 0x8CBD, 0x8CB2, + 0x8CB3, 0x8CAE, 0x8CB6, 0x8CC8, 0x8CC1, 0x8CE4, + 0x8CE3, 0x8CDA, 0x8CFD, 0x8CFA, 0x8CFB, 0x8D04, + 0x8D05, 0x8D0A, 0x8D07, 0x8D0F, 0x8D0D, 0x8D10, + 0x9F4E, 0x8D13, 0x8CCD, 0x8D14, 0x8D16, 0x8D67, + 0x8D6D, 0x8D71, 0x8D73, 0x8D81, 0x8D99, 0x8DC2, + 0x8DBE, 0x8DBA, 0x8DCF, 0x8DDA, 0x8DD6, 0x8DCC, + 0x8DDB, 0x8DCB, 0x8DEA, 0x8DEB, 0x8DDF, 0x8DE3, + 0x8DFC, 0x8E08, 0x8E09, 0x8DFF, 0x8E1D, 0x8E1E, + 0x8E10, 0x8E1F, 0x8E42, 0x8E35, 0x8E30, 0x8E34, + 0x8E4A, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE7[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x8E47, 0x8E49, + 0x8E4C, 0x8E50, 0x8E48, 0x8E59, 0x8E64, 0x8E60, + 0x8E2A, 0x8E63, 0x8E55, 0x8E76, 0x8E72, 0x8E7C, + 0x8E81, 0x8E87, 0x8E85, 0x8E84, 0x8E8B, 0x8E8A, + 0x8E93, 0x8E91, 0x8E94, 0x8E99, 0x8EAA, 0x8EA1, + 0x8EAC, 0x8EB0, 0x8EC6, 0x8EB1, 0x8EBE, 0x8EC5, + 0x8EC8, 0x8ECB, 0x8EDB, 0x8EE3, 0x8EFC, 0x8EFB, + 0x8EEB, 0x8EFE, 0x8F0A, 0x8F05, 0x8F15, 0x8F12, + 0x8F19, 0x8F13, 0x8F1C, 0x8F1F, 0x8F1B, 0x8F0C, + 0x8F26, 0x8F33, 0x8F3B, 0x8F39, 0x8F45, 0x8F42, + 0x8F3E, 0x8F4C, 0x8F49, 0x8F46, 0x8F4E, 0x8F57, + 0x8F5C, 0x0000, 0x8F62, 0x8F63, 0x8F64, 0x8F9C, + 0x8F9F, 0x8FA3, 0x8FAD, 0x8FAF, 0x8FB7, 0x8FDA, + 0x8FE5, 0x8FE2, 0x8FEA, 0x8FEF, 0x9087, 0x8FF4, + 0x9005, 0x8FF9, 0x8FFA, 0x9011, 0x9015, 0x9021, + 0x900D, 0x901E, 0x9016, 0x900B, 0x9027, 0x9036, + 0x9035, 0x9039, 0x8FF8, 0x904F, 0x9050, 0x9051, + 0x9052, 0x900E, 0x9049, 0x903E, 0x9056, 0x9058, + 0x905E, 0x9068, 0x906F, 0x9076, 0x96A8, 0x9072, + 0x9082, 0x907D, 0x9081, 0x9080, 0x908A, 0x9089, + 0x908F, 0x90A8, 0x90AF, 0x90B1, 0x90B5, 0x90E2, + 0x90E4, 0x6248, 0x90DB, 0x9102, 0x9112, 0x9119, + 0x9132, 0x9130, 0x914A, 0x9156, 0x9158, 0x9163, + 0x9165, 0x9169, 0x9173, 0x9172, 0x918B, 0x9189, + 0x9182, 0x91A2, 0x91AB, 0x91AF, 0x91AA, 0x91B5, + 0x91B4, 0x91BA, 0x91C0, 0x91C1, 0x91C9, 0x91CB, + 0x91D0, 0x91D6, 0x91DF, 0x91E1, 0x91DB, 0x91FC, + 0x91F5, 0x91F6, 0x921E, 0x91FF, 0x9214, 0x922C, + 0x9215, 0x9211, 0x925E, 0x9257, 0x9245, 0x9249, + 0x9264, 0x9248, 0x9295, 0x923F, 0x924B, 0x9250, + 0x929C, 0x9296, 0x9293, 0x929B, 0x925A, 0x92CF, + 0x92B9, 0x92B7, 0x92E9, 0x930F, 0x92FA, 0x9344, + 0x932E, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE8[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9319, 0x9322, + 0x931A, 0x9323, 0x933A, 0x9335, 0x933B, 0x935C, + 0x9360, 0x937C, 0x936E, 0x9356, 0x93B0, 0x93AC, + 0x93AD, 0x9394, 0x93B9, 0x93D6, 0x93D7, 0x93E8, + 0x93E5, 0x93D8, 0x93C3, 0x93DD, 0x93D0, 0x93C8, + 0x93E4, 0x941A, 0x9414, 0x9413, 0x9403, 0x9407, + 0x9410, 0x9436, 0x942B, 0x9435, 0x9421, 0x943A, + 0x9441, 0x9452, 0x9444, 0x945B, 0x9460, 0x9462, + 0x945E, 0x946A, 0x9229, 0x9470, 0x9475, 0x9477, + 0x947D, 0x945A, 0x947C, 0x947E, 0x9481, 0x947F, + 0x9582, 0x9587, 0x958A, 0x9594, 0x9596, 0x9598, + 0x9599, 0x0000, 0x95A0, 0x95A8, 0x95A7, 0x95AD, + 0x95BC, 0x95BB, 0x95B9, 0x95BE, 0x95CA, 0x6FF6, + 0x95C3, 0x95CD, 0x95CC, 0x95D5, 0x95D4, 0x95D6, + 0x95DC, 0x95E1, 0x95E5, 0x95E2, 0x9621, 0x9628, + 0x962E, 0x962F, 0x9642, 0x964C, 0x964F, 0x964B, + 0x9677, 0x965C, 0x965E, 0x965D, 0x965F, 0x9666, + 0x9672, 0x966C, 0x968D, 0x9698, 0x9695, 0x9697, + 0x96AA, 0x96A7, 0x96B1, 0x96B2, 0x96B0, 0x96B4, + 0x96B6, 0x96B8, 0x96B9, 0x96CE, 0x96CB, 0x96C9, + 0x96CD, 0x894D, 0x96DC, 0x970D, 0x96D5, 0x96F9, + 0x9704, 0x9706, 0x9708, 0x9713, 0x970E, 0x9711, + 0x970F, 0x9716, 0x9719, 0x9724, 0x972A, 0x9730, + 0x9739, 0x973D, 0x973E, 0x9744, 0x9746, 0x9748, + 0x9742, 0x9749, 0x975C, 0x9760, 0x9764, 0x9766, + 0x9768, 0x52D2, 0x976B, 0x9771, 0x9779, 0x9785, + 0x977C, 0x9781, 0x977A, 0x9786, 0x978B, 0x978F, + 0x9790, 0x979C, 0x97A8, 0x97A6, 0x97A3, 0x97B3, + 0x97B4, 0x97C3, 0x97C6, 0x97C8, 0x97CB, 0x97DC, + 0x97ED, 0x9F4F, 0x97F2, 0x7ADF, 0x97F6, 0x97F5, + 0x980F, 0x980C, 0x9838, 0x9824, 0x9821, 0x9837, + 0x983D, 0x9846, 0x984F, 0x984B, 0x986B, 0x986F, + 0x9870, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisE9[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9871, 0x9874, + 0x9873, 0x98AA, 0x98AF, 0x98B1, 0x98B6, 0x98C4, + 0x98C3, 0x98C6, 0x98E9, 0x98EB, 0x9903, 0x9909, + 0x9912, 0x9914, 0x9918, 0x9921, 0x991D, 0x991E, + 0x9924, 0x9920, 0x992C, 0x992E, 0x993D, 0x993E, + 0x9942, 0x9949, 0x9945, 0x9950, 0x994B, 0x9951, + 0x9952, 0x994C, 0x9955, 0x9997, 0x9998, 0x99A5, + 0x99AD, 0x99AE, 0x99BC, 0x99DF, 0x99DB, 0x99DD, + 0x99D8, 0x99D1, 0x99ED, 0x99EE, 0x99F1, 0x99F2, + 0x99FB, 0x99F8, 0x9A01, 0x9A0F, 0x9A05, 0x99E2, + 0x9A19, 0x9A2B, 0x9A37, 0x9A45, 0x9A42, 0x9A40, + 0x9A43, 0x0000, 0x9A3E, 0x9A55, 0x9A4D, 0x9A5B, + 0x9A57, 0x9A5F, 0x9A62, 0x9A65, 0x9A64, 0x9A69, + 0x9A6B, 0x9A6A, 0x9AAD, 0x9AB0, 0x9ABC, 0x9AC0, + 0x9ACF, 0x9AD1, 0x9AD3, 0x9AD4, 0x9ADE, 0x9ADF, + 0x9AE2, 0x9AE3, 0x9AE6, 0x9AEF, 0x9AEB, 0x9AEE, + 0x9AF4, 0x9AF1, 0x9AF7, 0x9AFB, 0x9B06, 0x9B18, + 0x9B1A, 0x9B1F, 0x9B22, 0x9B23, 0x9B25, 0x9B27, + 0x9B28, 0x9B29, 0x9B2A, 0x9B2E, 0x9B2F, 0x9B32, + 0x9B44, 0x9B43, 0x9B4F, 0x9B4D, 0x9B4E, 0x9B51, + 0x9B58, 0x9B74, 0x9B93, 0x9B83, 0x9B91, 0x9B96, + 0x9B97, 0x9B9F, 0x9BA0, 0x9BA8, 0x9BB4, 0x9BC0, + 0x9BCA, 0x9BB9, 0x9BC6, 0x9BCF, 0x9BD1, 0x9BD2, + 0x9BE3, 0x9BE2, 0x9BE4, 0x9BD4, 0x9BE1, 0x9C3A, + 0x9BF2, 0x9BF1, 0x9BF0, 0x9C15, 0x9C14, 0x9C09, + 0x9C13, 0x9C0C, 0x9C06, 0x9C08, 0x9C12, 0x9C0A, + 0x9C04, 0x9C2E, 0x9C1B, 0x9C25, 0x9C24, 0x9C21, + 0x9C30, 0x9C47, 0x9C32, 0x9C46, 0x9C3E, 0x9C5A, + 0x9C60, 0x9C67, 0x9C76, 0x9C78, 0x9CE7, 0x9CEC, + 0x9CF0, 0x9D09, 0x9D08, 0x9CEB, 0x9D03, 0x9D06, + 0x9D2A, 0x9D26, 0x9DAF, 0x9D23, 0x9D1F, 0x9D44, + 0x9D15, 0x9D12, 0x9D41, 0x9D3F, 0x9D3E, 0x9D46, + 0x9D48, 0x0000, 0x0000, 0x0000 +}; + +static u16 SjisEA[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x9D5D, 0x9D5E, + 0x9D64, 0x9D51, 0x9D50, 0x9D59, 0x9D72, 0x9D89, + 0x9D87, 0x9DAB, 0x9D6F, 0x9D7A, 0x9D9A, 0x9DA4, + 0x9DA9, 0x9DB2, 0x9DC4, 0x9DC1, 0x9DBB, 0x9DB8, + 0x9DBA, 0x9DC6, 0x9DCF, 0x9DC2, 0x9DD9, 0x9DD3, + 0x9DF8, 0x9DE6, 0x9DED, 0x9DEF, 0x9DFD, 0x9E1A, + 0x9E1B, 0x9E1E, 0x9E75, 0x9E79, 0x9E7D, 0x9E81, + 0x9E88, 0x9E8B, 0x9E8C, 0x9E92, 0x9E95, 0x9E91, + 0x9E9D, 0x9EA5, 0x9EA9, 0x9EB8, 0x9EAA, 0x9EAD, + 0x9761, 0x9ECC, 0x9ECE, 0x9ECF, 0x9ED0, 0x9ED4, + 0x9EDC, 0x9EDE, 0x9EDD, 0x9EE0, 0x9EE5, 0x9EE8, + 0x9EEF, 0x0000, 0x9EF4, 0x9EF6, 0x9EF7, 0x9EF9, + 0x9EFB, 0x9EFC, 0x9EFD, 0x9F07, 0x9F08, 0x76B7, + 0x9F15, 0x9F21, 0x9F2C, 0x9F3E, 0x9F4A, 0x9F52, + 0x9F54, 0x9F63, 0x9F5F, 0x9F60, 0x9F61, 0x9F66, + 0x9F67, 0x9F6C, 0x9F6A, 0x9F77, 0x9F72, 0x9F76, + 0x9F95, 0x9F9C, 0x9FA0, 0x582F, 0x69C7, 0x9059, + 0x7464, 0x51DC, 0x7199, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + +static u16* SjisUcsTable[256] = {0}; + +u32 OSSJIStoUTF32(u16 sjis) { + u16* table; + + table = SjisUcsTable[(sjis >> 8) & 0xFF]; + if (table != 0) { + return table[sjis & 0xFF]; + } + + return 0; +} diff --git a/src/dolphin/os/__os.h b/src/dolphin/os/__os.h new file mode 100644 index 0000000000..452dd20c80 --- /dev/null +++ b/src/dolphin/os/__os.h @@ -0,0 +1,130 @@ +#ifndef _DOLPHIN_OS_INTERNAL_H_ +#define _DOLPHIN_OS_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// OS +extern char* __OSExceptionNames[17]; // D ONLY + +u32 __OSIsDebuggerPresent(void); +void __OSPSInit(void); + +// OSAlloc +extern volatile int __OSCurrHeap; + +// OSAudioSystem +void __OSInitAudioSystem(void); +void __OSStopAudioSystem(void); + +// OSCache +void __OSCacheInit(void); + +// OSContext +void __OSContextInit(void); + +// OSError +void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar); + +// OSExec +void __OSGetExecParams(OSExecParams* params); +void __OSSetExecParams(const OSExecParams* params, OSExecParams* addr); +void __OSBootDolSimple(u32 doloffset, u32 restartCode, void* regionStart, void* regionEnd, BOOL argsUseDefault, s32 argc, char** argv); +void __OSBootDol(u32 doloffset, u32 restartCode, const char** argv); + +// OSInterrupt +extern void __RAS_OSDisableInterrupts_begin(void); +extern void __RAS_OSDisableInterrupts_end(void); + +extern u64 __OSSpuriousInterrupts; // D ONLY +extern char* __OSInterruptNames[33]; // D ONLY +extern char* __OSPIErrors[8]; // D ONLY + +__OSInterruptHandler __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler); +__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt); +void __OSInterruptInit(void); +OSInterruptMask __OSMaskInterrupts(OSInterruptMask global); +OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask global); +void __OSDispatchInterrupt(__OSException exception, OSContext* context); +void __OSModuleInit(void); + +// OSMemory +void __OSInitMemoryProtection(void); + +// OSMutex +void __OSUnlockAllMutex(OSThread* thread); +int __OSCheckDeadLock(OSThread* thread); +int __OSCheckMutexes(OSThread* thread); + +// OSReset +void __OSDoHotReset(u32 resetCode); +void __OSShutdownDevices(BOOL doRecal); +int __OSCallResetFunctions(BOOL final); + +// OSResetSW +void __OSResetSWInterruptHandler(s16 exception, OSContext* context); +void __OSSetResetButtonTimer(u8 min); + +// OSRtc +int __OSGetRTC(u32* rtc); +int __OSSetRTC(u32 rtc); +void __OSInitSram(void); +OSSram* __OSLockSram(void); +OSSramEx* __OSLockSramEx(void); +int __OSUnlockSram(BOOL commit); +int __OSUnlockSramEx(BOOL commit); +int __OSSyncSram(void); +int __OSCheckSram(void); +int __OSReadROM(void* buffer, s32 length, s32 offset); +int __OSReadROMAsync(void* buffer, s32 length, s32 offset, void (*callback)()); +u8 __OSGetBootMode(void); +void __OSSetBootMode(u8 ntd); + +// OSSync +extern void __OSSystemCallVectorStart(); +extern void __OSSystemCallVectorEnd(); + +void __OSInitSystemCall(void); + +// OSThread +void __OSThreadInit(void); +s32 __OSGetEffectivePriority(OSThread* thread); +void __OSPromoteThread(OSThread* thread, s32 priority); +void __OSReschedule(void); + +// OSTime +void __OSSetTime(OSTime time); +OSTime __OSGetSystemTime(); +void __OSSetTick(register OSTick newTicks); +OSTime __OSTimeToSystemTime(OSTime time); + +// ppc_eabi_init +__declspec(section ".init") asm void __init_hardware(void); +__declspec(section ".init") asm void __flush_cache(void* address, unsigned int size); +void __init_user(void); +void _ExitProcess(void); + +// start +__declspec(weak) void InitMetroTRK_BBA(); + +__declspec(section ".init") void __start(void); + +__declspec(section ".init") extern void __start(void); +__declspec(section ".init") void __copy_rom_section(void* dst, const void* src, u32 size); +__declspec(section ".init") void __init_bss_section(void* dst, u32 size); +__declspec(section ".init") extern void __init_registers(void); +__declspec(section ".init") extern void __init_data(void); + +// time.dolphin +OSTime __get_clock(void); +u32 __get_time(void); +int __to_gm_time(void); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_OS_INTERNAL_H_ diff --git a/src/dolphin/os/__ppc_eabi_init.c b/src/dolphin/os/__ppc_eabi_init.c new file mode 100644 index 0000000000..1a90be2a73 --- /dev/null +++ b/src/dolphin/os/__ppc_eabi_init.c @@ -0,0 +1,85 @@ +#include +#include +#include + +#include "__os.h" + +__declspec(section ".ctors") extern void (* _ctors[])(); +__declspec(section ".dtors") extern void (* _dtors[])(); + +static void __init_cpp(void); +static void __fini_cpp(void); + +__declspec(section ".init") asm void __init_hardware(void) +{ // clang-format off + nofralloc + mfmsr r0 + ori r0,r0,MSR_FP + mtmsr r0 + mflr r31 + bl __OSPSInit + bl __OSFPRInit + bl __OSCacheInit + mtlr r31 + blr +} + +__declspec(section ".init") asm void __flush_cache(void *address, unsigned int size) +{ // clang-format off + nofralloc + lis r5, 0xffff + ori r5, r5, 0xfff1 + and r5, r5, r3 + subf r3, r5, r3 + add r4, r4, r3 +rept: + dcbst 0,r5 + sync + icbi 0,r5 + addic r5,r5,0x8 + subic. r4,r4,0x8 + bge rept + isync + blr +} + +void __init_user(void) { + __init_cpp(); +} + +static void __init_cpp(void) { + void (* * constructor)(); + + /* + * call static initializers + */ + for (constructor = _ctors; *constructor; constructor++) { + (*constructor)(); + } +} + +static void __fini_cpp(void) { + void (* * destructor)(); + + /* + * call destructors + */ + for (destructor = _dtors; *destructor; destructor++) { + (*destructor)(); + } +} + +__declspec(weak) +void abort(void) { + _ExitProcess(); +} + +__declspec(weak) +void exit(int status) { + __fini_cpp(); + _ExitProcess(); +} + +void _ExitProcess(void) { + PPCHalt(); +} diff --git a/src/dolphin/os/__ppc_eabi_init.cpp b/src/dolphin/os/__ppc_eabi_init.cpp index 154753a984..a9008920b7 100644 --- a/src/dolphin/os/__ppc_eabi_init.cpp +++ b/src/dolphin/os/__ppc_eabi_init.cpp @@ -49,4 +49,4 @@ void _ExitProcess(void) { #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/src/dolphin/os/__start.c b/src/dolphin/os/__start.c index 8f80895955..479c3a4840 100644 --- a/src/dolphin/os/__start.c +++ b/src/dolphin/os/__start.c @@ -272,4 +272,4 @@ lbl_80003438: isync blr // clang-format on -} \ No newline at end of file +} diff --git a/src/dolphin/os/time.dolphin.c b/src/dolphin/os/time.dolphin.c new file mode 100644 index 0000000000..5e9d20af8e --- /dev/null +++ b/src/dolphin/os/time.dolphin.c @@ -0,0 +1,16 @@ +#include +#include + +#include "__os.h" + +OSTime __get_clock(void) { + return __OSGetSystemTime(); +} + +u32 __get_time(void) { + return OSTicksToSeconds(OSGetTime()) - 0x43E83E00; +} + +int __to_gm_time(void) { + return 0; +} diff --git a/src/dolphin/pad/Pad.c b/src/dolphin/pad/Pad.c index 7ceb78bd0b..27c554518e 100644 --- a/src/dolphin/pad/Pad.c +++ b/src/dolphin/pad/Pad.c @@ -1,162 +1,109 @@ -#include "dolphin/pad.h" -#include "dolphin/os.h" -#include "dolphin/si/SIBios.h" +#include +#include +#include -u8 UnkVal : (OS_BASE_CACHED | 0x30e3); -u16 __OSWirelessPadFixMode : (OS_BASE_CACHED | 0x30E0); +#include "__si.h" -/* 80450A20-80450A24 -00001 0004+00 1/1 0/0 0/0 .sdata __PADVersion */ -static char* __PADVersion = "<< Dolphin SDK - PAD\trelease build: Apr 5 2004 04:14:49 (0x2301) >>"; +#if DEBUG +const char* __PADVersion = "<< Dolphin SDK - PAD\tdebug build: Apr 5 2004 03:56:05 (0x2301) >>"; +#else +const char* __PADVersion = "<< Dolphin SDK - PAD\trelease build: Apr 5 2004 04:14:49 (0x2301) >>"; +#endif -static void UpdateOrigin(s32 chan); -static void SPEC0_MakeStatus(s32 chan, PADStatus* status, u32 data[2]); -static void SPEC1_MakeStatus(s32 chan, PADStatus* status, u32 data[2]); -static void SPEC2_MakeStatus(s32 chan, PADStatus* status, u32 data[2]); -static BOOL OnReset(BOOL final); -static void SamplingHandler(__OSInterrupt interrupt, OSContext* context); -static PADSamplingCallback PADSetSamplingCallback(PADSamplingCallback callback); -BOOL __PADDisableRecalibration(BOOL disable); -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); -static void PADTypeAndStatusCallback(s32 chan, u32 type); -static void PADReceiveCheckCallback(s32 chan, u32 type); +#define PAD_ALL \ + ( \ + PAD_BUTTON_LEFT | \ + PAD_BUTTON_RIGHT | \ + PAD_BUTTON_DOWN | \ + PAD_BUTTON_UP | \ + PAD_TRIGGER_Z | \ + PAD_TRIGGER_R | \ + PAD_TRIGGER_L | \ + PAD_BUTTON_A | \ + PAD_BUTTON_B | \ + PAD_BUTTON_X | \ + PAD_BUTTON_Y | \ + PAD_BUTTON_MENU | \ + 0x2000 | \ + 0x0080 \ + ) -extern u32 __PADFixBits; +static s32 ResettingChan = 0x20; +static u32 XPatchBits = PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT; +static u32 AnalogMode = 0x300; +static u32 Spec = PAD_SPEC_5; + +static BOOL Initialized; +static u32 EnabledBits; +static u32 ResettingBits; +static u32 RecalibrateBits; +static u32 WaitingBits; +static u32 CheckingBits; +static u32 PendingBits; +static u32 BarrelBits; -/* 8044CB70-8044CB80 079890 0010+00 3/3 0/0 0/0 .bss Type */ static u32 Type[4]; - -/* 8044CB80-8044CBB0 0798A0 0030+00 8/8 0/0 0/0 .bss Origin */ static PADStatus Origin[4]; -/* 80450A24-80450A28 0004A4 0004+00 7/7 0/0 0/0 .sdata ResettingChan */ -static s32 ResettingChan = 0x00000020; +u32 __PADSpec; -/* 80450A28-80450A2C 0004A8 0004+00 1/1 0/0 0/0 .sdata XPatchBits */ -static u32 XPatchBits = PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT; +// prototypes +static void PADTypeAndStatusCallback(s32 chan, u32 type); +static u16 GetWirelessID(s32 chan); +static void SetWirelessID(s32 chan, u16 id); +static void DoReset(); +static void PADEnable(s32 chan); +static void ProbeWireless(s32 chan); +static void PADProbeCallback(s32 chan, u32 error, OSContext *context); +static void PADDisable(s32 chan); +static void UpdateOrigin(s32 chan); +static void PADOriginCallback(s32 chan, u32 error, OSContext *context); +static void PADFixCallback(s32 unused, u32 error, struct OSContext *context); +static void PADResetCallback(s32 unused, u32 error, struct OSContext *context); +static void PADReceiveCheckCallback(s32 chan, u32 error); +static void SPEC0_MakeStatus(s32 chan, PADStatus *status, u32 data[2]); +static void SPEC1_MakeStatus(s32 chan, PADStatus *status, u32 data[2]); +static s8 ClampS8(s8 var, s8 org); +static u8 ClampU8(u8 var, u8 org); +static void SPEC2_MakeStatus(s32 chan, PADStatus *status, u32 data[2]); +static BOOL OnReset(BOOL f); +void __PADDisableXPatch(void); +BOOL __PADDisableRumble(BOOL disable); -/* 80450A2C-80450A30 0004AC 0004+00 7/7 0/0 0/0 .sdata AnalogMode */ -static u32 AnalogMode = 0x00000300; +typedef void (*SPECCallback)(s32, PADStatus*, u32*); +static SPECCallback MakeStatus = SPEC2_MakeStatus; -/* 8034E2B4-8034E458 348BF4 01A4+00 2/2 0/0 0/0 .text UpdateOrigin */ -static void UpdateOrigin(s32 chan) { - PADStatus* origin; - u32 chanBit = (u32)PAD_CHAN0_BIT >> chan; +static u32 CmdTypeAndStatus; +static u32 CmdReadOrigin = 0x41000000; +static u32 CmdCalibrate = 0x42000000; +static u32 CmdProbeDevice[4]; - origin = &Origin[chan]; - switch (AnalogMode & 0x00000700u) { - case 0x00000000u: - case 0x00000500u: - case 0x00000600u: - case 0x00000700u: - origin->trigger_left &= ~15; - origin->trigger_right &= ~15; - origin->analog_a &= ~15; - origin->analog_b &= ~15; - break; - case 0x00000100u: - origin->substick_x &= ~15; - origin->substick_y &= ~15; - origin->analog_a &= ~15; - origin->analog_b &= ~15; - break; - case 0x00000200u: - origin->substick_x &= ~15; - origin->substick_y &= ~15; - origin->trigger_left &= ~15; - origin->trigger_right &= ~15; - break; - case 0x00000300u: - break; - case 0x00000400u: - break; - } +static OSResetFunctionInfo ResetFunctionInfo = { + OnReset, + 127, + NULL, + NULL, +}; - origin->stick_x -= 128; - origin->stick_y -= 128; - origin->substick_x -= 128; - origin->substick_y -= 128; - - if (XPatchBits & chanBit) { - if (64 < origin->stick_x && (SIGetType(chan) & 0xFFFF0000) == SI_GC_CONTROLLER) { - origin->stick_x = 0; - } - } -} - -/* ############################################################################################## */ -/* 80451848-8045184C 000D48 0004+00 1/1 0/0 0/0 .sbss Initialized */ -static BOOL Initialized; - -/* 8045184C-80451850 000D4C 0004+00 10/10 0/0 0/0 .sbss EnabledBits */ -static u32 EnabledBits; - -/* 80451850-80451854 000D50 0004+00 7/7 0/0 0/0 .sbss ResettingBits */ -static u32 ResettingBits; - -inline void PADEnable(s32 chan) { +static void PADEnable(s32 chan) { u32 cmd; u32 chanBit; u32 data[2]; - chanBit = (u32)PAD_CHAN0_BIT >> chan; + chanBit = PAD_CHAN0_BIT >> chan; EnabledBits |= chanBit; - SIGetResponse(chan, data); - cmd = (0x40 << 16) | AnalogMode; + SIGetResponse(chan, &data); + cmd = (AnalogMode | 0x400000); SISetCommand(chan, cmd); SIEnablePolling(EnabledBits); } -inline void DoReset(void) { - u32 chanBit; - - ResettingChan = __cntlzw(ResettingBits); - if (ResettingChan == 32) { - return; - } - - chanBit = (u32)PAD_CHAN0_BIT >> ResettingChan; - ResettingBits &= ~chanBit; - - memset(&Origin[ResettingChan], 0, sizeof(PADStatus)); - SIGetTypeAsync(ResettingChan, PADTypeAndStatusCallback); -} - -/* 8034E458-8034E51C 348D98 00C4+00 1/1 0/0 0/0 .text PADOriginCallback */ -static void PADOriginCallback(s32 chan, u32 error, OSContext* context) { - if (!(error & - (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) - { - UpdateOrigin(ResettingChan); - PADEnable(ResettingChan); - } - DoReset(); -} - -/* ############################################################################################## */ -/* 80451854-80451858 000D54 0004+00 4/4 0/0 0/0 .sbss RecalibrateBits */ -static u32 RecalibrateBits; - -/* 80451858-8045185C 000D58 0004+00 7/7 0/0 0/0 .sbss WaitingBits */ -static u32 WaitingBits; - -/* 8045185C-80451860 000D5C 0004+00 6/6 0/0 0/0 .sbss CheckingBits */ -static u32 CheckingBits; - -/* 80451860-80451864 000D60 0004+00 6/6 0/0 0/0 .sbss PendingBits */ -static u32 PendingBits; - -/* 80451864-80451868 000D64 0004+00 6/6 0/0 0/0 .sbss BarrelBits */ -static u32 BarrelBits; - -inline void PADDisable(s32 chan) { +static void PADDisable(s32 chan) { BOOL enabled; u32 chanBit; enabled = OSDisableInterrupts(); - - chanBit = (u32)PAD_CHAN0_BIT >> chan; + chanBit = PAD_CHAN0_BIT >> chan; SIDisablePolling(chanBit); EnabledBits &= ~chanBit; WaitingBits &= ~chanBit; @@ -164,77 +111,128 @@ inline void PADDisable(s32 chan) { PendingBits &= ~chanBit; BarrelBits &= ~chanBit; OSSetWirelessID(chan, 0); - OSRestoreInterrupts(enabled); } -/* 8034E51C-8034E5E8 348E5C 00CC+00 2/2 0/0 0/0 .text PADOriginUpdateCallback */ -static void PADOriginUpdateCallback(s32 chan, u32 error, OSContext* context) { - if (!(EnabledBits & ((u32)PAD_CHAN0_BIT >> chan))) { - return; +static void DoReset() { + u32 chanBit; + + ResettingChan = __cntlzw(ResettingBits); + if (ResettingChan != 32) { + ASSERTLINE(559, 0 <= ResettingChan && ResettingChan < SI_MAX_CHAN); + chanBit = (PAD_CHAN0_BIT >> ResettingChan); + ResettingBits &= ~chanBit; + + memset(&Origin[ResettingChan], 0, sizeof(PADStatus)); + SIGetTypeAsync(ResettingChan, PADTypeAndStatusCallback); + } +} + +static void UpdateOrigin(s32 chan) { + PADStatus* origin; + u32 chanBit = PAD_CHAN0_BIT >> chan; + + origin = &Origin[chan]; + switch (AnalogMode & 0x00000700u) { + case 0x00000000u: + case 0x00000500u: + case 0x00000600u: + case 0x00000700u: + origin->triggerLeft &= ~15; + origin->triggerRight &= ~15; + origin->analogA &= ~15; + origin->analogB &= ~15; + break; + case 0x00000100u: + origin->substickX &= ~15; + origin->substickY &= ~15; + origin->analogA &= ~15; + origin->analogB &= ~15; + break; + case 0x00000200u: + origin->substickX &= ~15; + origin->substickY &= ~15; + origin->triggerLeft &= ~15; + origin->triggerRight &= ~15; + break; + case 0x00000300u: break; + case 0x00000400u: break; } - if (!(error & - (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) + origin->stickX -= 128; + origin->stickY -= 128; + origin->substickX -= 128; + origin->substickY -= 128; + + if (XPatchBits & chanBit) { + if (64 < origin->stickX && (SIGetType(chan) & 0xFFFF0000) == SI_GC_CONTROLLER) { + origin->stickX = 0; + } + } +} + +static void PADOriginCallback(s32 chan, u32 error, OSContext* context) { + ASSERTLINE(641, 0 <= ResettingChan && ResettingChan < SI_MAX_CHAN); + ASSERTLINE(642, chan == ResettingChan); + + if (!(error & (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) { - UpdateOrigin(chan); + UpdateOrigin(ResettingChan); + PADEnable(ResettingChan); } + DoReset(); +} + +static void PADOriginUpdateCallback(s32 chan, u32 error, OSContext* context) { + ASSERTLINE(671, 0 <= chan && chan < SI_MAX_CHAN); + if (!(EnabledBits & (PAD_CHAN0_BIT >> chan))) + return; + if (!(error & (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) + UpdateOrigin(chan); if (error & SI_ERROR_NO_RESPONSE) { PADDisable(chan); } } -/* 8034E5E8-8034E6C0 348F28 00D8+00 1/1 0/0 0/0 .text PADProbeCallback */ static void PADProbeCallback(s32 chan, u32 error, OSContext* context) { - if (!(error & - (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) + u32 type; + ASSERTLINE(710, 0 <= ResettingChan && ResettingChan < SI_MAX_CHAN); + ASSERTLINE(711, chan == ResettingChan); + ASSERTLINE(713, (Type[chan] & SI_WIRELESS_CONT_MASK) == SI_WIRELESS_CONT && !(Type[chan] & SI_WIRELESS_LITE)); + + if (!(error & (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) { PADEnable(ResettingChan); - WaitingBits |= (u32)PAD_CHAN0_BIT >> ResettingChan; + WaitingBits |= PAD_CHAN0_BIT >> ResettingChan; } + DoReset(); } -/* ############################################################################################## */ -/* 80450A30-80450A34 0004B0 0004+00 4/4 0/0 0/0 .sdata Spec */ -static u32 Spec = 5; - -/* 80450A34-80450A38 -00001 0004+00 2/2 0/0 0/0 .sdata MakeStatus */ -static void (*MakeStatus)(s32, PADStatus*, u32[2]) = SPEC2_MakeStatus; - -/* 80450A38-80450A3C 0004B8 0004+00 3/3 0/0 0/0 .sdata CmdReadOrigin */ -static f32 CmdReadOrigin = 8.0f; - -/* 80450A3C-80450A40 0004BC 0004+00 1/1 0/0 0/0 .sdata CmdCalibrate */ -static f32 CmdCalibrate = 32.0f; - -/* 8044CBB0-8044CBC0 0798D0 0010+00 0/1 0/0 0/0 .bss CmdProbeDevice */ -#pragma push -#pragma force_active on -static u32 CmdProbeDevice[4]; -#pragma pop - -/* 8034E6C0-8034E9EC 349000 032C+00 4/4 0/0 0/0 .text PADTypeAndStatusCallback */ static void PADTypeAndStatusCallback(s32 chan, u32 type) { u32 chanBit; u32 recalibrate; BOOL rc = TRUE; u32 error; - chanBit = (u32)PAD_CHAN0_BIT >> ResettingChan; + + ASSERTLINE(746, 0 <= ResettingChan && ResettingChan < SI_MAX_CHAN); + ASSERTLINE(747, chan == ResettingChan); + + chanBit = PAD_CHAN0_BIT >> ResettingChan; error = type & 0xFF; + ASSERTLINE(756, !(error & SI_ERROR_BUSY)); + recalibrate = RecalibrateBits & chanBit; RecalibrateBits &= ~chanBit; - if (error & - (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION)) + if (error & (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION)) { DoReset(); return; } type &= ~0xFF; - Type[ResettingChan] = type; if ((type & SI_TYPE_MASK) != SI_TYPE_GC || !(type & SI_GC_STANDARD)) { @@ -267,6 +265,7 @@ static void PADTypeAndStatusCallback(s32 chan, u32 type) { &Origin[ResettingChan], 8, PADProbeCallback, 0); } } + if (!rc) { PendingBits |= chanBit; DoReset(); @@ -274,67 +273,66 @@ static void PADTypeAndStatusCallback(s32 chan, u32 type) { } } -/* 8034E9EC-8034EB2C 34932C 0140+00 1/1 0/0 0/0 .text PADReceiveCheckCallback */ static void PADReceiveCheckCallback(s32 chan, u32 type) { u32 error; u32 chanBit; - chanBit = (u32)PAD_CHAN0_BIT >> chan; - if (!(EnabledBits & chanBit)) { - return; - } + chanBit = PAD_CHAN0_BIT >> chan; - error = type & 0xFF; - type &= ~0xFF; + if (EnabledBits & chanBit) { + error = type & 0xFF; + type &= ~0xFF; - WaitingBits &= ~chanBit; - CheckingBits &= ~chanBit; + WaitingBits &= ~chanBit; + CheckingBits &= ~chanBit; - if (!(error & - (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION)) && - (type & SI_GC_WIRELESS) && (type & SI_WIRELESS_FIX_ID) && (type & SI_WIRELESS_RECEIVED) && - !(type & SI_WIRELESS_IR) && (type & SI_WIRELESS_CONT_MASK) == SI_WIRELESS_CONT && - !(type & SI_WIRELESS_LITE)) - { - SITransfer(chan, &CmdReadOrigin, 1, &Origin[chan], 10, PADOriginUpdateCallback, 0); - } else { - PADDisable(chan); + if (!(error & + (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION)) && + (type & SI_GC_WIRELESS) && (type & SI_WIRELESS_FIX_ID) && (type & SI_WIRELESS_RECEIVED) && + !(type & SI_WIRELESS_IR) && (type & SI_WIRELESS_CONT_MASK) == SI_WIRELESS_CONT && + !(type & SI_WIRELESS_LITE)) + { + SITransfer(chan, &CmdReadOrigin, 1, &Origin[chan], 10, PADOriginUpdateCallback, 0); + } else { + PADDisable(chan); + } } } -/* 8034EB2C-8034EC3C 34946C 0110+00 2/2 1/1 0/0 .text PADReset */ -BOOL PADReset(u32 mask) { +int PADReset(u32 mask) { BOOL enabled; - u32 diableBits; + u32 disableBits; + + ASSERTMSGLINE(0x381, !(mask & 0x0FFFFFFF), "PADReset(): invalid mask"); enabled = OSDisableInterrupts(); - mask |= PendingBits; PendingBits = 0; mask &= ~(WaitingBits | CheckingBits); ResettingBits |= mask; - diableBits = ResettingBits & EnabledBits; + disableBits = ResettingBits & EnabledBits; EnabledBits &= ~mask; BarrelBits &= ~mask; - if (Spec == PAD_SPEC_4) { + if (Spec == 4) { RecalibrateBits |= mask; } - SIDisablePolling(diableBits); + SIDisablePolling(disableBits); - if (ResettingChan == 32) { + if (ResettingChan == 0x20) { DoReset(); } + OSRestoreInterrupts(enabled); - return TRUE; + return 1; } -/* 8034EC3C-8034ED50 34957C 0114+00 1/1 1/1 0/0 .text PADRecalibrate */ BOOL PADRecalibrate(u32 mask) { BOOL enabled; u32 disableBits; + ASSERTMSGLINE(939, !(mask & 0x0FFFFFFF), "PADReset(): invalid mask"); enabled = OSDisableInterrupts(); mask |= PendingBits; @@ -345,60 +343,42 @@ BOOL PADRecalibrate(u32 mask) { EnabledBits &= ~mask; BarrelBits &= ~mask; - if (!(UnkVal & 0x40)) { + if (!(__gUnknown800030E3 & 0x40)) { RecalibrateBits |= mask; } SIDisablePolling(disableBits); - if (ResettingChan == 32) { + if (ResettingChan == 32) DoReset(); - } + OSRestoreInterrupts(enabled); - return TRUE; + return 1; } -/* ############################################################################################## */ -/* 803D1B90-803D1BA0 -00001 0010+00 1/1 0/0 0/0 .data ResetFunctionInfo */ -static OSResetFunctionInfo ResetFunctionInfo = { - OnReset, - 0x0000007F, -}; - -/* 80451868-8045186C 000D68 0004+00 3/3 0/0 0/0 .sbss SamplingCallback */ -static void (*SamplingCallback)(void); - -/* 8045186C-80451870 000D6C 0004+00 1/1 0/0 0/0 .sbss recalibrated$388 */ -static BOOL recalibrated; - -/* 80451870-80451878 000D70 0004+04 2/2 1/1 0/0 .sbss __PADSpec */ -u32 __PADSpec; - -/* 8034ED50-8034EEA0 349690 0150+00 0/0 1/1 0/0 .text PADInit */ BOOL PADInit() { s32 chan; if (Initialized) { - return TRUE; + return 1; } - + OSRegisterVersion(__PADVersion); - if (__PADSpec) { + if (__PADSpec) PADSetSpec(__PADSpec); - } Initialized = TRUE; if (__PADFixBits != 0) { OSTime time = OSGetTime(); - __OSWirelessPadFixMode = (u16)((((time) & 0xffff) + ((time >> 16) & 0xffff) + - ((time >> 32) & 0xffff) + ((time >> 48) & 0xffff)) & - 0x3fffu); + __OSWirelessPadFixMode + = (u16)((((time)&0xffff) + ((time >> 16) & 0xffff) + ((time >> 32) & 0xffff) + ((time >> 48) & 0xffff)) + & 0x3fffu); + RecalibrateBits = PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT; } for (chan = 0; chan < SI_MAX_CHAN; ++chan) { - CmdProbeDevice[chan] = - (0x4D << 24) | (chan << 22) | ((__OSWirelessPadFixMode & 0x3fffu) << 8); + CmdProbeDevice[chan] = (0x4D << 24) | (chan << 22) | ((__OSWirelessPadFixMode & 0x3fffu) << 8); } SIRefreshSamplingRate(); @@ -407,7 +387,6 @@ BOOL PADInit() { return PADReset(PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT); } -/* 8034EEA0-8034F1A0 3497E0 0300+00 0/0 1/1 0/0 .text PADRead */ u32 PADRead(PADStatus* status) { BOOL enabled; s32 chan; @@ -418,124 +397,150 @@ u32 PADRead(PADStatus* status) { u32 motor; enabled = OSDisableInterrupts(); - motor = 0; - for (chan = 0; chan < SI_MAX_CHAN; chan++, status++) { - chanBit = (u32)PAD_CHAN0_BIT >> chan; + + for (chan = 0; chan < 4; chan++, status++) { + chanBit = PAD_CHAN0_BIT >> chan; chanShift = 8 * (SI_MAX_CHAN - 1 - chan); if (PendingBits & chanBit) { PADReset(0); - status->error = PAD_ERR_NOT_READY; - memset(status, 0, offsetof(PADStatus, error)); - continue; - } + status->err = PAD_ERR_NOT_READY; + memset(status, 0, offsetof(PADStatus, err)); + } else if ((ResettingBits & chanBit) || ResettingChan == chan) { + status->err = PAD_ERR_NOT_READY; + memset(status, 0, offsetof(PADStatus, err)); + } else if (!(EnabledBits & chanBit)) { + status->err = PAD_ERR_NO_CONTROLLER; + memset(status, 0, offsetof(PADStatus, err)); + } else if (SIIsChanBusy(chan)) { + status->err = PAD_ERR_TRANSFER; + memset(status, 0, offsetof(PADStatus, err)); + } else { + sr = SIGetStatus(chan); + if (sr & SI_ERROR_NO_RESPONSE) { + SIGetResponse(chan, data); - if ((ResettingBits & chanBit) || ResettingChan == chan) { - status->error = PAD_ERR_NOT_READY; - memset(status, 0, offsetof(PADStatus, error)); - continue; - } + if (WaitingBits & chanBit) { + status->err = PAD_ERR_NONE; + memset(status, 0, offsetof(PADStatus, err)); - if (!(EnabledBits & chanBit)) { - status->error = (s8)PAD_ERR_NO_CONTROLLER; - memset(status, 0, offsetof(PADStatus, error)); - continue; - } - - if (SIIsChanBusy(chan)) { - status->error = PAD_ERR_TRANSFER; - memset(status, 0, offsetof(PADStatus, error)); - continue; - } - - sr = SIGetStatus(chan); - if (sr & SI_ERROR_NO_RESPONSE) { - SIGetResponse(chan, data); - - if (WaitingBits & chanBit) { - status->error = (s8)PAD_ERR_NONE; - memset(status, 0, offsetof(PADStatus, error)); - - if (!(CheckingBits & chanBit)) { - CheckingBits |= chanBit; - SIGetTypeAsync(chan, PADReceiveCheckCallback); + if (!(CheckingBits & chanBit)) { + CheckingBits |= chanBit; + SIGetTypeAsync(chan, PADReceiveCheckCallback); + } + } else { + PADDisable(chan); + status->err = PAD_ERR_NO_CONTROLLER; + memset(status, 0, offsetof(PADStatus, err)); + } + } else { + if (!(SIGetType(chan) & SI_GC_NOMOTOR)) { + motor |= chanBit; + } + + if (!SIGetResponse(chan, &data)) { + status->err = PAD_ERR_TRANSFER; + memset(status, 0, offsetof(PADStatus, err)); + } else if (data[0] & 0x80000000) { + status->err = PAD_ERR_TRANSFER; + memset(status, 0, offsetof(PADStatus, err)); + } else { + MakeStatus(chan, status, data); + + // Check and clear PAD_ORIGIN bit + if (status->button & 0x2000) { + status->err = PAD_ERR_TRANSFER; + memset(status, 0, offsetof(PADStatus, err)); + + // Get origin. It is okay if the following transfer fails + // since the PAD_ORIGIN bit remains until the read origin + // command complete. + SITransfer(chan, &CmdReadOrigin, 1, &Origin[chan], 10, PADOriginUpdateCallback, 0); + } else { + status->err = PAD_ERR_NONE; + + // Clear PAD_INTERFERE bit + status->button &= ~0x0080; + } } - continue; } - - PADDisable(chan); - - status->error = (s8)PAD_ERR_NO_CONTROLLER; - memset(status, 0, offsetof(PADStatus, error)); - continue; } - - if (!(SIGetType(chan) & SI_GC_NOMOTOR)) { - motor |= chanBit; - } - - if (!SIGetResponse(chan, data)) { - status->error = PAD_ERR_TRANSFER; - memset(status, 0, offsetof(PADStatus, error)); - continue; - } - - if (data[0] & 0x80000000) { - status->error = PAD_ERR_TRANSFER; - memset(status, 0, offsetof(PADStatus, error)); - continue; - } - - MakeStatus(chan, status, data); - - // Check and clear PAD_ORIGIN bit - if (status->button & 0x2000) { - status->error = PAD_ERR_TRANSFER; - memset(status, 0, offsetof(PADStatus, error)); - - // Get origin. It is okay if the following transfer fails - // since the PAD_ORIGIN bit remains until the read origin - // command complete. - SITransfer(chan, &CmdReadOrigin, 1, &Origin[chan], 10, PADOriginUpdateCallback, 0); - continue; - } - - status->error = PAD_ERR_NONE; - - // Clear PAD_INTERFERE bit - status->button &= ~0x0080; } OSRestoreInterrupts(enabled); return motor; } -/* 8034F1A0-8034F258 349AE0 00B8+00 0/0 2/2 0/0 .text PADControlMotor */ +typedef struct XY { + u8 line; + u8 count; +} XY; + +void PADSetSamplingRate(u32 msec) { + SISetSamplingRate(msec); +} + +#if DEBUG +void __PADTestSamplingRate(u32 tvmode) { + __SITestSamplingRate(tvmode); +} +#endif + +void PADControlAllMotors(const u32* commandArray) { + BOOL enabled; + int chan; + u32 command; + BOOL commit; + u32 chanBit; + + enabled = OSDisableInterrupts(); + commit = FALSE; + + for (chan = 0; chan < SI_MAX_CHAN; chan++, commandArray++) { + chanBit = PAD_CHAN0_BIT >> chan; + if ((EnabledBits & chanBit) && !(SIGetType(chan) & 0x20000000)) { + command = *commandArray; + ASSERTMSGLINE(0x4B5, !(command & 0xFFFFFFFC), "PADControlAllMotors(): invalid command"); + if (Spec < PAD_SPEC_2 && command == PAD_MOTOR_STOP_HARD) + command = PAD_MOTOR_STOP; + if (__gUnknown800030E3 & 0x20) + command = PAD_MOTOR_STOP; + SISetCommand(chan, (0x40 << 16) | AnalogMode | (command & (0x00000001 | 0x00000002))); + commit = TRUE; + } + } + + if (commit) + SITransferCommands(); + + OSRestoreInterrupts(enabled); +} + void PADControlMotor(s32 chan, u32 command) { BOOL enabled; u32 chanBit; + ASSERTMSGLINE(1244, !(command & 0xFFFFFFFC), "PADControlMotor(): invalid command"); + enabled = OSDisableInterrupts(); - chanBit = (u32)PAD_CHAN0_BIT >> chan; + chanBit = PAD_CHAN0_BIT >> chan; if ((EnabledBits & chanBit) && !(SIGetType(chan) & SI_GC_NOMOTOR)) { - if (Spec < PAD_SPEC_2 && command == PAD_MOTOR_STOP_HARD) { + if (Spec < PAD_SPEC_2 && command == PAD_MOTOR_STOP_HARD) command = PAD_MOTOR_STOP; - } - - if (UnkVal & 0x20) { + if (__gUnknown800030E3 & 0x20) command = PAD_MOTOR_STOP; - } - SISetCommand(chan, (0x40 << 16) | AnalogMode | (command & (0x00000001 | 0x00000002))); SITransferCommands(); } + OSRestoreInterrupts(enabled); } -/* 8034F258-8034F2B8 349B98 0060+00 1/1 1/1 0/0 .text PADSetSpec */ void PADSetSpec(u32 spec) { + ASSERTLINE(1282, !Initialized); __PADSpec = 0; + switch (spec) { case PAD_SPEC_0: MakeStatus = SPEC0_MakeStatus; @@ -553,7 +558,10 @@ void PADSetSpec(u32 spec) { Spec = spec; } -/* 8034F2B8-8034F42C 349BF8 0174+00 1/1 0/0 0/0 .text SPEC0_MakeStatus */ +u32 PADGetSpec(void) { + return Spec; +} + static void SPEC0_MakeStatus(s32 chan, PADStatus* status, u32 data[2]) { status->button = 0; status->button |= ((data[0] >> 16) & 0x0008) ? PAD_BUTTON_A : 0; @@ -561,35 +569,24 @@ static void SPEC0_MakeStatus(s32 chan, PADStatus* status, u32 data[2]) { status->button |= ((data[0] >> 16) & 0x0100) ? PAD_BUTTON_X : 0; status->button |= ((data[0] >> 16) & 0x0001) ? PAD_BUTTON_Y : 0; status->button |= ((data[0] >> 16) & 0x0010) ? PAD_BUTTON_START : 0; - - status->stick_x = (s8)(data[1] >> 16); - status->stick_y = (s8)(data[1] >> 24); - - status->substick_x = (s8)(data[1]); - status->substick_y = (s8)(data[1] >> 8); - - status->trigger_left = (u8)(data[0] >> 8); - status->trigger_right = (u8)data[0]; - - status->analog_a = 0; - status->analog_b = 0; - - if (170 <= status->trigger_left) { + status->stickX = (s8)(data[1] >> 16); + status->stickY = (s8)(data[1] >> 24); + status->substickX = (s8)(data[1]); + status->substickY = (s8)(data[1] >> 8); + status->triggerLeft = (u8)(data[0] >> 8); + status->triggerRight = (u8)data[0]; + status->analogA = 0; + status->analogB = 0; + if (170 <= status->triggerLeft) status->button |= PAD_TRIGGER_L; - } - - if (170 <= status->trigger_right) { + if (170 <= status->triggerRight) status->button |= PAD_TRIGGER_R; - } - - status->stick_x -= 128; - status->stick_y -= 128; - - status->substick_x -= 128; - status->substick_y -= 128; + status->stickX -= 128; + status->stickY -= 128; + status->substickX -= 128; + status->substickY -= 128; } -/* 8034F42C-8034F5A0 349D6C 0174+00 1/1 0/0 0/0 .text SPEC1_MakeStatus */ static void SPEC1_MakeStatus(s32 chan, PADStatus* status, u32 data[2]) { status->button = 0; status->button |= ((data[0] >> 16) & 0x0080) ? PAD_BUTTON_A : 0; @@ -598,145 +595,146 @@ static void SPEC1_MakeStatus(s32 chan, PADStatus* status, u32 data[2]) { status->button |= ((data[0] >> 16) & 0x0010) ? PAD_BUTTON_Y : 0; status->button |= ((data[0] >> 16) & 0x0200) ? PAD_BUTTON_START : 0; - status->stick_x = (s8)(data[1] >> 16); - status->stick_y = (s8)(data[1] >> 24); - status->substick_x = (s8)(data[1]); - status->substick_y = (s8)(data[1] >> 8); + status->stickX = (s8)(data[1] >> 16); + status->stickY = (s8)(data[1] >> 24); + status->substickX = (s8)(data[1]); + status->substickY = (s8)(data[1] >> 8); - status->trigger_left = (u8)(data[0] >> 8); - status->trigger_right = (u8)data[0]; + status->triggerLeft = (u8)(data[0] >> 8); + status->triggerRight = (u8)data[0]; - status->analog_a = 0; - status->analog_b = 0; + status->analogA = 0; + status->analogB = 0; - if (170 <= status->trigger_left) { + if (170 <= status->triggerLeft) status->button |= PAD_TRIGGER_L; - } - - if (170 <= status->trigger_right) { + if (170 <= status->triggerRight) status->button |= PAD_TRIGGER_R; - } - status->stick_x -= 128; - status->stick_y -= 128; - status->substick_x -= 128; - status->substick_y -= 128; + status->stickX -= 128; + status->stickY -= 128; + status->substickX -= 128; + status->substickY -= 128; } -inline s8 ClampS8(s8 var, s8 org) { +static s8 ClampS8(s8 var, s8 org) { if (0 < org) { s8 min = (s8)(-128 + org); - if (var < min) { + if (var < min) var = min; - } } else if (org < 0) { s8 max = (s8)(127 + org); - if (max < var) { + if (max < var) var = max; - } } return var -= org; } -inline u8 ClampU8(u8 var, u8 org) { - if (var < org) { +static u8 ClampU8(u8 var, u8 org) { + if (var < org) var = org; - } return var -= org; } -#define PAD_ALL \ - (PAD_BUTTON_LEFT | PAD_BUTTON_RIGHT | PAD_BUTTON_DOWN | PAD_BUTTON_UP | PAD_TRIGGER_Z | \ - PAD_TRIGGER_R | PAD_TRIGGER_L | PAD_BUTTON_A | PAD_BUTTON_B | PAD_BUTTON_X | PAD_BUTTON_Y | \ - PAD_BUTTON_MENU | 0x2000 | 0x0080) - -/* 8034F5A0-8034FA10 349EE0 0470+00 2/1 0/0 0/0 .text SPEC2_MakeStatus */ static void SPEC2_MakeStatus(s32 chan, PADStatus* status, u32 data[2]) { PADStatus* origin; - u32 type; status->button = (u16)((data[0] >> 16) & PAD_ALL); - status->stick_x = (s8)(data[0] >> 8); - status->stick_y = (s8)(data[0]); + status->stickX = (s8)(data[0] >> 8); + status->stickY = (s8)(data[0]); switch (AnalogMode & 0x00000700) { case 0x00000000: case 0x00000500: case 0x00000600: case 0x00000700: - status->substick_x = (s8)(data[1] >> 24); - status->substick_y = (s8)(data[1] >> 16); - status->trigger_left = (u8)(((data[1] >> 12) & 0x0f) << 4); - status->trigger_right = (u8)(((data[1] >> 8) & 0x0f) << 4); - status->analog_a = (u8)(((data[1] >> 4) & 0x0f) << 4); - status->analog_b = (u8)(((data[1] >> 0) & 0x0f) << 4); + status->substickX = (s8)(data[1] >> 24); + status->substickY = (s8)(data[1] >> 16); + status->triggerLeft = (u8)(((data[1] >> 12) & 0x0f) << 4); + status->triggerRight = (u8)(((data[1] >> 8) & 0x0f) << 4); + status->analogA = (u8)(((data[1] >> 4) & 0x0f) << 4); + status->analogB = (u8)(((data[1] >> 0) & 0x0f) << 4); break; case 0x00000100: - status->substick_x = (s8)(((data[1] >> 28) & 0x0f) << 4); - status->substick_y = (s8)(((data[1] >> 24) & 0x0f) << 4); - status->trigger_left = (u8)(data[1] >> 16); - status->trigger_right = (u8)(data[1] >> 8); - status->analog_a = (u8)(((data[1] >> 4) & 0x0f) << 4); - status->analog_b = (u8)(((data[1] >> 0) & 0x0f) << 4); + status->substickX = (s8)(((data[1] >> 28) & 0x0f) << 4); + status->substickY = (s8)(((data[1] >> 24) & 0x0f) << 4); + status->triggerLeft = (u8)(data[1] >> 16); + status->triggerRight = (u8)(data[1] >> 8); + status->analogA = (u8)(((data[1] >> 4) & 0x0f) << 4); + status->analogB = (u8)(((data[1] >> 0) & 0x0f) << 4); break; case 0x00000200: - status->substick_x = (s8)(((data[1] >> 28) & 0x0f) << 4); - status->substick_y = (s8)(((data[1] >> 24) & 0x0f) << 4); - status->trigger_left = (u8)(((data[1] >> 20) & 0x0f) << 4); - status->trigger_right = (u8)(((data[1] >> 16) & 0x0f) << 4); - status->analog_a = (u8)(data[1] >> 8); - status->analog_b = (u8)(data[1] >> 0); + status->substickX = (s8)(((data[1] >> 28) & 0x0f) << 4); + status->substickY = (s8)(((data[1] >> 24) & 0x0f) << 4); + status->triggerLeft = (u8)(((data[1] >> 20) & 0x0f) << 4); + status->triggerRight = (u8)(((data[1] >> 16) & 0x0f) << 4); + status->analogA = (u8)(data[1] >> 8); + status->analogB = (u8)(data[1] >> 0); break; case 0x00000300: - status->substick_x = (s8)(data[1] >> 24); - status->substick_y = (s8)(data[1] >> 16); - status->trigger_left = (u8)(data[1] >> 8); - status->trigger_right = (u8)(data[1] >> 0); - status->analog_a = 0; - status->analog_b = 0; + status->substickX = (s8)(data[1] >> 24); + status->substickY = (s8)(data[1] >> 16); + status->triggerLeft = (u8)(data[1] >> 8); + status->triggerRight = (u8)(data[1] >> 0); + status->analogA = 0; + status->analogB = 0; break; case 0x00000400: - status->substick_x = (s8)(data[1] >> 24); - status->substick_y = (s8)(data[1] >> 16); - status->trigger_left = 0; - status->trigger_right = 0; - status->analog_a = (u8)(data[1] >> 8); - status->analog_b = (u8)(data[1] >> 0); + status->substickX = (s8)(data[1] >> 24); + status->substickY = (s8)(data[1] >> 16); + status->triggerLeft = 0; + status->triggerRight = 0; + status->analogA = (u8)(data[1] >> 8); + status->analogB = (u8)(data[1] >> 0); break; } - status->stick_x -= 128; - status->stick_y -= 128; - status->substick_x -= 128; - status->substick_y -= 128; + status->stickX -= 128; + status->stickY -= 128; + status->substickX -= 128; + status->substickY -= 128; - type = Type[chan]; - - if (((type & (0xffff0000)) == SI_GC_CONTROLLER) && ((status->button & 0x80) ^ 0x80)) { + if (((Type[chan] & (0xFFFF0000)) == SI_GC_CONTROLLER) && ((status->button & 0x80) ^ 0x80)) { BarrelBits |= (PAD_CHAN0_BIT >> chan); - status->stick_x = 0; - status->stick_y = 0; - status->substick_x = 0; - status->substick_y = 0; + status->stickX = 0; + status->stickY = 0; + status->substickX = 0; + status->substickY = 0; return; } else { BarrelBits &= ~(PAD_CHAN0_BIT >> chan); } origin = &Origin[chan]; - status->stick_x = ClampS8(status->stick_x, origin->stick_x); - status->stick_y = ClampS8(status->stick_y, origin->stick_y); - status->substick_x = ClampS8(status->substick_x, origin->substick_x); - status->substick_y = ClampS8(status->substick_y, origin->substick_y); - status->trigger_left = ClampU8(status->trigger_left, origin->trigger_left); - status->trigger_right = ClampU8(status->trigger_right, origin->trigger_right); + status->stickX = ClampS8(status->stickX, origin->stickX); + status->stickY = ClampS8(status->stickY, origin->stickY); + status->substickX = ClampS8(status->substickX, origin->substickX); + status->substickY = ClampS8(status->substickY, origin->substickY); + status->triggerLeft = ClampU8(status->triggerLeft, origin->triggerLeft); + status->triggerRight = ClampU8(status->triggerRight, origin->triggerRight); +} + +int PADGetType(s32 chan, u32* type) { + u32 chanBit; + + *type = SIGetType(chan); + chanBit = PAD_CHAN0_BIT >> chan; + if (ResettingBits & chanBit || ResettingChan == chan || !(EnabledBits & chanBit)) { + return 0; + } + return 1; +} + +BOOL PADSync(void) { + return ResettingBits == 0 && (s32)ResettingChan == 32 && !SIBusy(); } -/* 8034FA10-8034FA84 34A350 0074+00 0/0 2/2 0/0 .text PADSetAnalogMode */ void PADSetAnalogMode(u32 mode) { BOOL enabled; u32 mask; + ASSERTMSGLINE(1615, (mode < 8), "PADSetAnalogMode(): invalid mode"); + enabled = OSDisableInterrupts(); AnalogMode = mode << 8; mask = EnabledBits; @@ -749,35 +747,32 @@ void PADSetAnalogMode(u32 mode) { OSRestoreInterrupts(enabled); } -inline BOOL PADSync(void) { - return ResettingBits == 0 && ResettingChan == 32 && !SIBusy(); -} +static void (*SamplingCallback)(); -/* 8034FA84-8034FB40 34A3C4 00BC+00 1/0 0/0 0/0 .text OnReset */ -static BOOL OnReset(BOOL f) { - static BOOL recalibrated = FALSE; +static BOOL OnReset(BOOL final) { BOOL sync; + static BOOL recalibrated = FALSE; - if (SamplingCallback) { + if (SamplingCallback) PADSetSamplingCallback(NULL); - } - if (!f) { + if (!final) { sync = PADSync(); if (!recalibrated && sync) { - recalibrated = - PADRecalibrate(PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT); + recalibrated = PADRecalibrate(PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT); return FALSE; } return sync; - } else { + } else recalibrated = FALSE; - } return TRUE; } -/* 8034FB40-8034FBA0 34A480 0060+00 1/1 0/0 0/0 .text SamplingHandler */ +void __PADDisableXPatch(void) { + XPatchBits = 0; +} + static void SamplingHandler(__OSInterrupt interrupt, OSContext* context) { OSContext exceptionContext; @@ -790,7 +785,6 @@ static void SamplingHandler(__OSInterrupt interrupt, OSContext* context) { } } -/* 8034FBA0-8034FBF4 34A4E0 0054+00 1/1 0/0 0/0 .text PADSetSamplingCallback */ PADSamplingCallback PADSetSamplingCallback(PADSamplingCallback callback) { PADSamplingCallback prev; @@ -801,20 +795,47 @@ PADSamplingCallback PADSetSamplingCallback(PADSamplingCallback callback) { } else { SIUnregisterPollingHandler(SamplingHandler); } + return prev; } -/* 8034FBF4-8034FC70 34A534 007C+00 0/0 1/1 0/0 .text __PADDisableRecalibration */ BOOL __PADDisableRecalibration(BOOL disable) { BOOL enabled; BOOL prev; enabled = OSDisableInterrupts(); - prev = (UnkVal & 0x40) ? TRUE : FALSE; - UnkVal &= ~0x40; + prev = (__gUnknown800030E3 & 0x40) ? TRUE : FALSE; + __gUnknown800030E3 &= ~0x40; if (disable) { - UnkVal |= 0x40; + __gUnknown800030E3 |= 0x40; + } + + OSRestoreInterrupts(enabled); + return prev; +} + +BOOL __PADDisableRumble(BOOL disable) { + BOOL enabled; + BOOL prev; + + enabled = OSDisableInterrupts(); + prev = (__gUnknown800030E3 & 0x20) ? TRUE : FALSE; + __gUnknown800030E3 &= ~0x20; + if (disable) { + __gUnknown800030E3 |= 0x20; } OSRestoreInterrupts(enabled); return prev; -} \ No newline at end of file +} + +BOOL PADIsBarrel(s32 chan) { + if (chan < 0 || chan >= 4) { + return FALSE; + } + + if (BarrelBits & (PAD_CHAN0_BIT >> chan)) { + return TRUE; + } + + return FALSE; +} diff --git a/src/dolphin/pad/Padclamp.c b/src/dolphin/pad/Padclamp.c index 5d50eb5405..741a0e87b7 100644 --- a/src/dolphin/pad/Padclamp.c +++ b/src/dolphin/pad/Padclamp.c @@ -1,25 +1,32 @@ -#include "dolphin/pad/Padclamp.h" +#include "fake_tgmath.h" +#include +#include -// older version of MSL_C sqrtf. needed here instead of updated version -static inline f32 dolsqrtf(f32 x) { - static const f64 _half = .5; - static const f64 _three = 3.0; - vf32 y; - if (x > 0.0f) { - f64 guess = __frsqrte((f64)x); // returns an approximation to - guess = _half * guess * (_three - guess * guess * x); // now have 12 sig bits - guess = _half * guess * (_three - guess * guess * x); // now have 24 sig bits - guess = _half * guess * (_three - guess * guess * x); // now have 32 sig bits - y = (f32)(x * guess); - return y; - } - return x; -} +static const PADClampRegion ClampRegion = { + // Triggers + 30, + 180, + // Left stick + 15, + 72, + 40, + + // Right stick + 15, + 59, + 31, + + // Stick radii + 56, + 44, +}; + +// prototypes static void ClampStick(s8* px, s8* py, s8 max, s8 xy, s8 min); static void ClampCircle(s8* px, s8* py, s8 radius, s8 min); +static void ClampTrigger(u8* trigger, u8 min, u8 max); -/* 8034DDBC-8034DEEC 3486FC 0130+00 1/1 0/0 0/0 .text ClampStick */ static void ClampStick(s8* px, s8* py, s8 max, s8 xy, s8 min) { int x = *px; int y = *py; @@ -75,8 +82,7 @@ static void ClampStick(s8* px, s8* py, s8 max, s8 xy, s8 min) { *py = (s8)(signY * y); } -/* 8034DEEC-8034E094 34882C 01A8+00 1/1 0/0 0/0 .text ClampCircle */ -void ClampCircle(s8* px, s8* py, s8 radius, s8 min) { +static void ClampCircle(s8* px, s8* py, s8 radius, s8 min) { int x = *px; int y = *py; int squared; @@ -100,7 +106,7 @@ void ClampCircle(s8* px, s8* py, s8 radius, s8 min) { squared = x * x + y * y; if (radius * radius < squared) { - length = dolsqrtf(squared); + length = sqrtf(squared); x = (x * radius) / length; y = (y * radius) / length; } @@ -109,29 +115,7 @@ void ClampCircle(s8* px, s8* py, s8 radius, s8 min) { *py = y; } -/* ############################################################################################## */ -/* 803A2170-803A2180 02E7D0 000A+06 2/2 0/0 0/0 .rodata ClampRegion */ -static const PADClampRegion ClampRegion = { - // Triggers - 30, - 180, - - // Left stick - 15, - 72, - 40, - - // Right stick - 15, - 59, - 31, - - // Stick radii - 56, - 44, -}; - -inline void ClampTrigger(u8* trigger, u8 min, u8 max) { +static void ClampTrigger(u8* trigger, u8 min, u8 max) { if (*trigger <= min) { *trigger = 0; } else { @@ -142,35 +126,27 @@ inline void ClampTrigger(u8* trigger, u8 min, u8 max) { } } -/* 8034E094-8034E1A8 3489D4 0114+00 0/0 1/1 0/0 .text PADClamp */ -void PADClamp(PADStatus* status) { +void PADClamp(PADStatus * status) { int i; - for (i = 0; i < 4; i++, status++) { - if (status->error != PAD_ERR_NONE) { - continue; - } - ClampStick(&status->stick_x, &status->stick_y, ClampRegion.maxStick, ClampRegion.xyStick, - ClampRegion.minStick); - ClampStick(&status->substick_x, &status->substick_y, ClampRegion.maxSubstick, - ClampRegion.xySubstick, ClampRegion.minSubstick); - ClampTrigger(&status->trigger_left, ClampRegion.minTrigger, ClampRegion.maxTrigger); - ClampTrigger(&status->trigger_right, ClampRegion.minTrigger, ClampRegion.maxTrigger); + for (i = 0; i < 4; i++, status++) { + if (status->err == PAD_ERR_NONE) { + ClampStick(&status->stickX, &status->stickY, ClampRegion.maxStick, ClampRegion.xyStick, ClampRegion.minStick); + ClampStick(&status->substickX, &status->substickY, ClampRegion.maxSubstick, ClampRegion.xySubstick, ClampRegion.minSubstick); + ClampTrigger(&status->triggerLeft, ClampRegion.minTrigger, ClampRegion.maxTrigger); + ClampTrigger(&status->triggerRight, ClampRegion.minTrigger, ClampRegion.maxTrigger); + } } } -/* 8034E1A8-8034E2B4 348AE8 010C+00 0/0 1/1 0/0 .text PADClampCircle */ void PADClampCircle(PADStatus* status) { int i; for (i = 0; i < 4; ++i, status++) { - if (status->error != PAD_ERR_NONE) { - continue; + if (status->err == PAD_ERR_NONE) { + ClampCircle(&status->stickX, &status->stickY, ClampRegion.radStick, ClampRegion.minStick); + ClampCircle(&status->substickX, &status->substickY, ClampRegion.radSubstick, ClampRegion.minSubstick); + ClampTrigger(&status->triggerLeft, ClampRegion.minTrigger, ClampRegion.maxTrigger); + ClampTrigger(&status->triggerRight, ClampRegion.minTrigger, ClampRegion.maxTrigger); } - - ClampCircle(&status->stick_x, &status->stick_y, ClampRegion.radStick, ClampRegion.minStick); - ClampCircle(&status->substick_x, &status->substick_y, ClampRegion.radSubstick, - ClampRegion.minSubstick); - ClampTrigger(&status->trigger_left, ClampRegion.minTrigger, ClampRegion.maxTrigger); - ClampTrigger(&status->trigger_right, ClampRegion.minTrigger, ClampRegion.maxTrigger); } -} \ No newline at end of file +} diff --git a/src/dolphin/perf/__perf.h b/src/dolphin/perf/__perf.h new file mode 100644 index 0000000000..0257b57bed --- /dev/null +++ b/src/dolphin/perf/__perf.h @@ -0,0 +1,14 @@ +#ifndef _DOLPHIN_PERF_INTERNAL_H_ +#define _DOLPHIN_PERF_INTERNAL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void __PERFDrawInit(void (*id)()); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_PERF_INTERNAL_H_ diff --git a/src/dolphin/perf/perf.c b/src/dolphin/perf/perf.c new file mode 100644 index 0000000000..7ad66a7dd8 --- /dev/null +++ b/src/dolphin/perf/perf.c @@ -0,0 +1,467 @@ +#include +#include +#include +#include "fake_tgmath.h" + +#include "__perf.h" +#include "../gx/__gx.h" + +#if DEBUG +const char* __PERFVersion = "<< Dolphin SDK - PERF\tdebug build: Apr 5 2004 03:57:10 (0x2301) >>"; +#else +const char* __PERFVersion = "<< Dolphin SDK - PERF\trelease build: Apr 5 2004 04:15:51 (0x2301) >>"; +#endif + +#define TOKEN_MAX 0xFFFF + +static OSAlarm PERFAlarm; + +static volatile s32 CurrAutoSample = 0xFFFFFFFF; +static volatile u32 CurrToken = 0x0000FFFF; + +static volatile u8 magic; +static void* (*PerfAlloc)(u32); +static void (*PerfFree)(void*); +static void (*DSCB)(u16); +u32 PERFNumFrames; +u32 PERFNumEvents; +u32 PERFNumSamples; +Frame* PERFFrames; +PerfEvent* PERFEvents; +u32 PERFCurrFrame; +volatile s32 PERFCurrSample; + +// prototypes +static void PERFResetAllMemMetrics(void); +static void PERFGetAllMemMetrics(PerfSample* s, u32 i); +void PERFSetDrawSyncCallback(void (*cb)(u16)); +static void PERFTokenCallback(u16 token); +u32 PERFInit(u32 numSamples, u32 numFramesHistory, u32 numTypes, PERFAllocator allocator, PERFDeallocator deallocator, void (*initDraw)()); +void PERFSetEvent(u8 id, char* name, PerfType type); +void PERFSetEventColor(u8 id, GXColor color); +void PERFStartFrame(void); +void PERFEndFrame(void); +void PERFEventStart(u8 id); +__declspec(weak) s32 PERFGetNewSample(void); +void PERFEventEnd(u8 id); +static void PERFStartAutoSample(void); +static void PERFEndAutoSample(void); +static void PERFTimerCallback(OSAlarm* alarm, OSContext* context); +void PERFStartAutoSampling(f32 msInterval); +void PERFStopAutoSampling(void); + +#ifndef DEBUG +inline s32 PERFGetNewSample(void) { + if (PERFCurrSample >= (PERFNumSamples - 1)) { + PERFCurrSample = PERFNumSamples - 1; + return PERFCurrSample; + } + return PERFCurrSample++; +} +#endif + +static void PERFResetAllMemMetrics(void) { + ((u16*)__memReg)[25] = 0; + ((u16*)__memReg)[26] = 0; + ((u16*)__memReg)[27] = 0; + ((u16*)__memReg)[28] = 0; + ((u16*)__memReg)[30] = 0; + ((u16*)__memReg)[29] = 0; + ((u16*)__memReg)[32] = 0; + ((u16*)__memReg)[31] = 0; + ((u16*)__memReg)[34] = 0; + ((u16*)__memReg)[33] = 0; + ((u16*)__memReg)[36] = 0; + ((u16*)__memReg)[35] = 0; + ((u16*)__memReg)[38] = 0; + ((u16*)__memReg)[37] = 0; + ((u16*)__memReg)[40] = 0; + ((u16*)__memReg)[39] = 0; + ((u16*)__memReg)[42] = 0; + ((u16*)__memReg)[41] = 0; + ((u16*)__memReg)[44] = 0; + ((u16*)__memReg)[43] = 0; +} + +static void PERFGetAllMemMetrics(PerfSample* s, u32 i) { + u32 ctrl; + u32 ctrh; + + GXReadXfRasMetric(&s->xfWaitIn[i], &s->xfWaitOut[i], &s->rasBusy[i], &s->rasClocks[i]); + + ctrl = ((u16*)__memReg)[26]; + ctrh = ((u16*)__memReg)[25]; + s->cpReq[i] = ((ctrh << 0x10) | ctrl); + + ctrl = ((u16*)__memReg)[28]; + ctrh = ((u16*)__memReg)[27]; + s->tcReq[i] = ((ctrh << 0x10) | ctrl); + + ctrl = ((u16*)__memReg)[30]; + ctrh = ((u16*)__memReg)[29]; + s->cpuRdReq[i] = ((ctrh << 0x10) | ctrl); + + ctrl = ((u16*)__memReg)[32]; + ctrh = ((u16*)__memReg)[31]; + s->cpuWrReq[i] = ((ctrh << 0x10) | ctrl); + + ctrl = ((u16*)__memReg)[34]; + ctrh = ((u16*)__memReg)[33]; + s->dspReq[i] = ((ctrh << 0x10) | ctrl); + + ctrl = ((u16*)__memReg)[36]; + ctrh = ((u16*)__memReg)[35]; + s->ioReq[i] = ((ctrh << 0x10) | ctrl); + + ctrl = ((u16*)__memReg)[38]; + ctrh = ((u16*)__memReg)[37]; + s->viReq[i] = ((ctrh << 0x10) | ctrl); + + ctrl = ((u16*)__memReg)[40]; + ctrh = ((u16*)__memReg)[39]; + s->peReq[i] = ((ctrh << 0x10) | ctrl); + + ctrl = ((u16*)__memReg)[42]; + ctrh = ((u16*)__memReg)[41]; + s->rfReq[i] = ((ctrh << 0x10) | ctrl); + + ctrl = ((u16*)__memReg)[44]; + ctrh = ((u16*)__memReg)[43]; + s->fiReq[i] = ((ctrh << 0x10) | ctrl); +} + +void PERFSetDrawSyncCallback(void (*cb)(u16)) { + DSCB = cb; +} + +static void PERFTokenCallback(u16 token) { + s32 sample; + + if ((token < 0xE000) || (((int)((u32)token >> 8) & 0xF) != magic) || (PERFCurrSample == 0)) { + if (DSCB) { + DSCB(token); + } + } else { + if (token >= 0xF000) { + if (CurrToken == TOKEN_MAX) { + ASSERTLINE(341, CurrAutoSample >= 0); + PERFEndAutoSample(); + PERFStartAutoSample(); + return; + } + + sample = (u8)(u32)token; + if ((u8)(u16)CurrToken != sample) { + sample = (u8)(u16)CurrToken; + } + + ASSERTLINE(357, sample < PERFCurrSample); + + PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampEnd = PPCMfpmc4(); + PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[1] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[sample].instructions[1] = PPCMfpmc1(); + PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[sample], 1); + if (CurrAutoSample >= 0) { + ASSERTLINE(369, CurrToken == TOKEN_MAX); + PERFEndAutoSample(); + } + CurrToken = 0xFFFF; + PERFStartAutoSample(); + return; + } + + if (CurrToken < 0xFFFF) { + ASSERTLINE(384, CurrAutoSample < 0); + sample = (u8)(u16)CurrToken; + PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampEnd = PPCMfpmc4(); + PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[1] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[sample].instructions[1] = PPCMfpmc1(); + PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[sample], 1); + } else { + ASSERTLINE(394, CurrAutoSample >= 0); + PERFEndAutoSample(); + } + + sample = (u8)(u32)token; + PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[0] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[sample].instructions[0] = PPCMfpmc1(); + PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampStart = PERFFrames[PERFCurrFrame].samples[sample].origgpStart = PPCMfpmc4(); + PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[sample], 0); + CurrToken = (u32)(u16)token; + } +} + +u32 PERFInit(u32 numSamples, u32 numFramesHistory, u32 numTypes, PERFAllocator allocator, PERFDeallocator deallocator, void (*initDraw)()) { + u32 i; + u32 size; + + OSRegisterVersion(__PERFVersion); + + PerfAlloc = allocator; + PerfFree = deallocator; + PERFNumFrames = numFramesHistory; + PERFNumEvents = numTypes; + PERFNumSamples = numSamples; + + size = (numFramesHistory * 0x10); + size += (numFramesHistory * (numSamples * 0xB0)); + size += (numTypes* 0x10); + + PERFFrames = (Frame*)PerfAlloc(numFramesHistory * 0x10); + + for (i = 0; i < PERFNumFrames; i++) { + PERFFrames[i].samples = (PerfSample *)PerfAlloc(numSamples* 0xB0); + PERFFrames[i].lastSample = 0; + } + + PERFEvents = (PerfEvent *)PerfAlloc(numTypes* 0x10); + + for (i = 0; i < numTypes; i++) { + PERFEvents[i].name = 0; + PERFEvents[i].currSample = -1; + } + + __PERFDrawInit(initDraw); + GXSetDrawSyncCallback(PERFTokenCallback); + GXInitXfRasMetric(); + return size; +} + +void PERFSetEvent(u8 id, char* name, PerfType type) { + GXColor def = {0xFF, 0x19, 0x00, 0xC8}; + + PERFEvents[id].name = name; + PERFEvents[id].type = type; + PERFEvents[id].currSample = -1; + PERFEvents[id].color = def; +} + +void PERFSetEventColor(u8 id, GXColor color) { + PERFEvents[id].color = color; +} + +void PERFStartFrame(void) { + BOOL enabled = OSDisableInterrupts(); + + PERFCurrSample = 0; + CurrToken = 0xFFFF; + GXSetDrawSyncCallback(PERFTokenCallback); + PERFFrames[PERFCurrFrame].lastSample = 0; + PERFResetAllMemMetrics(); + GXClearGPMetric(); + PPCMtpmc1(0); + PPCMtpmc2(0); + PPCMtpmc3(0); + PPCMtpmc4(0); + PPCMtmmcr0(0x8B); + PPCMtmmcr1(0x78400000); + PERFStartAutoSample(); + OSRestoreInterrupts(enabled); +} + +void PERFEndFrame(void) { + u32 i; + BOOL enabled; + + enabled = OSDisableInterrupts(); + PERFEndAutoSample(); + GXSetDrawSyncCallback(DSCB); + PERFFrames[PERFCurrFrame].end = PPCMfpmc4(); + PERFFrames[PERFCurrFrame].lastSample = PERFCurrSample; + PERFFrames[PERFCurrFrame].cachemisscycles = PPCMfpmc3(); + PERFCurrFrame = (PERFCurrFrame + 1) % PERFNumFrames; + PERFCurrSample = 0; + + for (i = 0; i < PERFNumEvents; i++) { + PERFEvents[i].currSample = -1; + } + + magic += 1; + + if ((u8)magic >= 0x10) { + magic = 0; + } + + OSRestoreInterrupts(enabled); +} + +void PERFEventStart(u8 id) { + BOOL enabled; + s32 sample; + + enabled = OSDisableInterrupts(); + + sample = PERFEvents[id].currSample; + if (sample < 0) { + sample = PERFGetNewSample(); + PERFEvents[id].currSample = sample; + PERFFrames[PERFCurrFrame].samples[sample].id = id; + PERFFrames[PERFCurrFrame].samples[sample].interrupted = 0; + + switch(PERFEvents[id].type) { + case PERF_GP_EVENT: + PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[0] = 0; + PERFFrames[PERFCurrFrame].samples[sample].instructions[0] = 0; + PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampStart = 0; + PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampEnd = 0; + GXSetDrawSync(((u16)sample + 0x10000) + (((u16)magic << 8) & 0xFF00) - 0x2000); + break; + case PERF_CPU_GP_EVENT: + PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampStart = 0; + PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampEnd = 0; + PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[0] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[sample].instructions[0] = PPCMfpmc1(); + GXSetDrawSync(((u16)sample + 0x10000) + (((u16)magic << 8) & 0xFF00) - 0x2000); + // fallthrough + case PERF_CPU_EVENT: + PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[2] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[sample].instructions[2] = PPCMfpmc1(); + PERFFrames[PERFCurrFrame].samples[sample].origcpuStart = PERFFrames[PERFCurrFrame].samples[sample].cpuTimeStampStart = PPCMfpmc4(); + PERFFrames[PERFCurrFrame].samples[sample].cpuTimeStampEnd = 0; + break; + default: + OSReport("PERF : Unknown event type for ID %d - possibly out of memory\n", id); + break; + } + } else { + OSReport("PERF : event is still open for CPU!\n"); + } + + OSRestoreInterrupts(enabled); +} + +#if DEBUG +__declspec(weak) s32 PERFGetNewSample(void) { + if (PERFCurrSample >= (PERFNumSamples - 1)) { + PERFCurrSample = PERFNumSamples - 1; + return PERFCurrSample; + } + return PERFCurrSample++; +} +#endif + +void PERFEventEnd(u8 id) { + BOOL enabled; + s32 sample; + + enabled = OSDisableInterrupts(); + sample = PERFEvents[id].currSample; + if (sample < 0) { + OSReport("PERF : ending an event that never started!\n"); + OSRestoreInterrupts(enabled); + return; + } + + switch(PERFEvents[id].type) { + case PERF_GP_EVENT: + GXSetDrawSync(((u16)sample + 0x10000) + (((u16)magic << 8) & 0xFF00) - 0x1000); + break; + case PERF_CPU_GP_EVENT: + GXSetDrawSync(((u16)sample + 0x10000) + (((u16)magic << 8) & 0xFF00) - 0x1000); + case PERF_CPU_EVENT: + PERFFrames[PERFCurrFrame].samples[sample].cpuTimeStampEnd = PPCMfpmc4(); + PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[3] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[sample].instructions[3] = PPCMfpmc1(); + break; + } + + PERFEvents[id].currSample = -1; + OSRestoreInterrupts(enabled); +} + +static void PERFStartAutoSample(void) { + CurrAutoSample = PERFGetNewSample(); + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].id = 0xFF; + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].interrupted = 0; + PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[CurrAutoSample], 0); + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].gpTimeStampStart = PPCMfpmc4(); + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].gpTimeStampEnd = 0; + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].cacheMisses[0] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].instructions[0] = PPCMfpmc1(); +} + +static void PERFEndAutoSample(void) { + if (CurrAutoSample >= 0) { + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].gpTimeStampEnd = PPCMfpmc4(); + PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[CurrAutoSample], 1); + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].cacheMisses[1] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].instructions[1] = PPCMfpmc1(); + } + CurrAutoSample = -1; +} + +static void PERFTimerCallback(OSAlarm* alarm, OSContext* context) { + s32 sample; + s32 newsample; + + if (PERFCurrSample != 0) { + if (CurrToken < 0xFFFF) { + sample = (u8)(u16)CurrToken; + // stupid CurrToken loading AGAIN + if ((u8)((CurrToken >> 8) & 0xF) != (s32)magic) { + PERFEndAutoSample(); + PERFStartAutoSample(); + return; + } + + ASSERTLINE(884, CurrAutoSample < 0); + + newsample = PERFGetNewSample(); + memcpy(&PERFFrames[PERFCurrFrame].samples[newsample], &PERFFrames[PERFCurrFrame].samples[sample], 0xB0); + PERFFrames[PERFCurrFrame].samples[newsample].gpTimeStampEnd = PPCMfpmc4(); + PERFFrames[PERFCurrFrame].samples[newsample].cacheMisses[1] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[newsample].instructions[1] = PPCMfpmc1(); + PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[newsample], 1); + PERFFrames[PERFCurrFrame].samples[newsample].id = 0xFF; + PERFFrames[PERFCurrFrame].samples[sample].gpTimeStampStart = PPCMfpmc4(); + PERFFrames[PERFCurrFrame].samples[sample].cacheMisses[0] = PPCMfpmc3(); + PERFFrames[PERFCurrFrame].samples[sample].instructions[0] = PPCMfpmc1(); + PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[sample], 0); + PERFFrames[PERFCurrFrame].samples[sample].interrupted = 1; + CurrAutoSample = -1; + return; + } + + if (CurrAutoSample < 0) { + OSReport("PERF : AUTOSAMPLE < 0!!!! SHOULD NEVER HAPPEN!\n"); + return; + } + + PERFEndAutoSample(); + PERFStartAutoSample(); + } +} + +void PERFStartAutoSampling(f32 msInterval) { + OSSetPeriodicAlarm(&PERFAlarm, OSGetTime(), (u32)OSMillisecondsToTicks(msInterval), PERFTimerCallback); +} + +void PERFStopAutoSampling(void) { + BOOL enabled = OSDisableInterrupts(); + + if (CurrAutoSample >= 0) { + PERFFrames[PERFCurrFrame].samples[CurrAutoSample].gpTimeStampEnd = PPCMfpmc4(); + PERFGetAllMemMetrics(&PERFFrames[PERFCurrFrame].samples[CurrAutoSample], 1); + } + + OSCancelAlarm(&PERFAlarm); + OSRestoreInterrupts(enabled); +} + +void PERFShutDown(void) { + BOOL enabled; + u32 i; + + enabled = OSDisableInterrupts(); + PERFStopAutoSampling(); + PERFEndAutoSample(); + GXSetDrawSyncCallback(DSCB); + + for (i = 0; i < PERFNumFrames; i++) { + PerfFree(PERFFrames[i].samples); + } + + PerfFree(PERFEvents); + PerfFree(PERFFrames); + OSRestoreInterrupts(enabled); +} diff --git a/src/dolphin/perf/perfdraw.c b/src/dolphin/perf/perfdraw.c new file mode 100644 index 0000000000..036e9182b3 --- /dev/null +++ b/src/dolphin/perf/perfdraw.c @@ -0,0 +1,695 @@ +#include +#include +#include "fake_tgmath.h" + +#include "__perf.h" + +__declspec(weak) f32 HEIGHT(u32 a, f32 f); +__declspec(weak) f32 COORD(u32 a); + +// internal macro for Perfdraw. +#define DRAW_RECT(x1, x2, y1, y2, color) \ + do { \ + GXSetChanMatColor(GX_COLOR0A0, color); \ + GXBegin(GX_QUADS, GX_VTXFMT0, 4); \ + GXPosition3f32((x1), (y1), -1.0f); \ + GXPosition3f32((x1), (y2), -1.0f); \ + GXPosition3f32((x2), (y2), -1.0f); \ + GXPosition3f32((x2), (y1), -1.0f); \ + GXEnd(); \ + } while(0) + +static u32 DrawFrameMax; +static f32 DrawFrameH; +static u32 MaxBusTransactions; + +static u32 DrawNumFrames = 3; +static f32 DrawFrameW = 205.33333f; +static GXColor DrawFrameBGColor = { 0xC8, 0xC8, 0xC8, 0xC8 }; +static GXColor DrawFrameColor = { 0x19, 0x19, 0x19, 0xC8 }; +static GXColor DrawCPUColor = { 0xFF, 0x19, 0x00, 0xC8 }; +static GXColor DrawFullColor = { 0xFF, 0x00, 0xFF, 0xC8 }; +static GXColor DrawGPColor = { 0x00, 0x64, 0xFF, 0xC8 }; +static GXColor DrawCPUCacheColor = { 0x00, 0x96, 0x00, 0xC8 }; +static GXColor DrawConnectColor = { 0x00, 0x00, 0x00, 0xC8 }; +static GXColor DrawBWBarColor = { 0x32, 0x32, 0x32, 0xC8 }; +static GXColor DrawIPCBarColor = { 0x00, 0x00, 0x5A, 0xAA }; +static GXColor DrawGPUBarColor = { 0x5A, 0x00, 0x00, 0xAA }; +static GXColor DrawIPCColor = { 0xC8, 0x64, 0x00, 0xAA }; +static GXColor DrawCPColor = { 0xC8, 0x00, 0xC8, 0xC8 }; +static GXColor DrawTCColor = { 0x00, 0xC8, 0x00, 0xC8 }; +static GXColor DrawCPURDColor = { 0xFF, 0xFF, 0x00, 0xC8 }; +static GXColor DrawCPUWRColor = { 0x00, 0x64, 0x64, 0xC8 }; +static GXColor DrawDSPColor = { 0xC8, 0x00, 0x00, 0xC8 }; +static GXColor DrawIOColor = { 0x96, 0x96, 0x32, 0xC8 }; +static GXColor DrawVIColor = { 0xFF, 0xFF, 0xFF, 0xC8 }; +static GXColor DrawPEColor = { 0x00, 0x00, 0xC8, 0xC8 }; +static GXColor DrawRFColor = { 0x00, 0xFF, 0xFF, 0xC8 }; +static GXColor DrawFIColor = { 0xC8, 0x64, 0x64, 0xC8 }; +static GXColor DrawGPXFIColor = { 0x00, 0xC8, 0x00, 0xAA }; +static GXColor DrawGPXFOColor = { 0x00, 0x00, 0xC8, 0xAA }; +static GXColor DrawGPRASIDLEColor = { 0xC8, 0xC8, 0x00, 0xAA }; + +static BOOL bDrawBWBar = TRUE; +static BOOL bDrawCPUBar = TRUE; +static BOOL bDrawXFBars = TRUE; +static BOOL bDrawRASBar = TRUE; +static BOOL bAutoScale = TRUE; + +static BOOL bDrawBWBarKey; +static f32 lastx; + +static f32 FramePts[28] = { + 0.0f, + 0.0f, + 0.0f, + 10.0f, + 0.0f, + 0.0f, + 616.0f, + 0.0f, + 616.0f, + 0.0f, + 616.0f, + 10.0f, + 0.0f, + 10.0f, + 616.0f, + 10.0f, + 205.33333f, + 0.0f, + 205.33333f, + 10.0f, + 410.66666f, + 0.0f, + 410.66666f, + 10.0f, + 616.0f, + 0.0f, + 616.0f, + 10.0f, +}; + +static f32 CPUPts[4] = { + 0.0f, + 0.0f, + 616.0f, + 0.0f, +}; + +static f32 GPPts[4] = { + 0.0f, + 0.0f, + 616.0f, + 0.0f, +}; + +void (*GameDrawInit)(); +Mtx mID; + +#ifndef DEBUG +inline f32 HEIGHT(u32 a, f32 f) { + return 140.0f * ((f32) a / ((f32) MaxBusTransactions * f)); +} + +inline f32 COORD(u32 a) { + return 616.0f * ((f32) a / (f32) DrawFrameMax); +} +#endif + +void __PERFDrawInit(void (*id)()) { + MTXIdentity(mID); + GameDrawInit = id; + DrawFrameMax = (OS_CORE_CLOCK / 60) * 3; + DrawFrameH = (PERFNumEvents + 1) * 7; + MaxBusTransactions = (OS_BUS_CLOCK / 120); + FramePts[3] = FramePts[11] = FramePts[13] = FramePts[15] = FramePts[19] = FramePts[23] = DrawFrameH; + FramePts[6] = FramePts[8] = FramePts[10] = FramePts[14] = 616.0f; + GPPts[1] = (PERFNumEvents + 2) * 19; + GPPts[3] = GPPts[1]; +} + +static Mtx44 mProj; +f32 pSave[7]; + +void PERFPreDraw(void) { + u32 i; + u32 j; + + GXGetProjectionv(pSave); + + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + mProj[i][j] = 0.0f; + } + } + + mProj[0][0] = 0.003125f; + mProj[1][1] = 0.004166667f; + mProj[2][2] = 1.0f; + mProj[3][3] = 1.0f; + mProj[0][3] = -0.95f; + mProj[1][3] = -0.87500005f; + + GXSetProjection(mProj, GX_ORTHOGRAPHIC); + GXClearVtxDesc(); + GXInvalidateVtxCache(); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); + GXSetZCompLoc(GX_FALSE); + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_REG, 0, GX_DF_NONE, GX_AF_NONE); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); + GXSetNumTexGens(0); + GXSetNumTevStages(1); + GXSetZMode(GX_DISABLE, GX_ALWAYS, GX_DISABLE); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_TEX_ST, GX_RGBA6, 0); +} + +static void DrawBWBar(PerfSample* s) { + u32 delta; + u32 interval; + f32 bwscale; + f32 lastY; + f32 x1; + f32 x2; + f32 height; + u32 rasclocks; + u32 rasBusy; + u32 xfI; + u32 xfO; + u32 instructions; + f32 ipc; + f32 ipcscale; + u32 misses; + + interval = s->gpTimeStampEnd - s->gpTimeStampStart; + bwscale = (f32)interval / (OS_CORE_CLOCK / 60); + lastY = 7.0f + DrawFrameH; + x1 = COORD(s->gpTimeStampStart); + x2 = COORD(s->gpTimeStampEnd); + if (fabs(lastx - x1) < 1.0f) { + x1 = lastx; + } + lastx = x2; + + // Draw BW Bars if toggled + if (bDrawBWBar) { + delta = s->cpReq[1] - s->cpReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawCPColor); + lastY += height; + } + delta = s->tcReq[1] - s->tcReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawTCColor); + lastY += height; + } + delta = s->cpuRdReq[1] - s->cpuRdReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawCPURDColor); + lastY += height; + } + delta = s->cpuWrReq[1] - s->cpuWrReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawCPUWRColor); + lastY += height; + } + delta = s->dspReq[1] - s->dspReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawDSPColor); + lastY += height; + } + delta = s->ioReq[1] - s->ioReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawIOColor); + lastY += height; + } + delta = s->viReq[1] - s->viReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawVIColor); + lastY += height; + } + delta = s->peReq[1] - s->peReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawPEColor); + lastY += height; + } + delta = s->rfReq[1] - s->rfReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawRFColor); + lastY += height; + } + s->fiReq[0] /= 2; + s->fiReq[1] /= 2; + delta = s->fiReq[1] - s->fiReq[0]; + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawFIColor); + } + } + + if (bDrawCPUBar) { + instructions = s->instructions[1] - s->instructions[0]; + ipc = (f32)instructions / (f32) interval; + ipcscale = ipc / 2.0f; + misses = s->cacheMisses[1] - s->cacheMisses[0]; + lastY = 7.0f + (140.0f + (7.0f + DrawFrameH)); + height = ipcscale * 50.0f; + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawIPCColor); + } + height = (50.0f * (f32) misses) / (f32) interval; + DRAW_RECT(x1, x2, (50.0f + lastY) - height, (50.0f + lastY), DrawCPUCacheColor); + } + + rasclocks = s->rasClocks[1] - s->rasClocks[0]; + + if (bDrawXFBars) { + lastY = 14.0f + (50.0f + (140.0f + (7.0f + DrawFrameH))); + xfI = s->xfWaitIn[1] - s->xfWaitIn[0]; + xfO = s->xfWaitOut[1] - s->xfWaitOut[0]; + if (rasclocks >= (u32) (xfO + xfI)) { + xfI = rasclocks - (xfO + xfI); + height = (50.0f * xfI) / rasclocks; + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawGPXFIColor); + } + } + } + + if (bDrawRASBar) { + lastY = 50.0f + (21.0f + (50.0f + (140.0f + (7.0f + DrawFrameH)))); + rasBusy = s->rasBusy[1] - s->rasBusy[0]; + height = (50.0f * (f32)rasBusy) / rasclocks; + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawGPRASIDLEColor); + } + } +} + +#if DEBUG +__declspec(weak) f32 HEIGHT(u32 a, f32 f) { + return 140.0f * ((f32) a / ((f32) MaxBusTransactions * f)); +} + +__declspec(weak) f32 COORD(u32 a) { + return 616.0f * ((f32) a / (f32) DrawFrameMax); +} +#endif + +static void DrawKey(void) { + u32 delta; + u32 foo[2]; + f32 bwscale; + f32 lastY; + f32 x1; + f32 x2; + f32 height; + + x1 = 595.4667f; + x2 = 616.0f; + lastY = 7.0f + DrawFrameH; + bwscale = 1.0f; + foo[0] = 0; + foo[1] = MaxBusTransactions / 10; + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawCPColor); + lastY += height; + } + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawTCColor); + lastY += height; + } + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawCPURDColor); + lastY += height; + } + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawCPUWRColor); + lastY += height; + } + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawDSPColor); + lastY += height; + } + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawIOColor); + lastY += height; + } + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawVIColor); + lastY += height; + } + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawPEColor); + lastY += height; + } + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawRFColor); + lastY += height; + } + + delta = (foo[1] - foo[0]); + height = HEIGHT(delta, bwscale); + if (height > 1.0f) { + DRAW_RECT(x1, x2, lastY, lastY + height, DrawFIColor); + lastY += height; + } +} + +void PERFDumpScreen(void) { + PerfSample* samples; + u32 s; + u32 id; + u32 i; + u32 delta; + u32 e; + f32 c; + f32 lastY; + f32 allX; + f32 xcoord; + + if (GameDrawInit) { + samples = PERFFrames[PERFCurrFrame].samples; + + if (bAutoScale) { + DrawNumFrames = PERFFrames[PERFCurrFrame].end / (OS_CORE_CLOCK / 60) + 1; + } + + DrawFrameMax = (OS_CORE_CLOCK / 60) * DrawNumFrames; + DrawFrameW = 616.0f / DrawNumFrames; + allX = COORD(PERFFrames[PERFCurrFrame].end); + GXLoadPosMtxImm(mID, 0); + DRAW_RECT(0.0f, 616.0f, 0.0f, DrawFrameH, DrawFrameBGColor); + GXSetChanMatColor(GX_COLOR0A0, DrawFrameColor); + GXSetLineWidth(0xCU, GX_TO_ZERO); + + // different draw shape? Consider other forms of this draw macro that may work. If anything will work. + GXBegin(GX_LINES, GX_VTXFMT0, 8); + GXPosition3f32(FramePts[0], FramePts[1], -1.0f); + GXPosition3f32(FramePts[2], FramePts[3], -1.0f); + GXPosition3f32(FramePts[4], FramePts[5], -1.0f); + GXPosition3f32(FramePts[6], FramePts[7], -1.0f); + GXPosition3f32(FramePts[8], FramePts[9], -1.0f); + GXPosition3f32(FramePts[10], FramePts[11], -1.0f); + GXPosition3f32(FramePts[12], FramePts[13], -1.0f); + GXPosition3f32(FramePts[14], FramePts[15], -1.0f); + GXEnd(); + + if (DrawNumFrames > 1) { + GXBegin(GX_LINES, GX_VTXFMT0, (DrawNumFrames - 1) * 2); + for(i = 1; i < DrawNumFrames; i++) { + xcoord = COORD(i * (OS_CORE_CLOCK / 60)); + GXPosition3f32(xcoord, FramePts[17], -1.0f); + GXPosition3f32(xcoord, FramePts[19], -1.0f); + } + GXEnd(); + } + + GXSetChanMatColor(GX_COLOR0A0, DrawFullColor); + GXSetLineWidth(0x20U, GX_TO_ZERO); + + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(0.0f, 0.0f, -1.0f); + GXPosition3f32(allX, 0.0f, -1.0f); + GXEnd(); + + GXSetChanMatColor(GX_COLOR0A0, DrawCPUCacheColor); + + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(0.0f, 0.0f, -1.0f); + GXPosition3f32(COORD(PERFFrames[PERFCurrFrame].cachemisscycles), 0.0f, -1.0f); + GXEnd(); + + if (bDrawBWBar) { + lastY = 7.0f + DrawFrameH; + GXSetChanMatColor(GX_COLOR0A0, DrawBWBarColor); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32(0.0f, lastY, -1.0f); + GXPosition3f32(0.0f, 140.0f + lastY, -1.0f); + GXPosition3f32(allX, 140.0f + lastY, -1.0f); + GXPosition3f32(allX, lastY, -1.0f); + GXEnd(); + } + + if (bDrawCPUBar) { + lastY = 7.0f + (140.0f + (7.0f + DrawFrameH)); + GXSetChanMatColor(GX_COLOR0A0, DrawIPCBarColor); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32(0.0f, lastY, -1.0f); + GXPosition3f32(0.0f, 50.0f + lastY, -1.0f); + GXPosition3f32(allX, 50.0f + lastY, -1.0f); + GXPosition3f32(allX, lastY, -1.0f); + GXEnd(); + GXSetChanMatColor(GX_COLOR0A0, DrawConnectColor); + GXSetLineWidth(6, GX_TO_ZERO); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(0.0f, 25.0f + lastY, -1.0f); + GXPosition3f32(allX, 25.0f + lastY, -1.0f); + GXEnd(); + } + + if (bDrawXFBars) { + lastY = 14.0f + (50.0f + (140.0f + (7.0f + DrawFrameH))); + GXSetChanMatColor(GX_COLOR0A0, DrawGPUBarColor); + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32(0.0f, lastY, -1.0f); + GXPosition3f32(0.0f, 50.0f + lastY, -1.0f); + GXPosition3f32(allX, 50.0f + lastY, -1.0f); + GXPosition3f32(allX, lastY, -1.0f); + GXEnd(); + } + + if (bDrawRASBar) { + lastY = 50.0f + (21.0f + (50.0f + (140.0f + (7.0f + DrawFrameH)))); + GXSetChanMatColor(GX_COLOR0A0, DrawGPUBarColor); + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32(0.0f, lastY, -1.0f); + GXPosition3f32(0.0f, 50.0f + lastY, -1.0f); + GXPosition3f32(allX, 50.0f + lastY, -1.0f); + GXPosition3f32(allX, lastY, -1.0f); + GXEnd(); + } + + for (s = 0; s < PERFFrames[PERFCurrFrame].lastSample; s++) { + id = samples[s].id; + if (id == 0xFF) { + DrawBWBar(&samples[s]); + } else { + switch(PERFEvents[id].type) { + case PERF_CPU_GP_EVENT: + GXSetChanMatColor(GX_COLOR0A0, PERFEvents[id].color); + GXSetLineWidth(32, GX_TO_ZERO); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(COORD(samples[s].cpuTimeStampStart), (f32) ((id + 1) * 7), -1.0f); + GXPosition3f32(COORD(samples[s].cpuTimeStampEnd), (f32) ((id + 1) * 7), -1.0f); + GXEnd(); + delta = samples[s].cacheMisses[3] - samples[s].cacheMisses[2]; + if (delta) { + e = delta + samples[s].cpuTimeStampStart; + c = COORD(e); + GXSetChanMatColor(GX_COLOR0A0, DrawCPUCacheColor); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(COORD(samples[s].cpuTimeStampStart), (f32) ((id + 1) * 7), -1.0f); + GXPosition3f32(c, (f32) ((id + 1) * 7), -1.0f); + GXEnd(); + } + + if (samples[s].gpTimeStampEnd != 0) { + if (!samples[s].interrupted) { + GXSetChanMatColor(GX_COLOR0A0, DrawGPColor); + GXSetLineWidth(32, GX_TO_ZERO); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(COORD(samples[s].gpTimeStampStart), DrawFrameH, -1.0f); + GXPosition3f32(COORD(samples[s].gpTimeStampEnd), DrawFrameH, -1.0f); + GXEnd(); + + DrawBWBar(&samples[s]); + + GXSetChanMatColor(GX_COLOR0A0, DrawConnectColor); + GXSetLineWidth(6, GX_TO_ZERO); + GXBegin(GX_LINES, GX_VTXFMT0, 4); + GXPosition3f32(COORD(samples[s].gpTimeStampStart), DrawFrameH, -1.0f); + GXPosition3f32(COORD(samples[s].cpuTimeStampStart), (f32) ((id + 1) * 7), -1.0f); + GXPosition3f32(COORD(samples[s].gpTimeStampEnd), DrawFrameH, -1.0f); + GXPosition3f32(COORD(samples[s].cpuTimeStampEnd), (f32) ((id + 1) * 7), -1.0f); + GXEnd(); + } else { + GXSetChanMatColor(GX_COLOR0A0, DrawGPColor); + GXSetLineWidth(32, GX_TO_ZERO); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(COORD(samples[s].origgpStart), DrawFrameH, -1.0f); + GXPosition3f32(COORD(samples[s].gpTimeStampEnd), DrawFrameH, -1.0f); + GXEnd(); + + DrawBWBar(&samples[s]); + + GXSetChanMatColor(GX_COLOR0A0, DrawConnectColor); + GXSetLineWidth(6, GX_TO_ZERO); + GXBegin(GX_LINES, GX_VTXFMT0, 4); + GXPosition3f32(COORD(samples[s].origgpStart), DrawFrameH, -1.0f); + GXPosition3f32(COORD(samples[s].origcpuStart), (f32) ((id + 1) * 7), -1.0f); + GXPosition3f32(COORD(samples[s].gpTimeStampEnd), DrawFrameH, -1.0f); + GXPosition3f32(COORD(samples[s].cpuTimeStampEnd), (f32) ((id + 1) * 7), -1.0f); + GXEnd(); + } + } + break; + case PERF_CPU_EVENT: + GXSetChanMatColor(GX_COLOR0A0, PERFEvents[id].color); + GXSetLineWidth(32, GX_TO_ZERO); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + !samples[s].cpuTimeStampStart; // needed to match + GXPosition3f32(COORD(samples[s].cpuTimeStampStart), (f32) ((id + 1) * 7), -1.0f); + GXPosition3f32(COORD(samples[s].cpuTimeStampEnd), (f32) ((id + 1) * 7), -1.0f); + GXEnd(); + + delta = samples[s].cacheMisses[3] - samples[s].cacheMisses[2]; + if (delta != 0) { + e = delta + samples[s].cpuTimeStampStart; + c = COORD(e); + GXSetChanMatColor(GX_COLOR0A0, DrawCPUCacheColor); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(COORD(samples[s].cpuTimeStampStart), (f32) ((id + 1) * 7), -1.0f); + GXPosition3f32(c, (f32) ((id + 1) * 7), -1.0f); + GXEnd(); + } + break; + case PERF_GP_EVENT: + if (samples[s].interrupted == 0) { + GXSetChanMatColor(GX_COLOR0A0, DrawGPColor); + GXSetLineWidth(32, GX_TO_ZERO); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(COORD(samples[s].gpTimeStampStart), DrawFrameH, -1.0f); + GXPosition3f32(COORD(samples[s].gpTimeStampEnd), DrawFrameH, -1.0f); + GXEnd(); + DrawBWBar(&samples[s]); + } else { + GXSetChanMatColor(GX_COLOR0A0, DrawGPColor); + GXSetLineWidth(32, GX_TO_ZERO); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(COORD(samples[s].origgpStart), DrawFrameH, -1.0f); + GXPosition3f32(COORD(samples[s].gpTimeStampEnd), DrawFrameH, -1.0f); + GXEnd(); + DrawBWBar(&samples[s]); + } + break; + } + } + } + + if (bDrawBWBarKey) { + DrawKey(); + } + } +} + +void PERFPostDraw(void) { + u32 i; + u32 j; + + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + mProj[i][j] = 0.0f; + } + } + + mProj[0][0] = pSave[1]; + mProj[0][2] = pSave[2]; + mProj[1][1] = pSave[3]; + mProj[1][2] = pSave[4]; + mProj[2][2] = pSave[5]; + mProj[2][3] = pSave[6]; + mProj[3][2] = -1.0f; + GXSetProjection(mProj, GX_PERSPECTIVE); + GameDrawInit(); +} + +void PERFSetDrawBWBarKey(BOOL tf) { + bDrawBWBarKey = tf; +} + +void PERFSetDrawBWBar(BOOL tf) { + bDrawBWBar = tf; +} + +void PERFSetDrawCPUBar(BOOL tf) { + bDrawCPUBar = tf; +} + +void PERFSetDrawXFBars(BOOL tf) { + bDrawXFBars = tf; +} + +void PERFSetDrawRASBar(BOOL tf) { + bDrawRASBar = tf; +} + +void PERFToggleDrawBWBarKey(void) { + bDrawBWBarKey = (bDrawBWBarKey) ? FALSE : TRUE; +} + +void PERFToggleDrawBWBar(void) { + bDrawBWBar = (bDrawBWBar) ? FALSE : TRUE; +} + +void PERFToggleDrawCPUBar(void) { + bDrawCPUBar = (bDrawCPUBar) ? FALSE : TRUE; +} + +void PERFToggleDrawXFBars(void) { + bDrawXFBars = (bDrawXFBars) ? FALSE : TRUE; +} + +void PERFToggleDrawRASBar(void) { + bDrawRASBar = (bDrawRASBar) ? FALSE : TRUE; +} + +void PERFSetDrawFrames(u32 frames) { + if (frames != 0) { + DrawNumFrames = frames; + bAutoScale = FALSE; + } else { + bAutoScale = TRUE; + } +} diff --git a/src/dolphin/seq/seq.c b/src/dolphin/seq/seq.c new file mode 100644 index 0000000000..582a323395 --- /dev/null +++ b/src/dolphin/seq/seq.c @@ -0,0 +1,468 @@ +#include +#include + +static u8 __SEQMidiEventLength[128] = { + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, + 0x00, 0x00, 0x02, 0x01, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +static SEQSEQUENCE* __SEQSequenceList; + +// prototypes +static void __SEQPushSequenceList(SEQSEQUENCE* sequence); +static void __SEQRemoveSequenceFromList(SEQSEQUENCE* sequence); +static u32 __SEQGetIntTrack(SEQTRACK* track); +static void __SEQHandleSysExEvent(SEQTRACK* track); +static void __SEQSetTicksPerFrame(SEQTRACK* track, f32 bps); +static void __SEQTempoMetaEvent(SEQTRACK* track); +static void __SEQTrackEnd(SEQTRACK* track); +static void __SEQHandleMetaEvent(SEQTRACK* track); +static void __SEQHandleSynthEvent(SYNSYNTH* synth, SEQTRACK* track); +static void __SEQRunEvent(SYNSYNTH* synth, SEQTRACK* track); +static void __SEQInitTracks(SEQSEQUENCE* sequence, u8* read, int tracks); +static void __SEQReadHeader(SEQSEQUENCE* sequence, u8* midiStream); + +static void __SEQPushSequenceList(SEQSEQUENCE* sequence) { + BOOL old; + + old = OSDisableInterrupts(); + if (__SEQSequenceList) { + sequence->next = __SEQSequenceList; + } else { + sequence->next = NULL; + } + + __SEQSequenceList = sequence; + OSRestoreInterrupts(old); +} + +static void __SEQRemoveSequenceFromList(SEQSEQUENCE* sequence) { + BOOL old; + SEQSEQUENCE* thisSequence; + SEQSEQUENCE* next; + + old = OSDisableInterrupts(); + thisSequence = __SEQSequenceList; + __SEQSequenceList = NULL; + + while(thisSequence) { + next = thisSequence->next; + if (thisSequence != sequence) { + __SEQPushSequenceList(thisSequence); + } + thisSequence = next; + } + + OSRestoreInterrupts(old); +} + +static u32 __SEQGetIntTrack(SEQTRACK* track) { + u32 value; + + ASSERTLINE(120, track); + for (value = *track->current & 0x7F; *track->current & 0x80; value = (value << 7) + (*track->current & 0x7F)) { + track->current++; + } + track->current++; + return value; +} + +static void __SEQHandleSysExEvent(SEQTRACK* track) { + u32 length; + + ASSERTLINE(143, track); + length = __SEQGetIntTrack(track); + track->current += length; +} + +static void __SEQSetTicksPerFrame(SEQTRACK* track, f32 bps) { + SEQSEQUENCE* sequence; + + ASSERTLINE(157, track); + sequence = track->sequence; + track->beatsPerSec = bps; + track->ticksPerFrame = (65536.0f * (160.0f / ((32000.0f / bps) / sequence->timeFormat))); +} + +static void __SEQTempoMetaEvent(SEQTRACK* track) { + u32 data; + f32 beatsPerSec; + + data = *track->current; + track->current++; + + data = (data << 8) + *track->current; + track->current++; + + data = (data << 8) + *track->current; + track->current++; + + beatsPerSec = 1000000 / (f32)data; + __SEQSetTicksPerFrame(track, beatsPerSec); +} + +static void __SEQTrackEnd(SEQTRACK* track) { + SEQSEQUENCE* sequence; + ASSERTLINE(199, track); + + sequence = track->sequence; + sequence->tracksRunning--; + track->state = 0; + if (sequence->tracksRunning == 0) { + sequence->end = 1; + } +} + +static void __SEQHandleMetaEvent(SEQTRACK* track) { + u8 type; + u32 length; + + ASSERTLINE(218, track); + type = *track->current; + track->current++; + + switch(type) { + case 0x2F: + __SEQTrackEnd(track); + return; + case 0x51: + length = __SEQGetIntTrack(track); + __SEQTempoMetaEvent(track); + return; + default: + length = __SEQGetIntTrack(track); + track->current += length; + return; + } +} + +static void __SEQHandleSynthEvent(SYNSYNTH* synth, SEQTRACK* track) { + u8 ch[3]; + u32 bytes; + void (*callback)(void *, u8); + + bytes = __SEQMidiEventLength[track->status - 0x80]; + ch[0] = track->status; + + switch(bytes) { + case 0: + break; + case 1: + ch[1] = *track->current; track->current++; + break; + case 2: + ch[1] = *track->current; track->current++; + ch[2] = *track->current; track->current++; + break; + } + + if ((ch[0] & 0xF0) == 0xB0) { + callback = ((SEQSEQUENCE*)track->sequence)->callback[ch[1]]; + if (callback) { + callback(track, ch[1]); + } + } + + SYNMidiInput(synth, ch); +} + +static void __SEQRunEvent(SYNSYNTH* synth, SEQTRACK* track) { + u8 event; + + ASSERTLINE(303, synth); + ASSERTLINE(304, track); + + event = *track->current; + if (event >= 0x80) { + track->status = event; track->current++; + } + + switch(track->status) { + case 0xF7: + case 0xF0: + __SEQHandleSysExEvent(track); + break; + case 0xFF: + __SEQHandleMetaEvent(track); + break; + default: + __SEQHandleSynthEvent(synth, track); + break; + } + + if (track->current >= track->end) { + __SEQTrackEnd(track); + } +} + +static void __SEQInitTracks(SEQSEQUENCE* sequence, u8* read, int tracks) { + int i; + u8* p; + u32 chunk; + u32 bytes; + SEQTRACK* track; + + i = 0; + p = read; + + while (tracks) { + while (1) { + chunk = *(u32*)p; + p += 4; + bytes = *(u32*)p; + p += 4; + if (chunk == 'MTrk') { + track = &sequence->track[i]; + track->sequence = sequence; + track->start = p; + track->end = &p[bytes]; + track->current = p; + track->defaultTicksPerFrame = (u32)(65536.0f * (160.0f / (16000.0f / (f32)sequence->timeFormat))); + track->state = 0; + p += bytes; + break; + } + p += bytes; + } + tracks--; + i++; + } +} + +static void __SEQReadHeader(SEQSEQUENCE* sequence, u8* midiStream) { + u8* read; + u32 bytes; + u32 fileType; + + read = midiStream; + ASSERTMSGLINE(401, *(u32*)read == 'MThd', "!!!midiStream is not a valid MIDI file\n!!!"); + read += 4; + + bytes = *(u32*)read; + read += 4; + + fileType = *(u16*)read; + read+=2; + + sequence->nTracks = *(u16*)read; + read+=2; + + sequence->timeFormat = *(s16*)read; + read+=2; + + ASSERTMSGLINE(416, sequence->timeFormat >= 0, "!!!SEQ does not support SMPTE time!!!\n"); + bytes -= 6; + read += bytes; + + switch(fileType) { + case 0: + sequence->nTracks = 1; + __SEQInitTracks(sequence, read, 1); + break; + case 1: + ASSERTMSGLINE(438, sequence->nTracks < 0x40, "exceeded SEQ_MAX_TRACKS, please increase SEQ_MAX_TRACKS\n"); + __SEQInitTracks(sequence, read, sequence->nTracks); + break; + default: + ASSERTMSGLINE(446, 0, "!!!Invalid MIDI file type\n!!!"); + break; + } + + sequence->tracksRunning = sequence->nTracks; +} + +void SEQInit(void) { + __SEQSequenceList = NULL; +} + +void SEQQuit(void) { + __SEQSequenceList = NULL; +} + +void SEQRunAudioFrame(void) { + SEQSEQUENCE* sequence; + u32 i; + SEQTRACK* track; + u32 ticks; + + for (sequence = __SEQSequenceList; sequence; sequence = sequence->next) { + if ((sequence->state == 1) || (sequence->state == 2)) { + for (i = 0; i < sequence->nTracks; i++) { + track = &sequence->track[i]; + if ((track->state == 1) || (track->state == 2)) { + ticks = track->ticksPerFrame; + if (track->delay > ticks) { + track->delay -= ticks; + } else { + while (ticks >= track->delay) { + ticks -= track->delay; + __SEQRunEvent(&sequence->synth, track); + if (track->state != 0) { + track->delay = __SEQGetIntTrack(track) << 0x10; + } else { + break; + } + } + + track->delay -= ticks; + } + } + } + } + + if (sequence->end != 0) { + if (sequence->state == 2) { + SEQSetState(sequence, 0); + SEQSetState(sequence, 2); + } else { + SEQSetState(sequence, 0); + } + } + } +} + +void SEQAddSequence(SEQSEQUENCE* sequence, u8* midiStream, void* wt, u32 aramBase, u32 zeroBase, u32 priorityVoiceAlloc, u32 priorityNoteOn, u32 priorityNoteRelease) { + int i; + + ASSERTLINE(559, sequence); + ASSERTLINE(560, midiStream); + ASSERTLINE(561, wt); + ASSERTLINE(562, aramBase); + ASSERTLINE(563, (priorityVoiceAlloc < 32) && (priorityVoiceAlloc > 0)); + ASSERTLINE(564, (priorityNoteOn < 32) && (priorityNoteOn > 0)); + ASSERTLINE(565, (priorityNoteRelease < 32) && (priorityNoteRelease > 0)); + + SYNInitSynth(&sequence->synth, wt, aramBase, zeroBase, priorityVoiceAlloc, priorityNoteOn, priorityNoteRelease); + sequence->state = 0; + + for(i = 0; i < 0x80; i++) { + sequence->callback[i] = 0; + } + + __SEQReadHeader(sequence, midiStream); + __SEQPushSequenceList(sequence); +} + +void SEQRemoveSequence(SEQSEQUENCE* sequence) { + ASSERTLINE(598, sequence); + __SEQRemoveSequenceFromList(sequence); + SYNQuitSynth(&sequence->synth); +} + +void SEQRegisterControllerCallback(SEQSEQUENCE* sequence, u8 controller, void (*callback)(void*, u8)) { + ASSERTLINE(617, sequence); + ASSERTLINE(618, controller < 128); + ASSERTLINE(619, callback); + sequence->callback[controller] = callback; +} + +void SEQSetState(SEQSEQUENCE* sequence, u32 state) { + int i; + + ASSERTLINE(632, sequence); + + switch(state) { + case 1: + case 2: + if (sequence->state == 0) { + int old; + + old = OSDisableInterrupts(); + for (i = 0; i < sequence->nTracks; i++) { + SEQTRACK* track = &sequence->track[i]; + track->current = track->start; + track->ticksPerFrame = track->defaultTicksPerFrame; + track->delay = __SEQGetIntTrack(track) << 0x10; + track->state = 1; + } + sequence->tracksRunning = sequence->nTracks; + OSRestoreInterrupts(old); + } + sequence->end = 0; + break; + case 0: + case 3: { + int old; + u8 ch[3]; + + for (i = 0; i < 16; i++) { + old = OSDisableInterrupts(); + ch[0] = (i | 0xB0); + ch[1] = 0x7B; + ch[2] = 0; + SYNMidiInput(&sequence->synth, ch); + OSRestoreInterrupts(old); + } + break; + } + } + + sequence->state = state; +} + +u32 SEQGetState(SEQSEQUENCE* sequence) { + ASSERTLINE(700, sequence); + return sequence->state; +} + +void SEQSetTempo(SEQSEQUENCE* sequence, u32 trackIndex, f32 bpm) { + int i; + + ASSERTLINE(711, sequence); + ASSERTLINE(712, (trackIndex < sequence->nTracks) || (trackIndex == SEQ_ALL_TRACKS)); + + if (trackIndex == -1) { + for (i = 0; i < sequence->nTracks; i++) { + __SEQSetTicksPerFrame(&sequence->track[i], bpm / 60.0f); + } + return; + } + + __SEQSetTicksPerFrame(&sequence->track[trackIndex], bpm / 60.0f); +} + +f32 SEQGetTempo(SEQSEQUENCE* sequence, u32 trackIndex) { + ASSERTLINE(733, sequence); + ASSERTLINE(734, trackIndex < sequence->nTracks); + return 60.0f* sequence->track[trackIndex].beatsPerSec; +} + +void SEQSetVolume(SEQSEQUENCE* sequence, s32 dB) { + ASSERTLINE(745, sequence); + SYNSetMasterVolume(&sequence->synth, dB); +} + +long SEQGetVolume(SEQSEQUENCE* sequence) { + ASSERTLINE(756, sequence); + SYNGetMasterVolume(&sequence->synth); +} diff --git a/src/dolphin/si/SIBios.c b/src/dolphin/si/SIBios.c index 793227f907..cc7164e8d2 100644 --- a/src/dolphin/si/SIBios.c +++ b/src/dolphin/si/SIBios.c @@ -1,101 +1,98 @@ -#include "dolphin/si/SIBios.h" -#include "dolphin/os.h" +#include +#include -/* 804509C8-804509D0 -00001 0004+04 1/1 0/0 0/0 .sdata __SIVersion */ -static char* __SIVersion = "<< Dolphin SDK - SI\trelease build: Apr 5 2004 04:14:16 (0x2301) >>"; +#include "__os.h" -static u32 CompleteTransfer(void); -BOOL __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, - SICallback callback); +#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) + +#ifdef DEBUG +const char* __SIVersion = "<< Dolphin SDK - SI\tdebug build: Apr 5 2004 03:55:31 (0x2301) >>"; +#else +const char* __SIVersion = "<< Dolphin SDK - SI\trelease build: Apr 5 2004 04:14:16 (0x2301) >>"; +#endif + +static SIControl Si = { + /* chan */ -1, + /* poll */ 0, + /* inputBytes */ 0, + /* input */ NULL, + /* callback */ NULL +}; + +static SIPacket Packet[4]; +static OSAlarm Alarm[4]; +static u32 Type[4] = { SI_ERROR_NO_RESPONSE, SI_ERROR_NO_RESPONSE, SI_ERROR_NO_RESPONSE, SI_ERROR_NO_RESPONSE }; +static OSTime TypeTime[4]; +static OSTime XferTime[4]; +static SITypeCallback TypeCallback[4][4]; +static __OSInterruptHandler RDSTHandler[4]; +static BOOL InputBufferValid[4]; +static u32 InputBuffer[4][2]; +static volatile u32 InputBufferVcount[4]; + +u32 __PADFixBits; + +// prototypes +static u32 CompleteTransfer(); +static void SITransferNext(s32 chan); +static void SIInterruptHandler(__OSInterrupt interrupt, OSContext* context); +static int __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, SICallback callback); static void AlarmHandler(OSAlarm* alarm, OSContext* context); static void GetTypeCallback(s32 chan, u32 error, OSContext* context); +static int SIGetResponseRaw(s32 chan); -u32 VIGetCurrentLine(); - - -/* 803D11FC-803D1210 02E31C 0014+00 8/11 0/0 0/0 .data Si */ -static SIControl Si = { - -1, 0, 0, NULL, NULL, -}; - -/* 803D1210-803D1220 02E330 0010+00 5/5 0/0 0/0 .data Type */ -static u32 Type[SI_MAX_CHAN] = { - SI_ERROR_NO_RESPONSE, - SI_ERROR_NO_RESPONSE, - SI_ERROR_NO_RESPONSE, - SI_ERROR_NO_RESPONSE, -}; - -/* 80344BA0-80344BC0 33F4E0 0020+00 0/0 1/1 0/0 .text SIBusy */ -BOOL SIBusy() { - return Si.chan != -1 ? TRUE : FALSE; +BOOL SIBusy(void) { + return (Si.chan != -1) ? TRUE : FALSE; } -/* 8044C630-8044C6B0 079350 0080+00 9/9 0/0 0/0 .bss Packet */ -static SIPacket Packet[SI_MAX_CHAN]; - -/* 80344BC0-80344BFC 33F500 003C+00 0/0 1/1 0/0 .text SIIsChanBusy */ BOOL SIIsChanBusy(s32 chan) { - return (Packet[chan].chan != -1 || Si.chan == chan); + return Packet[chan].chan != -1 || Si.chan == chan; } -/* 8044C6B0-8044C750 0793D0 00A0+00 1/1 0/0 0/0 .bss Alarm */ -static OSAlarm Alarm[SI_MAX_CHAN]; - -/* 8044C750-8044C770 079470 0020+00 2/2 0/0 0/0 .bss TypeTime */ -static OSTime TypeTime[SI_MAX_CHAN]; - -/* 8044C770-8044C790 079490 0020+00 1/1 0/0 0/0 .bss XferTime */ -static OSTime XferTime[SI_MAX_CHAN]; - -static inline void SIClearTCInterrupt() { +static void SIClearTCInterrupt(void) { u32 reg; - reg = __SIRegs[13]; - reg |= 0x80000000; - reg &= ~0x00000001; - __SIRegs[13] = reg; + reg = __SIRegs[SI_COMCSR_IDX]; + reg |= SI_COMCSR_TCINT_MASK; + reg &= ~SI_COMCSR_TSTART_MASK; + __SIRegs[SI_COMCSR_IDX] = reg; } -/* 80344BFC-80344EF8 33F53C 02FC+00 1/1 0/0 0/0 .text CompleteTransfer */ -static u32 CompleteTransfer() { +static u32 CompleteTransfer(void) { u32 sr; u32 i; u32 rLen; u8* input; + u32 temp; - sr = __SIRegs[14]; - + sr = __SIRegs[SI_STATUS_IDX]; SIClearTCInterrupt(); if (Si.chan != -1) { XferTime[Si.chan] = __OSGetSystemTime(); - input = Si.input; - - rLen = Si.inputBytes / 4; + rLen = Si.inputBytes / sizeof(u32); for (i = 0; i < rLen; i++) { - *(u32*)input = __SIRegs[32 + i]; - input += 4; + *((u32*)input)++ = __SIRegs[i+0x20]; } - + rLen = Si.inputBytes & 3; - if (rLen) { - u32 temp = __SIRegs[32 + i]; + if (rLen != 0) { + temp = __SIRegs[i + 32]; for (i = 0; i < rLen; i++) { - *input++ = (u8)((temp >> ((3 - i) * 8)) & 0xff); + *(input++) = temp >> ((3 - i) * 8); } } - if (__SIRegs[13] & 0x20000000) { - sr >>= 8 * (3 - Si.chan); - sr &= 0xf; - - if ((sr & SI_ERROR_NO_RESPONSE) && !(Type[Si.chan] & SI_ERROR_BUSY)) { - Type[Si.chan] = SI_ERROR_NO_RESPONSE; + if (__SIRegs[SI_COMCSR_IDX] & SI_COMCSR_COMERR_MASK) { + sr >>= (3 - Si.chan) * 8; + sr &= 0xF; + if ((sr & 8) != 0 && (Type[Si.chan] & 0x80) == 0) { + Type[Si.chan] = 8; } + if (sr == 0) { - sr = SI_ERROR_COLLISION; + sr = 4; } } else { TypeTime[Si.chan] = __OSGetSystemTime(); @@ -104,126 +101,97 @@ static u32 CompleteTransfer() { Si.chan = -1; } + return sr; } -/* ############################################################################################## */ -/* 8044C790-8044C7D0 0794B0 0040+00 1/1 0/0 0/0 .bss TypeCallback */ -static SITypeAndStatusCallback TypeCallback[SI_MAX_CHAN][4]; - -/* 8044C7D0-8044C7E0 0794F0 0010+00 2/3 0/0 0/0 .bss RDSTHandler */ -static __OSInterruptHandler RDSTHandler[4]; - -/* 8044C7E0-8044C7F0 079500 0010+00 0/0 0/0 0/0 .bss InputBufferValid */ -#pragma push -#pragma force_active on -static BOOL InputBufferValid[SI_MAX_CHAN]; -#pragma pop - -/* 8044C7F0-8044C810 079510 0020+00 0/0 0/0 0/0 .bss InputBuffer */ -#pragma push -#pragma force_active on -static u32 InputBuffer[SI_MAX_CHAN][2]; -#pragma pop - -/* 8044C810-8044C820 079530 0010+00 0/2 0/0 0/0 .bss InputBufferVcount */ -#pragma push -#pragma force_active on -static volatile u32 InputBufferVcount[SI_MAX_CHAN]; -#pragma pop - -inline void SITransferNext(s32 chan) { +static void SITransferNext(s32 chan) { int i; SIPacket* packet; - for (i = 0; i < SI_MAX_CHAN; ++i) { - ++chan; - chan %= SI_MAX_CHAN; + for (i = 0; i < 4; i++) { + chan++; + chan %= 4; packet = &Packet[chan]; - if (packet->chan != -1 && packet->fire <= __OSGetSystemTime()) { - if (__SITransfer(packet->chan, packet->output, packet->outputBytes, packet->input, - packet->inputBytes, packet->callback)) - { - OSCancelAlarm(&Alarm[chan]); - packet->chan = -1; + + if (packet->chan != -1) { + if (packet->fire <= __OSGetSystemTime()) { + if (__SITransfer(packet->chan, packet->output, packet->outputBytes, packet->input, packet->inputBytes, packet->callback) != 0) { + OSCancelAlarm(&Alarm[chan]); + packet->chan = -1; + } + return; } - break; } } } -/* 804516F0-804516F4 000BF0 0004+00 1/1 0/0 0/0 .sbss cmdTypeAndStatus$78 */ -static u8 cmdTypeAndStatus_78[4]; +#define CHAN_NONE -1 -/* 80344EF8-8034523C 33F838 0344+00 1/1 0/0 0/0 .text SIInterruptHandler */ static void SIInterruptHandler(__OSInterrupt interrupt, OSContext* context) { u32 reg; + s32 chan; + u32 sr; + SICallback callback; + int i; + u32 vcount; + u32 x; - reg = __SIRegs[13]; - - if ((reg & 0xc0000000) == 0xc0000000) { - s32 chan; - u32 sr; - SICallback callback; + reg = __SIRegs[SI_COMCSR_IDX]; + if ((reg & (SI_COMCSR_TCINT_MASK | SI_COMCSR_TCINTMSK_MASK)) == (SI_COMCSR_TCINT_MASK | SI_COMCSR_TCINTMSK_MASK)) { + ASSERTLINE(376, Si.chan != CHAN_NONE); chan = Si.chan; sr = CompleteTransfer(); callback = Si.callback; - Si.callback = 0; - + Si.callback = NULL; SITransferNext(chan); if (callback) { callback(chan, sr, context); } - sr = __SIRegs[14]; - sr &= 0xf000000 >> (8 * chan); - __SIRegs[14] = sr; + sr = __SIRegs[SI_STATUS_IDX]; + sr &= 0x0F000000 >> (chan << 3); + __SIRegs[SI_STATUS_IDX] = sr; if (Type[chan] == SI_ERROR_BUSY && !SIIsChanBusy(chan)) { - static u32 cmdTypeAndStatus = 0 << 24; - SITransfer(chan, &cmdTypeAndStatus, 1, &Type[chan], 3, GetTypeCallback, - OSMicrosecondsToTicks(65)); + static u32 cmdTypeAndStatus; + + SITransfer(chan, &cmdTypeAndStatus, 1, &Type[chan], 3, &GetTypeCallback, OSMicrosecondsToTicks(65)); } } - if ((reg & 0x18000000) == 0x18000000) { - int i; - u32 vcount; - u32 x; + if ((reg & (SI_COMCSR_RDSTINT_MASK | SI_COMCSR_RDSTINTMSK_MASK)) == (SI_COMCSR_RDSTINT_MASK | SI_COMCSR_RDSTINTMSK_MASK)) { + vcount = 1 + VIGetCurrentLine(); + x = (Si.poll & (0x3FF << 16)) >> 16; - vcount = VIGetCurrentLine() + 1; - x = (Si.poll & 0x03ff0000) >> 16; - - for (i = 0; i < SI_MAX_CHAN; ++i) { + for (i = 0; i < 4; i++) { if (SIGetResponseRaw(i)) { InputBufferVcount[i] = vcount; } } - for (i = 0; i < SI_MAX_CHAN; ++i) { - if (!(Si.poll & (SI_CHAN0_BIT >> (31 - 7 + i)))) { - continue; - } - if (InputBufferVcount[i] == 0 || InputBufferVcount[i] + (x / 2) < vcount) { - return; + for (i = 0; i < 4; i++) { + if ((Si.poll & (0x80000000 >> (24 + i))) != 0) { + if (InputBufferVcount[i] == 0 || ((x >> 1) + InputBufferVcount[i]) < vcount) { + return; + } } } - for (i = 0; i < SI_MAX_CHAN; ++i) { + for (i = 0; i < 4; i++) { InputBufferVcount[i] = 0; } - for (i = 0; i < 4; ++i) { - if (RDSTHandler[i]) { - RDSTHandler[i](interrupt, context); + for (i = 0; i < 4; i++) { + if (RDSTHandler[i] != 0) { + (*RDSTHandler[i])(interrupt, context); } } } } -/* 8034523C-803452D4 33FB7C 0098+00 2/2 0/0 0/0 .text SIEnablePollingInterrupt */ static BOOL SIEnablePollingInterrupt(BOOL enable) { BOOL enabled; BOOL rc; @@ -231,35 +199,39 @@ static BOOL SIEnablePollingInterrupt(BOOL enable) { int i; enabled = OSDisableInterrupts(); - reg = __SIRegs[13]; - rc = (reg & 0x08000000) ? TRUE : FALSE; + reg = __SIRegs[SI_COMCSR_IDX]; + rc = ((reg & SI_COMCSR_RDSTINTMSK_MASK) != 0) ? TRUE : FALSE; + if (enable) { - reg |= 0x08000000; - for (i = 0; i < SI_MAX_CHAN; ++i) { + reg |= SI_COMCSR_RDSTINTMSK_MASK; + + for (i = 0; i < 4; i++) { InputBufferVcount[i] = 0; } } else { - reg &= ~0x08000000; + reg &= ~SI_COMCSR_RDSTINTMSK_MASK; } - reg &= ~0x80000001; - __SIRegs[13] = reg; + + reg &= ~(SI_COMCSR_TCINT_MASK | SI_COMCSR_TSTART_MASK); + __SIRegs[SI_COMCSR_IDX] = reg; + OSRestoreInterrupts(enabled); return rc; } -/* 803452D4-803453A0 33FC14 00CC+00 0/0 1/1 0/0 .text SIRegisterPollingHandler */ BOOL SIRegisterPollingHandler(__OSInterruptHandler handler) { BOOL enabled; int i; enabled = OSDisableInterrupts(); - for (i = 0; i < 4; ++i) { + for (i = 0; i < 4; i++) { if (RDSTHandler[i] == handler) { OSRestoreInterrupts(enabled); return TRUE; } } - for (i = 0; i < 4; ++i) { + + for (i = 0; i < 4; i++) { if (RDSTHandler[i] == 0) { RDSTHandler[i] = handler; SIEnablePollingInterrupt(TRUE); @@ -267,52 +239,51 @@ BOOL SIRegisterPollingHandler(__OSInterruptHandler handler) { return TRUE; } } + OSRestoreInterrupts(enabled); return FALSE; } -/* 803453A0-80345494 33FCE0 00F4+00 0/0 1/1 0/0 .text SIUnregisterPollingHandler */ BOOL SIUnregisterPollingHandler(__OSInterruptHandler handler) { BOOL enabled; int i; enabled = OSDisableInterrupts(); - for (i = 0; i < 4; ++i) { + for (i = 0; i < 4; i++) { if (RDSTHandler[i] == handler) { RDSTHandler[i] = 0; - for (i = 0; i < 4; ++i) { - if (RDSTHandler[i]) { + + for (i = 0; i < 4; i++) { + if (RDSTHandler[i] != 0) { break; } } + if (i == 4) { SIEnablePollingInterrupt(FALSE); } + OSRestoreInterrupts(enabled); return TRUE; - break; } - } + } + OSRestoreInterrupts(enabled); return FALSE; } -/* 80345494-80345548 33FDD4 00B4+00 0/0 1/1 0/0 .text SIInit */ void SIInit(void) { OSRegisterVersion(__SIVersion); Packet[0].chan = Packet[1].chan = Packet[2].chan = Packet[3].chan = -1; - Si.poll = 0; SISetSamplingRate(0); - while (__SIRegs[13] & 1) - ; + do {} while(__SIRegs[SI_COMCSR_IDX] & SI_COMCSR_TSTART_MASK); - __SIRegs[13] = 0x80000000; - - __OSSetInterruptHandler(OS_INTR_PI_SI, SIInterruptHandler); - __OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_SI); + __SIRegs[SI_COMCSR_IDX] = SI_COMCSR_TCINT_MASK; + __OSSetInterruptHandler(0x14, SIInterruptHandler); + __OSUnmaskInterrupts(0x800); SIGetType(0); SIGetType(1); @@ -320,27 +291,44 @@ void SIInit(void) { SIGetType(3); } -#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) - -/* 80345548-80345754 33FE88 020C+00 3/3 0/0 0/0 .text __SITransfer */ -static BOOL __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, - SICallback callback) { +static int __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, SICallback callback) { BOOL enabled; u32 rLen; u32 i; u32 sr; - SIComm_u comcsr; + union { + u32 val; + struct { + u32 tcint : 1; + u32 tcintmsk : 1; + u32 comerr : 1; + u32 rdstint : 1; + u32 rdstintmsk : 1; + u32 pad2 : 4; + u32 outlngth : 7; + u32 pad1 : 1; + u32 inlngth : 7; + u32 pad0 : 5; + u32 channel : 2; + u32 tstart : 1; + } f; + } comcsr; + + ASSERTMSGLINE(627, (chan >= 0) && (chan < 4), "SITransfer(): invalid channel."); + ASSERTMSGLINE(629, (outputBytes != 0) && (outputBytes <= 128), "SITransfer(): output size is out of range (must be 1 to 128)."); + ASSERTMSGLINE(631, (inputBytes != 0) && (inputBytes <= 128), "SITransfer(): input size is out of range (must be 1 to 128)."); enabled = OSDisableInterrupts(); if (Si.chan != -1) { OSRestoreInterrupts(enabled); - return FALSE; + return 0; } - sr = __SIRegs[14]; - sr &= (0xf000000) >> (8 * chan); - __SIRegs[14] = sr; - + ASSERTLINE(641, (__SIRegs[SI_COMCSR_IDX] & (SI_COMCSR_TSTART_MASK | SI_COMCSR_TCINT_MASK)) == 0); + sr = __SIRegs[SI_STATUS_IDX]; + sr &= (0x0F000000 >> (chan* 8)); + __SIRegs[SI_STATUS_IDX] = sr; + Si.chan = chan; Si.callback = callback; Si.inputBytes = inputBytes; @@ -348,181 +336,192 @@ static BOOL __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u rLen = ROUND(outputBytes, 4) / 4; for (i = 0; i < rLen; i++) { - __SIRegs[32 + i] = ((u32*)output)[i]; + __SIRegs[i + 0x20] = ((u32*)output)[i]; } - - comcsr.val = __SIRegs[13]; + + comcsr.val = __SIRegs[SI_COMCSR_IDX]; comcsr.f.tcint = 1; comcsr.f.tcintmsk = callback ? 1 : 0; - comcsr.f.outlngth = (outputBytes == SI_MAX_COMCSR_OUTLNGTH) ? 0 : outputBytes; - comcsr.f.inlngth = (inputBytes == SI_MAX_COMCSR_INLNGTH) ? 0 : inputBytes; + comcsr.f.outlngth = outputBytes == 0x80 ? 0 : outputBytes; + comcsr.f.inlngth = inputBytes == 0x80 ? 0 : inputBytes; comcsr.f.channel = chan; comcsr.f.tstart = 1; - __SIRegs[13] = comcsr.val; + __SIRegs[SI_COMCSR_IDX] = comcsr.val; OSRestoreInterrupts(enabled); - - return TRUE; + return 1; +} + +u32 SISync(void) { + BOOL enabled; + u32 sr; + + do {} while(__SIRegs[SI_COMCSR_IDX] & SI_COMCSR_TSTART_MASK); + + enabled = OSDisableInterrupts(); + sr = CompleteTransfer(); + SITransferNext(4); + OSRestoreInterrupts(enabled); + return sr; } -/* 80345754-803457D0 340094 007C+00 1/1 1/1 0/0 .text SIGetStatus */ u32 SIGetStatus(s32 chan) { BOOL enabled; u32 sr; int chanShift; enabled = OSDisableInterrupts(); - sr = __SIRegs[14]; - chanShift = 8 * (SI_MAX_CHAN - 1 - chan); + sr = __SIRegs[SI_STATUS_IDX]; + chanShift = (3 - chan) * 8; sr >>= chanShift; - if (sr & SI_ERROR_NO_RESPONSE) { - if (!(Type[chan] & SI_ERROR_BUSY)) { - Type[chan] = SI_ERROR_NO_RESPONSE; + + if ((sr & 8) != 0) { + if ((Type[chan] & SI_ERROR_BUSY) == 0) { + Type[chan] = 8; } } + OSRestoreInterrupts(enabled); return sr; } -/* 803457D0-803457E4 340110 0014+00 0/0 4/4 0/0 .text SISetCommand */ void SISetCommand(s32 chan, u32 command) { - __SIRegs[3 * chan] = command; + ASSERTMSGLINE(752, (chan >= 0) && (chan < 4), "SISetCommand(): invalid channel."); + __SIRegs[chan* 3] = command; +} + +u32 SIGetCommand(s32 chan) { + ASSERTMSGLINE(770, (chan >= 0) && (chan < 4), "SIGetCommand(): invalid channel."); + return __SIRegs[chan* 3]; } -/* 803457E4-803457F4 340124 0010+00 0/0 1/1 0/0 .text SITransferCommands */ void SITransferCommands(void) { - __SIRegs[14] = 0x80000000; + __SIRegs[SI_STATUS_IDX] = SI_COMCSR_TCINT_MASK; } -/* 803457F4-80345860 340134 006C+00 0/0 1/1 0/0 .text SISetXY */ -// needs compiler epilogue patch u32 SISetXY(u32 x, u32 y) { u32 poll; BOOL enabled; - poll = x << 16; - poll |= y << 8; + ASSERTMSGLINE(803, x >= 8, "SISetXY(): x is out of range (8 <= x <= 1023)."); + ASSERTMSGLINE(804, x <= 1023, "SISetXY(): x is out of range (8 <= x <= 1023)."); + ASSERTMSGLINE(805, y <= 255, "SISetXY(): y is out of range (0 <= y <= 255)."); + poll = x << 0x10; + poll |= y << 8; enabled = OSDisableInterrupts(); - Si.poll &= ~(0x03ff0000 | 0x0000ff00); + Si.poll &= 0xFC0000FF; Si.poll |= poll; poll = Si.poll; - __SIRegs[12] = poll; + __SIRegs[0x30 / 4] = poll; OSRestoreInterrupts(enabled); return poll; } -/* 80345860-803458FC 3401A0 009C+00 0/0 3/3 0/0 .text SIEnablePolling */ u32 SIEnablePolling(u32 poll) { BOOL enabled; u32 en; + ASSERTMSGLINE(834, (poll & 0x0FFFFFFF) == 0, "SIEnablePolling(): invalid chan bit(s)."); if (poll == 0) { return Si.poll; } - + enabled = OSDisableInterrupts(); - - poll >>= (31 - 7); - en = poll & 0xf0; - - poll &= (en >> 4) | 0x03fffff0; - - poll &= ~0x03ffff00; - + poll = poll >> 24; + en = poll & 0xF0; + ASSERTLINE(865, en); + poll &= ((en >> 4) | 0x03FFFFF0); + poll &= 0xFC0000FF; + Si.poll &= ~(en >> 4); - Si.poll |= poll; - poll = Si.poll; - SITransferCommands(); - - __SIRegs[12] = poll; - + __SIRegs[0x30 / 4] = poll; OSRestoreInterrupts(enabled); - return poll; } -/* 803458FC-80345968 34023C 006C+00 0/0 6/6 0/0 .text SIDisablePolling */ u32 SIDisablePolling(u32 poll) { BOOL enabled; + ASSERTMSGLINE(908, (poll & 0x0FFFFFFF) == 0, "SIDisablePolling(): invalid chan bit(s)."); if (poll == 0) { return Si.poll; } enabled = OSDisableInterrupts(); - - poll >>= (31 - 7); - poll &= 0xf0; - + poll = poll >> 24; + poll &= 0xF0; + ASSERTLINE(921, poll); poll = Si.poll & ~poll; - - __SIRegs[12] = poll; + __SIRegs[0x30 / 4] = poll; Si.poll = poll; - OSRestoreInterrupts(enabled); return poll; } -/* 80345968-80345A3C 3402A8 00D4+00 1/1 0/0 0/0 .text SIGetResponseRaw */ static BOOL SIGetResponseRaw(s32 chan) { u32 sr; sr = SIGetStatus(chan); - if (sr & SI_ERROR_RDST) { - InputBuffer[chan][0] = __SIRegs[3 * chan + 1]; - InputBuffer[chan][1] = __SIRegs[3 * chan + 2]; + if (sr & 0x20) { + InputBuffer[chan][0] = __SIRegs[1 + chan * 3]; + InputBuffer[chan][1] = __SIRegs[2 + chan * 3]; InputBufferValid[chan] = TRUE; return TRUE; } + return FALSE; } -/* 80345A3C-80345B00 34037C 00C4+00 0/0 4/4 0/0 .text SIGetResponse */ BOOL SIGetResponse(s32 chan, void* data) { BOOL rc; BOOL enabled; + ASSERTMSGLINE(971, ((chan >= 0) && (chan < 4)), "SIGetResponse(): invalid channel."); enabled = OSDisableInterrupts(); SIGetResponseRaw(chan); rc = InputBufferValid[chan]; InputBufferValid[chan] = FALSE; + if (rc) { ((u32*)data)[0] = InputBuffer[chan][0]; ((u32*)data)[1] = InputBuffer[chan][1]; } + OSRestoreInterrupts(enabled); return rc; } -/* 80345B00-80345B8C 340440 008C+00 1/1 0/0 0/0 .text AlarmHandler */ static void AlarmHandler(OSAlarm* alarm, OSContext* context) { s32 chan; SIPacket* packet; - chan = alarm - Alarm; + chan = (s32)(alarm - Alarm); + ASSERTLINE(1002, 0 <= chan && chan < SI_MAX_CHAN); + packet = &Packet[chan]; if (packet->chan != -1) { - if (__SITransfer(packet->chan, packet->output, packet->outputBytes, packet->input, - packet->inputBytes, packet->callback)) - { + ASSERTLINE(1006, packet->fire <= __OSGetSystemTime()); + + if (__SITransfer(packet->chan, packet->output, packet->outputBytes, packet->input, packet->inputBytes, packet->callback)) { packet->chan = -1; } } } -/* 80345B8C-80345CF8 3404CC 016C+00 3/3 3/3 0/0 .text SITransfer */ -BOOL SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, +BOOL SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, SICallback callback, OSTime delay) { BOOL enabled; - SIPacket* packet = &Packet[chan]; + SIPacket* packet; OSTime now; OSTime fire; + packet = &Packet[chan]; enabled = OSDisableInterrupts(); + if (packet->chan != -1 || Si.chan == chan) { OSRestoreInterrupts(enabled); return FALSE; @@ -532,8 +531,9 @@ BOOL SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputB if (delay == 0) { fire = now; } else { - fire = XferTime[chan] + delay; + fire = delay + XferTime[chan]; } + if (now < fire) { delay = fire - now; OSSetAlarm(&Alarm[chan], delay, AlarmHandler); @@ -549,100 +549,89 @@ BOOL SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputB packet->inputBytes = inputBytes; packet->callback = callback; packet->fire = fire; - OSRestoreInterrupts(enabled); return TRUE; } -/* ############################################################################################## */ -/* 804516F4-804516F8 000BF4 0004+00 1/1 0/0 0/0 .sbss cmdTypeAndStatus$372 */ -static u8 cmdTypeAndStatus_372[4]; - -/* 804516F8-80451700 000BF8 0004+04 1/1 1/1 0/0 .sbss __PADFixBits */ -extern u32 __PADFixBits; -u32 __PADFixBits; - -static inline void CallTypeAndStatusCallback(s32 chan, u32 type) { - SITypeAndStatusCallback callback; +static void CallTypeAndStatusCallback(s32 chan, u32 type) { + SITypeCallback callback; int i; - for (i = 0; i < 4; ++i) { + for (i = 0; i < 4; i++) { callback = TypeCallback[chan][i]; - if (callback) { + + if (callback != 0) { TypeCallback[chan][i] = 0; - callback(chan, type); + (*callback)(chan, type); } } } -/* 80345CF8-80345F90 340638 0298+00 2/2 0/0 0/0 .text GetTypeCallback */ static void GetTypeCallback(s32 chan, u32 error, OSContext* context) { - static u32 cmdFixDevice[SI_MAX_CHAN]; u32 type; u32 chanBit; - BOOL fix; + int fix; u32 id; - + + ASSERTLINE(1137, 0 <= chan && chan < SI_MAX_CHAN); + + ASSERTLINE(1139, (Type[chan] & 0xff) == SI_ERROR_BUSY); Type[chan] &= ~SI_ERROR_BUSY; Type[chan] |= error; TypeTime[chan] = __OSGetSystemTime(); type = Type[chan]; - - chanBit = SI_CHAN0_BIT >> chan; - fix = (BOOL)(__PADFixBits & chanBit); + chanBit = 0x80000000 >> chan; + fix = __PADFixBits & chanBit; __PADFixBits &= ~chanBit; - if ((error & - (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION)) || - (type & SI_TYPE_MASK) != SI_TYPE_DOLPHIN || !(type & SI_GC_WIRELESS) || - (type & SI_WIRELESS_IR)) - { + if ((error & 0xF) != 0 || (type & 0x18000000) != 0x08000000 || (type & 0x80000000) == 0 || (type & 0x04000000) != 0) { OSSetWirelessID(chan, 0); CallTypeAndStatusCallback(chan, Type[chan]); - return; - } + } else { + static u32 cmdFixDevice[4]; - id = (u32)(OSGetWirelessID(chan) << 8); - - if (fix && (id & SI_WIRELESS_FIX_ID)) { - cmdFixDevice[chan] = 0x4Eu << 24 | (id & SI_WIRELESS_TYPE_ID) | SI_WIRELESS_FIX_ID; - Type[chan] = SI_ERROR_BUSY; - SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, GetTypeCallback, 0); - return; - } - - if (type & SI_WIRELESS_FIX_ID) { - if ((id & SI_WIRELESS_TYPE_ID) != (type & SI_WIRELESS_TYPE_ID)) { - if (!(id & SI_WIRELESS_FIX_ID)) { - id = type & SI_WIRELESS_TYPE_ID; - id |= SI_WIRELESS_FIX_ID; - OSSetWirelessID(chan, (u16)((id >> 8) & 0xffff)); - } - - cmdFixDevice[chan] = 0x4E << 24 | id; + id = OSGetWirelessID(chan) << 8; + + if (fix != 0 && (id & 0x100000) != 0) { + cmdFixDevice[chan] = 0x4E000000 | (id & 0xCFFF00) | 0x100000; Type[chan] = SI_ERROR_BUSY; - SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, GetTypeCallback, 0); + SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, &GetTypeCallback, 0); return; } - } else if (type & SI_WIRELESS_RECEIVED) { - id = type & SI_WIRELESS_TYPE_ID; - id |= SI_WIRELESS_FIX_ID; - OSSetWirelessID(chan, (u16)((id >> 8) & 0xffff)); + if ((type & 0x00100000) != 0) { + if ((id & 0xCFFF00) != (type & 0xCFFF00)) { + if ((id & 0x100000) == 0) { + id = type & 0xCFFF00; + id |= 0x100000; + OSSetWirelessID(chan, id >> 8); + } - cmdFixDevice[chan] = 0x4E << 24 | id; - Type[chan] = SI_ERROR_BUSY; - SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, GetTypeCallback, 0); - return; - } else { - OSSetWirelessID(chan, 0); + cmdFixDevice[chan] = 0x4E000000 | id; + Type[chan] = SI_ERROR_BUSY; + SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, &GetTypeCallback, 0); + return; + } + } else { + if ((type & 0x40000000) != 0) { + id = type & 0xCFFF00; + id |= 0x100000; + OSSetWirelessID(chan, id >> 8); + + cmdFixDevice[chan] = 0x4E000000 | id; + Type[chan] = SI_ERROR_BUSY; + SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, &GetTypeCallback, 0); + return; + } + + OSSetWirelessID(chan, 0); + } + + CallTypeAndStatusCallback(chan, Type[chan]); } - - CallTypeAndStatusCallback(chan, Type[chan]); } -/* 80345F90-80346154 3408D0 01C4+00 2/2 3/3 0/0 .text SIGetType */ u32 SIGetType(s32 chan) { static u32 cmdTypeAndStatus; BOOL enabled; @@ -650,64 +639,138 @@ u32 SIGetType(s32 chan) { OSTime diff; enabled = OSDisableInterrupts(); - + ASSERTLINE(1243, 0 <= chan && chan < SI_MAX_CHAN); type = Type[chan]; diff = __OSGetSystemTime() - TypeTime[chan]; - if (Si.poll & (0x80 >> chan)) { - if (type != SI_ERROR_NO_RESPONSE) { + if ((Si.poll & (0x80 >> chan)) != 0) { + if (type != 8) { TypeTime[chan] = __OSGetSystemTime(); OSRestoreInterrupts(enabled); return type; + } + + type = Type[chan] = SI_ERROR_BUSY; + } else { + if (diff <= OSMillisecondsToTicks(50) && type != 8) { + OSRestoreInterrupts(enabled); + return type; + } + + if (diff <= OSMillisecondsToTicks(75)) { + Type[chan] = SI_ERROR_BUSY; } else { type = Type[chan] = SI_ERROR_BUSY; } - } else if (diff <= OSMillisecondsToTicks(50) && type != SI_ERROR_NO_RESPONSE) { - OSRestoreInterrupts(enabled); - return type; - } else if (diff <= OSMillisecondsToTicks(75)) { - Type[chan] = SI_ERROR_BUSY; - } else { - type = Type[chan] = SI_ERROR_BUSY; } + TypeTime[chan] = __OSGetSystemTime(); - - SITransfer(chan, &cmdTypeAndStatus, 1, &Type[chan], 3, GetTypeCallback, - OSMicrosecondsToTicks(65)); - + SITransfer(chan, &cmdTypeAndStatus, 1, &Type[chan], 3, &GetTypeCallback, OSMicrosecondsToTicks(65)); OSRestoreInterrupts(enabled); return type; } -/* 80346154-80346290 340A94 013C+00 0/0 6/6 0/0 .text SIGetTypeAsync */ -u32 SIGetTypeAsync(s32 chan, SITypeAndStatusCallback callback) { +u32 SIGetTypeAsync(s32 chan, SITypeCallback callback) { BOOL enabled; u32 type; + int i; enabled = OSDisableInterrupts(); type = SIGetType(chan); - if (Type[chan] & SI_ERROR_BUSY) { - int i; - for (i = 0; i < 4; ++i) { + if ((Type[chan] & SI_ERROR_BUSY) != 0) { + for (i = 0; i < SI_MAX_TYPE; i++) { if (TypeCallback[chan][i] == callback) { break; } + if (TypeCallback[chan][i] == 0) { TypeCallback[chan][i] = callback; break; } } + + ASSERTLINE(1324, i < SI_MAX_TYPE); } else { - callback(chan, type); + (*callback)(chan, type); } + OSRestoreInterrupts(enabled); return type; } +u32 SIDecodeType(u32 type) { + u32 error; + + error = type & 0xFF; + type &= ~0xFF; + + if (error & SI_ERROR_NO_RESPONSE) { + return SI_ERROR_NO_RESPONSE; + } + + if (error & (SI_ERROR_UNKNOWN | SI_ERROR_COLLISION | SI_ERROR_OVER_RUN | SI_ERROR_UNDER_RUN)) { + return SI_ERROR_UNKNOWN; + } + + if (error != 0) { + ASSERTLINE(1371, error == SI_ERROR_BUSY); + return SI_ERROR_BUSY; + } + + if ((type & SI_TYPE_MASK) == SI_TYPE_N64) { + switch (type & 0xFFFF0000) { + case SI_N64_MIC: + case SI_N64_KEYBOARD: + case SI_GBA: + case SI_N64_MOUSE: + case SI_N64_CONTROLLER: + return type & 0xFFFF0000; + default: + return SI_ERROR_UNKNOWN; + } + } + + if ((type & SI_TYPE_MASK) != SI_TYPE_DOLPHIN) { + return SI_ERROR_UNKNOWN; + } + + switch (type & 0xFFFF0000) { + case SI_GC_STEERING: + case SI_GC_CONTROLLER: + return type & 0xFFFF0000; + } + + if ((type & 0xFFE00000) == SI_GC_KEYBOARD) { + return SI_GC_KEYBOARD; + } + + if ((type & SI_GC_WIRELESS) != 0 && (type & SI_WIRELESS_IR) == 0) { + if ((type & SI_GC_WAVEBIRD) == SI_GC_WAVEBIRD) { + return SI_GC_WAVEBIRD; + } + + if ((type & SI_WIRELESS_STATE) == 0) { + return SI_GC_RECEIVER; + } + } + + if ((type & SI_GC_CONTROLLER) == SI_GC_CONTROLLER) { + return SI_GC_CONTROLLER; + } + + return SI_ERROR_UNKNOWN; +} + +u32 SIProbe(s32 chan) { + return SIDecodeType(SIGetType(chan)); +} + char* SIGetTypeString(u32 type) { switch (SIDecodeType(type)) { case SI_ERROR_NO_RESPONSE: return "No response"; + case SI_ERROR_BUSY: + return "Busy"; case SI_N64_CONTROLLER: return "N64 controller"; case SI_N64_MIC: @@ -728,5 +791,8 @@ char* SIGetTypeString(u32 type) { return "Keyboard"; case SI_GC_STEERING: return "Steering"; + case SI_ERROR_UNKNOWN: + default: + return "Unknown"; } -} \ No newline at end of file +} diff --git a/src/dolphin/si/SISamplingRate.c b/src/dolphin/si/SISamplingRate.c index d3d1ae25e7..b1a6f60f8c 100644 --- a/src/dolphin/si/SISamplingRate.c +++ b/src/dolphin/si/SISamplingRate.c @@ -1,39 +1,57 @@ -#include "dolphin/si/SISamplingRate.h" -#include "dolphin/os.h" -#include "dolphin/vi.h" +#include +#include -u32 VIGetTvFormat(); +#include "__os.h" + +#define LATENCY 8 + +static u32 SamplingRate = 0; + +typedef struct XY { + u16 line; + u8 count; +} XY; -/* ############################################################################################## */ -/* 803D12D0-803D1300 02E3F0 0030+00 1/1 0/0 0/0 .data XYNTSC */ static XY XYNTSC[12] = { - {263 - 17, 2}, {14, 19}, {30, 9}, {44, 6}, {52, 5}, {65, 4}, - {87, 3}, {87, 3}, {87, 3}, {131, 2}, {131, 2}, {131, 2}, + {0x00F6, 0x02}, + {0x000E, 0x13}, + {0x001E, 0x09}, + {0x002C, 0x06}, + {0x0034, 0x05}, + {0x0041, 0x04}, + {0x0057, 0x03}, + {0x0057, 0x03}, + {0x0057, 0x03}, + {0x0083, 0x02}, + {0x0083, 0x02}, + {0x0083, 0x02}, }; -/* 803D1300-803D1330 02E420 0030+00 0/1 0/0 0/0 .data XYPAL */ -#pragma push -#pragma force_active on static XY XYPAL[12] = { - {313 - 17, 2}, {15, 21}, {29, 11}, {45, 7}, {52, 6}, {63, 5}, - {78, 4}, {104, 3}, {104, 3}, {104, 3}, {104, 3}, {156, 2}, + {0x0128, 0x02}, + {0x000F, 0x15}, + {0x001D, 0x0B}, + {0x002D, 0x07}, + {0x0034, 0x06}, + {0x003F, 0x05}, + {0x004E, 0x04}, + {0x0068, 0x03}, + {0x0068, 0x03}, + {0x0068, 0x03}, + {0x0068, 0x03}, + {0x009C, 0x02}, }; -#pragma pop -/* 80451700-80451708 000C00 0004+04 2/2 0/0 0/0 .sbss SamplingRate */ -static u32 SamplingRate; - -/* 80346290-80346374 340BD0 00E4+00 1/1 1/1 0/0 .text SISetSamplingRate */ void SISetSamplingRate(u32 msec) { XY* xy; + BOOL progressive; BOOL enabled; + ASSERTMSGLINE(377, 0 <= msec && msec <= 11, "SISetSamplingRate(): out of rage (0 <= msec <= 11)"); if (msec > 11) { msec = 11; } - enabled = OSDisableInterrupts(); - SamplingRate = msec; switch (VIGetTvFormat()) { @@ -52,11 +70,56 @@ void SISetSamplingRate(u32 msec) { break; } - SISetXY((__VIRegs[54] & 1 ? 2u : 1u) * xy[msec].line, xy[msec].count); + progressive = __VIRegs[VI_CLOCK_SEL] & 1; + SISetXY((progressive ? 2 : 1) * xy[msec].line, xy[msec].count); OSRestoreInterrupts(enabled); } -/* 80346374-80346398 340CB4 0024+00 0/0 2/2 0/0 .text SIRefreshSamplingRate */ -void SIRefreshSamplingRate() { +void SIRefreshSamplingRate(void) { SISetSamplingRate(SamplingRate); -} \ No newline at end of file +} + +#if DEBUG +void __SITestSamplingRate(u32 tvmode) { + u32 msec; + u32 line; + u32 count; + XY* xy; + + switch (tvmode) { + case VI_NTSC: + case VI_MPAL: + xy = XYNTSC; + for (msec = 0; msec <= 11; msec++) { + line = xy[msec].line; + count = xy[msec].count; + OSReport("%2d[msec]: count %3d, line %3d, last %3d, diff0 %2d.%03d, diff1 %2d.%03d\n", + msec, count, line, line * (count - 1) + LATENCY, (line * 636) / 10000, (line * 636) % 10000, + ((263 - line * (count - 1)) * 636) / 10000, ((263 - line * (count - 1)) * 636) % 10000); + ASSERTLINE(446, line * (count - 1) + LATENCY < 263); + + if (msec != 0) { + ASSERTLINE(449, 636 * line < msec * 10000); + ASSERTLINE(450, 636 * (263 - line * (count - 1)) < msec * 10000); + } + } + break; + case VI_PAL: + xy = XYPAL; + for (msec = 0; msec <= 11; msec++) { + line = xy[msec].line; + count = xy[msec].count; + OSReport("%2d[msec]: count %3d, line %3d, last %3d, diff0 %2d.%03d, diff1 %2d.%03d\n", + msec, count, line, line * (count - 1) + LATENCY, (line * 640) / 10000, (line * 640) % 10000, + ((313 - line * (count - 1)) * 640) / 10000, ((313 - line * (count - 1)) * 640) % 10000); + ASSERTLINE(470, line * (count - 1) + LATENCY < 313); + + if (msec != 0) { + ASSERTLINE(473, 640 * line < msec * 10000); + ASSERTLINE(474, 640 * (313 - line * (count - 1)) < msec * 10000); + } + } + break; + } +} +#endif diff --git a/src/dolphin/si/SISteering.c b/src/dolphin/si/SISteering.c new file mode 100644 index 0000000000..c0d6c66b55 --- /dev/null +++ b/src/dolphin/si/SISteering.c @@ -0,0 +1,120 @@ +#include +#include + +#include "__si.h" + +// prototypes +static void DefaultCallback(s32, s32); +static s32 SISteeringBegin(SISteeringControl* sc, SISteeringCallback callback); +static void ResetProc(s32 chan); +static int OnReset(BOOL final); + +SISteeringControl __SISteering[4]; +BOOL __SIResetSteering; + +static OSResetFunctionInfo ResetFunctionInfo = {OnReset, 127}; + +void SIInitSteering(void) { + static BOOL initialized; + SISteeringControl* sc; + s32 chan; + + if (!initialized) { + initialized = TRUE; + + for (chan = 0; chan < 4; chan++) { + sc = &__SISteering[chan]; + sc->ret = 0; + OSInitThreadQueue(&sc->threadQueue); + } + + SIRefreshSamplingRate(); + __SIResetSteering = 0; + OSRegisterResetFunction(&ResetFunctionInfo); + } +} + +static void DefaultCallback(s32, s32) {} + +static s32 SISteeringBegin(SISteeringControl* sc, SISteeringCallback callback) { + BOOL enabled; + s32 ret; + + callback = callback != 0 ? callback : DefaultCallback; + + enabled = OSDisableInterrupts(); + if (sc->callback) { + ret = -2; + } else { + sc->callback = callback; + ret = 0; + } + + OSRestoreInterrupts(enabled); + return ret; +} + +static void ResetProc(s32 chan) { + SISteeringControl* sc = &__SISteering[chan]; + + if (sc->ret == 0 && __SIResetSteering == 0) { + __SISteeringEnable(chan); + } +} + +s32 SIResetSteeringAsync(s32 chan, SISteeringCallback callback) { + SISteeringControl* sc; + s32 ret; + + sc = &__SISteering[chan]; + ret = SISteeringBegin(sc, callback); + if (ret != 0) { + return ret; + } + + sc->output[0] = 0xFF; + return __SISteeringTransfer(chan, 1, 3, ResetProc); +} + +s32 SIResetSteering(s32 chan) { + SISteeringControl* sc; + s32 ret; + +#ifndef DEBUG + u32 padding; +#endif + + sc = &__SISteering[chan]; + ret = SIResetSteeringAsync(chan, __SISteeringSyncCallback); + if (ret != 0) { + return ret; + } + + return __SISteeringSync(chan); +} + +static int OnReset(BOOL final) { + static s32 count; + s32 chan; + + if (!__SIResetSteering) { + __SIResetSteering = TRUE; + + for (chan = 0; chan < 4; chan++) { + if ((0x80000000 >> chan) & __SISteeringEnableBits) { + SIControlSteering(chan, 0x400, 0); + } + } + + count = VIGetRetraceCount(); + } + + if ((s32)VIGetRetraceCount() - count > 2) { + while (__SISteeringEnableBits != 0) { + __SISteeringDisable(__cntlzw(__SISteeringEnableBits)); + } + return 1; + } + + return 0; +} diff --git a/src/dolphin/si/SISteeringAuto.c b/src/dolphin/si/SISteeringAuto.c new file mode 100644 index 0000000000..b8e23e97fd --- /dev/null +++ b/src/dolphin/si/SISteeringAuto.c @@ -0,0 +1,130 @@ +#include +#include + +static void (*SamplingCallback)(); +u32 __SISteeringEnableBits; + +void __SISteeringEnable(s32 chan) { + u32 cmd; + u32 chanBit; + u32 data[2]; + + chanBit = 0x80000000 >> chan; + if (!(__SISteeringEnableBits & chanBit)) { + __SISteeringEnableBits |= chanBit; + SIGetResponse(chan, &data); + + cmd = 0x300680; + SISetCommand(chan, cmd); + SIEnablePolling(__SISteeringEnableBits); + } +} + +void __SISteeringDisable(s32 chan) { + u32 chanBit; + + chanBit = 0x80000000 >> chan; + SIDisablePolling(chanBit); + __SISteeringEnableBits &= ~chanBit; +} + +s32 SIReadSteering(s32 chan, SISteeringStatus* status) { + BOOL enabled; + SISteeringControl* sc; + u32 data[2]; + u32 chanBit; + u32 sr; + s32 ret; + + enabled = OSDisableInterrupts(); + sc = &__SISteering[chan]; + chanBit = 0x80000000 >> chan; + + if (SIIsChanBusy(chan)) { + sc->ret = -2; + } else if (!(__SISteeringEnableBits & chanBit)) { + sc->ret = -1; + } else { + sr = SIGetStatus(chan); + if (sr & 8) { + SIGetResponse(chan, &data); + __SISteeringDisable(chan); + sc->ret = -1; + } else if ((SIGetResponse(chan, &data) == 0) || (data[0] & 0x80000000)) { + sc->ret = -3; + } else { + sc->ret = 0; + if (status != 0) { + status->button = data[0] >> 0x10; + status->misc = data[0] >> 8; + status->steering = (data[0] & 0xFF) - 0x80; + status->gas = data[1] >> 0x18; + status->brake = data[1] >> 0x10; + status->left = data[1] >> 8; + status->right = data[1]; + } + } + } + + if (status != 0) { + status->err = sc->ret; + } + + ret = sc->ret; + OSRestoreInterrupts(enabled); + return ret; +} + +static void SamplingHandler(__OSInterrupt interrupt, OSContext* context) { + OSContext exceptionContext; + + if (SamplingCallback != 0) { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + SamplingCallback(); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } +} + +void (* SISetSteeringSamplingCallback(void (*callback)()))() { + void (*prev)() = SamplingCallback; + SamplingCallback = callback; + + if (callback != 0) { + SIRegisterPollingHandler(SamplingHandler); + } else { + SIUnregisterPollingHandler(SamplingHandler); + } + + return prev; +} + +void SIControlSteering(s32 chan, u32 control, s32 level) { + BOOL enabled; + u32 chanBit; + u32 command; + + control &= 0x600; + + if (level <= -0x80) { + command = 0; + } else if (level >= 0x80) { + command = 0x100; + } else { + command = level + 0x80; + } + + command |= control; + command &= 0x7FF; + + enabled = OSDisableInterrupts(); + chanBit = 0x80000000 >> chan; + if (__SISteeringEnableBits & chanBit) { + command |= 0x300000; + SISetCommand(chan, command); + SITransferCommands(); + } + + OSRestoreInterrupts(enabled); +} diff --git a/src/dolphin/si/SISteeringXfer.c b/src/dolphin/si/SISteeringXfer.c new file mode 100644 index 0000000000..3bb8abdb89 --- /dev/null +++ b/src/dolphin/si/SISteeringXfer.c @@ -0,0 +1,118 @@ +#include +#include + +#include "__os.h" + +static void __SISteeringHandler(s32 chan, u32 error, OSContext* context) { + SISteeringControl* sc; + void (*proc)(s32); + SISteeringCallback callback; + OSContext exceptionContext; + + sc = &__SISteering[chan]; + if (!__SIResetSteering) { + if (error & 8) { + sc->ret = -1; + } else if (error & 7) { + sc->ret = -3; + } else { + sc->ret = 0; + } + + if (sc->proc != 0) { + proc = sc->proc; + sc->proc = NULL; + proc(chan); + } + + if (sc->callback != 0) { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + callback = sc->callback; + sc->callback = NULL; + callback(chan, sc->ret); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } + } +} + +void __SISteeringSyncCallback(s32 chan) { + SISteeringControl* sc; + + sc = &__SISteering[chan]; + OSWakeupThread(&sc->threadQueue); +} + +s32 __SISteeringSync(s32 chan) { + SISteeringControl* sc; + s32 ret; + BOOL enabled; + + sc = &__SISteering[chan]; + enabled = OSDisableInterrupts(); + + while (sc->callback != 0) { + OSSleepThread(&sc->threadQueue); + } + + ret = sc->ret; + OSRestoreInterrupts(enabled); + return ret; +} + +static void TypeAndStatusCallback(s32 chan, u32 type) { + SISteeringControl* sc; + void (*proc)(s32); + SISteeringCallback callback; + OSContext exceptionContext; + OSContext* context; + + sc = &__SISteering[chan]; + if (!__SIResetSteering) { + ASSERTLINE(127, !(type & SI_ERROR_BUSY)); + + if ((u32)((type & 0xFFFF0000) + 0xF8000000) == 0) { + if (SITransfer(chan, sc, sc->outputBytes, sc->input, sc->inputBytes, __SISteeringHandler, 0)) { + return; + } + sc->ret = -2; + } else { + sc->ret = -1; + } + + if (sc->proc != 0) { + proc = sc->proc; + sc->proc = NULL; + proc(chan); + } + + if (sc->callback != 0) { + context = OSGetCurrentContext(); + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + callback = sc->callback; + sc->callback = NULL; + callback(chan, sc->ret); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + __OSReschedule(); + } + } +} + +s32 __SISteeringTransfer(s32 chan, u32 outputBytes, u32 inputBytes, void (*proc)(s32)) { + BOOL enabled; + SISteeringControl* sc; + + sc = &__SISteering[chan]; + enabled = OSDisableInterrupts(); + + sc->proc = proc; + sc->outputBytes = outputBytes; + sc->inputBytes = inputBytes; + SIGetTypeAsync(chan, &TypeAndStatusCallback); + + OSRestoreInterrupts(enabled); + return 0; +} diff --git a/src/dolphin/si/__si.h b/src/dolphin/si/__si.h new file mode 100644 index 0000000000..d609f90762 --- /dev/null +++ b/src/dolphin/si/__si.h @@ -0,0 +1,21 @@ +#ifndef _DOLPHIN_SI_INTERNAL_H_ +#define _DOLPHIN_SI_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void __SISteeringEnable(s32 chan); +s32 __SISteeringTransfer(s32 chan, u32 outputBytes, u32 inputBytes, void (*proc)(s32)); +void __SISteeringSyncCallback(s32 chan, s32); +s32 __SISteeringSync(s32 chan); +void __SISteeringDisable(s32 chan); +void __SITestSamplingRate(u32 tvmode); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dolphin/sp/sp.c b/src/dolphin/sp/sp.c new file mode 100644 index 0000000000..b934423b2b --- /dev/null +++ b/src/dolphin/sp/sp.c @@ -0,0 +1,404 @@ +#include +#include + +void SPInitSoundTable(SPSoundTable* table, u32 aramBase, u32 zeroBase) { + int i; + SPSoundEntry* sound; + SPADPCM* adpcm; + u32 aramBase4, aramBase8, aramBase16; + u32 zeroBase4, zeroBase8, zeroBase16; + + ASSERTLINE(34, table); + + aramBase4 = aramBase << 1; + zeroBase4 = (zeroBase << 1) + 2; + aramBase8 = aramBase; + + zeroBase8 = zeroBase; + aramBase16 = aramBase >> 1; + zeroBase16 = zeroBase >> 1; + + sound = &table->sound[0]; + adpcm = (SPADPCM*)&table->sound[table->entries]; + + for (i = 0; i < table->entries; i++) { + switch (sound->type) { + case 0: + sound->loopAddr = zeroBase4; + sound->loopEndAddr = 0; + sound->endAddr = aramBase4 + sound->endAddr; + sound->currentAddr = aramBase4 + sound->currentAddr; + sound->adpcm = adpcm; + adpcm++; + break; + case 1: + sound->loopAddr = aramBase4 + sound->loopAddr; + sound->loopEndAddr = aramBase4 + sound->loopEndAddr; + sound->endAddr = aramBase4 + sound->endAddr; + sound->currentAddr = aramBase4 + sound->currentAddr; + sound->adpcm = adpcm; + adpcm++; + break; + case 2: + sound->loopAddr = zeroBase16; + sound->loopEndAddr = 0; + sound->endAddr = aramBase16 + sound->endAddr; + sound->currentAddr = aramBase16 + sound->currentAddr; + break; + case 3: + sound->loopAddr = aramBase16 + sound->loopAddr; + sound->loopEndAddr = aramBase16 + sound->loopEndAddr; + sound->endAddr = aramBase16 + sound->endAddr; + sound->currentAddr = aramBase16 + sound->currentAddr; + break; + case 4: + sound->loopAddr = zeroBase8; + sound->loopEndAddr = 0; + sound->endAddr = aramBase8 + sound->endAddr; + sound->currentAddr = aramBase8 + sound->currentAddr; + break; + case 5: + sound->loopAddr = aramBase8 + sound->loopAddr; + sound->loopEndAddr = aramBase8 + sound->loopEndAddr; + sound->endAddr = aramBase8 + sound->endAddr; + sound->currentAddr = aramBase8 + sound->currentAddr; + break; + } + sound++; + } +} + +SPSoundEntry* SPGetSoundEntry(SPSoundTable* table, u32 index) { + ASSERTLINE(123, table); + + if (table->entries > index) { + return &table->sound[index]; + } + + return NULL; +} + +void SPPrepareSound(SPSoundEntry* sound, AXVPB* axvpb, u32 sampleRate) { + BOOL old; + u32 srcBits; + u32 loopAddr, endAddr, currentAddr; + u16* p; + u16* p1; + + ASSERTLINE(140, sound); + ASSERTLINE(141, axvpb); + + srcBits = 0x10000 * ((f32)sampleRate / 32000); + + switch (sound->type) { + case 0: + loopAddr = sound->loopAddr; + endAddr = sound->endAddr; + currentAddr = sound->currentAddr; + + p = (u16*)&axvpb->pb.addr; + p1 = (u16*)sound->adpcm; + + old = OSDisableInterrupts(); + + *p++ = 0; + *p++ = 0; + *p++ = (u16)(loopAddr >> 0x10); + *p++ = (u16)(loopAddr & 0xFFFF); + *p++ = (u16)(endAddr >> 0x10); + *p++ = (u16)(endAddr & 0xFFFF); + *p++ = (u16)(currentAddr >> 0x10); + *p++ = (u16)(currentAddr & 0xFFFF); + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = (u16)(srcBits >> 0x10); + *p++ = (u16)(srcBits & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + + axvpb->sync |= 0x61000; + OSRestoreInterrupts(old); + break; + case 1: + loopAddr = sound->loopAddr; + endAddr = sound->loopEndAddr; + currentAddr = sound->currentAddr; + + p = (u16*)&axvpb->pb.addr; + p1 = (u16*)sound->adpcm; + + old = OSDisableInterrupts(); + + *p++ = 1; + *p++ = 0; + *p++ = (u16)(loopAddr >> 0x10); + *p++ = (u16)(loopAddr & 0xFFFF); + *p++ = (u16)(endAddr >> 0x10); + *p++ = (u16)(endAddr & 0xFFFF); + *p++ = (u16)(currentAddr >> 0x10); + *p++ = (u16)(currentAddr & 0xFFFF); + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + *p++ = (u16)(srcBits >> 0x10); + *p++ = (u16)(srcBits & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = *p1++; + *p++ = *p1++; + *p++ = *p1++; + + axvpb->sync |= 0x161000; + OSRestoreInterrupts(old); + break; + case 2: + loopAddr = sound->loopAddr; + endAddr = sound->endAddr; + currentAddr = sound->currentAddr; + + p = (u16*)&axvpb->pb.addr; + + old = OSDisableInterrupts(); + + *p++ = 0; + *p++ = 10; + *p++ = (u16)(loopAddr >> 0x10); + *p++ = (u16)(loopAddr & 0xFFFF); + *p++ = (u16)(endAddr >> 0x10); + *p++ = (u16)(endAddr & 0xFFFF); + *p++ = (u16)(currentAddr >> 0x10); + *p++ = (u16)(currentAddr & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0x800; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = (u16)(srcBits >> 0x10); + *p++ = (u16)(srcBits & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + + axvpb->sync |= 0x61000; + OSRestoreInterrupts(old); + break; + case 3: + loopAddr = sound->loopAddr; + endAddr = sound->loopEndAddr; + currentAddr = sound->currentAddr; + + p = (u16*)&axvpb->pb.addr; + + old = OSDisableInterrupts(); + + *p++ = 1; + *p++ = 10; + *p++ = (u16)(loopAddr >> 0x10); + *p++ = (u16)(loopAddr & 0xFFFF); + *p++ = (u16)(endAddr >> 0x10); + *p++ = (u16)(endAddr & 0xFFFF); + *p++ = (u16)(currentAddr >> 0x10); + *p++ = (u16)(currentAddr & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0x800; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = (u16)(srcBits >> 0x10); + *p++ = (u16)(srcBits & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + + axvpb->sync |= 0x61000; + OSRestoreInterrupts(old); + break; + case 4: + loopAddr = sound->loopAddr; + endAddr = sound->endAddr; + currentAddr = sound->currentAddr; + + p = (u16*)&axvpb->pb.addr; + + old = OSDisableInterrupts(); + + *p++ = 0; + *p++ = 0x19; + *p++ = (u16)(loopAddr >> 0x10); + *p++ = (u16)(loopAddr & 0xFFFF); + *p++ = (u16)(endAddr >> 0x10); + *p++ = (u16)(endAddr & 0xFFFF); + *p++ = (u16)(currentAddr >> 0x10); + *p++ = (u16)(currentAddr & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0x100; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = (u16)(srcBits >> 0x10); + *p++ = (u16)(srcBits & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + + axvpb->sync |= 0x61000; + OSRestoreInterrupts(old); + break; + case 5: + loopAddr = sound->loopAddr; + endAddr = sound->loopEndAddr; + currentAddr = sound->currentAddr; + + p = (u16*)&axvpb->pb.addr; + + old = OSDisableInterrupts(); + + *p++ = 1; + *p++ = 0x19; + *p++ = (u16)(loopAddr >> 0x10); + *p++ = (u16)(loopAddr & 0xFFFF); + *p++ = (u16)(endAddr >> 0x10); + *p++ = (u16)(endAddr & 0xFFFF); + *p++ = (u16)(currentAddr >> 0x10); + *p++ = (u16)(currentAddr & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0x100; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = (u16)(srcBits >> 0x10); + *p++ = (u16)(srcBits & 0xFFFF); + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + + axvpb->sync |= 0x61000; + OSRestoreInterrupts(old); + break; + } +} + +void SPPrepareEnd(SPSoundEntry* sound, AXVPB* axvpb) { + BOOL old; + + ASSERTLINE(497, sound); + ASSERTLINE(498, axvpb); + + old = OSDisableInterrupts(); + + axvpb->pb.addr.loopFlag = 0; + axvpb->pb.addr.endAddressHi = sound->endAddr >> 0x10; + axvpb->pb.addr.endAddressLo = sound->endAddr & 0xFFFF; + + axvpb->sync |= 0xA000; + OSRestoreInterrupts(old); +} diff --git a/src/dolphin/support/HTable.c b/src/dolphin/support/HTable.c new file mode 100644 index 0000000000..6cee989f97 --- /dev/null +++ b/src/dolphin/support/HTable.c @@ -0,0 +1,68 @@ +#include +#include + +void DSInitHTable(DSHashTable* hTable, u16 size, DSList* listArray, DSHashFunc* hashFunc, Ptr obj, DSLinkPtr link) { + u16 i; + + hTable->table = listArray; + hTable->tableSize = size; + hTable->hash = hashFunc; + for (i = 0; i < size; i++) { + DSInitList(&listArray[i], obj, link); + } +} + +void DSInsertHTableObj(DSHashTable* hTable, Ptr obj) { + DSList* list = &hTable->table[hTable->hash(obj)]; + DSInsertListObject(list, 0, obj); +} + +void DSHTableToList(DSHashTable* hTable, DSList* list) { + DSLink* link = NULL; + u16 i = 0; + + list->Offset = hTable->table[i].Offset; + for (i = 0; i < hTable->tableSize; i++) { + DSAttachList(list, &hTable->table[i]); + } +} + +void* DSNextHTableObj(DSHashTable* hTable, Ptr obj) { + s32 currentIndex; + void* cursor; + + if (!hTable) { + return NULL; + } + + if (!obj) { + currentIndex = 0; + cursor = DSNextListObj(&hTable->table[currentIndex], NULL); + } else { + currentIndex = DSHTableIndex(hTable, obj); + if (currentIndex == -1) { + return NULL; + } + cursor = DSNextListObj(&hTable->table[currentIndex], obj); + } + + while (cursor == NULL && currentIndex < hTable->tableSize - 1) { + currentIndex++; + cursor = DSNextListObj(&hTable->table[currentIndex], NULL); + } + return cursor; +} + +s32 DSHTableIndex(DSHashTable* hTable, Ptr obj) { + if (!hTable || !obj) { + return -1; + } + return hTable->hash(obj); +} + +void* DSHTableHead(DSHashTable* hTable, s32 index) { + if (index < 0 || index >= hTable->tableSize) { + return NULL; + } + return DSNextListObj(&hTable->table[index], NULL); +} diff --git a/src/dolphin/support/List.c b/src/dolphin/support/List.c new file mode 100644 index 0000000000..34b6bc8a56 --- /dev/null +++ b/src/dolphin/support/List.c @@ -0,0 +1,92 @@ +#include + +void DSInitList(DSListPtr list, Ptr obj, DSLinkPtr link) { + list->Head = NULL; + list->Tail = NULL; + list->Offset = (Ptr)link - obj; +} + +void DSInsertListObject(DSListPtr list, Ptr cursor, Ptr obj) { + DSLinkPtr link; + DSLinkPtr linkNext; + DSLinkPtr linkPrev; + + link = (DSLinkPtr)(obj + list->Offset); + if (list->Head) { + if (!cursor) { + linkPrev = (DSLinkPtr)(list->Tail + list->Offset); + linkPrev->Next = obj; + link->Prev = list->Tail; + link->Next = NULL; + list->Tail = obj; + } else { + linkNext = (DSLinkPtr)(cursor + list->Offset); + if (cursor == list->Head) { + list->Head = obj; + link->Next = cursor; + linkNext->Prev = obj; + } else { + linkPrev = (DSLinkPtr)(linkNext->Prev + list->Offset); + link->Next = cursor; + link->Prev = linkNext->Prev; + linkNext->Prev = obj; + linkPrev->Next = obj; + } + } + } else { + list->Tail = obj; + list->Head = obj; + link->Next = link->Prev = NULL; + } +} + +void DSRemoveListObject(DSListPtr list, Ptr obj) { + DSLinkPtr link = (DSLinkPtr)(obj + list->Offset); + + if (obj) { + if (link->Prev) { + ((DSLinkPtr)(link->Prev + list->Offset))->Next = link->Next; + } else { + list->Head = link->Next; + } + + if (link->Next) { + ((DSLinkPtr)(link->Next + list->Offset))->Prev = link->Prev; + } else { + list->Tail = link->Prev; + } + + link->Prev = NULL; + link->Next = NULL; + } +} + +void DSAttachList(DSListPtr baseList, DSListPtr attachList) { + DSLinkPtr link; + DSLinkPtr linkPrev; + + if (baseList->Offset == attachList->Offset && (attachList->Head || attachList->Tail)) { + linkPrev = (DSLinkPtr)(attachList->Head + attachList->Offset); + if (baseList->Head) { + link = (DSLinkPtr)(baseList->Tail + baseList->Offset); + link->Next = attachList->Head; + linkPrev->Prev = baseList->Tail; + baseList->Tail = attachList->Tail; + return; + } + baseList->Head = attachList->Head; + baseList->Tail = attachList->Tail; + linkPrev; // needed to match + } +} + +void* DSNextListObj(DSListPtr list, Ptr obj) { + if (!list) { + return NULL; + } + if (!obj) { + return list->Head; + } + + return ((DSLinkPtr)(obj + list->Offset))->Next; +} diff --git a/src/dolphin/support/Tree.c b/src/dolphin/support/Tree.c new file mode 100644 index 0000000000..34ced4516f --- /dev/null +++ b/src/dolphin/support/Tree.c @@ -0,0 +1,106 @@ +#include + +void DSExtractBranch(DSTreePtr tree, Ptr obj) { + DSBranchPtr branch = (DSBranchPtr)(obj + tree->Offset); + Ptr cursor = branch->Children; + Ptr next; + + while (cursor) { + next = ((DSBranchPtr)(cursor + tree->Offset))->Next; + DSInsertBranchBelow(tree, branch->Parent, cursor); + cursor = next; + } + DSRemoveBranch(tree, obj); +} + +void DSInitTree(DSTreePtr tree, Ptr obj, DSBranchPtr branch) { + tree->Root = NULL; + tree->Offset = (Ptr)branch - obj; +} + +void DSInsertBranchBelow(DSTreePtr tree, Ptr cursor, Ptr obj) { + DSBranchPtr branch; + DSBranchPtr objBranch = (DSBranchPtr)(obj + tree->Offset); + Ptr tail = NULL; + + if (cursor) { + branch = (DSBranchPtr)(cursor + tree->Offset); + if (branch->Children) { + tail = branch->Children; + } else { + branch->Children = obj; + } + } else if (tree->Root) { + tail = tree->Root; + } else { + tree->Root = obj; + } + + if (tail) { + while (((DSBranchPtr)(tail + tree->Offset))->Next) { + tail = ((DSBranchPtr)(tail + tree->Offset))->Next; + } + ((DSBranchPtr)(tail + tree->Offset))->Next = obj; + objBranch->Prev = tail; + } else { + objBranch->Prev = NULL; + } + + objBranch->Next = NULL; + objBranch->Parent = cursor; +} + +void DSInsertBranchBeside(DSTreePtr tree, Ptr cursor, Ptr obj) { + DSBranchPtr parent; + DSBranchPtr branch; + + branch = (DSBranchPtr)(obj + tree->Offset); + if (!cursor) { + if (!tree->Root) { + tree->Root = obj; + branch->Next = NULL; + branch->Prev = NULL; + branch->Children = NULL; + branch->Parent = NULL; + return; + } + cursor = tree->Root; + } + + while (((DSBranchPtr)(cursor + tree->Offset))->Next) { + cursor = ((DSBranchPtr)(cursor + tree->Offset))->Next; + } + + parent = (DSBranchPtr)(cursor + tree->Offset); + parent->Next = obj; + branch->Prev = cursor; + branch->Next = NULL; + branch->Parent = parent->Parent; +} + +void DSRemoveBranch(DSTreePtr tree, Ptr obj) { + DSBranchPtr branch; + DSBranchPtr parent; + + branch = (DSBranchPtr)(obj + tree->Offset); + if (branch->Parent) { + parent = (DSBranchPtr)(branch->Parent + tree->Offset); + if (parent->Children == obj) { + parent->Children = branch->Next; + } + } else if (tree->Root == obj) { + tree->Root = branch->Next; + } + + if (branch->Prev) { + ((DSBranchPtr)(branch->Prev + tree->Offset))->Next = branch->Next; + } + + if (branch->Next) { + ((DSBranchPtr)(branch->Next + tree->Offset))->Prev = branch->Prev; + } + + branch->Prev = NULL; + branch->Next = NULL; + branch->Parent = NULL; +} diff --git a/src/dolphin/support/string.c b/src/dolphin/support/string.c new file mode 100644 index 0000000000..f55ec794c3 --- /dev/null +++ b/src/dolphin/support/string.c @@ -0,0 +1,74 @@ +#include + +u8 Strcat(char* str1, char* str2, char* dst) { + char* srcCursor = str1; + char* dstCursor = dst;; + + if (!dst) { + return 0; + } + if (!str1) { + return 0; + } + if (!str2) { + return 0; + } + + while ((s8)*srcCursor != 0) { + *dstCursor = *srcCursor; + dstCursor++; + srcCursor++; + } + + srcCursor = str2; + while ((s8)*srcCursor != 0) { + *dstCursor = *srcCursor; + dstCursor++; + srcCursor++; + } + + *dstCursor = 0; + return 1; +} + +void Strcpy(char* dst, char* src) { + do { + *dst = *src; + dst++; + src++; + } while ((s8)*src != 0); +} + +s8 Strcmp(char* str1, char* str2) { + char* cursor1 = str1; + char* cursor2 = str2; + while (1) { + if ((s8)*cursor1 < (s8)*cursor2) { + return 1; + } + if ((s8)*cursor1 > (s8)*cursor2) { + return -1; + } + cursor1++; + cursor2++; + if ((s8)*cursor1 == 0 || (s8)*cursor2 == 0) { + return 0; + } + } +} + +u32 Strlen(char* str) { + char* cursor = str; + u32 counter = 0; + + if (!str) { + return 0; + } + + while ((s8)*cursor != 0) { + cursor++; + counter++; + } + + return counter; +} diff --git a/src/dolphin/syn/__syn.h b/src/dolphin/syn/__syn.h new file mode 100644 index 0000000000..ce2e970a99 --- /dev/null +++ b/src/dolphin/syn/__syn.h @@ -0,0 +1,67 @@ +#ifndef _DOLPHIN_SYN_INTERNAL_H_ +#define _DOLPHIN_SYN_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// syn +extern SYNSYNTH* __SYNSynthList; + +// synctrl +extern f32 __SYNn128[128]; + +void __SYNClearAllNotes(SYNSYNTH* synth); +void __SYNSetController(SYNSYNTH* synth, u8 midiChannel, u8 function, u8 value); +void __SYNResetController0(SYNSYNTH* synth, u8 midiChannel); +void __SYNResetController(SYNSYNTH* synth, u8 midiChannel); +void __SYNResetAllControllers(SYNSYNTH* synth); +void __SYNRunInputBufferEvents(SYNSYNTH* synth); + +// synenv +s32 __SYNGetEnvelopeTime(s32 scale, s32 mod, u8 key); +void __SYNSetupVolumeEnvelope(SYNVOICE* voice); +void __SYNSetupPitchEnvelope(SYNVOICE* voice); +void __SYNRunVolumeEnvelope(SYNVOICE* voice); +void __SYNRunPitchEnvelope(SYNVOICE* voice); + +// synlfo +void __SYNSetupLfo(SYNVOICE* voice); +void __SYNRunLfo(SYNVOICE* voice); + +// synmix +extern s32 __SYNVolumeAttenuation[128]; +extern s32 __SYNAttackAttnTable[100]; + +void __SYNSetupVolume(SYNVOICE* voice); +void __SYNSetupPan(SYNVOICE* voice); +s32 __SYNGetVoiceInput(SYNVOICE* voice); +s32 __SYNGetVoiceFader(SYNVOICE* voice); +void __SYNUpdateMix(SYNVOICE* voice); + +// synpitch +f32 __SYNGetRelativePitch(SYNVOICE* voice); +void __SYNSetupPitch(SYNVOICE* voice); +void __SYNSetupSrc(SYNVOICE* voice); +void __SYNUpdateSrc(SYNVOICE* voice); + +// synsample +void __SYNSetupSample(SYNVOICE* voice); + +// synvoice +extern SYNVOICE __SYNVoice[64]; + +void __SYNClearVoiceReferences(void* p); +void __SYNSetVoiceToRelease(SYNVOICE* voice, u32 priority); +void __SYNServiceVoice(int i); + +// synwt +int __SYNGetWavetableData(SYNVOICE* voice); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_SYN_INTERNAL_H_ diff --git a/src/dolphin/syn/syn.c b/src/dolphin/syn/syn.c new file mode 100644 index 0000000000..17bdebc515 --- /dev/null +++ b/src/dolphin/syn/syn.c @@ -0,0 +1,180 @@ +#include +#include +#include +#include +#include +#include "fake_tgmath.h" + +#include "__syn.h" + +SYNSYNTH* __SYNSynthList; + +// prototypes +static void __SYNAddSynthToList(SYNSYNTH* synth); +static void __SYNRemoveSynthFromList(SYNSYNTH* synth); + +static void __SYNAddSynthToList(SYNSYNTH* synth) { + BOOL old = OSDisableInterrupts(); + + if (__SYNSynthList) { + synth->next = __SYNSynthList; + } else { + synth->next = NULL; + } + __SYNSynthList = synth; + OSRestoreInterrupts(old); +} + +static void __SYNRemoveSynthFromList(SYNSYNTH* synth) { + SYNSYNTH* tempHead; + SYNSYNTH* tempTail; + SYNSYNTH* tempSynth; + BOOL old; + + old = OSDisableInterrupts(); + tempHead = NULL; + tempTail = NULL; + + for (tempSynth = __SYNSynthList; tempSynth; tempSynth = tempSynth->next) { + if (tempSynth != synth) { + if (tempHead) { + tempTail->next = tempSynth; + tempTail = tempSynth; + } else { + tempHead = tempTail = tempSynth; + } + } + } + + if (tempTail) { + tempTail->next = NULL; + } + + __SYNSynthList = tempHead; + OSRestoreInterrupts(old); +} + +void SYNInit(void) { + int i; + + for (i = 0; i < 64; i++) { + __SYNVoice[i].synth = 0; + } + __SYNSynthList = NULL; +} + +void SYNQuit(void) { + SYNInit(); +} + +void SYNRunAudioFrame(void) { + int i; + SYNSYNTH* synth; + + for (i = 0; i < 64; i++) { + __SYNServiceVoice(i); + } + + for (synth = __SYNSynthList; synth; synth = synth->next) { + __SYNRunInputBufferEvents(synth); + } +} + +void SYNInitSynth(SYNSYNTH* synth, void* wavetable, u32 aramBase, u32 zeroBase, u32 priorityVoiceAlloc, u32 priorityNoteOn, u32 priorityNoteRelease) { + u32* p; + u32 midiChannel; + u32 noteNumber; + + ASSERTLINE(158, synth); + ASSERTLINE(159, wavetable); + ASSERTLINE(160, aramBase); + + p = wavetable; + synth->percussiveInst = (void*)((u32)wavetable + *(p)); p += 1; + synth->melodicInst = (void*)((u32)wavetable + *(p)); p += 1; + synth->region = (void*)((u32)wavetable + *(p)); p += 1; + synth->art = (void*)((u32)wavetable + *(p)); p += 1; + synth->sample = (void*)((u32)wavetable + *(p)); p += 1; + synth->adpcm = (void*)((u32)wavetable + *(p)); p += 1; + synth->aramBaseWord = (aramBase >> 1); + synth->aramBaseByte = aramBase; + synth->aramBaseNibble = (aramBase << 1); + synth->zeroBaseWord = zeroBase >> 1; + synth->zeroBaseByte = zeroBase; + synth->zeroBaseNibble = (zeroBase << 1); + synth->priorityVoiceAlloc = priorityVoiceAlloc; + synth->priorityNoteOn = priorityNoteOn; + synth->priorityNoteRelease = priorityNoteRelease; + synth->masterVolume = 0; + __SYNResetAllControllers(synth); + synth->inputPosition = &synth->input[0][0]; + synth->inputCounter = 0; + synth->notes = 0; + + for (midiChannel = 0; midiChannel < 16; midiChannel++) { + for (noteNumber = 0; noteNumber < 16; noteNumber++) { + synth->keyGroup[midiChannel][noteNumber] = 0; + } + } + + for (midiChannel = 0; midiChannel < 16; midiChannel++) { + for (noteNumber = 0; noteNumber < 128; noteNumber++) { + synth->voice[midiChannel][noteNumber] = 0; + } + } + + __SYNAddSynthToList(synth); +} + +void SYNQuitSynth(SYNSYNTH* synth) { + int i; + BOOL old; + SYNVOICE* voice; + + old = OSDisableInterrupts(); + if (synth->notes) { + for (i = 0; i < 64; i++) { + voice = &__SYNVoice[i]; + if (voice->synth == synth) { + MIXReleaseChannel(voice->axvpb); + AXFreeVoice(voice->axvpb); + voice->synth = 0; + } + } + } + + __SYNRemoveSynthFromList(synth); + OSRestoreInterrupts(old); +} + +void SYNMidiInput(SYNSYNTH* synth, u8* input) { + u8* src; + + ASSERTLINE(244, synth); + ASSERTLINE(245, input); + + src = input; + *(synth->inputPosition) = *(src); (synth->inputPosition) += 1; (src) += 1; + *(synth->inputPosition) = *(src); (synth->inputPosition) += 1; (src) += 1; + *(synth->inputPosition) = *(src); (synth->inputPosition) += 1; (src) += 1; + synth->inputCounter++; + + if (synth->inputCounter >= SYN_INPUT_BUFFER_SIZE) { + ASSERTMSGLINE(258, FALSE, "synth input buffer exceeded, increase SYN_INPUT_BUFFER_SIZE"); + } +} + +void SYNSetMasterVolume(SYNSYNTH* synth, s32 dB) { + ASSERTLINE(267, synth); + synth->masterVolume = (dB << 0x10); +} + +s32 SYNGetMasterVolume(SYNSYNTH* synth) { + ASSERTLINE(278, synth); + return synth->masterVolume >> 0x10; +} + +u32 SYNGetActiveNotes(SYNSYNTH* synth) { + ASSERTLINE(289, synth); + return synth->notes; +} diff --git a/src/dolphin/syn/synctrl.c b/src/dolphin/syn/synctrl.c new file mode 100644 index 0000000000..cfae4ec96e --- /dev/null +++ b/src/dolphin/syn/synctrl.c @@ -0,0 +1,510 @@ +#include +#include +#include +#include +#include "fake_tgmath.h" + +#include "__syn.h" + +f32 __SYNn128[128] = { + 0.000000f, + 0.007813f, + 0.015625f, + 0.023438f, + 0.031250f, + 0.039063f, + 0.046875f, + 0.054688f, + 0.062500f, + 0.070313f, + 0.078125f, + 0.085938f, + 0.093750f, + 0.101563f, + 0.109375f, + 0.117188f, + 0.125000f, + 0.132813f, + 0.140625f, + 0.148438f, + 0.156250f, + 0.164063f, + 0.171875f, + 0.179688f, + 0.187500f, + 0.195313f, + 0.203125f, + 0.210938f, + 0.218750f, + 0.226563f, + 0.234375f, + 0.242188f, + 0.250000f, + 0.257813f, + 0.265625f, + 0.273438f, + 0.281250f, + 0.289063f, + 0.296875f, + 0.304688f, + 0.312500f, + 0.320313f, + 0.328125f, + 0.335938f, + 0.343750f, + 0.351563f, + 0.359375f, + 0.367188f, + 0.375000f, + 0.382813f, + 0.390625f, + 0.398438f, + 0.406250f, + 0.414063f, + 0.421875f, + 0.429688f, + 0.437500f, + 0.445313f, + 0.453125f, + 0.460938f, + 0.468750f, + 0.476563f, + 0.484375f, + 0.492188f, + 0.500000f, + 0.507813f, + 0.515625f, + 0.523438f, + 0.531250f, + 0.539063f, + 0.546875f, + 0.554688f, + 0.562500f, + 0.570313f, + 0.578125f, + 0.585938f, + 0.593750f, + 0.601563f, + 0.609375f, + 0.617188f, + 0.625000f, + 0.632813f, + 0.640625f, + 0.648438f, + 0.656250f, + 0.664063f, + 0.671875f, + 0.679688f, + 0.687500f, + 0.695313f, + 0.703125f, + 0.710938f, + 0.718750f, + 0.726563f, + 0.734375f, + 0.742188f, + 0.750000f, + 0.757813f, + 0.765625f, + 0.773438f, + 0.781250f, + 0.789063f, + 0.796875f, + 0.804688f, + 0.812500f, + 0.820313f, + 0.828125f, + 0.835938f, + 0.843750f, + 0.851563f, + 0.859375f, + 0.867188f, + 0.875000f, + 0.882813f, + 0.890625f, + 0.898438f, + 0.906250f, + 0.914063f, + 0.921875f, + 0.929688f, + 0.937500f, + 0.945313f, + 0.953125f, + 0.960938f, + 0.968750f, + 0.976563f, + 0.984375f, + 0.992188f +}; + +// prototypes +static void __SYNSetData(SYNSYNTH* synth, u8 midiChannel); +static void __SYNSetSustainPedal(SYNSYNTH* synth, u8 midiChannel, u8 data); +static void __SYNProgramChange(SYNSYNTH* synth, u8 midiChannel, u8 program); +static void __SYNReleaseChannelNotes(SYNSYNTH* synth, u8 midiChannel); +static void __SYNNoteOff(SYNSYNTH* synth, u8 midiChannel, u8 keyNum); +static void __SYNNoteOn(SYNSYNTH* synth, u8 midiChannel, u8 keyNum, u8 keyVel); +static void __SYNPitchWheel(SYNSYNTH* synth, u8 midiChannel, u8 lsb, u8 msb); +static void __SYNMidiIn(SYNSYNTH* synth, u8* input); + +static void __SYNSetData(SYNSYNTH* synth, u8 midiChannel) { + ASSERTLINE(59, synth); + ASSERTLINE(60, midiChannel < 16); + + if (synth->rpn[midiChannel]) { + u16 param = (synth->controller[midiChannel][0x65] << 8) + synth->controller[midiChannel][0x64]; + switch(param) { + case 0: + synth->pwMaxCents[midiChannel] = (synth->controller[midiChannel][0x26] + (synth->controller[midiChannel][0x6] * 100)) << 0x10; + break; + case 1: + ASSERTMSGLINE(80, FALSE, "RPN 0001 not supported\n"); + break; + case 2: + ASSERTMSGLINE(86, FALSE, "RPN 0002 not supported\n"); + break; + case 3: + ASSERTMSGLINE(92, FALSE, "RPN 0003 not supported\n"); + break; + case 4: + ASSERTMSGLINE(98, FALSE, "RPN 0004 not supported\n"); + break; + } + } +} + +static void __SYNSetSustainPedal(SYNSYNTH* synth, u8 midiChannel, u8 data) { + int i; + SYNVOICE* voice; + + ASSERTLINE(111, synth); + ASSERTLINE(112, midiChannel < 16); + ASSERTLINE(113, data < 128); + + // check if you're below 0x80 only to check if you're below 0x40. ok then. + if (data < 64) { + for (i = 0; i < 128; i++) { + voice = synth->voice[midiChannel][i]; + if (voice && voice->hold) { + __SYNSetVoiceToRelease(voice, synth->priorityNoteRelease); + voice->synth->voice[voice->midiChannel][voice->keyNum] = 0; + } + } + } +} + +static void __SYNProgramChange(SYNSYNTH* synth, u8 midiChannel, u8 program) { + ASSERTLINE(142, synth); + ASSERTLINE(143, midiChannel < 16); + ASSERTLINE(144, program < 128); + + if (midiChannel == 9) { + synth->inst[midiChannel] = synth->percussiveInst; + } else { + synth->inst[midiChannel] = synth->melodicInst; + } + + synth->inst[midiChannel] += program; +} + +static void __SYNReleaseChannelNotes(SYNSYNTH* synth, u8 midiChannel) { + int i; + SYNVOICE* voice; + + ASSERTLINE(162, synth); + ASSERTLINE(163, midiChannel < 16); + + for (i = 0; i < 128; i++) { + voice = synth->voice[midiChannel][i]; + if (voice) { + __SYNSetVoiceToRelease(voice, synth->priorityNoteRelease); + synth->voice[midiChannel][i] = 0; + } + } +} + +void __SYNClearAllNotes(SYNSYNTH* synth) { + u8 i; + + ASSERTLINE(189, synth); + + for (i = 0; i < 16; i++) { + __SYNReleaseChannelNotes(synth, i); + } +} + +void __SYNSetController(SYNSYNTH* synth, u8 midiChannel, u8 function, u8 value) { + ASSERTLINE(201, synth); + ASSERTLINE(202, midiChannel < 16); + ASSERTLINE(203, function < 128); + ASSERTLINE(204, value < 128); + + synth->controller[midiChannel][function] = value; + switch(function) { + case 6: + __SYNSetData(synth, midiChannel); + break; + case 7: + synth->volAttn[midiChannel] = __SYNVolumeAttenuation[value]; + break; + case 11: + synth->expAttn[midiChannel] = __SYNVolumeAttenuation[value]; + break; + case 0x26: + __SYNSetData(synth, midiChannel); + break; + case 0x40: + __SYNSetSustainPedal(synth, midiChannel, value); + break; + case 0x5B: + synth->auxAAttn[midiChannel] = __SYNVolumeAttenuation[value]; + break; + case 0x5C: + synth->auxBAttn[midiChannel] = __SYNVolumeAttenuation[value]; + break; + case 0x5D: + break; + case 0x62: + case 0x63: + synth->rpn[midiChannel] = 0; + break; + case 0x64: + case 0x65: + synth->rpn[midiChannel] = 1; + break; + case 0x78: + __SYNReleaseChannelNotes(synth, midiChannel); + break; + case 0x79: + if (value == 0) { + __SYNResetController0(synth, midiChannel); + } else { + __SYNResetController(synth, midiChannel); + } + break; + case 0x7B: + case 0x7C: + case 0x7D: + case 0x7E: + case 0x7F: + __SYNReleaseChannelNotes(synth, midiChannel); + break; + default: + break; + } +} + +void __SYNResetController0(SYNSYNTH* synth, u8 midiChannel) { + u8 volume; + u8 pan; + u8 expression; + int i; + + ASSERTLINE(315, synth); + ASSERTLINE(316, midiChannel < 16); + + synth->pwMaxCents[midiChannel] = 0xC80000; + synth->pwCents[midiChannel] = 0; + volume = synth->controller[midiChannel][7]; + pan = synth->controller[midiChannel][10]; + expression = synth->controller[midiChannel][11]; + + for (i = 0; i < 128; i++) { + synth->controller[midiChannel][i] = 0; + } + + __SYNSetController(synth, midiChannel, 7, volume); + __SYNSetController(synth, midiChannel, 0xA, pan); + __SYNSetController(synth, midiChannel, 0xB, expression); + __SYNSetController(synth, midiChannel, 0x5B, 0); + __SYNSetController(synth, midiChannel, 0x5C, 0); +} + +void __SYNResetController(SYNSYNTH* synth, u8 midiChannel) { + int i; + + ASSERTLINE(345, synth); + ASSERTLINE(346, midiChannel < 16); + + synth->pwMaxCents[midiChannel] = 0xC80000; + synth->pwCents[midiChannel] = 0; + + for (i = 0; i < 128; i++) { + synth->controller[midiChannel][i] = 0; + } + + __SYNSetController(synth, midiChannel, 7, 0x64); + __SYNSetController(synth, midiChannel, 0xA, 0x40); + __SYNSetController(synth, midiChannel, 0xB, 0x7F); + __SYNSetController(synth, midiChannel, 0x5B, 0); + __SYNSetController(synth, midiChannel, 0x5C, 0); +} + +void __SYNResetAllControllers(SYNSYNTH* synth) { + u8 midiChannel; + + ASSERTLINE(372, synth); + + for (midiChannel = 0; midiChannel < 16; midiChannel++) { + __SYNProgramChange(synth, midiChannel, 0); + __SYNResetController(synth, midiChannel); + } +} + +static void __SYNNoteOff(SYNSYNTH* synth, u8 midiChannel, u8 keyNum) { + SYNVOICE* voice; + + ASSERTLINE(389, synth); + ASSERTLINE(390, midiChannel < 16); + ASSERTLINE(391, keyNum < 128); + + voice = synth->voice[midiChannel][keyNum]; + if (voice) { + if (synth->controller[midiChannel][64] > 64) { + voice->hold = 1; + return; + } + __SYNSetVoiceToRelease(voice, synth->priorityNoteRelease); + synth->voice[midiChannel][keyNum] = 0; + } +} + +static void __SYNNoteOn(SYNSYNTH* synth, u8 midiChannel, u8 keyNum, u8 keyVel) { + AXVPB* axvpb; + SYNVOICE* voice; + SYNVOICE* oldVoice; + + ASSERTLINE(420, synth); + ASSERTLINE(421, midiChannel < 16); + ASSERTLINE(422, keyNum < 128); + ASSERTLINE(423, keyVel < 128); + + if (keyVel) { + if (synth->voice[midiChannel][keyNum]) { + __SYNSetVoiceToRelease(synth->voice[midiChannel][keyNum], synth->priorityNoteRelease); + synth->voice[midiChannel][keyNum] = 0; + } + + axvpb = AXAcquireVoice(synth->priorityVoiceAlloc, &__SYNClearVoiceReferences, (u32)synth); + + if (axvpb) { + voice = &__SYNVoice[axvpb->index]; + voice->axvpb = axvpb; + voice->synth = synth; + voice->midiChannel = midiChannel; + voice->keyNum = keyNum; + voice->keyVel = keyVel; + voice->hold = 0; + + if (__SYNGetWavetableData(voice) != 0) { + synth->voice[midiChannel][keyNum] = voice; + synth->notes++; + voice->keyGroup = voice->region->keyGroup; + if (voice->keyGroup != 0) { + oldVoice = synth->keyGroup[midiChannel][voice->keyGroup]; + if (oldVoice) { + oldVoice->synth = 0; + MIXReleaseChannel(oldVoice->axvpb); + AXFreeVoice(oldVoice->axvpb); + synth->voice[midiChannel][oldVoice->keyNum] = 0; + synth->notes--; + } + synth->keyGroup[midiChannel][voice->keyGroup] = voice; + } + + __SYNSetupPitch(voice); + __SYNSetupVolume(voice); + __SYNSetupPan(voice); + __SYNSetupLfo(voice); + __SYNSetupVolumeEnvelope(voice); + __SYNSetupPitchEnvelope(voice); + + if (midiChannel == 9) { + MIXInitChannel(axvpb, 0, __SYNGetVoiceInput(voice), synth->auxAAttn[midiChannel] >> 0x10, synth->auxBAttn[midiChannel] >> 0x10, voice->pan, 0x7F, __SYNGetVoiceFader(voice)); + } else { + MIXInitChannel(axvpb, 0, __SYNGetVoiceInput(voice), synth->auxAAttn[midiChannel] >> 0x10, synth->auxBAttn[midiChannel] >> 0x10, synth->controller[midiChannel][10], 0x7F, __SYNGetVoiceFader(voice)); + } + + __SYNSetupSample(voice); + __SYNSetupSrc(voice); + axvpb->pb.state = 1; + axvpb->sync = (axvpb->sync | 4); + AXSetVoicePriority(axvpb, synth->priorityNoteOn); + return; + } + + voice->synth = NULL; + MIXReleaseChannel(axvpb); + AXFreeVoice(axvpb); + } + } else { + __SYNNoteOff(synth, midiChannel, keyNum); + } +} + +static void __SYNPitchWheel(SYNSYNTH* synth, u8 midiChannel, u8 lsb, u8 msb) { + s32 position; + + ASSERTLINE(565, synth); + ASSERTLINE(566, midiChannel < 16); + ASSERTLINE(567, lsb < 128); + ASSERTLINE(568, msb < 128); + + position = lsb + (msb << 7) - 0x2000; + synth->pwCents[midiChannel] = (synth->pwMaxCents[midiChannel] * ((f32)position / 8192.0f)); +} + +static void __SYNMidiIn(SYNSYNTH* synth, u8* input) { + u8* ch; + u8 midiFunction; + u8 midiChannel; + u8 _2ndByte; + u8 _3rdByte; + + ASSERTLINE(589, synth); + ASSERTLINE(590, input); + + ch = input; + midiFunction = (*(ch) >> 4); ch += 0; + midiChannel = (*(ch) & 0xF); ch += 1; + _2ndByte = *(ch); ch += 1; + + switch(midiFunction) { + case 8: + __SYNNoteOff(synth, midiChannel, _2ndByte); + return; + case 9: + _3rdByte = *(ch); ch += 1; + __SYNNoteOn(synth, midiChannel, _2ndByte, _3rdByte); + return; + case 11: + _3rdByte = *(ch); ch += 1; + __SYNSetController(synth, midiChannel, _2ndByte, _3rdByte); + return; + case 12: + __SYNProgramChange(synth, midiChannel, _2ndByte); + return; + case 14: + _3rdByte = *(ch); ch+=1; + __SYNPitchWheel(synth, midiChannel, _2ndByte, _3rdByte); + return; + } +} + +void __SYNRunInputBufferEvents(SYNSYNTH* synth) { + u8* input; + + for (input = &synth->input[0][0]; synth->inputCounter; synth->inputCounter--) { + __SYNMidiIn(synth, input); + input+=3; + } + + synth->inputPosition = &synth->input[0][0]; +} + +u8 SYNGetMidiController(SYNSYNTH* synth, u8 midiChannel, u8 function) { + ASSERTLINE(678, synth); + ASSERTLINE(679, midiChannel < 16); + ASSERTLINE(680, function < 128); + return synth->controller[midiChannel][function]; +} diff --git a/src/dolphin/syn/synenv.c b/src/dolphin/syn/synenv.c new file mode 100644 index 0000000000..caafb5ea07 --- /dev/null +++ b/src/dolphin/syn/synenv.c @@ -0,0 +1,185 @@ +#include +#include +#include +#include "fake_tgmath.h" +#include "cmath.h" + +#include "__syn.h" + +s32 __SYNGetEnvelopeTime(s32 scale, s32 mod, u8 key) { + if (scale == 0x80000000) { + return 0; + } + + if (mod == 0x80000000) { + return (1000.0f* powf(2.0f, (f32)scale / (65536* 1200))); + } + + return (1000.0f* powf(2.0f, ((f32)scale + (mod* __SYNn128[key])) / (65535* 1200))); +} + +void __SYNSetupVolumeEnvelope(SYNVOICE* voice) { + ASSERTLINE(46, voice); + + if (voice->art->eg1Attack + 0x80000000 == 0) { + voice->veState = 1; + voice->veAttn = 0; + if (voice->art->eg1Decay + 0x80000000 == 0) { + voice->veState = 2; + voice->veAttn = voice->art->eg1Sustain; + } + } else { + s32 frames = __SYNGetEnvelopeTime(voice->art->eg1Attack, voice->art->eg1Vel2Attack, voice->keyVel) / 5; + if (frames != 0) { + voice->veAttack = 0; + voice->veAttackDelta = 0x640000 / frames; + voice->veAttn = 0xFC400000; + voice->veState = 0; + } else { + voice->veAttack = 0; + voice->veAttackDelta = 0x640000; + voice->veAttn = 0xFC400000; + voice->veState = 0; + } + } + + if (voice->veState < 2) { + s32 frames = __SYNGetEnvelopeTime(voice->art->eg1Decay, voice->art->eg1Key2Decay, voice->keyNum) / 5; + if (frames != 0) { + voice->veDecay = -0x03C00000 / frames; + } else { + voice->veDecay = -0x03C00000; + } + } + + voice->veSustain = voice->art->eg1Sustain; + voice->veRelease = voice->art->eg1Release; +} + +void __SYNSetupPitchEnvelope(SYNVOICE* voice) { + ASSERTLINE(110, voice); + + voice->peCents = 0; + voice->pePitch = voice->art->eg2Pitch; + if (voice->pePitch != 0) { + if (voice->art->eg2Attack + 0x80000000 == 0) { + voice->peState = 1; + voice->peCents = voice->pePitch; + if (voice->art->eg2Decay + 0x80000000 == 0) { + voice->peState = 2; + voice->peCents = voice->art->eg2Sustain; + } + } else { + s32 frames = __SYNGetEnvelopeTime(voice->art->eg2Attack, voice->art->eg2Vel2Attack, voice->keyVel) / 5; + if (frames != 0) { + voice->peAttack = voice->pePitch / frames; + voice->peState = 0; + } else { + voice->peAttack = voice->pePitch; + voice->peState = 0; + } + } + + if (voice->peState < 2) { + s32 frames = __SYNGetEnvelopeTime(voice->art->eg2Decay, voice->art->eg2Key2Decay, voice->keyNum) / 5; + if (frames != 0) { + voice->peDecay = voice->pePitch / frames; + } else { + voice->peDecay = voice->pePitch; + } + voice->peDecay = voice->peDecay * -1; + } + voice->peSustain = voice->art->eg2Sustain; + voice->peRelease = voice->art->eg2Release; + } +} + +void __SYNRunVolumeEnvelope(SYNVOICE* voice) { + ASSERTLINE(178, voice); + + switch(voice->veState) { + case 0: + voice->veAttack = (voice->veAttack + voice->veAttackDelta); + if (voice->veAttack >= 0x630000) { + voice->veAttn = 0; + } else { + voice->veAttn = __SYNAttackAttnTable[voice->veAttack >> 0x10]; + } + if (voice->veAttn == 0) { + voice->veState = 1; + } + case 2: + return; + case 1: + voice->veAttn = (voice->veAttn + voice->veDecay); + if (voice->veAttn <= voice->veSustain) { + voice->veAttn = voice->veSustain; + voice->veState = 2; + } + if (voice->veAttn <= -0x02D00000) { + voice->veState = 4; + voice->synth->voice[voice->midiChannel][voice->keyNum] = 0; + } + return; + case 3: + if (voice->veAttn <= -0x02D00000) { + voice->veState = 4; + } else { + voice->veAttn = (voice->veAttn + voice->veRelease); + } + return; + } +} + +void __SYNRunPitchEnvelope(SYNVOICE* voice) { + ASSERTLINE(243, voice); + + if (voice->pePitch != 0) { + switch(voice->peState) { + case 0: + voice->peCents = (voice->peCents + voice->peAttack); + if (voice->pePitch > 0) { + if (voice->peCents >= voice->pePitch) { + voice->pePitch = voice->peCents; + voice->peState = 1; + } + } else if (voice->peCents <= voice->pePitch) { + voice->pePitch = voice->peCents; + voice->peState = 1; + } + case 2: + return; + case 1: + voice->peCents = (voice->peCents + voice->peDecay); + if (voice->pePitch > 0) { + if (voice->peCents <= 0) { + voice->peCents = 0; + voice->pePitch = 0; + } else if (voice->peCents <= voice->peSustain) { + voice->peCents = voice->peSustain; + voice->peState = 2; + } + } else { + if (voice->peCents >= 0) { + voice->peCents = 0; + voice->pePitch = 0; + } else if (voice->peCents >= voice->peSustain) { + voice->peCents = voice->peSustain; + voice->peState = 2; + } + } + break; + case 3: + voice->peCents = (voice->peCents + voice->peRelease); + if (voice->pePitch > 0) { + if (voice->peCents <= 0) { + voice->peCents = 0; + voice->pePitch = 0; + } + } else if (voice->peCents >= 0) { + voice->peCents = 0; + voice->pePitch = 0; + } + } + } +} diff --git a/src/dolphin/syn/synlfo.c b/src/dolphin/syn/synlfo.c new file mode 100644 index 0000000000..22ace20110 --- /dev/null +++ b/src/dolphin/syn/synlfo.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include "fake_tgmath.h" + +#include "__syn.h" + +static f32 __SYNLfo[64] = { + 0.000000f, + 0.098020f, + 0.195090f, + 0.290280f, + 0.382680f, + 0.471400f, + 0.555570f, + 0.634390f, + 0.707110f, + 0.773010f, + 0.831470f, + 0.881920f, + 0.923880f, + 0.956940f, + 0.980790f, + 0.995180f, + 1.000000f, + 0.995180f, + 0.980790f, + 0.956940f, + 0.923880f, + 0.881920f, + 0.831470f, + 0.773010f, + 0.707110f, + 0.634390f, + 0.555570f, + 0.471400f, + 0.382680f, + 0.290280f, + 0.195090f, + 0.098020f, + 0.000000f, + -0.098020f, + -0.195090f, + -0.290280f, + -0.382680f, + -0.471400f, + -0.555570f, + -0.634390f, + -0.707110f, + -0.773010f, + -0.831470f, + -0.881920f, + -0.923880f, + -0.956940f, + -0.980790f, + -0.995180f, + -1.000000f, + -0.995180f, + -0.980790f, + -0.956940f, + -0.923880f, + -0.881920f, + -0.831470f, + -0.773010f, + -0.707110f, + -0.634390f, + -0.555570f, + -0.471400f, + -0.382680f, + -0.290280f, + -0.195090f, + -0.098020f, +}; + +void __SYNSetupLfo(SYNVOICE* voice) { + ASSERTLINE(47, voice); + + voice->lfoState = voice->lfoAttn = voice->lfoCents = 0; + voice->lfoFreq = voice->art->lfoFreq; + voice->lfoDelay = voice->art->lfoDelay; + voice->lfoAttn_ = voice->art->lfoAtten; + voice->lfoCents = voice->art->lfoPitch; + voice->lfoModAttn = voice->art->lfoMod2Atten; + voice->lfoModCents = voice->art->lfoMod2Pitch; +} + +void __SYNRunLfo(SYNVOICE* voice) { + f32 lfoAmplitude; + f32 lfoModWheel; + + ASSERTLINE(66, voice); + + if (voice->lfoDelay != 0) { + voice->lfoDelay--; + } else { + voice->lfoState += voice->lfoFreq; + lfoAmplitude = __SYNLfo[(voice->lfoState >> 0x10) % 64]; + lfoModWheel = __SYNn128[voice->synth->controller[voice->midiChannel][1]]; + voice->lfoAttn = (lfoAmplitude * (voice->lfoAttn_ + (voice->lfoModAttn* lfoModWheel))); + voice->lfoCents = (lfoAmplitude * (voice->lfoCents_ + (voice->lfoModCents* lfoModWheel))); + } +} diff --git a/src/dolphin/syn/synmix.c b/src/dolphin/syn/synmix.c new file mode 100644 index 0000000000..56dc0ac178 --- /dev/null +++ b/src/dolphin/syn/synmix.c @@ -0,0 +1,274 @@ +#include +#include +#include +#include +#include "fake_tgmath.h" + +#include "__syn.h" + +s32 __SYNVolumeAttenuation[128] = { + 0xFC400000, + 0xFCB67A80, + 0xFD2EE3F9, + 0xFD7553B8, + 0xFDA74D72, + 0xFDCE1108, + 0xFDEDBD30, + 0xFE08848A, + 0xFE1FB6EA, + 0xFE342CEF, + 0xFE467A80, + 0xFE57091D, + 0xFE6626A9, + 0xFE740E4D, + 0xFE80EE03, + 0xFE8CEA3F, + 0xFE982063, + 0xFEA2A878, + 0xFEAC9668, + 0xFEB5FADF, + 0xFEBEE3F9, + 0xFEC75DC2, + 0xFECF7295, + 0xFED72B6E, + 0xFEDE9022, + 0xFEE5A78F, + 0xFEEC77C6, + 0xFEF30626, + 0xFEF9577C, + 0xFEFF700E, + 0xFF0553B8, + 0xFF0B05F0, + 0xFF1089DC, + 0xFF15E254, + 0xFF1B11F1, + 0xFF201B12, + 0xFF24FFE1, + 0xFF29C25C, + 0xFF2E6457, + 0xFF32E784, + 0xFF374D72, + 0xFF3B9791, + 0xFF3FC73A, + 0xFF43DDAC, + 0xFF47DC0E, + 0xFF4BC376, + 0xFF4F94E7, + 0xFF535152, + 0xFF56F99B, + 0xFF5A8E94, + 0xFF5E1108, + 0xFF6181B0, + 0xFF64E13E, + 0xFF68305A, + 0xFF6B6F9F, + 0xFF6E9FA4, + 0xFF71C0F4, + 0xFF74D416, + 0xFF77D987, + 0xFF7AD1BF, + 0xFF7DBD30, + 0xFF809C47, + 0xFF836F69, + 0xFF8636F9, + 0xFF88F355, + 0xFF8BA4D4, + 0xFF8E4BCD, + 0xFF90E890, + 0xFF937B6A, + 0xFF9604A6, + 0xFF98848A, + 0xFF9AFB5B, + 0xFF9D6959, + 0xFF9FCEC3, + 0xFFA22BD4, + 0xFFA480C6, + 0xFFA6CDD0, + 0xFFA91327, + 0xFFAB50FD, + 0xFFAD8784, + 0xFFAFB6EA, + 0xFFB1DF5E, + 0xFFB4010A, + 0xFFB61C19, + 0xFFB830B3, + 0xFFBA3F00, + 0xFFBC4724, + 0xFFBE4946, + 0xFFC04587, + 0xFFC23C0A, + 0xFFC42CEF, + 0xFFC61857, + 0xFFC7FE60, + 0xFFC9DF28, + 0xFFCBBACB, + 0xFFCD9166, + 0xFFCF6313, + 0xFFD12FED, + 0xFFD2F80D, + 0xFFD4BB8B, + 0xFFD67A80, + 0xFFD83502, + 0xFFD9EB29, + 0xFFDB9D08, + 0xFFDD4AB7, + 0xFFDEF449, + 0xFFE099D2, + 0xFFE23B66, + 0xFFE3D918, + 0xFFE572F9, + 0xFFE7091D, + 0xFFE89B93, + 0xFFEA2A6D, + 0xFFEBB5BC, + 0xFFED3D8F, + 0xFFEEC1F6, + 0xFFF04300, + 0xFFF1C0BC, + 0xFFF33B38, + 0xFFF4B283, + 0xFFF626A9, + 0xFFF797B9, + 0xFFF905BF, + 0xFFFA70C9, + 0xFFFBD8E2, + 0xFFFD3E16, + 0xFFFEA072, + 0x00000000 +}; + +s32 __SYNAttackAttnTable[100] = { + 0xFC400000, + 0xFE70DF7B, + 0xFEAD1437, + 0xFED04C17, + 0xFEE948F4, + 0xFEFCAABF, + 0xFF0C80D3, + 0xFF19E480, + 0xFF257DB0, + 0xFF2FB8B2, + 0xFF38DF7B, + 0xFF4126C9, + 0xFF48B58F, + 0xFF4FA961, + 0xFF56193C, + 0xFF5C175A, + 0xFF61B26C, + 0xFF66F677, + 0xFF6BED6F, + 0xFF709FAA, + 0xFF751437, + 0xFF79511C, + 0xFF7D5B85, + 0xFF8137F2, + 0xFF84EA4C, + 0xFF887602, + 0xFF8BDE1E, + 0xFF8F254E, + 0xFF924DF9, + 0xFF955A42, + 0xFF984C17, + 0xFF9B2533, + 0xFF9DE729, + 0xFFA09365, + 0xFFA32B33, + 0xFFA5AFC4, + 0xFFA8222B, + 0xFFAA8369, + 0xFFACD466, + 0xFFAF15FD, + 0xFFB148F4, + 0xFFB36E03, + 0xFFB585D8, + 0xFFB79111, + 0xFFB99042, + 0xFFBB83F6, + 0xFFBD6CAE, + 0xFFBF4AE4, + 0xFFC11F08, + 0xFFC2E985, + 0xFFC4AABF, + 0xFFC66313, + 0xFFC812DA, + 0xFFC9BA68, + 0xFFCB5A0A, + 0xFFCCF20D, + 0xFFCE82B5, + 0xFFD00C46, + 0xFFD18EFE, + 0xFFD30B1A, + 0xFFD480D3, + 0xFFD5F05E, + 0xFFD759EF, + 0xFFD8BDB7, + 0xFFDA1BE5, + 0xFFDB74A5, + 0xFFDCC821, + 0xFFDE1683, + 0xFFDF5FF0, + 0xFFE0A48E, + 0xFFE1E480, + 0xFFE31FE8, + 0xFFE456E7, + 0xFFE5899C, + 0xFFE6B825, + 0xFFE7E29E, + 0xFFE90923, + 0xFFEA2BCE, + 0xFFEB4AB9, + 0xFFEC65FD, + 0xFFED7DB0, + 0xFFEE91EA, + 0xFFEFA2C0, + 0xFFF0B047, + 0xFFF1BA94, + 0xFFF2C1BB, + 0xFFF3C5CD, + 0xFFF4C6DE, + 0xFFF5C4FE, + 0xFFF6C040, + 0xFFF7B8B2, + 0xFFF8AE66, + 0xFFF9A16B, + 0xFFFA91CF, + 0xFFFB7FA0, + 0xFFFC6AEE, + 0xFFFD53C4, + 0xFFFE3A31, + 0xFFFF1E41, + 0x00000000 +}; + +void __SYNSetupVolume(SYNVOICE* voice) { + ASSERTLINE(85, voice); + voice->attn = (voice->region->attn + __SYNVolumeAttenuation[voice->keyVel]); +} + +void __SYNSetupPan(SYNVOICE* voice) { + ASSERTLINE(98, voice); + if (voice->midiChannel == 9) { + voice->pan = voice->art->pan; + } else { + voice->pan = voice->synth->controller[voice->midiChannel][10]; + } +} + +s32 __SYNGetVoiceInput(SYNVOICE* voice) { + return (voice->attn + voice->lfoAttn + voice->veAttn) >> 0x10; +} + +s32 __SYNGetVoiceFader(SYNVOICE* voice) { + return (voice->synth->volAttn[voice->midiChannel] + voice->synth->expAttn[voice->midiChannel] + voice->synth->masterVolume) >> 0x10; +} + +void __SYNUpdateMix(SYNVOICE* voice) { + MIXSetInput(voice->axvpb, __SYNGetVoiceInput(voice)); + MIXSetAuxA(voice->axvpb, voice->synth->auxAAttn[voice->midiChannel] >> 0x10); + MIXSetAuxB(voice->axvpb, voice->synth->auxBAttn[voice->midiChannel] >> 0x10); + MIXSetFader(voice->axvpb, __SYNGetVoiceFader(voice)); + + if (voice->midiChannel != 9) { + MIXSetPan(voice->axvpb, voice->synth->controller[voice->midiChannel][10]); + } +} diff --git a/src/dolphin/syn/synpitch.c b/src/dolphin/syn/synpitch.c new file mode 100644 index 0000000000..ed1d543734 --- /dev/null +++ b/src/dolphin/syn/synpitch.c @@ -0,0 +1,340 @@ +#include +#include +#include "fake_tgmath.h" + +#include "__syn.h" + +static f32 __SYNCentsTable[100] = { + 1.000000f, + 1.000578f, + 1.001156f, + 1.001734f, + 1.002313f, + 1.002892f, + 1.003472f, + 1.004052f, + 1.004632f, + 1.005212f, + 1.005793f, + 1.006374f, + 1.006956f, + 1.007537f, + 1.008120f, + 1.008702f, + 1.009285f, + 1.009868f, + 1.010451f, + 1.011035f, + 1.011619f, + 1.012204f, + 1.012789f, + 1.013374f, + 1.013959f, + 1.014545f, + 1.015132f, + 1.015718f, + 1.016305f, + 1.016892f, + 1.017480f, + 1.018068f, + 1.018656f, + 1.019244f, + 1.019833f, + 1.020423f, + 1.021012f, + 1.021602f, + 1.022192f, + 1.022783f, + 1.023374f, + 1.023965f, + 1.024557f, + 1.025149f, + 1.025741f, + 1.026334f, + 1.026927f, + 1.027520f, + 1.028114f, + 1.028708f, + 1.029302f, + 1.029897f, + 1.030492f, + 1.031087f, + 1.031683f, + 1.032279f, + 1.032876f, + 1.033472f, + 1.034070f, + 1.034667f, + 1.035265f, + 1.035863f, + 1.036462f, + 1.037060f, + 1.037660f, + 1.038259f, + 1.038859f, + 1.039459f, + 1.040060f, + 1.040661f, + 1.041262f, + 1.041864f, + 1.042466f, + 1.043068f, + 1.043671f, + 1.044274f, + 1.044877f, + 1.045481f, + 1.046085f, + 1.046689f, + 1.047294f, + 1.047899f, + 1.048505f, + 1.049111f, + 1.049717f, + 1.050323f, + 1.050930f, + 1.051537f, + 1.052145f, + 1.052753f, + 1.053361f, + 1.053970f, + 1.054579f, + 1.055188f, + 1.055798f, + 1.056408f, + 1.057018f, + 1.057629f, + 1.058240f, + 1.058851f, +}; + +static f32 __SYNOctavesTableUp[12] = { + 1.000000f, + 2.000000f, + 4.000000f, + 8.000000f, + 16.000000f, + 32.000000f, + 64.000000f, + 128.000000f, + 256.000000f, + 512.000000f, + 1024.000000f, + 2048.000000f, +}; + +static f32 __SYNSemitonesTableUp[12] = { + 1.000000f, + 1.059463f, + 1.122462f, + 1.189207f, + 1.259921f, + 1.334840f, + 1.414214f, + 1.498307f, + 1.587401f, + 1.681793f, + 1.781797f, + 1.887749f, +}; + +static f32 __SYNSemitonesTableDown[128] = { + 1.000000f, + 0.943874f, + 0.890899f, + 0.840896f, + 0.793701f, + 0.749154f, + 0.707107f, + 0.667420f, + 0.629961f, + 0.594604f, + 0.561231f, + 0.529732f, + 0.500000f, + 0.471937f, + 0.445449f, + 0.420448f, + 0.396850f, + 0.374577f, + 0.353553f, + 0.333710f, + 0.314980f, + 0.297302f, + 0.280616f, + 0.264866f, + 0.250000f, + 0.235969f, + 0.222725f, + 0.210224f, + 0.198425f, + 0.187288f, + 0.176777f, + 0.166855f, + 0.157490f, + 0.148651f, + 0.140308f, + 0.132433f, + 0.125000f, + 0.117984f, + 0.111362f, + 0.105112f, + 0.099213f, + 0.093644f, + 0.088388f, + 0.083427f, + 0.078745f, + 0.074325f, + 0.070154f, + 0.066216f, + 0.062500f, + 0.058992f, + 0.055681f, + 0.052556f, + 0.049606f, + 0.046822f, + 0.044194f, + 0.041714f, + 0.039373f, + 0.037163f, + 0.035077f, + 0.033108f, + 0.031250f, + 0.029496f, + 0.027841f, + 0.026278f, + 0.024803f, + 0.023411f, + 0.022097f, + 0.020857f, + 0.019686f, + 0.018581f, + 0.017538f, + 0.016554f, + 0.015625f, + 0.014748f, + 0.013920f, + 0.013139f, + 0.012402f, + 0.011706f, + 0.011049f, + 0.010428f, + 0.009843f, + 0.009291f, + 0.008769f, + 0.008277f, + 0.007813f, + 0.007374f, + 0.006960f, + 0.006570f, + 0.006201f, + 0.005853f, + 0.005524f, + 0.005214f, + 0.004922f, + 0.004645f, + 0.004385f, + 0.004139f, + 0.003906f, + 0.003687f, + 0.003480f, + 0.003285f, + 0.003100f, + 0.002926f, + 0.002762f, + 0.002607f, + 0.002461f, + 0.002323f, + 0.002192f, + 0.002069f, + 0.001953f, + 0.001844f, + 0.001740f, + 0.001642f, + 0.001550f, + 0.001463f, + 0.001381f, + 0.001304f, + 0.001230f, + 0.001161f, + 0.001096f, + 0.001035f, + 0.000977f, + 0.000922f, + 0.000870f, + 0.000821f, + 0.000775f, + 0.000732f, + 0.000691f, + 0.000652f, +}; + +f32 __SYNGetRelativePitch(SYNVOICE* voice) { + s32 cents; + + cents = voice->cents + voice->lfoCents + voice->peCents + voice->synth->pwCents[voice->midiChannel]; + cents = cents / 65536; + + if (cents > 0) { + s32 octaves = (cents / 1200); + s32 semitones = (cents % 1200) / 100; + cents = (cents % 100); + return __SYNOctavesTableUp[octaves] * __SYNSemitonesTableUp[semitones] * __SYNCentsTable[cents]; + } + + if (cents < 0) { + s32 semitones = cents / 100; + cents = (cents % 100); + if (cents != 0) { + cents += 100; + semitones-=1; + } + semitones *= -1; + return __SYNSemitonesTableDown[semitones] * __SYNCentsTable[cents]; + } + + return 1.0f; +} + +void __SYNSetupPitch(SYNVOICE* voice) { + voice->srcRatio = (voice->sample->sampleRate / 32000.0f); + voice->cents = (voice->keyNum - voice->region->unityNote) * 100; + voice->cents = (voice->cents + voice->region->fineTune); + voice->cents = (voice->cents << 0x10); +} + +void __SYNSetupSrc(SYNVOICE* voice) { + f32 srcRatio; + u32 value; + u16* p; + + srcRatio = voice->srcRatio* __SYNGetRelativePitch(voice); + if (srcRatio > 4.0f) { + value = 0x40000; + } else { + value = (65536.0f* srcRatio); + } + + voice->axvpb->pb.srcSelect = 1; + p = (void*)&voice->axvpb->pb.src; + *(p) = (value >> 0x10); p += 1; + *(p) = (value); p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + + voice->axvpb->sync &= 0xFFF7FFFF; + voice->axvpb->sync |= 0x40001; +} + +void __SYNUpdateSrc(SYNVOICE* voice) { + u32 ratio = (65536.0f * (voice->srcRatio * __SYNGetRelativePitch(voice))); + + if (ratio > 0x40000) { + ratio = 0x40000; + } + + *(u32*)&voice->axvpb->pb.src.ratioHi = ratio; + voice->axvpb->sync |= 0x80000; +} diff --git a/src/dolphin/syn/synsample.c b/src/dolphin/syn/synsample.c new file mode 100644 index 0000000000..8419c57189 --- /dev/null +++ b/src/dolphin/syn/synsample.c @@ -0,0 +1,241 @@ +#include +#include +#include +#include "fake_tgmath.h" + +#include "__syn.h" + +// prototypes +static u32 __SYNGetNibbleAddress(u32 count); +static void __SYNSetupAdpcm(SYNVOICE* voice); +static void __SYNSetupPcm16(SYNVOICE* voice); +static void __SYNSetupPcm8(SYNVOICE* voice); + +static u32 __SYNGetNibbleAddress(u32 count) { + u32 samples = count; + u32 frames = (samples / 14); + u32 samplesLeft = (samples % 14); + + return (frames * 0x10) + 2 + samplesLeft; +} + +static void __SYNSetupAdpcm(SYNVOICE* voice) { + AXVPB* axvpb = voice->axvpb; + + if ((voice->region->loopStart + voice->region->loopLength) != 0) { + u32 sampleStart; + u32 sampleLoop; + u32 sampleEnd; + u32* p; + u32* adpcm; + u16* adpcmloop; + + adpcm = (void*)&voice->adpcm->a; + voice->type = 1; + sampleStart = voice->synth->aramBaseNibble + voice->sample->offset; + sampleLoop = sampleStart + __SYNGetNibbleAddress(voice->region->loopStart); + sampleEnd = sampleStart + __SYNGetNibbleAddress(voice->region->loopStart + voice->region->loopLength - 1); + ASSERTLINE(79, (sampleStart & 0x000f) == 0); + ASSERTLINE(80, (sampleLoop & 0x000f) > 1); + ASSERTLINE(81, (sampleEnd & 0x000f) > 1); + + // the hell? why not just write the members??? what is this doing??? + // why not just write to the members directly? + sampleStart = sampleStart + 2; + p = (u32*)&axvpb->pb.addr; + *(p) = 0x10000; p += 1; + *(p) = sampleLoop; p += 1; + *(p) = sampleEnd; p += 1; + *(p) = sampleStart; p += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + adpcmloop = (void*)(adpcm); + axvpb->pb.adpcmLoop.loop_pred_scale = *(adpcmloop); adpcmloop += 1; + axvpb->pb.adpcmLoop.loop_yn1 = *(adpcmloop); adpcmloop += 1; + axvpb->pb.adpcmLoop.loop_yn2 = *(adpcmloop); adpcmloop += 1; + axvpb->sync &= 0xFFFE1FFF; + axvpb->sync |= 0x121000; + } else { + u32 sampleStart; + u32 sampleLoop; + u32 sampleEnd; + u32* p; + u32* adpcm; + + adpcm = (void*)&voice->adpcm->a; + voice->type = 0; + sampleStart = voice->synth->aramBaseNibble + voice->sample->offset; + sampleLoop = sampleStart + __SYNGetNibbleAddress(voice->synth->zeroBaseNibble); + sampleEnd = sampleStart + __SYNGetNibbleAddress(voice->sample->length - 1); + + ASSERTLINE(135, (sampleStart & 0x000f) == 0); + ASSERTLINE(136, (sampleEnd & 0x000f) > 1); + + // same wtf writes here + sampleStart = sampleStart + 2; + p = (void*)&axvpb->pb.addr; + *(p) = 0; p += 1; + *(p) = sampleLoop; p += 1; + *(p) = sampleEnd; p += 1; + *(p) = sampleStart; p += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + *(p) = *(adpcm); p += 1, adpcm += 1; + axvpb->sync &= 0xFFFE1FFF; + axvpb->sync |= 0x21000; + } +} + +static void __SYNSetupPcm16(SYNVOICE* voice) { + AXVPB* axvpb = voice->axvpb; + + if ((voice->region->loopStart + voice->region->loopLength) != 0) { + u32 sampleStart; + u32 sampleLoop; + u32 sampleEnd; + u32* p; + + voice->type = 1; + sampleStart = voice->synth->aramBaseWord + voice->sample->offset; + sampleLoop = sampleStart + voice->region->loopStart; + sampleEnd = sampleLoop + voice->region->loopLength - 1; + + p = (u32*)&axvpb->pb.addr; + *(p) = 0x1000A; p += 1; + *(p) = sampleLoop; p += 1; + *(p) = sampleEnd; p += 1; + *(p) = sampleStart; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0x08000000; p += 1; + *(p) = 0; p += 1; + } else { + u32 sampleStart; + u32 sampleLoop; + u32 sampleEnd; + u32* p; + + voice->type = 0; + sampleStart = voice->synth->aramBaseWord + voice->sample->offset; + sampleLoop = voice->synth->zeroBaseWord; + sampleEnd = sampleStart + voice->sample->length - 1; + + p = (u32*)&axvpb->pb.addr; + *(p) = 0x0000A; p += 1; + *(p) = sampleLoop; p += 1; + *(p) = sampleEnd; p += 1; + *(p) = sampleStart; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0x08000000; p += 1; + *(p) = 0; p += 1; + } + axvpb->sync &= 0xFFFE1FFF; + axvpb->sync |= 0x21000; +} + +static void __SYNSetupPcm8(SYNVOICE* voice) { + AXVPB* axvpb = voice->axvpb; + + if ((voice->region->loopStart + voice->region->loopLength) != 0) { + u32 sampleStart; + u32 sampleLoop; + u32 sampleEnd; + u32* p; + + voice->type = 1; + sampleStart = voice->synth->aramBaseByte + voice->sample->offset; + sampleLoop = sampleStart + voice->region->loopStart; + sampleEnd = sampleLoop + voice->region->loopLength - 1; + p = (u32*)&axvpb->pb.addr; + *(p) = 0x10019; p += 1; + *(p) = sampleLoop; p += 1; + *(p) = sampleEnd; p += 1; + *(p) = sampleStart; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0x01000000; p += 1; + *(p) = 0; p += 1; + } else { + u32 sampleStart; + u32 sampleLoop; + u32 sampleEnd; + u32* p; + + voice->type = 0; + sampleStart = voice->synth->aramBaseByte + voice->sample->offset; + sampleLoop = voice->synth->zeroBaseByte; + sampleEnd = sampleStart + voice->sample->length - 1; + + p = (u32*)&axvpb->pb.addr; + *(p) = 0x19; p += 1; + *(p) = sampleLoop; p += 1; + *(p) = sampleEnd; p += 1; + *(p) = sampleStart; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0; p += 1; + *(p) = 0x01000000; p += 1; + *(p) = 0; p += 1; + } + + axvpb->sync &= 0xFFFE1FFF; + axvpb->sync |= 0x21000; +} + +void __SYNSetupSample(SYNVOICE* voice) { + ASSERTLINE(361, voice); + + switch(voice->sample->format) { + case SYN_SAMPLE_FORMAT_ADPCM: + __SYNSetupAdpcm(voice); + return; + case SYN_SAMPLE_FORMAT_PCM16: + __SYNSetupPcm16(voice); + return; + case SYN_SAMPLE_FORMAT_PCM8: + __SYNSetupPcm8(voice); + return; + default: + ASSERTMSGLINE(385, FALSE, "unknown sample format\n"); + return; + } +} diff --git a/src/dolphin/syn/synvoice.c b/src/dolphin/syn/synvoice.c new file mode 100644 index 0000000000..ea5e66d5ba --- /dev/null +++ b/src/dolphin/syn/synvoice.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include "fake_tgmath.h" + +#include "__syn.h" + +#define AX_MAX_VOICES 64 + +SYNVOICE __SYNVoice[64]; + +void __SYNClearVoiceReferences(void* p) { + AXVPB* axvpb; + SYNSYNTH* synth; + SYNVOICE* voice; + + ASSERTLINE(33, p); + + axvpb = p; + synth = (void*)axvpb->userContext; + voice = &__SYNVoice[axvpb->index]; + + ASSERTLINE(38, synth); + ASSERTLINE(39, axvpb->index < AX_MAX_VOICES); + MIXReleaseChannel(axvpb); + + if (voice->keyGroup) { + synth->keyGroup[voice->midiChannel][voice->keyGroup] = 0; + } + if (synth->voice[voice->midiChannel][voice->keyNum] == voice) { + synth->voice[voice->midiChannel][voice->keyNum] = 0; + } + + voice->synth = 0; + synth->notes--; +} + +void __SYNSetVoiceToRelease(SYNVOICE* voice, u32 priority) { + ASSERTLINE(63, voice); + voice->veState = 3; + voice->peState = 3; + AXSetVoicePriority(voice->axvpb, priority); +} + +void __SYNServiceVoice(int i) { + SYNVOICE* voice; + SYNSYNTH* synth; + + voice = &__SYNVoice[i]; + synth = voice->synth; + + if (synth != NULL) { + if ((voice->type == 0) && (voice->axvpb->pb.state == 0)) { + if (voice->keyGroup != 0) { + voice->synth->keyGroup[voice->midiChannel][voice->keyGroup] = 0; + } + if (synth->voice[voice->midiChannel][voice->keyNum] == voice) { + synth->voice[voice->midiChannel][voice->keyNum] = 0; + } + voice->veState = 4; + } + + __SYNRunVolumeEnvelope(voice); + + if (voice->veState == 4) { + if (voice->keyGroup != 0) { + voice->synth->keyGroup[voice->midiChannel][voice->keyGroup] = 0; + } + voice->synth = NULL; + MIXReleaseChannel(voice->axvpb); + AXFreeVoice(voice->axvpb); + synth->notes--; + return; + } + + __SYNRunLfo(voice); + __SYNRunPitchEnvelope(voice); + __SYNUpdateMix(voice); + __SYNUpdateSrc(voice); + } +} diff --git a/src/dolphin/syn/synwt.c b/src/dolphin/syn/synwt.c new file mode 100644 index 0000000000..6a03e030af --- /dev/null +++ b/src/dolphin/syn/synwt.c @@ -0,0 +1,21 @@ +#include +#include +#include "fake_tgmath.h" + +#include "__syn.h" + +int __SYNGetWavetableData(SYNVOICE* voice) { + u32 regionIndex; + SYNSYNTH* synth; + + synth = voice->synth; + regionIndex = synth->inst[voice->midiChannel]->keyRegion[voice->keyNum]; + if (regionIndex == 0xFFFF) { + return 0; + } + voice->region = &synth->region[regionIndex]; + voice->art = &synth->art[voice->region->articulationIndex]; + voice->sample = &synth->sample[voice->region->sampleIndex]; + voice->adpcm = &synth->adpcm[voice->sample->adpcmIndex]; + return 1; +} diff --git a/src/dolphin/texPalette/texPalette.c b/src/dolphin/texPalette/texPalette.c new file mode 100644 index 0000000000..7f3a87fdd1 --- /dev/null +++ b/src/dolphin/texPalette/texPalette.c @@ -0,0 +1,112 @@ +#include +#include +#include +#include +#include + +static void LoadTexPalette(TEXPalettePtr* pal, char* name); +static void UnpackTexPalette(TEXPalettePtr pal); +static void TexFreeFunc(TEXPalettePtr* pal); + +void TEXGetPalette(TEXPalettePtr* pal, char* name) { + void* p = TexFreeFunc; + + if (DOCacheInitialized) { + *pal = (TEXPalettePtr)DSGetCacheObj(&DODisplayCache, name); + } + + if (!*pal) { + LoadTexPalette(pal, name); + if (DOCacheInitialized) { + DSAddCacheNode(&DODisplayCache, name, (Ptr)*pal, p); + DSGetCacheObj(&DODisplayCache, name); + } + } +} + +static void LoadTexPalette(TEXPalettePtr* pal, char* name) { + DVDFileInfo dfi; + + DVDOpen(name, &dfi); + *pal = OSAlloc(OSRoundUp32B(dfi.length)); + DVDReadPrio(&dfi, *pal, OSRoundUp32B(dfi.length), 0, 2); + DVDClose(&dfi); + UnpackTexPalette(*pal); +} + +#define PALETTE_VERSION 0x20AF30 + +static void UnpackTexPalette(TEXPalettePtr pal) { + u16 i; + + if (pal->versionNumber != PALETTE_VERSION) { + OSPanic(__FILE__, 86, "invalid version number for texture palette"); + } + + pal->descriptorArray = (TEXDescriptorPtr)((Ptr)pal->descriptorArray + (u32)pal); + for (i = 0; i < pal->numDescriptors; i++) { + if (pal->descriptorArray[i].textureHeader) { + pal->descriptorArray[i].textureHeader = (TEXHeaderPtr)((Ptr)pal + (u32)pal->descriptorArray[i].textureHeader); + if (!pal->descriptorArray[i].textureHeader->unpacked) { + pal->descriptorArray[i].textureHeader->data = (Ptr)pal + (u32)pal->descriptorArray[i].textureHeader->data; + pal->descriptorArray[i].textureHeader->unpacked = TRUE; + } + } + + if (pal->descriptorArray[i].CLUTHeader) { + pal->descriptorArray[i].CLUTHeader = (CLUTHeaderPtr)((u8 *)pal + (u32)pal->descriptorArray[i].CLUTHeader); + if (!pal->descriptorArray[i].CLUTHeader->unpacked) { + pal->descriptorArray[i].CLUTHeader->data = (Ptr)pal + (u32)pal->descriptorArray[i].CLUTHeader->data; + pal->descriptorArray[i].CLUTHeader->unpacked = TRUE; + } + } + } +} + +TEXDescriptorPtr TEXGet(TEXPalettePtr pal, u32 id) { + ASSERTMSGLINE(147, id < pal->numDescriptors, "GetTexture(): Texture Not Found "); + return &pal->descriptorArray[id]; +} + +static void TexFreeFunc(TEXPalettePtr* pal) { + OSFree(*pal); + *pal = NULL; +} + +void TEXReleasePalette(TEXPalettePtr* pal) { + if (DOCacheInitialized) { + DSReleaseCacheObj(&DODisplayCache, (Ptr)*pal); + } else { + OSFree(*pal); + *pal = NULL; + } +} + +void TEXGetGXTexObjFromPalette(TEXPalettePtr pal, GXTexObj* to, u32 id) { + TEXDescriptorPtr tdp; + GXBool mipMap; + + tdp = TEXGet(pal, id); + if (tdp->textureHeader->minLOD == tdp->textureHeader->maxLOD) { + mipMap = GX_FALSE; + } else { + mipMap = GX_TRUE; + } + GXInitTexObj(to, tdp->textureHeader->data, tdp->textureHeader->width, tdp->textureHeader->height, tdp->textureHeader->format, tdp->textureHeader->wrapS, tdp->textureHeader->wrapT, mipMap); + GXInitTexObjLOD(to, tdp->textureHeader->minFilter, tdp->textureHeader->magFilter, tdp->textureHeader->minLOD, tdp->textureHeader->maxLOD, tdp->textureHeader->LODBias, GX_DISABLE, tdp->textureHeader->edgeLODEnable, GX_ANISO_1); +} + +void TEXGetGXTexObjFromPaletteCI(TEXPalettePtr pal, GXTexObj* to, GXTlutObj* tlo, GXTlut tluts, u32 id) { + GXBool mipMap; + TEXDescriptorPtr tdp; + + tdp = TEXGet(pal, id); + if (tdp->textureHeader->minLOD == tdp->textureHeader->maxLOD) { + mipMap = GX_FALSE; + } else { + mipMap = GX_TRUE; + } + GXInitTlutObj(tlo, tdp->CLUTHeader->data, tdp->CLUTHeader->format, tdp->CLUTHeader->numEntries); + GXInitTexObjCI(to, tdp->textureHeader->data, tdp->textureHeader->width, tdp->textureHeader->height, tdp->textureHeader->format, tdp->textureHeader->wrapS, tdp->textureHeader->wrapT, mipMap, tluts); + GXInitTexObjLOD(to, tdp->textureHeader->minFilter, tdp->textureHeader->magFilter, tdp->textureHeader->minLOD, tdp->textureHeader->maxLOD, tdp->textureHeader->LODBias, GX_DISABLE, tdp->textureHeader->edgeLODEnable, GX_ANISO_1); +} diff --git a/src/dolphin/vi/__vi.h b/src/dolphin/vi/__vi.h new file mode 100644 index 0000000000..1132f8cca0 --- /dev/null +++ b/src/dolphin/vi/__vi.h @@ -0,0 +1,37 @@ +#ifndef _DOLPHIN_VI_INTERNAL_H_ +#define _DOLPHIN_VI_INTERNAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* gpioexi.c */ + +void __VIInitI2C(void); +void __VISetSCL(int value); +int __VIGetSCL(void); +void __VISetSDA(int value); +int __VIGetSDA(void); + +/* i2c.c */ + +int __VISendI2CData(u8 slaveAddr, u8* pData, int nBytes); + +/* initphilips.c */ + +void __VIInitPhilips(void); + +/* vi.c */ + +void __VIInit(VITVMode mode); +void __VISetAdjustingValues(s16 x, s16 y); +void __VIGetAdjustingValues(s16* x, s16* y); +void __VIGetCurrentPosition(s16* x, s16* y); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dolphin/vi/gpioexi.c b/src/dolphin/vi/gpioexi.c new file mode 100644 index 0000000000..db3c8f3fb1 --- /dev/null +++ b/src/dolphin/vi/gpioexi.c @@ -0,0 +1,146 @@ +#include +#include +#include + +#include "__vi.h" + +static u8 shadowGPIOOE; +static u8 shadowGPIOData; + +// prototypes +static void initGpioExi(void); +static void setVideoReset(int value); +static void setI2CEnable(int value); +static int gpioOutput(u8 value); +static int gpioOE(u8 value); +static int gpioOut(u32 addr, u8 value); +static int gpioInput(u8* p); + +void __VIInitI2C(void) { + OSTime time; + + initGpioExi(); + setVideoReset(0); + time = OSGetTime(); + while (OSGetTime() - time < OS_USEC_TO_TICKS(100)) {} + setVideoReset(1); + setI2CEnable(1); +} + +static void initGpioExi(void) { + shadowGPIOOE = 0; + shadowGPIOData = 0; + gpioOutput(shadowGPIOData); + gpioOE(shadowGPIOOE); +} + +void __VISetSCL(int value) { + shadowGPIOOE &= ~2; + if (value == 0) { + shadowGPIOOE |= 2; + } + gpioOE(shadowGPIOOE); +} + +int __VIGetSCL(void) { + u8 value; + + gpioInput(&value); + if (value & 2) { + return 1; + } else { + return 0; + } +} + +void __VISetSDA(int value) { + shadowGPIOOE &= ~1; + if (value == 0) { + shadowGPIOOE |= 1; + } + gpioOE(shadowGPIOOE); +} + +int __VIGetSDA(void) { + u8 value; + + gpioInput(&value); + if (value & 1) { + return 1; + } else { + return 0; + } +} + +static void setVideoReset(int value) { + if (value != 0) { + shadowGPIOData |= 4; + } else { + shadowGPIOData &= ~4; + } + shadowGPIOOE |= 4; + gpioOutput(shadowGPIOData); + gpioOE(shadowGPIOOE); +} + +static void setI2CEnable(int value) { + if (value != 0) { + shadowGPIOData &= ~0x10; + } else { + shadowGPIOData |= 0x10; + } + shadowGPIOOE |= 0x10; + gpioOutput(shadowGPIOData); + gpioOE(shadowGPIOOE); +} + +static int gpioOutput(u8 value) { + return gpioOut(0x800404U, value); +} + +static int gpioOE(u8 value) { + return gpioOut(0x800408U, value); +} + +static int gpioOut(u32 addr, u8 value) { + u32 cmd; + + cmd = (addr | 0x02000000) << 6; + if (EXILock(0, 1, 0) == 0) { + return 0; + } + if (EXISelect(0, 1, 4) == 0) { + EXIUnlock(0); + return 0; + } + + EXIImm(0, &cmd, 4, EXI_WRITE, 0); + EXISync(0); + cmd = value << 24; + EXIImm(0, &cmd, 1, EXI_WRITE, 0); + EXISync(0); + EXIDeselect(0); + EXIUnlock(0); + return 1; +} + +static int gpioInput(u8* p) { + u32 cmd; + + if (EXILock(0, 1, 0) == 0) { + return 0; + } + if (EXISelect(0, 1, 4) == 0) { + EXIUnlock(0); + return 0; + } + cmd = 0x20010100; + EXIImm(0, &cmd, 4, EXI_WRITE, 0); + EXISync(0); + EXIImm(0, &cmd, 1, EXI_READ, 0); + EXISync(0); + EXIDeselect(0); + EXIUnlock(0); + *p = cmd >> 24; + return 1; +} diff --git a/src/dolphin/vi/i2c.c b/src/dolphin/vi/i2c.c new file mode 100644 index 0000000000..af048c61e3 --- /dev/null +++ b/src/dolphin/vi/i2c.c @@ -0,0 +1,105 @@ +#include + +#include "__vi.h" + +static int lastError; + +static int wait4ClkHigh(void) { + int n; + + for (n = 0; n < 1000; n++) { + if (__VIGetSCL() != 0) { + return 1; + } + } + + lastError = 2; + return 0; +} + +static int sendSlaveAddr(u8 slaveAddr) { + int i; + + __VISetSDA(0); + __VISetSCL(0); + + for (i = 0; i < 8; i++) { + if (slaveAddr & 0x80) { + __VISetSDA(1); + } else { + __VISetSDA(0); + } + + __VISetSCL(1); + if (wait4ClkHigh() == 0) { + return 0; + } + + __VISetSCL(0); + slaveAddr <<= 1; + } + + __VISetSDA(1); + __VISetSCL(1); + + if (wait4ClkHigh() == 0) { + return 0; + } + + if (__VIGetSDA() != 0) { + lastError = 1; + return 0; + } + + __VISetSCL(0); + return 1; +} + +int __VISendI2CData(u8 slaveAddr, u8* pData, int nBytes) { + s32 i; + u8 data; + + if (sendSlaveAddr(slaveAddr) == 0) { + return 0; + } + + while (nBytes != 0) { + data = *pData++; + for (i = 0; i < 8; i++) { + if (data & 0x80) { + __VISetSDA(1); + } else { + __VISetSDA(0); + } + + __VISetSCL(1); + + if (wait4ClkHigh() == 0) { + return 0; + } + + __VISetSCL(0); + data <<= 1; + } + + __VISetSDA(1); + __VISetSCL(1); + + if (wait4ClkHigh() == 0) { + return 0; + } + + if (nBytes != 1 && __VIGetSDA() != 0) { + lastError = 1; + return 0; + } + + __VISetSCL(0); + nBytes--; + } + + __VISetSDA(0); + __VISetSCL(1); + __VISetSDA(1); + return 1; +} diff --git a/src/dolphin/vi/initphilips.c b/src/dolphin/vi/initphilips.c new file mode 100644 index 0000000000..81358adbc6 --- /dev/null +++ b/src/dolphin/vi/initphilips.c @@ -0,0 +1,73 @@ +#include + +#include "__vi.h" + +static u8 ntscRange0[4] = { 0x00, 0x00, 0x19, 0x1D }; + +static u8 ntscRange1[38] = { + 0x2D, 0x76, 0xA5, 0x2A, + 0x2E, 0x2E, 0x00, 0x15, + 0x3F, 0x1F, 0x7C, 0xF0, + 0x21, 0x55, 0x56, 0x67, + 0x58, 0x20, 0xF9, 0x00, + 0xB0, 0x14, 0x80, 0xE8, + 0x10, 0x42, 0x03, 0x03, + 0x05, 0x16, 0x04, 0x16, + 0x18, 0x38, 0x40, 0x00, + 0x00, 0x00 +}; + +static u8 palRange0[4] = { 0x00, 0x00, 0x21, 0x1D }; + +static u8 palRange1[38] = { + 0x0C, 0x7D, 0xAF, 0x23, + 0x35, 0x35, 0x00, 0x06, + 0x2F, 0xCB, 0x8A, 0x09, + 0x2A, 0x55, 0x56, 0x67, + 0x58, 0x20, 0x05, 0x20, + 0xA0, 0x14, 0x80, 0xE8, + 0x10, 0x42, 0x03, 0x03, + 0x05, 0x16, 0x04, 0x16, + 0x18, 0x38, 0x40, 0x00, + 0x00, 0x00 +}; + +static u8 value3a = 19; + +static void send7120Data(u8 *range0, u8 *range1) { + u8 i; + u8 buffer[2]; + + for (i = 0; i < 38; i++) { + buffer[0] = i; + buffer[1] = 0; + __VISendI2CData(0x88, buffer, 2); + } + + for (i = 38; i < 42; i++) { + buffer[0] = i; + buffer[1] = range0[i - 38]; + __VISendI2CData(0x88, buffer, 2); + } + + for (i = 42; i < 58; i++) { + buffer[0] = i; + buffer[1] = 0; + __VISendI2CData(0x88, buffer, 2); + } + + buffer[0] = 0x3A; + buffer[1] = value3a; + __VISendI2CData(0x88, buffer, 2); + + for (i = 90; i < 128; i++) { + buffer[0] = i; + buffer[1] = range1[i - 90]; + __VISendI2CData(0x88, buffer, 2); + } +} + +void __VIInitPhilips(void) { + __VIInitI2C(); + send7120Data(ntscRange0, ntscRange1); +} diff --git a/src/dolphin/vi/vi.c b/src/dolphin/vi/vi.c index a1bcae9fe8..c28ed1c907 100644 --- a/src/dolphin/vi/vi.c +++ b/src/dolphin/vi/vi.c @@ -1,263 +1,266 @@ -// -// Generated By: dol2asm -// Translation Unit: vi -// +#include +#include +#include +#include +#include -#include "dolphin/vi.h" -#include "dol2asm.h" -#include "dolphin/os.h" -#include "gx/GXStruct.h" +#include "__gx.h" +#include "__os.h" +#include "__vi.h" -#define CLAMP(x, l, h) (((x) > (h)) ? (h) : (((x) < (l)) ? (l) : (x))) -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#define IS_LOWER_16MB(x) ((x) < 16 * 1024 * 1024) -#define ToPhysical(fb) (u32)(((u32)(fb)) & 0x3FFFFFFF) -#define ONES(x) ((1 << (x)) - 1) -#define VI_BITMASK(index) (1ull << (63 - (index))) +#ifdef DEBUG +const char* __VIVersion = "<< Dolphin SDK - VI\tdebug build: Apr 7 2004 03:55:59 (0x2301) >>"; +#else +const char* __VIVersion = "<< Dolphin SDK - VI\trelease build: Apr 7 2004 04:13:59 (0x2301) >>"; +#endif -#define VI_VERT_TIMING (0) -#define VI_DISP_CONFIG (1) -#define VI_HORIZ_TIMING_0L (2) -#define VI_HORIZ_TIMING_0U (3) -#define VI_HORIZ_TIMING_1L (4) -#define VI_HORIZ_TIMING_1U (5) -#define VI_VERT_TIMING_ODD (6) -#define VI_VERT_TIMING_ODD_U (7) -#define VI_VERT_TIMING_EVEN (8) -#define VI_VERT_TIMING_EVEN_U (9) +typedef struct { + u8 equ; + u16 acv; + u16 prbOdd; + u16 prbEven; + u16 psbOdd; + u16 psbEven; + u8 bs1; + u8 bs2; + u8 bs3; + u8 bs4; + u16 be1; + u16 be2; + u16 be3; + u16 be4; + u16 nhlines; + u16 hlw; + u8 hsy; + u8 hcs; + u8 hce; + u8 hbe640; + u16 hbs640; + u8 hbeCCIR656; + u16 hbsCCIR656; +} VITiming; -#define VI_BBI_ODD (10) // burst blanking interval -#define VI_BBI_ODD_U (11) // burst blanking interval -#define VI_BBI_EVEN (12) // burst blanking interval -#define VI_BBI_EVEN_U (13) // burst blanking interval +typedef struct { + u16 DispPosX; + u16 DispPosY; + u16 DispSizeX; + u16 DispSizeY; + u16 AdjustedDispPosX; + u16 AdjustedDispPosY; + u16 AdjustedDispSizeY; + u16 AdjustedPanPosY; + u16 AdjustedPanSizeY; + u16 FBSizeX; + u16 FBSizeY; + u16 PanPosX; + u16 PanPosY; + u16 PanSizeX; + u16 PanSizeY; + VIXFBMode FBMode; + u32 nonInter; + u32 tv; + u8 wordPerLine; + u8 std; + u8 wpl; + u32 bufAddr; + u32 tfbb; + u32 bfbb; + u8 xof; + BOOL black; + BOOL threeD; + u32 rbufAddr; + u32 rtfbb; + u32 rbfbb; + VITiming* timing; +} SomeVIStruct; -#define VI_TOP_FIELD_BASE_LEFT (14) // top in 2d, top of left pic in 3d -#define VI_TOP_FIELD_BASE_LEFT_U (15) // top in 2d, top of left pic in 3d - -#define VI_TOP_FIELD_BASE_RIGHT (16) // top of right pic in 3d -#define VI_TOP_FIELD_BASE_RIGHT_U (17) // top of right pic in 3d - -#define VI_BTTM_FIELD_BASE_LEFT (18) // bottom in 2d, bottom of left pic in 3d -#define VI_BTTM_FIELD_BASE_LEFT_U (19) // bottom in 2d, bottom of left pic in 3d - -#define VI_BTTM_FIELD_BASE_RIGHT (20) // bottom of right pic in 3d -#define VI_BTTM_FIELD_BASE_RIGHT_U (21) // bottom of right pic in 3d - -#define VI_VERT_COUNT (22) // vertical display position -#define VI_HORIZ_COUNT (23) // horizontal display position - -#define VI_DISP_INT_0 (24) // display interrupt 0L -#define VI_DISP_INT_0U (25) // display interrupt 0U -#define VI_DISP_INT_1 (26) // display interrupt 1L -#define VI_DISP_INT_1U (27) // display interrupt 1U -#define VI_DISP_INT_2 (28) // display interrupt 2L -#define VI_DISP_INT_2U (29) // display interrupt 2U -#define VI_DISP_INT_3 (30) // display interrupt 3L -#define VI_DISP_INT_3U (31) // display interrupt 3U - -#define VI_HSW (36) // horizontal scaling width -#define VI_HSR (37) // horizontal scaling register - -#define VI_FCT_0 (38) // filter coefficient table 0L -#define VI_FCT_0U (39) // filter coefficient table 0U -#define VI_FCT_1 (40) // filter coefficient table 1L -#define VI_FCT_1U (41) // filter coefficient table 1U -#define VI_FCT_2 (42) // filter coefficient table 2L -#define VI_FCT_2U (43) // filter coefficient table 2U -#define VI_FCT_3 (44) // filter coefficient table 3L -#define VI_FCT_3U (45) // filter coefficient table 3U -#define VI_FCT_4 (46) // filter coefficient table 4L -#define VI_FCT_4U (47) // filter coefficient table 4U -#define VI_FCT_5 (48) // filter coefficient table 5L -#define VI_FCT_5U (49) // filter coefficient table 5U -#define VI_FCT_6 (50) // filter coefficient table 6L -#define VI_FCT_6U (51) // filter coefficient table 6U - -#define VI_CLOCK_SEL (54) // clock select -#define VI_DTV_STAT (55) // DTV status - -#define VI_WIDTH (56) - -void __VIGetCurrentPosition(s16* x, s16* y); -static u32 getCurrentFieldEvenOdd(); - -// -// External References: -// - -void SIRefreshSamplingRate(); -void __shl2i(); -void __shr2u(); - -// -// Declarations: -// - -/* ############################################################################################## */ -/* 8044CA28-8044CAA0 079748 0076+02 8/8 0/0 0/0 .bss regs */ -static vu16 regs[59]; - -/* 804517E0-804517E4 000CE0 0004+00 1/1 0/0 0/0 .sbss IsInitialized */ static BOOL IsInitialized; +static volatile u32 retraceCount; -/* 804517E4-804517E8 000CE4 0004+00 4/3 0/0 0/0 .sbss retraceCount */ -static vu32 retraceCount; - -/* 804517E8-804517EC 000CE8 0004+00 3/3 0/0 0/0 .sbss flushFlag */ -static u32 flushFlag; - -/* 804517EC-804517F4 000CEC 0008+00 3/3 0/0 0/0 .sbss retraceQueue */ +static volatile u32 flushFlag; static OSThreadQueue retraceQueue; - -/* 804517F4-804517F8 000CF4 0004+00 3/3 0/0 0/0 .sbss PreCB */ -static VIRetraceCallback PreCB; - -/* 804517F8-804517FC 000CF8 0004+00 3/3 0/0 0/0 .sbss PostCB */ -static VIRetraceCallback PostCB; - -/* 804517FC-80451800 000CFC 0004+00 1/1 0/0 0/0 .sbss PositionCallback */ -static VIPositionCallback PositionCallback; - -/* 80451800-80451804 000D00 0004+00 2/2 0/0 0/0 .sbss encoderType */ +static void (*PreCB)(u32); +static void (*PostCB)(u32); +static void (*PositionCallback)(s16, s16); static u32 encoderType; - -/* 80451804 0002+00 data_80451804 displayOffsetH */ static s16 displayOffsetH; - -/* 80451806 0002+00 data_80451806 displayOffsetV */ static s16 displayOffsetV; - -/* 80451808-80451810 000D08 0004+04 3/3 0/0 0/0 .sbss changeMode */ -static vu32 changeMode; - -/* 80451810-80451814 000D10 0004+00 5/5 0/0 0/0 .sbss changed */ -static vu64 changed; - -/* 80451818-80451820 000D18 0004+04 3/3 0/0 0/0 .sbss shdwChangeMode */ -static vu32 shdwChangeMode; - -/* 80451820-80451824 000D20 0004+00 3/3 0/0 0/0 .sbss shdwChanged */ -static vu64 shdwChanged; - -/* 80451828-8045182C 000D28 0004+00 6/6 0/0 0/0 .sbss CurrTiming */ -static VITimingInfo* CurrTiming; - -/* 8045182C-80451830 000D2C 0004+00 3/3 0/0 0/0 .sbss CurrTvMode */ +static volatile u32 changeMode; +static volatile u64 changed; +static volatile u32 shdwChangeMode; +static volatile u16 regs[59]; +static volatile u64 shdwChanged; +static VITiming* CurrTiming; static u32 CurrTvMode; - -/* 80451830-80451834 000D30 0004+00 3/2 0/0 0/0 .sbss NextBufAddr */ static u32 NextBufAddr; - -/* 80451834-80451838 000D34 0004+00 2/1 0/0 0/0 .sbss CurrBufAddr */ static u32 CurrBufAddr; +static volatile u16 shdwRegs[59]; -/* ############################################################################################## */ -/* 8044CAA0-8044CB18 0797C0 0076+02 0/0 0/0 0/0 .bss shdwRegs */ -#pragma push -#pragma force_active on -static vu16 shdwRegs[59]; -#pragma pop +#define MARK_CHANGED(index) (changed |= 1LL << (63 - (index))) -/* 8044CB18-8044CB70 079838 0058+00 2/5 0/0 0/0 .bss HorVer */ -static VIPositionInfo HorVer; +static VITiming timing[10] = { + { 6, 240, 24, 25, 3, 2, 12, 13, 12, 13, 520, 519, 520, 519, 525, 429, 64, 71, 105, 162, 373, 122, 412 }, + { 6, 240, 24, 24, 4, 4, 12, 12, 12, 12, 520, 520, 520, 520, 526, 429, 64, 71, 105, 162, 373, 122, 412 }, + { 5, 287, 35, 36, 1, 0, 13, 12, 11, 10, 619, 618, 617, 620, 625, 432, 64, 75, 106, 172, 380, 133, 420 }, + { 5, 287, 33, 33, 2, 2, 13, 11, 13, 11, 619, 621, 619, 621, 624, 432, 64, 75, 106, 172, 380, 133, 420 }, + { 6, 240, 24, 25, 3, 2, 16, 15, 14, 13, 518, 517, 516, 519, 525, 429, 64, 78, 112, 162, 373, 122, 412 }, + { 6, 240, 24, 24, 4, 4, 16, 14, 16, 14, 518, 520, 518, 520, 526, 429, 64, 78, 112, 162, 373, 122, 412 }, + { 12, 480, 48, 48, 6, 6, 24, 24, 24, 24, 1038, 1038, 1038, 1038, 1050, 429, 64, 71, 105, 162, 373, 122, 412 }, + { 12, 480, 44, 44, 10, 10, 24, 24, 24, 24, 1038, 1038, 1038, 1038, 1050, 429, 64, 71, 105, 168, 379, 122, 412 }, + { 6, 241, 24, 25, 1, 0, 12, 13, 12, 13, 520, 519, 520, 519, 525, 429, 64, 71, 105, 159, 370, 122, 412 }, + { 12, 480, 48, 48, 6, 6, 24, 24, 24, 24, 1038, 1038, 1038, 1038, 1050, 429, 64, 71, 105, 180, 391, 122, 412 } +}; -static int cntlzd(u64 bit) { - u32 hi, lo; - int value; +static u16 taps[25] = { + 0x01F0, 0x01DC, + 0x01AE, 0x0174, + 0x0129, 0x00DB, + 0x008E, 0x0046, + 0x000C, 0x00E2, + 0x00CB, 0x00C0, + 0x00C4, 0x00CF, + 0x00DE, 0x00EC, + 0x00FC, 0x0008, + 0x000F, 0x0013, + 0x0013, 0x000F, + 0x000C, 0x0008, + 0x0001 +}; - hi = (u32)(bit >> 32); - lo = (u32)(bit & 0xFFFFFFFF); +static SomeVIStruct HorVer; +static u32 FBSet; +static VITiming* timingExtra; + +// prototypes +static u32 getCurrentFieldEvenOdd(void); +VITiming* __VISetExtraTiming(VITiming* t); +void __VIEnableRawPositionInterrupt(s16 x, s16 y, void (*callback)(s16, s16)); +void (*__VIDisableRawPositionInterrupt())(s16, s16); +void __VIDisplayPositionToXY(u32 hct, u32 vct, s16* x, s16* y); +void __VISetLatchMode(u32 mode); +int __VIGetLatch0Position(s16* px, s16* py); +int __VIGetLatch1Position(s16* px, s16* py); +int __VIGetLatchPosition(u32 port, s16* px, s16* py); + + +static u32 getEncoderType(void) { + return 1; +} + +static s32 cntlzd(u64 bit) { + u32 hi; + u32 lo; + s32 value; + + hi = bit >> 32; + lo = bit & 0xFFFFFFFF; value = __cntlzw(hi); - if (value < 32) { return value; } - - return (32 + __cntlzw(lo)); + return __cntlzw(lo) + 32; } -static BOOL VISetRegs(void) { - int regIndex; +static int VISetRegs(void) { + s32 regIndex; - if (!((shdwChangeMode == 1) && (getCurrentFieldEvenOdd() == 0))) { - while (shdwChanged) { + if (shdwChangeMode != 1 || getCurrentFieldEvenOdd() != 0) { + while (shdwChanged != 0) { regIndex = cntlzd(shdwChanged); __VIRegs[regIndex] = shdwRegs[regIndex]; - shdwChanged &= ~(VI_BITMASK(regIndex)); + shdwChanged &= ~((u64)1 << (63 - regIndex)); } shdwChangeMode = 0; CurrTiming = HorVer.timing; CurrTvMode = HorVer.tv; CurrBufAddr = NextBufAddr; - - return TRUE; + return 1; } - return FALSE; + + return 0; } -/* 8034BF6C-8034C1E0 3468AC 0274+00 1/1 0/0 0/0 .text __VIRetraceHandler */ -static void __VIRetraceHandler(__OSInterrupt interrupt, OSContext* context) { +static void __VIRetraceHandler(__OSInterrupt unused, OSContext* context) { OSContext exceptionContext; - u16 viReg; - u32 inter = 0; + u16 reg; + u32 inter; +#if DEBUG + static u32 dbgCount; +#endif - viReg = __VIRegs[VI_DISP_INT_0]; - if (viReg & 0x8000) { - __VIRegs[VI_DISP_INT_0] = (u16)(viReg & ~0x8000); + inter = 0; + reg = __VIRegs[0x18]; + if (reg & 0x8000) { + __VIRegs[0x18] = reg & ~0x8000; inter |= 1; } - - viReg = __VIRegs[VI_DISP_INT_1]; - if (viReg & 0x8000) { - __VIRegs[VI_DISP_INT_1] = (u16)(viReg & ~0x8000); + reg = __VIRegs[0x1A]; + if (reg & 0x8000) { + __VIRegs[0x1A] = reg & ~0x8000; inter |= 2; } - - viReg = __VIRegs[VI_DISP_INT_2]; - if (viReg & 0x8000) { - __VIRegs[VI_DISP_INT_2] = (u16)(viReg & ~0x8000); + reg = __VIRegs[0x1C]; + if (reg & 0x8000) { + __VIRegs[0x1C] = reg & ~0x8000; inter |= 4; } - - viReg = __VIRegs[VI_DISP_INT_3]; - if (viReg & 0x8000) { - __VIRegs[VI_DISP_INT_3] = (u16)(viReg & ~0x8000); + reg = __VIRegs[0x1E]; + if (reg & 0x8000) { + __VIRegs[0x1E] = reg & ~0x8000; inter |= 8; } + reg = __VIRegs[0x1E]; if ((inter & 4) || (inter & 8)) { OSClearContext(&exceptionContext); OSSetCurrentContext(&exceptionContext); - if (PositionCallback) { + + if (PositionCallback != 0) { s16 x, y; __VIGetCurrentPosition(&x, &y); (*PositionCallback)(x, y); } + OSClearContext(&exceptionContext); OSSetCurrentContext(context); return; } - retraceCount++; - - OSClearContext(&exceptionContext); - OSSetCurrentContext(&exceptionContext); - if (PreCB) { - (*PreCB)(retraceCount); + if (inter == 0) { + ASSERTLINE(955, FALSE); } - if (flushFlag) { - if (VISetRegs()) { + retraceCount += 1; + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + if (PreCB) { + PreCB(retraceCount); + } + + if (flushFlag != 0) { +#if DEBUG + dbgCount = 0; +#endif + if (VISetRegs() != 0) { flushFlag = 0; SIRefreshSamplingRate(); } } +#if DEBUG + else if (changed != 0) { + dbgCount++; + if (dbgCount > 60) { + OSReport("Warning: VIFlush() was not called for 60 frames although VI settings were changed\n"); + dbgCount = 0; + } + } +#endif if (PostCB) { OSClearContext(&exceptionContext); - (*PostCB)(retraceCount); + PostCB(retraceCount); } OSWakeupThread(&retraceQueue); @@ -265,259 +268,171 @@ static void __VIRetraceHandler(__OSInterrupt interrupt, OSContext* context) { OSSetCurrentContext(context); } -/* 8034C1E0-8034C224 346B20 0044+00 0/0 4/4 0/0 .text VISetPreRetraceCallback */ VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback cb) { - VIRetraceCallback prevCb = PreCB; - BOOL enable = OSDisableInterrupts(); + BOOL enabled; + VIRetraceCallback oldcb; + + oldcb = PreCB; + enabled = OSDisableInterrupts(); PreCB = cb; - OSRestoreInterrupts(enable); - return prevCb; + OSRestoreInterrupts(enabled); + return oldcb; } -/* 8034C224-8034C268 346B64 0044+00 0/0 4/4 2/2 .text VISetPostRetraceCallback */ VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback cb) { - VIRetraceCallback prevCb = PostCB; - BOOL enable = OSDisableInterrupts(); + BOOL enabled; + VIRetraceCallback oldcb; + + oldcb = PostCB; + enabled = OSDisableInterrupts(); PostCB = cb; - OSRestoreInterrupts(enable); - return prevCb; + OSRestoreInterrupts(enabled); + return oldcb; } -/* ############################################################################################## */ -/* 803D1760-803D17A4 02E880 0044+00 4/3 0/0 0/0 .data @1 */ -SECTION_DATA static char lit_1[] = - "<< Dolphin SDK - VI\trelease build: Apr 7 2004 04:13:59 (0x2301) >>"; +VITiming* __VISetExtraTiming(VITiming* t) { + VITiming* old = timingExtra; -/* 803D17A4-803D1920 02E8C4 017C+00 0/1 0/0 0/0 .data timing */ -static VITimingInfo timing[10] = { - { - // NTSC INT - 6, 240, 24, 25, 3, 2, 12, 13, 12, 13, 520, 519, - 520, 519, 525, 429, 64, 71, 105, 162, 373, 122, 412, - }, - { - // NTSC DS - 6, 240, 24, 24, 4, 4, 12, 12, 12, 12, 520, 520, - 520, 520, 526, 429, 64, 71, 105, 162, 373, 122, 412, - }, - { - // PAL INT - 5, 287, 35, 36, 1, 0, 13, 12, 11, 10, 619, 618, - 617, 620, 625, 432, 64, 75, 106, 172, 380, 133, 420, - }, - { - // PAL DS - 5, 287, 33, 33, 2, 2, 13, 11, 13, 11, 619, 621, - 619, 621, 624, 432, 64, 75, 106, 172, 380, 133, 420, - }, - { - // MPAL INT - 6, 240, 24, 25, 3, 2, 16, 15, 14, 13, 518, 517, - 516, 519, 525, 429, 64, 78, 112, 162, 373, 122, 412, - }, - { - // MPAL DS - 6, 240, 24, 24, 4, 4, 16, 14, 16, 14, 518, 520, - 518, 520, 526, 429, 64, 78, 112, 162, 373, 122, 412, - }, - { - // NTSC PRO - 12, 480, 48, 48, 6, 6, 24, 24, 24, 24, 1038, 1038, - 1038, 1038, 1050, 429, 64, 71, 105, 162, 373, 122, 412, - }, - { - // NTSC 3D - 12, 480, 44, 44, 10, 10, 24, 24, 24, 24, 1038, 1038, - 1038, 1038, 1050, 429, 64, 71, 105, 168, 379, 122, 412, - }, - { - // GCA INT - 6, 241, 24, 25, 1, 0, 12, 13, 12, 13, 520, 519, - 520, 519, 525, 429, 64, 71, 105, 159, 370, 122, 412, - }, - { - // GCA DS - 12, 480, 48, 48, 6, 6, 24, 24, 24, 24, 1038, 1038, - 1038, 1038, 1050, 429, 64, 71, 105, 180, 391, 122, 412, - }, -}; + timingExtra = t; + return old; +} -/* 803D1920-803D1954 02EA40 0032+02 0/1 0/0 0/0 .data taps */ -#pragma push -#pragma force_active on -static u16 taps[] = {496, 476, 430, 372, 297, 219, 142, 70, 12, 226, 203, 192, 196, - 207, 222, 236, 252, 8, 15, 19, 19, 15, 12, 8, 1}; -#pragma pop - -/* 80451838-8045183C 000D38 0004+00 2/2 0/0 0/0 .sbss FBSet */ -static u32 FBSet; - -/* 8045183C-80451840 000D3C 0004+00 1/1 0/0 0/0 .sbss timingExtra */ -static VITimingInfo* timingExtra; - -/* 8034C268-8034C310 346BA8 00A8+00 4/3 0/0 0/0 .text getTiming */ -static VITimingInfo* getTiming(VITVMode mode) { +#pragma dont_inline on +static VITiming* getTiming(VITVMode mode) { switch (mode) { - case VI_TVMODE_NTSC_INT: - return &timing[0]; - case VI_TVMODE_NTSC_DS: - return &timing[1]; - - case VI_TVMODE_PAL_INT: - return &timing[2]; - case VI_TVMODE_PAL_DS: - return &timing[3]; - - case VI_TVMODE_EURGB60_INT: - return &timing[0]; - case VI_TVMODE_EURGB60_DS: - return &timing[1]; - - case VI_TVMODE_MPAL_INT: - return &timing[4]; - case VI_TVMODE_MPAL_DS: - return &timing[5]; - - case VI_TVMODE_NTSC_PROG: - return &timing[6]; - case VI_TVMODE_NTSC_3D: - return &timing[7]; - - case VI_TVMODE_DEBUG_PAL_INT: - return &timing[2]; - case VI_TVMODE_DEBUG_PAL_DS: - return &timing[3]; - - case VI_TVMODE_GCA_INT: - return &timing[8]; - case VI_TVMODE_GCA_PROG: - return &timing[9]; - + case VI_TVMODE_NTSC_INT: return &timing[0]; + case VI_TVMODE_NTSC_DS: return &timing[1]; + case VI_TVMODE_PAL_INT: return &timing[2]; + case VI_TVMODE_PAL_DS: return &timing[3]; + case VI_TVMODE_EURGB60_INT: return &timing[0]; + case VI_TVMODE_EURGB60_DS: return &timing[1]; + case VI_TVMODE_MPAL_INT: return &timing[4]; + case VI_TVMODE_MPAL_DS: return &timing[5]; + case VI_TVMODE_NTSC_PROG: return &timing[6]; + case 3: return &timing[7]; + case VI_TVMODE_DEBUG_PAL_INT: return &timing[2]; + case VI_TVMODE_DEBUG_PAL_DS: return &timing[3]; + case 24: return &timing[8]; + case 26: return &timing[9]; case 29: case 30: case 28: return timingExtra; + default: + return NULL; } - - return NULL; } +#pragma dont_inline reset -/* 8034C310-8034C514 346C50 0204+00 1/1 0/0 0/0 .text __VIInit */ void __VIInit(VITVMode mode) { - VITimingInfo* tm; + VITiming* tm; u32 nonInter; - vu32 a, b; - u32 tv, tvForReg; + u32 tv; + u32 tvForReg; + volatile u32 a; + u16 hct; + u16 vct; + u32 encoderType; - u16 hct, vct; - - tv = (u32)mode >> 2; - nonInter = mode & 3; - - *(u32*)OSPhysicalToCached(0xCC) = tv; - - tm = getTiming(mode); - - __VIRegs[VI_DISP_CONFIG] = 2; - for (a = 0; a < 1000; a++) { - ; + encoderType = getEncoderType(); + if (encoderType == 0) { + __VIInitPhilips(); } - __VIRegs[VI_DISP_CONFIG] = 0; + nonInter = mode & 3; + tv = (u32)mode >> 2; + *(u32*)OSPhysicalToCached(0xCC) = tv; + if (encoderType == 0) { + tv = 3; + } + tm = getTiming(mode); + __VIRegs[1] = 2; - __VIRegs[VI_HORIZ_TIMING_0U] = tm->hlw << 0; - __VIRegs[VI_HORIZ_TIMING_0L] = (tm->hce << 0) | (tm->hcs << 8); + // why? + for (a = 0; a < 1000; a++) {} - __VIRegs[VI_HORIZ_TIMING_1U] = (tm->hsy << 0) | ((tm->hbe640 & ((1 << 9) - 1)) << 7); - __VIRegs[VI_HORIZ_TIMING_1L] = ((tm->hbe640 >> 9) << 0) | (tm->hbs640 << 1); + __VIRegs[1] = 0; + __VIRegs[3] = (u32)tm->hlw; + __VIRegs[2] = tm->hce | (tm->hcs << 8); + __VIRegs[5] = tm->hsy | ((tm->hbe640 & 0x1FF) << 7); + __VIRegs[4] = (tm->hbe640 >> 9) | ((tm->hbs640 & 0xFFFF) << 1); + if (encoderType == 0) { + __VIRegs[0x39] = tm->hbeCCIR656 | 0x8000; + __VIRegs[0x3A] = (u32)tm->hbsCCIR656; + } + __VIRegs[0] = (u32)tm->equ; + __VIRegs[7] = (u32)(tm->prbOdd + (tm->acv * 2) - 2); + __VIRegs[6] = (u32)(tm->psbOdd + 2); + __VIRegs[9] = (u32)(tm->prbEven + (tm->acv * 2) - 2); + __VIRegs[8] = (u32)(tm->psbEven + 2); + __VIRegs[11] = tm->bs1 | (tm->be1 << 5); + __VIRegs[10] = tm->bs3 | (tm->be3 << 5); + __VIRegs[13] = tm->bs2 | (tm->be2 << 5); + __VIRegs[12] = tm->bs4 | (tm->be4 << 5); + __VIRegs[36] = 0x2828; + __VIRegs[27] = 1; + __VIRegs[26] = 0x1001; + hct = tm->hlw + 1; + vct = (tm->nhlines / 2) + 1; + __VIRegs[25] = (u16)(u32)hct; + __VIRegs[24] = vct | 0x1000; - __VIRegs[VI_VERT_TIMING] = (tm->equ << 0) | (0 << 4); - - __VIRegs[VI_VERT_TIMING_ODD_U] = (tm->prbOdd + tm->acv * 2 - 2) << 0; - __VIRegs[VI_VERT_TIMING_ODD] = tm->psbOdd + 2 << 0; - - __VIRegs[VI_VERT_TIMING_EVEN_U] = (tm->prbEven + tm->acv * 2 - 2) << 0; - __VIRegs[VI_VERT_TIMING_EVEN] = tm->psbEven + 2 << 0; - - __VIRegs[VI_BBI_ODD_U] = (tm->bs1 << 0) | (tm->be1 << 5); - __VIRegs[VI_BBI_ODD] = (tm->bs3 << 0) | (tm->be3 << 5); - - __VIRegs[VI_BBI_EVEN_U] = (tm->bs2 << 0) | (tm->be2 << 5); - __VIRegs[VI_BBI_EVEN] = (tm->bs4 << 0) | (tm->be4 << 5); - - __VIRegs[VI_HSW] = (40 << 0) | (40 << 8); - - __VIRegs[VI_DISP_INT_1U] = 1; - __VIRegs[VI_DISP_INT_1] = (1 << 0) | (1 << 12) | (0 << 15); - - hct = (tm->hlw + 1); - vct = (tm->numHalfLines / 2 + 1) | (1 << 12) | (0 << 15); - __VIRegs[VI_DISP_INT_0U] = hct << 0; - __VIRegs[VI_DISP_INT_0] = vct; - switch (tv) { - case VI_TVMODE_NTSC_DS: - case VI_TVMODE_NTSC_PROG: - case VI_TVMODE_NTSC_3D: + case 1: + case 2: + case 3: tvForReg = tv; break; default: tvForReg = 0; - break; } - if (nonInter <= 1) { - __VIRegs[VI_DISP_CONFIG] = - (1 << 0) | (0 << 1) | ((nonInter & 1) << 2) | (0 << 3) | (0 << 4) | (0 << 6) | (tvForReg << 8); - __VIRegs[VI_CLOCK_SEL] = 0; - } else { - __VIRegs[VI_DISP_CONFIG] = - (1 << 0) | (0 << 1) | (1 << 2) | (0 << 3) | (0 << 4) | (0 << 6) | (tvForReg << 8); - __VIRegs[VI_CLOCK_SEL] = 1; + if (nonInter == 0 || nonInter == 1) { + __VIRegs[1] = ((nonInter << 2) & 4) | 1 | (tvForReg << 8); + __VIRegs[54] = 0; + return; } + + __VIRegs[1] = (tvForReg << 8) | 5; + __VIRegs[54] = 1; } -/* 80450A10-80450A14 -00001 0004+00 1/1 0/0 0/0 .sdata __VIVersion */ -SECTION_SDATA static void* __VIVersion = (void*)&lit_1; +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define CLAMP(val, min, max) ((val) > (max) ? (max) : (val) < (min) ? (min) : (val)) static void AdjustPosition(u16 acv) { - s32 coeff, frac; + s32 coeff; + s32 frac; - HorVer.adjDispPosX = - (u16)CLAMP((s16)HorVer.dispPosX + displayOffsetH, 0, 720 - HorVer.dispSizeX); - - coeff = (HorVer.xfbMode == VI_XFBMODE_SF) ? 2 : 1; - frac = HorVer.dispPosY & 1; - - HorVer.adjDispPosY = (u16)MAX((s16)HorVer.dispPosY + displayOffsetV, frac); - - HorVer.adjDispSizeY = - (u16)(HorVer.dispSizeY + MIN((s16)HorVer.dispPosY + displayOffsetV - frac, 0) - - MAX((s16)HorVer.dispPosY + (s16)HorVer.dispSizeY + displayOffsetV - - ((s16)acv * 2 - frac), - 0)); - - HorVer.adjPanPosY = - (u16)(HorVer.panPosY - MIN((s16)HorVer.dispPosY + displayOffsetV - frac, 0) / coeff); - - HorVer.adjPanSizeY = - (u16)(HorVer.panSizeY + MIN((s16)HorVer.dispPosY + displayOffsetV - frac, 0) / coeff - - MAX((s16)HorVer.dispPosY + (s16)HorVer.dispSizeY + displayOffsetV - - ((s16)acv * 2 - frac), - 0) / - coeff); + HorVer.AdjustedDispPosX = CLAMP((s16)HorVer.DispPosX + displayOffsetH, 0, 0x2D0 - HorVer.DispSizeX); + coeff = (HorVer.FBMode == VI_XFBMODE_SF) ? 2 : 1; + frac = HorVer.DispPosY & 1; + HorVer.AdjustedDispPosY = MAX((s16)HorVer.DispPosY + displayOffsetV, frac); + HorVer.AdjustedDispSizeY = HorVer.DispSizeY + + MIN((s16)HorVer.DispPosY + displayOffsetV - frac, 0) + - MAX((s16)HorVer.DispPosY + (s16)HorVer.DispSizeY + displayOffsetV - (((s16)acv * 2) - frac), 0); + HorVer.AdjustedPanPosY = HorVer.PanPosY + - (MIN((s16)HorVer.DispPosY + displayOffsetV - frac, 0) / coeff); + HorVer.AdjustedPanSizeY = HorVer.PanSizeY + + (MIN((s16)HorVer.DispPosY + displayOffsetV - frac, 0) / coeff) + - (MAX((s16)HorVer.DispPosY + (s16)HorVer.DispSizeY + displayOffsetV - (((s16)acv * 2) - frac), 0) / coeff); } static void ImportAdjustingValues(void) { - displayOffsetH = __OSLockSram()->displayOffsetH; + OSSram* sram = __OSLockSram(); + + ASSERTLINE(1322, sram); + displayOffsetH = sram->displayOffsetH; displayOffsetV = 0; - __OSUnlockSram(FALSE); + __OSUnlockSram(0); } -/* 8034C514-8034C9C4 346E54 04B0+00 0/0 1/1 0/0 .text VIInit */ void VIInit(void) { u16 dspCfg; - u32 value, tv, tvInBootrom; + u32 value; + u32 tv; + u32 tvInBootrom; if (IsInitialized) { return; @@ -525,9 +440,9 @@ void VIInit(void) { OSRegisterVersion(__VIVersion); IsInitialized = TRUE; - encoderType = 1; - if (!(__VIRegs[VI_DISP_CONFIG] & 1)) { + encoderType = getEncoderType(); + if (!(__VIRegs[1] & 1)) { __VIInit(VI_TVMODE_NTSC_INT); } @@ -538,190 +453,186 @@ void VIInit(void) { shdwChangeMode = 0; flushFlag = 0; - __VIRegs[VI_FCT_0U] = ((((taps[0])) << 0) | (((taps[1] & ((1 << (6)) - 1))) << 10)); - __VIRegs[VI_FCT_0] = ((((taps[1] >> 6)) << 0) | (((taps[2])) << 4)); - __VIRegs[VI_FCT_1U] = ((((taps[3])) << 0) | (((taps[4] & ((1 << (6)) - 1))) << 10)); - __VIRegs[VI_FCT_1] = ((((taps[4] >> 6)) << 0) | (((taps[5])) << 4)); - __VIRegs[VI_FCT_2U] = ((((taps[6])) << 0) | (((taps[7] & ((1 << (6)) - 1))) << 10)); - __VIRegs[VI_FCT_2] = ((((taps[7] >> 6)) << 0) | (((taps[8])) << 4)); - __VIRegs[VI_FCT_3U] = ((((taps[9])) << 0) | (((taps[10])) << 8)); - __VIRegs[VI_FCT_3] = ((((taps[11])) << 0) | (((taps[12])) << 8)); - __VIRegs[VI_FCT_4U] = ((((taps[13])) << 0) | (((taps[14])) << 8)); - __VIRegs[VI_FCT_4] = ((((taps[15])) << 0) | (((taps[16])) << 8)); - __VIRegs[VI_FCT_5U] = ((((taps[17])) << 0) | (((taps[18])) << 8)); - __VIRegs[VI_FCT_5] = ((((taps[19])) << 0) | (((taps[20])) << 8)); - __VIRegs[VI_FCT_6U] = ((((taps[21])) << 0) | (((taps[22])) << 8)); - __VIRegs[VI_FCT_6] = ((((taps[23])) << 0) | (((taps[24])) << 8)); - - __VIRegs[VI_WIDTH] = 640; + __VIRegs[39] = taps[0] | ((taps[1] & 0x3F) << 10); + __VIRegs[38] = (taps[1] >> 6) | (taps[2] << 4); + __VIRegs[41] = taps[3] | ((taps[4] & 0x3F) << 10); + __VIRegs[40] = (taps[4] >> 6) | (taps[5] << 4); + __VIRegs[43] = taps[6] | ((taps[7] & 0x3F) << 10); + __VIRegs[42] = (taps[7] >> 6) | (taps[8] << 4); + __VIRegs[45] = taps[9] | (taps[10] << 8); + __VIRegs[44] = taps[11] | (taps[12] << 8); + __VIRegs[47] = taps[13] | (taps[14] << 8); + __VIRegs[46] = taps[15] | (taps[16] << 8); + __VIRegs[49] = taps[17] | (taps[18] << 8); + __VIRegs[48] = taps[19] | (taps[20] << 8); + __VIRegs[51] = taps[21] | (taps[22] << 8); + __VIRegs[50] = taps[23] | (taps[24] << 8); + __VIRegs[56] = 0x280; ImportAdjustingValues(); + tvInBootrom = *(u32*)OSPhysicalToCached(0xCC); - dspCfg = __VIRegs[VI_DISP_CONFIG]; + dspCfg = __VIRegs[1]; + HorVer.nonInter = (s32) ((dspCfg >> 2U) & 1); + HorVer.tv = ((u32)(dspCfg) & 0x300) >> 8; - HorVer.nonInter = ((((u32)(dspCfg)) >> 2 & 0x00000001)); - HorVer.tv = ((((u32)(dspCfg)) & 0x00000300) >> 8); - - if ((tvInBootrom == VI_PAL) && (HorVer.tv == VI_NTSC)) { + if (tvInBootrom == VI_PAL && HorVer.tv == VI_NTSC) { HorVer.tv = VI_EURGB60; } - tv = (HorVer.tv == VI_DEBUG) ? VI_NTSC : HorVer.tv; - HorVer.timing = getTiming((VITVMode)VI_TVMODE(tv, HorVer.nonInter)); - regs[VI_DISP_CONFIG] = dspCfg; + tv = (HorVer.tv == 3) ? 0 : HorVer.tv; + HorVer.timing = getTiming((tv << 2) + HorVer.nonInter); + regs[1] = dspCfg; CurrTiming = HorVer.timing; CurrTvMode = HorVer.tv; - HorVer.dispSizeX = 640; - HorVer.dispSizeY = (u16)(CurrTiming->acv * 2); - HorVer.dispPosX = (u16)((720 - HorVer.dispSizeX) / 2); - HorVer.dispPosY = 0; - + HorVer.DispSizeX = 640; + HorVer.DispSizeY = CurrTiming->acv * 2; + HorVer.DispPosX = (720 - HorVer.DispSizeX) / 2; + HorVer.DispPosY = 0; AdjustPosition(CurrTiming->acv); + HorVer.FBSizeX = 640; + HorVer.FBSizeY = CurrTiming->acv * 2; + HorVer.PanPosX = 0; + HorVer.PanPosY = 0; + HorVer.PanSizeX = 640; + HorVer.PanSizeY = CurrTiming->acv * 2; + HorVer.FBMode = 0; - HorVer.fbSizeX = 640; - HorVer.fbSizeY = (u16)(CurrTiming->acv * 2); - HorVer.panPosX = 0; - HorVer.panPosY = 0; - HorVer.panSizeX = 640; - HorVer.panSizeY = (u16)(CurrTiming->acv * 2); - HorVer.xfbMode = VI_XFBMODE_SF; HorVer.wordPerLine = 40; HorVer.std = 40; HorVer.wpl = 40; HorVer.xof = 0; - HorVer.isBlack = TRUE; - HorVer.is3D = FALSE; - + HorVer.black = 1; + HorVer.threeD = 0; OSInitThreadQueue(&retraceQueue); - - value = __VIRegs[VI_DISP_INT_0]; - value = (((u32)(value)) & ~0x00008000) | (((0)) << 15); - __VIRegs[VI_DISP_INT_0] = value; - - value = __VIRegs[VI_DISP_INT_1]; - value = (((u32)(value)) & ~0x00008000) | (((0)) << 15); - __VIRegs[VI_DISP_INT_1] = value; - + value = __VIRegs[24]; + value &= ~0x8000; +#if !DEBUG + value = (u16)value; +#endif + __VIRegs[24] = value; + value = __VIRegs[26]; + value = value & ~0x8000; +#if !DEBUG + value = (u16)value; +#endif + __VIRegs[26] = value; PreCB = NULL; PostCB = NULL; - - __OSSetInterruptHandler(24, __VIRetraceHandler); - __OSUnmaskInterrupts((0x80000000u >> (24))); + __OSSetInterruptHandler(0x18, __VIRetraceHandler); + __OSUnmaskInterrupts(0x80); } -/* 8034C9C4-8034CA18 347304 0054+00 0/0 10/10 0/0 .text VIWaitForRetrace */ -void VIWaitForRetrace() { - BOOL enable = OSDisableInterrupts(); - u32 startVal = retraceCount; +void VIWaitForRetrace(void) { + BOOL enabled; + u32 count; + enabled = OSDisableInterrupts(); + count = retraceCount; do { OSSleepThread(&retraceQueue); - } while (startVal == retraceCount); - - OSRestoreInterrupts(enable); + } while (count == retraceCount); + OSRestoreInterrupts(enabled); } -static void setInterruptRegs(VITimingInfo* tm) { - u16 vct, hct, borrow; - - vct = (u16)(tm->numHalfLines / 2); - borrow = (u16)(tm->numHalfLines % 2); - hct = (u16)((borrow) ? tm->hlw : (u16)0); +static void setInterruptRegs(VITiming* tm) { +#if DEBUG + u16 vct, hct; +#else + u16 hct, vct; +#endif + u16 borrow; + vct = tm->nhlines / 2; + borrow = tm->nhlines % 2; + if (borrow != 0) { + hct = tm->hlw; + } else { + hct = 0; + } vct++; hct++; + regs[25] = (u16)(u32)hct; + MARK_CHANGED(25); + regs[24] = vct | 0x1000; + MARK_CHANGED(24); - regs[VI_DISP_INT_0U] = (u16)hct; - changed |= VI_BITMASK(VI_DISP_INT_0U); - - regs[VI_DISP_INT_0] = (u16)((((u32)(vct))) | (((u32)(1)) << 12) | (((u32)(0)) << 15)); - changed |= VI_BITMASK(VI_DISP_INT_0); + vct; // fixes regalloc } -static void setPicConfig(u16 fbSizeX, VIXFBMode xfbMode, u16 panPosX, u16 panSizeX, u8* wordPerLine, - u8* std, u8* wpl, u8* xof) { - *wordPerLine = (u8)((fbSizeX + 15) / 16); - *std = (u8)((xfbMode == VI_XFBMODE_SF) ? *wordPerLine : (u8)(2 * *wordPerLine)); - *xof = (u8)(panPosX % 16); - *wpl = (u8)((*xof + panSizeX + 15) / 16); - - regs[VI_HSW] = (u16)((((u32)(*std))) | (((u32)(*wpl)) << 8)); - changed |= VI_BITMASK(VI_HSW); +static void setPicConfig(u16 fbSizeX, VIXFBMode xfbMode, u16 panPosX, u16 panSizeX, u8* wordPerLine, u8* std, u8* wpl, u8* xof) { + *wordPerLine = (fbSizeX + 15) / 16; + *std = (xfbMode == VI_XFBMODE_SF) ? *wordPerLine : (u8)(*wordPerLine * 2); + *xof = panPosX % 16; + *wpl = (*xof + panSizeX + 15) / 16; + regs[0x24] = *std | (*wpl << 8); + changed |= 0x8000000; } -static void setBBIntervalRegs(VITimingInfo* tm) { +static void setBBIntervalRegs(VITiming* tm) { u16 val; - val = (u16)((((u32)(tm->bs1))) | (((u32)(tm->be1)) << 5)); - regs[VI_BBI_ODD_U] = val; - changed |= VI_BITMASK(VI_BBI_ODD_U); + val = tm->bs1 | (tm->be1 << 5); + regs[11] = val; + changed |= 0x10000000000000; - val = (u16)((((u32)(tm->bs3))) | (((u32)(tm->be3)) << 5)); - regs[VI_BBI_ODD] = val; - changed |= VI_BITMASK(VI_BBI_ODD); + val = tm->bs3 | (tm->be3 << 5); + regs[10] = val; + changed |= 0x20000000000000; - val = (u16)((((u32)(tm->bs2))) | (((u32)(tm->be2)) << 5)); - regs[VI_BBI_EVEN_U] = val; - changed |= VI_BITMASK(VI_BBI_EVEN_U); + val = tm->bs2 | (tm->be2 << 5); + regs[13] = val; + changed |= 0x4000000000000; - val = (u16)((((u32)(tm->bs4))) | (((u32)(tm->be4)) << 5)); - regs[VI_BBI_EVEN] = val; - changed |= VI_BITMASK(VI_BBI_EVEN); + val = tm->bs4 | (tm->be4 << 5); + regs[12] = val; + changed |= (1LL << (63-12)); } -static void setScalingRegs(u16 panSizeX, u16 dispSizeX, BOOL is3D) { +static void setScalingRegs(u16 panSizeX, u16 dispSizeX, BOOL threeD) { u32 scale; - panSizeX = (u16)(is3D ? panSizeX * 2 : panSizeX); - + panSizeX = threeD ? (panSizeX << 1) : panSizeX; if (panSizeX < dispSizeX) { - scale = (256 * (u32)panSizeX + (u32)dispSizeX - 1) / (u32)dispSizeX; - - regs[VI_HSR] = (u16)((((u32)(scale))) | (((u32)(1)) << 12)); - changed |= VI_BITMASK(VI_HSR); - - regs[VI_WIDTH] = (u16)((((u32)(panSizeX)))); - changed |= VI_BITMASK(VI_WIDTH); + scale = (u32)(dispSizeX + (panSizeX << 8) - 1) / dispSizeX; + regs[37] = scale | 0x1000; + changed |= 0x04000000; + regs[56] = (u32)panSizeX; + changed |= 0x80; } else { - regs[VI_HSR] = (u16)((((u32)(256))) | (((u32)(0)) << 12)); - changed |= VI_BITMASK(VI_HSR); + regs[37] = 0x100; + changed |= 0x04000000; } } -static void calcFbbs(u32 bufAddr, u16 panPosX, u16 panPosY, u8 wordPerLine, VIXFBMode xfbMode, - u16 dispPosY, u32* tfbb, u32* bfbb) { - u32 bytesPerLine, xoffInWords; - xoffInWords = (u32)panPosX / 16; - bytesPerLine = (u32)wordPerLine * 32; - - *tfbb = bufAddr + xoffInWords * 32 + bytesPerLine * panPosY; - *bfbb = (xfbMode == VI_XFBMODE_SF) ? *tfbb : (*tfbb + bytesPerLine); +static void calcFbbs(u32 bufAddr, u16 panPosX, u16 panPosY, u8 wordPerLine, VIXFBMode xfbMode, u16 dispPosY, u32* tfbb, u32* bfbb) { + u32 bytesPerLine; + u32 xoffInWords; + u32 tmp; + xoffInWords = (panPosX & ~0xF) >> 4; + bytesPerLine = (wordPerLine & 0xFF) << 5; + *tfbb = bufAddr + (xoffInWords << 5) + (bytesPerLine * panPosY); + *bfbb = (xfbMode == VI_XFBMODE_SF) ? *tfbb : *tfbb + bytesPerLine; if (dispPosY % 2 == 1) { - u32 tmp = *tfbb; + tmp = *tfbb; *tfbb = *bfbb; *bfbb = tmp; } - - *tfbb = ToPhysical(*tfbb); - *bfbb = ToPhysical(*bfbb); + *tfbb &= 0x3FFFFFFF; + *bfbb &= 0x3FFFFFFF; } -/* 8034CA18-8034CCEC 347358 02D4+00 2/2 0/0 0/0 .text setFbbRegs */ -static void setFbbRegs(VIPositionInfo* hv, u32* tfbb, u32* bfbb, u32* rtfbb, u32* rbfbb) { +static void setFbbRegs(SomeVIStruct* HorVer, u32* tfbb, u32* bfbb, u32* rtfbb, u32* rbfbb) { u32 shifted; - calcFbbs(hv->bufAddr, hv->panPosX, hv->adjPanPosY, hv->wordPerLine, hv->xfbMode, - hv->adjDispPosY, tfbb, bfbb); - if (hv->is3D) { - calcFbbs(hv->rbufAddr, hv->panPosX, hv->adjPanPosY, hv->wordPerLine, hv->xfbMode, - hv->adjDispPosY, rtfbb, rbfbb); + calcFbbs(HorVer->bufAddr, HorVer->PanPosX, HorVer->AdjustedPanPosY, HorVer->wordPerLine, HorVer->FBMode, HorVer->AdjustedDispPosY, tfbb, bfbb); + if (HorVer->threeD) { + calcFbbs(HorVer->rbufAddr, HorVer->PanPosX, HorVer->AdjustedPanPosY, HorVer->wordPerLine, HorVer->FBMode, HorVer->AdjustedDispPosY, rtfbb, rbfbb); } - if (IS_LOWER_16MB(*tfbb) && IS_LOWER_16MB(*bfbb) && IS_LOWER_16MB(*rtfbb) && - IS_LOWER_16MB(*rbfbb)) - { + if (*tfbb < 0x01000000U && *bfbb < 0x01000000U && *rtfbb < 0x01000000U && *rbfbb < 0x01000000U) { shifted = 0; } else { shifted = 1; @@ -734,61 +645,57 @@ static void setFbbRegs(VIPositionInfo* hv, u32* tfbb, u32* bfbb, u32* rtfbb, u32 *rbfbb >>= 5; } - regs[VI_TOP_FIELD_BASE_LEFT_U] = (u16)(*tfbb & 0xFFFF); - changed |= VI_BITMASK(VI_TOP_FIELD_BASE_LEFT_U); + regs[15] = (u16)*tfbb & 0xFFFF; + MARK_CHANGED(15); + regs[14] = (shifted << 12) | ((*tfbb >> 16) | (HorVer->xof << 8)); + MARK_CHANGED(14); + regs[19] = (u16)*bfbb & 0xFFFF; + MARK_CHANGED(19); + regs[18] = (*bfbb >> 16); + MARK_CHANGED(18); - regs[VI_TOP_FIELD_BASE_LEFT] = (u16)((((*tfbb >> 16))) | hv->xof << 8 | shifted << 12); - changed |= VI_BITMASK(VI_TOP_FIELD_BASE_LEFT); - - regs[VI_BTTM_FIELD_BASE_LEFT_U] = (u16)(*bfbb & 0xFFFF); - changed |= VI_BITMASK(VI_BTTM_FIELD_BASE_LEFT_U); - - regs[VI_BTTM_FIELD_BASE_LEFT] = (u16)(*bfbb >> 16); - changed |= VI_BITMASK(VI_BTTM_FIELD_BASE_LEFT); - - if (hv->is3D) { - regs[VI_TOP_FIELD_BASE_RIGHT_U] = *rtfbb & 0xffff; - changed |= VI_BITMASK(VI_TOP_FIELD_BASE_RIGHT_U); - - regs[VI_TOP_FIELD_BASE_RIGHT] = *rtfbb >> 16; - changed |= VI_BITMASK(VI_TOP_FIELD_BASE_RIGHT); - - regs[VI_BTTM_FIELD_BASE_RIGHT_U] = *rbfbb & 0xFFFF; - changed |= VI_BITMASK(VI_BTTM_FIELD_BASE_RIGHT_U); - - regs[VI_BTTM_FIELD_BASE_RIGHT] = *rbfbb >> 16; - changed |= VI_BITMASK(VI_BTTM_FIELD_BASE_RIGHT); + if (HorVer->threeD) { + regs[17] = (u16)*rtfbb & 0xFFFF; + MARK_CHANGED(17); + regs[16] = *rtfbb >> 16; + MARK_CHANGED(16); + regs[21] = (u16)*rbfbb & 0xFFFF; + MARK_CHANGED(21); + regs[20] = *rbfbb >> 16; + MARK_CHANGED(20); } } -static void setHorizontalRegs(VITimingInfo* tm, u16 dispPosX, u16 dispSizeX) { - u32 hbe, hbs, hbeLo, hbeHi; +static void setHorizontalRegs(VITiming* tm, u16 dispPosX, u16 dispSizeX) { + u32 hbe; + u32 hbs; + u32 hbeLo; + u32 hbeHi; - regs[VI_HORIZ_TIMING_0U] = (u16)tm->hlw; - changed |= VI_BITMASK(VI_HORIZ_TIMING_0U); - - regs[VI_HORIZ_TIMING_0L] = (u16)(tm->hce | tm->hcs << 8); - changed |= VI_BITMASK(VI_HORIZ_TIMING_0L); - - hbe = (u32)(tm->hbe640 - 40 + dispPosX); - hbs = (u32)(tm->hbs640 + 40 + dispPosX - (720 - dispSizeX)); - - hbeLo = hbe & ONES(9); + regs[3] = (u16)(u32)tm->hlw; + MARK_CHANGED(3); + regs[2] = tm->hce | (tm->hcs << 8); + MARK_CHANGED(2); + hbe = tm->hbe640 - 40 + dispPosX; + hbs = tm->hbs640 + 40 + dispPosX - (720 - dispSizeX); + hbeLo = hbe & 0x1FF; hbeHi = hbe >> 9; - - regs[VI_HORIZ_TIMING_1U] = (u16)(tm->hsy | hbeLo << 7); - changed |= VI_BITMASK(VI_HORIZ_TIMING_1U); - - regs[VI_HORIZ_TIMING_1L] = (u16)(hbeHi | hbs << 1); - changed |= VI_BITMASK(VI_HORIZ_TIMING_1L); + regs[5] = tm->hsy | (hbeLo << 7); + MARK_CHANGED(5); + regs[4] = hbeHi | (hbs * 2); + MARK_CHANGED(4); } -/* 8034CCEC-8034CE8C 34762C 01A0+00 2/2 0/0 0/0 .text setVerticalRegs */ -static void setVerticalRegs(u16 dispPosY, u16 dispSizeY, u8 equ, u16 acv, u16 prbOdd, u16 prbEven, - u16 psbOdd, u16 psbEven, BOOL black) { - u16 actualPrbOdd, actualPrbEven, actualPsbOdd, actualPsbEven, actualAcv, c, d; +static void setVerticalRegs(u16 dispPosY, u16 dispSizeY, u8 equ, u16 acv, u16 prbOdd, u16 prbEven, u16 psbOdd, u16 psbEven, BOOL black) { + u16 actualPrbOdd; + u16 actualPrbEven; + u16 actualPsbOdd; + u16 actualPsbEven; + u16 actualAcv; + u16 c; + u16 d; - if (regs[VI_CLOCK_SEL] & 1) { + if (regs[54] & 1) { c = 1; d = 2; } else { @@ -796,19 +703,19 @@ static void setVerticalRegs(u16 dispPosY, u16 dispSizeY, u8 equ, u16 acv, u16 pr d = 1; } - if (dispPosY % 2 == 0) { - actualPrbOdd = (u16)(prbOdd + d * dispPosY); - actualPsbOdd = (u16)(psbOdd + d * ((c * acv - dispSizeY) - dispPosY)); - actualPrbEven = (u16)(prbEven + d * dispPosY); - actualPsbEven = (u16)(psbEven + d * ((c * acv - dispSizeY) - dispPosY)); + if ((dispPosY % 2) == 0) { + actualPrbOdd = prbOdd + (d * dispPosY); + actualPsbOdd = psbOdd + (d * (((c * acv) - dispSizeY) - dispPosY)); + actualPrbEven = prbEven + (d * dispPosY); + actualPsbEven = psbEven + (d * (((c * acv) - dispSizeY) - dispPosY)); } else { - actualPrbOdd = (u16)(prbEven + d * dispPosY); - actualPsbOdd = (u16)(psbEven + d * ((c * acv - dispSizeY) - dispPosY)); - actualPrbEven = (u16)(prbOdd + d * dispPosY); - actualPsbEven = (u16)(psbOdd + d * ((c * acv - dispSizeY) - dispPosY)); + actualPrbOdd = prbEven + (d * dispPosY); + actualPsbOdd = psbEven + (d * (((c * acv) - dispSizeY) - dispPosY)); + actualPrbEven = prbOdd + (d * dispPosY); + actualPsbEven = psbOdd + (d * (((c * acv) - dispSizeY) - dispPosY)); } - actualAcv = (u16)(dispSizeY / c); + actualAcv = dispSizeY / c; if (black) { actualPrbOdd += 2 * actualAcv - 2; @@ -818,27 +725,20 @@ static void setVerticalRegs(u16 dispPosY, u16 dispSizeY, u8 equ, u16 acv, u16 pr actualAcv = 0; } - regs[VI_VERT_TIMING] = (u16)(equ | actualAcv << 4); - changed |= VI_BITMASK(VI_VERT_TIMING); - - regs[VI_VERT_TIMING_ODD_U] = (u16)actualPrbOdd << 0; - changed |= VI_BITMASK(VI_VERT_TIMING_ODD_U); - - regs[VI_VERT_TIMING_ODD] = (u16)actualPsbOdd << 0; - changed |= VI_BITMASK(VI_VERT_TIMING_ODD); - - regs[VI_VERT_TIMING_EVEN_U] = (u16)actualPrbEven << 0; - changed |= VI_BITMASK(VI_VERT_TIMING_EVEN_U); - - regs[VI_VERT_TIMING_EVEN] = (u16)actualPsbEven << 0; - changed |= VI_BITMASK(VI_VERT_TIMING_EVEN); + regs[0] = equ | (actualAcv << 4); + MARK_CHANGED(0); + regs[7] = (u16)(u32)actualPrbOdd; + MARK_CHANGED(7); + regs[6] = (u16)(u32)actualPsbOdd; + MARK_CHANGED(6); + regs[9] = (u16)(u32)actualPrbEven; + MARK_CHANGED(9); + regs[8] = (u16)(u32)actualPsbEven; + MARK_CHANGED(8); } -/* 80451840-80451848 000D40 0004+04 1/1 0/0 0/0 .sbss message$351 */ -static u32 message; - static void PrintDebugPalCaution(void) { - // static u32 message = 0; + static u32 message; if (message == 0) { message = 1; @@ -852,24 +752,44 @@ static void PrintDebugPalCaution(void) { } } -/* 8034CE8C-8034D694 3477CC 0808+00 0/0 2/2 0/0 .text VIConfigure */ -void VIConfigure(const GXRenderModeObj* obj) { - VITimingInfo* tm; - u32 regDspCfg, regClockSel, regClockSel2; +void VIConfigure(const GXRenderModeObj* rm) { + VITiming* tm; + u32 regDspCfg; + u32 regClksel; BOOL enabled; - u32 newNonInter, tvInBootrom, tvInGame; + u32 newNonInter; + u32 tvInBootrom; + u32 tvInGame; enabled = OSDisableInterrupts(); - newNonInter = (u32)obj->vi_tv_mode & 3; + newNonInter = rm->viTVmode & 3; if (HorVer.nonInter != newNonInter) { changeMode = 1; HorVer.nonInter = newNonInter; } - tvInGame = (u32)obj->vi_tv_mode >> 2; - tvInBootrom = *(u32*)OSPhysicalToCached(0xCC); + ASSERTMSGLINEV(1926, (rm->viHeight & 1) == 0, + "VIConfigure(): Odd number(%d) is specified to viHeight\n", + rm->viHeight); +#ifdef DEBUG + if (rm->xFBmode == VI_XFBMODE_DF || newNonInter == VI_TVMODE_NTSC_PROG || newNonInter == 3) { + ASSERTMSGLINEV(1933, rm->xfbHeight == rm->viHeight, + "VIConfigure(): xfbHeight(%d) is not equal to viHeight(%d) when DF XFB mode or progressive mode is specified\n", + rm->xfbHeight, rm->viHeight); + } + + if (rm->xFBmode == VI_XFBMODE_SF && newNonInter != VI_TVMODE_NTSC_PROG && newNonInter != 3) { + ASSERTMSGLINEV(1941, rm->viHeight == rm->xfbHeight * 2, + "VIConfigure(): xfbHeight(%d) is not as twice as viHeight(%d) when SF XFB mode is specified\n", + rm->xfbHeight, rm->viHeight); + } +#endif + + tvInGame = (u32)rm->viTVmode >> 2; + tvInBootrom = *(u32*)OSPhysicalToCached(0xCC); + if (tvInGame == VI_DEBUG_PAL) { PrintDebugPalCaution(); } @@ -877,9 +797,9 @@ void VIConfigure(const GXRenderModeObj* obj) { switch (tvInBootrom) { case VI_MPAL: case VI_NTSC: - case VI_GCA: + case 6: case 7: - if (tvInGame == VI_NTSC || tvInGame == VI_MPAL || tvInGame == VI_GCA || tvInGame == 7) { + if (tvInGame == VI_NTSC || tvInGame == VI_MPAL || tvInGame == 6 || tvInGame == 7) { break; } goto panic; @@ -901,102 +821,120 @@ void VIConfigure(const GXRenderModeObj* obj) { HorVer.tv = tvInGame; } - HorVer.dispPosX = obj->vi_x_origin; - HorVer.dispPosY = (u16)((HorVer.nonInter == VI_NON_INTERLACE) ? (u16)(obj->vi_y_origin * 2) : - obj->vi_y_origin); - HorVer.dispSizeX = obj->vi_width; - HorVer.fbSizeX = obj->fb_width; - HorVer.fbSizeY = obj->xfb_height; - HorVer.xfbMode = obj->xfb_mode; - HorVer.panSizeX = HorVer.fbSizeX; - HorVer.panSizeY = HorVer.fbSizeY; - HorVer.panPosX = 0; - HorVer.panPosY = 0; + HorVer.DispPosX = rm->viXOrigin; + HorVer.DispPosY = (HorVer.nonInter == 1) ? (u16)(rm->viYOrigin * 2) : rm->viYOrigin; + HorVer.DispSizeX = rm->viWidth; + HorVer.FBSizeX = rm->fbWidth; + HorVer.FBSizeY = rm->xfbHeight; + HorVer.FBMode = rm->xFBmode; + HorVer.PanSizeX = HorVer.FBSizeX; + HorVer.PanSizeY = HorVer.FBSizeY; + HorVer.PanPosX = 0; + HorVer.PanPosY = 0; + HorVer.DispSizeY = (HorVer.nonInter == 2) ? HorVer.PanSizeY : + (HorVer.nonInter == 3) ? HorVer.PanSizeY : + (HorVer.FBMode == VI_XFBMODE_SF) ? (u16)(HorVer.PanSizeY * 2) : + HorVer.PanSizeY; + HorVer.threeD = (HorVer.nonInter == 3) ? TRUE : FALSE; - HorVer.dispSizeY = (u16)((HorVer.nonInter == VI_PROGRESSIVE) ? HorVer.panSizeY : - (HorVer.nonInter == VI_3D) ? HorVer.panSizeY : - (HorVer.xfbMode == VI_XFBMODE_SF) ? (u16)(2 * HorVer.panSizeY) : - HorVer.panSizeY); - - HorVer.is3D = (HorVer.nonInter == VI_3D) ? TRUE : FALSE; - - tm = getTiming((VITVMode)VI_TVMODE(HorVer.tv, HorVer.nonInter)); + tm = getTiming((HorVer.tv << 2) + HorVer.nonInter); HorVer.timing = tm; AdjustPosition(tm->acv); + ASSERTMSGLINEV(2022, rm->viXOrigin <= tm->hlw + 40 - tm->hbe640, + "VIConfigure(): viXOrigin(%d) cannot be greater than %d in this TV mode\n", + rm->viXOrigin, tm->hlw + 40 - tm->hbe640); + ASSERTMSGLINEV(2027, rm->viXOrigin + rm->viWidth >= 680 - tm->hbs640, + "VIConfigure(): viXOrigin + viWidth (%d) cannot be less than %d in this TV mode\n", + rm->viXOrigin + rm->viWidth, 680 - tm->hbs640); + if (encoderType == 0) { - HorVer.tv = VI_DEBUG; + HorVer.tv = 3; } setInterruptRegs(tm); - regDspCfg = regs[VI_DISP_CONFIG]; - regClockSel = regs[VI_CLOCK_SEL]; - // TODO: USE BIT MACROS OR SOMETHING - if ((HorVer.nonInter == VI_PROGRESSIVE) || (HorVer.nonInter == VI_3D)) { + regDspCfg = regs[1]; + regClksel = regs[54]; + if (HorVer.nonInter == VI_PROGRESSIVE || HorVer.nonInter == 3) { regDspCfg = (((u32)(regDspCfg)) & ~0x00000004) | (((u32)(1)) << 2); - regClockSel2 = (regClockSel & ~1) | 1; + regClksel = (((u32)(regClksel)) & ~0x00000001) | (((u32)(1)) << 0); } else { - regDspCfg = (((u32)(regDspCfg)) & ~0x00000004) | (((u32)(HorVer.nonInter & 1)) << 2); - regClockSel2 = regClockSel & ~1; + OLD_SET_REG_FIELD(2052, regDspCfg, 1, 2, HorVer.nonInter & 1); + regClksel = (((u32)(regClksel)) & ~0x00000001); } - regDspCfg = (((u32)(regDspCfg)) & ~0x00000008) | (((u32)(HorVer.is3D)) << 3); + OLD_SET_REG_FIELD(2056, regDspCfg, 1, 3, HorVer.threeD); - if ((HorVer.tv == VI_TVMODE_NTSC_DS) || (HorVer.tv == VI_TVMODE_NTSC_PROG) || (HorVer.tv == VI_TVMODE_NTSC_3D)) { - regDspCfg = (((u32)(regDspCfg)) & ~0x00000300) | (((u32)(HorVer.tv)) << 8); + if ((HorVer.tv == VI_PAL) || (HorVer.tv == VI_MPAL) || (HorVer.tv == 3)) { + OLD_SET_REG_FIELD(2060, regDspCfg, 2, 8, HorVer.tv); } else { regDspCfg = (((u32)(regDspCfg)) & ~0x00000300); } - regs[VI_DISP_CONFIG] = (u16)regDspCfg; + regs[1] = regDspCfg; + regs[54] = (u16)regClksel; - // regDspCfg = regs[VI_CLOCK_SEL]; - // if (obj->vi_tv_mode == VI_TVMODE_NTSC_PROG || obj->vi_tv_mode == VI_TVMODE_NTSC_3D || - // obj->vi_tv_mode == VI_TVMODE_GCA_PROG) - // { - // regDspCfg = (u32)(regDspCfg & ~0x1) | 1; - // } else { - // regDspCfg = (u32)(regDspCfg & ~0x1); - // } + MARK_CHANGED(1); + MARK_CHANGED(54); - regs[VI_CLOCK_SEL] = (u16)regClockSel2; - - changed |= VI_BITMASK(0x01); - changed |= 0x200; - - setScalingRegs(HorVer.panSizeX, HorVer.dispSizeX, HorVer.is3D); - setHorizontalRegs(tm, HorVer.adjDispPosX, HorVer.dispSizeX); + setScalingRegs(HorVer.PanSizeX, HorVer.DispSizeX, HorVer.threeD); + setHorizontalRegs(tm, HorVer.AdjustedDispPosX, HorVer.DispSizeX); setBBIntervalRegs(tm); - setPicConfig(HorVer.fbSizeX, HorVer.xfbMode, HorVer.panPosX, HorVer.panSizeX, - &HorVer.wordPerLine, &HorVer.std, &HorVer.wpl, &HorVer.xof); - - if (FBSet) { + setPicConfig(HorVer.FBSizeX, HorVer.FBMode, HorVer.PanPosX, HorVer.PanSizeX, &HorVer.wordPerLine, &HorVer.std, &HorVer.wpl, &HorVer.xof); + if (FBSet != 0) { setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); } - - setVerticalRegs(HorVer.adjDispPosY, HorVer.adjDispSizeY, tm->equ, tm->acv, tm->prbOdd, - tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.isBlack); + setVerticalRegs(HorVer.AdjustedDispPosY, HorVer.AdjustedDispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.black); OSRestoreInterrupts(enabled); } -/* 80450A14-80450A1C 000494 0005+03 1/1 0/0 0/0 .sdata @537 */ -SECTION_SDATA static char lit_537[] = "vi.c"; +void VIConfigurePan(u16 xOrg, u16 yOrg, u16 width, u16 height) { + BOOL enabled; + VITiming* tm; + +#if DEBUG + ASSERTMSGLINEV(2118, (xOrg & 1) == 0, + "VIConfigurePan(): Odd number(%d) is specified to xOrg\n", + xOrg); + if (HorVer.FBMode == VI_XFBMODE_DF) { + ASSERTMSGLINEV(2123, (height & 1) == 0, + "VIConfigurePan(): Odd number(%d) is specified to height when DF XFB mode\n", + height); + } +#endif + enabled = OSDisableInterrupts(); + HorVer.PanPosX = xOrg; + HorVer.PanPosY = yOrg; + HorVer.PanSizeX = width; + HorVer.PanSizeY = height; + HorVer.DispSizeY = (HorVer.nonInter == 2) ? HorVer.PanSizeY : + (HorVer.nonInter == 3) ? HorVer.PanSizeY : + (HorVer.FBMode == VI_XFBMODE_SF) ? (u16)(HorVer.PanSizeY * 2) : + HorVer.PanSizeY; + tm = HorVer.timing; + AdjustPosition(tm->acv); + setScalingRegs(HorVer.PanSizeX, HorVer.DispSizeX, HorVer.threeD); + setPicConfig(HorVer.FBSizeX, HorVer.FBMode, HorVer.PanPosX, HorVer.PanSizeX, &HorVer.wordPerLine, &HorVer.std, &HorVer.wpl, &HorVer.xof); + if (FBSet != 0) { + setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); + } + setVerticalRegs(HorVer.AdjustedDispPosY, HorVer.DispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.black); + OSRestoreInterrupts(enabled); +} -/* 8034D694-8034D7C4 347FD4 0130+00 0/0 9/9 0/0 .text VIFlush */ void VIFlush(void) { BOOL enabled; s32 regIndex; - u32 val; // for stack. enabled = OSDisableInterrupts(); shdwChangeMode |= changeMode; changeMode = 0; shdwChanged |= changed; - while (changed) { + while (changed != 0) { regIndex = cntlzd(changed); shdwRegs[regIndex] = regs[regIndex]; - changed &= ~VI_BITMASK(regIndex); + changed &= ~((u64)1 << (63 - regIndex)); } flushFlag = 1; @@ -1004,44 +942,69 @@ void VIFlush(void) { OSRestoreInterrupts(enabled); } -/* 8034D7C4-8034D830 348104 006C+00 0/0 3/3 0/0 .text VISetNextFrameBuffer */ void VISetNextFrameBuffer(void* fb) { - BOOL enabled = OSDisableInterrupts(); + BOOL enabled; + + ASSERTMSGLINEV(2216, ((u32)fb & 0x1F) == 0, + "VISetNextFrameBuffer(): Frame buffer address(0x%08x) is not 32byte aligned\n", + fb); + enabled = OSDisableInterrupts(); HorVer.bufAddr = (u32)fb; FBSet = 1; setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); OSRestoreInterrupts(enabled); } -/* 8034D830-8034D838 -00001 0008+00 0/0 0/0 0/0 .text VIGetNextFrameBuffer */ -void* VIGetNextFrameBuffer() { +void* VIGetNextFrameBuffer(void) { return *(void**)(&NextBufAddr); } -/* 8034D838-8034D840 -00001 0008+00 0/0 0/0 0/0 .text VIGetCurrentFrameBuffer */ -void* VIGetCurrentFrameBuffer() { +void* VIGetCurrentFrameBuffer(void) { return *(void**)(&CurrBufAddr); } -/* 8034D840-8034D8BC 348180 007C+00 0/0 7/7 0/0 .text VISetBlack */ -void VISetBlack(BOOL isBlack) { - int interrupt; - VITimingInfo* tm; +void VISetNextRightFrameBuffer(void* fb) { + BOOL enabled; - interrupt = OSDisableInterrupts(); - HorVer.isBlack = isBlack; - tm = HorVer.timing; - setVerticalRegs(HorVer.adjDispPosY, HorVer.dispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, - tm->psbOdd, tm->psbEven, HorVer.isBlack); - OSRestoreInterrupts(interrupt); + ASSERTMSGLINEV(2284, ((u32)fb & 0x1F) == 0, + "VISetNextFrameBuffer(): Frame buffer address(0x%08x) is not 32byte aligned\n", + fb); + enabled = OSDisableInterrupts(); + HorVer.rbufAddr = (u32)fb; + FBSet = 1; + setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); + OSRestoreInterrupts(enabled); } -/* 8034D8BC-8034D8C4 -00001 0008+00 0/0 0/0 0/0 .text VIGetRetraceCount */ -u32 VIGetRetraceCount() { +void VISetBlack(BOOL black) { + BOOL enabled; + VITiming* tm; + + enabled = OSDisableInterrupts(); + HorVer.black = black; + tm = HorVer.timing; + setVerticalRegs(HorVer.AdjustedDispPosY, HorVer.DispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.black); + OSRestoreInterrupts(enabled); +} + +void VISet3D(BOOL threeD) { + BOOL enabled; + u32 reg; + + enabled = OSDisableInterrupts(); + HorVer.threeD = threeD; + reg = regs[1]; + OLD_SET_REG_FIELD(2355, reg, 1, 3, HorVer.threeD); + regs[1] = reg; + MARK_CHANGED(1); + setScalingRegs(HorVer.PanSizeX, HorVer.DispSizeX, HorVer.threeD); + OSRestoreInterrupts(enabled); +} + +u32 VIGetRetraceCount(void) { return retraceCount; } -/* 8034D8C4-8034D900 348204 003C+00 1/1 0/0 0/0 .text GetCurrentDisplayPosition */ static void GetCurrentDisplayPosition(u32* hct, u32* vct) { u32 hcount, vcount0, vcount; vcount = __VIRegs[VI_VERT_COUNT] & 0x7FF; @@ -1063,140 +1026,282 @@ static u32 getCurrentHalfLine(void) { return ((vcount - 1) << 1) + ((hcount - 1) / CurrTiming->hlw); } -/* 8034D900-8034D968 348240 0068+00 1/1 0/0 0/0 .text getCurrentFieldEvenOdd */ -static u32 getCurrentFieldEvenOdd() { - return (getCurrentHalfLine() < CurrTiming->numHalfLines) ? 1 : 0; +static u32 getCurrentFieldEvenOdd(void) { + return (getCurrentHalfLine() < CurrTiming->nhlines) ? 1 : 0; } -/* 8034D968-8034DA04 3482A8 009C+00 0/0 0/0 2/2 .text VIGetNextField */ u32 VIGetNextField(void) { - u32 nextField; - int interrupt; + s32 nextField; + BOOL enabled; +#if !DEBUG + u8 unused[4]; +#endif - interrupt = OSDisableInterrupts(); + enabled = OSDisableInterrupts(); nextField = getCurrentFieldEvenOdd() ^ 1; - OSRestoreInterrupts(interrupt); - return nextField ^ (HorVer.adjDispPosY & 1); + OSRestoreInterrupts(enabled); + return nextField ^ (HorVer.AdjustedDispPosY & 1); } -/* 8034DA04-8034DA9C 348344 0098+00 0/0 1/1 0/0 .text VIGetCurrentLine */ u32 VIGetCurrentLine(void) { - u32 line; - VITimingInfo* tm; - int interrupt; + u32 halfLine; + VITiming* tm; + BOOL enabled; tm = CurrTiming; - interrupt = OSDisableInterrupts(); - line = getCurrentHalfLine(); - OSRestoreInterrupts(interrupt); - - if (line >= tm->numHalfLines) { - line -= tm->numHalfLines; + enabled = OSDisableInterrupts(); + halfLine = getCurrentHalfLine(); + OSRestoreInterrupts(enabled); + if (halfLine >= tm->nhlines) { + halfLine -= tm->nhlines; } - - return (line >> 1); + return halfLine >> 1U; } -/* 8034DA9C-8034DB04 3483DC 0068+00 1/0 2/2 1/1 .text VIGetTvFormat */ u32 VIGetTvFormat(void) { - u32 fmt; - int interrupt; + u32 format; + BOOL enabled; - interrupt = OSDisableInterrupts(); + enabled = OSDisableInterrupts(); switch (CurrTvMode) { case VI_NTSC: case VI_DEBUG: - case VI_GCA: + case 6: case 7: - fmt = VI_NTSC; + format = VI_NTSC; break; case VI_PAL: case VI_DEBUG_PAL: - fmt = VI_PAL; + format = VI_PAL; break; case VI_EURGB60: case VI_MPAL: - fmt = CurrTvMode; + format = CurrTvMode; break; + default: + ASSERTLINE(2527, FALSE); + } + + OSRestoreInterrupts(enabled); + return format; +} + +u32 VIGetScanMode(void) { + u32 scanMode; + BOOL enabled = OSDisableInterrupts(); + + if ((u32)(__VIRegs[54] & 1) == 1) { + scanMode = 2; + } else if (!((__VIRegs[1] & (1 << 2)) >> 2)) { + scanMode = 0; + } else { + scanMode = 1; + } + + OSRestoreInterrupts(enabled); + return scanMode; +} + +u32 VIGetDTVStatus(void) { + u32 dtvStatus; + BOOL enabled = OSDisableInterrupts(); + + dtvStatus = __VIRegs[55] & 3; + OSRestoreInterrupts(enabled); + return dtvStatus & 1; +} + +void __VISetAdjustingValues(s16 x, s16 y) { + BOOL enabled; + VITiming* tm; + + ASSERTMSGLINE(2611, (y & 1) == 0, "__VISetAdjustValues(): y offset should be an even number"); + enabled = OSDisableInterrupts(); + displayOffsetH = x; + displayOffsetV = y; + tm = HorVer.timing; + AdjustPosition(tm->acv); + setHorizontalRegs(tm, HorVer.AdjustedDispPosX, HorVer.DispSizeX); + if (FBSet != 0) { + setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); + } + setVerticalRegs(HorVer.AdjustedDispPosY, HorVer.AdjustedDispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.black); + OSRestoreInterrupts(enabled); +} + +void __VIGetAdjustingValues(s16* x, s16* y) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + *x = displayOffsetH; + *y = displayOffsetV; + OSRestoreInterrupts(enabled); +} + +// DEBUG NONMATCHING - wrong reg use, equivalent +void __VIEnableRawPositionInterrupt(s16 x, s16 y, void (*callback)(s16, s16)) { + BOOL enabled; + u32 halfLine; + u32 halfLineOff; + + enabled = OSDisableInterrupts(); + __VIRegs[29] = x + 1U; + __VIRegs[31] = x + 1U; + + if (HorVer.nonInter == 0) { + if (y & 1) { + halfLineOff = CurrTiming->prbEven + ((CurrTiming->equ * 3) + CurrTiming->nhlines); + __VIRegs[30] = (((halfLineOff / 2) + (y / 2)) + 1) | 0x1000; + } else { + halfLineOff = CurrTiming->prbOdd + (CurrTiming->equ * 3); + __VIRegs[28] = (((halfLineOff / 2) + (y / 2)) + 1) | 0x1000; + } + } else if (HorVer.nonInter == 1) { + ASSERTLINE(2702, (y & 1) == 0); + halfLine = CurrTiming->prbOdd + ((CurrTiming->equ * 3)) + y; + __VIRegs[28] = ((halfLine / 2) + 1) | 0x1000; + __VIRegs[30] = (((halfLine + CurrTiming->nhlines) / 2) + 1) | 0x1000; + } else if (HorVer.nonInter == 2) { + halfLine = CurrTiming->prbOdd + ((CurrTiming->equ * 3)) + y; + __VIRegs[28] = (halfLine + 1) | 0x1000; + __VIRegs[30] = 0; } - OSRestoreInterrupts(interrupt); - return fmt; + PositionCallback = callback; + OSRestoreInterrupts(enabled); } -/* 8034DB04-8034DB40 348444 003C+00 0/0 2/2 0/0 .text VIGetDTVStatus */ -u32 VIGetDTVStatus() { - u32 val; - BOOL enable = OSDisableInterrupts(); - val = __VIRegs[55] & 3; - OSRestoreInterrupts(enable); - return val & 1; +void (*__VIDisableRawPositionInterrupt())(s16, s16) { + BOOL enabled; + void (*old)(s16, s16); + + enabled = OSDisableInterrupts(); + __VIRegs[28] = 0; + __VIRegs[30] = 0; + + old = PositionCallback; + PositionCallback = 0; + OSRestoreInterrupts(enabled); + return old; } -/* 8034DB40-8034DD5C 348480 021C+00 1/1 0/0 0/0 .text __VIDisplayPositionToXY */ -void __VIDisplayPositionToXY(u32 hcount, u32 vcount, s16* x, s16* y) { - u32 halfLine = ((vcount - 1) << 1) + ((hcount - 1) / CurrTiming->hlw); +void __VIDisplayPositionToXY(u32 hct, u32 vct, s16* x, s16* y) { + u32 halfLine = ((vct - 1) << 1) + ((hct - 1) / CurrTiming->hlw); if (HorVer.nonInter == VI_INTERLACE) { - if (halfLine < CurrTiming->numHalfLines) { + if (halfLine < CurrTiming->nhlines) { if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) { *y = -1; - } else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbOdd) { + } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbOdd) { *y = -1; } else { *y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd) & ~1); } } else { - halfLine -= CurrTiming->numHalfLines; + halfLine -= CurrTiming->nhlines; if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbEven) { *y = -1; - } else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbEven) { + } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbEven) { *y = -1; } else { *y = (s16)(((halfLine - CurrTiming->equ * 3 - CurrTiming->prbEven) & ~1) + 1); } } } else if (HorVer.nonInter == VI_NON_INTERLACE) { - if (halfLine >= CurrTiming->numHalfLines) { - halfLine -= CurrTiming->numHalfLines; + if (halfLine >= CurrTiming->nhlines) { + halfLine -= CurrTiming->nhlines; } if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) { *y = -1; - } else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbOdd) { + } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbOdd) { *y = -1; } else { *y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd) & ~1); } } else if (HorVer.nonInter == VI_PROGRESSIVE) { - if (halfLine < CurrTiming->numHalfLines) { + if (halfLine < CurrTiming->nhlines) { if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) { *y = -1; - } else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbOdd) { + } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbOdd) { *y = -1; } else { *y = (s16)(halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd); } } else { - halfLine -= CurrTiming->numHalfLines; + halfLine -= CurrTiming->nhlines; if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbEven) { *y = -1; - } else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbEven) { + } else if (halfLine >= CurrTiming->nhlines - CurrTiming->psbEven) { *y = -1; } else *y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbEven) & ~1); } } - *x = (s16)(hcount - 1); + *x = (s16)(hct - 1); } -/* 8034DD5C-8034DDBC 34869C 0060+00 1/1 0/0 0/0 .text __VIGetCurrentPosition */ void __VIGetCurrentPosition(s16* x, s16* y) { - u32 h, v; - GetCurrentDisplayPosition(&h, &v); - __VIDisplayPositionToXY(h, v, x, y); + u32 hcount, vcount; + GetCurrentDisplayPosition(&hcount, &vcount); + __VIDisplayPositionToXY(hcount, vcount, x, y); +} + +void __VISetLatchMode(u32 mode) { + u32 reg; + + reg = __VIRegs[1]; + OLD_SET_REG_FIELD(2834, reg, 2, 4, mode); + OLD_SET_REG_FIELD(2835, reg, 2, 6, mode); + __VIRegs[1] = reg; +} + +#pragma dont_inline on +int __VIGetLatch0Position(s16* px, s16* py) { + u32 hcount; + u32 vcount; + + if (((__VIRegs[32] & 0x8000) >> 15) != 0) { + vcount = __VIRegs[32] & 0x7FF; + hcount = __VIRegs[33] & 0x7FF; + __VIRegs[32] = 0; + __VIRegs[33] = 0; + __VIDisplayPositionToXY(hcount, vcount, px, py); + return 1; + } + + *px = *py = -1; + return 0; +} +#pragma dont_inline reset + +#pragma dont_inline on +int __VIGetLatch1Position(s16* px, s16* py) { + u32 hcount; + u32 vcount; + + if (((__VIRegs[34] & 0x8000) >> 15) != 0) { + vcount = __VIRegs[34] & 0x7FF; + hcount = __VIRegs[35] & 0x7FF; + __VIRegs[34] = 0; + __VIRegs[35] = 0; + __VIDisplayPositionToXY(hcount, vcount, px, py); + return 1; + } + + *px = *py = -1; + return 0; +} +#pragma dont_inline reset + +int __VIGetLatchPosition(u32 port, s16* px, s16* py) { + if (port == 0) { + return __VIGetLatch0Position(px, py); + } else { + return __VIGetLatch1Position(px, py); + } } diff --git a/src/m_Do/m_Do_DVDError.cpp b/src/m_Do/m_Do_DVDError.cpp index 9ac9098e96..eb6402a3c1 100644 --- a/src/m_Do/m_Do_DVDError.cpp +++ b/src/m_Do/m_Do_DVDError.cpp @@ -5,7 +5,7 @@ #include "m_Do/m_Do_DVDError.h" #include "JSystem/JKernel/JKRAssertHeap.h" -#include "dolphin/os/OSInterrupt.h" +#include #include "m_Do/m_Do_dvd_thread.h" #include "m_Do/m_Do_ext.h" #include "m_Do/m_Do_Reset.h" @@ -29,7 +29,7 @@ void mDoDvdErr_ThdInit() { OSThread* curThread = OSGetCurrentThread(); s32 priority = OSGetThreadPriority(curThread); - OSCreateThread(&DvdErr_thread, mDoDvdErr_Watch, NULL, DvdErr_stack + sizeof(DvdErr_stack), + OSCreateThread(&DvdErr_thread, (void*(*)(void*))mDoDvdErr_Watch, NULL, DvdErr_stack + sizeof(DvdErr_stack), sizeof(DvdErr_stack), priority - 3, 1); OSResumeThread(&DvdErr_thread); OSCreateAlarm(&Alarm); @@ -67,4 +67,4 @@ static void mDoDvdErr_Watch(void*) { */ static void AlarmHandler(OSAlarm*, OSContext*) { OSResumeThread(&DvdErr_thread); -} \ No newline at end of file +} diff --git a/src/m_Do/m_Do_MemCard.cpp b/src/m_Do/m_Do_MemCard.cpp index 0ffa40d7c9..93b0f9e95c 100644 --- a/src/m_Do/m_Do_MemCard.cpp +++ b/src/m_Do/m_Do_MemCard.cpp @@ -33,7 +33,7 @@ void mDoMemCd_Ctrl_c::ThdInit() { OSInitCond(&mCond); int priority = OSGetThreadPriority(OSGetCurrentThread()); - OSCreateThread(&MemCardThread, mDoMemCd_main, NULL, MemCardStack + sizeof(MemCardStack), + OSCreateThread(&MemCardThread, (void*(*)(void*))mDoMemCd_main, NULL, MemCardStack + sizeof(MemCardStack), sizeof(MemCardStack), priority + 1, 1); OSResumeThread(&MemCardThread); } @@ -499,4 +499,4 @@ static int mDoMemCd_main(void*) { g_mDoMemCd_control.main(); return 0; -} \ No newline at end of file +} diff --git a/src/m_Do/m_Do_MemCardRWmng.cpp b/src/m_Do/m_Do_MemCardRWmng.cpp index e72a313dbb..1c35f6d7ea 100644 --- a/src/m_Do/m_Do_MemCardRWmng.cpp +++ b/src/m_Do/m_Do_MemCardRWmng.cpp @@ -161,8 +161,8 @@ static void mDoMemCdRWm_BuildHeader(mDoMemCdRWm_HeaderData* header) { OSCalendarTime time; OSTicksToCalendarTime(OSGetTime(), &time); - snprintf(header->mComment, sizeof(header->mComment), "%d/%d Save Data", time.month + 1, - time.day_of_month); + snprintf(header->mComment, sizeof(header->mComment), "%d/%d Save Data", time.mon + 1, + time.mday); ResTIMG* banner_data = (ResTIMG*)g_dComIfG_gameInfo.play.mCardIconResArchive->getResource("zelda2_gc_banner.bti"); diff --git a/src/m_Do/m_Do_dvd_thread.cpp b/src/m_Do/m_Do_dvd_thread.cpp index 6b4d1f3307..23825d720d 100644 --- a/src/m_Do/m_Do_dvd_thread.cpp +++ b/src/m_Do/m_Do_dvd_thread.cpp @@ -37,7 +37,7 @@ static u8 padding[0x18]; /* 80015858-800158B4 010198 005C+00 0/0 1/1 0/0 .text create__9mDoDvdThdFl */ void mDoDvdThd::create(s32 param_0) { - OSCreateThread(&l_thread, mDoDvdThd::main, &l_param, + OSCreateThread(&l_thread, (void*(*)(void*))mDoDvdThd::main, &l_param, l_threadStack.stack + sizeof(l_threadStack), sizeof(l_threadStack), param_0, 1); OSResumeThread(&l_thread); } @@ -350,4 +350,4 @@ static void dummy() { OSReport("mDoDvdThd_getResource_c::create() クラス生成に失敗\n"); OSReport("mDoDvdThd_getResource_c::create() リソース取得に失敗\n"); OSReport("mDoDvdThd_getResource_c::execute() リソース取得に失敗\n"); -} \ No newline at end of file +} diff --git a/src/m_Do/m_Do_ext.cpp b/src/m_Do/m_Do_ext.cpp index f208d5ad9c..084fa09e33 100644 --- a/src/m_Do/m_Do_ext.cpp +++ b/src/m_Do/m_Do_ext.cpp @@ -16,7 +16,7 @@ #include "Z2AudioLib/Z2Creature.h" #include "d/d_com_inf_game.h" #include "dol2asm.h" -#include "dolphin/gx/GXDraw.h" +#include #include #include "global.h" #include "m_Do/m_Do_mtx.h" @@ -858,7 +858,7 @@ void mDoExt_MtxCalcAnmBlendTbl::calc() { } } Mtx mtx; - MTXQuat(mtx, (PSQuaternion*)&quat3); + MTXQuat(mtx, &quat3); mDoExt_setJ3DData(mtx, &info2, jntNo); } @@ -2426,7 +2426,7 @@ void drawCube(MtxP mtx, cXyz* pos, const GXColor& color) { GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0); GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); GXSetCullMode(GX_CULL_BACK); GXSetClipMode(GX_CLIP_ENABLE); @@ -2483,7 +2483,7 @@ void mDoExt_cylinderPacket::draw() { GXSetZMode(GX_DISABLE, GX_LEQUAL, GX_DISABLE); } - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); GXSetCullMode(GX_CULL_BACK); GXSetClipMode(GX_CLIP_ENABLE); diff --git a/src/m_Do/m_Do_graphic.cpp b/src/m_Do/m_Do_graphic.cpp index 5bff7ace1a..6fe1c8cfd6 100644 --- a/src/m_Do/m_Do_graphic.cpp +++ b/src/m_Do/m_Do_graphic.cpp @@ -92,8 +92,8 @@ void mDoGph_gInf_c::create() { JFWDisplay::createManager(NULL, JKRHeap::sCurrentHeap, JUTXfb::UNK_2, true); JFWDisplay::getManager()->setDrawDoneMethod(JFWDisplay::UNK_METHOD_1); - JUTFader* faderPtr = new JUTFader(0, 0, JUTVideo::getManager()->getRenderMode()->fb_width, - JUTVideo::getManager()->getRenderMode()->efb_height, + JUTFader* faderPtr = new JUTFader(0, 0, JUTVideo::getManager()->getRenderMode()->fbWidth, + JUTVideo::getManager()->getRenderMode()->efbHeight, JUtility::TColor(0, 0, 0, 0)); setFader(faderPtr); JFWDisplay::getManager()->setFader(faderPtr); @@ -198,7 +198,7 @@ static void darwFilter(GXColor matColor) { GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, GX_TEVPREV); GXSetZCompLoc(GX_ENABLE); GXSetZMode(GX_DISABLE, GX_ALWAYS, GX_DISABLE); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_OR); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_OR); GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); GXSetFog(GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, g_clearColor); GXSetFogRangeAdj(GX_DISABLE, 0, NULL); @@ -296,7 +296,7 @@ int mDoGph_AfterOfDraw() { GXSetZCompLoc(GX_ENABLE); GXSetZMode(GX_DISABLE, GX_ALWAYS, GX_DISABLE); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); GXSetFog(GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, g_clearColor); GXSetFogRangeAdj(GX_DISABLE, 0, NULL); @@ -473,10 +473,10 @@ static void drawDepth2(view_class* param_0, view_port_class* param_1, int param_ GXSetZCompLoc(GX_TRUE); GXSetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE); if (g_env_light.mDemoAttentionPoint >= 0.0f) { - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); } else { - GXSetBlendMode(GX_BM_BLEND, GX_BL_INV_SRC_ALPHA, GX_BL_SRC_ALPHA, GX_LO_CLEAR); + GXSetBlendMode(GX_BM_BLEND, GX_BL_INVSRCALPHA, GX_BL_SRCALPHA, GX_LO_CLEAR); GXSetAlphaCompare(GX_LESS, 0xff, GX_AOP_OR, GX_LESS, 0xff); } @@ -546,7 +546,7 @@ static void trimming(view_class* param_0, view_port_class* param_1) { GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetZCompLoc(1); GXSetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE); - GXSetBlendMode(GX_BM_NONE, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); GXSetFog(GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, g_clearColor); GXSetCullMode(GX_CULL_NONE); @@ -656,7 +656,7 @@ void mDoGph_gInf_c::bloom_c::draw() { GX_TEVPREV); GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP1, GX_TEV_SWAP1); GXSetTevColor(GX_TEVREG2, mMonoColor); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_OR); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_OR); mDoGph_drawFilterQuad(4, 4); } if (enabled) { @@ -711,7 +711,7 @@ void mDoGph_gInf_c::bloom_c::draw() { u32 iVar11 = 0x1e; s16 sVar10 = 0; GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c); - for (int texCoord = (int)GX_TEXCOORD1; texCoord < (int)GX_MAXCOORD; + for (int texCoord = (int)GX_TEXCOORD1; texCoord < (int)GX_MAX_TEXCOORD; texCoord++, iVar11 += 3, sVar10 += 0x2492) { GXSetTexCoordGen((GXTexCoordID)texCoord, GX_TG_MTX2x4, GX_TG_TEX0, iVar11); @@ -751,7 +751,7 @@ void mDoGph_gInf_c::bloom_c::draw() { GXInitTexObjLOD(&auStack_c0, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1); GXLoadTexObj(&auStack_e0, GX_TEXMAP0); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_OR); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_OR); GXPixModeSync(); GXInvalidateTexAll(); mDoGph_drawFilterQuad(1, 1); @@ -787,11 +787,11 @@ void mDoGph_gInf_c::bloom_c::draw() { GX_TEVPREV); GXBlendFactor blendFactor; if (mMode == 1) { - blendFactor = GX_BL_INV_DST_COLOR; + blendFactor = GX_BL_INVDSTCLR; } else { blendFactor = GX_BL_ONE; } - GXSetBlendMode(GX_BM_BLEND, blendFactor, GX_BL_SRC_ALPHA, GX_LO_OR); + GXSetBlendMode(GX_BM_BLEND, blendFactor, GX_BL_SRCALPHA, GX_LO_OR); GXPixModeSync(); GXInvalidateTexAll(); mDoGph_drawFilterQuad(4, 4); @@ -852,7 +852,7 @@ static void motionBlure(view_class* param_0) { GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetZCompLoc(1); GXSetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE); - GXSetBlendMode(GX_BM_BLEND, GX_BL_SRC_ALPHA, GX_BL_INV_SRC_ALPHA, GX_LO_CLEAR); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); GXSetFog(GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, g_clearColor); GXSetCullMode(GX_CULL_NONE); diff --git a/src/m_Do/m_Do_hostIO.cpp b/src/m_Do/m_Do_hostIO.cpp index 61c2cbebd6..1f2cc6c1f1 100644 --- a/src/m_Do/m_Do_hostIO.cpp +++ b/src/m_Do/m_Do_hostIO.cpp @@ -3,10 +3,6 @@ #ifdef DEBUG -void mDoHIO_updateChild(s8 i_no); -void mDoHIO_deleteChild(s8 i_no); -s8 mDoHIO_createChild(const char*, JORReflexible*); - mDoHIO_root_c mDoHIO_root; mDoHIO_root_c::~mDoHIO_root_c() {} diff --git a/src/m_Do/m_Do_machine_exception.cpp b/src/m_Do/m_Do_machine_exception.cpp index cc1cd9e090..9588919d7f 100644 --- a/src/m_Do/m_Do_machine_exception.cpp +++ b/src/m_Do/m_Do_machine_exception.cpp @@ -68,18 +68,18 @@ void dispDateInfo() { OSCalendarTime time; OSTicksToCalendarTime(mDoMain::sPowerOnTime, &time); - print_f("PowerOnTime: %04d/%2d/%2d %2d:%2d:%2d`%03d\"%03d\n", time.year, time.month, - time.day_of_month, time.hours, time.minutes, time.seconds, time.milliseconds, - time.microseconds); + print_f("PowerOnTime: %04d/%2d/%2d %2d:%2d:%2d`%03d\"%03d\n", time.year, time.mon, + time.mday, time.hour, time.min, time.sec, time.msec, + time.usec); OSTicksToCalendarTime(mDoMain::sHungUpTime, &time); - print_f("HungUpTime : %04d/%2d/%2d %2d:%2d:%2d`%03d\"%03d\n", time.year, time.month, - time.day_of_month, time.hours, time.minutes, time.seconds, time.milliseconds, - time.microseconds); + print_f("HungUpTime : %04d/%2d/%2d %2d:%2d:%2d`%03d\"%03d\n", time.year, time.mon, + time.mday, time.hour, time.min, time.sec, time.msec, + time.usec); OSTicksToCalendarTime(mDoMain::sHungUpTime - mDoMain::sPowerOnTime, &time); - print_f("PlayTime : %4d days, %2d:%2d:%2d`%03d\"%03d\n", time.year_day, time.hours, - time.minutes, time.seconds, time.milliseconds, time.microseconds); + print_f("PlayTime : %4d days, %2d:%2d:%2d`%03d\"%03d\n", time.yday, time.hour, + time.min, time.sec, time.msec, time.usec); print("---------------------------------------\n"); } @@ -93,4 +93,4 @@ void exception_addition(JUTConsole* pConsole) { dispDateInfo(); dispConsoleToTerminal(); dispGameInfo(); -} \ No newline at end of file +} diff --git a/src/m_Do/m_Do_main.cpp b/src/m_Do/m_Do_main.cpp index fa5c31f098..e566e66365 100644 --- a/src/m_Do/m_Do_main.cpp +++ b/src/m_Do/m_Do_main.cpp @@ -535,9 +535,9 @@ void main() { if (mDoMain::developmentMode < 0) { DVDDiskID* disk_id = DVDGetCurrentDiskID(); - if (disk_id->game_version > 0x90) { + if (disk_id->gameVersion > 0x90) { mDoMain::developmentMode = 1; - } else if (disk_id->game_version > 0x80) { + } else if (disk_id->gameVersion > 0x80) { u32 consoleType = OSGetConsoleType(); mDoMain::developmentMode = (consoleType >> 0x1C) & 1; } else { @@ -546,7 +546,7 @@ void main() { } s32 priority = OSGetThreadPriority(current_thread); - OSCreateThread(&mainThread, main01, 0, stack + sizeof(mainThreadStack), sizeof(mainThreadStack), priority, 0); + OSCreateThread(&mainThread, (void*(*)(void*))main01, 0, stack + sizeof(mainThreadStack), sizeof(mainThreadStack), priority, 0); OSResumeThread(&mainThread); OSSetThreadPriority(current_thread, 0x1F); OSSuspendThread(current_thread); diff --git a/src/m_Do/m_Do_printf.cpp b/src/m_Do/m_Do_printf.cpp index e070606630..9569a4f869 100644 --- a/src/m_Do/m_Do_printf.cpp +++ b/src/m_Do/m_Do_printf.cpp @@ -123,8 +123,8 @@ void mDoPrintf_vprintf(char const* fmt, va_list args) { if (currentThread == NULL) { mDoPrintf_vprintf_Interrupt(fmt, args); } else { - u8* stackPtr = OSGetStackPointer(); - if (stackPtr < (u8*)currentThread->stack_end + 0xA00 || stackPtr > currentThread->stack_base) { + u8* stackPtr = (u8*)OSGetStackPointer(); + if (stackPtr < (u8*)currentThread->stackEnd + 0xA00 || stackPtr > currentThread->stackBase) { mDoPrintf_vprintf_Interrupt(fmt, args); } else { mDoPrintf_vprintf_Thread(fmt, args); @@ -221,7 +221,7 @@ void OSReport_System(const char* fmt, ...) { } /* 80006E7C-80006FB4 0017BC 0138+00 0/0 9/9 0/0 .text OSPanic */ -void OSPanic(const char* file, s32 line, const char* fmt, ...) { +void OSPanic(const char* file, int line, const char* fmt, ...) { va_list args; u32 i; u32* p; @@ -241,4 +241,4 @@ void OSPanic(const char* file, s32 line, const char* fmt, ...) { tmp = (u32*)0x1234567; // ?????? *tmp = 0x1234567; PPCHalt(); -} \ No newline at end of file +} diff --git a/src/odemuexi2/DebuggerDriver.c b/src/odemuexi2/DebuggerDriver.c index cb50e0fc38..86a05180ca 100644 --- a/src/odemuexi2/DebuggerDriver.c +++ b/src/odemuexi2/DebuggerDriver.c @@ -1,4 +1,4 @@ -#include "dolphin/exi/EXIBios.h" +#include #include "dolphin/os.h" typedef void (*MTRCallbackType)(int); @@ -319,4 +319,4 @@ BOOL DBWrite(void* src, u32 size) { void DBOpen(void) {} /* 80372D2C-80372D30 36D66C 0004+00 0/0 1/1 0/0 .text DBClose */ -void DBClose(void) {} \ No newline at end of file +void DBClose(void) {}