From 3166a819cf89caa720af1c5e1e1092ec04d918ae Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Tue, 20 May 2025 22:43:17 -0400 Subject: [PATCH 01/19] zMain work --- src/SB/Core/x/xserializer.h | 6 +- src/SB/Game/zEntPlayerOOBState.h | 1 + src/SB/Game/zMain.cpp | 180 ++++++++++++++++++++++++++++++- src/SB/Game/zMain.h | 2 - src/SB/Game/zTalkBox.h | 3 +- 5 files changed, 183 insertions(+), 9 deletions(-) diff --git a/src/SB/Core/x/xserializer.h b/src/SB/Core/x/xserializer.h index f9b229172..a03a12d83 100644 --- a/src/SB/Core/x/xserializer.h +++ b/src/SB/Core/x/xserializer.h @@ -12,10 +12,10 @@ struct st_SERIAL_CLIENTINFO S32 actsize; }; -struct st_SERIAL_PERCID_SIZE +struct st_SERIAL_PERCID_SIZE { U32 idtag; - S32 needsize; + S32 needsize; }; struct xSerial @@ -50,7 +50,7 @@ struct xSerial void operator delete(void*); }; -void xSerialStartup(S32, st_SERIAL_PERCID_SIZE*); +S32 xSerialStartup(S32, st_SERIAL_PERCID_SIZE*); void xSerialShutdown(); void xSerialTraverse(S32 (*func)(U32 clientID, xSerial* xser)); void xSerialWipeMainBuffer(); diff --git a/src/SB/Game/zEntPlayerOOBState.h b/src/SB/Game/zEntPlayerOOBState.h index 42469d439..1bbfdaf08 100644 --- a/src/SB/Game/zEntPlayerOOBState.h +++ b/src/SB/Game/zEntPlayerOOBState.h @@ -13,6 +13,7 @@ namespace oob_state void fx_render(); void read_persistent(xSerial& s); void write_persistent(xSerial& s); + void load_settings(xIniFile& ini); float oob_timer(); diff --git a/src/SB/Game/zMain.cpp b/src/SB/Game/zMain.cpp index 882c0a69e..71a91c985 100644 --- a/src/SB/Game/zMain.cpp +++ b/src/SB/Game/zMain.cpp @@ -24,13 +24,20 @@ #include "zCamera.h" #include "zCutsceneMgr.h" #include "zEntPlayerBungeeState.h" +#include "zEntPlayerOOBState.h" +#include "zMenu.h" +#include "iTime.h" +#include "xstransvc.h" S32 percentageDone; _tagxPad* gDebugPad; -S32 sShowMenuOnBoot; +static S32 sShowMenuOnBoot; S32 gGameSfxReport; +static st_SERIAL_PERCID_SIZE* g_xser_sizeinfo; void zLedgeAdjust(zLedgeGrabParams* params); +void zMainMemCardRenderText(const char*, bool); +void RenderText(const char*, bool); void main(S32 argc, char** argv) { @@ -377,8 +384,8 @@ void zMainParseINIGlobals(xIniFile* ini) zLedgeAdjust(&globals.player.sb.ledge); bungee_state::load_settings(*ini); - //oob_state::load_settings(xIniFile&) - //ztalkbox::load_settings(*ini); + oob_state::load_settings(*ini); + ztalkbox::load_settings(*ini); { static F32 fbuf[] = { 2.0f, 0.7f, 0.35f, 0.0f }; @@ -590,10 +597,37 @@ void zLedgeAdjust(zLedgeGrabParams* params) void zMainShowProgressBar() { + S32 progBar; + size_t sVar2; + char loadingText[12]; + char auStack_cc[64]; + char acStack_8c[64]; + char formattedStr[72]; + + if (zMenuIsFirstBoot() != 0) + { + if (100 < percentageDone) + { + percentageDone = 100; + } + progBar = percentageDone / 10; + strcpy(loadingText, "Loading..."); + memset(formattedStr, 0, 0x40); + memset(acStack_8c, 0, 0x40); + strcpy(auStack_cc, loadingText); + auStack_cc[progBar] = '\0'; + sVar2 = strlen(loadingText); + memcpy(auStack_cc, acStack_8c + progBar, progBar); // 3rd arg should have progBar - sVar2 + sprintf(formattedStr, "{font=0}{h*2}{w*2}%s{color=FFFFFFFF}%s{~:c}", auStack_cc, + acStack_8c); + zMainMemCardRenderText(formattedStr, '\x01'); + percentageDone = percentageDone + 10; + } } void zMainLoop() { + iTime time; S64 t; U32* preinit; RpAtomic* modl; @@ -608,6 +642,92 @@ void zMainLoop() U32 preinit_bubble_matfx[6]; U32 preinit_shiny_models[8]; U32 preinit_ADC_models[10]; + + zMainShowProgressBar(); + xMemPushBase(); + time = iTimeGet(); + xUtil_idtag2string(0x464f4e54, 0); + iTimeDiffSec(time); + xSTPreLoadScene(0x464f4e54, NULL, 0x1); + time = iTimeGet(); + xUtil_idtag2string(0x464f4e54, 0); + iTimeDiffSec(time); + xSTQueueSceneAssets(0x464f4e54, 1); + time = iTimeGet(); + xUtil_idtag2string(0x464f4e54, 0); + iTimeDiffSec(time); + + do + { + xSTLoadStep(time); + } while (time < 1.0f); + + xSTDisconnect(0x464f4e54, 1); + time = iTimeGet(); + xUtil_idtag2string(0x464f4e54, 0); + iTimeDiffSec(time); + zMainShowProgressBar(); + xSTPreLoadScene(0x504c4154, 0, 1); + xSTQueueSceneAssets(0x504c4154, 1); + + do + { + xSTLoadStep(time); + } while (time < 1.0f); + + xSTDisconnect(0x504c4154, 1); + zMainShowProgressBar(); + iTimeGet(); + xShadowSimple_Init(); + globals.pickupTable = (zAssetPickupTable*)xSTFindAssetByType(0x5049434b, 0, 0); + // globals.pickupTable = zPickupTableInit(); + // zPickupTableInit hasnt been implemented yet + xMemPushBase(); + time = iTimeGet(); + xUtil_idtag2string(0x4d4e5534, 0); + iTimeDiffSec(time); + xSTPreLoadScene(0x4d4e5534, 0, 1); + time = iTimeGet(); + xUtil_idtag2string(0x4d4e5534, 0); + iTimeDiffSec(time); + xSTQueueSceneAssets(0x4d4e5534, 1); + time = iTimeGet(); + xUtil_idtag2string(0x4d4e5534, 0); + iTimeDiffSec(time); + do + { + xSTLoadStep(time); + } while (time < 1.0f); + xSTDisconnect(0x4d4e5534, 1); + zMainShowProgressBar(); + time = iTimeGet(); + xUtil_idtag2string(0x4d4e5534, 0); + iTimeDiffSec(time); + xMemPushBase(); + time = iTimeGet(); + xUtil_idtag2string(0x4d4e5535, 0); + iTimeDiffSec(time); + xSTPreLoadScene(0x4d4e5535, 0, 1); + time = iTimeGet(); + xUtil_idtag2string(0x4d4e5535, 0); + iTimeDiffSec(time); + xSTQueueSceneAssets(0x4d4e5535, 1); + time = iTimeGet(); + xUtil_idtag2string(0x4d4e5535, 0); + iTimeDiffSec(time); + do + { + xSTLoadStep(time); + } while (time < 1.0f); + xSTDisconnect(0x4d4e5535, 1); + zMainShowProgressBar(); + time = iTimeGet(); + xUtil_idtag2string(0x4d4e5535, 0); + iTimeDiffSec(time); + xModelInit(); + xModelPoolInit(0x20, 0x40); + xModelPoolInit(0x28, 8); + xModelPoolInit(0x38, 1); } void zMainReadINI() @@ -635,8 +755,62 @@ void zMainMemCardSpaceQuery() S32 status; } +void zMainMemCardQueryPost(S32 needed, S32 available, S32 neededFiles, S32 unk0) +{ + RwCamera* cam = 0; + RwRGBA* colour = 0; + RwInt32 clearMode = 3; + + cam = iCameraCreate(0x280, 0x1e0, 0); + RwCameraClear(cam, colour, clearMode); + RwCameraBeginUpdate(cam); + render_mem_card_no_space(needed, available, neededFiles, unk0); + RwCameraEndUpdate(cam); + RwCameraShowRaster(cam, 0, 1); + iCameraDestroy(cam); +} + +void zMainMemCardRenderText(const char* a, bool enabled) +{ + RwCamera* cam = 0; + RwRGBA* colour = 0; + RwInt32 clearMode = 3; + + cam = iCameraCreate(0x280, 0x1e0, 0); + RwCameraClear(cam, colour, clearMode); + RwCameraBeginUpdate(cam); + RenderText(a, enabled); + RwCameraEndUpdate(cam); + RwCameraShowRaster(cam, 0, 1); + iCameraDestroy(cam); +} + void zMainLoadFontHIP() { + iTime time; + + xMemPushBase(); + time = iTimeGet(); + xUtil_idtag2string(0x464f4e54, 0); + iTimeDiffSec(time); + xSTPreLoadScene(0x464f4e54, NULL, 0x1); + time = iTimeGet(); + xUtil_idtag2string(0x464f4e54, 0); + iTimeDiffSec(time); + xSTQueueSceneAssets(0x464f4e54, 1); + time = iTimeGet(); + xUtil_idtag2string(0x464f4e54, 0); + iTimeDiffSec(time); + + do + { + xSTLoadStep(time); + } while (time < 1.0f); + + xSTDisconnect(0x464f4e54, 1); + time = iTimeGet(); + xUtil_idtag2string(0x464f4e54, 0); + iTimeDiffSec(time); } void iEnvStartup() diff --git a/src/SB/Game/zMain.h b/src/SB/Game/zMain.h index c19b8f4f1..ccd77a5f7 100644 --- a/src/SB/Game/zMain.h +++ b/src/SB/Game/zMain.h @@ -5,8 +5,6 @@ #include "xIni.h" #include "xserializer.h" -st_SERIAL_PERCID_SIZE* g_xser_sizeinfo; - enum eStartupErrors { eNoError, diff --git a/src/SB/Game/zTalkBox.h b/src/SB/Game/zTalkBox.h index c27bfb787..e7c75e60c 100644 --- a/src/SB/Game/zTalkBox.h +++ b/src/SB/Game/zTalkBox.h @@ -3,6 +3,7 @@ #include "zTextBox.h" #include "zNPCTypeCommon.h" +#include "xIni.h" #include "xScene.h" @@ -83,6 +84,7 @@ struct ztalkbox : xBase static void init(); static void load(xBase& data, xDynAsset& asset, size_t); + static void load_settings(xIniFile& ini); static void update_all(xScene& s, F32 dt); static void render_all(); static void reset_all(); @@ -90,7 +92,6 @@ struct ztalkbox : xBase static void permit(U32 add_flags, U32 remove_flags); static ztalkbox* get_active(); - void start_talk(U32 textID, callback*, zNPCCommon*); // FIXME: params not verified void load(const asset_type& tasset); From bd8b0137f80d10a69c89f3c6695933376bde72b8 Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Thu, 22 May 2025 13:44:39 -0400 Subject: [PATCH 02/19] review fixes --- src/SB/Game/zMain.cpp | 60 +++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/SB/Game/zMain.cpp b/src/SB/Game/zMain.cpp index e87f0199f..5d9efb3ca 100644 --- a/src/SB/Game/zMain.cpp +++ b/src/SB/Game/zMain.cpp @@ -595,14 +595,14 @@ void zMainMemLvlChkCB() void zLedgeAdjust(zLedgeGrabParams* params) { - params->animGrab *= (1.0f/30); + params->animGrab *= (1.0f / 30); params->animGrab *= (1.0f / 30); } void zMainShowProgressBar() { S32 progBar; - size_t sVar2; + size_t str; char loadingText[12]; char auStack_cc[64]; char acStack_8c[64]; @@ -620,7 +620,7 @@ void zMainShowProgressBar() memset(acStack_8c, 0, 0x40); strcpy(auStack_cc, loadingText); auStack_cc[progBar] = '\0'; - sVar2 = strlen(loadingText); + str = strlen(loadingText); memcpy(auStack_cc, acStack_8c + progBar, progBar); // 3rd arg should have progBar - sVar2 sprintf(formattedStr, "{font=0}{h*2}{w*2}%s{color=FFFFFFFF}%s{~:c}", auStack_cc, acStack_8c); @@ -650,15 +650,15 @@ void zMainLoop() zMainShowProgressBar(); xMemPushBase(); time = iTimeGet(); - xUtil_idtag2string(0x464f4e54, 0); + xUtil_idtag2string('BOOT', 0); iTimeDiffSec(time); - xSTPreLoadScene(0x464f4e54, NULL, 0x1); + xSTPreLoadScene('BOOT', NULL, 0x1); time = iTimeGet(); - xUtil_idtag2string(0x464f4e54, 0); + xUtil_idtag2string('BOOT', 0); iTimeDiffSec(time); - xSTQueueSceneAssets(0x464f4e54, 1); + xSTQueueSceneAssets('BOOT', 1); time = iTimeGet(); - xUtil_idtag2string(0x464f4e54, 0); + xUtil_idtag2string('BOOT', 0); iTimeDiffSec(time); do @@ -666,13 +666,13 @@ void zMainLoop() xSTLoadStep(time); } while (time < 1.0f); - xSTDisconnect(0x464f4e54, 1); + xSTDisconnect('BOOT', 1); time = iTimeGet(); - xUtil_idtag2string(0x464f4e54, 0); + xUtil_idtag2string('BOOT', 0); iTimeDiffSec(time); zMainShowProgressBar(); - xSTPreLoadScene(0x504c4154, 0, 1); - xSTQueueSceneAssets(0x504c4154, 1); + xSTPreLoadScene('PLAT', 0, 1); + xSTQueueSceneAssets('PLAT', 1); do { @@ -688,45 +688,45 @@ void zMainLoop() // zPickupTableInit hasnt been implemented yet xMemPushBase(); time = iTimeGet(); - xUtil_idtag2string(0x4d4e5534, 0); + xUtil_idtag2string('MNU4', 0); iTimeDiffSec(time); - xSTPreLoadScene(0x4d4e5534, 0, 1); + xSTPreLoadScene('MNU4', 0, 1); time = iTimeGet(); - xUtil_idtag2string(0x4d4e5534, 0); + xUtil_idtag2string('MNU4', 0); iTimeDiffSec(time); - xSTQueueSceneAssets(0x4d4e5534, 1); + xSTQueueSceneAssets('MNU4', 1); time = iTimeGet(); - xUtil_idtag2string(0x4d4e5534, 0); + xUtil_idtag2string('MNU4', 0); iTimeDiffSec(time); do { xSTLoadStep(time); } while (time < 1.0f); - xSTDisconnect(0x4d4e5534, 1); + xSTDisconnect('MNU4', 1); zMainShowProgressBar(); time = iTimeGet(); - xUtil_idtag2string(0x4d4e5534, 0); + xUtil_idtag2string('MNU4', 0); iTimeDiffSec(time); xMemPushBase(); time = iTimeGet(); - xUtil_idtag2string(0x4d4e5535, 0); + xUtil_idtag2string('MNU5', 0); iTimeDiffSec(time); - xSTPreLoadScene(0x4d4e5535, 0, 1); + xSTPreLoadScene('MNU5', 0, 1); time = iTimeGet(); - xUtil_idtag2string(0x4d4e5535, 0); + xUtil_idtag2string('MNU5', 0); iTimeDiffSec(time); - xSTQueueSceneAssets(0x4d4e5535, 1); + xSTQueueSceneAssets('MNU5', 1); time = iTimeGet(); - xUtil_idtag2string(0x4d4e5535, 0); + xUtil_idtag2string('MNU5', 0); iTimeDiffSec(time); do { xSTLoadStep(time); } while (time < 1.0f); - xSTDisconnect(0x4d4e5535, 1); + xSTDisconnect('MNU5', 1); zMainShowProgressBar(); time = iTimeGet(); - xUtil_idtag2string(0x4d4e5535, 0); + xUtil_idtag2string('MNU5', 0); iTimeDiffSec(time); xModelInit(); xModelPoolInit(0x20, 0x40); @@ -765,12 +765,12 @@ void zMainMemCardQueryPost(S32 needed, S32 available, S32 neededFiles, S32 unk0) RwRGBA* colour = 0; RwInt32 clearMode = 3; - cam = iCameraCreate(0x280, 0x1e0, 0); + cam = iCameraCreate(640, 480, 0); RwCameraClear(cam, colour, clearMode); RwCameraBeginUpdate(cam); render_mem_card_no_space(needed, available, neededFiles, unk0); RwCameraEndUpdate(cam); - RwCameraShowRaster(cam, 0, 1); + RwCameraShowRaster(cam, NULL, 1); iCameraDestroy(cam); } @@ -780,12 +780,12 @@ void zMainMemCardRenderText(const char* a, bool enabled) RwRGBA* colour = 0; RwInt32 clearMode = 3; - cam = iCameraCreate(0x280, 0x1e0, 0); + cam = iCameraCreate(640, 480, 0); RwCameraClear(cam, colour, clearMode); RwCameraBeginUpdate(cam); RenderText(a, enabled); RwCameraEndUpdate(cam); - RwCameraShowRaster(cam, 0, 1); + RwCameraShowRaster(cam, NULL, 1); iCameraDestroy(cam); } From 481c2b9af57e22e3567f46cc8e3ab130d5426224 Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Thu, 22 May 2025 19:42:09 +0000 Subject: [PATCH 03/19] review fix 2 --- src/SB/Game/zMain.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/SB/Game/zMain.cpp b/src/SB/Game/zMain.cpp index 5d9efb3ca..ab5238744 100644 --- a/src/SB/Game/zMain.cpp +++ b/src/SB/Game/zMain.cpp @@ -683,7 +683,7 @@ void zMainLoop() zMainShowProgressBar(); iTimeGet(); xShadowSimple_Init(); - globals.pickupTable = (zAssetPickupTable*)xSTFindAssetByType(0x5049434b, 0, 0); + globals.pickupTable = (zAssetPickupTable*)xSTFindAssetByType('PLAT', 0, 0); // globals.pickupTable = zPickupTableInit(); // zPickupTableInit hasnt been implemented yet xMemPushBase(); @@ -795,15 +795,15 @@ void zMainLoadFontHIP() xMemPushBase(); time = iTimeGet(); - xUtil_idtag2string(0x464f4e54, 0); + xUtil_idtag2string('FONT', 0); iTimeDiffSec(time); - xSTPreLoadScene(0x464f4e54, NULL, 0x1); + xSTPreLoadScene('FONT', NULL, 0x1); time = iTimeGet(); - xUtil_idtag2string(0x464f4e54, 0); + xUtil_idtag2string('FONT', 0); iTimeDiffSec(time); - xSTQueueSceneAssets(0x464f4e54, 1); + xSTQueueSceneAssets('FONT', 1); time = iTimeGet(); - xUtil_idtag2string(0x464f4e54, 0); + xUtil_idtag2string('FONT', 0); iTimeDiffSec(time); do @@ -811,9 +811,9 @@ void zMainLoadFontHIP() xSTLoadStep(time); } while (time < 1.0f); - xSTDisconnect(0x464f4e54, 1); + xSTDisconnect('FONT', 1); time = iTimeGet(); - xUtil_idtag2string(0x464f4e54, 0); + xUtil_idtag2string('FONT', 0); iTimeDiffSec(time); } From c538bda5136dd99d64337b72e95500611dec980d Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Sat, 24 May 2025 01:20:38 -0400 Subject: [PATCH 04/19] Day 1 SDK link --- config/GQPE78/splits.txt | 366 +-- configure.py | 599 +++-- .../MSL/MSL_C/MSL_Common/Include/cctype | 6 - .../MSL/MSL_C/MSL_Common/Include/climits | 6 - .../MSL/MSL_C/MSL_Common/Include/cstdarg | 8 - .../MSL/MSL_C/MSL_Common/Include/cstddef | 6 - .../MSL/MSL_C/MSL_Common/Include/ctime | 6 - .../MSL/MSL_C/MSL_Common/Include/ctype.h | 14 - .../MSL/MSL_C/MSL_Common/Include/limits.h | 6 - .../MSL/MSL_C/MSL_Common/Include/math.h | 41 - .../MSL/MSL_C/MSL_Common/Include/stdarg.h | 6 - .../MSL/MSL_C/MSL_Common/Include/stddef.h | 6 - .../MSL/MSL_C/MSL_Common/Include/stdio.h | 27 - .../MSL/MSL_C/MSL_Common/Include/string.h | 28 - .../MSL/MSL_C/MSL_Common/Include/va_list.h | 6 - include/bink/bink.h | 3 +- include/dolphin/CARDPriv.h | 139 + include/dolphin/DVDPriv.h | 35 + include/dolphin/OSRtcPriv.h | 38 + include/dolphin/ai.h | 48 +- include/dolphin/ar/ar.h | 45 + include/dolphin/ar/arq.h | 51 + include/dolphin/base.h | 13 + include/dolphin/base/PPCArch.h | 846 +++--- include/dolphin/card.h | 378 +-- include/dolphin/db.h | 28 +- include/dolphin/dolphin/ar.h | 69 - include/dolphin/dolphin/gx.h | 40 - include/dolphin/dolphin/gx/GXBump.h | 29 - include/dolphin/dolphin/gx/GXCommandList.h | 35 - include/dolphin/dolphin/gx/GXCpu2Efb.h | 29 - include/dolphin/dolphin/gx/GXCull.h | 18 - include/dolphin/dolphin/gx/GXDispList.h | 16 - include/dolphin/dolphin/gx/GXDraw.h | 22 - include/dolphin/dolphin/gx/GXEnum.h | 898 ------- include/dolphin/dolphin/gx/GXFifo.h | 50 - include/dolphin/dolphin/gx/GXFrameBuffer.h | 66 - include/dolphin/dolphin/gx/GXGeometry.h | 47 - include/dolphin/dolphin/gx/GXGet.h | 64 - include/dolphin/dolphin/gx/GXLighting.h | 32 - include/dolphin/dolphin/gx/GXManage.h | 36 - include/dolphin/dolphin/gx/GXPerf.h | 30 - include/dolphin/dolphin/gx/GXPixel.h | 30 - include/dolphin/dolphin/gx/GXStruct.h | 75 - include/dolphin/dolphin/gx/GXTev.h | 33 - include/dolphin/dolphin/gx/GXTexture.h | 52 - include/dolphin/dolphin/gx/GXTransform.h | 34 - include/dolphin/dolphin/gx/GXVerify.h | 29 - include/dolphin/dolphin/gx/GXVert.h | 162 -- include/dolphin/dolphin/mtx.h | 373 --- include/dolphin/dolphin/vi.h | 7 - include/dolphin/dolphin/vi/vifuncs.h | 35 - include/dolphin/dolphin/vi/vitypes.h | 39 - include/dolphin/dsp.h | 85 +- include/dolphin/dvd.h | 237 +- include/dolphin/dvd/dvd.h | 169 ++ include/dolphin/dvd/dvdfs.h | 49 + include/dolphin/dvd/dvdlow.h | 41 + include/dolphin/dvd/dvdqueue.h | 28 + include/dolphin/eth/eth.h | 72 + include/dolphin/eth/hashfunc.c | 20 + include/dolphin/exi.h | 86 +- include/dolphin/gd.h | 102 +- include/dolphin/gx.h | 50 +- include/dolphin/gx/GXBump.h | 29 +- include/dolphin/gx/GXCommandList.h | 56 +- include/dolphin/gx/GXCull.h | 9 +- include/dolphin/gx/GXDispList.h | 8 +- include/dolphin/gx/GXDraw.h | 16 +- include/dolphin/gx/GXEnum.h | 1391 +++++----- include/dolphin/gx/GXFifo.h | 35 +- include/dolphin/gx/GXFrameBuffer.h | 40 +- include/dolphin/gx/GXGeometry.h | 58 +- include/dolphin/gx/GXGet.h | 61 +- include/dolphin/gx/GXLighting.h | 30 +- include/dolphin/gx/GXManage.h | 26 +- include/dolphin/gx/GXMisc.h | 21 + include/dolphin/gx/GXPerf.h | 22 +- include/dolphin/gx/GXPixel.h | 19 +- include/dolphin/gx/GXPriv.h | 38 + include/dolphin/gx/GXStruct.h | 93 +- include/dolphin/gx/GXTev.h | 22 +- include/dolphin/gx/GXTexture.h | 59 +- include/dolphin/gx/GXTransform.h | 28 +- include/dolphin/gx/GXVert.h | 191 +- include/dolphin/hio.h | 44 +- include/dolphin/hw_regs.h | 166 +- include/dolphin/ip/ip.h | 26 + include/dolphin/lg.h | 29 + include/dolphin/md5.h | 52 + include/dolphin/mtx.h | 474 +--- include/dolphin/os.h | 421 ++- include/dolphin/os/OSAlarm.h | 34 +- include/dolphin/os/OSAlloc.h | 36 +- include/dolphin/os/OSArena.h | 13 + include/dolphin/os/OSBootInfo.h | 41 + include/dolphin/os/OSCache.h | 11 +- include/dolphin/os/OSContext.h | 57 +- include/dolphin/os/OSError.h | 53 +- include/dolphin/os/OSException.h | 45 +- include/dolphin/os/OSExpansion.h | 79 + include/dolphin/os/OSFastCast.h | 86 + include/dolphin/os/OSFont.h | 80 +- include/dolphin/os/OSFst.h | 19 + include/dolphin/os/OSInterrupt.h | 71 +- include/dolphin/os/OSMemory.h | 10 +- include/dolphin/os/OSMessage.h | 40 +- include/dolphin/os/OSModule.h | 92 +- include/dolphin/os/OSMutex.h | 24 +- include/dolphin/os/OSPriv.h | 18 + include/dolphin/os/OSReset.h | 52 +- include/dolphin/os/OSResetSW.h | 11 +- include/dolphin/os/OSSerial.h | 71 +- include/dolphin/os/OSThread.h | 155 +- include/dolphin/os/OSTime.h | 57 +- include/dolphin/os/init/__start.h | 46 + include/dolphin/pad.h | 48 +- include/dolphin/sipriv.h | 42 + include/dolphin/tcp/tcp.h | 29 + include/dolphin/thp.h | 129 + include/dolphin/types.h | 61 +- include/dolphin/vi.h | 175 +- include/dolphin/vi/vitypes.h | 60 +- include/inline/fastmath.h | 2 +- include/macros.h | 80 + include/mathHelper.h | 14 + include/rwsdk/rwplcore.h | 2 +- include/std/bitset.h | 116 + include/std/math.h | 79 + include/types.h | 51 + .../MSL_C++/MSL_Common/Include/exception | 0 .../MSL_C++/MSL_Common/Include/exception.h | 0 .../MSL_C++/MSL_Common/Include/new | 0 .../MSL_C++/MSL_Common/Include/new.h | 2 +- .../MSL_C/MSL_Common/FILE_POS.h | 20 + .../MSL_C/MSL_Common/abort_exit.h | 17 + .../MSL_C/MSL_Common/alloc.h | 8 + .../MSL_C/MSL_Common/ansi_files.h | 90 + .../MSL_C/MSL_Common/ansi_fp.h | 40 + .../MSL_C/MSL_Common/ansi_params.h | 14 + .../MSL_C/MSL_Common/arith.h | 24 + .../MSL_C/MSL_Common/bsearch.h | 18 + .../MSL_C/MSL_Common}/cmath | 0 .../MSL_C/MSL_Common/critical_regions.h | 32 + .../MSL_C/MSL_Common}/cstdlib | 0 .../MSL_C/MSL_Common}/cstring | 0 .../MSL_C/MSL_Common/ctype_api.h | 36 + .../MSL_C/MSL_Common/direct_io.h | 10 + .../MSL_C/MSL_Common/file_io.h | 10 + .../MSL_C/MSL_Common/file_struc.h | 10 + .../MSL_C/MSL_Common/locale_api.h | 9 + .../MSL_C/MSL_Common/math_api.h | 93 + .../MSL_C/MSL_Common/mbstring.h | 21 + .../MSL_C/MSL_Common/mem_funcs.h | 11 + .../MSL_C/MSL_Common/misc_io.h | 8 + .../MSL_C/MSL_Common/printf.h | 25 + .../MSL_C/MSL_Common/rand.h | 17 + .../MSL_C/MSL_Common/scanf.h | 18 + .../MSL_C/MSL_Common/secure_error.h | 10 + .../MSL_C/MSL_Common/signal.h | 17 + .../MSL_C/MSL_Common}/size_t.h | 0 .../MSL_C/MSL_Common/stdio_api.h | 38 + .../MSL_C/MSL_Common}/stdlib.h | 4 +- .../MSL_C/MSL_Common/strtold.h | 6 + .../MSL_C/MSL_Common/strtoul.h | 20 + .../MSL_C/MSL_Common}/time.h | 0 .../MSL_C/MSL_Common/wchar_io.h | 9 + .../MSL_C/PPC_EABI/math_ppc.h | 18 + .../MetroTRK/custconn/CircleBuffer.h | 24 + .../MetroTRK/custconn/cc_gdev.h | 23 + .../PowerPC_EABI_Support/MetroTRK/dispatch.h | 25 + .../MetroTRK/dolphin_trk.h | 16 + .../MetroTRK/target_options.h | 9 + .../PowerPC_EABI_Support/MetroTRK/trk.h | 219 ++ .../Runtime/Gecko_ExceptionPPC.h | 231 ++ .../Runtime/MWCPlusPlusLib.h | 46 + .../Runtime/NMWException.h | 34 + .../Runtime/__init_cpp_exceptions.h | 14 + .../PowerPC_EABI_Support/Runtime/__mem.h | 16 + .../Runtime/__ppc_eabi_linker.h | 74 + .../PowerPC_EABI_Support/Runtime/__va_arg.h | 13 + .../Runtime/global_destructor_chain.h | 26 + .../PowerPC_EABI_Support/Runtime/runtime.h | 19 + libs/PowerPC_EABI_Support/include/algorithm | 51 + libs/PowerPC_EABI_Support/include/ctype.h | 54 + libs/PowerPC_EABI_Support/include/errno.h | 59 + libs/PowerPC_EABI_Support/include/exception | 20 + libs/PowerPC_EABI_Support/include/extras.h | 14 + libs/PowerPC_EABI_Support/include/fdlibm.h | 230 ++ libs/PowerPC_EABI_Support/include/float.h | 59 + libs/PowerPC_EABI_Support/include/functional | 20 + libs/PowerPC_EABI_Support/include/iterator | 41 + libs/PowerPC_EABI_Support/include/limits | 70 + libs/PowerPC_EABI_Support/include/limits.h | 36 + libs/PowerPC_EABI_Support/include/locale.h | 129 + libs/PowerPC_EABI_Support/include/math.h | 99 + libs/PowerPC_EABI_Support/include/mem.h | 20 + libs/PowerPC_EABI_Support/include/signal.h | 18 + libs/PowerPC_EABI_Support/include/stdarg.h | 40 + libs/PowerPC_EABI_Support/include/stddef.h | 6 + libs/PowerPC_EABI_Support/include/stdio.h | 19 + libs/PowerPC_EABI_Support/include/stdlib.h | 20 + libs/PowerPC_EABI_Support/include/string.h | 31 + libs/PowerPC_EABI_Support/include/utility | 21 + libs/PowerPC_EABI_Support/include/wchar.h | 16 + .../src/MSL_C/MSL_Common/FILE_POS.C | 130 + .../src/MSL_C/MSL_Common/alloc.c | 452 ++++ .../src/MSL_C/MSL_Common/ansi_files.c | 154 ++ .../src/MSL_C/MSL_Common/arith.c | 120 + .../src/MSL_C/MSL_Common/bsearch.c | 40 + .../src/MSL_C/MSL_Common/buffer_io.c | 53 + .../src/MSL_C/MSL_Common/ctype.c | 137 + .../src/MSL_C/MSL_Common/direct_io.c | 143 + .../src/MSL_C/MSL_Common/errno.c | 3 + .../src/MSL_C/MSL_Common/extras.c | 401 +++ .../src/MSL_C/MSL_Common/file_io.c | 93 + .../src/MSL_C/MSL_Common/float.c | 8 + .../src/MSL_C/MSL_Common/locale.c | 33 + .../src/MSL_C/MSL_Common/mbstring.c | 260 ++ .../src/MSL_C/MSL_Common/mem.c | 105 + .../src/MSL_C/MSL_Common/mem_funcs.c | 217 ++ .../src/MSL_C/MSL_Common/misc_io.c | 25 + .../src/MSL_C/MSL_Common/printf.c | 1250 +++++++++ .../src/MSL_C/MSL_Common/rand.c | 14 + .../src/MSL_C/MSL_Common/scanf.c | 670 +++++ .../src/MSL_C/MSL_Common/signal.c | 39 + .../src/MSL_C/MSL_Common/string.c | 306 +++ .../src/MSL_C/MSL_Common/strtold.c | 703 +++++ .../src/MSL_C/MSL_Common/strtoul.c | 353 +++ .../src/MSL_C/MSL_Common/wchar_io.c | 82 + .../Math/Double_precision/e_asin.c | 117 + .../Math/Double_precision/e_atan2.c | 143 + .../Math/Double_precision/e_exp.c | 162 ++ .../Math/Double_precision/e_fmod.c | 167 ++ .../Math/Double_precision/e_log.c | 157 ++ .../Math/Double_precision/e_log10.c | 99 + .../Math/Double_precision/e_pow.c | 408 +++ .../Math/Double_precision/e_rem_pio2.c | 181 ++ .../Math/Double_precision/e_sqrt.c | 462 ++++ .../Math/Double_precision/k_cos.c | 93 + .../Math/Double_precision/k_rem_pio2.c | 355 +++ .../Math/Double_precision/k_sin.c | 80 + .../Math/Double_precision/k_tan.c | 181 ++ .../Math/Double_precision/s_atan.c | 143 + .../Math/Double_precision/s_ceil.c | 90 + .../Math/Double_precision/s_copysign.c | 30 + .../Math/Double_precision/s_cos.c | 82 + .../Math/Double_precision/s_floor.c | 89 + .../Math/Double_precision/s_frexp.c | 58 + .../Math/Double_precision/s_ldexp.c | 63 + .../Math/Double_precision/s_modf.c | 79 + .../Math/Double_precision/s_sin.c | 82 + .../Math/Double_precision/s_tan.c | 73 + .../Math/Double_precision/w_asin.c | 15 + .../Math/Double_precision/w_atan2.c | 15 + .../Math/Double_precision/w_exp.c | 15 + .../Math/Double_precision/w_fmod.c | 15 + .../Math/Double_precision/w_log10.c | 15 + .../Math/Double_precision/w_pow.c | 15 + .../Math/Double_precision/w_sqrt.c | 15 + .../src/MSL_C/MSL_Common_Embedded/ansi_fp.c | 779 ++++++ .../MSL_Common_Embedded/uart_console_io_gcn.c | 57 + .../src/MSL_C/PPC_EABI/abort_exit.c | 70 + .../PPC_EABI/critical_regions.gamecube.c | 10 + .../src/MSL_C/PPC_EABI/math_ppc.c | 520 ++++ .../src/Runtime/CPlusLibPPC.cp | 41 + .../src/Runtime/GCN_mem_alloc.c | 36 + .../src/Runtime/Gecko_ExceptionPPC.cp | 891 +++++++ .../src/Runtime/NMWException.cp | 91 + .../src/Runtime/__init_cpp_exceptions.cpp | 37 + libs/PowerPC_EABI_Support/src/Runtime/__mem.c | 102 + .../src/Runtime/__va_arg.c | 44 + .../src/Runtime/global_destructor_chain.c | 32 + libs/PowerPC_EABI_Support/src/Runtime/ptmf.c | 104 + .../src/Runtime/runtime.c | 920 +++++++ .../src/runtime3/READ_ME.txt | 6 + .../src/runtime3/runtime.c | 920 +++++++ libs/dolphin/OdemuExi2/DebuggerDriver.c | 0 libs/dolphin/ai/ai.c | 354 +++ libs/dolphin/ar/ar.c | 383 +++ libs/dolphin/ar/arq.c | 271 ++ libs/dolphin/ax/AX.c | 43 + libs/dolphin/ax/AXAlloc.c | 256 ++ libs/dolphin/ax/AXAux.c | 184 ++ libs/dolphin/ax/AXCL.c | 226 ++ libs/dolphin/ax/AXComp.c | 287 ++ libs/dolphin/ax/AXOut.c | 243 ++ libs/dolphin/ax/AXProf.c | 24 + libs/dolphin/ax/AXSPB.c | 94 + libs/dolphin/ax/AXVPB.c | 1299 +++++++++ libs/dolphin/ax/DSPCode.c | 211 ++ libs/dolphin/ax/__ax.h | 67 + libs/dolphin/base/PPCArch.c | 263 ++ libs/dolphin/card/CARDBios.c | 722 +++++ libs/dolphin/card/CARDBlock.c | 159 ++ libs/dolphin/card/CARDCheck.c | 406 +++ libs/dolphin/card/CARDCreate.c | 141 + libs/dolphin/card/CARDDelete.c | 85 + libs/dolphin/card/CARDDir.c | 92 + libs/dolphin/card/CARDFormat.c | 138 + libs/dolphin/card/CARDMount.c | 366 +++ libs/dolphin/card/CARDNet.c | 55 + libs/dolphin/card/CARDOpen.c | 209 ++ libs/dolphin/card/CARDRdwr.c | 125 + libs/dolphin/card/CARDRead.c | 151 ++ libs/dolphin/card/CARDRename.c | 83 + libs/dolphin/card/CARDStat.c | 152 ++ libs/dolphin/card/CARDStatEx.c | 125 + libs/dolphin/card/CARDUnlock.c | 419 +++ libs/dolphin/card/CARDWrite.c | 128 + libs/dolphin/card/__card.h | 104 + libs/dolphin/db/db.c | 46 + libs/dolphin/dsp/dsp.c | 115 + libs/dolphin/dsp/dsp_debug.c | 6 + libs/dolphin/dsp/dsp_task.c | 426 +++ libs/dolphin/dvd/dvd.c | 1664 ++++++++++++ libs/dolphin/dvd/dvdFatal.c | 112 + libs/dolphin/dvd/dvderror.c | 77 + libs/dolphin/dvd/dvdfs.c | 739 ++++++ libs/dolphin/dvd/dvdidutils.c | 31 + libs/dolphin/dvd/dvdlow.c | 515 ++++ libs/dolphin/dvd/dvdqueue.c | 159 ++ libs/dolphin/dvd/emu_level2/fstload.c | 75 + libs/dolphin/eth/base64.c | 70 + libs/dolphin/eth/eth.c | 1031 ++++++++ libs/dolphin/eth/ethsec.c | 344 +++ libs/dolphin/eth/md5.c | 285 ++ libs/dolphin/exi/EXIBios.c | 854 ++++++ libs/dolphin/exi/EXIUart.c | 202 ++ libs/dolphin/gd/GDBase.c | 0 libs/dolphin/gd/GDGeometry.c | 0 libs/dolphin/gx/GXAttr.c | 0 libs/dolphin/gx/GXBump.c | 0 libs/dolphin/gx/GXDisplayList.c | 0 libs/dolphin/gx/GXDraw.c | 0 libs/dolphin/gx/GXFifo.c | 0 libs/dolphin/gx/GXFrameBuf.c | 0 libs/dolphin/gx/GXGeometry.c | 0 libs/dolphin/gx/GXInit.c | 0 libs/dolphin/gx/GXLight.c | 0 libs/dolphin/gx/GXMisc.c | 0 libs/dolphin/gx/GXPerf.c | 0 libs/dolphin/gx/GXPixel.c | 0 libs/dolphin/gx/GXTev.c | 0 libs/dolphin/gx/GXTexture.c | 0 libs/dolphin/gx/GXTransform.c | 0 libs/dolphin/hio/hio.c | 0 libs/dolphin/ip/IFFifo.c | 0 libs/dolphin/ip/IFRing.c | 0 libs/dolphin/ip/IP.c | 0 libs/dolphin/ip/IPArp.c | 0 libs/dolphin/ip/IPChap.c | 0 libs/dolphin/ip/IPDhcp.c | 0 libs/dolphin/ip/IPDns.c | 0 libs/dolphin/ip/IPEther.c | 0 libs/dolphin/ip/IPFrag.c | 0 libs/dolphin/ip/IPIcmp.c | 0 libs/dolphin/ip/IPIgmp.c | 0 libs/dolphin/ip/IPIpcp.c | 0 libs/dolphin/ip/IPLcp.c | 0 libs/dolphin/ip/IPOpt.c | 0 libs/dolphin/ip/IPPPP.c | 0 libs/dolphin/ip/IPPPPoE.c | 0 libs/dolphin/ip/IPPap.c | 0 libs/dolphin/ip/IPRoute.c | 0 libs/dolphin/ip/IPSocket.c | 0 libs/dolphin/ip/IPTcp.c | 0 libs/dolphin/ip/IPTcpOutput.c | 0 libs/dolphin/ip/IPTcpTimeWait.c | 0 libs/dolphin/ip/IPTcpTimer.c | 0 libs/dolphin/ip/IPTcpUser.c | 0 libs/dolphin/ip/IPUdp.c | 0 libs/dolphin/ip/IPUuid.c | 0 libs/dolphin/ip/IPZero.c | 0 libs/dolphin/lg/allsrc.c | 0 libs/dolphin/mtx/mtx.c | 0 libs/dolphin/mtx/mtx44.c | 0 libs/dolphin/mtx/mtx44vec.c | 39 + libs/dolphin/mtx/mtxvec.c | 0 libs/dolphin/mtx/quat.c | 0 libs/dolphin/mtx/vec.c | 262 ++ libs/dolphin/odenotstub/odenotstub.c | 0 libs/dolphin/os/OS.c | 678 +++++ libs/dolphin/os/OSAlarm.c | 254 ++ libs/dolphin/os/OSAlloc.c | 228 ++ libs/dolphin/os/OSArena.c | 41 + libs/dolphin/os/OSAudioSystem.c | 114 + libs/dolphin/os/OSCache.c | 426 +++ libs/dolphin/os/OSContext.c | 637 +++++ libs/dolphin/os/OSError.c | 205 ++ libs/dolphin/os/OSFont.c | 32 + libs/dolphin/os/OSInterrupt.c | 427 +++ libs/dolphin/os/OSLink.c | 556 ++++ libs/dolphin/os/OSMemory.c | 223 ++ libs/dolphin/os/OSMessage.c | 86 + libs/dolphin/os/OSMutex.c | 223 ++ libs/dolphin/os/OSReboot.c | 119 + libs/dolphin/os/OSReset.c | 211 ++ libs/dolphin/os/OSResetSW.c | 118 + libs/dolphin/os/OSRtc.c | 399 +++ libs/dolphin/os/OSSync.c | 29 + libs/dolphin/os/OSThread.c | 590 +++++ libs/dolphin/os/OSTime.c | 137 + libs/dolphin/os/init/__ppc_eabi_init.cpp | 74 + libs/dolphin/os/init/__start.c | 223 ++ libs/dolphin/pad/Pad.c | 901 +++++++ libs/dolphin/pad/Padclamp.c | 198 ++ libs/dolphin/si/SIBios.c | 902 +++++++ libs/dolphin/si/SISamplingRate.c | 80 + libs/dolphin/si/SISteering.c | 0 libs/dolphin/si/SISteeringAuto.c | 0 libs/dolphin/si/SISteeringXfer.c | 0 libs/dolphin/thp/THPAudio.c | 202 ++ libs/dolphin/thp/THPDec.c | 2316 +++++++++++++++++ libs/dolphin/upnp/UPnP.c | 0 libs/dolphin/upnp/UPnPHttp.c | 0 libs/dolphin/upnp/UPnPHttpd.c | 0 libs/dolphin/upnp/UPnPHttpdResponse.c | 0 libs/dolphin/upnp/UPnPSsdp.c | 0 libs/dolphin/upnp/UPnPUri.c | 0 libs/dolphin/upnp/UPnPUuid.c | 0 libs/dolphin/vi/vi.c | 1037 ++++++++ .../embedded/MetroTRK/Export/mslsupp.c | 0 .../embedded/MetroTRK/Os/dolphin/UDP_Stubs.c | 0 .../MetroTRK/Os/dolphin/dolphin_trk.c | 0 .../MetroTRK/Os/dolphin/dolphin_trk_glue.c | 0 .../embedded/MetroTRK/Os/dolphin/targcont.c | 0 .../MetroTRK/Os/dolphin/target_options.c | 0 .../embedded/MetroTRK/Os/dolphin/usr_put.c | 0 .../embedded/MetroTRK/Portable/dispatch.c | 0 .../embedded/MetroTRK/Portable/main_TRK.c | 0 .../embedded/MetroTRK/Portable/mainloop.c | 0 .../embedded/MetroTRK/Portable/mem_TRK.c | 0 .../debugger/embedded/MetroTRK/Portable/msg.c | 0 .../embedded/MetroTRK/Portable/msgbuf.c | 0 .../embedded/MetroTRK/Portable/msghndlr.c | 0 .../embedded/MetroTRK/Portable/mutex_TRK.c | 0 .../embedded/MetroTRK/Portable/notify.c | 0 .../embedded/MetroTRK/Portable/nubevent.c | 0 .../embedded/MetroTRK/Portable/nubinit.c | 0 .../embedded/MetroTRK/Portable/serpoll.c | 0 .../embedded/MetroTRK/Portable/support.c | 0 .../MetroTRK/Processor/ppc/Export/targsupp.s | 0 .../Processor/ppc/Generic/__exception.s | 0 .../Processor/ppc/Generic/flush_cache.c | 0 .../Processor/ppc/Generic/mpc_7xx_603e.c | 0 .../MetroTRK/Processor/ppc/Generic/targimpl.c | 0 .../cc/exi2/GCN/EXI2_DDH_GCN/main.c | 0 .../cc/exi2/GCN/EXI2_GDEV_GCN/main.c | 0 .../utils/common/CircleBuffer.c | 0 .../cust_connection/utils/common/MWTrace.c | 0 .../utils/gc/MWCriticalSection_gc.cpp | 0 src/SB/Core/gc/iFMV.cpp | 1 + src/SB/Core/gc/iFMV.h | 2 +- src/SB/Core/gc/iMath.cpp | 2 +- src/SB/Core/gc/iMemMgr.cpp | 2 +- src/SB/Core/gc/iMix.c | 729 ++---- src/SB/Core/gc/iPad.cpp | 2 + src/SB/Core/gc/iTRC.cpp | 14 +- src/SB/Core/gc/ngcrad3d.c | 173 +- src/SB/Core/x/xAnim.cpp | 20 +- src/SB/Core/x/xCamera.cpp | 17 +- src/SB/Core/x/xCutscene.cpp | 12 +- src/SB/Core/x/xFont.cpp | 1 + src/SB/Core/x/xHud.cpp | 24 +- src/SB/Core/x/xHudMeter.cpp | 1 + src/SB/Core/x/xHudModel.cpp | 2 +- src/SB/Core/x/xHudText.cpp | 4 +- src/SB/Core/x/xIni.cpp | 4 +- src/SB/Core/x/xJaw.cpp | 16 +- src/SB/Core/x/xMath.cpp | 233 +- src/SB/Core/x/xModelBucket.cpp | 2 +- src/SB/Core/x/xPtankPool.cpp | 2 +- src/SB/Core/x/xRMemData.h | 2 +- src/SB/Core/x/xString.h | 2 +- src/SB/Core/x/xpkrsvc.h | 3 +- src/SB/Core/x/xutil.cpp | 2 + src/SB/Game/zAssetTypes.cpp | 1 + src/SB/Game/zCamera.h | 2 + src/SB/Game/zDiscoFloor.cpp | 1 + src/SB/Game/zEnt.cpp | 3 +- src/SB/Game/zEntCruiseBubble.cpp | 2 +- src/SB/Game/zEntPlayerBungeeState.cpp | 2 +- src/SB/Game/zFX.cpp | 2 +- src/SB/Game/zMain.cpp | 2 +- src/SB/Game/zParPTank.cpp | 11 +- src/SB/Game/zUI.cpp | 5 +- src/SB/Game/zVar.cpp | 1 + 488 files changed, 48837 insertions(+), 7114 deletions(-) delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cctype delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/climits delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdarg delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstddef delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctime delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctype.h delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/limits.h delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/math.h delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdarg.h delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stddef.h delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdio.h delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/va_list.h create mode 100644 include/dolphin/CARDPriv.h create mode 100644 include/dolphin/DVDPriv.h create mode 100644 include/dolphin/OSRtcPriv.h create mode 100644 include/dolphin/ar/ar.h create mode 100644 include/dolphin/ar/arq.h create mode 100644 include/dolphin/base.h delete mode 100644 include/dolphin/dolphin/ar.h delete mode 100644 include/dolphin/dolphin/gx.h delete mode 100644 include/dolphin/dolphin/gx/GXBump.h delete mode 100644 include/dolphin/dolphin/gx/GXCommandList.h delete mode 100644 include/dolphin/dolphin/gx/GXCpu2Efb.h delete mode 100644 include/dolphin/dolphin/gx/GXCull.h delete mode 100644 include/dolphin/dolphin/gx/GXDispList.h delete mode 100644 include/dolphin/dolphin/gx/GXDraw.h delete mode 100644 include/dolphin/dolphin/gx/GXEnum.h delete mode 100644 include/dolphin/dolphin/gx/GXFifo.h delete mode 100644 include/dolphin/dolphin/gx/GXFrameBuffer.h delete mode 100644 include/dolphin/dolphin/gx/GXGeometry.h delete mode 100644 include/dolphin/dolphin/gx/GXGet.h delete mode 100644 include/dolphin/dolphin/gx/GXLighting.h delete mode 100644 include/dolphin/dolphin/gx/GXManage.h delete mode 100644 include/dolphin/dolphin/gx/GXPerf.h delete mode 100644 include/dolphin/dolphin/gx/GXPixel.h delete mode 100644 include/dolphin/dolphin/gx/GXStruct.h delete mode 100644 include/dolphin/dolphin/gx/GXTev.h delete mode 100644 include/dolphin/dolphin/gx/GXTexture.h delete mode 100644 include/dolphin/dolphin/gx/GXTransform.h delete mode 100644 include/dolphin/dolphin/gx/GXVerify.h delete mode 100644 include/dolphin/dolphin/gx/GXVert.h delete mode 100644 include/dolphin/dolphin/mtx.h delete mode 100644 include/dolphin/dolphin/vi.h delete mode 100644 include/dolphin/dolphin/vi/vifuncs.h delete mode 100644 include/dolphin/dolphin/vi/vitypes.h create mode 100644 include/dolphin/dvd/dvd.h create mode 100644 include/dolphin/dvd/dvdfs.h create mode 100644 include/dolphin/dvd/dvdlow.h create mode 100644 include/dolphin/dvd/dvdqueue.h create mode 100644 include/dolphin/eth/eth.h create mode 100644 include/dolphin/eth/hashfunc.c create mode 100644 include/dolphin/gx/GXMisc.h create mode 100644 include/dolphin/gx/GXPriv.h create mode 100644 include/dolphin/ip/ip.h create mode 100644 include/dolphin/lg.h create mode 100644 include/dolphin/md5.h create mode 100644 include/dolphin/os/OSArena.h create mode 100644 include/dolphin/os/OSBootInfo.h create mode 100644 include/dolphin/os/OSExpansion.h create mode 100644 include/dolphin/os/OSFastCast.h create mode 100644 include/dolphin/os/OSFst.h create mode 100644 include/dolphin/os/OSPriv.h create mode 100644 include/dolphin/os/init/__start.h create mode 100644 include/dolphin/sipriv.h create mode 100644 include/dolphin/tcp/tcp.h create mode 100644 include/dolphin/thp.h create mode 100644 include/macros.h create mode 100644 include/mathHelper.h create mode 100644 include/std/bitset.h create mode 100644 include/std/math.h rename {include/PowerPC_EABI_Support/MSL => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support}/MSL_C++/MSL_Common/Include/exception (100%) rename {include/PowerPC_EABI_Support/MSL => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support}/MSL_C++/MSL_Common/Include/exception.h (100%) rename {include/PowerPC_EABI_Support/MSL => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support}/MSL_C++/MSL_Common/Include/new (100%) rename {include/PowerPC_EABI_Support/MSL => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support}/MSL_C++/MSL_Common/Include/new.h (94%) create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/abort_exit.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/alloc.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_fp.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_params.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/arith.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/bsearch.h rename {include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common}/cmath (100%) create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h rename {include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common}/cstdlib (100%) rename {include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common}/cstring (100%) create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ctype_api.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/direct_io.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_io.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_struc.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/locale_api.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mbstring.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mem_funcs.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/printf.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/rand.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/scanf.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/secure_error.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/signal.h rename {include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common}/size_t.h (100%) create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h rename {include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common}/stdlib.h (71%) create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtold.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtoul.h rename {include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common}/time.h (100%) create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/wchar_io.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/PPC_EABI/math_ppc.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/custconn/CircleBuffer.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/custconn/cc_gdev.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dispatch.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dolphin_trk.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/target_options.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trk.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/Gecko_ExceptionPPC.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/MWCPlusPlusLib.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/NMWException.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__init_cpp_exceptions.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__mem.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__va_arg.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/global_destructor_chain.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/runtime.h create mode 100644 libs/PowerPC_EABI_Support/include/algorithm create mode 100644 libs/PowerPC_EABI_Support/include/ctype.h create mode 100644 libs/PowerPC_EABI_Support/include/errno.h create mode 100644 libs/PowerPC_EABI_Support/include/exception create mode 100644 libs/PowerPC_EABI_Support/include/extras.h create mode 100644 libs/PowerPC_EABI_Support/include/fdlibm.h create mode 100644 libs/PowerPC_EABI_Support/include/float.h create mode 100644 libs/PowerPC_EABI_Support/include/functional create mode 100644 libs/PowerPC_EABI_Support/include/iterator create mode 100644 libs/PowerPC_EABI_Support/include/limits create mode 100644 libs/PowerPC_EABI_Support/include/limits.h create mode 100644 libs/PowerPC_EABI_Support/include/locale.h create mode 100644 libs/PowerPC_EABI_Support/include/math.h create mode 100644 libs/PowerPC_EABI_Support/include/mem.h create mode 100644 libs/PowerPC_EABI_Support/include/signal.h create mode 100644 libs/PowerPC_EABI_Support/include/stdarg.h create mode 100644 libs/PowerPC_EABI_Support/include/stddef.h create mode 100644 libs/PowerPC_EABI_Support/include/stdio.h create mode 100644 libs/PowerPC_EABI_Support/include/stdlib.h create mode 100644 libs/PowerPC_EABI_Support/include/string.h create mode 100644 libs/PowerPC_EABI_Support/include/utility create mode 100644 libs/PowerPC_EABI_Support/include/wchar.h create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/FILE_POS.C create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/alloc.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ansi_files.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/arith.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/bsearch.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/buffer_io.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ctype.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/direct_io.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/errno.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/extras.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/file_io.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/float.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/locale.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mbstring.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem_funcs.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/misc_io.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/printf.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/rand.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/scanf.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/signal.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/string.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtold.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtoul.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/wchar_io.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log10.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_sqrt.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log10.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_sqrt.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/ansi_fp.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/abort_exit.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/critical_regions.gamecube.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/math_ppc.c create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/CPlusLibPPC.cp create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/GCN_mem_alloc.c create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/Gecko_ExceptionPPC.cp create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/NMWException.cp create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/__init_cpp_exceptions.cpp create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/__mem.c create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/__va_arg.c create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/global_destructor_chain.c create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/ptmf.c create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/runtime.c create mode 100644 libs/PowerPC_EABI_Support/src/runtime3/READ_ME.txt create mode 100644 libs/PowerPC_EABI_Support/src/runtime3/runtime.c create mode 100644 libs/dolphin/OdemuExi2/DebuggerDriver.c create mode 100644 libs/dolphin/ai/ai.c create mode 100644 libs/dolphin/ar/ar.c create mode 100644 libs/dolphin/ar/arq.c create mode 100644 libs/dolphin/ax/AX.c create mode 100644 libs/dolphin/ax/AXAlloc.c create mode 100644 libs/dolphin/ax/AXAux.c create mode 100644 libs/dolphin/ax/AXCL.c create mode 100644 libs/dolphin/ax/AXComp.c create mode 100644 libs/dolphin/ax/AXOut.c create mode 100644 libs/dolphin/ax/AXProf.c create mode 100644 libs/dolphin/ax/AXSPB.c create mode 100644 libs/dolphin/ax/AXVPB.c create mode 100644 libs/dolphin/ax/DSPCode.c create mode 100644 libs/dolphin/ax/__ax.h create mode 100644 libs/dolphin/base/PPCArch.c create mode 100644 libs/dolphin/card/CARDBios.c create mode 100644 libs/dolphin/card/CARDBlock.c create mode 100644 libs/dolphin/card/CARDCheck.c create mode 100644 libs/dolphin/card/CARDCreate.c create mode 100644 libs/dolphin/card/CARDDelete.c create mode 100644 libs/dolphin/card/CARDDir.c create mode 100644 libs/dolphin/card/CARDFormat.c create mode 100644 libs/dolphin/card/CARDMount.c create mode 100644 libs/dolphin/card/CARDNet.c create mode 100644 libs/dolphin/card/CARDOpen.c create mode 100644 libs/dolphin/card/CARDRdwr.c create mode 100644 libs/dolphin/card/CARDRead.c create mode 100644 libs/dolphin/card/CARDRename.c create mode 100644 libs/dolphin/card/CARDStat.c create mode 100644 libs/dolphin/card/CARDStatEx.c create mode 100644 libs/dolphin/card/CARDUnlock.c create mode 100644 libs/dolphin/card/CARDWrite.c create mode 100644 libs/dolphin/card/__card.h create mode 100644 libs/dolphin/db/db.c create mode 100644 libs/dolphin/dsp/dsp.c create mode 100644 libs/dolphin/dsp/dsp_debug.c create mode 100644 libs/dolphin/dsp/dsp_task.c create mode 100644 libs/dolphin/dvd/dvd.c create mode 100644 libs/dolphin/dvd/dvdFatal.c create mode 100644 libs/dolphin/dvd/dvderror.c create mode 100644 libs/dolphin/dvd/dvdfs.c create mode 100644 libs/dolphin/dvd/dvdidutils.c create mode 100644 libs/dolphin/dvd/dvdlow.c create mode 100644 libs/dolphin/dvd/dvdqueue.c create mode 100644 libs/dolphin/dvd/emu_level2/fstload.c create mode 100644 libs/dolphin/eth/base64.c create mode 100644 libs/dolphin/eth/eth.c create mode 100644 libs/dolphin/eth/ethsec.c create mode 100644 libs/dolphin/eth/md5.c create mode 100644 libs/dolphin/exi/EXIBios.c create mode 100644 libs/dolphin/exi/EXIUart.c create mode 100644 libs/dolphin/gd/GDBase.c create mode 100644 libs/dolphin/gd/GDGeometry.c create mode 100644 libs/dolphin/gx/GXAttr.c create mode 100644 libs/dolphin/gx/GXBump.c create mode 100644 libs/dolphin/gx/GXDisplayList.c create mode 100644 libs/dolphin/gx/GXDraw.c create mode 100644 libs/dolphin/gx/GXFifo.c create mode 100644 libs/dolphin/gx/GXFrameBuf.c create mode 100644 libs/dolphin/gx/GXGeometry.c create mode 100644 libs/dolphin/gx/GXInit.c create mode 100644 libs/dolphin/gx/GXLight.c create mode 100644 libs/dolphin/gx/GXMisc.c create mode 100644 libs/dolphin/gx/GXPerf.c create mode 100644 libs/dolphin/gx/GXPixel.c create mode 100644 libs/dolphin/gx/GXTev.c create mode 100644 libs/dolphin/gx/GXTexture.c create mode 100644 libs/dolphin/gx/GXTransform.c create mode 100644 libs/dolphin/hio/hio.c create mode 100644 libs/dolphin/ip/IFFifo.c create mode 100644 libs/dolphin/ip/IFRing.c create mode 100644 libs/dolphin/ip/IP.c create mode 100644 libs/dolphin/ip/IPArp.c create mode 100644 libs/dolphin/ip/IPChap.c create mode 100644 libs/dolphin/ip/IPDhcp.c create mode 100644 libs/dolphin/ip/IPDns.c create mode 100644 libs/dolphin/ip/IPEther.c create mode 100644 libs/dolphin/ip/IPFrag.c create mode 100644 libs/dolphin/ip/IPIcmp.c create mode 100644 libs/dolphin/ip/IPIgmp.c create mode 100644 libs/dolphin/ip/IPIpcp.c create mode 100644 libs/dolphin/ip/IPLcp.c create mode 100644 libs/dolphin/ip/IPOpt.c create mode 100644 libs/dolphin/ip/IPPPP.c create mode 100644 libs/dolphin/ip/IPPPPoE.c create mode 100644 libs/dolphin/ip/IPPap.c create mode 100644 libs/dolphin/ip/IPRoute.c create mode 100644 libs/dolphin/ip/IPSocket.c create mode 100644 libs/dolphin/ip/IPTcp.c create mode 100644 libs/dolphin/ip/IPTcpOutput.c create mode 100644 libs/dolphin/ip/IPTcpTimeWait.c create mode 100644 libs/dolphin/ip/IPTcpTimer.c create mode 100644 libs/dolphin/ip/IPTcpUser.c create mode 100644 libs/dolphin/ip/IPUdp.c create mode 100644 libs/dolphin/ip/IPUuid.c create mode 100644 libs/dolphin/ip/IPZero.c create mode 100644 libs/dolphin/lg/allsrc.c create mode 100644 libs/dolphin/mtx/mtx.c create mode 100644 libs/dolphin/mtx/mtx44.c create mode 100644 libs/dolphin/mtx/mtx44vec.c create mode 100644 libs/dolphin/mtx/mtxvec.c create mode 100644 libs/dolphin/mtx/quat.c create mode 100644 libs/dolphin/mtx/vec.c create mode 100644 libs/dolphin/odenotstub/odenotstub.c create mode 100644 libs/dolphin/os/OS.c create mode 100644 libs/dolphin/os/OSAlarm.c create mode 100644 libs/dolphin/os/OSAlloc.c create mode 100644 libs/dolphin/os/OSArena.c create mode 100644 libs/dolphin/os/OSAudioSystem.c create mode 100644 libs/dolphin/os/OSCache.c create mode 100644 libs/dolphin/os/OSContext.c create mode 100644 libs/dolphin/os/OSError.c create mode 100644 libs/dolphin/os/OSFont.c create mode 100644 libs/dolphin/os/OSInterrupt.c create mode 100644 libs/dolphin/os/OSLink.c create mode 100644 libs/dolphin/os/OSMemory.c create mode 100644 libs/dolphin/os/OSMessage.c create mode 100644 libs/dolphin/os/OSMutex.c create mode 100644 libs/dolphin/os/OSReboot.c create mode 100644 libs/dolphin/os/OSReset.c create mode 100644 libs/dolphin/os/OSResetSW.c create mode 100644 libs/dolphin/os/OSRtc.c create mode 100644 libs/dolphin/os/OSSync.c create mode 100644 libs/dolphin/os/OSThread.c create mode 100644 libs/dolphin/os/OSTime.c create mode 100644 libs/dolphin/os/init/__ppc_eabi_init.cpp create mode 100644 libs/dolphin/os/init/__start.c create mode 100644 libs/dolphin/pad/Pad.c create mode 100644 libs/dolphin/pad/Padclamp.c create mode 100644 libs/dolphin/si/SIBios.c create mode 100644 libs/dolphin/si/SISamplingRate.c create mode 100644 libs/dolphin/si/SISteering.c create mode 100644 libs/dolphin/si/SISteeringAuto.c create mode 100644 libs/dolphin/si/SISteeringXfer.c create mode 100644 libs/dolphin/thp/THPAudio.c create mode 100644 libs/dolphin/thp/THPDec.c create mode 100644 libs/dolphin/upnp/UPnP.c create mode 100644 libs/dolphin/upnp/UPnPHttp.c create mode 100644 libs/dolphin/upnp/UPnPHttpd.c create mode 100644 libs/dolphin/upnp/UPnPHttpdResponse.c create mode 100644 libs/dolphin/upnp/UPnPSsdp.c create mode 100644 libs/dolphin/upnp/UPnPUri.c create mode 100644 libs/dolphin/upnp/UPnPUuid.c create mode 100644 libs/dolphin/vi/vi.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Export/mslsupp.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/UDP_Stubs.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/targcont.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/target_options.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/usr_put.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/dispatch.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/main_TRK.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mainloop.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mem_TRK.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msg.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mutex_TRK.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/notify.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubevent.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubinit.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/serpoll.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c create mode 100644 libs/runtime_libs/gamedev/cust_connection/cc/exi2/GCN/EXI2_DDH_GCN/main.c create mode 100644 libs/runtime_libs/gamedev/cust_connection/cc/exi2/GCN/EXI2_GDEV_GCN/main.c create mode 100644 libs/runtime_libs/gamedev/cust_connection/utils/common/CircleBuffer.c create mode 100644 libs/runtime_libs/gamedev/cust_connection/utils/common/MWTrace.c create mode 100644 libs/runtime_libs/gamedev/cust_connection/utils/gc/MWCriticalSection_gc.cpp diff --git a/config/GQPE78/splits.txt b/config/GQPE78/splits.txt index dfd29e29f..4f8b6fd67 100644 --- a/config/GQPE78/splits.txt +++ b/config/GQPE78/splits.txt @@ -2468,206 +2468,206 @@ bink/src/sdk/dct.c: bink/src/sdk/bitplane.c: .text start:0x801B1F24 end:0x801B5350 -dolphin/ai/src/ai.c: +dolphin/ai/ai.c: .text start:0x801B5350 end:0x801B5C34 .data start:0x802B03C0 end:0x802B0408 .sdata start:0x803CAE48 end:0x803CAE50 .sbss start:0x803CC220 end:0x803CC260 -dolphin/amcstubs/src/AmcExi2Stubs.c: +dolphin/amcstubs/AmcExi2Stubs.c: .text start:0x801B5C34 end:0x801B5C64 -dolphin/ar/src/ar.c: +dolphin/ar/ar.c: .text start:0x801B5C64 end:0x801B77A4 .data start:0x802B0408 end:0x802B0450 .sdata start:0x803CAE50 end:0x803CAE58 .sbss start:0x803CC260 end:0x803CC280 -dolphin/ar/src/arq.c: +dolphin/ar/arq.c: .text start:0x801B77A4 end:0x801B7C60 .data start:0x802B0450 end:0x802B0498 .sdata start:0x803CAE58 end:0x803CAE60 .sbss start:0x803CC280 end:0x803CC2B0 -dolphin/ax/src/AX.c: +dolphin/ax/AX.c: .text start:0x801B7C60 end:0x801B7D04 .data start:0x802B0498 end:0x802B04E0 .sdata start:0x803CAE60 end:0x803CAE68 -dolphin/ax/src/AXAlloc.c: +dolphin/ax/AXAlloc.c: .text start:0x801B7D04 end:0x801B81CC .bss start:0x80363D88 end:0x80363EA0 .sbss start:0x803CC2B0 end:0x803CC2B8 -dolphin/ax/src/AXAux.c: +dolphin/ax/AXAux.c: .text start:0x801B81CC end:0x801B8654 .bss start:0x80363EA0 end:0x80366BA0 .sbss start:0x803CC2B8 end:0x803CC2F0 -dolphin/ax/src/AXCL.c: +dolphin/ax/AXCL.c: .text start:0x801B8654 end:0x801B8D70 .bss start:0x80366BA0 end:0x803671A0 .sbss start:0x803CC2F0 end:0x803CC308 -dolphin/ax/src/AXOut.c: +dolphin/ax/AXOut.c: .text start:0x801B8D70 end:0x801B9540 .bss start:0x803671A0 end:0x8036BC40 .sbss start:0x803CC308 end:0x803CC340 -dolphin/ax/src/AXSPB.c: +dolphin/ax/AXSPB.c: .text start:0x801B9540 end:0x801B9A08 .bss start:0x8036BC40 end:0x8036BC80 .sbss start:0x803CC340 end:0x803CC368 -dolphin/ax/src/AXVPB.c: +dolphin/ax/AXVPB.c: .text start:0x801B9A08 end:0x801BAC28 .data start:0x802B04E0 end:0x802B05C0 .bss start:0x8036BC80 end:0x8037D480 .sbss start:0x803CC368 end:0x803CC378 .sdata2 start:0x803CFC70 end:0x803CFC78 -dolphin/ax/src/AXComp.c: +dolphin/ax/AXComp.c: .data start:0x802B05C0 end:0x802B2000 -dolphin/ax/src/DSPCode.c: +dolphin/ax/DSPCode.c: .data start:0x802B2000 end:0x802B3EC0 .sdata start:0x803CAE68 end:0x803CAE70 -dolphin/ax/src/AXProf.c: +dolphin/ax/AXProf.c: .text start:0x801BAC28 end:0x801BAC70 .sbss start:0x803CC378 end:0x803CC388 -dolphin/base/src/PPCArch.c: +dolphin/base/PPCArch.c: .text start:0x801BAC70 end:0x801BAD84 -dolphin/card/src/CARDBios.c: +dolphin/card/CARDBios.c: .text start:0x801BAD84 end:0x801BC174 .data start:0x802B3EC0 end:0x802B3F20 .bss start:0x8037D480 end:0x8037D6C0 .sdata start:0x803CAE70 end:0x803CAE78 .sbss start:0x803CC388 end:0x803CC390 -dolphin/card/src/CARDUnlock.c: +dolphin/card/CARDUnlock.c: .text start:0x801BC174 end:0x801BD3D4 .data start:0x802B3F20 end:0x802B4080 .sdata start:0x803CAE78 end:0x803CAE80 -dolphin/card/src/CARDRdwr.c: +dolphin/card/CARDRdwr.c: .text start:0x801BD3D4 end:0x801BD66C -dolphin/card/src/CARDBlock.c: +dolphin/card/CARDBlock.c: .text start:0x801BD66C end:0x801BDA70 -dolphin/card/src/CARDDir.c: +dolphin/card/CARDDir.c: .text start:0x801BDA70 end:0x801BDCD4 -dolphin/card/src/CARDCheck.c: +dolphin/card/CARDCheck.c: .text start:0x801BDCD4 end:0x801BEC98 -dolphin/card/src/CARDMount.c: +dolphin/card/CARDMount.c: .text start:0x801BEC98 end:0x801BF758 .data start:0x802B4080 end:0x802B40C0 -dolphin/card/src/CARDFormat.c: +dolphin/card/CARDFormat.c: .text start:0x801BF758 end:0x801BFF90 -dolphin/card/src/CARDOpen.c: +dolphin/card/CARDOpen.c: .text start:0x801BFF90 end:0x801C0680 -dolphin/card/src/CARDCreate.c: +dolphin/card/CARDCreate.c: .text start:0x801C0680 end:0x801C0A18 -dolphin/card/src/CARDRead.c: +dolphin/card/CARDRead.c: .text start:0x801C0A18 end:0x801C0E8C -dolphin/card/src/CARDWrite.c: +dolphin/card/CARDWrite.c: .text start:0x801C0E8C end:0x801C11C0 -dolphin/card/src/CARDDelete.c: +dolphin/card/CARDDelete.c: .text start:0x801C11C0 end:0x801C13BC -dolphin/card/src/CARDStat.c: +dolphin/card/CARDStat.c: .text start:0x801C13BC end:0x801C1884 -dolphin/card/src/CARDStatEx.c: +dolphin/card/CARDStatEx.c: .text start:0x801C1884 end:0x801C1BC4 -dolphin/card/src/CARDNet.c: +dolphin/card/CARDNet.c: .text start:0x801C1BC4 end:0x801C1CF0 .sdata start:0x803CAE80 end:0x803CAE88 -dolphin/db/src/db.c: +dolphin/db/db.c: .text start:0x801C1CF0 end:0x801C1DDC .data start:0x802B40C0 end:0x802B40D8 .sbss start:0x803CC390 end:0x803CC398 -dolphin/dsp/src/dsp.c: +dolphin/dsp/dsp.c: .text start:0x801C1DDC end:0x801C206C .data start:0x802B40D8 end:0x802B4158 .sdata start:0x803CAE88 end:0x803CAE90 .sbss start:0x803CC398 end:0x803CC3A0 -dolphin/dsp/src/dsp_debug.c: +dolphin/dsp/dsp_debug.c: .text start:0x801C206C end:0x801C20BC -dolphin/dsp/src/dsp_task.c: +dolphin/dsp/dsp_task.c: .text start:0x801C20BC end:0x801C2940 .data start:0x802B4158 end:0x802B4298 .sbss start:0x803CC3A0 end:0x803CC3B8 -dolphin/dvd/src/dvdlow.c: +dolphin/dvd/dvdlow.c: .text start:0x801C2940 end:0x801C3784 .bss start:0x8037D6C0 end:0x8037D7A0 .sdata start:0x803CAE90 end:0x803CAE98 .sbss start:0x803CC3B8 end:0x803CC400 -dolphin/dvd/src/dvdfs.c: +dolphin/dvd/dvdfs.c: .text start:0x801C3784 end:0x801C4128 .data start:0x802B4298 end:0x802B4428 .sdata start:0x803CAE98 end:0x803CAEA0 .sbss start:0x803CC400 end:0x803CC420 -dolphin/dvd/src/dvd.c: +dolphin/dvd/dvd.c: .text start:0x801C4128 end:0x801C6B40 .data start:0x802B4428 end:0x802B45A8 .bss start:0x8037D7A0 end:0x8037D838 .sdata start:0x803CAEA0 end:0x803CAEB8 .sbss start:0x803CC420 end:0x803CC470 -dolphin/dvd/src/dvdqueue.c: +dolphin/dvd/dvdqueue.c: .text start:0x801C6B40 end:0x801C6D38 .bss start:0x8037D838 end:0x8037D858 -dolphin/dvd/src/dvderror.c: +dolphin/dvd/dvderror.c: .text start:0x801C6D38 end:0x801C6ED0 .data start:0x802B45A8 end:0x802B45F0 -dolphin/dvd/src/dvdidutils.c: +dolphin/dvd/dvdidutils.c: .text start:0x801C6ED0 end:0x801C6FC8 -dolphin/dvd/src/dvdFatal.c: +dolphin/dvd/dvdFatal.c: .text start:0x801C6FC8 end:0x801C6FF8 .sbss start:0x803CC470 end:0x803CC478 -dolphin/dvd/src/emu_level2/fstload.c: +dolphin/dvd/emu_level2/fstload.c: .text start:0x801C6FF8 end:0x801C7238 .data start:0x802B45F0 end:0x802B4660 .bss start:0x8037D858 end:0x8037D8C8 .sdata start:0x803CAEB8 end:0x803CAEC8 .sbss start:0x803CC478 end:0x803CC488 -dolphin/exi/src/EXIBios.c: +dolphin/exi/EXIBios.c: .text start:0x801C7238 end:0x801C8C14 .data start:0x802B4660 end:0x802B4780 .bss start:0x8037D8C8 end:0x8037D988 .sdata start:0x803CAEC8 end:0x803CAED0 .sbss start:0x803CC488 end:0x803CC490 -dolphin/exi/src/EXIUart.c: +dolphin/exi/EXIUart.c: .text start:0x801C8C14 end:0x801C91E8 .sbss start:0x803CC490 end:0x803CC4A0 -dolphin/gx/src/GXInit.c: +dolphin/gx/GXInit.c: .text start:0x801C91E8 end:0x801CA560 .data start:0x802B4780 end:0x802B49C0 .bss start:0x8037D988 end:0x8037DFC0 @@ -2675,450 +2675,450 @@ dolphin/gx/src/GXInit.c: .sbss start:0x803CC4A0 end:0x803CC4C8 .sdata2 start:0x803CFC78 end:0x803CFCA0 -dolphin/gx/src/GXFifo.c: +dolphin/gx/GXFifo.c: .text start:0x801CA560 end:0x801CAD5C .sbss start:0x803CC4C8 end:0x803CC4E8 -dolphin/gx/src/GXAttr.c: +dolphin/gx/GXAttr.c: .text start:0x801CAD5C end:0x801CBAB0 .data start:0x802B49C0 end:0x802B4B20 .sdata start:0x803CAED8 end:0x803CAEE8 -dolphin/gx/src/GXMisc.c: +dolphin/gx/GXMisc.c: .text start:0x801CBAB0 end:0x801CC198 .sbss start:0x803CC4E8 end:0x803CC500 -dolphin/gx/src/GXGeometry.c: +dolphin/gx/GXGeometry.c: .text start:0x801CC198 end:0x801CC518 -dolphin/gx/src/GXFrameBuf.c: +dolphin/gx/GXFrameBuf.c: .text start:0x801CC518 end:0x801CD0B4 .data start:0x802B4B20 end:0x802B4C10 .sdata2 start:0x803CFCA0 end:0x803CFCB0 -dolphin/gx/src/GXLight.c: +dolphin/gx/GXLight.c: .text start:0x801CD0B4 end:0x801CD6C8 .data start:0x802B4C10 end:0x802B4C30 .sdata2 start:0x803CFCB0 end:0x803CFCE0 -dolphin/gx/src/GXTexture.c: +dolphin/gx/GXTexture.c: .text start:0x801CD6C8 end:0x801CE8CC .data start:0x802B4C30 end:0x802B4E58 .sdata start:0x803CAEE8 end:0x803CAF28 .sdata2 start:0x803CFCE0 end:0x803CFD18 -dolphin/gx/src/GXBump.c: +dolphin/gx/GXBump.c: .text start:0x801CE8CC end:0x801CED74 .sdata2 start:0x803CFD18 end:0x803CFD20 -dolphin/gx/src/GXTev.c: +dolphin/gx/GXTev.c: .text start:0x801CED74 end:0x801CF4D8 .data start:0x802B4E58 end:0x802B4ED0 -dolphin/gx/src/GXPixel.c: +dolphin/gx/GXPixel.c: .text start:0x801CF4D8 end:0x801CFB20 .data start:0x802B4ED0 end:0x802B4EF0 .sdata2 start:0x803CFD20 end:0x803CFD58 -dolphin/gx/src/GXDisplayList.c: +dolphin/gx/GXDisplayList.c: .text start:0x801CFB20 end:0x801CFB90 -dolphin/gx/src/GXTransform.c: +dolphin/gx/GXTransform.c: .text start:0x801CFB90 end:0x801D0124 .sdata2 start:0x803CFD58 end:0x803CFD68 -dolphin/gx/src/GXPerf.c: +dolphin/gx/GXPerf.c: .text start:0x801D0124 end:0x801D097C .data start:0x802B4EF0 end:0x802B4FE0 -dolphin/mtx/src/mtx.c: +dolphin/mtx/mtx.c: .text start:0x801D097C end:0x801D0A9C .sdata start:0x803CAF28 end:0x803CAF30 .sdata2 start:0x803CFD68 end:0x803CFD70 -dolphin/mtx/src/mtx44.c: +dolphin/mtx/mtx44.c: .text start:0x801D0A9C end:0x801D0B34 .sdata2 start:0x803CFD70 end:0x803CFD80 -dolphin/odenotstub/src/odenotstub.c: +dolphin/odenotstub/odenotstub.c: .text start:0x801D0B34 end:0x801D0B3C -dolphin/os/src/OS.c: +dolphin/os/OS.c: .text start:0x801D0B3C end:0x801D1628 .data start:0x802B4FE0 end:0x802B51D8 .bss start:0x8037DFC0 end:0x8037E010 .sdata start:0x803CAF30 end:0x803CAF40 .sbss start:0x803CC500 end:0x803CC540 -dolphin/os/src/OSAlarm.c: +dolphin/os/OSAlarm.c: .text start:0x801D1628 end:0x801D1D54 .sbss start:0x803CC540 end:0x803CC548 -dolphin/os/src/OSAlloc.c: +dolphin/os/OSAlloc.c: .text start:0x801D1D54 end:0x801D2064 .sdata start:0x803CAF40 end:0x803CAF48 .sbss start:0x803CC548 end:0x803CC558 -dolphin/os/src/OSArena.c: +dolphin/os/OSArena.c: .text start:0x801D2064 end:0x801D2084 .sdata start:0x803CAF48 end:0x803CAF50 .sbss start:0x803CC558 end:0x803CC560 -dolphin/os/src/OSAudioSystem.c: +dolphin/os/OSAudioSystem.c: .text start:0x801D2084 end:0x801D2318 .data start:0x802B51D8 end:0x802B5258 -dolphin/os/src/OSCache.c: +dolphin/os/OSCache.c: .text start:0x801D2318 end:0x801D2750 .data start:0x802B5258 end:0x802B5488 -dolphin/os/src/OSContext.c: +dolphin/os/OSContext.c: .text start:0x801D2750 end:0x801D2F04 .data start:0x802B5488 end:0x802B5660 -dolphin/os/src/OSError.c: +dolphin/os/OSError.c: .text start:0x801D2F04 end:0x801D35B0 .data start:0x802B5660 end:0x802B5980 .bss start:0x8037E010 end:0x8037E060 .sdata start:0x803CAF50 end:0x803CAF58 -dolphin/os/src/OSFont.c: +dolphin/os/OSFont.c: .text start:0x801D35B0 end:0x801D4310 .data start:0x802B5980 end:0x802B6490 .sdata start:0x803CAF58 end:0x803CAF60 .sbss start:0x803CC560 end:0x803CC570 .sdata2 start:0x803CFD80 end:0x803CFD88 -dolphin/os/src/OSInterrupt.c: +dolphin/os/OSInterrupt.c: .text start:0x801D4310 end:0x801D4B7C .data start:0x802B6490 end:0x802B64C0 .sbss start:0x803CC570 end:0x803CC588 -dolphin/os/src/OSLink.c: +dolphin/os/OSLink.c: .text start:0x801D4B7C end:0x801D4B94 -dolphin/os/src/OSMemory.c: +dolphin/os/OSMemory.c: .text start:0x801D4B94 end:0x801D4E6C .data start:0x802B64C0 end:0x802B64D0 -dolphin/os/src/OSMutex.c: +dolphin/os/OSMutex.c: .text start:0x801D4E6C end:0x801D4EDC -dolphin/os/src/OSReboot.c: +dolphin/os/OSReboot.c: .text start:0x801D4EDC end:0x801D5238 .bss start:0x8037E060 end:0x8037E080 .sbss start:0x803CC588 end:0x803CC598 -dolphin/os/src/OSReset.c: +dolphin/os/OSReset.c: .text start:0x801D5238 end:0x801D565C .sbss start:0x803CC598 end:0x803CC5A8 -dolphin/os/src/OSResetSW.c: +dolphin/os/OSResetSW.c: .text start:0x801D565C end:0x801D59E8 .sbss start:0x803CC5A8 end:0x803CC5C8 -dolphin/os/src/OSRtc.c: +dolphin/os/OSRtc.c: .text start:0x801D59E8 end:0x801D6588 .bss start:0x8037E080 end:0x8037E0D8 -dolphin/os/src/OSSync.c: +dolphin/os/OSSync.c: .text start:0x801D6588 end:0x801D660C -dolphin/os/src/OSThread.c: +dolphin/os/OSThread.c: .text start:0x801D660C end:0x801D754C .bss start:0x8037E0D8 end:0x8037EAD0 .sdata start:0x803CAF60 end:0x803CAF68 .sbss start:0x803CC5C8 end:0x803CC5D8 -dolphin/os/src/OSTime.c: +dolphin/os/OSTime.c: .text start:0x801D754C end:0x801D79C8 .data start:0x802B64D0 end:0x802B6530 -dolphin/os/src/init/__start.c: +dolphin/os/init/__start.c: .init start:0x80003100 end:0x80003400 .text start:0x801D79C8 end:0x801D79CC .sbss start:0x803CC5D8 end:0x803CC5E0 -dolphin/os/src/init/__ppc_eabi_init.cpp: +dolphin/os/init/__ppc_eabi_init.cpp: .init start:0x80003400 end:0x80003458 .text start:0x801D79CC end:0x801D7A60 -dolphin/pad/src/Padclamp.c: +dolphin/pad/Padclamp.c: .text start:0x801D7A60 end:0x801D7CA4 .rodata start:0x80279920 end:0x80279930 -dolphin/pad/src/Pad.c: +dolphin/pad/Pad.c: .text start:0x801D7CA4 end:0x801D9774 .data start:0x802B6530 end:0x802B6588 .bss start:0x8037EAD0 end:0x8037EB20 .sdata start:0x803CAF68 end:0x803CAF88 .sbss start:0x803CC5E0 end:0x803CC608 -dolphin/si/src/SIBios.c: +dolphin/si/SIBios.c: .text start:0x801D9774 end:0x801DAE64 .data start:0x802B6588 end:0x802B66A0 .bss start:0x8037EB20 end:0x8037ED20 .sdata start:0x803CAF88 end:0x803CAF90 .sbss start:0x803CC608 end:0x803CC618 -dolphin/si/src/SISamplingRate.c: +dolphin/si/SISamplingRate.c: .text start:0x801DAE64 end:0x801DAF6C .data start:0x802B66A0 end:0x802B6738 .sbss start:0x803CC618 end:0x803CC620 -dolphin/vi/src/vi.c: +dolphin/vi/vi.c: .text start:0x801DAF6C end:0x801DCD7C .data start:0x802B6738 end:0x802B6B08 .bss start:0x8037ED20 end:0x8037EE68 .sdata start:0x803CAF90 end:0x803CAFA0 .sbss start:0x803CC620 end:0x803CC680 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/abort_exit.c: +MSL_C/PPC_EABI/abort_exit.c: .text start:0x801DCD7C end:0x801DCF08 .bss start:0x8037EE68 end:0x8037EF68 .sbss start:0x803CC680 end:0x803CC690 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/alloc.c: +MSL_C/MSL_Common/alloc.c: .text start:0x801DCF08 end:0x801DE534 .rodata start:0x80279930 end:0x80279948 .bss start:0x8037EF68 end:0x8037EFA0 .sbss start:0x803CC690 end:0x803CC698 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/errno.c: +MSL_C/MSL_Common/errno.c: .sbss start:0x803CC698 end:0x803CC6A0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/ansi_files.c: +MSL_C/MSL_Common/ansi_files.c: .text start:0x801DE534 end:0x801DE844 .data start:0x802B6B08 end:0x802B6C48 .bss start:0x8037EFA0 end:0x8037F2A0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Src/ansi_fp.c: +MSL_C/MSL_Common_Embedded/ansi_fp.c: .text start:0x801DE844 end:0x801E1E20 .rodata start:0x80279948 end:0x80279A28 .data start:0x802B6C48 end:0x802B6DB0 .sdata2 start:0x803CFD88 end:0x803CFDB8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/arith.c: +MSL_C/MSL_Common/arith.c: .text start:0x801E1E20 end:0x801E1E30 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/buffer_io.c: +MSL_C/MSL_Common/buffer_io.c: .text start:0x801E1E30 end:0x801E215C PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/char_io.c: .text start:0x801E215C end:0x801E25FC -PowerPC_EABI_Support/MSL/MSL_C/PPC_EABI/SRC/critical_regions.gamecube.c: +MSL_C/PPC_EABI/critical_regions.gamecube.c: .text start:0x801E25FC end:0x801E2608 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/ctype.c: +MSL_C/MSL_Common/ctype.c: .text start:0x801E2608 end:0x801E2644 .data start:0x802B6DB0 end:0x802B70B0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/locale.c: +MSL_C/MSL_Common/locale.c: .rodata start:0x80279A28 end:0x80279A30 .data start:0x802B70B0 end:0x802B70E8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/direct_io.c: +MSL_C/MSL_Common/direct_io.c: .text start:0x801E2644 end:0x801E2D98 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/file_io.c: +MSL_C/MSL_Common/file_io.c: .text start:0x801E2D98 end:0x801E3458 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/FILE_POS.C: +MSL_C/MSL_Common/FILE_POS.C: .text start:0x801E3458 end:0x801E37A8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mbstring.c: +MSL_C/MSL_Common/mbstring.c: .text start:0x801E37A8 end:0x801E3ACC .sdata2 start:0x803CFDB8 end:0x803CFDC0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mem.c: +MSL_C/MSL_Common/mem.c: .text start:0x801E3ACC end:0x801E3C3C -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mem_funcs.c: +MSL_C/MSL_Common/mem_funcs.c: .text start:0x801E3C3C end:0x801E3F0C -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/misc_io.c: +MSL_C/MSL_Common/misc_io.c: .text start:0x801E3F0C end:0x801E3F34 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/printf.c: +MSL_C/MSL_Common/printf.c: .text start:0x801E3F34 end:0x801E6074 .rodata start:0x80279A30 end:0x80279A58 .data start:0x802B70E8 end:0x802B7318 .sdata start:0x803CAFA0 end:0x803CAFA8 .sdata2 start:0x803CFDC0 end:0x803CFDC8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/qsort.c: +MSL_C/MSL_Common/qsort.c: .text start:0x801E6074 end:0x801E61E0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/rand.c: +MSL_C/MSL_Common/rand.c: .text start:0x801E61E0 end:0x801E6200 .sdata start:0x803CAFA8 end:0x803CAFB0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/scanf.c: +MSL_C/MSL_Common/scanf.c: .text start:0x801E6200 end:0x801E7248 .rodata start:0x80279A58 end:0x80279A80 .data start:0x802B7318 end:0x802B73E8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/signal.c: +MSL_C/MSL_Common/signal.c: .text start:0x801E7248 end:0x801E7308 .bss start:0x8037F2A0 end:0x8037F2B8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/string.c: +MSL_C/MSL_Common/string.c: .text start:0x801E7308 end:0x801E77D4 .rodata start:0x80279A80 end:0x80279E10 .sdata start:0x803CAFB0 end:0x803CAFB8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/float.c: +MSL_C/MSL_Common/float.c: .sdata start:0x803CAFB8 end:0x803CAFE8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/strtold.c: +MSL_C/MSL_Common/strtold.c: .text start:0x801E77D4 end:0x801E886C .rodata start:0x80279E10 end:0x80279E48 .sdata2 start:0x803CFDC8 end:0x803CFDE0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/strtoul.c: +MSL_C/MSL_Common/strtoul.c: .text start:0x801E886C end:0x801E90B0 .data start:0x802B73E8 end:0x802B7470 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Src/uart_console_io.c: +MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c: .text start:0x801E90B0 end:0x801E917C .sbss start:0x803CC6A0 end:0x803CC6A8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/wchar_io.c: +MSL_C/MSL_Common/wchar_io.c: .text start:0x801E917C end:0x801E9204 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c: .text start:0x801E9204 end:0x801E9514 .sdata2 start:0x803CFDE0 end:0x803CFE70 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c: .text start:0x801E9514 end:0x801E9778 .sdata2 start:0x803CFE70 end:0x803CFF08 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c: .text start:0x801E9778 end:0x801E9A08 .sdata2 start:0x803CFF08 end:0x803CFF60 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c: .text start:0x801E9A08 end:0x801E9C2C .rodata start:0x80279E48 end:0x80279E78 .sdata2 start:0x803CFF60 end:0x803CFFD8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c: .text start:0x801E9C2C end:0x801E9F68 .rodata start:0x80279E78 end:0x80279E88 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c: .text start:0x801E9F68 end:0x801EA1E4 .sbss start:0x803CC6A8 end:0x803CC6B0 .sdata2 start:0x803CFFD8 end:0x803D0058 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c: .text start:0x801EA1E4 end:0x801EAA98 .rodata start:0x80279E88 end:0x80279EB8 .sdata2 start:0x803D0058 end:0x803D0168 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c: .text start:0x801EAA98 end:0x801EAE38 .rodata start:0x80279EB8 end:0x8027A040 .sdata2 start:0x803D0168 end:0x803D01C0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c: .text start:0x801EAE38 end:0x801EAF2C .sdata2 start:0x803D01C0 end:0x803D0208 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c: .text start:0x801EAF2C end:0x801EBD80 .rodata start:0x8027A040 end:0x8027A090 .sdata2 start:0x803D0208 end:0x803D0248 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c: .text start:0x801EBD80 end:0x801EBE20 .sdata2 start:0x803D0248 end:0x803D0280 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c: .text start:0x801EBE20 end:0x801EC034 .rodata start:0x8027A090 end:0x8027A0F8 .sdata2 start:0x803D0280 end:0x803D02B8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c: .text start:0x801EC034 end:0x801EC24C .rodata start:0x8027A0F8 end:0x8027A190 .sdata2 start:0x803D02B8 end:0x803D02E0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c: .text start:0x801EC24C end:0x801EC390 .sdata2 start:0x803D02E0 end:0x803D02F0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c: .text start:0x801EC390 end:0x801EC3B8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c: .text start:0x801EC3B8 end:0x801EC48C .sdata2 start:0x803D02F0 end:0x803D02F8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c: .text start:0x801EC48C end:0x801EC5D4 .sdata2 start:0x803D02F8 end:0x803D0308 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c: .text start:0x801EC5D4 end:0x801EC660 .sdata2 start:0x803D0308 end:0x803D0310 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c: .text start:0x801EC660 end:0x801EC824 .sdata2 start:0x803D0310 end:0x803D0338 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c: .text start:0x801EC824 end:0x801EC920 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c: .text start:0x801EC920 end:0x801EC9F8 .sdata2 start:0x803D0338 end:0x803D0340 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c: .text start:0x801EC9F8 end:0x801ECA70 .sdata2 start:0x803D0340 end:0x803D0348 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_acos.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/w_acos.c: .text start:0x801ECA70 end:0x801ECA90 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c: .text start:0x801ECA90 end:0x801ECAB0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c: .text start:0x801ECAB0 end:0x801ECAD0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c: .text start:0x801ECAD0 end:0x801ECAF0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c: .text start:0x801ECAF0 end:0x801ECB10 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log.c: .text start:0x801ECB10 end:0x801ECB30 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c: .text start:0x801ECB30 end:0x801ECB50 -PowerPC_EABI_Support/MSL/MSL_C/PPC_EABI/SRC/math_ppc.c: +MSL_C/PPC_EABI/math_ppc.c: .text start:0x801ECB50 end:0x801ECC44 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/extras.c: +MSL_C/MSL_Common/extras.c: .text start:0x801ECC44 end:0x801ECD5C -PowerPC_EABI_Support/Runtime/Src/__va_arg.c: +Runtime/__va_arg.c: .text start:0x801ECD5C end:0x801ECE24 -PowerPC_EABI_Support/Runtime/Src/global_destructor_chain.c: +Runtime/global_destructor_chain.c: .text start:0x801ECE24 end:0x801ECE6C .dtors start:0x80251D48 end:0x80251D4C .sbss start:0x803CC6B0 end:0x803CC6B8 -PowerPC_EABI_Support/Runtime/Src/CPlusLibPPC.cp: +Runtime/CPlusLibPPC.cp: .text start:0x801ECE6C end:0x801ECE9C -PowerPC_EABI_Support/Runtime/Src/New.cp: +Runtime/New.cp: extab start:0x800056E0 end:0x80005730 extabindex start:0x80005800 end:0x80005818 .text start:0x801ECE9C end:0x801ECF68 @@ -3126,23 +3126,23 @@ PowerPC_EABI_Support/Runtime/Src/New.cp: .data start:0x802B7470 end:0x802B7480 .sdata start:0x803CAFE8 end:0x803CAFF0 -PowerPC_EABI_Support/Runtime/Src/NMWException.cp: +Runtime/NMWException.cp: extab start:0x80005730 end:0x80005770 extabindex start:0x80005818 end:0x80005860 .text start:0x801ECF68 end:0x801ED3DC .sdata start:0x803CAFF0 end:0x803CAFF8 -PowerPC_EABI_Support/Runtime/Src/runtime.c: +Runtime/runtime.c: .text start:0x801ED3DC end:0x801EDB6C .rodata start:0x8027A1B0 end:0x8027A1C8 -PowerPC_EABI_Support/Runtime/Src/__init_cpp_exceptions.cpp: +Runtime/__init_cpp_exceptions.cpp: .text start:0x801EDB6C end:0x801EDBE8 .ctors start:0x80251D00 end:0x80251D04 .dtors start:0x80251D40 end:0x80251D48 .sdata start:0x803CAFF8 end:0x803CB000 -PowerPC_EABI_Support/Runtime/Src/Gecko_ExceptionPPC.cp: +Runtime/Gecko_ExceptionPPC.cp: extab start:0x80005770 end:0x800057E4 extabindex start:0x80005860 end:0x800058B4 .text start:0x801EDBE8 end:0x801EF020 @@ -3151,108 +3151,108 @@ PowerPC_EABI_Support/Runtime/Src/Gecko_ExceptionPPC.cp: .bss start:0x8037F2B8 end:0x8037F2C8 .sdata start:0x803CB000 end:0x803CB010 -PowerPC_EABI_Support/Runtime/Src/GCN_mem_alloc.c: +Runtime/GCN_mem_alloc.c: .text start:0x801EF020 end:0x801EF190 .rodata start:0x8027A260 end:0x8027A2D8 -TRK_MINNOW_DOLPHIN/Portable/mainloop.c: +debugger/embedded/MetroTRK/Portable/mainloop.c: .text start:0x801EF190 end:0x801EF288 -TRK_MINNOW_DOLPHIN/Portable/nubevent.c: +debugger/embedded/MetroTRK/Portable/nubevent.c: .text start:0x801EF288 end:0x801EF4B0 .bss start:0x8037F2C8 end:0x8037F2F0 -TRK_MINNOW_DOLPHIN/Portable/nubinit.c: +debugger/embedded/MetroTRK/Portable/nubinit.c: .text start:0x801EF4B0 end:0x801EF634 .rodata start:0x8027A2D8 end:0x8027A2F8 .bss start:0x8037F2F0 end:0x8037F2F8 -TRK_MINNOW_DOLPHIN/Portable/msg.c: +debugger/embedded/MetroTRK/Portable/msg.c: .text start:0x801EF634 end:0x801EF810 -TRK_MINNOW_DOLPHIN/Portable/msgbuf.c: +debugger/embedded/MetroTRK/Portable/msgbuf.c: .text start:0x801EF810 end:0x801F03EC .rodata start:0x8027A2F8 end:0x8027A318 .bss start:0x8037F2F8 end:0x80380CA8 -TRK_MINNOW_DOLPHIN/Portable/serpoll.c: +debugger/embedded/MetroTRK/Portable/serpoll.c: .text start:0x801F03EC end:0x801F07B8 .bss start:0x80380CA8 end:0x80380CC0 -TRK_MINNOW_DOLPHIN/Portable/usr_put.c: +debugger/embedded/MetroTRK/Os/dolphin/usr_put.c: .text start:0x801F07B8 end:0x801F0844 -TRK_MINNOW_DOLPHIN/Portable/dispatch.c: +debugger/embedded/MetroTRK/Portable/dispatch.c: .text start:0x801F0844 end:0x801F08E0 .data start:0x802B7568 end:0x802B75F0 .bss start:0x80380CC0 end:0x80380CC8 -TRK_MINNOW_DOLPHIN/Portable/msghndlr.c: +debugger/embedded/MetroTRK/Portable/msghndlr.c: .text start:0x801F08E0 end:0x801F3140 .data start:0x802B75F0 end:0x802B7628 .bss start:0x80380CC8 end:0x80380CD0 -TRK_MINNOW_DOLPHIN/Portable/support.c: +debugger/embedded/MetroTRK/Portable/support.c: .text start:0x801F3140 end:0x801F3A00 -TRK_MINNOW_DOLPHIN/Portable/mutex_TRK.c: +debugger/embedded/MetroTRK/Portable/mutex_TRK.c: .text start:0x801F3A00 end:0x801F3A18 -TRK_MINNOW_DOLPHIN/Portable/notify.c: +debugger/embedded/MetroTRK/Portable/notify.c: .text start:0x801F3A18 end:0x801F3AF0 -TRK_MINNOW_DOLPHIN/ppc/Generic/flush_cache.c: +debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c: .text start:0x801F3AF0 end:0x801F3B28 -PowerPC_EABI_Support/Runtime/Src/__mem.c: +Runtime/__mem.c: .init start:0x80003458 end:0x80003590 -TRK_MINNOW_DOLPHIN/Portable/mem_TRK.c: +debugger/embedded/MetroTRK/Portable/mem_TRK.c: .init start:0x80003590 end:0x800035E4 .text start:0x801F3B28 end:0x801F3BE0 -TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.c: +debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c: .text start:0x801F3BE0 end:0x801F5760 .rodata start:0x8027A318 end:0x8027A3A0 .data start:0x802B7628 end:0x802B7658 .bss start:0x80380CD0 end:0x80381250 -TRK_MINNOW_DOLPHIN/ppc/Export/targsupp.s: comment:0 +debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s: comment:0 .text start:0x801F5760 end:0x801F5780 -TRK_MINNOW_DOLPHIN/ppc/Generic/__exception.s: comment:0 +debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s: comment:0 .init start:0x800035E4 end:0x80005518 -TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk.c: +debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c: .init start:0x80005518 end:0x8000563C .text start:0x801F5780 end:0x801F58D8 .data start:0x802B7658 end:0x802B7698 .bss start:0x80381250 end:0x80381258 -TRK_MINNOW_DOLPHIN/ppc/Generic/mpc_7xx_603e.c: +debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c: .text start:0x801F58D8 end:0x801F5C50 -TRK_MINNOW_DOLPHIN/Portable/main_TRK.c: +debugger/embedded/MetroTRK/Portable/main_TRK.c: .text start:0x801F5C50 end:0x801F5C94 .bss start:0x80381258 end:0x80381260 -TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk_glue.c: +debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c: .text start:0x801F5C94 end:0x801F61A4 .rodata start:0x8027A3A0 end:0x8027A3F0 .data start:0x802B7698 end:0x802B76B8 .bss start:0x80381260 end:0x80383488 -TRK_MINNOW_DOLPHIN/Os/dolphin/targcont.c: +debugger/embedded/MetroTRK/Os/dolphin/targcont.c: .text start:0x801F61A4 end:0x801F61D8 -TRK_MINNOW_DOLPHIN/Os/dolphin/target_options.c: +debugger/embedded/MetroTRK/Os/dolphin/target_options.c: .text start:0x801F61D8 end:0x801F61F4 .bss start:0x80383488 end:0x80383490 -TRK_MINNOW_DOLPHIN/MetroTRK/Export/mslsupp.c: +debugger/embedded/MetroTRK/Export/mslsupp.c: .text start:0x801F61F4 end:0x801F6790 -OdemuExi2/DebuggerDriver.c: +dolphin/OdemuExi2/DebuggerDriver.c: .text start:0x801F6790 end:0x801F7210 .sdata start:0x803CB010 end:0x803CB018 .sbss start:0x803CC6B8 end:0x803CC6D0 diff --git a/configure.py b/configure.py index f3f11d844..9350e48da 100644 --- a/configure.py +++ b/configure.py @@ -159,7 +159,7 @@ "-I include", f"-I build/{config.version}/include", f"--defsym BUILD_VERSION={version_num}", - f"--defsym VERSION_{config.version}", + f"--defsym VERSION_={config.version}", ] config.ldflags = [ "-fp hardware", @@ -200,6 +200,9 @@ "-str reuse", "-multibyte", # For Wii compilers, replace with `-enc SJIS` "-i include", + "-i libs/PowerPC_EABI_Support/include", + "-i include/dolphin", + "-i libs", f"-i build/{config.version}/include", f"-DBUILD_VERSION={version_num}", f"-DVERSION_{config.version}", @@ -222,6 +225,19 @@ "-inline auto", ] +# dolphin library flags +cflags_dolphin = [ + *cflags_base, + "-lang=c", + "-fp fmadd", + "-fp_contract off", + "-char signed", + "-str reuse", + "-common off", + "-O4,p", + #"-requireprotos" +] + # REL flags cflags_rel = [ *cflags_base, @@ -232,6 +248,7 @@ # Game-specific flags cflags_bfbb = [ *cflags_base, + "-lang=C++", "-common on", "-char unsigned", "-str reuse,pool,readonly", @@ -240,8 +257,6 @@ "-inline off", "-gccinc", "-i include/bink", - "-i include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include", - "-i include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include", "-i include/inline", "-i include/rwsdk", "-i src/SB/Core/gc", @@ -257,12 +272,36 @@ def DolphinLib(lib_name: str, objects: List[Object]) -> Dict[str, Any]: return { "lib": lib_name, + "src_dir": "libs", "mw_version": "GC/1.2.5n", - "cflags": cflags_base, + "cflags": cflags_dolphin, "progress_category": "sdk", + "host": True, + "objects": objects, + } + +# Helper function for MSL libraries +def mslLib(lib_name: str, extra_cflags: List[str], objects: List[Object]) -> Dict[str, Any]: + return { + "lib": lib_name, + "src_dir": "libs/PowerPC_EABI_Support/src", + "mw_version": "GC/2.6", + "cflags": cflags_runtime + extra_cflags, + "progress_category": "msl", + "host": True, "objects": objects, } +def trkLib(lib_name: str, objects: List[Object]) -> Dict[str, Any]: + return { + "lib": lib_name, + "src_dir": "libs/runtime_libs", + "mw_version": "GC/2.6", + "cflags": cflags_runtime, + "progress_category": "msl", + "host": True, + "objects": objects, + } # Helper function for RenderWare libraries def RenderWareLib(lib_name: str, objects: List[Object]) -> Dict[str, Any]: @@ -270,7 +309,7 @@ def RenderWareLib(lib_name: str, objects: List[Object]) -> Dict[str, Any]: "lib": lib_name, "mw_version": "GC/1.3.2", "cflags": cflags_base, - "progress_category": "sdk", + "progress_category": "RW", "objects": objects, } @@ -557,296 +596,404 @@ def MatchingFor(*versions): DolphinLib( "ai", [ - Object(NonMatching, "dolphin/ai/src/ai.c"), + Object(Matching, "dolphin/ai/ai.c"), ], ), DolphinLib( "amcstubs", [ - Object(NonMatching, "dolphin/amcstubs/src/AmcExi2Stubs.c"), + Object(Matching, "dolphin/amcstubs/AmcExi2Stubs.c"), ], ), DolphinLib( "ar", [ - Object(NonMatching, "dolphin/ar/src/ar.c"), - Object(NonMatching, "dolphin/ar/src/arq.c"), - ], + Object(NonMatching, "dolphin/ar/ar.c"), + Object(Matching, "dolphin/ar/arq.c") + ] ), DolphinLib( "ax", [ - Object(NonMatching, "dolphin/ax/src/AX.c"), - Object(NonMatching, "dolphin/ax/src/AXAlloc.c"), - Object(NonMatching, "dolphin/ax/src/AXAux.c"), - Object(NonMatching, "dolphin/ax/src/AXCL.c"), - Object(NonMatching, "dolphin/ax/src/AXOut.c"), - Object(NonMatching, "dolphin/ax/src/AXSPB.c"), - Object(NonMatching, "dolphin/ax/src/AXVPB.c"), - Object(NonMatching, "dolphin/ax/src/AXComp.c"), - Object(NonMatching, "dolphin/ax/src/DSPCode.c"), - Object(NonMatching, "dolphin/ax/src/AXProf.c"), + Object(Matching, "dolphin/ax/AX.c"), + Object(NonMatching, "dolphin/ax/AXAlloc.c"), + Object(Matching, "dolphin/ax/AXAux.c"), + Object(NonMatching, "dolphin/ax/AXCL.c"), + Object(NonMatching, "dolphin/ax/AXOut.c"), + Object(NonMatching, "dolphin/ax/AXSPB.c"), + Object(NonMatching, "dolphin/ax/AXVPB.c"), + Object(Matching, "dolphin/ax/AXComp.c"), + Object(NonMatching, "dolphin/ax/DSPCode.c"), + Object(Matching, "dolphin/ax/AXProf.c"), ], ), DolphinLib( "base", [ - Object(NonMatching, "dolphin/base/src/PPCArch.c"), - ], + # Needs a lot of Extended ASM work + # Object(NonMatching, "dolphin/base/PPCArch.c") + ] ), DolphinLib( "card", [ - Object(NonMatching, "dolphin/card/src/CARDBios.c"), - Object(NonMatching, "dolphin/card/src/CARDUnlock.c"), - Object(NonMatching, "dolphin/card/src/CARDRdwr.c"), - Object(NonMatching, "dolphin/card/src/CARDBlock.c"), - Object(NonMatching, "dolphin/card/src/CARDDir.c"), - Object(NonMatching, "dolphin/card/src/CARDCheck.c"), - Object(NonMatching, "dolphin/card/src/CARDMount.c"), - Object(NonMatching, "dolphin/card/src/CARDFormat.c"), - Object(NonMatching, "dolphin/card/src/CARDOpen.c"), - Object(NonMatching, "dolphin/card/src/CARDCreate.c"), - Object(NonMatching, "dolphin/card/src/CARDRead.c"), - Object(NonMatching, "dolphin/card/src/CARDWrite.c"), - Object(NonMatching, "dolphin/card/src/CARDDelete.c"), - Object(NonMatching, "dolphin/card/src/CARDStat.c"), - Object(NonMatching, "dolphin/card/src/CARDStatEx.c"), - Object(NonMatching, "dolphin/card/src/CARDNet.c"), - ], + Object(NonMatching, "dolphin/card/CARDBios.c"), + Object(NonMatching, "dolphin/card/CARDUnlock.c"), + Object(Matching, "dolphin/card/CARDRdwr.c"), + Object(Matching, "dolphin/card/CARDBlock.c"), + Object(Matching, "dolphin/card/CARDDir.c"), + Object(Matching, "dolphin/card/CARDCheck.c"), + Object(Matching, "dolphin/card/CARDMount.c"), + Object(Matching, "dolphin/card/CARDFormat.c"), + Object(Matching, "dolphin/card/CARDOpen.c"), + Object(Matching, "dolphin/card/CARDCreate.c"), + Object(Matching, "dolphin/card/CARDRead.c"), + Object(Matching, "dolphin/card/CARDWrite.c"), + Object(Matching, "dolphin/card/CARDDelete.c"), + Object(Matching, "dolphin/card/CARDStat.c"), + Object(Matching,"dolphin/card/CARDStatEx.c"), + Object(NonMatching, "dolphin/card/CARDNet.c"), + ] ), DolphinLib( "db", [ - Object(NonMatching, "dolphin/db/src/db.c"), - ], + Object(Matching, "dolphin/db/db.c"), + ] ), DolphinLib( "dsp", [ - Object(NonMatching, "dolphin/dsp/src/dsp.c"), - Object(NonMatching, "dolphin/dsp/src/dsp_debug.c"), - Object(NonMatching, "dolphin/dsp/src/dsp_task.c"), - ], + Object(NonMatching, "dolphin/dsp/dsp.c"), + Object(Matching, "dolphin/dsp/dsp_debug.c"), + Object(NonMatching, "dolphin/dsp/dsp_task.c") + ] ), DolphinLib( "dvd", [ - Object(NonMatching, "dolphin/dvd/src/dvdlow.c"), - Object(NonMatching, "dolphin/dvd/src/dvdfs.c"), - Object(NonMatching, "dolphin/dvd/src/dvd.c"), - Object(NonMatching, "dolphin/dvd/src/dvdqueue.c"), - Object(NonMatching, "dolphin/dvd/src/dvderror.c"), - Object(NonMatching, "dolphin/dvd/src/dvdidutils.c"), - Object(NonMatching, "dolphin/dvd/src/dvdFatal.c"), - Object(NonMatching, "dolphin/dvd/src/emu_level2/fstload.c"), + Object(NonMatching, "dolphin/dvd/dvdlow.c"), + Object(NonMatching, "dolphin/dvd/dvdfs.c"), + Object(NonMatching, "dolphin/dvd/dvd.c"), + Object(NonMatching, "dolphin/dvd/dvdqueue.c"), + Object(NonMatching, "dolphin/dvd/dvderror.c"), + Object(Matching, "dolphin/dvd/dvdidutils.c"), + Object(NonMatching, "dolphin/dvd/dvdFatal.c"), + Object(NonMatching, "dolphin/dvd/emu_level2/fstload.c"), ], ), + DolphinLib( + "eth", + [ + Object(Matching, "dolphin/eth/eth.c"), + Object(Matching, "dolphin/eth/ethsec.c"), + Object(Matching, "dolphin/eth/md5.c"), + Object(Matching, "dolphin/eth/base64.c") + ] + ), DolphinLib( "exi", [ - Object(NonMatching, "dolphin/exi/src/EXIBios.c"), - Object(NonMatching, "dolphin/exi/src/EXIUart.c"), - ], + Object(NonMatching, "dolphin/exi/EXIBios.c"), + Object(NonMatching, "dolphin/exi/EXIUart.c") + ] + ), + DolphinLib( + "gd", + [ + Object(NonMatching, "dolphin/gd/GDBase.c"), + Object(NonMatching, "dolphin/gd/GDGeometry.c") + ] ), DolphinLib( "gx", [ - Object(NonMatching, "dolphin/gx/src/GXInit.c"), - Object(NonMatching, "dolphin/gx/src/GXFifo.c"), - Object(NonMatching, "dolphin/gx/src/GXAttr.c"), - Object(NonMatching, "dolphin/gx/src/GXMisc.c"), - Object(NonMatching, "dolphin/gx/src/GXGeometry.c"), - Object(NonMatching, "dolphin/gx/src/GXFrameBuf.c"), - Object(NonMatching, "dolphin/gx/src/GXLight.c"), - Object(NonMatching, "dolphin/gx/src/GXTexture.c"), - Object(NonMatching, "dolphin/gx/src/GXBump.c"), - Object(NonMatching, "dolphin/gx/src/GXTev.c"), - Object(NonMatching, "dolphin/gx/src/GXPixel.c"), - Object(NonMatching, "dolphin/gx/src/GXDisplayList.c"), - Object(NonMatching, "dolphin/gx/src/GXTransform.c"), - Object(NonMatching, "dolphin/gx/src/GXPerf.c"), - ], + Object(NonMatching, "dolphin/gx/GXInit.c"), + Object(NonMatching, "dolphin/gx/GXFifo.c"), + Object(NonMatching, "dolphin/gx/GXAttr.c"), + Object(NonMatching, "dolphin/gx/GXMisc.c"), + Object(NonMatching, "dolphin/gx/GXGeometry.c"), + Object(NonMatching, "dolphin/gx/GXFrameBuf.c"), + Object(NonMatching, "dolphin/gx/GXLight.c"), + Object(NonMatching, "dolphin/gx/GXTexture.c"), + Object(NonMatching, "dolphin/gx/GXBump.c"), + Object(NonMatching, "dolphin/gx/GXTev.c"), + Object(NonMatching, "dolphin/gx/GXPixel.c"), + Object(NonMatching, "dolphin/gx/GXDraw.c"), + Object(NonMatching, "dolphin/gx/GXDisplayList.c"), + Object(NonMatching, "dolphin/gx/GXTransform.c"), + Object(NonMatching, "dolphin/gx/GXPerf.c") + ] + ), + DolphinLib( + "hio", + [ + Object(NonMatching, "dolphin/hio/hio.c") + ] + ), + DolphinLib( + "ip", + [ + Object(NonMatching, "dolphin/ip/IP.c"), + Object(NonMatching, "dolphin/ip/IPArp.c"), + Object(NonMatching, "dolphin/ip/IPIcmp.c"), + Object(NonMatching, "dolphin/ip/IPRoute.c"), + Object(NonMatching, "dolphin/ip/IPUdp.c"), + Object(NonMatching, "dolphin/ip/IPFrag.c"), + Object(NonMatching, "dolphin/ip/IPEther.c"), + Object(NonMatching, "dolphin/ip/IFFifo.c"), + Object(NonMatching, "dolphin/ip/IFRing.c"), + Object(NonMatching, "dolphin/ip/IPTcp.c"), + Object(NonMatching, "dolphin/ip/IPTcpOutput.c"), + Object(NonMatching, "dolphin/ip/IPTcpTimer.c"), + Object(NonMatching, "dolphin/ip/IPTcpUser.c"), + Object(NonMatching, "dolphin/ip/IPTcpTimeWait.c"), + Object(NonMatching, "dolphin/ip/IPDns.c"), + Object(NonMatching, "dolphin/ip/IPDhcp.c"), + Object(NonMatching, "dolphin/ip/IPZero.c"), + Object(NonMatching, "dolphin/ip/IPOpt.c"), + Object(NonMatching, "dolphin/ip/IPSocket.c"), + Object(NonMatching, "dolphin/ip/IPPPP.c"), + Object(NonMatching, "dolphin/ip/IPPPPoE.c"), + Object(NonMatching, "dolphin/ip/IPLcp.c"), + Object(NonMatching, "dolphin/ip/IPIpcp.c"), + Object(NonMatching, "dolphin/ip/IPPap.c"), + Object(NonMatching, "dolphin/ip/IPChap.c"), + Object(NonMatching, "dolphin/ip/IPIgmp.c"), + Object(NonMatching, "dolphin/ip/IPUuid.c") + ] + ), + DolphinLib( + "lg", # unofficial name + [ + Object(NonMatching, "dolphin/lg/allsrc.c") + ] ), DolphinLib( "mtx", [ - Object(NonMatching, "dolphin/mtx/src/mtx.c"), - Object(NonMatching, "dolphin/mtx/src/mtx44.c"), - ], + Object(NonMatching, "dolphin/mtx/mtx.c"), + Object(NonMatching, "dolphin/mtx/mtxvec.c"), + Object(NonMatching, "dolphin/mtx/mtx44.c"), + Object(Matching, "dolphin/mtx/mtx44vec.c"), + Object(Matching, "dolphin/mtx/vec.c"), + Object(NonMatching, "dolphin/mtx/quat.c"), + ] + ), + DolphinLib( + "OdemuExi2", + [ + Object(NonMatching, "dolphin/OdemuExi2/DebuggerDriver.c") + ] ), DolphinLib( "odenotstub", [ - Object(NonMatching, "dolphin/odenotstub/src/odenotstub.c"), - ], + Object(NonMatching, "dolphin/odenotstub/odenotstub.c") + ] ), DolphinLib( "os", [ - Object(NonMatching, "dolphin/os/src/OS.c"), - Object(NonMatching, "dolphin/os/src/OSAlarm.c"), - Object(NonMatching, "dolphin/os/src/OSAlloc.c"), - Object(NonMatching, "dolphin/os/src/OSArena.c"), - Object(NonMatching, "dolphin/os/src/OSAudioSystem.c"), - Object(NonMatching, "dolphin/os/src/OSCache.c"), - Object(NonMatching, "dolphin/os/src/OSContext.c"), - Object(NonMatching, "dolphin/os/src/OSError.c"), - Object(NonMatching, "dolphin/os/src/OSFont.c"), - Object(NonMatching, "dolphin/os/src/OSInterrupt.c"), - Object(NonMatching, "dolphin/os/src/OSLink.c"), - Object(NonMatching, "dolphin/os/src/OSMemory.c"), - Object(NonMatching, "dolphin/os/src/OSMutex.c"), - Object(NonMatching, "dolphin/os/src/OSReboot.c"), - Object(NonMatching, "dolphin/os/src/OSReset.c"), - Object(NonMatching, "dolphin/os/src/OSResetSW.c"), - Object(NonMatching, "dolphin/os/src/OSRtc.c"), - Object(NonMatching, "dolphin/os/src/OSSync.c"), - Object(NonMatching, "dolphin/os/src/OSThread.c"), - Object(NonMatching, "dolphin/os/src/OSTime.c"), - Object(NonMatching, "dolphin/os/src/init/__start.c"), - Object(NonMatching, "dolphin/os/src/init/__ppc_eabi_init.cpp"), - ], + Object(NonMatching, "dolphin/os/OS.c"), + Object(NonMatching, "dolphin/os/OSAlarm.c"), + Object(NonMatching, "dolphin/os/OSAlloc.c"), + Object(NonMatching, "dolphin/os/OSArena.c"), + Object(Matching, "dolphin/os/OSAudioSystem.c"), + Object(NonMatching, "dolphin/os/OSCache.c"), + Object(NonMatching, "dolphin/os/OSContext.c"), + Object(NonMatching, "dolphin/os/OSError.c"), + Object(NonMatching, "dolphin/os/OSFont.c"), + Object(NonMatching, "dolphin/os/OSInterrupt.c"), + Object(NonMatching, "dolphin/os/OSLink.c"), + Object(NonMatching, "dolphin/os/OSMessage.c"), + Object(NonMatching, "dolphin/os/OSMemory.c"), + Object(NonMatching, "dolphin/os/OSMutex.c"), + Object(Matching, "dolphin/os/OSReboot.c"), + Object(NonMatching, "dolphin/os/OSReset.c"), + Object(NonMatching, "dolphin/os/OSResetSW.c"), + Object(NonMatching, "dolphin/os/OSRtc.c"), + Object(NonMatching, "dolphin/os/OSThread.c"), + Object(NonMatching, "dolphin/os/OSTime.c"), + Object(NonMatching, "dolphin/os/OSSync.c"), + Object(NonMatching, "dolphin/os/init/__start.c"), + Object(NonMatching, "dolphin/os/init/__ppc_eabi_init.cpp") + ] ), DolphinLib( "pad", [ - Object(NonMatching, "dolphin/pad/src/Padclamp.c"), - Object(NonMatching, "dolphin/pad/src/Pad.c"), - ], + Object(NonMatching, "dolphin/pad/Padclamp.c"), + Object(NonMatching, "dolphin/pad/Pad.c") + ] ), DolphinLib( "si", [ - Object(NonMatching, "dolphin/si/src/SIBios.c"), - Object(NonMatching, "dolphin/si/src/SISamplingRate.c"), - ], + Object(NonMatching, "dolphin/si/SIBios.c"), + Object(Matching, "dolphin/si/SISamplingRate.c"), + ] + ), + DolphinLib( + "upnp", + [ + Object(NonMatching, "dolphin/upnp/UPnP.c"), + Object(NonMatching, "dolphin/upnp/UPnPHttp.c"), + Object(NonMatching, "dolphin/upnp/UPnPSsdp.c"), + Object(NonMatching, "dolphin/upnp/UPnPUuid.c"), + Object(NonMatching, "dolphin/upnp/UPnPUri.c"), + Object(NonMatching, "dolphin/upnp/UPnPHttpd.c"), + Object(NonMatching, "dolphin/upnp/UPnPHttpdResponse.c") + ] ), DolphinLib( "vi", [ - Object(NonMatching, "dolphin/vi/src/vi.c"), + Object(NonMatching, "dolphin/vi/vi.c"), ], ), - { - "lib": "Runtime.PPCEABI.H", - "mw_version": config.linker_version, - "cflags": cflags_runtime, - "progress_category": "sdk", - "objects": [ - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/__mem.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/abort_exit.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/alloc.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/errno.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/ansi_files.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Src/ansi_fp.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/arith.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/buffer_io.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/char_io.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/PPC_EABI/SRC/critical_regions.gamecube.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/ctype.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/locale.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/direct_io.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/file_io.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/FILE_POS.C"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mbstring.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mem.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mem_funcs.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/misc_io.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/printf.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/qsort.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/rand.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/scanf.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/signal.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/string.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/float.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/strtold.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/strtoul.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Src/uart_console_io.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/wchar_io.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_acos.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/PPC_EABI/SRC/math_ppc.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/extras.c"), - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/__va_arg.c"), - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/global_destructor_chain.c"), - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/CPlusLibPPC.cp"), - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/New.cp"), - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/NMWException.cp"), - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/runtime.c"), - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/__init_cpp_exceptions.cpp"), - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/Gecko_ExceptionPPC.cp"), - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/GCN_mem_alloc.c"), - ], - }, - { - "lib": "TRK_Minnow_Dolphin", - "mw_version": "GC/1.3.2", - "cflags": cflags_runtime, - "progress_category": "sdk", - "objects": [ - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/mainloop.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/nubevent.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/nubinit.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/msg.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/msgbuf.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/serpoll.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/usr_put.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/dispatch.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/msghndlr.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/support.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/mutex_TRK.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/notify.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/ppc/Generic/flush_cache.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/mem_TRK.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/ppc/Export/targsupp.s"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/ppc/Generic/__exception.s"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/ppc/Generic/mpc_7xx_603e.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/main_TRK.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk_glue.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Os/dolphin/targcont.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Os/dolphin/target_options.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/MetroTRK/Export/mslsupp.c"), - ], - }, - { - "lib": "OdemuExi2", - "mw_version": "GC/1.3.2", - "cflags": cflags_runtime, - "progress_category": "sdk", - "objects": [ - Object(NonMatching, "OdemuExi2/DebuggerDriver.c"), - ], - }, + DolphinLib( + "thp", + [ + Object(Matching, "dolphin/thp/THPDec.c"), + Object(Matching, "dolphin/thp/THPAudio.c") + ] + ), + mslLib( + "Runtime.PPCEABI.H", + [], + [ + Object(NonMatching, "Runtime/__mem.c"), + Object(Matching, "Runtime/__va_arg.c"), + Object(NonMatching, "Runtime/global_destructor_chain.c"), + Object(NonMatching, "Runtime/New.cp"), + Object(NonMatching, "Runtime/NMWException.cp"), + Object(NonMatching, "Runtime/CPlusLibPPC.cp"), + Object(NonMatching, "Runtime/ptmf.c"), + #Object(NonMatching, "Runtime/runtime.c"), + Object(NonMatching, "Runtime/__init_cpp_exceptions.cpp"), + Object(NonMatching, "Runtime/Gecko_ExceptionPPC.cp"), + Object(NonMatching, "Runtime/GCN_mem_alloc.c"), + ] + ), + mslLib( + "MSL_C.PPCEABI.H", + ["-str pool", "-opt level=0, peephole, schedule, nospace", "-inline off", "-sym on"], + [ + Object(NonMatching, "MSL_C/PPC_EABI/abort_exit.c"), + Object(NonMatching, "MSL_C/MSL_Common/alloc.c"), + Object(NonMatching, "MSL_C/MSL_Common/ansi_files.c"), + Object(NonMatching, "MSL_C/MSL_Common_Embedded/ansi_fp.c"), + Object(NonMatching, "MSL_C/MSL_Common/arith.c"), + Object(NonMatching, "MSL_C/MSL_Common/bsearch.c"), + Object(NonMatching, "MSL_C/MSL_Common/buffer_io.c"), + Object(NonMatching, "MSL_C/PPC_EABI/critical_regions.gamecube.c"), + Object(NonMatching, "MSL_C/MSL_Common/ctype.c"), + Object(NonMatching, "MSL_C/MSL_Common/direct_io.c"), + Object(Matching, "MSL_C/MSL_Common/errno.c"), + Object(NonMatching, "MSL_C/MSL_Common/file_io.c"), + Object(NonMatching, "MSL_C/MSL_Common/FILE_POS.C"), + Object(NonMatching, "MSL_C/MSL_Common/locale.c"), + Object(NonMatching, "MSL_C/MSL_Common/mbstring.c"), + Object(NonMatching, "MSL_C/MSL_Common/mem.c"), + Object(NonMatching, "MSL_C/MSL_Common/mem_funcs.c"), + Object(NonMatching, "MSL_C/MSL_Common/misc_io.c"), + Object(NonMatching, "MSL_C/MSL_Common/printf.c"), + Object(NonMatching, "MSL_C/MSL_Common/qsort.c"), + Object(NonMatching, "MSL_C/MSL_Common/rand.c"), + Object(NonMatching, "MSL_C/MSL_Common/scanf.c"), + Object(NonMatching, "MSL_C/MSL_Common/signal.c"), + Object(NonMatching, "MSL_C/MSL_Common/string.c"), + Object(NonMatching, "MSL_C/MSL_Common/strtold.c"), + Object(NonMatching, "MSL_C/MSL_Common/strtoul.c"), + Object(NonMatching, "MSL_C/MSL_Common/float.c"), + # Causes cyclic dependency error + # Object(NonMatching, "MSL_C/MSL_Common/char_io.c"), + Object(NonMatching, "MSL_C/MSL_Common/wchar_io.c"), + Object(NonMatching, "MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c") + ] + ), + mslLib( + "fdlibm.PPCEABI.H", + [], + [ + Object(NonMatching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c"), + Object(NonMatching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c"), + Object(NonMatching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c"), + Object(NonMatching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_acos.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c"), + Object(NonMatching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c"), + Object(NonMatching, "MSL_C/PPC_EABI/math_ppc.c"), + ] + ), + trkLib( + "TRK_MINNOW_DOLPHIN", + [ + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/mainloop.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/nubevent.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/nubassrt.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/nubinit.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msg.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msgbuf.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/serpoll.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/dispatch.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msghndlr.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/support.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/mutex_TRK.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/notify.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/main_TRK.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/mem_TRK.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/string_TRK.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s"), + Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s"), + Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/usr_put.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/targcont.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/target_options.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/UDP_Stubs.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Export/mslsupp.c"), + + Object(NonMatching, "gamedev/cust_connection/cc/exi2/GCN/EXI2_DDH_GCN/main.c"), + Object(NonMatching, "gamedev/cust_connection/utils/common/CircleBuffer.c"), + Object(NonMatching, "gamedev/cust_connection/cc/exi2/GCN/EXI2_GDEV_GCN/main.c"), + Object(NonMatching, "gamedev/cust_connection/utils/common/MWTrace.c"), + Object(NonMatching, "gamedev/cust_connection/utils/gc/MWCriticalSection_gc.cpp"), + ] + ), + mslLib( + "MSL_C.PPCEABI.bare.H", + [], + [ + Object(NonMatching, "MSL_C/MSL_Common/extras.c") + ] + ), RenderWareLib( "rpcollis", [ @@ -1047,6 +1194,8 @@ def link_order_callback(module_id: int, objects: List[str]) -> List[str]: config.progress_categories = [ ProgressCategory("game", "Game Code"), ProgressCategory("sdk", "SDK Code"), + ProgressCategory("msl", "MSL"), + ProgressCategory("RW", "Renderware SDK"), ] config.progress_each_module = args.verbose diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cctype b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cctype deleted file mode 100644 index 4e84d98dd..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cctype +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MSL_CLIMITS -#define _MSL_CLIMITS - -#include - -#endif diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/climits b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/climits deleted file mode 100644 index 2a3cdf3e5..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/climits +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MSL_CLIMITS -#define _MSL_CLIMITS - -#include - -#endif diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdarg b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdarg deleted file mode 100644 index 51ecd3f00..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdarg +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _MSL_CSTDDEF -#define _MSL_CSTDDEF - -#include - -#endif - -#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstddef b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstddef deleted file mode 100644 index 64f3ce007..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstddef +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MSL_CSTDDEF -#define _MSL_CSTDDEF - -#include - -#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctime b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctime deleted file mode 100644 index f7b51a432..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctime +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MSL_CTIME -#define _MSL_CTIME - -#include - -#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctype.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctype.h deleted file mode 100644 index 221e2220d..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctype.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _MSL_CTYPE_H -#define _MSL_CTYPE_H - -#ifdef __cplusplus -extern "C" { -#endif - -int isprint(int c); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/limits.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/limits.h deleted file mode 100644 index 530c1ee10..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/limits.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MSL_LIMITS_H -#define _MSL_LIMITS_H - -#define SHRT_MAX 32767 - -#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/math.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/math.h deleted file mode 100644 index f2e4cd41a..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/math.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _MSL_MATH_H -#define _MSL_MATH_H - -#define FP_NAN 1 -#define FP_INFINITE 2 -#define FP_ZERO 3 -#define FP_NORMAL 4 -#define FP_SUBNORMAL 5 - -#define fpclassify(x) \ - ((sizeof(x) == sizeof(float)) ? __fpclassifyf((float)(x)) : __fpclassifyd((double)(x))) - -#define isnormal(x) (fpclassify(x) == FP_NORMAL) -#define isnan(x) (fpclassify(x) == FP_NAN) -#define isinf(x) (fpclassify(x) == FP_INFINITE) -#define isfinite(x) ((fpclassify(x) > FP_INFINITE)) - -#ifdef __cplusplus -extern "C" { -#endif - -int __fpclassifyf(float); -int __fpclassifyd(double); - -double sin(double); -double cos(double); -double tan(double); -double atan2(double, double); -double ceil(double); -double asin(double); -double acos(double); -double exp(double); -double floor(double); -double log(double); -double sqrt(double); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdarg.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdarg.h deleted file mode 100644 index 52d613f5d..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdarg.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MSL_STDARG_H -#define _MSL_STDARG_H - -#include - -#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stddef.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stddef.h deleted file mode 100644 index 934197fdb..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stddef.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MSL_STDDEF_H -#define _MSL_STDDEF_H - -#include - -#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdio.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdio.h deleted file mode 100644 index 5174e1851..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdio.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _MSL_STDIO -#define _MSL_STDIO - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _FILE -{ - U8 pad[0x50]; -} FILE; - -extern FILE __files[4]; - -#define stdin &(__files[0]) -#define stdout &(__files[1]) -#define stderr &(__files[2]) - -int sprintf(char* s, const char* format, ...); -void printf(const char* format, ...); -int fprintf(FILE* stream, const char* format, ...); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h deleted file mode 100644 index 73c45e289..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _MSL_STRING_H -#define _MSL_STRING_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void* memset(void*, int, size_t); -void* memcpy(void*, const void*, size_t); -int memcmp(const void* ptr1, const void* ptr2, size_t num); -size_t strlen(const char*); -char* strcpy(char* dest, const char* source); -char* strncpy(char* dest, const char* source, size_t n); -char* strcat(char* dest, const char* source); -int strcmp(const char* a, const char* b); -int stricmp(const char* a, const char* b); -int strcmpi(const char* a, const char* b); -char* strstr(const char* haystack, const char* needle); -char* strtok(char* str, const char* delimiters); -int atoi(const char* s); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/va_list.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/va_list.h deleted file mode 100644 index 47118e307..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/va_list.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MSL_VA_LIST_H -#define _MSL_VA_LIST_H - -typedef char* va_list; - -#endif \ No newline at end of file diff --git a/include/bink/bink.h b/include/bink/bink.h index 11dc19a72..4762aafac 100644 --- a/include/bink/bink.h +++ b/include/bink/bink.h @@ -1,7 +1,7 @@ #ifndef __BINK_H__ #define __BINK_H__ -#include +#include #define BINKSURFACE8P 0 #define BINKSURFACE24 1 @@ -80,4 +80,3 @@ extern void BinkClose(HBINK bink); #endif #endif - diff --git a/include/dolphin/CARDPriv.h b/include/dolphin/CARDPriv.h new file mode 100644 index 000000000..8b7adeef6 --- /dev/null +++ b/include/dolphin/CARDPriv.h @@ -0,0 +1,139 @@ +#ifndef _DOLPHIN_CARDPRIV +#define _DOLPHIN_CARDPRIV + +#include +#include +#include +#include + +#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 * 1024) + +#define CARD_MAX_MOUNT_STEP (CARD_NUM_SYSTEM_BLOCK + 2) + +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 { + BOOL attached; + s32 result; + u16 size; + u16 pageSize; + s32 sectorSize; + u16 cBlock; + u16 vendorID; + s32 latency; + u8 id[12]; + int mountStep; + int formatStep; + u32 scramble; + DSPTaskInfo task; + void* workArea; + CARDDir* currentDir; + u16* currentFat; + OSThreadQueue threadQueue; + u8 cmd[9]; + s32 cmdlen; + vu32 mode; + int retry; + int repeat; + u32 addr; + void* buffer; + s32 xferred; + u16 freeNo; + u16 startBlock; + CARDFileInfo* fileInfo; + CARDCallback extCallback; + CARDCallback txCallback; + CARDCallback exiCallback; + CARDCallback apiCallback; + CARDCallback xferCallback; + CARDCallback eraseCallback; + CARDCallback unlockCallback; + OSAlarm alarm; + u32 cid; + 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); +void __CARDSyncCallback(s32 channel, s32 result); + +#define CARDIsValidBlockNo(card, iBlock) \ + (CARD_NUM_SYSTEM_BLOCK <= (iBlock) && (iBlock) < (card)->cBlock) +#define __CARDGetDirCheck(dir) ((CARDDirCheck*)&(dir)[CARD_MAX_FILE]) + +CARDDir* __CARDGetDirBlock(CARDControl* card); +u16* __CARDGetFatBlock(CARDControl* card); +s32 __CARDUpdateFatBlock(s32 chan, u16* fat, CARDCallback callback); +void __CARDCheckSum(void* ptr, int length, u16* checkSum, u16* checkSumInv); +u16 __CARDGetFontEncode(); +void __CARDExiHandler(s32 chan, OSContext* context); +void __CARDExtHandler(s32 chan, OSContext* context); +void __CARDUnlockedHandler(s32 chan, OSContext* context); +s32 __CARDAccess(CARDControl* card, CARDDir* ent); +s32 __CARDIsWritable(CARDControl *card, CARDDir *entry); + +#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 __CARDPermMask; + +#ifdef __cplusplus +} +#endif +#endif // _DOLPHIN_CARDPRIV \ No newline at end of file diff --git a/include/dolphin/DVDPriv.h b/include/dolphin/DVDPriv.h new file mode 100644 index 000000000..e65a3d900 --- /dev/null +++ b/include/dolphin/DVDPriv.h @@ -0,0 +1,35 @@ +#ifndef _DOLPHIN_DVDPRIV +#define _DOLPHIN_DVDPRIV + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +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; + +#ifdef __cplusplus +} +#endif // _DOLPHIN_DVDPRIV + +#endif __DVDPRIV_H__ diff --git a/include/dolphin/OSRtcPriv.h b/include/dolphin/OSRtcPriv.h new file mode 100644 index 000000000..464f80323 --- /dev/null +++ b/include/dolphin/OSRtcPriv.h @@ -0,0 +1,38 @@ +#ifndef _DOLPHIN_OSRTCPRIV +#define _DOLPHIN_OSRTCPRIV + +#include + +typedef struct OSSram +{ + u16 checkSum; + u16 checkSumInv; + u32 ead0; + u32 ead1; + u32 counterBias; + s8 displayOffsetH; + u8 ntd; + u8 language; + u8 flags; +} OSSram; + +typedef struct OSSramEx +{ + u8 flashID[2][12]; + u32 wirelessKeyboardID; + u16 wirelessPadID[4]; + u8 dvdErrorCode; + u8 _padding0; + u8 flashIDCheckSum[2]; + u16 gbs; + u8 _padding1[2]; +} OSSramEx; + +OSSram *__OSLockSram(); +OSSramEx *__OSLockSramEx(); +void OSSetWirelessID(s32 chan, u16 id); +u16 OSGetWirelessID(s32 chan); +u16 OSGetGbsMode(); +void OSSetGbsMode(u16 mode); + +#endif // _DOLPHIN_OSRTCPRIV \ No newline at end of file diff --git a/include/dolphin/ai.h b/include/dolphin/ai.h index 84db3343b..af223f153 100644 --- a/include/dolphin/ai.h +++ b/include/dolphin/ai.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_AI_H_ -#define _DOLPHIN_AI_H_ +#ifndef _DOLPHIN_AI +#define _DOLPHIN_AI #include @@ -10,41 +10,35 @@ 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 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); +BOOL AIGetDMAEnableFlag(); +void AIStartDMA(); +void AIStopDMA(); +u32 AIGetDMABytesLeft(); +u32 AIGetDMAStartAddr(); +u32 AIGetDMALength(); +u32 AIGetDSPSampleRate(); +void AISetDSPSampleRate(u32 rate); AISCallback AIRegisterStreamCallback(AISCallback callback); -u32 AIGetStreamSampleCount(void); -void AIResetStreamSampleCount(void); +u32 AIGetStreamSampleCount(); +void AIResetStreamSampleCount(); void AISetStreamTrigger(u32 trigger); -u32 AIGetStreamTrigger(void); +u32 AIGetStreamTrigger(); void AISetStreamPlayState(u32 state); -u32 AIGetStreamPlayState(void); -void AISetDSPSampleRate(u32 rate); -u32 AIGetDSPSampleRate(void); +u32 AIGetStreamPlayState(); void AISetStreamSampleRate(u32 rate); -u32 AIGetStreamSampleRate(void); +u32 AIGetStreamSampleRate(); void AISetStreamVolLeft(u8 vol); -u8 AIGetStreamVolLeft(void); void AISetStreamVolRight(u8 vol); -u8 AIGetStreamVolRight(void); -void AIInit(u8* stack); -void AIReset(void); +u8 AIGetStreamVolLeft(); +u8 AIGetStreamVolRight(); +void AIInit(u8 *stack); +BOOL AICheckInit(); +void AIReset(); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_AI diff --git a/include/dolphin/ar/ar.h b/include/dolphin/ar/ar.h new file mode 100644 index 000000000..287cc3607 --- /dev/null +++ b/include/dolphin/ar/ar.h @@ -0,0 +1,45 @@ +#ifndef _DOLPHIN_AR +#define _DOLPHIN_AR + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define AR_STACK_INDEX_ENTRY_SIZE sizeof(u32) + +#define ARAM_DIR_MRAM_TO_ARAM 0x00 +#define ARAM_DIR_ARAM_TO_MRAM 0x01 + +#define AR_CLEAR_INTERNAL_ALL 0x00 +#define AR_CLEAR_INTERNAL_USER 0x01 +#define AR_CLEAR_EXPANSION 0x02 + +typedef void (*ARCallback)(void); + +ARCallback ARRegisterDMACallback(ARCallback 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 ARGetBaseAddress(void); +BOOL ARCheckInit(void); +void ARReset(void); +u32 ARAlloc(u32 length); +u32 ARFree(u32* length); +u32 ARGetSize(void); +u32 ARGetInternalSize(void); +void ARSetSize(void); +void ARClear(u32 flag); + +void __ARClearInterrupt(void); +u16 __ARGetInterruptStatus(void); + +#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) + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_AR \ No newline at end of file diff --git a/include/dolphin/ar/arq.h b/include/dolphin/ar/arq.h new file mode 100644 index 000000000..3c7d2f167 --- /dev/null +++ b/include/dolphin/ar/arq.h @@ -0,0 +1,51 @@ +#ifndef _DOLPHIN_ARQ +#define _DOLPHIN_ARQ + +#include "dolphin/ar/ar.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define ARQ_DMA_ALIGNMENT 32 +#define ARQ_CHUNK_SIZE_DEFAULT 4096 + +#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 + + typedef void (*ARQCallback)(u32 pointerToARQRequest); + + typedef struct ARQRequest + { + + struct ARQRequest *next; + u32 owner; + u32 type; + u32 priority; + u32 source; + u32 dest; + u32 length; + ARQCallback callback; + + } ARQRequest; + + void ARQInit(void); + void ARQReset(void); + void ARQPostRequest(ARQRequest *task, u32 owner, u32 type, u32 priority, u32 source, u32 dest, + u32 length, ARQCallback callback); + void ARQRemoveRequest(ARQRequest *task); + void ARQRemoveOwnerRequest(u32 owner); + void ARQFlushQueue(void); + void ARQSetChunkSize(u32 size); + u32 ARQGetChunkSize(void); + BOOL ARQCheckInit(void); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_ARQ \ No newline at end of file diff --git a/include/dolphin/base.h b/include/dolphin/base.h new file mode 100644 index 000000000..fc8416e00 --- /dev/null +++ b/include/dolphin/base.h @@ -0,0 +1,13 @@ +#ifndef _DOLPHIN_PUBLIC_BASE_H +#define _DOLPHIN_PUBLIC_BASE_H +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/include/dolphin/base/PPCArch.h b/include/dolphin/base/PPCArch.h index 35f5da9c7..88e48a009 100644 --- a/include/dolphin/base/PPCArch.h +++ b/include/dolphin/base/PPCArch.h @@ -1,542 +1,344 @@ -#ifndef _DOLPHIN_PPCARCH -#define _DOLPHIN_PPCARCH - -#include "dolphin/types.h" +#ifndef _DOLPHIN_PPC_ARCH_H +#define _DOLPHIN_PPC_ARCH_H +#include #ifdef __cplusplus -extern "C" { -#endif - -#define CTR 9 -#define XER 1 -#define LR 8 - -#define UPMC1 937 -#define UPMC2 938 -#define UPMC3 941 -#define UPMC4 942 - -#define USIA 939 - -#define UMMCR0 936 -#define UMMCR1 940 - -#define HID0 1008 -#define HID1 1009 - -#define PVR 287 - -#define IBAT0U 528 -#define IBAT0L 529 -#define IBAT1U 530 -#define IBAT1L 531 -#define IBAT2U 532 -#define IBAT2L 533 -#define IBAT3U 534 -#define IBAT3L 535 - -#define DBAT0U 536 -#define DBAT0L 537 -#define DBAT1U 538 -#define DBAT1L 539 -#define DBAT2U 540 -#define DBAT2L 541 -#define DBAT3U 542 -#define DBAT3L 543 - -#define SDR1 25 - -#define SPRG0 272 -#define SPRG1 273 -#define SPRG2 274 -#define SPRG3 275 - -#define DAR 19 -#define DSISR 18 - -#define SRR0 26 -#define SRR1 27 - -#define EAR 282 - -#define DABR 1013 - -#define TBL 284 -#define TBU 285 - -#define L2CR 1017 - -#define DEC 22 - -#define IABR 1010 - -#define PMC1 953 -#define PMC2 954 -#define PMC3 957 -#define PMC4 958 - -#define SIA 955 - -#define MMCR0 952 -#define MMCR1 956 - -#define THRM1 1020 -#define THRM2 1021 -#define THRM3 1022 - -#define ICTC 1019 - -#define GQR0 912 -#define GQR1 913 -#define GQR2 914 -#define GQR3 915 -#define GQR4 916 -#define GQR5 917 -#define GQR6 918 -#define GQR7 919 - -#define HID2 920 - -#define WPAR 921 - -#define DMA_U 922 -#define DMA_L 923 - -#define MSR_POW 0x00040000 // Power Management -#define MSR_ILE 0x00010000 // Interrupt Little Endian -#define MSR_EE 0x00008000 // external interrupt -#define MSR_PR 0x00004000 // privilege level(should be 0) -#define MSR_FP 0x00002000 // floating point available -#define MSR_ME 0x00001000 // machine check enable -#define MSR_FE0 0x00000800 // floating point exception enable -#define MSR_SE 0x00000400 // single step trace enable -#define MSR_BE 0x00000200 // branch trace enable -#define MSR_FE1 0x00000100 // floating point exception enable -#define MSR_IP 0x00000040 // Exception prefix -#define MSR_IR 0x00000020 // instruction relocate -#define MSR_DR 0x00000010 // data relocate -#define MSR_PM 0x00000004 // Performance monitor marked mode -#define MSR_RI 0x00000002 // Recoverable interrupt -#define MSR_LE 0x00000001 // Little Endian - -#define MSR_POW_BIT 13 // Power Management -#define MSR_ILE_BIT 15 // Interrupt Little Endian -#define MSR_EE_BIT 16 // external interrupt -#define MSR_PR_BIT 17 // privilege level (should be 0) -#define MSR_FP_BIT 18 // floating point available -#define MSR_ME_BIT 19 // machine check enable -#define MSR_FE0_BIT 20 // floating point exception enable -#define MSR_SE_BIT 21 // single step trace enable -#define MSR_BE_BIT 22 // branch trace enable -#define MSR_FE1_BIT 23 // floating point exception enable -#define MSR_IP_BIT 25 // Exception prefix -#define MSR_IR_BIT 26 // instruction relocate -#define MSR_DR_BIT 27 // data relocate -#define MSR_PM_BIT 29 // Performance monitor marked mode -#define MSR_RI_BIT 30 // Recoverable interrupt -#define MSR_LE_BIT 31 // Little Endian - -/*---------------------------------------------------------------------------* - HID0 bits - *---------------------------------------------------------------------------*/ -#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 -#define HID0_ILOCK_BIT 18 // ICache lock -#define HID0_DLOCK_BIT 19 // DCache lock - -#define HID2_LSQE 0x80000000 // L/S quantize enable -#define HID2_WPE 0x40000000 // Write pipe enable -#define HID2_PSE 0x20000000 // Paired single enable -#define HID2_LCE 0x10000000 // Locked cache enable - -#define HID2_DCHERR 0x00800000 // ERROR: dcbz_l cache hit -#define HID2_DNCERR 0x00400000 // ERROR: DMA access to normal cache -#define HID2_DCMERR 0x00200000 // ERROR: DMA cache miss error -#define HID2_DQOERR 0x00100000 // ERROR: DMA queue overflow -#define HID2_DCHEE 0x00080000 // dcbz_l cache hit error enable -#define HID2_DNCEE 0x00040000 // DMA access to normal cache error enable -#define HID2_DCMEE 0x00020000 // DMA cache miss error error enable -#define HID2_DQOEE 0x00010000 // DMA queue overflow error enable - -#define HID2_DMAQL_MASK 0x0F000000 // DMA queue length mask -#define HID2_DMAQL_SHIFT 24 // DMA queue shift - -#define HID2_LSQE_BIT 0 -#define HID2_WPE_BIT 1 -#define HID2_PSE_BIT 2 -#define HID2_LCE_BIT 3 - -#define HID2_DCHERR_BIT 8 -#define HID2_DNCERR_BIT 9 -#define HID2_DCMERR_BIT 10 -#define HID2_DQOERR_BIT 11 -#define HID2_DCHEE_BIT 12 -#define HID2_DNCEE_BIT 13 -#define HID2_DCMEE_BIT 14 -#define HID2_DQOEE_BIT 15 - -#define GQR_LOAD_SCALE_MASK 0x3F000000 // load scale field -#define GQR_LOAD_TYPE_MASK 0x00070000 // load type field -#define GQR_STORE_SCALE_MASK 0x00003F00 // store scale field -#define GQR_STORE_TYPE_MASK 0x00000007 // store type field - -typedef struct -{ - u32 _pad0 :2; - u32 loadScale :6; - u32 _pad1 :5; - u32 loadType :3; - u32 _pad2 :2; - u32 storeScale :6; - u32 _pad3 :5; - u32 storeType :3; -} PPC_GQR_t; - -typedef union -{ - u32 val; - PPC_GQR_t f; -} PPC_GQR_u; - - -#define DMA_U_ADDR_MASK 0xFFFFFFE0 // Start addr in memory -#define DMA_U_LEN_U_MASK 0x0000001F // lines to transfer (U) - -#define DMA_L_LC_ADDR_MASK 0xFFFFFFE0 // Start addr in LC -#define DMA_L_LOAD 0x00000010 // 0 - store, 1 - load -#define DMA_L_STORE 0x00000000 // 0 - store, 1 - load -#define DMA_L_LEN_MASK 0x0000000C // lines to transfer (L) -#define DMA_L_TRIGGER 0x00000002 // 0 - cmd inactive, 1 - cmd rdy -#define DMA_L_FLUSH 0x00000001 // 1 - Flush DMA queue - -typedef struct -{ - u32 memAddr :27; - u32 dmaLenU :5; -} PPC_DMA_U_t; - -typedef union -{ - u32 val; - PPC_DMA_U_t f; -} PPC_DMA_U_u; - - -typedef struct +extern "C" { - u32 lcAddr :27; - u32 dmaLd :1; - u32 dmaLenL :2; - u32 dmaTrigger :1; - u32 dmaFlush :1; -} PPC_DMA_L_t; - - -typedef union -{ - u32 val; - PPC_DMA_L_t f; -} PPC_DMA_L_u; - - -#define WPAR_ADDR 0xFFFFFFE0 // 32byte gather address -#define WPAR_BNE 0x00000001 // Buffer not empty (R) - -#define SRR1_DMA_BIT 0x00200000 -#define SRR1_L2DP_BIT 0x00100000 - -#define L2CR_L2E 0x80000000 // L2 Enable -#define L2CR_L2PE 0x40000000 // L2 data parity generation and checking enable - -#define L2CR_L2SIZ_256K 0x10000000 // L2 size 256K -#define L2CR_L2SIZ_512K 0x20000000 // L2 size 512 -#define L2CR_L2SIZ_1M 0x30000000 // L2 size 1M - -#define L2CR_L2CLK_1_0 0x02000000 // L2 clock ratio 1 -#define L2CR_L2CLK_1_5 0x04000000 // L2 clock ratio 1.5 -#define L2CR_L2CLK_2_0 0x08000000 // L2 clock ratio 2 -#define L2CR_L2CLK_2_5 0x0A000000 // L2 clock ratio 2.5 -#define L2CR_L2CLK_3_0 0x0C000000 // L2 clock ratio 3 - -#define L2CR_RAM_FLOW_THRU_BURST 0x00000000 // L2 RAM type flow-through sync. burst SRAM -#define L2CR_RAM_PIPELINE_BURST 0x01000000 // L2 RAM type pipelined sync. burst SRAM -#define L2CR_RAM_PIPELINE_LATE 0x01800000 // L2 RAM type pipelined sync. late-write SRAM - -#define L2CR_L2DO 0x00400000 // Data only -#define L2CR_L2I 0x00200000 // Global invalidate -#define L2CR_L2CTL 0x00100000 // ZZ enable -#define L2CR_L2WT 0x00080000 // L2 write through -#define L2CR_L2TS 0x00040000 // L2 test support - -#define L2CR_L2OH_0_5 0x00000000 // L2 output hold 0.5 ns -#define L2CR_L2OH_1_0 0x00010000 // L2 output hold 1.0 ns +#endif -#define L2CR_L2SL 0x00008000 // L2 DLL slow -#define L2CR_L2DF 0x00004000 // L2 differential clock -#define L2CR_L2BYP 0x00002000 // L2 DLL bypass -#define L2CR_L2CS 0x00000200 // L2 clock stop -#define L2CR_L2DRO 0x00000100 // L2 DLL rollover checkstop enable -#define L2CR_L2CTR_MASK 0x000000FE // L2 counter value mask -#define L2CR_L2IP 0x00000001 // L2 global invalidate in progress + u32 PPCMfmsr(void); + void PPCMtmsr(u32 val); -#define MMCR0_DIS 0x80000000 // Disables counting unconditionally -#define MMCR0_DP 0x40000000 // Disables counting while in supervisor mode -#define MMCR0_DU 0x20000000 // Disables counting while in user mode -#define MMCR0_DMS 0x10000000 // Disables counting while MSR[PM] is set -#define MMCR0_DMR 0x08000000 // Disables counting while MSR[PM] is zero -#define MMCR0_ENINT 0x04000000 // Enables performance monitor interrupt signaling -#define MMCR0_DISCOUNT 0x02000000 // Disables counting of PMCn when a performance monitor interrupt is signaled or... -#define MMCR0_RTCSELECT_MASK 0x01800000 // 64-bit time base, bit selection enable -#define MMCR0_RTCSELECT_63 0x00000000 // Pick bit 63 to count -#define MMCR0_RTCSELECT_55 0x00800000 // Pick bit 55 to count -#define MMCR0_RTCSELECT_51 0x01000000 // Pick bit 51 to count -#define MMCR0_RTCSELECT_47 0x01800000 // Pick bit 47 to count -#define MMCR0_INTONBITTRANS 0x00400000 // Causes interrupt signaling on bit transition from off to on -#define MMCR0_THRESHOLD_MASK 0x003F0000 // Threshold value -#define MMCR0_THRESHOLD(n) ((n) << 16) // Threshold value (0 - 63) -#define MMCR0_PMC1INTCONTROL 0x00008000 // Enables interrupt signaling due to PMC1 counter overflow -#define MMCR0_PMC2INTCONTROL 0x00004000 // Enables interrupt signaling due to PMC2-PMC4 counter overflow -#define MMCR0_PMCTRIGGER 0x00002000 // Can be used to trigger counting of PMC2-PMC4 after PMC1 has overflowed or... -#define MMCR0_PMC1SELECT_MASK 0x00001FC0 // PMC1 input selector -#define MMCR0_PMC2SELECT_MASK 0x0000003F // PMC2 input selector + u32 PPCMfhid0(void); + void PPCMthid0(u32 val); -#define MMCR1_PMC3SELECT_MASK 0xF8000000 // PMC3 input selector -#define MMCR1_PMC4SELECT_MASK 0x07C00000 // PMC4 input selector + u32 PPCMfl2cr(void); + void PPCMtl2cr(u32 val); -#define PMC1_OV 0x80000000 // Overflow -#define PMC1_COUNTER 0x7FFFFFFF // Counter value -#define PMC2_OV 0x80000000 // Overflow -#define PMC2_COUNTER 0x7FFFFFFF // Counter value -#define PMC3_OV 0x80000000 // Overflow -#define PMC3_COUNTER 0x7FFFFFFF // Counter value -#define PMC4_OV 0x80000000 // Overflow -#define PMC4_COUNTER 0x7FFFFFFF // Counter value + void PPCMtdec(u32 val); -/*---------------------------------------------------------------------------* - PMC1 Events - *---------------------------------------------------------------------------*/ -#define MMCR0_PMC1_HOLD 0x00000000 // Register holds current value -#define MMCR0_PMC1_CYCLE 0x00000040 // Processor cycles -#define MMCR0_PMC1_INSTRUCTION 0x00000080 // # of instructions completed. -#define MMCR0_PMC1_TRANSITION 0x000000C0 // # of transitions for 0 to 1 -#define MMCR0_PMC1_DISPATCHED 0x00000100 // # of instructions dispatched -#define MMCR0_PMC1_EIEIO 0x00000140 // # of eieio instructions completed -#define MMCR0_PMC1_ITLB_CYCLE 0x00000180 // # of cycles spent performing table search op. for the ITLB -#define MMCR0_PMC1_L2_HIT 0x000001C0 // # of access that hit the L2. -#define MMCR0_PMC1_EA 0x00000200 // # of valid instruction EAs delivered to the memory subsystem -#define MMCR0_PMC1_IABR 0x00000240 // # of time the address of an instruction matches the IABR -#define MMCR0_PMC1_L1_MISS 0x00000280 // # of loads that miss the L1 -#define MMCR0_PMC1_Bx_UNRESOLVED 0x000002C0 // # of branches that are unresolved when processed -#define MMCR0_PMC1_Bx_STALL_CYCLE 0x00000300 // # of cycles that dispatcher stalls due to a second - // unresolved branch in the instruction stream -#define MMCR0_PMC1_IC_FETCH_MISS 0x00000340 // # of times an instruction fetch missed the L1 Icache -#define MMCR0_PMC2_HOLD 0x00000000 // Register holds current value -#define MMCR0_PMC2_CYCLE 0x00000001 // Processor cycles -#define MMCR0_PMC2_INSTRUCTION 0x00000002 // # of instructions completed -#define MMCR0_PMC2_TRANSITION 0x00000003 // # of time-base (lower) bit transitions -#define MMCR0_PMC2_DISPATCHED 0x00000004 // # of instructions dispatched -#define MMCR0_PMC2_IC_MISS 0x00000005 // # of L1 instruction cache misses -#define MMCR0_PMC2_ITLB_MISS 0x00000006 // # of ITLB misses -#define MMCR0_PMC2_L2_I_MISS 0x00000007 // # of L2 instruction misses -#define MMCR0_PMC2_Bx_FALL_TROUGH 0x00000008 // # of fall-through branches -#define MMCR0_PMC2_PR_SWITCH 0x00000009 // # of MSR[PR] bit toggles -#define MMCR0_PMC2_RESERVED_LOAD 0x0000000A // # of reserved loads completed -#define MMCR0_PMC2_LOAD_STORE 0x0000000B // # of completed loads and stores -#define MMCR0_PMC2_SNOOP 0x0000000C // # of snoops -#define MMCR0_PMC2_L1_CASTOUT 0x0000000D // # of L1 castouts to L2 -#define MMCR0_PMC2_SYSTEM 0x0000000E // # of completed system unit instructions -#define MMCR0_PMC2_IC_FETCH_MISS 0x0000000F // # of instruction fetch misses in the L1 -#define MMCR0_PMC2_Bx_OUT_OF_ORDER 0x00000010 // # of branches allowing out-of-order execution + void PPCSync(void); + void PPCHalt(void); -/*---------------------------------------------------------------------------* - PMC3 Events - *---------------------------------------------------------------------------*/ -#define MMCR1_PMC3_HOLD 0x00000000 // Register holds current value -#define MMCR1_PMC3_CYCLE 0x08000000 // Processor cycles -#define MMCR1_PMC3_INSTRUCTION 0x10000000 // # of instructions completed -#define MMCR1_PMC3_TRANSITION 0x18000000 // # of time-base (lower) bit transitions -#define MMCR1_PMC3_DISPATCHED 0x20000000 // # of instructions dispatched -#define MMCR1_PMC3_DC_MISS 0x28000000 // # of L1 data cache misses -#define MMCR1_PMC3_DTLB_MISS 0x30000000 // # of DTLB misses -#define MMCR1_PMC3_L2_D_MISS 0x38000000 // # of L2 data misses -#define MMCR1_PMC3_Bx_TAKEN 0x40000000 // # predicted branches that were taken -#define MMCR1_PMC3_PM_SWITCH 0x48000000 // # of transitions between marked and unmarked processes -#define MMCR1_PMC3_COND_STORE 0x50000000 // # of store conditional instructions completed -#define MMCR1_PMC3_FPU 0x58000000 // # of instructions completed from the FPU -#define MMCR1_PMC3_L2_SNOOP_CASTOUT 0x60000000 // # of L2 castout caused by snoops to modified lines -#define MMCR1_PMC3_L2_HIT 0x68000000 // # of cache operations that hit in the L2 cache -#define MMCR1_PMC3_L1_MISS_CYCLE 0x78000000 // # of cycles generated by L1 load misses -#define MMCR1_PMC3_Bx_SECOND 0x80000000 // # of branches in the second speculative branch - // resolved correctly -#define MMCR1_PMC3_BPU_LR_CR 0x88000000 // # of cycles the BPU stalls due to LR or CR unresolved - // dependencies + void PPCMtmmcr0(u32 val); + void PPCMtmmcr1(u32 val); -#define MMCR1_PMC4_HOLD 0x00000000 // Register holds current value -#define MMCR1_PMC4_CYCLE 0x00400000 // Processor cycles -#define MMCR1_PMC4_INSTRUCTION 0x00800000 // # of instructions completed -#define MMCR1_PMC4_TRANSITION 0x00C00000 // # of time-base (lower) bit transitions -#define MMCR1_PMC4_DISPATCHED 0x01000000 // # of instructions dispatched -#define MMCR1_PMC4_L2_CASTOUT 0x01400000 // # of L2 castouts -#define MMCR1_PMC4_DTLB_CYCLE 0x01800000 // # of cycles spent performing table searches for DTLB accesses -#define MMCR1_PMC4_Bx_MISSED 0x02000000 // # of mispredicted branches -#define MMCR1_PMC4_COND_STORE_INT 0x02800000 // # of store conditional instructions completed - // with reservation intact -#define MMCR1_PMC4_SYNC 0x02C00000 // # of completed sync instructions -#define MMCR1_PMC4_SNOOP_RETRY 0x03000000 // # of snoop request retries -#define MMCR1_PMC4_INTEGER 0x03400000 // # of completed integer operations -#define MMCR1_PMC4_BPU_THIRD 0x03800000 // # of cycles the BPU cannot process new branches - // due to having two unresolved branches -#define MMCR1_PMC4_DC_MISS 0x07C00000 // # of L1 data cache misses + void PPCMtpmc1(u32 val); + void PPCMtpmc2(u32 val); + void PPCMtpmc3(u32 val); + void PPCMtpmc4(u32 val); -/*---------------------------------------------------------------------------* - FPSCR bits - *---------------------------------------------------------------------------*/ -#ifndef FPSCR_FX -#define FPSCR_FX 0x80000000 // Exception summary -#define FPSCR_FEX 0x40000000 // Enabled exception summary -#define FPSCR_VX 0x20000000 // Invalid operation -#define FPSCR_OX 0x10000000 // Overflow exception -#define FPSCR_UX 0x08000000 // Underflow exception -#define FPSCR_ZX 0x04000000 // Zero divide exception -#define FPSCR_XX 0x02000000 // Inexact exception -#define FPSCR_VXSNAN 0x01000000 // SNaN -#define FPSCR_VXISI 0x00800000 // Infinity - Infinity -#define FPSCR_VXIDI 0x00400000 // Infinity / Infinity -#define FPSCR_VXZDZ 0x00200000 // 0 / 0 -#define FPSCR_VXIMZ 0x00100000 // Infinity * 0 -#define FPSCR_VXVC 0x00080000 // Invalid compare -#define FPSCR_FR 0x00040000 // Fraction rounded -#define FPSCR_FI 0x00020000 // Fraction inexact -#define FPSCR_VXSOFT 0x00000400 // Software request -#define FPSCR_VXSQRT 0x00000200 // Invalid square root -#define FPSCR_VXCVI 0x00000100 // Invalid integer convert -#define FPSCR_VE 0x00000080 // Invalid operation exception enable -#define FPSCR_OE 0x00000040 // Overflow exception enable -#define FPSCR_UE 0x00000020 // Underflow exception enable -#define FPSCR_ZE 0x00000010 // Zero divide exception enable -#define FPSCR_XE 0x00000008 // Inexact exception enable -#define FPSCR_NI 0x00000004 // Non-IEEE mode -#endif + u32 PPCMffpscr(void); + void PPCMtfpscr(u32 val); -#ifndef FPSCR_FX_BIT -#define FPSCR_FX_BIT 0 // Exception summary -#define FPSCR_FEX_BIT 1 // Enabled exception summary -#define FPSCR_VX_BIT 2 // Invalid operation -#define FPSCR_OX_BIT 3 // Overflow exception -#define FPSCR_UX_BIT 4 // Underflow exception -#define FPSCR_ZX_BIT 5 // Zero divide exception -#define FPSCR_XX_BIT 6 // Inexact exception -#define FPSCR_VXSNAN_BIT 7 // SNaN -#define FPSCR_VXISI_BIT 8 // Infinity - Infinity -#define FPSCR_VXIDI_BIT 9 // Infinity / Infinity -#define FPSCR_VXZDZ_BIT 10 // 0 / 0 -#define FPSCR_VXIMZ_BIT 11 // Infinity * 0 -#define FPSCR_VXVC_BIT 12 // Invalid compare -#define FPSCR_FR_BIT 13 // Fraction rounded -#define FPSCR_FI_BIT 14 // Fraction inexact -#define FPSCR_VXSOFT_BIT 21 // Software request -#define FPSCR_VXSQRT_BIT 22 // Invalid square root -#define FPSCR_VXCVI_BIT 23 // Invalid integer convert -#define FPSCR_VE_BIT 24 // Invalid operation exception enable -#define FPSCR_OE_BIT 25 // Overflow exception enable -#define FPSCR_UE_BIT 26 // Underflow exception enable -#define FPSCR_ZE_BIT 27 // Zero divide exception enable -#define FPSCR_XE_BIT 28 // Inexact exception enable -#define FPSCR_NI_BIT 29 // Non-IEEE mode -#endif + u32 PPCMfhid2(void); + void PPCMthid2(u32 val); -union FpscrUnion { - f64 f; - struct { - u32 fpscr_pad; - u32 fpscr; - } u; -}; + u32 PPCMfwpar(void); + void PPCMtwpar(u32 val); -// 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(); + void PPCDisableSpeculation(void); + void PPCSetFpNonIEEEMode(void); -// PPCPm -void PMBegin(void); -void PMEnd(void); -void PMCycles(void); -void PML1FetchMisses(void); -void PML1MissCycles(void); -void PMInstructions(void); + void PPCMthid4(u32 val); #ifdef __cplusplus } #endif +#endif -#endif // _DOLPHIN_PPCARCH +/** + * MSR + * Machine Status Register + */ +// Power management enable +#define MSR_POW (1 << (31 - 13)) +// Exception little-endian mode +#define MSR_ILE (1 << (31 - 15)) +// External interrupt enable +#define MSR_EE (1 << (31 - 16)) +// Privilege level +#define MSR_PR (1 << (31 - 17)) +// Floating-point available +#define MSR_FP (1 << (31 - 18)) +// Machine check enable +#define MSR_ME (1 << (31 - 19)) +// IEEE floating-point exception mode 0 +#define MSR_FE0 (1 << (31 - 20)) +// Single-step trace enable +#define MSR_SE (1 << (31 - 21)) +// Branch trace enable +#define MSR_BE (1 << (31 - 22)) +// IEEE floating-point exception mode 1 +#define MSR_FE1 (1 << (31 - 23)) +// Exception prefix +#define MSR_IP (1 << (31 - 25)) +// Instruction address translation +#define MSR_IR (1 << (31 - 26)) +// Data address translation +#define MSR_DR (1 << (31 - 27)) +// Performance monitor marked mode +#define MSR_PM (1 << (31 - 29)) +// Indicates whether system reset or machine check exception is recoverable +#define MSR_RI (1 << (31 - 30)) +// Little-endian mode enable +#define MSR_LE (1 << (31 - 31)) + +/** + * HID0 + * Hardware Implementation-Dependent Register 0 + */ +// Enable MCP +#define HID0_EMCP (1 << (31 - 0)) +// Enable/disable 60x bus address and data parity generation +#define HID0_DBP (1 << (31 - 1)) +// Enable/disable 60x bus address parity checking +#define HID0_EBA (1 << (31 - 2)) +// Enable 60x bus data parity checking +#define HID0_EBD (1 << (31 - 3)) +// CLK_OUT enable +#define HID0_BCLK (1 << (31 - 4)) +// CLK_OUT enable +#define HID0_ECLK (1 << (31 - 6)) +// Disable precharge of ARTRY +#define HID0_PAR (1 << (31 - 7)) +// Doze mode enable +#define HID0_DOZE (1 << (31 - 8)) +// Nap mode enable +#define HID0_NAP (1 << (31 - 9)) +// Sleep mode enable +#define HID0_SLEEP (1 << (31 - 10)) +// Dynamic power management enable +#define HID0_DPM (1 << (31 - 11)) +// Not hard reset (software-use only) +#define HID0_NHR (1 << (31 - 15)) +// Instruction cache enable +#define HID0_ICE (1 << (31 - 16)) +// Data cache enable +#define HID0_DCE (1 << (31 - 17)) +// Instruction cache lock +#define HID0_ILOCK (1 << (31 - 18)) +// Data cache lock +#define HID0_DLOCK (1 << (31 - 19)) +// Instruction cache flash invalidate +#define HID0_ICFI (1 << (31 - 20)) +// Data cache flash invalidate +#define HID0_DCFI (1 << (31 - 21)) +// Speculative cache access disable +#define HID0_SPD (1 << (31 - 22)) +// Enable M bit on bus for instruction fetches +#define HID0_IFEM (1 << (31 - 23)) +// Store gathering enable +#define HID0_SGE (1 << (31 - 24)) +// Data cache flush assist +#define HID0_DCFA (1 << (31 - 25)) +// Branch Target Instruction Cache enable +#define HID0_BTIC (1 << (31 - 26)) +// Address broadcast enable +#define HID0_ABE (1 << (31 - 28)) +// Branch history table enable +#define HID0_BHT (1 << (31 - 29)) +// No-op the data cache touch instructions +#define HID0_NOOPTI (1 << (31 - 31)) + +/** + * HID1 + * Hardware Implementation-Dependent Register 1 + */ +// PLL configuration bits (read-only) +#define HID1_PC0 (1 << (31 - 0)) +#define HID1_PC1 (1 << (31 - 1)) +#define HID1_PC2 (1 << (31 - 2)) +#define HID1_PC3 (1 << (31 - 3)) +#define HID1_PC4 (1 << (31 - 4)) + +/** + * L2CR + * L2 Control Register + */ +// L2 enable +#define L2CR_L2E (1 << (31 - 0)) +// L2 Checkstop enable +#define L2CR_L2CE (1 << (31 - 1)) +// L2 data-only +#define L2CR_L2DO (1 << (31 - 9)) +// L2 global invalidate +#define L2CR_L2I (1 << (31 - 10)) +// L2 write-through +#define L2CR_L2WT (1 << (31 - 12)) +// L2 test support +#define L2CR_L2TS (1 << (31 - 13)) +// L2 global invalidate in progress (read only) +#define L2CR_L2IP (1 << (31 - 31)) + +/** + * PMC1-PMC4 + * Performance Monitor Counter Registers + */ +// Overflow +#define PMC_OV (1 << (31 - 0)) + +/** + * FPSCR + * Floating-Point Status and Control Register + */ +// Floating-point exception summary +#define FPSCR_FX (1 << (31 - 0)) +// Floating-point enabled exception summary +#define FPSCR_FEX (1 << (31 - 1)) +// Floating-point invalid operation exception summary +#define FPSCR_VX (1 << (31 - 2)) +// Floating-point overflow exception +#define FPSCR_OX (1 << (31 - 3)) +// Floating-point underflow exception +#define FPSCR_UX (1 << (31 - 4)) +// Floating-point zero divide exception +#define FPSCR_ZX (1 << (31 - 5)) +// Floating-point inexact exception +#define FPSCR_XX (1 << (31 - 6)) +// Floating-point invalid operation exception for SNaN +#define FPSCR_VXSNAN (1 << (31 - 7)) +// Floating-point invalid operation exception for (inf - inf) +#define FPSCR_VXISI (1 << (31 - 8)) +// Floating-point invalid operation exception for (inf / inf) +#define FPSCR_VXIDI (1 << (31 - 9)) +// Floating-point invalid operation exception for (0 / 0) +#define FPSCR_VXZDZ (1 << (31 - 10)) +// Floating-point invalid operation exception for (inf * 0) +#define FPSCR_VXIMZ (1 << (31 - 11)) +// Floating-point invalid operation exception for invalid compare +#define FPSCR_VXVC (1 << (31 - 12)) +// Floating-point fraction rounded +#define FPSCR_FR (1 << (31 - 13)) +// Floating-point fraction inexact +#define FPSCR_FI (1 << (31 - 14)) +// Floating-point result flags +#define FPSCR_FPRF (0x1F << (31 - 19)) +// Unknown +#define FPSCR_UNK20 (1 << (31 - 20)) +// Floating-point invalid operation exception for software request +#define FPSCR_VXSOFT (1 << (31 - 21)) +// Floating-point invalid operation exception for invalid square root +#define FPSCR_VXSQRT (1 << (31 - 22)) +// Floating-point invalid operation exception for invalid integer convert +#define FPSCR_VXCVI (1 << (31 - 23)) +// Floating-point invalid operation exception enable +#define FPSCR_VE (1 << (31 - 24)) +// IEEE floating-point overflow exception enable +#define FPSCR_OE (1 << (31 - 25)) +// IEEE floating-point underflow exception enable +#define FPSCR_UE (1 << (31 - 26)) +// IEEE floating-point zero divide exception enable +#define FPSCR_ZE (1 << (31 - 27)) +// Floating-point inexact exception enable +#define FPSCR_XE (1 << (31 - 28)) +// Floating-point non-IEEE mode +#define FPSCR_NI (1 << (31 - 29)) +// Floating-point rounding control +#define FPSCR_RN (0x3 << (31 - 31)) + +/** + * HID2 + * Hardware Implementation-Dependent Register 2 + */ +// Write pipe enable +#define HID2_WPE (1 << (31 - 1)) +// Paired-single enable +#define HID2_PSE (1 << (31 - 2)) +// Locked cache enable +#define HID2_LCE (1 << (31 - 3)) +// DMA queue length (read only) +#define HID2_DMAQL \ + ((1 << (31 - 4)) | (1 << (31 - 5)) | (1 << (31 - 6)) | (1 << (31 - 7))) +// dcbz_l cache hit error +#define HID2_DCHERR (1 << (31 - 8)) +// DMA access to normal cache error +#define HID2_DNCERR (1 << (31 - 9)) +// DMA cache miss error +#define HID2_DCMERR (1 << (31 - 10)) +// DMA queue overflow error +#define HID2_DQOERR (1 << (31 - 11)) +// dcbz_l cache hit error enable +#define HID2_DCHEE (1 << (31 - 12)) +// DMA access to normal cache error enable +#define HID2_DNCEE (1 << (31 - 13)) +// DMA cache miss error enable +#define HID2_DCMEE (1 << (31 - 14)) +// DMA queue overflow error enable +#define HID2_DQOEE (1 << (31 - 15)) + +#define SRR1_DMA_BIT 0x00200000 +#define SRR1_L2DP_BIT 0x00100000 + +/** + * WPAR + * Write Pipe Address Register + */ +// High order address bits of the data to be gathered +#define WPAR_GB_ADDR (0x07FFFFFF << (31 - 26)) +// Buffer not empty (read only) +#define WPAR_BNE (1 << (31 - 31)) + +/** + * DMAU + * Direct Memory Access Upper Register + */ +// High order address bits of starting address in external memory of the DMA +// transfer +#define DMAU_MEM_ADDR (0x07FFFFFF << (31 - 26)) +// High order bits of transfer length, in cache lines. Low order bits are in +// DMAL +#define DMAU_DMA_LEN_U (0x0000001F << (31 - 31)) + +/** + * DMAL + * Direct Memory Access Lower Register + */ +// High order address bits of starting address in locked cache of the DMA +// transfer +#define DMAL_LC_ADDR (0x07FFFFFF << (31 - 26)) +// DMA load command +#define DMAL_DMA_LD (1 << (31 - 27)) +// Low order bits of transfer length, in cache lines. High order bits are in +// DMAU +#define DMAL_DMA_LEN_L (0x3 << (31 - 29)) +// Trigger bit +#define DMAL_DMA_T (1 << (31 - 30)) +// Flush bit +#define DMAL_DMA_F (1 << (31 - 31)) + +/** + * PVR + * Processor Version Register + */ +// A 16-bit number that uniquely identifies a particular processor version +#define PVR_VER (0xFFFF0000) +// A 16-bit number that distinguishes between various releases of a particular +// version (that is, an engineering change level) +#define PVR_REV (0x0000FFFF) + +/** + * HID4 + * Hardware Implementation-Dependent Register 4 + */ +// Unknown +#define HID4_H4A (1 << (31 - 0)) +// L2 fetch mode +#define HID4_L2FM (0x3 << (31 - 2)) +// Bus pipeline depth +#define HID4_BPD (0x3 << (31 - 4)) +// L2 second castout buffer enable +#define HID4_BCO (1 << (31 - 5)) +// Secondary BAT enable +#define HID4_SBE (1 << (31 - 6)) +// Paired-singles control bit 1 +#define HID4_PS1_CTL (1 << (31 - 7)) +// Data bus parking +#define HID4_DBP (1 << (31 - 9)) +// L2 MUM enable +#define HID4_L2MUM (1 << (31 - 10)) +// L2CFI - L2 complete castout prior to L2 flash invalidate +#define HID4_L2_CCFI (1 << (31 - 11)) +// Paired-singles control bit 2 +#define HID4_PSS2_CTL (1 << (31 - 12)) \ No newline at end of file diff --git a/include/dolphin/card.h b/include/dolphin/card.h index f335a2a8d..ff05e8393 100644 --- a/include/dolphin/card.h +++ b/include/dolphin/card.h @@ -1,166 +1,49 @@ -#ifndef _DOLPHIN_CARD_H_ -#define _DOLPHIN_CARD_H_ +#ifndef _DOLPHIN_CARD +#define _DOLPHIN_CARD -#include -#include -#include +#include #ifdef __cplusplus extern "C" { #endif +#define CARD_ENCODE_ANSI 0u +#define CARD_ENCODE_SJIS 1u -#define CARD_FILENAME_MAX 32 +/* 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_ICON_MAX 8 +#define CARD_ICON_WIDTH 32 +#define CARD_ICON_HEIGHT 32 +#define CARD_BANNER_WIDTH 96 +#define CARD_BANNER_HEIGHT 32 -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) +/* Icon animation */ +#define CARD_MODE_NORMAL 0 +#define CARD_MODE_FAST 1 -#define CARD_MAX_MOUNT_STEP (CARD_NUM_SYSTEM_BLOCK + 2) +#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_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_NUM_CHANS 2 #define CARD_RESULT_UNLOCKED 1 #define CARD_RESULT_READY 0 @@ -180,18 +63,6 @@ typedef struct CARDStat #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 - #define CARD_STAT_ICON_NONE 0 #define CARD_STAT_ICON_C8 1 #define CARD_STAT_ICON_RGB5A3 2 @@ -202,133 +73,106 @@ typedef struct CARDStat #define CARD_STAT_BANNER_RGB5A3 2 #define CARD_STAT_BANNER_MASK 3 -#define CARD_ENCODE_ANSI 0 -#define CARD_ENCODE_SJIS 1 - #define CARD_STAT_ANIM_LOOP 0x00 #define CARD_STAT_ANIM_BOUNCE 0x04 #define CARD_STAT_ANIM_MASK 0x04 -#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_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 -extern u32 __CARDFreq; +#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 -#if DEBUG -#define CARDFreq __CARDFreq -#else -#define CARDFreq EXI_FREQ_16M -#endif +typedef struct CARDFileInfo { + s32 chan; + s32 fileNo; -void CARDInit(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* old, const char* _new, CARDCallback callback); + 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); -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); +BOOL CARDSetFastMode(BOOL enable); -// CARDCheck -s32 CARDCheckExAsync(s32 chan, s32* xferBytes, CARDCallback callback); +s32 CARDCheck(s32 chan); s32 CARDCheckAsync(s32 chan, CARDCallback callback); s32 CARDCheckEx(s32 chan, s32* xferBytes); -s32 CARDCheck(s32 chan); - -// CARDCreate +s32 CARDCheckExAsync(s32 chan, s32* xferBytes, CARDCallback callback); +s32 CARDCreate(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo); s32 CARDCreateAsync(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo, CARDCallback callback); -s32 CARDCreate(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo); - -// 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 CARDDeleteAsync(s32 chan, const char* fileName, CARDCallback callback); +s32 CARDFastDelete(s32 chan, s32 fileNo); +s32 CARDFastDeleteAsync(s32 chan, s32 fileNo, CARDCallback callback); +s32 CARDFastOpen(s32 chan, s32 fileNo, CARDFileInfo* fileInfo); s32 CARDFormat(s32 chan); - -// CARDMount -int CARDProbe(s32 chan); -s32 CARDProbeEx(s32 chan, s32* memSize, s32* sectorSize); +s32 CARDFormatAsync(s32 chan, CARDCallback callback); +s32 CARDFreeBlocks(s32 chan, s32* byteNotUsed, s32* filesNotUsed); +s32 CARDGetAttributes(s32 chan, s32 fileNo, u8* attr); +s32 CARDGetEncoding(s32 chan, u16* encode); +s32 CARDGetMemSize(s32 chan, u16* size); +s32 CARDGetResultCode(s32 chan); +s32 CARDGetSectorSize(s32 chan, u32* size); +s32 CARDGetSerialNo(s32 chan, u64* serialNo); +s32 CARDGetStatus(s32 chan, s32 fileNo, CARDStat* stat); +s32 CARDGetXferredBytes(s32 chan); +s32 CARDMount(s32 chan, void* workArea, CARDCallback detachCallback); s32 CARDMountAsync(s32 chan, void* workArea, CARDCallback detachCallback, CARDCallback attachCallback); -s32 CARDMount(s32 chan, void* workArea, CARDCallback detachCallback); -s32 CARDUnmount(s32 chan); - -// 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 CARDOpen(s32 chan, const char* fileName, CARDFileInfo* fileInfo); +BOOL CARDProbe(s32 chan); +s32 CARDProbeEx(s32 chan, s32* memSize, s32* sectorSize); +s32 CARDRename(s32 chan, const char* oldName, const char* newName); +s32 CARDRenameAsync(s32 chan, const char* oldName, const char* newName, CARDCallback callback); s32 CARDSetAttributesAsync(s32 chan, s32 fileNo, u8 attr, CARDCallback callback); s32 CARDSetAttributes(s32 chan, s32 fileNo, u8 attr); - -// CARDOpen -s32 CARDFastOpen(s32 chan, s32 fileNo, CARDFileInfo* fileInfo); -s32 CARDOpen(s32 chan, const char* fileName, CARDFileInfo* fileInfo); -s32 CARDClose(CARDFileInfo* fileInfo); - -// CARDProgram -s32 CARDProgramAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, - CARDCallback callback); -s32 CARDProgram(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset); - -// 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* old, const char* _new); - -// CARDStat -s32 CARDGetStatus(s32 chan, s32 fileNo, CARDStat* stat); -s32 CARDSetStatusAsync(s32 chan, s32 fileNo, CARDStat* stat, CARDCallback callback); s32 CARDSetStatus(s32 chan, s32 fileNo, CARDStat* stat); - -// CARDWrite -s32 CARDWriteAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, +s32 CARDSetStatusAsync(s32 chan, s32 fileNo, CARDStat* stat, CARDCallback callback); +s32 CARDUnmount(s32 chan); +s32 CARDGetCurrentMode(s32 chan, u32* mode); +s32 CARDCancel(CARDFileInfo* fileInfo); +s32 CARDClose(CARDFileInfo* fileInfo); +s32 CARDRead(CARDFileInfo* fileInfo, void* addr, s32 length, s32 offset); +s32 CARDReadAsync(CARDFileInfo* fileInfo, void* addr, s32 length, s32 offset, + CARDCallback callback); +s32 CARDWrite(CARDFileInfo* fileInfo, const void* addr, s32 length, s32 offset); +s32 CARDWriteAsync(CARDFileInfo* fileInfo, const void* addr, s32 length, s32 offset, CARDCallback callback); -s32 CARDWrite(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset); #ifdef __cplusplus } #endif - -#endif +#endif // _DOLPHIN_CARD \ No newline at end of file diff --git a/include/dolphin/db.h b/include/dolphin/db.h index a126bbe39..dc19c6311 100644 --- a/include/dolphin/db.h +++ b/include/dolphin/db.h @@ -1,20 +1,32 @@ -#ifndef _DOLPHIN_DB_H_ -#define _DOLPHIN_DB_H_ +#ifndef _DOLPHIN_DB +#define _DOLPHIN_DB -#include -#include +#include "types.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #define OS_DBINTERFACE_ADDR 0x00000040 -BOOL DBIsDebuggerPresent(void); -void DBPrintf(char* str, ...); +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); +static void __DBExceptionDestination(void); +void DBPrintf(char *format, ...); #ifdef __cplusplus } #endif -#endif // _DOLPHIN_DB_H_ +#endif // _DOLPHIN_DB \ No newline at end of file diff --git a/include/dolphin/dolphin/ar.h b/include/dolphin/dolphin/ar.h deleted file mode 100644 index 210f136c7..000000000 --- a/include/dolphin/dolphin/ar.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef _DOLPHIN_AR_H_ -#define _DOLPHIN_AR_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*ARQCallback)(u32 pointerToARQRequest); - -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 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); -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 diff --git a/include/dolphin/dolphin/gx.h b/include/dolphin/dolphin/gx.h deleted file mode 100644 index 0e90e543e..000000000 --- a/include/dolphin/dolphin/gx.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef _DOLPHIN_GX_H_ -#define _DOLPHIN_GX_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 - -// GXMisc -void (*GXSetDrawSyncCallback(void (*cb)(u16)))(u16); -void GXSetDrawSync(u16 token); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/dolphin/dolphin/gx/GXBump.h b/include/dolphin/dolphin/gx/GXBump.h deleted file mode 100644 index 2a24dc69f..000000000 --- a/include/dolphin/dolphin/gx/GXBump.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _DOLPHIN_GX_GXBUMP_H_ -#define _DOLPHIN_GX_GXBUMP_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -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 diff --git a/include/dolphin/dolphin/gx/GXCommandList.h b/include/dolphin/dolphin/gx/GXCommandList.h deleted file mode 100644 index b9933c9c7..000000000 --- a/include/dolphin/dolphin/gx/GXCommandList.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _DOLPHIN_GX_GXCOMMANDLIST_H_ -#define _DOLPHIN_GX_GXCOMMANDLIST_H_ - -#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/dolphin/gx/GXCpu2Efb.h b/include/dolphin/dolphin/gx/GXCpu2Efb.h deleted file mode 100644 index 46aa3e336..000000000 --- a/include/dolphin/dolphin/gx/GXCpu2Efb.h +++ /dev/null @@ -1,29 +0,0 @@ -#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/dolphin/gx/GXCull.h b/include/dolphin/dolphin/gx/GXCull.h deleted file mode 100644 index cac438181..000000000 --- a/include/dolphin/dolphin/gx/GXCull.h +++ /dev/null @@ -1,18 +0,0 @@ -#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/dolphin/gx/GXDispList.h b/include/dolphin/dolphin/gx/GXDispList.h deleted file mode 100644 index 15c5eb054..000000000 --- a/include/dolphin/dolphin/gx/GXDispList.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _DOLPHIN_GX_GXDISPLIST_H_ -#define _DOLPHIN_GX_GXDISPLIST_H_ - -#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/dolphin/gx/GXDraw.h b/include/dolphin/dolphin/gx/GXDraw.h deleted file mode 100644 index 1e32f635c..000000000 --- a/include/dolphin/dolphin/gx/GXDraw.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _DOLPHIN_GX_GXDRAW_H_ -#define _DOLPHIN_GX_GXDRAW_H_ - -#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 diff --git a/include/dolphin/dolphin/gx/GXEnum.h b/include/dolphin/dolphin/gx/GXEnum.h deleted file mode 100644 index c3686e538..000000000 --- a/include/dolphin/dolphin/gx/GXEnum.h +++ /dev/null @@ -1,898 +0,0 @@ -#ifndef _DOLPHIN_GX_GXENUM_H_ -#define _DOLPHIN_GX_GXENUM_H_ - -typedef u8 GXBool; - -#define GX_FALSE ((GXBool)0) -#define GX_TRUE ((GXBool)1) - -#define GX_ENABLE ((GXBool)1) -#define GX_DISABLE ((GXBool)0) - -typedef enum _GXProjectionType { - GX_PERSPECTIVE, - GX_ORTHOGRAPHIC, -} GXProjectionType; - -typedef enum _GXCompare { - GX_NEVER, - GX_LESS, - GX_EQUAL, - GX_LEQUAL, - GX_GREATER, - GX_NEQUAL, - GX_GEQUAL, - GX_ALWAYS, -} GXCompare; - -typedef enum _GXAlphaOp { - GX_AOP_AND, - GX_AOP_OR, - GX_AOP_XOR, - GX_AOP_XNOR, - GX_MAX_ALPHAOP, -} GXAlphaOp; - -typedef enum _GXZFmt16 { - GX_ZC_LINEAR, - GX_ZC_NEAR, - GX_ZC_MID, - GX_ZC_FAR, -} GXZFmt16; - -typedef enum _GXGamma { - GX_GM_1_0, - GX_GM_1_7, - GX_GM_2_2, -} GXGamma; - -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; - -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 _GXVtxFmt { - GX_VTXFMT0, - GX_VTXFMT1, - GX_VTXFMT2, - GX_VTXFMT3, - GX_VTXFMT4, - GX_VTXFMT5, - GX_VTXFMT6, - GX_VTXFMT7, - GX_MAX_VTXFMT, -} GXVtxFmt; - -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 { - 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 _GXPosNrmMtx { - 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, - 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, - 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 _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 _GXPerf0 { - 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, - 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, - 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, - GX_PERF0_NONE, -} GXPerf0; - -typedef enum _GXPerf1 { - 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, - 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, - GX_PERF1_CALL_REQ, - GX_PERF1_VC_MISS_REQ, - GX_PERF1_CP_ALL_REQ, - - GX_PERF1_CLOCKS, - GX_PERF1_NONE, -} GXPerf1; - -typedef enum _GXVCachePerf { - GX_VC_POS = 0, - GX_VC_NRM = 1, - GX_VC_CLR0 = 2, - GX_VC_CLR1 = 3, - GX_VC_TEX0 = 4, - GX_VC_TEX1 = 5, - GX_VC_TEX2 = 6, - GX_VC_TEX3 = 7, - GX_VC_TEX4 = 8, - GX_VC_TEX5 = 9, - GX_VC_TEX6 = 10, - GX_VC_TEX7 = 11, - GX_VC_ALL = 15, -} GXVCachePerf; - -typedef enum _GXClipMode { - GX_CLIP_ENABLE = 0, - GX_CLIP_DISABLE = 1, -} GXClipMode; - -typedef enum _GXFBClamp { - GX_CLAMP_NONE = 0, - GX_CLAMP_TOP = 1, - GX_CLAMP_BOTTOM = 2, -} GXFBClamp; - -typedef enum _GXCopyMode { - GX_COPY_PROGRESSIVE = 0, - GX_COPY_INTLC_EVEN = 2, - GX_COPY_INTLC_ODD = 3, -} GXCopyMode; - -typedef enum _GXAlphaReadMode { - GX_READ_00, - GX_READ_FF, - GX_READ_NONE, -} GXAlphaReadMode; - -typedef enum _GXTexCacheSize { - GX_TEXCACHE_32K, - GX_TEXCACHE_128K, - GX_TEXCACHE_512K, - GX_TEXCACHE_NONE, -} GXTexCacheSize; - -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; - -typedef enum _GXTlutFmt { - GX_TL_IA8, - GX_TL_RGB565, - GX_TL_RGB5A3, - GX_MAX_TLUTFMT, -} GXTlutFmt; - -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; - -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; - -#endif diff --git a/include/dolphin/dolphin/gx/GXFifo.h b/include/dolphin/dolphin/gx/GXFifo.h deleted file mode 100644 index 1452975f5..000000000 --- a/include/dolphin/dolphin/gx/GXFifo.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _DOLPHIN_GX_GXFIFO_H_ -#define _DOLPHIN_GX_GXFIFO_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct OSThread; - -typedef struct -{ - u8 pad[128]; -} GXFifoObj; - -typedef void (*GXBreakPtCallback)(void); - -void GXInitFifoBase(GXFifoObj* fifo, void* base, u32 size); -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 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 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 diff --git a/include/dolphin/dolphin/gx/GXFrameBuffer.h b/include/dolphin/dolphin/gx/GXFrameBuffer.h deleted file mode 100644 index 73b513fa3..000000000 --- a/include/dolphin/dolphin/gx/GXFrameBuffer.h +++ /dev/null @@ -1,66 +0,0 @@ -#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/dolphin/gx/GXGeometry.h b/include/dolphin/dolphin/gx/GXGeometry.h deleted file mode 100644 index 188fa7a59..000000000 --- a/include/dolphin/dolphin/gx/GXGeometry.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef _DOLPHIN_GX_GXGEOMETRY_H_ -#define _DOLPHIN_GX_GXGEOMETRY_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -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 diff --git a/include/dolphin/dolphin/gx/GXGet.h b/include/dolphin/dolphin/gx/GXGet.h deleted file mode 100644 index d1ba630a4..000000000 --- a/include/dolphin/dolphin/gx/GXGet.h +++ /dev/null @@ -1,64 +0,0 @@ -#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/dolphin/gx/GXLighting.h b/include/dolphin/dolphin/gx/GXLighting.h deleted file mode 100644 index 83c5aae42..000000000 --- a/include/dolphin/dolphin/gx/GXLighting.h +++ /dev/null @@ -1,32 +0,0 @@ -#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/dolphin/gx/GXManage.h b/include/dolphin/dolphin/gx/GXManage.h deleted file mode 100644 index fd899d361..000000000 --- a/include/dolphin/dolphin/gx/GXManage.h +++ /dev/null @@ -1,36 +0,0 @@ -#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/dolphin/gx/GXPerf.h b/include/dolphin/dolphin/gx/GXPerf.h deleted file mode 100644 index bd1b474aa..000000000 --- a/include/dolphin/dolphin/gx/GXPerf.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _DOLPHIN_GX_GXPERF_H_ -#define _DOLPHIN_GX_GXPERF_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void GXSetGPMetric(GXPerf0 perf0, GXPerf1 perf1); -void GXReadGPMetric(u32* cnt0, u32* cnt1); -void GXClearGPMetric(void); -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 diff --git a/include/dolphin/dolphin/gx/GXPixel.h b/include/dolphin/dolphin/gx/GXPixel.h deleted file mode 100644 index d61838d1a..000000000 --- a/include/dolphin/dolphin/gx/GXPixel.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _DOLPHIN_GX_GXPIXEL_H_ -#define _DOLPHIN_GX_GXPIXEL_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -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 diff --git a/include/dolphin/dolphin/gx/GXStruct.h b/include/dolphin/dolphin/gx/GXStruct.h deleted file mode 100644 index 0e7dc0be6..000000000 --- a/include/dolphin/dolphin/gx/GXStruct.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef _DOLPHIN_GX_GXSTRUCT_H_ -#define _DOLPHIN_GX_GXSTRUCT_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 { - u8 r, g, b, a; -} GXColor; - -typedef struct _GXColorS10 { - s16 r, g, b, a; -} GXColorS10; - -typedef struct _GXTexObj { - u32 dummy[8]; -} GXTexObj; - -typedef struct _GXLightObj { - u32 dummy[16]; -} GXLightObj; - -typedef struct _GXTexRegion { - u32 dummy[4]; -} GXTexRegion; - -typedef struct _GXTlutObj { - u32 dummy[3]; -} GXTlutObj; - -typedef struct _GXTlutRegion { - u32 dummy[4]; -} GXTlutRegion; - -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/dolphin/gx/GXTev.h b/include/dolphin/dolphin/gx/GXTev.h deleted file mode 100644 index 8deb22d08..000000000 --- a/include/dolphin/dolphin/gx/GXTev.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef _DOLPHIN_GX_GXTEV_H_ -#define _DOLPHIN_GX_GXTEV_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 GXSetTevColor(GXTevRegID id, GXColor color); -void GXSetTevColorS10(GXTevRegID id, GXColorS10 color); -void GXSetTevKColor(GXTevKColorID id, GXColor color); -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 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 nStages); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/dolphin/dolphin/gx/GXTexture.h b/include/dolphin/dolphin/gx/GXTexture.h deleted file mode 100644 index f42dc2295..000000000 --- a/include/dolphin/dolphin/gx/GXTexture.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef _DOLPHIN_GX_GXTEXTURE_H_ -#define _DOLPHIN_GX_GXTEXTURE_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef GXTexRegion *(*GXTexRegionCallback)(GXTexObj* t_obj, GXTexMapID id); -typedef GXTlutRegion *(*GXTlutRegionCallback)(u32 idx); - -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* 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 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 diff --git a/include/dolphin/dolphin/gx/GXTransform.h b/include/dolphin/dolphin/gx/GXTransform.h deleted file mode 100644 index 1e7f94e57..000000000 --- a/include/dolphin/dolphin/gx/GXTransform.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef _DOLPHIN_GX_GXTRANSFORM_H_ -#define _DOLPHIN_GX_GXTRANSFORM_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#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 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 diff --git a/include/dolphin/dolphin/gx/GXVerify.h b/include/dolphin/dolphin/gx/GXVerify.h deleted file mode 100644 index 93a1b29e5..000000000 --- a/include/dolphin/dolphin/gx/GXVerify.h +++ /dev/null @@ -1,29 +0,0 @@ -#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/dolphin/gx/GXVert.h b/include/dolphin/dolphin/gx/GXVert.h deleted file mode 100644 index e674041bc..000000000 --- a/include/dolphin/dolphin/gx/GXVert.h +++ /dev/null @@ -1,162 +0,0 @@ -#ifndef _DOLPHIN_GX_GXVERT_H_ -#define _DOLPHIN_GX_GXVERT_H_ - -#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 : (GXFIFO_ADDR); -#else -#define GXWGFifo (*(volatile PPCWGPipe*)GXFIFO_ADDR) -#endif - -#if DEBUG - -// external functions - -#define FUNC_1PARAM(name, T) void name##1##T(T x); -#define FUNC_2PARAM(name, T) void name##2##T(T x, T y); -#define FUNC_3PARAM(name, T) void name##3##T(T x, T y, T z); -#define FUNC_4PARAM(name, T) void name##4##T(T x, T y, T z, T w); -#define FUNC_INDEX8(name) void name##1x8(u8 x); -#define FUNC_INDEX16(name) void name##1x16(u16 x); - -#else - -// inline functions - -#define FUNC_1PARAM(name, T) \ - static inline void name##1##T(T x) \ - { \ - GXWGFifo.T = x; \ - } - -#define FUNC_2PARAM(name, T) \ - static inline void name##2##T(T x, T y) \ - { \ - GXWGFifo.T = x; \ - GXWGFifo.T = y; \ - } - -#define FUNC_3PARAM(name, T) \ - static inline void name##3##T(T x, T y, T z) \ - { \ - GXWGFifo.T = x; \ - GXWGFifo.T = y; \ - GXWGFifo.T = z; \ - } - -#define FUNC_4PARAM(name, T) \ - static inline 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) \ - static inline void name##1x8(u8 x) \ - { \ - GXWGFifo.u8 = x; \ - } - -#define FUNC_INDEX16(name) \ - static inline void name##1x16(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/dolphin/mtx.h b/include/dolphin/dolphin/mtx.h deleted file mode 100644 index aaaaf6f2e..000000000 --- a/include/dolphin/dolphin/mtx.h +++ /dev/null @@ -1,373 +0,0 @@ -#ifndef _DOLPHIN_MTX_H_ -#define _DOLPHIN_MTX_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - f32 x, y, z; -} Vec, *VecPtr, Point3d, *Point3dPtr; - -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]; - -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 sinA, f32 cosA); -void PSMTXRotAxisRad(Mtx m, const Vec* axis, f32 rad); -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); - -#ifdef DEBUG -#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_MTXRotRad -#define MTXTrans C_MTXTrans -#define MTXTransApply C_MTXTransApply -#define MTXScale C_MTXScale -#define MTXScaleApply C_MTXScaleApply -#define MTXQuat C_MTXQuat -#define MTXReflect C_MTXReflect -#else -#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 PSMTXRotRad -#define MTXTrans PSMTXTrans -#define MTXTransApply PSMTXTransApply -#define MTXScale PSMTXScale -#define MTXScaleApply PSMTXScaleApply -#define MTXQuat PSMTXQuat -#define MTXReflect PSMTXReflect -#endif - -// 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 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); - -#ifdef DEBUG -#define MTXMultVec C_MTXMultVec -#define MTXMultVecArray C_MTXMultVecArray -#define MTXMultVecSR C_MTXMultVecSR -#define MTXMultVecArraySR C_MTXMultVecArraySR -#else -#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 diff --git a/include/dolphin/dolphin/vi.h b/include/dolphin/dolphin/vi.h deleted file mode 100644 index af4184426..000000000 --- a/include/dolphin/dolphin/vi.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _DOLPHIN_VI_H_ -#define _DOLPHIN_VI_H_ - -#include -#include - -#endif diff --git a/include/dolphin/dolphin/vi/vifuncs.h b/include/dolphin/dolphin/vi/vifuncs.h deleted file mode 100644 index f9b6086d9..000000000 --- a/include/dolphin/dolphin/vi/vifuncs.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _DOLPHIN_VIFUNCS_H_ -#define _DOLPHIN_VIFUNCS_H_ - -#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/dolphin/vi/vitypes.h b/include/dolphin/dolphin/vi/vitypes.h deleted file mode 100644 index 1334696f8..000000000 --- a/include/dolphin/dolphin/vi/vitypes.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _DOLPHIN_VITYPES_H_ -#define _DOLPHIN_VITYPES_H_ - -#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/dolphin/dsp.h b/include/dolphin/dsp.h index db2975948..472827ad3 100644 --- a/include/dolphin/dsp.h +++ b/include/dolphin/dsp.h @@ -1,35 +1,50 @@ -#ifndef _DOLPHIN_DSP_H_ -#define _DOLPHIN_DSP_H_ +#ifndef _DOLPHIN_DSP +#define _DOLPHIN_DSP +#include "types.h" #include #ifdef __cplusplus extern "C" { #endif +#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 + typedef void (*DSPCallback)(void* task); -typedef struct STRUCT_DSP_TASK DSPTaskInfo; - -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 */ DSPTaskInfo* next; - /* 0x3C */ DSPTaskInfo* prev; - /* 0x40 */ OSTime t_context; - /* 0x48 */ OSTime t_task; + +typedef struct STRUCT_DSP_TASK { + vu32 state; + vu32 priority; + vu32 flags; + u16* iram_mmem_addr; + u32 iram_length; + u32 iram_addr; + + u16* dram_mmem_addr; + u32 dram_length; + u32 dram_addr; + + u16 dsp_init_vector; + u16 dsp_resume_vector; + + DSPCallback init_cb; + DSPCallback res_cb; + DSPCallback done_cb; + DSPCallback req_cb; + + struct STRUCT_DSP_TASK* next; + struct STRUCT_DSP_TASK* prev; + + OSTime t_context; + OSTime t_task; + } DSPTaskInfo; u32 DSPCheckMailToDSP(void); @@ -44,14 +59,26 @@ void DSPReset(void); void DSPHalt(void); void DSPUnhalt(void); u32 DSPGetDMAStatus(void); -DSPTaskInfo* DSPAddTask(DSPTaskInfo* task); -DSPTaskInfo* DSPCancelTask(DSPTaskInfo* task); -DSPTaskInfo* DSPAssertTask(DSPTaskInfo* task); +DSPTaskInfo *DSPAddTask(DSPTaskInfo *task); +DSPTaskInfo *DSPCancelTask(DSPTaskInfo *task); +DSPTaskInfo *DSPAssertTask(DSPTaskInfo *task); -DSPTaskInfo* __DSPGetCurrentTask(void); +DSPTaskInfo *__DSPGetCurrentTask(void); + +extern DSPTaskInfo *__DSP_curr_task; +extern DSPTaskInfo *__DSP_last_task; +extern DSPTaskInfo *__DSP_first_task; + +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 +#endif // _DOLPHIN_DSP \ No newline at end of file diff --git a/include/dolphin/dvd.h b/include/dolphin/dvd.h index 4bbe3190e..0774f0459 100644 --- a/include/dolphin/dvd.h +++ b/include/dolphin/dvd.h @@ -1,237 +1,18 @@ -#ifndef _DOLPHIN_DVD_H_ -#define _DOLPHIN_DVD_H_ - -#include +#ifndef _DOLPHIN_PUBLIC_DVD_H +#define _DOLPHIN_PUBLIC_DVD_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -// needed for matching release -#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) - -#define DVD_ASSERTMSG2LINE(line, cond, msg, arg1, arg2) \ - if (!(cond)) \ - OSPanic(__FILE__, line, msg, arg1, arg2) - -#define DVD_RESULT_GOOD 0 -#define DVD_RESULT_FATAL_ERROR -1 -#define DVD_RESULT_IGNORED -2 -#define DVD_RESULT_CANCELED -6 - -#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 { - char gameName[4]; - char company[2]; - u8 diskNumber; - u8 gameVersion; - u8 streaming; - u8 streamingBufSize; - u8 padding[22]; -} DVDDiskID; - -typedef struct DVDCommandBlock DVDCommandBlock; -typedef void (*DVDCBCallback)(s32 result, DVDCommandBlock* block); -typedef void (*DVDLowCallback)(u32); - -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* addr; - /* 0x1C */ u32 currTransferSize; - /* 0x20 */ u32 transferredSize; - /* 0x24 */ DVDDiskID* id; - /* 0x28 */ DVDCBCallback callback; - /* 0x2C */ void* userData; -}; - -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; -}; - -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 revisionLevel; - /* 0x02 */ u16 deviceCode; - /* 0x04 */ u32 releaseDate; - /* 0x08 */ u8 padding[24]; -} DVDDriveInfo; - -// DVD -void DVDInit(void); -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); -int DVDCancelAsync(DVDCommandBlock* block, DVDCBCallback callback); -s32 DVDCancel(volatile DVDCommandBlock* block); -int DVDCancelAllAsync(DVDCBCallback callback); -s32 DVDCancelAll(void); -DVDDiskID* DVDGetCurrentDiskID(void); -BOOL DVDCheckDisk(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); +#include +#include +#include +#include #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_PUBLIC_DVD_H \ No newline at end of file diff --git a/include/dolphin/dvd/dvd.h b/include/dolphin/dvd/dvd.h new file mode 100644 index 000000000..2a0adc52e --- /dev/null +++ b/include/dolphin/dvd/dvd.h @@ -0,0 +1,169 @@ +#ifndef _DOLPHIN_DVD_H +#define _DOLPHIN_DVD_H + +#include "types.h" +#include + +#define DVD_MIN_TRANSFER_SIZE 32 + +#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_FILEINFO_READY 0 +#define DVD_FILEINFO_BUSY 1 + +#define DVD_RESULT_GOOD 0 +#define DVD_RESULT_FATAL_ERROR -1 +#define DVD_RESULT_IGNORED -2 +#define DVD_RESULT_CANCELED -3 + +#define DVD_AIS_SUCCESS 0x0 + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct DVDDiskID +{ + char gameName[4]; + char company[2]; + u8 diskNumber; + u8 gameVersion; + u8 streaming; + u8 streamingBufSize; // 0 = default + u8 padding[22]; // 0's are stored +} DVDDiskID; + +typedef struct DVDCommandBlock DVDCommandBlock; + +typedef void (*DVDCBCallback)(s32 result, DVDCommandBlock *block); + +struct DVDCommandBlock +{ + DVDCommandBlock *next; + DVDCommandBlock *prev; + u32 command; + s32 state; + u32 offset; + u32 length; + void *addr; + u32 currTransferSize; + u32 transferredSize; + DVDDiskID *id; + DVDCBCallback callback; + void *userData; +}; + +typedef struct DVDFileInfo DVDFileInfo; + +typedef void (*DVDCallback)(s32 result, DVDFileInfo *fileInfo); + +struct DVDFileInfo +{ + DVDCommandBlock cb; + u32 startAddr; + u32 length; + DVDCallback callback; +}; + +typedef struct +{ + u32 entryNum; + u32 location; + u32 next; +} DVDDir; + +typedef struct +{ + u32 entryNum; + BOOL isDir; + char *name; +} DVDDirEntry; + +typedef struct DVDDriveInfo +{ + u16 revisionLevel; + u16 deviceCode; + u32 releaseDate; + u8 padding[24]; +} DVDDriveInfo; + +void DVDInit(); +BOOL DVDClose(DVDFileInfo *f); +BOOL DVDSetAutoFatalMessaging(BOOL); +BOOL DVDSetAutoInvalidation(BOOL autoInval); +void DVDPause(); +void DVDReset(); +void DVDResume(); +s32 DVDCancel(DVDCommandBlock *block); + +BOOL DVDFastOpen(s32 entrynum, DVDFileInfo *fileInfo); +s32 DVDGetCommandBlockStatus(const DVDCommandBlock *block); +BOOL DVDCancelAsync(DVDCommandBlock *block, DVDCBCallback callback); +s32 DVDCancel(DVDCommandBlock *block); +BOOL DVDCancelAllAsync(DVDCBCallback callback); +s32 DVDCancelAll(); +BOOL DVDPrepareStreamAsync(DVDFileInfo *fInfo, u32 length, u32 offset, DVDCallback callback); + +BOOL DVDPrepareStreamAbsAsync(DVDCommandBlock *block, u32 length, u32 offset, + DVDCBCallback callback); +s32 DVDPrepareStream(DVDFileInfo *fInfo, u32 length, u32 offset); + +BOOL DVDCancelStreamAsync(DVDCommandBlock *block, DVDCBCallback callback); +s32 DVDCancelStream(DVDCommandBlock *block); + +BOOL DVDStopStreamAtEndAsync(DVDCommandBlock *block, DVDCBCallback callback); +s32 DVDStopStreamAtEnd(DVDCommandBlock *block); + +BOOL DVDGetStreamErrorStatusAsync(DVDCommandBlock *block, DVDCBCallback callback); +s32 DVDGetStreamErrorStatus(DVDCommandBlock *block); + +BOOL DVDGetStreamPlayAddrAsync(DVDCommandBlock *block, DVDCBCallback callback); +s32 DVDGetStreamPlayAddr(DVDCommandBlock *block); + +BOOL DVDInquiryAsync(DVDCommandBlock *block, DVDDriveInfo *info, DVDCBCallback callback); + +BOOL DVDReadDiskID(DVDCommandBlock *block, DVDDiskID *diskID, DVDCBCallback callback); + +s32 DVDGetDriveStatus(); +DVDDiskID *DVDGetCurrentDiskID(); +int DVDCheckDisk(); + +BOOL DVDReadAsyncPrio(DVDFileInfo *fileInfo, void *addr, s32 length, s32 offset, + DVDCallback callback, s32 prio); + +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 __DVDTestAlarm(OSAlarm *alarm); +void __DVDPrepareResetAsync(DVDCBCallback callback); + +#define DVDReadAsync(fileInfo, addr, length, offset, callback) \ + DVDReadAsyncPrio((fileInfo), (addr), (length), (offset), (callback), 2) +#define DVDSeekAsync(fileInfo, offset, callback) \ + DVDSeekAsyncPrio((fileInfo), (offset), (callback), 2) + +BOOL DVDCompareDiskID(DVDDiskID *id1, DVDDiskID *id2); +void __DVDStoreErrorCode(u32 error); +void __DVDPrintFatalMessage(); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_DVD \ No newline at end of file diff --git a/include/dolphin/dvd/dvdfs.h b/include/dolphin/dvd/dvdfs.h new file mode 100644 index 000000000..9a18215b4 --- /dev/null +++ b/include/dolphin/dvd/dvdfs.h @@ -0,0 +1,49 @@ +#ifndef _DOLPHIN_DVDFS_H +#define _DOLPHIN_DVDFS_H + +#include + +#ifdef __cplusplus +extern "C" +{ +// clang-format off +#endif + +// TODO + + +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(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); + +BOOL DVDSeekAsyncPrio(DVDFileInfo *fileInfo, s32 offset, DVDCallback callback, s32 prio); +s32 DVDSeekPrio(DVDFileInfo *fileInfo, s32 offset, s32 prio); + +s32 DVDGetFileInfoStatus(DVDFileInfo *fileInfo); +BOOL DVDFastOpenDir(s32 entrynum, DVDDir *dir); +BOOL DVDOpenDir(char *dirName, DVDDir *dir); +BOOL DVDReadDir(DVDDir *dir, DVDDirEntry *dirent); +BOOL DVDCloseDir(DVDDir *dir); +void DVDRewindDir(DVDDir *dir); +void *DVDGetFSTLocation(); + +BOOL DVDPrepareStreamAsync(DVDFileInfo *fileInfo, u32 length, u32 offset, DVDCallback callback); +s32 DVDPrepareStream(DVDFileInfo *fileInfo, u32 length, u32 offset); + +s32 DVDGetTransferredSize(DVDFileInfo *fileinfo); + +extern OSThreadQueue __DVDThreadQueue; + +#ifdef __cplusplus +} +// clang-format on +#endif + +#endif \ No newline at end of file diff --git a/include/dolphin/dvd/dvdlow.h b/include/dolphin/dvd/dvdlow.h new file mode 100644 index 000000000..ab3d05e0a --- /dev/null +++ b/include/dolphin/dvd/dvdlow.h @@ -0,0 +1,41 @@ +#ifndef _DOLPHIN_DVDLOW_H +#define _DOLPHIN_DVDLOW_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +// clang-format off +#endif + +typedef void (*DVDLowCallback)(u32 intType); + +void __DVDInitWA(); +void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext *context); + +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(); + +DVDLowCallback DVDLowClearCallback(); + +void __DVDLowSetWAType(u32 type, u32 location); +BOOL __DVDLowTestAlarm(OSAlarm *alarm); + +#ifdef __cplusplus +} +// clang-format on +#endif + +#endif \ No newline at end of file diff --git a/include/dolphin/dvd/dvdqueue.h b/include/dolphin/dvd/dvdqueue.h new file mode 100644 index 000000000..2f1b3ceab --- /dev/null +++ b/include/dolphin/dvd/dvdqueue.h @@ -0,0 +1,28 @@ +#ifndef _DOLPHIN_DVDQUEUE_H +#define _DOLPHIN_DVDQUEUE_H + +#include + +#ifdef __cplusplus +extern "C" +{ +// clang-format off +#endif + +typedef void (*DVDOptionalCommandChecker)(DVDCommandBlock* block, void (*cb)(u32 intType)); + +void __DVDClearWaitingQueue(); +BOOL __DVDPushWaitingQueue(s32 prio, DVDCommandBlock *block); +DVDCommandBlock *__DVDPopWaitingQueue(); +BOOL __DVDCheckWaitingQueue(); +BOOL __DVDDequeueWaitingQueue(DVDCommandBlock *block); +BOOL __DVDIsBlockInWaitingQueue(DVDCommandBlock *block); + +DVDCommandBlock* __DVDPopWaitingQueue(); + +#ifdef __cplusplus +} +// clang-format on +#endif + +#endif \ No newline at end of file diff --git a/include/dolphin/eth/eth.h b/include/dolphin/eth/eth.h new file mode 100644 index 000000000..6411d51d8 --- /dev/null +++ b/include/dolphin/eth/eth.h @@ -0,0 +1,72 @@ +#ifndef _DOLPHIN_OS_ETH_H_ +#define _DOLPHIN_OS_ETH_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define ME_NCRA_TXFIFO (1 << 2) + +#define ETH_OK 1 + +#define ETH_TYPE_AUTO 0 +#define ETH_TYPE_100FULL 1 +#define ETH_TYPE_100HALF 2 +#define ETH_TYPE_10FULL 3 +#define ETH_TYPE_10HALF 4 +#define ETH_TYPE_NONE 5 + +typedef struct ETHHeader { + u8 dst[6]; + u8 src[6]; + u16 type; +} ETHHeader; + +typedef struct ETHStat { + u32 rcvcount; + u32 sendcount; + u16 cntof; + u16 re; + u16 te; + u16 fifoe; + u16 rbf; + u16 rx_bf; + u16 rx_crc; + u16 rx_fae; + u16 rx_fo; + u16 rx_rw; + u16 rx_rf; + u16 tx_crs; + u16 tx_uf; + u16 tx_owc; +} ETHStat; + +s32 ETHInit(s32 mode); +void ETHSendAsync(void* addr, s32 length, void (*callback2)(u8)); +void ETHGetMACAddr(u8* macaddr); +void ETHSetMACAddr(u8* macaddr); +void ETHSetRecvCallback(void* (*cb0)(u16, s32, u8), void (*cb1)(u8*, s32)); +BOOL ETHGetLinkStateAsync(BOOL* status); +s32 ETHGetNWAYMode(void); +void ETHSetProtoType(u16* array, s32 num); +void ETHGetStatus(ETHStat* stat); +s32 ETHGetLibraryVersion(void); +s32 ETHGetBBAType(void); +void ETHAddMulticastAddress(const u8* macaddr); +void ETHChangeIntPriority(BOOL flag); +u32 ETHGetREVID(void); +void ETHClearMulticastAddresses(void); + +BOOL __ETHPostSend(u8, void (*)(u8), void*); +BOOL __ETHFilter(u8 *, s32); + +extern OSTime __ETHInterruptTime; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/eth/hashfunc.c b/include/dolphin/eth/hashfunc.c new file mode 100644 index 000000000..250924746 --- /dev/null +++ b/include/dolphin/eth/hashfunc.c @@ -0,0 +1,20 @@ +#include + +static u32 hashfunc(u32 seccode) { + u8 p; + u8 q; + u8 r; + u8 s; + u8 a[sizeof(seccode)]; + u8 dev[sizeof(__devid)]; + + memcpy(a, &seccode, sizeof(seccode)); + memcpy(dev, &__devid, sizeof(__devid)); + + p = (a[0] + a[1] * 0xC1 + 0x18 + __revid) ^ (a[3] * a[2] + 0x90); + q = (a[1] + a[2] + 0x90) ^ (p - 0xC1 + a[0]); + r = (a[2] + 0xC8) ^ (p + ((dev[0] + __revid * 0x23) ^ 0x19)); + s = (a[0] + 0xC1) ^ (a[3] + ((dev[1] + 0xC8) ^ 0x90)); + + return (p << 24) | (q << 16) | (r << 8) | s; +} diff --git a/include/dolphin/exi.h b/include/dolphin/exi.h index f094c3613..47ab75d9a 100644 --- a/include/dolphin/exi.h +++ b/include/dolphin/exi.h @@ -1,78 +1,9 @@ #ifndef _DOLPHIN_EXI_H_ #define _DOLPHIN_EXI_H_ -#include +#include -#ifdef __cplusplus -extern "C" { -#endif - -#define EXI_MEMORY_CARD_59 0x00000004 -#define EXI_MEMORY_CARD_123 0x00000008 -#define EXI_MEMORY_CARD_251 0x00000010 -#define EXI_MEMORY_CARD_507 0x00000020 - -#define EXI_MEMORY_CARD_1019 0x00000040 -#define EXI_MEMORY_CARD_2043 0x00000080 - -#define EXI_MEMORY_CARD_1019A 0x00000140 -#define EXI_MEMORY_CARD_1019B 0x00000240 -#define EXI_MEMORY_CARD_1019C 0x00000340 -#define EXI_MEMORY_CARD_1019D 0x00000440 -#define EXI_MEMORY_CARD_1019E 0x00000540 -#define EXI_MEMORY_CARD_1019F 0x00000640 -#define EXI_MEMORY_CARD_1019G 0x00000740 - -#define EXI_MEMORY_CARD_2043A 0x00000180 -#define EXI_MEMORY_CARD_2043B 0x00000280 -#define EXI_MEMORY_CARD_2043C 0x00000380 -#define EXI_MEMORY_CARD_2043D 0x00000480 -#define EXI_MEMORY_CARD_2043E 0x00000580 -#define EXI_MEMORY_CARD_2043F 0x00000680 -#define EXI_MEMORY_CARD_2043G 0x00000780 - -#define EXI_USB_ADAPTER 0x01010000 -#define EXI_NPDP_GDEV 0x01020000 - -#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 - -#define EXI_MARLIN 0x03010000 - -#define EXI_IS_VIEWER 0x05070000 - -#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 - -typedef void (*EXICallback)(s32 chan, OSContext* context); -typedef struct EXIControl { - EXICallback exiCallback; - EXICallback tcCallback; - EXICallback extCallback; - volatile u32 state; - int immLen; - u8* immBuf; - u32 dev; - u32 id; - s32 idTime; - int items; - struct { - u32 dev; - EXICallback callback; - } queue[3]; -} EXIControl; +typedef void (*EXICallback)(s32 chan, OSContext *context); EXICallback EXISetExiCallback(s32 channel, EXICallback callback); @@ -81,9 +12,9 @@ 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 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); @@ -92,12 +23,5 @@ 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 diff --git a/include/dolphin/gd.h b/include/dolphin/gd.h index 57c929dad..4fcfdcdca 100644 --- a/include/dolphin/gd.h +++ b/include/dolphin/gd.h @@ -1,14 +1,92 @@ -#ifndef _DOLPHIN_GD_H_ -#define _DOLPHIN_GD_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include +#ifndef _DOLPHIN_GD_H +#define _DOLPHIN_GD_H + +#include "dolphin/gx.h" +#include "types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif // ifdef __cplusplus + + //////////////// GD TYPES ////////////////// + // Overflow callback function type. + typedef void (*GDOverflowCallback)(void); + + // Struct for data download (size 0x10). + typedef struct GDCurrentDL + { + u8 *begin; // _00 + s32 length; // _04 + u8 *pDisplayListData; // _08 + u8 *end; // _0C + } GDCurrentDL; + + //////////////////////////////////////////// + + ////////////// GD FUNCTIONS //////////////// + // GD base functions. + void GDInitGDLObj(GDCurrentDL *obj, u8 *start, s32 len); + void GDFlushCurrToMem(); + void GDPadCurr32(); + void GDOverflowed(void); + + // GD geometry functions. + void GDSetVtxDescv(GXVtxDescList *list); + void GDSetArray(GXAttr attr, const void *data, u8 stride); + void GDSetArrayRaw(GXAttr attr, u32 data, u8 stride); + + //////////////////////////////////////////// + + ///////////// GD DECLARATIONS ////////////// + + extern GDCurrentDL *__GDCurrentDL; + extern GDOverflowCallback overflowcb; + + //////////////////////////////////////////// + + /////////// GD HELPER FUNCTIONS //////////// + + static inline void __GDWrite(u8 data) { *__GDCurrentDL->pDisplayListData++ = data; } + + static inline void __GDCheckOverflowed(size_t size) + { + if (__GDCurrentDL->pDisplayListData + size > __GDCurrentDL->end) + { + GDOverflowed(); + } + } + + static inline void __GDSetCurrent(GDCurrentDL *obj) { __GDCurrentDL = obj; } + + static inline void __GDWriteU32(u32 data) + { + __GDWrite((data >> 24) & 0xFF); + __GDWrite((data >> 16) & 0xFF); + __GDWrite((data >> 8) & 0xFF); + __GDWrite((data >> 0) & 0xFF); + } + + static inline void __GDWriteU16(u16 data) + { + __GDWrite((data >> 8) & 0xFF); + __GDWrite((data >> 0) & 0xFF); + } + + static inline void __GDWriteU8(u8 data) { __GDWrite((data >> 0) & 0xFF); } + + static inline void __GDWriteF32(f32 data) + { + __GDWrite(((u8 *)&data)[0]); + __GDWrite(((u8 *)&data)[1]); + __GDWrite(((u8 *)&data)[2]); + __GDWrite(((u8 *)&data)[3]); + } + + //////////////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus #endif diff --git a/include/dolphin/gx.h b/include/dolphin/gx.h index 0e90e543e..b822fb6a6 100644 --- a/include/dolphin/gx.h +++ b/include/dolphin/gx.h @@ -1,40 +1,26 @@ -#ifndef _DOLPHIN_GX_H_ -#define _DOLPHIN_GX_H_ +#ifndef _DOLPHIN_GX +#define _DOLPHIN_GX +#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 #include -#include -#include - -// unsorted GX externs - -#ifdef __cplusplus -extern "C" { -#endif - -// GXMisc -void (*GXSetDrawSyncCallback(void (*cb)(u16)))(u16); -void GXSetDrawSync(u16 token); - -#ifdef __cplusplus -} -#endif +#include +#include +#include +#include +#include -#endif +#endif // _DOLPHIN_GX diff --git a/include/dolphin/gx/GXBump.h b/include/dolphin/gx/GXBump.h index 2a24dc69f..88c7cfba6 100644 --- a/include/dolphin/gx/GXBump.h +++ b/include/dolphin/gx/GXBump.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_GX_GXBUMP_H_ -#define _DOLPHIN_GX_GXBUMP_H_ +#ifndef _DOLPHIN_GXBUMP +#define _DOLPHIN_GXBUMP #include @@ -7,23 +7,20 @@ extern "C" { #endif -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); +void GXSetNumIndStages(u8 nIndStages); +void GXSetIndTexMtx(GXIndTexMtxID mtx_sel, const f32 offset[2][3], s8 scale_exp); +void GXSetIndTexOrder(GXIndTexStageID ind_stage, GXTexCoordID tex_coord, GXTexMapID tex_map); +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 ind_lod, + GXIndTexAlphaSel alpha_sel); +void GXSetTevIndWarp(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXBool signed_offsets, + GXBool replace_mode, GXIndTexMtxID matrix_sel); +void GXSetIndTexCoordScale(GXIndTexStageID ind_state, GXIndTexScale scale_s, GXIndTexScale scale_t); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXBUMP diff --git a/include/dolphin/gx/GXCommandList.h b/include/dolphin/gx/GXCommandList.h index 9adae3cb7..cf3a5172e 100644 --- a/include/dolphin/gx/GXCommandList.h +++ b/include/dolphin/gx/GXCommandList.h @@ -1,37 +1,35 @@ -#ifndef _DOLPHIN_GX_GXCOMMANDLIST_H_ -#define _DOLPHIN_GX_GXCOMMANDLIST_H_ +#ifndef _DOLPHIN_GXCOMMANDLIST +#define _DOLPHIN_GXCOMMANDLIST -#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 +#ifdef __cplusplus +extern "C" { +#endif -#define GX_DRAW_QUADS 0x80 -#define GX_DRAW_TRIANGLES 0x90 +#define GX_NOP 0x00 +#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_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_LOAD_BP_REG 0x61 +#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_OPCODE_MASK 0xF8 -#define GX_VAT_MASK 0x07 +#define GX_CMD_CALL_DL 0x40 +#define GX_CMD_INVL_VC 0x48 -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]; +#define GX_OPCODE_MASK 0xF8 +#define GX_VAT_MASK 0x07 +#ifdef __cplusplus +} #endif + +#endif // _DOLPHIN_GXCOMMANDLIST diff --git a/include/dolphin/gx/GXCull.h b/include/dolphin/gx/GXCull.h index cac438181..b2526e523 100644 --- a/include/dolphin/gx/GXCull.h +++ b/include/dolphin/gx/GXCull.h @@ -1,13 +1,12 @@ -#ifndef _DOLPHIN_GX_GXCULL_H_ -#define _DOLPHIN_GX_GXCULL_H_ +#ifndef _DOLPHIN_GXCULL +#define _DOLPHIN_GXCULL -#include +#include #ifdef __cplusplus extern "C" { #endif -void GXSetScissor(u32 left, u32 top, u32 wd, u32 ht); void GXSetCullMode(GXCullMode mode); void GXSetCoPlanar(GXBool enable); @@ -15,4 +14,4 @@ void GXSetCoPlanar(GXBool enable); } #endif -#endif +#endif // _DOLPHIN_GXCULL diff --git a/include/dolphin/gx/GXDispList.h b/include/dolphin/gx/GXDispList.h index 357fb8f7e..552eda2db 100644 --- a/include/dolphin/gx/GXDispList.h +++ b/include/dolphin/gx/GXDispList.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_GX_GXDISPLIST_H_ -#define _DOLPHIN_GX_GXDISPLIST_H_ +#ifndef _DOLPHIN_GXDISPLIST +#define _DOLPHIN_GXDISPLIST #include @@ -9,10 +9,10 @@ extern "C" { void GXBeginDisplayList(void* list, u32 size); u32 GXEndDisplayList(void); -void GXCallDisplayList(void* list, u32 nbytes); +void GXCallDisplayList(const void* list, u32 nbytes); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXDISPLIST diff --git a/include/dolphin/gx/GXDraw.h b/include/dolphin/gx/GXDraw.h index c8e779345..542460be1 100644 --- a/include/dolphin/gx/GXDraw.h +++ b/include/dolphin/gx/GXDraw.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_GX_GXDRAW_H_ -#define _DOLPHIN_GX_GXDRAW_H_ +#ifndef _DOLPHIN_GXDRAW +#define _DOLPHIN_GXDRAW #include @@ -7,18 +7,12 @@ 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); +void GXDrawCylinder(u8 numEdges); +void GXDrawCube(); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXDRAW diff --git a/include/dolphin/gx/GXEnum.h b/include/dolphin/gx/GXEnum.h index db4ea87d2..e69c621b7 100644 --- a/include/dolphin/gx/GXEnum.h +++ b/include/dolphin/gx/GXEnum.h @@ -1,8 +1,12 @@ -#ifndef _DOLPHIN_GX_GXENUM_H_ -#define _DOLPHIN_GX_GXENUM_H_ +#ifndef _DOLPHIN_GXENUM +#define _DOLPHIN_GXENUM #include +#ifdef __cplusplus +extern "C" { +#endif + typedef u8 GXBool; #define GX_FALSE ((GXBool)0) @@ -12,889 +16,890 @@ typedef u8 GXBool; #define GX_DISABLE ((GXBool)0) typedef enum _GXProjectionType { - GX_PERSPECTIVE, - GX_ORTHOGRAPHIC, + GX_PERSPECTIVE, + GX_ORTHOGRAPHIC, } GXProjectionType; typedef enum _GXCompare { - GX_NEVER, - GX_LESS, - GX_EQUAL, - GX_LEQUAL, - GX_GREATER, - GX_NEQUAL, - GX_GEQUAL, - GX_ALWAYS, + GX_NEVER, + GX_LESS, + GX_EQUAL, + GX_LEQUAL, + GX_GREATER, + GX_NEQUAL, + GX_GEQUAL, + GX_ALWAYS, } GXCompare; typedef enum _GXAlphaOp { - GX_AOP_AND, - GX_AOP_OR, - GX_AOP_XOR, - GX_AOP_XNOR, - GX_MAX_ALPHAOP, + GX_AOP_AND, + GX_AOP_OR, + GX_AOP_XOR, + GX_AOP_XNOR, + GX_MAX_ALPHAOP, } GXAlphaOp; +typedef enum _GXFBClamp { + GX_CLAMP_NONE, + GX_CLAMP_TOP, + GX_CLAMP_BOTTOM, +} GXFBClamp; + typedef enum _GXZFmt16 { - GX_ZC_LINEAR, - GX_ZC_NEAR, - GX_ZC_MID, - GX_ZC_FAR, + GX_ZC_LINEAR, + GX_ZC_NEAR, + GX_ZC_MID, + GX_ZC_FAR, } GXZFmt16; typedef enum _GXGamma { - GX_GM_1_0, - GX_GM_1_7, - GX_GM_2_2, + GX_GM_1_0, + GX_GM_1_7, + GX_GM_2_2, } GXGamma; 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, + 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; typedef enum _GXPrimitive { - GX_QUADS = 0x80, - GX_TRIANGLES = 0x90, - GX_TRIANGLESTRIP = 0x98, - GX_TRIANGLEFAN = 0xA0, - GX_LINES = 0xA8, - GX_LINESTRIP = 0xB0, - GX_POINTS = 0xB8, + GX_QUADS = 0x80, + GX_TRIANGLES = 0x90, + GX_TRIANGLESTRIP = 0x98, + GX_TRIANGLEFAN = 0xA0, + GX_LINES = 0xA8, + GX_LINESTRIP = 0xB0, + GX_POINTS = 0xB8, } GXPrimitive; typedef enum _GXVtxFmt { - GX_VTXFMT0, - GX_VTXFMT1, - GX_VTXFMT2, - GX_VTXFMT3, - GX_VTXFMT4, - GX_VTXFMT5, - GX_VTXFMT6, - GX_VTXFMT7, - GX_MAX_VTXFMT, + GX_VTXFMT0, + GX_VTXFMT1, + GX_VTXFMT2, + GX_VTXFMT3, + GX_VTXFMT4, + GX_VTXFMT5, + GX_VTXFMT6, + GX_VTXFMT7, + GX_MAX_VTXFMT, } GXVtxFmt; 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, + 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; +#define GX_MAX_VTXDESCLIST_SZ (GX_VA_MAX_ATTR + 1) + typedef enum _GXAttrType { - GX_NONE, - GX_DIRECT, - GX_INDEX8, - GX_INDEX16, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + GX_MODULATE, + GX_DECAL, + GX_BLEND, + GX_REPLACE, + GX_PASSCLR, } GXTevMode; typedef enum _GXTexMtxType { - GX_MTX3x4, - GX_MTX2x4, + GX_MTX3x4, + GX_MTX2x4, } GXTexMtxType; typedef enum _GXTexGenType { - 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, + 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 _GXPosNrmMtx { - 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, + 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, - 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, + 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, + 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, + 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, + GX_MAX_TEXGENSRC, } GXTexGenSrc; typedef enum _GXBlendMode { - GX_BM_NONE, - GX_BM_BLEND, - GX_BM_LOGIC, - GX_BM_SUBTRACT, - GX_MAX_BLENDMODE, + 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, + 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, + 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, + 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, + 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, - 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, + 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 _GXTevRegID { - GX_TEVPREV, - GX_TEVREG0, - GX_TEVREG1, - GX_TEVREG2, - GX_MAX_TEVREG, + GX_TEVPREV, + GX_TEVREG0, + GX_TEVREG1, + GX_TEVREG2, + GX_MAX_TEVREG, } GXTevRegID; typedef enum _GXDiffuseFn { - GX_DF_NONE, - GX_DF_SIGN, - GX_DF_CLAMP, + GX_DF_NONE, + GX_DF_SIGN, + GX_DF_CLAMP, } GXDiffuseFn; typedef enum _GXColorSrc { - GX_SRC_REG, - GX_SRC_VTX, + GX_SRC_REG, + GX_SRC_VTX, } GXColorSrc; typedef enum _GXAttnFn { - GX_AF_SPEC, - GX_AF_SPOT, - GX_AF_NONE, + 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, + 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, + 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, + 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, + 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 + 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 + 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 + 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, + 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 = GX_FOG_PERSP_LIN, + GX_FOG_EXP = GX_FOG_PERSP_EXP, + GX_FOG_EXP2 = GX_FOG_PERSP_EXP2, + GX_FOG_REVEXP = GX_FOG_PERSP_REVEXP, + GX_FOG_REVEXP2 = GX_FOG_PERSP_REVEXP2, } 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, + GX_CC_CPREV, + GX_CC_APREV, + GX_CC_C0, + GX_CC_A0, + GX_CC_C1, + GX_CC_A1, + GX_CC_C2, + GX_CC_A2, + GX_CC_TEXC, + GX_CC_TEXA, + GX_CC_RASC, + GX_CC_RASA, + GX_CC_ONE, + GX_CC_HALF, + GX_CC_KONST, + GX_CC_ZERO, } 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, + GX_CA_APREV, + GX_CA_A0, + GX_CA_A1, + GX_CA_A2, + GX_CA_TEXA, + GX_CA_RASA, + GX_CA_KONST, + GX_CA_ZERO, } 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 + 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 + 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 + 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 + GX_TEV_KCSEL_8_8 = 0x00, + GX_TEV_KCSEL_7_8 = 0x01, + GX_TEV_KCSEL_6_8 = 0x02, + GX_TEV_KCSEL_5_8 = 0x03, + GX_TEV_KCSEL_4_8 = 0x04, + GX_TEV_KCSEL_3_8 = 0x05, + GX_TEV_KCSEL_2_8 = 0x06, + GX_TEV_KCSEL_1_8 = 0x07, + GX_TEV_KCSEL_1 = GX_TEV_KCSEL_8_8, + GX_TEV_KCSEL_3_4 = GX_TEV_KCSEL_6_8, + GX_TEV_KCSEL_1_2 = GX_TEV_KCSEL_4_8, + GX_TEV_KCSEL_1_4 = GX_TEV_KCSEL_2_8, + 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 + GX_TEV_KASEL_8_8 = 0x00, + GX_TEV_KASEL_7_8 = 0x01, + GX_TEV_KASEL_6_8 = 0x02, + GX_TEV_KASEL_5_8 = 0x03, + GX_TEV_KASEL_4_8 = 0x04, + GX_TEV_KASEL_3_8 = 0x05, + GX_TEV_KASEL_2_8 = 0x06, + GX_TEV_KASEL_1_8 = 0x07, + GX_TEV_KASEL_1 = GX_TEV_KASEL_8_8, + GX_TEV_KASEL_3_4 = GX_TEV_KASEL_6_8, + GX_TEV_KASEL_1_2 = GX_TEV_KASEL_4_8, + GX_TEV_KASEL_1_4 = GX_TEV_KASEL_2_8, + 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 + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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 _GXPerf0 { - 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, - 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, - 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, - GX_PERF0_NONE, -} GXPerf0; - -typedef enum _GXPerf1 { - 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, - 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, - GX_PERF1_CALL_REQ, - GX_PERF1_VC_MISS_REQ, - GX_PERF1_CP_ALL_REQ, - - GX_PERF1_CLOCKS, - GX_PERF1_NONE, -} GXPerf1; - -typedef enum _GXVCachePerf { - GX_VC_POS = 0, - GX_VC_NRM = 1, - GX_VC_CLR0 = 2, - GX_VC_CLR1 = 3, - GX_VC_TEX0 = 4, - GX_VC_TEX1 = 5, - GX_VC_TEX2 = 6, - GX_VC_TEX3 = 7, - GX_VC_TEX4 = 8, - GX_VC_TEX5 = 9, - GX_VC_TEX6 = 10, - GX_VC_TEX7 = 11, - GX_VC_ALL = 15, -} GXVCachePerf; - typedef enum _GXClipMode { - GX_CLIP_ENABLE = 0, - GX_CLIP_DISABLE = 1, + GX_CLIP_ENABLE = 0, + GX_CLIP_DISABLE = 1, } GXClipMode; -typedef enum _GXFBClamp { - GX_CLAMP_NONE = 0, - GX_CLAMP_TOP = 1, - GX_CLAMP_BOTTOM = 2, -} GXFBClamp; - -typedef enum _GXCopyMode { - GX_COPY_PROGRESSIVE = 0, - GX_COPY_INTLC_EVEN = 2, - GX_COPY_INTLC_ODD = 3, -} GXCopyMode; - -typedef enum _GXAlphaReadMode { - GX_READ_00, - GX_READ_FF, - GX_READ_NONE, -} GXAlphaReadMode; - -typedef enum _GXTexCacheSize { - GX_TEXCACHE_32K, - GX_TEXCACHE_128K, - GX_TEXCACHE_512K, - GX_TEXCACHE_NONE, -} GXTexCacheSize; - 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, + GX_TLUT0 = 0, + GX_TLUT1 = 1, + GX_TLUT2 = 2, + GX_TLUT3 = 3, + GX_TLUT4 = 4, + GX_TLUT5 = 5, + GX_TLUT6 = 6, + GX_TLUT7 = 7, + GX_TLUT8 = 8, + GX_TLUT9 = 9, + GX_TLUT10 = 10, + GX_TLUT11 = 11, + GX_TLUT12 = 12, + GX_TLUT13 = 13, + GX_TLUT14 = 14, + GX_TLUT15 = 15, + GX_BIGTLUT0 = 16, + GX_BIGTLUT1 = 17, + GX_BIGTLUT2 = 18, + GX_BIGTLUT3 = 19, } GXTlut; typedef enum _GXTlutFmt { - GX_TL_IA8, - GX_TL_RGB565, - GX_TL_RGB5A3, - GX_MAX_TLUTFMT, + GX_TL_IA8, + GX_TL_RGB565, + GX_TL_RGB5A3, + GX_MAX_TLUTFMT, } GXTlutFmt; 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, + 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; typedef enum _GXMiscToken { - GX_MT_XF_FLUSH = 1, - GX_MT_DL_SAVE_CONTEXT = 2, - GX_MT_ABORT_WAIT_COPYOUT = 3, - GX_MT_NULL = 0, + GX_MT_NULL = 0, + GX_MT_XF_FLUSH = 1, + GX_MT_DL_SAVE_CONTEXT = 2, + GX_MT_ABORT_WAIT_COPYOUT = 3, } GXMiscToken; +typedef enum _GXTexCacheSize { + GX_TEXCACHE_32K, + GX_TEXCACHE_128K, + GX_TEXCACHE_512K, + GX_TEXCACHE_NONE +} GXTexCacheSize; + +typedef enum _GXPerf0 { + 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, + 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, + 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, + GX_PERF0_NONE + +} GXPerf0; + +typedef enum _GXPerf1 { + 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, + 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, + GX_PERF1_CALL_REQ, + GX_PERF1_VC_MISS_REQ, + GX_PERF1_CP_ALL_REQ, + + GX_PERF1_CLOCKS, + GX_PERF1_NONE + +} GXPerf1; + +typedef enum _GXVCachePerf { + GX_VC_POS, + GX_VC_NRM, + GX_VC_CLR0, + GX_VC_CLR1, + GX_VC_TEX0, + GX_VC_TEX1, + GX_VC_TEX2, + GX_VC_TEX3, + GX_VC_TEX4, + GX_VC_TEX5, + GX_VC_TEX6, + GX_VC_TEX7, + GX_VC_ALL = 0xf + +} GXVCachePerf; + +#ifdef __cplusplus +} #endif + +#endif // _DOLPHIN_GXENUM diff --git a/include/dolphin/gx/GXFifo.h b/include/dolphin/gx/GXFifo.h index 069f36a4e..85d61685b 100644 --- a/include/dolphin/gx/GXFifo.h +++ b/include/dolphin/gx/GXFifo.h @@ -1,46 +1,37 @@ -#ifndef _DOLPHIN_GX_GXFIFO_H_ -#define _DOLPHIN_GX_GXFIFO_H_ +#ifndef _DOLPHIN_GXFIFO +#define _DOLPHIN_GXFIFO #include -#include #ifdef __cplusplus extern "C" { #endif typedef struct { - u8 pad[128]; + u8 pad[128]; } GXFifoObj; typedef void (*GXBreakPtCallback)(void); void GXInitFifoBase(GXFifoObj* fifo, void* base, u32 size); void GXInitFifoPtrs(GXFifoObj* fifo, void* readPtr, void* writePtr); -void GXInitFifoLimits(GXFifoObj* fifo, u32 hiWatermark, u32 loWatermark); +void GXGetFifoPtrs(GXFifoObj* fifo, void** readPtr, void** writePtr); +GXFifoObj* GXGetCPUFifo(void); +GXFifoObj* GXGetGPFifo(void); void GXSetCPUFifo(GXFifoObj* fifo); void GXSetGPFifo(GXFifoObj* fifo); void GXSaveCPUFifo(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); +void GXGetFifoStatus(GXFifoObj* fifo, GXBool* overhi, GXBool* underlow, u32* fifoCount, + GXBool* cpu_write, GXBool* gp_read, GXBool* fifowrap); +void GXGetGPStatus(GXBool* overhi, GXBool* underlow, GXBool* readIdle, GXBool* cmdIdle, + GXBool* brkpt); +void GXInitFifoLimits(GXFifoObj* fifo, u32 hiWaterMark, u32 loWaterMark); GXBreakPtCallback GXSetBreakPtCallback(GXBreakPtCallback cb); -void GXEnableBreakPt(void* break_pt); +void GXEnableBreakPt(void* breakPt); 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 +#endif // _DOLPHIN_GXFIFO diff --git a/include/dolphin/gx/GXFrameBuffer.h b/include/dolphin/gx/GXFrameBuffer.h index 73b513fa3..2579fc00f 100644 --- a/include/dolphin/gx/GXFrameBuffer.h +++ b/include/dolphin/gx/GXFrameBuffer.h @@ -1,15 +1,13 @@ -#ifndef _DOLPHIN_GX_GXFRAMEBUFFER_H_ -#define _DOLPHIN_GX_GXFRAMEBUFFER_H_ +#ifndef _DOLPHIN_GXFRAMEBUFFER +#define _DOLPHIN_GXFRAMEBUFFER -#include #include +#include #ifdef __cplusplus extern "C" { #endif -#define GX_MAX_Z24 0x00ffffff - extern GXRenderModeObj GXNtsc240Ds; extern GXRenderModeObj GXNtsc240DsAa; extern GXRenderModeObj GXNtsc240Int; @@ -18,6 +16,7 @@ extern GXRenderModeObj GXNtsc480IntDf; extern GXRenderModeObj GXNtsc480Int; extern GXRenderModeObj GXNtsc480IntAa; extern GXRenderModeObj GXNtsc480Prog; +extern GXRenderModeObj GXNtsc480ProgSoft; extern GXRenderModeObj GXNtsc480ProgAa; extern GXRenderModeObj GXMpal240Ds; extern GXRenderModeObj GXMpal240DsAa; @@ -32,7 +31,7 @@ extern GXRenderModeObj GXPal264Int; extern GXRenderModeObj GXPal264IntAa; extern GXRenderModeObj GXPal528IntDf; extern GXRenderModeObj GXPal528Int; -extern GXRenderModeObj GXPal528IntAa; +extern GXRenderModeObj GXPal524IntAa; extern GXRenderModeObj GXEurgb60Hz240Ds; extern GXRenderModeObj GXEurgb60Hz240DsAa; extern GXRenderModeObj GXEurgb60Hz240Int; @@ -41,26 +40,27 @@ extern GXRenderModeObj GXEurgb60Hz480IntDf; extern GXRenderModeObj GXEurgb60Hz480Int; extern GXRenderModeObj GXEurgb60Hz480IntAa; -void GXAdjustForOverscan(const GXRenderModeObj* rmin, GXRenderModeObj* rmout, u16 hor, u16 ver); +#define GX_MAX_Z24 0x00FFFFFF + +void GXSetCopyClear(GXColor clear_clr, u32 clear_z); +void GXAdjustForOverscan(GXRenderModeObj* rmin, GXRenderModeObj* rmout, u16 hor, u16 ver); +void GXCopyDisp(void* dest, GXBool clear); +void GXSetDispCopyGamma(GXGamma gamma); 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); +f32 GXGetYScaleFactor(u16 efbHeight, u16 xfbHeight); 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); +void GXSetCopyFilter(GXBool aa, u8 sample_pattern[12][2], GXBool vf, u8 vfilter[7]); +void GXSetPixelFmt(GXPixelFmt pix_fmt, GXZFmt16 z_fmt); +void GXSetTexCopySrc(u16 left, u16 top, u16 wd, u16 ht); +void GXSetTexCopyDst(u16 wd, u16 ht, GXTexFmt fmt, GXBool mipmap); +void GXCopyTex(void* dest, GXBool clear); + +void GXSetCopyClamp(GXFBClamp clamp); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXFRAMEBUFFER diff --git a/include/dolphin/gx/GXGeometry.h b/include/dolphin/gx/GXGeometry.h index d9f47ba8d..870e7d2e9 100644 --- a/include/dolphin/gx/GXGeometry.h +++ b/include/dolphin/gx/GXGeometry.h @@ -1,63 +1,33 @@ -#ifndef _DOLPHIN_GX_GXGEOMETRY_H_ -#define _DOLPHIN_GX_GXGEOMETRY_H_ +#ifndef _DOLPHIN_GXGEOMETRY +#define _DOLPHIN_GXGEOMETRY #include -#include #ifdef __cplusplus extern "C" { #endif -void __GXCalculateVLim(); void GXSetVtxDesc(GXAttr attr, GXAttrType type); -void GXSetVtxDescv(const GXVtxDescList* attrPtr); +void GXSetVtxDescv(GXVtxDescList* list); 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 -} - -static inline void GXTexCoord2s16(int r3, int r4) // possible inline req. -{ - int ptr = 0xcc010000; - *(short*)((char*)(ptr) - 0x8000) = r3; - *(short*)((char*)(ptr) - 0x8000) = r4; -} - - -static inline void GXPosition3s16(int r3, int r4, int r5) // possible inline req. -{ - int ptr = 0xcc010000; - *(short*)((char*)(ptr) - 0x8000) = r3; - *(short*)((char*)(ptr) - 0x8000) = r4; - *(short*)((char*)(ptr) - 0x8000) = r5; -} - +void GXSetTexCoordGen2(GXTexCoordID dst_coord, GXTexGenType func, GXTexGenSrc src_param, u32 mtx, + GXBool normalize, u32 postmtx); void GXSetLineWidth(u8 width, GXTexOffset texOffsets); void GXSetPointSize(u8 pointSize, GXTexOffset texOffsets); -void GXEnableTexOffsets(GXTexCoordID coord, u8 line_enable, u8 point_enable); +void GXEnableTexOffsets(GXTexCoordID coord, GXBool line_enable, GXBool point_enable); +void GXSetArray(GXAttr attr, const void* data, u8 stride); +void GXInvalidateVtxCache(void); + +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); +} #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXGEOMETRY diff --git a/include/dolphin/gx/GXGet.h b/include/dolphin/gx/GXGet.h index d1ba630a4..487043144 100644 --- a/include/dolphin/gx/GXGet.h +++ b/include/dolphin/gx/GXGet.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_GX_GXGET_H_ -#define _DOLPHIN_GX_GXGET_H_ +#ifndef _DOLPHIN_GXGET +#define _DOLPHIN_GXGET #include #include @@ -8,57 +8,22 @@ 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); +GXBool GXGetTexObjMipMap(const GXTexObj* obj); +GXTexFmt GXGetTexObjFmt(const GXTexObj* obj); +u16 GXGetTexObjHeight(const GXTexObj* obj); +u16 GXGetTexObjWidth(const GXTexObj* obj); +GXTexWrapMode GXGetTexObjWrapS(const GXTexObj* obj); +GXTexWrapMode GXGetTexObjWrapT(const GXTexObj* obj); 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* GXGetTexObjData(const GXTexObj* obj); +void GXGetProjectionv(f32* p); 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); +void GXGetVtxAttrFmt(GXVtxFmt idx, GXAttr attr, GXCompCnt* compCnt, GXCompType* compType, + u8* shift); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXGET diff --git a/include/dolphin/gx/GXLighting.h b/include/dolphin/gx/GXLighting.h index 83c5aae42..a7e0ccc67 100644 --- a/include/dolphin/gx/GXLighting.h +++ b/include/dolphin/gx/GXLighting.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_GX_GXLIGHTING_H_ -#define _DOLPHIN_GX_GXLIGHTING_H_ +#ifndef _DOLPHIN_GXLIGHTING +#define _DOLPHIN_GXLIGHTING #include #include @@ -8,25 +8,25 @@ 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 GXSetNumChans(u8 nChans); +void GXSetChanCtrl(GXChannelID chan, GXBool enable, GXColorSrc amb_src, GXColorSrc mat_src, + u32 light_mask, GXDiffuseFn diff_fn, GXAttnFn attn_fn); +void GXSetChanAmbColor(GXChannelID chan, GXColor amb_color); +void GXSetChanMatColor(GXChannelID chan, GXColor mat_color); + 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 GXInitLightDistAttn(GXLightObj* lt_obj, f32 ref_distance, f32 ref_brightness, + 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); +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 GXLoadLightObjImm(GXLightObj* lt_obj, GXLightID light); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXLIGHTING diff --git a/include/dolphin/gx/GXManage.h b/include/dolphin/gx/GXManage.h index fd899d361..ab3a72c84 100644 --- a/include/dolphin/gx/GXManage.h +++ b/include/dolphin/gx/GXManage.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_GX_GXMANAGE_H_ -#define _DOLPHIN_GX_GXMANAGE_H_ +#ifndef _DOLPHIN_GXMANAGE +#define _DOLPHIN_GXMANAGE #include @@ -7,30 +7,18 @@ 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); +GXDrawDoneCallback GXSetDrawDoneCallback(GXDrawDoneCallback cb); void GXDrawDone(void); +void GXSetDrawDone(void); +void GXFlush(void); void GXPixModeSync(void); -void GXTexModeSync(void); -GXDrawSyncCallback GXSetDrawSyncCallback(GXDrawSyncCallback cb); -GXDrawDoneCallback GXSetDrawDoneCallback(GXDrawDoneCallback cb); +void GXSetMisc(GXMiscToken token, u32 val); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXMANAGE diff --git a/include/dolphin/gx/GXMisc.h b/include/dolphin/gx/GXMisc.h new file mode 100644 index 000000000..809a61ae4 --- /dev/null +++ b/include/dolphin/gx/GXMisc.h @@ -0,0 +1,21 @@ +#ifndef RVL_SDK_GX_MISC_H +#define RVL_SDK_GX_MISC_H +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +void GXSetMisc(GXMiscToken token, u32 val); +void GXFlush(); +void GXResetWriteGatherPipe(); +void GXPeekARGB(u16 x, u16 y, u32 *color); + +void GXAbortFrame(); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/include/dolphin/gx/GXPerf.h b/include/dolphin/gx/GXPerf.h index bd1b474aa..c3850dc3c 100644 --- a/include/dolphin/gx/GXPerf.h +++ b/include/dolphin/gx/GXPerf.h @@ -1,30 +1,16 @@ -#ifndef _DOLPHIN_GX_GXPERF_H_ -#define _DOLPHIN_GX_GXPERF_H_ +#ifndef _DOLPHIN_GXPERF +#define _DOLPHIN_GXPERF -#include +#include #ifdef __cplusplus extern "C" { #endif -void GXSetGPMetric(GXPerf0 perf0, GXPerf1 perf1); -void GXReadGPMetric(u32* cnt0, u32* cnt1); -void GXClearGPMetric(void); -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 +#endif // _DOLPHIN_GXPERF diff --git a/include/dolphin/gx/GXPixel.h b/include/dolphin/gx/GXPixel.h index d61838d1a..7dfae08fb 100644 --- a/include/dolphin/gx/GXPixel.h +++ b/include/dolphin/gx/GXPixel.h @@ -1,17 +1,17 @@ -#ifndef _DOLPHIN_GX_GXPIXEL_H_ -#define _DOLPHIN_GX_GXPIXEL_H_ +#ifndef _DOLPHIN_GXPIXEL +#define _DOLPHIN_GXPIXEL #include -#include #ifdef __cplusplus extern "C" { #endif 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 GXSetFogColor(GXColor color); +// ? GXSetFogRangeAdj(); +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); @@ -19,12 +19,11 @@ 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); +// ? GXSetFieldMask(); +// ? GXSetFieldMode(); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXPIXEL diff --git a/include/dolphin/gx/GXPriv.h b/include/dolphin/gx/GXPriv.h new file mode 100644 index 000000000..db0286b80 --- /dev/null +++ b/include/dolphin/gx/GXPriv.h @@ -0,0 +1,38 @@ +#ifndef _DOLPHIN_GXPRIV +#define _DOLPHIN_GXPRIV + +#include "dolphin/gx/GXVert.h" + +typedef struct GXLightObj_ { + u32 padding[3]; + u32 color; + float a0; + float a1; + float a2; + float k0; + float k1; + float k2; + float px; + float py; + float pz; + float nx; + float ny; + float nz; +} GXLightObj_; + +#define XF_LIGHT_BASE 0x0600 +#define XF_LIGHT_SIZE 0x10 + +#define GX_FIFO_ADDR 0xCC008000 + +#define GX_WRITE_U8(v) (GXWGFifo.u8 = v) +#define GX_WRITE_U32(v) (GXWGFifo.u32 = v) + +typedef struct GXData { + u16 cpSRreg; + u16 cpCRreg; +} GXData; + +extern GXData* __GXData; + +#endif // _DOLPHIN_GXPRIV diff --git a/include/dolphin/gx/GXStruct.h b/include/dolphin/gx/GXStruct.h index 0e7dc0be6..8ba5ba1b4 100644 --- a/include/dolphin/gx/GXStruct.h +++ b/include/dolphin/gx/GXStruct.h @@ -1,75 +1,82 @@ -#ifndef _DOLPHIN_GX_GXSTRUCT_H_ -#define _DOLPHIN_GX_GXSTRUCT_H_ +#ifndef _DOLPHIN_GXSTRUCT +#define _DOLPHIN_GXSTRUCT #include -#include +#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]; + VITVMode viTVmode; + u16 fbWidth; + u16 efbHeight; + u16 xfbHeight; + u16 viXOrigin; + u16 viYOrigin; + u16 viWidth; + u16 viHeight; + VIXFBMode xFBmode; + u8 field_rendering; + u8 aa; + u8 sample_pattern[12][2]; + u8 vfilter[7]; } GXRenderModeObj; typedef struct _GXColor { - u8 r, g, b, a; + u8 r; + u8 g; + u8 b; + u8 a; } GXColor; -typedef struct _GXColorS10 { - s16 r, g, b, a; -} GXColorS10; - typedef struct _GXTexObj { - u32 dummy[8]; + u32 dummy[8]; } GXTexObj; +typedef struct _GXTlutObj { + u32 dummy[3]; +} GXTlutObj; + typedef struct _GXLightObj { - u32 dummy[16]; + u32 dummy[16]; } GXLightObj; +typedef struct _GXVtxDescList { + GXAttr attr; + GXAttrType type; +} GXVtxDescList; + +typedef struct _GXVtxAttrFmtList { + GXAttr attr; + GXCompCnt cnt; + GXCompType type; + u8 frac; +} GXVtxAttrFmtList; + +typedef struct _GXColorS10 { + s16 r; + s16 g; + s16 b; + s16 a; +} GXColorS10; + typedef struct _GXTexRegion { - u32 dummy[4]; + u32 dummy[4]; } GXTexRegion; -typedef struct _GXTlutObj { - u32 dummy[3]; -} GXTlutObj; - typedef struct _GXTlutRegion { - u32 dummy[4]; + u32 dummy[4]; } GXTlutRegion; typedef struct _GXFogAdjTable { - u16 r[10]; + u16 fogVals[10]; // _00 } 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 +#endif // _DOLPHIN_GXSTRUCT diff --git a/include/dolphin/gx/GXTev.h b/include/dolphin/gx/GXTev.h index 8deb22d08..01290a9d5 100644 --- a/include/dolphin/gx/GXTev.h +++ b/include/dolphin/gx/GXTev.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_GX_GXTEV_H_ -#define _DOLPHIN_GX_GXTEV_H_ +#ifndef _DOLPHIN_GXTEV +#define _DOLPHIN_GXTEV #include #include @@ -9,18 +9,22 @@ 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 sel); void GXSetTevKAlphaSel(GXTevStageID stage, GXTevKAlphaSel sel); void GXSetTevSwapMode(GXTevStageID stage, GXTevSwapSel ras_sel, GXTevSwapSel tex_sel); -void GXSetTevSwapModeTable(GXTevSwapSel table, GXTevColorChan red, GXTevColorChan green, GXTevColorChan blue, GXTevColorChan alpha); -void GXSetTevClampMode(void); +void GXSetTevSwapModeTable(GXTevSwapSel table, GXTevColorChan red, GXTevColorChan green, + GXTevColorChan blue, GXTevColorChan alpha); 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); @@ -30,4 +34,4 @@ void GXSetNumTevStages(u8 nStages); } #endif -#endif +#endif // _DOLPHIN_GXTEV diff --git a/include/dolphin/gx/GXTexture.h b/include/dolphin/gx/GXTexture.h index f42dc2295..76bae19c1 100644 --- a/include/dolphin/gx/GXTexture.h +++ b/include/dolphin/gx/GXTexture.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_GX_GXTEXTURE_H_ -#define _DOLPHIN_GX_GXTEXTURE_H_ +#ifndef _DOLPHIN_GXTEXTURE +#define _DOLPHIN_GXTEXTURE #include #include @@ -8,45 +8,30 @@ extern "C" { #endif -typedef GXTexRegion *(*GXTexRegionCallback)(GXTexObj* t_obj, GXTexMapID id); -typedef GXTlutRegion *(*GXTlutRegionCallback)(u32 idx); +typedef GXTexRegion* (*GXTexRegionCallback)(const GXTexObj* obj, GXTexMapID id); -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 GXInitTexObj(GXTexObj* obj, void* image_ptr, u16 width, u16 height, GXTexFmt format, + GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, GXBool mipmap); +void GXInitTexObjCI(GXTexObj* obj, const void* data, u16 width, u16 height, GXCITexFmt format, + GXTexWrapMode wrapS, GXTexWrapMode wrapT, GXBool mipmap, u32 tlut); +void GXInitTexObjData(GXTexObj* obj, const void* data); +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 GXLoadTexObj(GXTexObj* obj, GXTexMapID id); -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 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); +u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, GXBool mipmap, u8 max_lod); +void GXInvalidateTexAll(); +void GXInitTexObjWrapMode(GXTexObj* obj, GXTexWrapMode s, GXTexWrapMode t); +void GXInitTlutObj(GXTlutObj* obj, const void* data, GXTlutFmt format, u16 entries); +void GXLoadTlut(const GXTlutObj* obj, u32 idx); +void GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 ss, u16 ts); +void GXInitTexCacheRegion(GXTexRegion* region, GXBool is_32b_mipmap, u32 tmem_even, + GXTexCacheSize size_even, u32 tmem_odd, GXTexCacheSize size_odd); +GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback callback); +void GXInvalidateTexRegion(const GXTexRegion* region); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXTEXTURE diff --git a/include/dolphin/gx/GXTransform.h b/include/dolphin/gx/GXTransform.h index 1e7f94e57..3d15e5e66 100644 --- a/include/dolphin/gx/GXTransform.h +++ b/include/dolphin/gx/GXTransform.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_GX_GXTRANSFORM_H_ -#define _DOLPHIN_GX_GXTRANSFORM_H_ +#ifndef _DOLPHIN_GXTRANSFORM +#define _DOLPHIN_GXTRANSFORM #include @@ -7,28 +7,22 @@ extern "C" { #endif -#define GX_PROJECTION_SZ 7 -#define GX_VIEWPORT_SZ 6 +#define GX_PROJECTION_SZ 7 -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 GXSetProjection(f32 mtx[4][4], GXProjectionType type); +void GXLoadPosMtxImm(f32 mtx[3][4], u32 id); +void GXLoadNrmMtxImm(f32 mtx[3][4], u32 id); +void GXLoadTexMtxImm(f32 mtx[][4], u32 id, GXTexMtxType type); +void GXSetViewport(f32 left, f32 top, f32 wd, f32 ht, f32 nearz, f32 farz); void GXSetCurrentMtx(u32 id); -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 GXSetScissor(u32 left, u32 top, u32 wd, u32 ht); +void GXGetScissor(u32 *x, u32 *y, u32 *w, u32 *h); void GXSetClipMode(GXClipMode mode); -void GXSetZScaleOffset(f32 scale, f32 offset); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXTRANSFORM diff --git a/include/dolphin/gx/GXVert.h b/include/dolphin/gx/GXVert.h index edb245cbc..7bce7e4ac 100644 --- a/include/dolphin/gx/GXVert.h +++ b/include/dolphin/gx/GXVert.h @@ -1,8 +1,7 @@ -#ifndef _DOLPHIN_GX_GXVERT_H_ -#define _DOLPHIN_GX_GXVERT_H_ +#ifndef _DOLPHIN_GXVERT +#define _DOLPHIN_GXVERT #include -#include #ifdef __cplusplus extern "C" { @@ -11,130 +10,108 @@ extern "C" { #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; + 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); +/*volatile*/ PPCWGPipe GXWGFifo : GXFIFO_ADDR; #else -#define GXWGFifo (*(volatile PPCWGPipe *)GXFIFO_ADDR) +#define GXWGFifo (*(volatile PPCWGPipe*)GXFIFO_ADDR) #endif -#if DEBUG +static inline void GXPosition2f32(const f32 x, const f32 y) +{ + GXWGFifo.f32 = x; + GXWGFifo.f32 = y; +} -// external functions +static inline void GXPosition3s16(const s16 x, const s16 y, const s16 z) +{ + GXWGFifo.s16 = x; + GXWGFifo.s16 = y; + GXWGFifo.s16 = z; +} -#define FUNC_1PARAM(name, T) void name##1##T(T x); -#define FUNC_2PARAM(name, T) void name##2##T(T x, T y); -#define FUNC_3PARAM(name, T) void name##3##T(T x, T y, T z); -#define FUNC_4PARAM(name, T) void name##4##T(T x, T y, T z, T w); -#define FUNC_INDEX8(name) void name##1x8(u8 x); -#define FUNC_INDEX16(name) void name##1x16(u16 x); +static inline void GXPosition3u16(const u16 x, const u16 y, const u16 z) +{ + GXWGFifo.u16 = x; + GXWGFifo.u16 = y; + GXWGFifo.u16 = z; +} -#else +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; +} -// inline functions +static inline void GXColor1u32(const u32 c) { GXWGFifo.u32 = c; } -#define FUNC_1PARAM(name, T) \ -static inline void name##1##T(T x) { GXWGFifo.T = x; } +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; +} -#define FUNC_2PARAM(name, T) \ -static inline void name##2##T(T x, T y) { GXWGFifo.T = x; GXWGFifo.T = y; } +static inline void GXTexCoord2s8(const s8 u, const s8 v) +{ + GXWGFifo.s8 = u; + GXWGFifo.s8 = v; +} -#define FUNC_3PARAM(name, T) \ -static inline void name##3##T(T x, T y, T z) { GXWGFifo.T = x; GXWGFifo.T = y; GXWGFifo.T = z; } +static inline void GXTexCoord2u8(const u8 s, const u8 t) +{ + GXWGFifo.u8 = s; + GXWGFifo.u8 = t; +} -#define FUNC_4PARAM(name, T) \ -static inline void name##4##T(T x, T y, T z, T w) { GXWGFifo.T = x; GXWGFifo.T = y; GXWGFifo.T = z; GXWGFifo.T = w; } +static inline void GXPosition2u16(u16 x, u16 y) +{ + GXWGFifo.u16 = x; + GXWGFifo.u16 = y; +} -#define FUNC_INDEX8(name) \ -static inline void name##1x8(u8 x) { GXWGFifo.u8 = x; } +static inline void GXTexCoord2s16(const s16 u, const s16 v) +{ + GXWGFifo.s16 = u; + GXWGFifo.s16 = v; +} -#define FUNC_INDEX16(name) \ -static inline void name##1x16(u16 x) { GXWGFifo.u16 = x; } +static inline void GXTexCoord2u16(const u16 u, const u16 v) +{ + GXWGFifo.u16 = u; + GXWGFifo.u16 = v; +} -#endif +static inline void GXTexCoord2f32(const f32 u, const f32 v) +{ + GXWGFifo.f32 = u; + GXWGFifo.f32 = v; +} -// 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 +static inline void GXEnd(void) {} #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXVERT diff --git a/include/dolphin/hio.h b/include/dolphin/hio.h index dc83ee19a..1e5aae25b 100644 --- a/include/dolphin/hio.h +++ b/include/dolphin/hio.h @@ -1,25 +1,37 @@ -#ifndef _DOLPHIN_HIO_H_ -#define _DOLPHIN_HIO_H_ +#ifndef _DOLPHIN_HOSTIO_H +#define _DOLPHIN_HOSTIO_H + +#ifdef __cplusplus +extern "C" +{ +#endif // ifdef __cplusplus + +#include #include -#ifdef __cplusplus -extern "C" { -#endif +typedef enum +{ + HIO_DEVICE_INVALID = -1, + HIO_DEVICE_EXI2USB_0 = 0, + HIO_DEVICE_EXI2USB_1 = 1, + HIO_DEVICE_MrEXI = 2 +} HostIOType; + +typedef enum +{ + GRAB_NOT_TRANSFERRING = 0, + GRAB_TRANSFERRING = 1 +} HostIOGrabStatus; -typedef void (*HIOCallback)(void); typedef BOOL (*HIOEnumCallback)(s32 chan); +typedef void (*HIOCallback)(void); -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); +BOOL HIOInit(s32 channel, HIOCallback cb); +BOOL HIOEnumDevices(HIOEnumCallback); +BOOL HIOWrite(u32 chunkSize, void * buf, u32 bufSize); +BOOL HIOReadMailbox(u32 *); +BOOL HIOWriteMailbox(u32); #ifdef __cplusplus } diff --git a/include/dolphin/hw_regs.h b/include/dolphin/hw_regs.h index 1f5700a16..627128c7e 100644 --- a/include/dolphin/hw_regs.h +++ b/include/dolphin/hw_regs.h @@ -1,29 +1,33 @@ -#ifndef _DOLPHIN_HW_REGS_H_ -#define _DOLPHIN_HW_REGS_H_ +#ifndef _DOLPHIN_HW_REGS +#define _DOLPHIN_HW_REGS -#include +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif #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); +vu16 __VIRegs[59] : 0xCC002000; +vu32 __PIRegs[12] : 0xCC003000; +vu16 __MEMRegs[64] : 0xCC004000; +vu16 __DSPRegs[32] : 0xCC005000; +vu32 __DIRegs[16] : 0xCC006000; +vu32 __SIRegs[64] : 0xCC006400; +vu32 __EXIRegs[16] : 0xCC006800; +vu32 __AIRegs[8] : 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) +#define __VIRegs ((vu16*)0xCC002000) +#define __PIRegs ((vu32*)0xCC003000) +#define __MEMRegs ((vu16*)0xCC004000) +#define __DSPRegs ((vu16*)0xCC005000) +#define __DIRegs ((vu32*)0xCC006000) +#define __SIRegs ((vu32*)0xCC006400) +#define __EXIRegs ((vu32*)0xCC006800) +#define __AIRegs ((vu32*)0xCC006C00) #endif -// Offsets for __VIRegs // offsets for __VIRegs[i] #define VI_VERT_TIMING (0) @@ -89,6 +93,50 @@ volatile u32 __AIRegs[8] AT_ADDRESS(0xCC006C00); #define VI_WIDTH (56) + +// offsets for __PIRegs[i] +#define PI_INTRPT_SRC (0) // interrupt cause +#define PI_INTRPT_MASK (1) // interrupt mask +#define PI_FIFO_START (3) // FIFO base start +#define PI_FIFO_END (4) // FIFO base end +#define PI_FIFO_PTR (5) // FIFO current write pointer + +#define PI_RESETCODE (9) // reset code, used by OSReset + +// PI Interrupt causes. +#define PI_INTRPT_ERR (0x1) // GP runtime error +#define PI_INTRPT_RSW (0x2) // reset switch +#define PI_INTRPT_DVD (0x4) // DVD/DI interrupt +#define PI_INTRPT_SI (0x8) // serial/controller interrupt +#define PI_INTRPT_EXI (0x10) // external mem interrupt +#define PI_INTRPT_AI (0x20) // audio streaming interrupt +#define PI_INTRPT_DSP (0x40) // digital signal proc interrupt +#define PI_INTRPT_MEM (0x80) // memory interface interrupt +#define PI_INTRPT_VI (0x100) // video interface interrupt +#define PI_INTRPT_PE_TOKEN (0x200) // pixel engine token +#define PI_INTRPT_PE_FINISH (0x400) // pixel engine finish +#define PI_INTRPT_CP (0x800) // command FIFO +#define PI_INTRPT_DEBUG (0x1000) // external debugger +#define PI_INTRPT_HSP (0x2000) // high speed port +#define PI_INTRPT_RSWST (0x10000) // reset switch state (1 when pressed) + + +// offsets for __MEMRegs[i] +#define MEM_PROT_1 (0) // protected region 1 +#define MEM_PROT_2 (2) // protected region 1 +#define MEM_PROT_3 (4) // protected region 1 +#define MEM_PROT_4 (6) // protected region 1 +#define MEM_PROT_TYPE (8) // protection type + +#define MEM_INTRPT_MASK (14) // interrupt mask +#define MEM_INTRPT_SRC (15) // interrupt cause +#define MEM_INTRPT_FLAG (16) // set when interrupt happens +#define MEM_INTRPT_ADDR_LO (17) // address that caused interrupt +#define MEM_INTRPT_ADDR_HI (18) // address that caused interrupt + +#define MEM_UNK_FLAG (20) // unknown memory flag, set in __OSInitMemoryProtection + + // offsets for __DSPRegs[i] #define DSP_MAILBOX_IN_HI (0) #define DSP_MAILBOX_IN_LO (1) @@ -113,4 +161,82 @@ volatile u32 __AIRegs[8] AT_ADDRESS(0xCC006C00); #define DSP_DMA_START_FLAG (0x8000) // set to start DSP + +// offsets for __DIRegs[i] +#define DI_STATUS (0) +#define DI_COVER_STATUS (1) // cover status - 0=normal, 1=interrupt/open +#define DI_CMD_BUF_0 (2) // command buffer 0 +#define DI_CMD_BUF_1 (3) // command buffer 1 +#define DI_CMD_BUF_2 (4) // command buffer 2 +#define DI_DMA_MEM_ADDR (5) // DMA address +#define DI_DMA_LENGTH (6) // transfer length address +#define DI_CONTROL (7) +#define DI_MM_BUF (8) // Main memory buffer +#define DI_CONFIG (9) + + +// offsets for __SIRegs[i] +// Channel 0/Joy-channel 1 +#define SI_CHAN_0_BUF (0) // output buffer +#define SI_CHAN_0_BTN_1 (1) // button 1 +#define SI_CHAN_0_BTN_2 (2) // button 2 +// Channel 1/Joy-channel 2 +#define SI_CHAN_1_BUF (3) // output buffer +#define SI_CHAN_1_BTN_1 (4) // button 1 +#define SI_CHAN_1_BTN_2 (5) // button 2 +// Channel 2/Joy-channel 3 +#define SI_CHAN_2_BUF (6) // output buffer +#define SI_CHAN_2_BTN_1 (7) // button 1 +#define SI_CHAN_2_BTN_2 (8) // button 2 +// Channel 3/Joy-channel 4 +#define SI_CHAN_3_BUF (9) // output buffer +#define SI_CHAN_3_BTN_1 (10) // button 1 +#define SI_CHAN_3_BTN_2 (11) // button 2 + +#define SI_POLL (12) +#define SI_CC_STAT (13) // communication control status +#define SI_STAT (14) +#define SI_EXI_LOCK (15) // exi clock lock + +#define SI_IO_BUFFER (32) // start of buffer (32 to 63) + + +// offsets for __EXIRegs[i] +// Channel 0 +#define EXI_CHAN_0_STAT (0) // parameters/status +#define EXI_CHAN_0_DMA_ADDR (1) // DMA start address +#define EXI_CHAN_0_LEN (2) // DMA transfer length +#define EXI_CHAN_0_CONTROL (3) // control register +#define EXI_CHAN_0_IMM (4) // immediate data +// Channel 1 +#define EXI_CHAN_1_STAT (5) // parameters/status +#define EXI_CHAN_1_DMA_ADDR (6) // DMA start address +#define EXI_CHAN_1_LEN (7) // DMA transfer length +#define EXI_CHAN_1_CONTROL (8) // control register +#define EXI_CHAN_1_IMM (9) // immediate data +// Channel 2 +#define EXI_CHAN_2_STAT (10) // parameters/status +#define EXI_CHAN_2_DMA_ADDR (11) // DMA start address +#define EXI_CHAN_2_LEN (12) // DMA transfer length +#define EXI_CHAN_2_CONTROL (13) // control register +#define EXI_CHAN_2_IMM (14) // immediate data + + +// offsets for __AIRegs[i] +#define AI_CONTROL (0) // control +#define AI_VOLUME (1) // volume +#define AI_SAMPLE_COUNTER (2) // number of stereo samples output +#define AI_INTRPT_TIMING (3) // interrupt timing + +#define AI_CONTROL_PLAY_STATE (0x1) +#define AI_CONTROL_STREAM_SAMPLE_RATE (0x2) +#define AI_CONTROL_DSP_SAMPLE_COUNT (0x4) +#define AI_CONTROL_UNKNOWN8 (0x8) +#define AI_CONTROL_STREAM_SAMPLE_COUNT (0x20) +#define AI_CONTROL_DSP_SAMPLE_RATE (0x40) + +#ifdef __cplusplus +} #endif + +#endif // _DOLPHIN_HW_REGS diff --git a/include/dolphin/ip/ip.h b/include/dolphin/ip/ip.h new file mode 100644 index 000000000..6ffaa80bb --- /dev/null +++ b/include/dolphin/ip/ip.h @@ -0,0 +1,26 @@ +#ifndef _DOLPHIN_IP_H_ +#define _DOLPHIN_IP_H_ + +#include + +// Protocols +#define IP_PROTO_ICMP 1 +#define IP_PROTO_TCP 6 +#define IP_PROTO_UDP 17 + +typedef struct IPHeader { + u8 verlen; + u8 tos; + u16 len; + u16 id; + u16 frag; + u8 ttl; + u8 proto; + u16 sum; + u8 src[4]; + u8 dst[4]; +} IPHeader; + +BOOL IPIsLocalAddr(u32, const u8 *addr); + +#endif diff --git a/include/dolphin/lg.h b/include/dolphin/lg.h new file mode 100644 index 000000000..9aaf6fea0 --- /dev/null +++ b/include/dolphin/lg.h @@ -0,0 +1,29 @@ +#ifndef DOLPHIN_LG_H +#define DOLPHIN_LG_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif // ifdef __cplusplus + +// This file presumably was for a logitech steering wheel, as it is some sort of controller handler + +struct LGPosition { // seems really similar to PADStatus but is slightly different + u16 button; + s8 _2; + s8 steerDirection; + u8 gasPedal; + u8 brakePedal; + u8 _6; // unknown, are there any other analog buttons?(start maybe) + u8 analogL; + u8 analogR; + s8 err; // -1 probably means disconnected? +}; + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/include/dolphin/md5.h b/include/dolphin/md5.h new file mode 100644 index 000000000..d4a7b613e --- /dev/null +++ b/include/dolphin/md5.h @@ -0,0 +1,52 @@ +#ifndef __DOLPHIN_OS_MD5_H__ +#define __DOLPHIN_OS_MD5_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* MD5.H - header file for MD5C.C */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + rights reserved. + + License to copy and use this software is granted provided that it + is identified as the "RSA Data Security, Inc. MD5 Message-Digest + Algorithm" in all material mentioning or referencing this software + or this function. + + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD5 Message-Digest Algorithm" in all material + mentioning or referencing the derived work. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + */ + +/* MD5 context. */ +typedef struct MD5Context MD5_CTX; +typedef struct MD5Context MD5Context; +struct MD5Context +{ + u32 state[4]; // state (ABCD) + u32 count[2]; // number of bits, modulo 2^64 (lsb first) + u8 buffer[64]; // input buffer +}; + +void MD5Init (MD5Context* context); +void MD5Update(MD5Context* context, u8* input, u32 inputLen); +void MD5Final (u8 digest[16], MD5Context* context); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/mtx.h b/include/dolphin/mtx.h index 5346bc75e..4cf62ffec 100644 --- a/include/dolphin/mtx.h +++ b/include/dolphin/mtx.h @@ -1,375 +1,115 @@ -#ifndef _DOLPHIN_MTX_H_ -#define _DOLPHIN_MTX_H_ +#ifndef _DOLPHIN_MTX_H +#define _DOLPHIN_MTX_H -#include +#include "types.h" #ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - f32 x, y, z; -} Vec, *VecPtr, Point3d, *Point3dPtr; - -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]; - -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 sinA, f32 cosA); -void PSMTXRotAxisRad(Mtx m, const Vec* axis, f32 rad); -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); - -#ifdef DEBUG -#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_MTXRotRad -#define MTXTrans C_MTXTrans -#define MTXTransApply C_MTXTransApply -#define MTXScale C_MTXScale -#define MTXScaleApply C_MTXScaleApply -#define MTXQuat C_MTXQuat -#define MTXReflect C_MTXReflect -#else -#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 PSMTXRotRad -#define MTXTrans PSMTXTrans -#define MTXTransApply PSMTXTransApply -#define MTXScale PSMTXScale -#define MTXScaleApply PSMTXScaleApply -#define MTXQuat PSMTXQuat -#define MTXReflect PSMTXReflect -#endif - -// 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 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); - -#ifdef DEBUG -#define MTXMultVec C_MTXMultVec -#define MTXMultVecArray C_MTXMultVecArray -#define MTXMultVecSR C_MTXMultVecSR -#define MTXMultVecArraySR C_MTXMultVecArraySR -#else -#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 +extern "C" +{ +#endif // ifdef __cplusplus + + typedef float Mtx[3][4]; + typedef float (*MtxPtr)[4]; + typedef float Mtx23[2][3]; + typedef float Mtx33[3][3]; + typedef float Mtx44[4][4]; + typedef float PSQuaternion[4]; + + typedef struct + { + f32 x, y, z; + } Vec, *VecPtr; + + typedef struct + { + s16 x, y, z; + } S16Vec, *S16VecPtr; + + typedef struct + { + f32 x, y, z, w; + } Quaternion, *QuaternionPtr; + +// (pi/180) +#define MTXDegToRad(a) ((a) * 0.01745329252f) + + // Paired single versions + + 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 PSMTXMultVec(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); + void PSMTXQuat(Mtx m, const Quaternion *q); + void PSMTXReflect(Mtx m, const Vec *p, const Vec *n); + 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 PSMTXRotRad(Mtx m, char axis, f32 rad); + void PSMTXRotTrig(Mtx m, char axis, f32 sinA, f32 cosA); + void PSMTXRotAxisRad(Mtx m, const Vec *axis, f32 rad); + + // move to vec.h? + void PSVECAdd(const Vec *a, const Vec *b, Vec *ab); + void PSVECSubtract(const Vec *a, const Vec *b, Vec *ab); + 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 *ab); + f32 PSVECSquareDistance(const Vec *a, const Vec *b); + f32 PSVECDistance(const Vec *a, const Vec *b); + + 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); + + // C Versions + + 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_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); + void C_MTXQuat(Mtx m, const Quaternion *q); + void C_MTXReflect(Mtx m, const Vec *p, const Vec *n); + 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_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_MTXLookAt(Mtx m, const Vec *camPos, const Vec *camUp, const Vec *target); + 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); + 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); #ifdef __cplusplus } #endif -#endif +#endif \ No newline at end of file diff --git a/include/dolphin/os.h b/include/dolphin/os.h index 05ea543a3..b5952f99f 100644 --- a/include/dolphin/os.h +++ b/include/dolphin/os.h @@ -1,258 +1,245 @@ -#ifndef _DOLPHIN_OS_H_ -#define _DOLPHIN_OS_H_ +#ifndef _DOLPHIN_OS +#define _DOLPHIN_OS +#include #include -#include #ifdef __cplusplus -extern "C" { +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) #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); - -// 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); +#define AT_ADDRESS(xyz) : (xyz) #else -#define __OSBusClock (*(u32 *)(OS_BASE_CACHED | 0x00F8)) -#define __OSCoreClock (*(u32 *)(OS_BASE_CACHED | 0x00FC)) +#define AT_ADDRESS +#endif +volatile int __OSTVMode AT_ADDRESS(OS_BASE_CACHED | 0xCC); +u32 __OSBusClock AT_ADDRESS(OS_BASE_CACHED | 0x00F8); // sync with OSLoMem.h +u32 __OSCoreClock AT_ADDRESS(OS_BASE_CACHED | 0x00FC); // sync with OSLoMem.h +#define OS_BUS_CLOCK (u32) __OSBusClock +#define OS_CORE_CLOCK __OSCoreClock +#define OS_TIMER_CLOCK (OS_BUS_CLOCK / 4) + +#ifndef _DEBUG +#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))) +#else +u32 OSPhysicalToCached(void *paddr); +u32 OSPhysicalToUncached(void *paddr); +u32 OSCachedToPhysical(void *caddr); +u32 OSUncachedToPhysical(void *ucaddr); +u32 OSCachedToUncached(void *caddr); +u32 OSUncachedToCached(void *ucaddr); #endif -#define OS_BUS_CLOCK __OSBusClock -#define OS_CORE_CLOCK __OSCoreClock -#define OS_TIMER_CLOCK (OS_BUS_CLOCK/4) - -#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* 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 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 OSDiffTick(tick1, tick0) ((s32)(tick1) - (s32)(tick0)) + +#define OSRoundUp32B(v) ((((u32)v + 31) & ~31)) +#define OSRoundDown32B(v) (((u32)(v) & ~31)) -#define OS_CONSOLE_MASK 0xF0000000 -#define OS_CONSOLE_RETAIL 0x00000000 +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); + +void OSInit(); + +#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_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_CONSOLE_EMULATOR 0x10000000 -#define OS_SOUND_MODE_MONO 0 -#define OS_SOUND_MODE_STEREO 1 +u32 OSGetConsoleType(); + +#define OS_SOUND_MODE_MONO 0u +#define OS_SOUND_MODE_STEREO 1u 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); - -#define OSRoundUp32B(x) (((u32)(x) + 32 - 1) & ~(32 - 1)) -#define OSRoundDown32B(x) (((u32)(x)) & ~(32 - 1)) - -void* OSPhysicalToCached(u32 paddr); -void* OSPhysicalToUncached(u32 paddr); -u32 OSCachedToPhysical(void* caddr); -u32 OSUncachedToPhysical(void* ucaddr); -void* OSCachedToUncached(void* caddr); -void* OSUncachedToCached(void* ucaddr); - -#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))) +#define OS_PROGRESSIVE_MODE_OFF 0u +#define OS_PROGRESSIVE_MODE_ON 1u + +u32 OSGetProgressiveMode(void); +void OSSetProgressiveMode(u32 on); + +#define OS_LANG_ENGLISH 0u +#define OS_LANG_GERMAN 1u +#define OS_LANG_FRENCH 2u +#define OS_LANG_SPANISH 3u +#define OS_LANG_ITALIAN 4u +#define OS_LANG_DUTCH 5u + +u8 OSGetLanguage(void); +void OSSetLanguage(u8 language); + +#define OS_EURGB60_OFF 0u +#define OS_EURGB60_ON 1u + +u32 OSGetEuRgb60Mode(void); +void OSSetEuRgb60Mode(u32 on); + +void OSRegisterVersion(const char *id); + +BOOL OSDisableInterrupts(void); +BOOL OSEnableInterrupts(void); +BOOL OSRestoreInterrupts(BOOL level); + +#ifndef REGION_EU +#define OSGetVideoMode() OSGetProgressiveMode() +#define OSSetVideoMode(on) OSSetProgressiveMode(on) +#else +#define OSGetVideoMode() OSGetEuRgb60Mode() +#define OSSetVideoMode(on) OSSetEuRgb60Mode(on) +#endif + +#define OSHalt(msg) OSPanic(__FILE__, __LINE__, msg) + +#ifdef _DEBUG + +#ifndef ASSERT +#define ASSERT(exp) (void)((exp) || (OSPanic(__FILE__, __LINE__, "Failed assertion " #exp), 0)) #endif -// 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) +#ifndef ASSERTMSG +#if defined(__STDC_VERSION__) && (199901L <= __STDC_VERSION__) || defined(__MWERKS__) || \ + defined(__SN__) +#define ASSERTMSG(exp, ...) (void)((exp) || (OSPanic(__FILE__, __LINE__, __VA_ARGS__), 0)) #else - #define LINE(l0, l1, l2) (l2) +#define ASSERTMSG(exp, msg) (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg)), 0)) +#endif #endif +#ifndef ASSERTMSG1 +#define ASSERTMSG1(exp, msg, param1) \ + (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1)), 0)) +#endif -#ifdef DEBUG -#define ASSERTLINE(line, cond) \ - ((cond) || (OSPanic(__FILE__, line, "Failed assertion " #cond), 0)) +#ifndef ASSERTMSG2 +#define ASSERTMSG2(exp, msg, param1, param2) \ + (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1), (param2)), 0)) +#endif -#define ASSERTMSGLINE(line, cond, msg) \ - ((cond) || (OSPanic(__FILE__, line, msg), 0)) +#ifndef ASSERTMSG3 +#define ASSERTMSG3(exp, msg, param1, param2, param3) \ + (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1), (param2), (param3)), 0)) +#endif + +#ifndef ASSERTMSG4 +#define ASSERTMSG4(exp, msg, param1, param2, param3, param4) \ + (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1), (param2), (param3), (param4)), 0)) +#endif + +#else // _DEBUG + +#ifndef ASSERT +#define ASSERT(exp) ((void)0) +#endif + +#ifndef ASSERTMSG +#if defined(__STDC_VERSION__) && (199901L <= __STDC_VERSION__) || defined(__MWERKS__) || \ + defined(__SN__) +#define ASSERTMSG(exp, ...) ((void)0) +#else +#define ASSERTMSG(exp, msg) ((void)0) +#endif +#endif + +#ifndef ASSERTMSG1 +#define ASSERTMSG1(exp, msg, param1) ((void)0) +#endif +#ifndef ASSERTMSG2 +#define ASSERTMSG2(exp, msg, param1, param2) ((void)0) +#endif +#ifndef ASSERTMSG3 +#define ASSERTMSG3(exp, msg, param1, param2, param3) ((void)0) +#endif +#ifndef ASSERTMSG4 +#define ASSERTMSG4(exp, msg, param1, param2, param3, param4) ((void)0) +#endif -// 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)) +#endif // _DEBUG -#define ASSERTMSGLINEV(line, cond, ...) \ - ((cond) || (OSPanic(__FILE__, line, __VA_ARGS__), 0)) +void OSReport(const char *msg, ...); +void OSPanic(const char *file, int line, const char *msg, ...); +void OSFatal(GXColor fg, GXColor bg, const char *msg); +#define OSError(...) OSPanic(__FILE__, __LINE__, __VA_ARGS__) +#ifndef MATCHING +#define OSErrorLine(line, ...) OSError(__VA_ARGS__) #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 +#define OSErrorLine(line, ...) OSPanic(__FILE__, line, __VA_ARGS__) #endif - -#define ASSERT(cond) ASSERTLINE(__LINE__, cond) #ifdef __cplusplus } #endif -#endif +// TODO: put this somewhere else +extern BOOL __OSInIPL; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif // _DOLPHIN_OS diff --git a/include/dolphin/os/OSAlarm.h b/include/dolphin/os/OSAlarm.h index 310503918..7b4a266e2 100644 --- a/include/dolphin/os/OSAlarm.h +++ b/include/dolphin/os/OSAlarm.h @@ -1,7 +1,9 @@ -#ifndef _DOLPHIN_OSALARM_H_ -#define _DOLPHIN_OSALARM_H_ +#ifndef _DOLPHIN_OSALARM +#define _DOLPHIN_OSALARM -#include +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -9,28 +11,30 @@ extern "C" { 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; + OSAlarmHandler handler; + u32 tag; + OSTime fire; + OSAlarm* prev; + OSAlarm* next; + OSTime period; + OSTime start; }; -BOOL OSCheckAlarmQueue(void); void OSInitAlarm(void); -void OSCreateAlarm(OSAlarm* alarm); void OSSetAlarm(OSAlarm* alarm, OSTime tick, OSAlarmHandler handler); +void OSSetAlarmTag(OSAlarm* alarm, u32 tag); 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 OSCreateAlarm(OSAlarm* alarm); +void OSCancelAlarm(OSAlarm* alarm); void OSCancelAlarms(u32 tag); +BOOL OSCheckAlarmQueue(void); + #ifdef __cplusplus } #endif -#endif // _DOLPHIN_OSALARM_H_ +#endif // _DOLPHIN_OSALARM diff --git a/include/dolphin/os/OSAlloc.h b/include/dolphin/os/OSAlloc.h index 77eb88661..afa1d9be1 100644 --- a/include/dolphin/os/OSAlloc.h +++ b/include/dolphin/os/OSAlloc.h @@ -1,34 +1,30 @@ -#ifndef _DOLPHIN_OSALLOC_H_ -#define _DOLPHIN_OSALLOC_H_ +#ifndef _DOLPHIN_OSALLOC +#define _DOLPHIN_OSALLOC #include #ifdef __cplusplus extern "C" { #endif - typedef int OSHeapHandle; - -extern volatile OSHeapHandle __OSCurrHeap; - -void* OSAllocFromHeap(int heap, u32 size); -void* OSAllocFixed(void* rstart, void* rend); -void OSFreeToHeap(int heap, void* ptr); -int OSSetCurrentHeap(int heap); +typedef void (*OSAllocVisitor)(void* obj, u32 size); 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); +OSHeapHandle OSCreateHeap(void* start, void* end); +void OSDestroyHeap(OSHeapHandle heap); +void OSAddToHeap(OSHeapHandle heap, void* start, void* end); +OSHeapHandle OSSetCurrentHeap(OSHeapHandle heap); +void* OSAllocFromHeap(OSHeapHandle heap, u32 size); +void* OSAllocFixed(void** rstart, void** rend); +void OSFreeToHeap(OSHeapHandle heap, void* ptr); +long OSCheckHeap(OSHeapHandle heap); +void OSDumpHeap(OSHeapHandle heap); u32 OSReferentSize(void* ptr); -void OSDumpHeap(int heap); -void OSVisitAllocated(void (*visitor)(void*, u32)); - +void OSVisitAllocated(OSAllocVisitor visitor); +extern volatile OSHeapHandle __OSCurrHeap; #define OSAlloc(size) OSAllocFromHeap(__OSCurrHeap, (size)) -#define OSFree(ptr) OSFreeToHeap(__OSCurrHeap, (ptr)) - +#define OSFree(ptr) OSFreeToHeap(__OSCurrHeap, (ptr)) #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_OSALLOC diff --git a/include/dolphin/os/OSArena.h b/include/dolphin/os/OSArena.h new file mode 100644 index 000000000..9dc157011 --- /dev/null +++ b/include/dolphin/os/OSArena.h @@ -0,0 +1,13 @@ +#ifndef _DOLPHIN_OSARENA +#define _DOLPHIN_OSARENA + +#include + +void* OSGetArenaHi(void); +void* OSGetArenaLo(void); +void OSSetArenaHi(void* addr); +void OSSetArenaLo(void* addr); +void* OSAllocFromArenaLo(u32 size, u32 align); +void* OSAllocFromArenaLo(u32 size, u32 align); + +#endif // _DOLPHIN_OSARENA diff --git a/include/dolphin/os/OSBootInfo.h b/include/dolphin/os/OSBootInfo.h new file mode 100644 index 000000000..fd7c3c0d2 --- /dev/null +++ b/include/dolphin/os/OSBootInfo.h @@ -0,0 +1,41 @@ +#ifndef _DOLPHIN_OSBOOTINFO +#define _DOLPHIN_OSBOOTINFO + +#define OS_BOOTROM_ADDR 0x81300000 + +typedef struct OSBootInfo { + DVDDiskID DVDDiskID; + u32 magic; + u32 version; + u32 memorySize; + u32 consoleType; + void* arenaLo; + void* arenaHi; + void* FSTLocation; + u32 FSTMaxLength; +} OSBootInfo; + +typedef struct { + BOOL valid; + u32 restartCode; + u32 bootDol; + void* regionStart; + void* regionEnd; + BOOL argsUseDefault; + void* argsAddr; // valid only when argsUseDefault = FALSE + +} OSExecParams; + +typedef struct BI2Debug { + s32 debugMonSize; // 0x0 + s32 simMemSize; // 0x4 + u32 argOffset; // 0x8 + u32 debugFlag; // 0xC + int trackLocation; // 0x10 + int trackSize; // 0x14 + u32 countryCode; // 0x18 + u8 unk[8]; // 0x1C + u32 padSpec; // 0x24 +} BI2Debug; + +#endif // _DOLPHIN_OSBOOTINFO diff --git a/include/dolphin/os/OSCache.h b/include/dolphin/os/OSCache.h index 89e7ce96b..b3dd94a21 100644 --- a/include/dolphin/os/OSCache.h +++ b/include/dolphin/os/OSCache.h @@ -1,7 +1,7 @@ -#ifndef _DOLPHIN_OSCACHE_H_ -#define _DOLPHIN_OSCACHE_H_ +#ifndef _DOLPHIN_OSCACHE +#define _DOLPHIN_OSCACHE -#include +#include "dolphin/types.h" #ifdef __cplusplus extern "C" { @@ -20,7 +20,7 @@ void ICInvalidateRange(void* addr, u32 nBytes); #define LC_BASE (LC_BASE_PREFIX << 16) #define LCGetBase() ((void*)LC_BASE) -void LCEnable(void); +void LCEnable(); void LCDisable(void); void LCLoadBlocks(void* destTag, void* srcAddr, u32 numBlocks); void LCStoreBlocks(void* destAddr, void* srcTag, u32 numBlocks); @@ -29,10 +29,9 @@ u32 LCStoreData(void* destAddr, void* srcAddr, u32 nBytes); u32 LCQueueLength(void); void LCQueueWait(u32 len); void LCFlushQueue(void); -void __OSCacheInit(void); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_OSCACHE diff --git a/include/dolphin/os/OSContext.h b/include/dolphin/os/OSContext.h index cbb0b92e4..fb024f8c5 100644 --- a/include/dolphin/os/OSContext.h +++ b/include/dolphin/os/OSContext.h @@ -1,7 +1,7 @@ -#ifndef _DOLPHIN_OSCONTEXT_H_ -#define _DOLPHIN_OSCONTEXT_H_ +#ifndef _DOLPHIN_OSCONTEXT +#define _DOLPHIN_OSCONTEXT -#include +#include #ifdef __cplusplus extern "C" { @@ -135,39 +135,38 @@ extern "C" { #define OS_CONTEXT_STATE_FPSAVED 0x01u typedef struct OSContext { - /* 0x000 */ u32 gpr[32]; - /* 0x080 */ u32 cr; - /* 0x084 */ u32 lr; - /* 0x088 */ u32 ctr; - /* 0x08C */ u32 xer; - /* 0x090 */ f64 fpr[32]; - /* 0x190 */ u32 fpscr_pad; - /* 0x194 */ u32 fpscr; - /* 0x198 */ u32 srr0; - /* 0x19C */ u32 srr1; - /* 0x1A0 */ u16 mode; - /* 0x1A2 */ u16 state; - /* 0x1A4 */ u32 gqr[8]; - /* 0x1C4 */ u32 psf_pad; - /* 0x1C8 */ f64 psf[32]; + u32 gpr[32]; + u32 cr; + u32 lr; + u32 ctr; + u32 xer; + + f64 fpr[32]; + + u32 fpscr_pad; + u32 fpscr; + + u32 srr0; + u32 srr1; + + u16 mode; + u16 state; + + u32 gqr[8]; + u32 psf_pad; + f64 psf[32]; + } OSContext; -u32 OSGetStackPointer(void); -void OSDumpContext(OSContext* context); -void OSLoadContext(OSContext* context); u32 OSSaveContext(OSContext* context); void OSClearContext(OSContext* context); -OSContext* OSGetCurrentContext(void); +OSContext* OSGetCurrentContext(); 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); +void OSFillFPUContext(OSContext *context); +u32 OSGetStackPointer(); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_OSCONTEXT diff --git a/include/dolphin/os/OSError.h b/include/dolphin/os/OSError.h index 4a2fc7bd7..151bfb480 100644 --- a/include/dolphin/os/OSError.h +++ b/include/dolphin/os/OSError.h @@ -1,38 +1,43 @@ -#ifndef _DOLPHIN_OSERROR_H_ -#define _DOLPHIN_OSERROR_H_ +#ifndef _DOLPHIN_OSERROR +#define _DOLPHIN_OSERROR -#include +#include #ifdef __cplusplus extern "C" { #endif -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_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_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) +#define OS_ERROR_BREAKPOINT 12 +#define OS_ERROR_SYSTEM_INTERRUPT 13 +#define OS_ERROR_THERMAL_INTERRUPT 14 +#define OS_ERROR_PROTECTION 15 +#define OS_ERROR_FPE 16 + +#define OS_ERROR_MAX (OS_ERROR_FPE + 1) + +typedef u16 OSError; +typedef void (*OSErrorHandler)( OSError error, OSContext* context, ... ); + +OSErrorHandler OSSetErrorHandler(OSError code, OSErrorHandler handler); -OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler); +// Error table. +extern OSErrorHandler __OSErrorTable[OS_ERROR_MAX]; extern u32 __OSFpscrEnableBits; -extern OSErrorHandler __OSErrorTable[17]; #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_OSERROR diff --git a/include/dolphin/os/OSException.h b/include/dolphin/os/OSException.h index e9a2f2256..f34236972 100644 --- a/include/dolphin/os/OSException.h +++ b/include/dolphin/os/OSException.h @@ -1,5 +1,6 @@ -#ifndef _DOLPHIN_OSEXCEPTION_H_ -#define _DOLPHIN_OSEXCEPTION_H_ + +#ifndef _DOLPHIN_OSEXCEPTION +#define _DOLPHIN_OSEXCEPTION #include #include @@ -7,33 +8,27 @@ #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 \ +#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_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); \ @@ -58,4 +53,4 @@ __OSExceptionHandler __OSGetExceptionHandler(__OSException exception); } #endif -#endif // _DOLPHIN_OSEXCEPTION_H_ +#endif // _DOLPHIN_OSEXCEPTION diff --git a/include/dolphin/os/OSExpansion.h b/include/dolphin/os/OSExpansion.h new file mode 100644 index 000000000..6e848b884 --- /dev/null +++ b/include/dolphin/os/OSExpansion.h @@ -0,0 +1,79 @@ +#ifndef _DOLPHIN_OSEXPANSION +#define _DOLPHIN_OSEXPANSION + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define EXI_MEMORY_CARD_59 0x00000004 +#define EXI_MEMORY_CARD_123 0x00000008 +#define EXI_MEMORY_CARD_251 0x00000010 +#define EXI_MEMORY_CARD_507 0x00000020 + +#define EXI_MEMORY_CARD_1019 0x00000040 +#define EXI_MEMORY_CARD_2043 0x00000080 + +#define EXI_MEMORY_CARD_1019A 0x00000140 +#define EXI_MEMORY_CARD_1019B 0x00000240 +#define EXI_MEMORY_CARD_1019C 0x00000340 +#define EXI_MEMORY_CARD_1019D 0x00000440 +#define EXI_MEMORY_CARD_1019E 0x00000540 +#define EXI_MEMORY_CARD_1019F 0x00000640 +#define EXI_MEMORY_CARD_1019G 0x00000740 + +#define EXI_MEMORY_CARD_2043A 0x00000180 +#define EXI_MEMORY_CARD_2043B 0x00000280 +#define EXI_MEMORY_CARD_2043C 0x00000380 +#define EXI_MEMORY_CARD_2043D 0x00000480 +#define EXI_MEMORY_CARD_2043E 0x00000580 +#define EXI_MEMORY_CARD_2043F 0x00000680 +#define EXI_MEMORY_CARD_2043G 0x00000780 + +#define EXI_USB_ADAPTER 0x01010000 +#define EXI_NPDP_GDEV 0x01020000 + +#define EXI_MODEM 0x02020000 +#define EXI_ETHER 0x04020200 +#define EXI_ETHER_VIEWER 0x04220001 +#define EXI_STREAM_HANGER 0x04130000 + +#define EXI_MARLIN 0x03010000 + +#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_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 + +BOOL EXIProbe(s32 chan); +s32 EXIProbeEx(s32 chan); + +s32 EXIGetType(s32 chan, u32 dev, u32* type); +char* EXIGetTypeString(u32 type); +u32 EXIClearInterrupts(s32 chan, BOOL exi, BOOL tc, BOOL ext); +s32 EXIGetID(s32 chan, u32 dev, u32* id); + +typedef void (*EXICallback)(s32 chan, OSContext* context); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_OSEXPANSION diff --git a/include/dolphin/os/OSFastCast.h b/include/dolphin/os/OSFastCast.h new file mode 100644 index 000000000..79e61fe79 --- /dev/null +++ b/include/dolphin/os/OSFastCast.h @@ -0,0 +1,86 @@ +#ifndef _DOLPHIN_OSFASTCAST +#define _DOLPHIN_OSFASTCAST + +#ifdef __cplusplus +extern "C" { +#endif + +#include "dolphin/types.h" + +#define OS_GQR_F32 0x0000 +#define OS_GQR_U8 0x0004 +#define OS_GQR_U16 0x0005 +#define OS_GQR_S8 0x0006 +#define OS_GQR_S16 0x0007 + +#define OS_FASTCAST_U8 2 +#define OS_FASTCAST_U16 3 +#define OS_FASTCAST_S8 4 +#define OS_FASTCAST_S16 5 +// clang-format off +static inline void OSInitFastCast(void) { +#ifdef __MWERKS__ + asm + { + li r3, OS_GQR_U8 + oris r3, r3, OS_GQR_U8 + mtspr GQR2, r3 + + li r3, OS_GQR_U16 + oris r3, r3, OS_GQR_U16 + mtspr GQR3, r3 + + li r3, OS_GQR_S8 + oris r3, r3, OS_GQR_S8 + mtspr GQR4, r3 + + li r3, OS_GQR_S16 + oris r3, r3, OS_GQR_S16 + mtspr GQR5, r3 + } +#else + +#endif +} +// clang-format off + + +static inline s16 __OSf32tos16(register f32 inF) +{ + register s16 out; + u32 tmp; + register u32* tmpPtr = &tmp; + // clang-format off + asm { + psq_st inF, 0(tmpPtr), 0x1, OS_FASTCAST_S16 + lha out, 0(tmpPtr) + } + // clang-format on + + return out; +} + +static inline void OSf32tos16(f32 *f, s16 *out) { *out = __OSf32tos16(*f); } + +static inline u8 __OSf32tou8(register f32 inF) +{ + register u8 out; + u32 tmp; + register u32 *tmpPtr = &tmp; + // clang-format off + asm { + psq_st inF, 0(tmpPtr), 0x1, OS_FASTCAST_U8 + lbz out, 0(tmpPtr) + } + // clang-format on + + return out; +} + +static inline void OSf32tou8(f32 *f, u8 *out) { *out = __OSf32tou8(*f); } + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_OSFASTCAST diff --git a/include/dolphin/os/OSFont.h b/include/dolphin/os/OSFont.h index 1fff41a62..ba312bde0 100644 --- a/include/dolphin/os/OSFont.h +++ b/include/dolphin/os/OSFont.h @@ -1,58 +1,58 @@ -#ifndef _DOLPHIN_OSFONT_H_ -#define _DOLPHIN_OSFONT_H_ +#ifndef _DOLPHIN_OSFONT +#define _DOLPHIN_OSFONT -#include -#include +#include #ifdef __cplusplus extern "C" { #endif +typedef struct OSFontHeader +{ + u16 fontType; // _00 + u16 firstChar; // _02, first char code defined in font. + u16 lastChar; // _04, last char code defined in font. + u16 invalChar; // _06, code to sub for invalid chars. + u16 ascent; // _08 + u16 descent; // _0A + u16 width; // _0C, max width. + u16 leading; // _0E + u16 cellWidth; // _10 + u16 cellHeight; // _12 + u32 sheetSize; // _14 + u16 sheetFormat; // _18, see GX_TF_* part of GXTexFmt enum + u16 sheetColumn; // _1A + u16 sheetRow; // _1C + u16 sheetWidth; // _1E + u16 sheetHeight; // _20 + u16 widthTable; // _22 + u32 sheetImage; // _24 + u32 sheetFullSize; // _28 + u8 c0; // _2C, font color components? + u8 c1; // _2D + u8 c2; // _2E + u8 c3; // _2F +} OSFontHeader; + +#define OS_FONT_ENCODE_NULL -1 #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 { - 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; +#define OS_FONT_ENCODE_UTF8 3u // UTF-8 [RFC 3629] +#define OS_FONT_ENCODE_UTF16 4u // UTF-16BE [RFC 2781] +#define OS_FONT_ENCODE_UTF32 5u // UTF-32 +#define OS_FONT_ENCODE_MAX 5u +#define OS_FONT_ENCODE_VOID 0xffffu + +#define OS_FONT_PROPORTIONAL FALSE +#define OS_FONT_FIXED TRUE u16 OSGetFontEncode(void); 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 +#endif // _DOLPHIN_OSFONT diff --git a/include/dolphin/os/OSFst.h b/include/dolphin/os/OSFst.h new file mode 100644 index 000000000..ee3ca6f80 --- /dev/null +++ b/include/dolphin/os/OSFst.h @@ -0,0 +1,19 @@ +#ifndef _DOLPHIN_OSFST_H +#define _DOLPHIN_OSFST_H + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +typedef struct OSFstEntry +{ + int entryNum; + int nextEntryNum; + char *fileNameMaybe; +} OSFstEntry; + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif \ No newline at end of file diff --git a/include/dolphin/os/OSInterrupt.h b/include/dolphin/os/OSInterrupt.h index fb74135a2..9e5d2aa03 100644 --- a/include/dolphin/os/OSInterrupt.h +++ b/include/dolphin/os/OSInterrupt.h @@ -1,44 +1,41 @@ -#ifndef _DOLPHIN_OSINTERRUPT_H_ -#define _DOLPHIN_OSINTERRUPT_H_ +#ifndef _DOLPHIN_OSINTERRUPT +#define _DOLPHIN_OSINTERRUPT +#include #include -#include #ifdef __cplusplus extern "C" { #endif -typedef s16 __OSInterrupt; -typedef u32 OSInterruptMask; - -#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_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_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)) @@ -47,9 +44,6 @@ typedef u32 OSInterruptMask; #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) @@ -94,8 +88,11 @@ typedef u32 OSInterruptMask; OS_INTERRUPTMASK_PI_PE_TOKEN | OS_INTERRUPTMASK_PI_PE_FINISH | OS_INTERRUPTMASK_PI_DEBUG | \ OS_INTERRUPTMASK_PI_HSP) +typedef s16 __OSInterrupt; typedef void (*__OSInterruptHandler)(__OSInterrupt interrupt, OSContext* context); +typedef u32 OSInterruptMask; + extern volatile __OSInterrupt __OSLastInterrupt; extern volatile u32 __OSLastInterruptSrr0; extern volatile OSTime __OSLastInterruptTime; @@ -115,4 +112,4 @@ OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask mask); } #endif -#endif +#endif // _DOLPHIN_OSINTERRUPT diff --git a/include/dolphin/os/OSMemory.h b/include/dolphin/os/OSMemory.h index a5debebc9..5e34d092a 100644 --- a/include/dolphin/os/OSMemory.h +++ b/include/dolphin/os/OSMemory.h @@ -1,7 +1,7 @@ -#ifndef _DOLPHIN_OSMEMORY_H_ -#define _DOLPHIN_OSMEMORY_H_ +#ifndef _DOLPHIN_OSMEMORY +#define _DOLPHIN_OSMEMORY -#include +#include "types.h" #ifdef __cplusplus extern "C" { @@ -18,11 +18,11 @@ extern "C" { #define OS_PROTECT_CONTROL_RDWR (OS_PROTECT_CONTROL_READ | OS_PROTECT_CONTROL_WRITE) void OSProtectRange(u32 chan, void* addr, u32 nBytes, u32 control); -u32 OSGetPhysicalMemSize(void); u32 OSGetConsoleSimulatedMemSize(void); +u32 OSGetPhysicalMemSize(void); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_OSMEMORY diff --git a/include/dolphin/os/OSMessage.h b/include/dolphin/os/OSMessage.h index 192f998fb..f67a84e38 100644 --- a/include/dolphin/os/OSMessage.h +++ b/include/dolphin/os/OSMessage.h @@ -1,28 +1,34 @@ -#ifndef _DOLPHIN_OSMESSAGE_H_ -#define _DOLPHIN_OSMESSAGE_H_ - -#include +#ifndef _DOLPHIN_OSMESSAGE +#define _DOLPHIN_OSMESSAGE #ifdef __cplusplus extern "C" { #endif -typedef struct { - OSThreadQueue queueSend; - OSThreadQueue queueReceive; - void* msgArray; - s32 msgCount; - s32 firstIndex; - s32 usedCount; -} OSMessageQueue; +#include +typedef struct OSMessageQueue OSMessageQueue; +typedef void* OSMessage; + +struct OSMessageQueue { + OSThreadQueue queueSend; + OSThreadQueue queueReceive; + OSMessage* msgArray; + s32 msgCount; + s32 firstIndex; + s32 usedCount; +}; + +// Flags to turn blocking on/off when sending/receiving message +#define OS_MESSAGE_NOBLOCK 0 +#define OS_MESSAGE_BLOCK 1 -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); +void OSInitMessageQueue(OSMessageQueue* mq, OSMessage* msgArray, s32 msgCount); +BOOL OSSendMessage(OSMessageQueue* mq, OSMessage msg, s32 flags); +BOOL OSJamMessage(OSMessageQueue* mq, OSMessage msg, s32 flags); +BOOL OSReceiveMessage(OSMessageQueue* mq, OSMessage* msg, s32 flags); #ifdef __cplusplus } #endif -#endif // _DOLPHIN_OSMESSAGE_H_ +#endif // _DOLPHIN_OSMESSAGE diff --git a/include/dolphin/os/OSModule.h b/include/dolphin/os/OSModule.h index 6e66e9b00..7baf2a9fc 100644 --- a/include/dolphin/os/OSModule.h +++ b/include/dolphin/os/OSModule.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_OSMODULE_H_ -#define _DOLPHIN_OSMODULE_H_ +#ifndef _DOLPHIN_OSMODULE +#define _DOLPHIN_OSMODULE #include @@ -7,7 +7,7 @@ extern "C" { #endif -#define OS_MODULE_VERSION 3 +#define OS_MODULE_VERSION 2 typedef struct OSModuleHeader OSModuleHeader; typedef u32 OSModuleID; @@ -19,59 +19,59 @@ typedef struct OSImportInfo OSImportInfo; typedef struct OSRel OSRel; struct OSModuleQueue { - OSModuleInfo* head; - OSModuleInfo* tail; + OSModuleInfo* head; + OSModuleInfo* tail; }; struct OSModuleLink { - OSModuleInfo* next; - OSModuleInfo* prev; + 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 + 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 + // 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 + u32 align; // module alignment constraint + u32 bssAlign; // bss alignment constraint #endif - // OS_MODULE_VERSION == 3 + // OS_MODULE_VERSION == 3 #if (3 <= OS_MODULE_VERSION) - u32 fixSize; + u32 fixSize; #endif }; #define OSGetSectionInfo(module) ((OSSectionInfo*)(((OSModuleInfo*)(module))->sectionInfoOffset)) struct OSSectionInfo { - u32 offset; - u32 size; + u32 offset; + u32 size; }; // OSSectionInfo.offset bit @@ -79,15 +79,15 @@ struct OSSectionInfo { #define OS_SECTIONINFO_OFFSET(offset) ((offset) & ~0x1) struct OSImportInfo { - OSModuleID id; // external module id - u32 offset; // offset to OSRel instructions + 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; + u16 offset; // byte offset from the previous entry + u8 type; + u8 section; + u32 addend; }; #define R_DOLPHIN_NOP 201 // C9h current offset += OSRel.offset @@ -95,13 +95,11 @@ struct OSRel { #define R_DOLPHIN_END 203 // CBh #define R_DOLPHIN_MRKREF 204 // CCh -void OSSetStringTable(void* stringTable); +void OSSetStringTable(const 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); @@ -114,4 +112,4 @@ void OSNotifyUnlink(OSModuleInfo* module); } #endif -#endif +#endif // _DOLPHIN_OSMODULE diff --git a/include/dolphin/os/OSMutex.h b/include/dolphin/os/OSMutex.h index ef5565eb6..9ee6ffe3e 100644 --- a/include/dolphin/os/OSMutex.h +++ b/include/dolphin/os/OSMutex.h @@ -1,22 +1,24 @@ -#ifndef _DOLPHIN_OSMUTEX_H_ -#define _DOLPHIN_OSMUTEX_H_ +#ifndef _DOLPHIN_OSMUTEX +#define _DOLPHIN_OSMUTEX -#include +#include "types.h" + +#include "dolphin/os/OSThread.h" #ifdef __cplusplus extern "C" { #endif struct OSMutex { - /* 0x00 */ OSThreadQueue queue; - /* 0x08 */ OSThread* thread; - /* 0x0C */ s32 count; - /* 0x10 */ OSMutexLink link; + OSThreadQueue queue; + OSThread* thread; // the current owner + s32 count; // lock count + OSMutexLink link; // for OSThread.queueMutex }; -typedef struct OSCond { - OSThreadQueue queue; -} OSCond; +struct OSCond { + OSThreadQueue queue; +}; void OSInitMutex(OSMutex* mutex); void OSLockMutex(OSMutex* mutex); @@ -30,4 +32,4 @@ void OSSignalCond(OSCond* cond); } #endif -#endif +#endif // _DOLPHIN_OSMUTEX diff --git a/include/dolphin/os/OSPriv.h b/include/dolphin/os/OSPriv.h new file mode 100644 index 000000000..8b914f258 --- /dev/null +++ b/include/dolphin/os/OSPriv.h @@ -0,0 +1,18 @@ +#ifndef _DOLPHIN_OSPRIV +#define _DOLPHIN_OSPRIV + +#include "dolphin/os.h" + +#ifdef __cplusplus +extern "C" { +#endif + +__OSExceptionHandler __OSGetExceptionHandler(__OSException exception); +OSTime __OSGetSystemTime(); +OSTime __OSTimeToSystemTime(OSTime); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_OSPRIV diff --git a/include/dolphin/os/OSReset.h b/include/dolphin/os/OSReset.h index 15c2ba62f..3613e1d37 100644 --- a/include/dolphin/os/OSReset.h +++ b/include/dolphin/os/OSReset.h @@ -1,39 +1,51 @@ -#ifndef _DOLPHIN_OSRESET_H_ -#define _DOLPHIN_OSRESET_H_ +#ifndef _DOLPHIN_OSRESET +#define _DOLPHIN_OSRESET -#include +#include #ifdef __cplusplus extern "C" { #endif -#define OS_RESET_RESTART 0 +#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_HOTRESET 1 #define OS_RESET_SHUTDOWN 2 -typedef struct OSResetFunctionInfo OSResetFunctionInfo; -typedef struct OSResetFunctionQueue { - OSResetFunctionInfo* head; - OSResetFunctionInfo* tail; -} OSResetFunctionQueue; +#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 BOOL (*OSResetFunction)(BOOL); +extern BOOL __OSIsGcam; + +typedef BOOL (*OSResetFunction)(BOOL final); +typedef struct OSResetFunctionInfo OSResetFunctionInfo; struct OSResetFunctionInfo { - OSResetFunction func; - u32 priority; - OSResetFunctionInfo* next; - OSResetFunctionInfo* prev; + // public + OSResetFunction func; + u32 priority; + + // private + OSResetFunctionInfo* next; + OSResetFunctionInfo* prev; }; -void OSRegisterResetFunction(OSResetFunctionInfo* info); -void OSUnregisterResetFunction(OSResetFunctionInfo* info); -void OSResetSystem(int reset, u32 resetCode, BOOL forceMenu); -u32 OSGetResetCode(); -u32 OSSetBootDol(u32 dolOffset); +void OSResetSystem(BOOL reset, u32 resetCode, BOOL forceMenu); +void OSRegisterResetFunction(OSResetFunctionInfo *func); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_OSRESET diff --git a/include/dolphin/os/OSResetSW.h b/include/dolphin/os/OSResetSW.h index 3c630b857..5cf0334ae 100644 --- a/include/dolphin/os/OSResetSW.h +++ b/include/dolphin/os/OSResetSW.h @@ -1,6 +1,7 @@ -#ifndef _DOLPHIN_OSRESETSW_H_ -#define _DOLPHIN_OSRESETSW_H_ +#ifndef _DOLPHIN_OSRESETSW +#define _DOLPHIN_OSRESETSW +#include #include #ifdef __cplusplus @@ -9,12 +10,12 @@ extern "C" { typedef void (*OSResetCallback)(void); -OSResetCallback OSSetResetCallback(OSResetCallback callback); -BOOL OSGetResetSwitchState(void); BOOL OSGetResetButtonState(void); +BOOL OSGetResetSwitchState(void); +OSResetCallback OSSetResetCallback(OSResetCallback callback); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_OSRESETSW diff --git a/include/dolphin/os/OSSerial.h b/include/dolphin/os/OSSerial.h index 7c38395f7..f0a6a4d3c 100644 --- a/include/dolphin/os/OSSerial.h +++ b/include/dolphin/os/OSSerial.h @@ -1,6 +1,69 @@ -#ifndef _DOLPHIN_OSSERIAL_H -#define _DOLPHIN_OSSERIAL_H +#ifndef _DOLPHIN_OSSERIAL +#define _DOLPHIN_OSSERIAL -#include +#include -#endif // _DOLPHIN_OSSERIAL_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) + +u32 SIProbe(s32 chan); +char* SIGetTypeString(u32 type); +void SIRefreshSamplingRate(void); +void SISetSamplingRate(u32 msec); + +#ifdef __cplusplus +} +#endif +#endif // _DOLPHIN_OSSERIAL diff --git a/include/dolphin/os/OSThread.h b/include/dolphin/os/OSThread.h index 5511c7595..c149ba068 100644 --- a/include/dolphin/os/OSThread.h +++ b/include/dolphin/os/OSThread.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_OSTHREAD_H_ -#define _DOLPHIN_OSTHREAD_H_ +#ifndef _DOLPHIN_OSTHREAD +#define _DOLPHIN_OSTHREAD #include @@ -7,106 +7,121 @@ extern "C" { #endif -typedef s32 OSPriority; +#define OS_THREAD_SPECIFIC_MAX 2 typedef struct OSThread OSThread; -typedef struct OSMutex OSMutex; typedef struct OSThreadQueue OSThreadQueue; -typedef struct OSMutexQueue OSMutexQueue; typedef struct OSThreadLink OSThreadLink; +typedef s32 OSPriority; // 0 highest, 31 lowest + +typedef struct OSMutex OSMutex; +typedef struct OSMutexQueue OSMutexQueue; typedef struct OSMutexLink OSMutexLink; +typedef struct OSCond OSCond; + +// Idle function type. +typedef void (*OSIdleFunction)(void *param); + +// Start function. +typedef void *(*OSThreadStartFunction)(void *); + +// Thread switching function. +typedef void (*OSSwitchThreadCallback)(OSThread *from, OSThread *to); struct OSThreadQueue { - OSThread* head; - OSThread* tail; + OSThread* head; + OSThread* tail; }; struct OSThreadLink { - OSThread* next; - OSThread* prev; + OSThread* next; + OSThread* prev; }; struct OSMutexQueue { - OSMutex* head; - OSMutex* tail; + OSMutex* head; + OSMutex* tail; }; struct OSMutexLink { - OSMutex* next; - OSMutex* prev; + OSMutex* next; + OSMutex* prev; }; 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]; + OSContext context; + u16 state; + u16 attr; + s32 suspend; + OSPriority priority; + OSPriority base; + void* val; + OSThreadQueue* queue; + OSThreadLink link; + OSThreadQueue queueJoin; + OSMutex* mutex; + OSMutexQueue queueMutex; + OSThreadLink linkActive; + u8* stackBase; + u32* stackEnd; + s32 error; + void* specific[OS_THREAD_SPECIFIC_MAX]; }; -enum OS_THREAD_STATE { - OS_THREAD_STATE_READY = 1, - OS_THREAD_STATE_RUNNING = 2, - OS_THREAD_STATE_WAITING = 4, - OS_THREAD_STATE_MORIBUND = 8, +enum OS_THREAD_STATE +{ + OS_THREAD_STATE_NULL = 0, + OS_THREAD_STATE_READY = 1, + OS_THREAD_STATE_RUNNING = 2, + OS_THREAD_STATE_WAITING = 4, + OS_THREAD_STATE_MORIBUND = 8, // set for death. }; +#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 -#define OS_THREAD_SPECIFIC_MAX 2 +//////// THREAD FUNCTIONS //////// +// Basic thread functions. +OSSwitchThreadCallback OSSetSwitchThreadCallback(OSSwitchThreadCallback); +void OSInitThreadQueue(OSThreadQueue *queue); +OSThread *OSGetCurrentThread(); +BOOL OSIsThreadTerminated(OSThread *thread); + +// Scheduler functions. +s32 OSDisableScheduler(); +s32 OSEnableScheduler(); + +// Thread manip functions. +void OSYieldThread(); +BOOL OSCreateThread(OSThread *thread, OSThreadStartFunction func, void *param, void *stack, u32 stackSize, OSPriority prio, u16 attr); +void OSExitThread(void *val); +void OSCancelThread(OSThread *thread); +void OSDetachThread(OSThread *thread); +s32 OSResumeThread(OSThread *thread); +s32 OSSuspendThread(OSThread *thread); +void OSSleepThread(OSThreadQueue *queue); +void OSWakeupThread(OSThreadQueue *queue); -#define OS_THREAD_ATTR_DETACH 0x0001u +void OSClearStack(u8 val); -#define OS_THREAD_STACK_MAGIC 0xDEADBABE +// Priority functions. +OSPriority OSGetThreadPriority(OSThread *thread); -typedef void (*OSSwitchThreadCallback)(OSThread*, OSThread*); -typedef void (*OSIdleFunction)(void*); - -void OSInitThreadQueue(OSThreadQueue* queue); -void OSSleepThread(OSThreadQueue* queue); -void OSWakeupThread(OSThreadQueue* queue); -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); -OSThread* OSSetIdleFunction(OSIdleFunction idleFunction, void* param, void* stack, u32 stackSize); -OSThread* OSGetIdleFunction(void); -s32 OSCheckActiveThreads(void); -void OSSetThreadSpecific(s32 index, void* ptr); -void* OSGetThreadSpecific(s32 index); - -OSSwitchThreadCallback OSSetSwitchThreadCallback(OSSwitchThreadCallback callback); - -#define IsSuspended(suspend) (suspend > 0) +// Unused/inlined in P2. +BOOL OSIsThreadSuspended(OSThread *thread); +BOOL OSJoinThread(OSThread *thread, void **val); +BOOL OSSetThreadPriority(OSThread *thread, OSPriority prio); +OSThread *OSSetIdleFunction(OSIdleFunction idleFunc, void *param, void *stack, u32 stackSize); +OSThread *OSGetIdleFunction(); +long OSCheckActiveThreads(); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_OSTHREAD diff --git a/include/dolphin/os/OSTime.h b/include/dolphin/os/OSTime.h index 118adee7c..44e65a700 100644 --- a/include/dolphin/os/OSTime.h +++ b/include/dolphin/os/OSTime.h @@ -1,44 +1,39 @@ -#ifndef _DOLPHIN_OSTIME_H_ -#define _DOLPHIN_OSTIME_H_ - +#ifndef _DOLPHIN_OSTIME_H +#define _DOLPHIN_OSTIME_H #include - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -// Time base frequency = 1/4 bus clock -#define OS_TIME_SPEED (OS_BUS_CLOCK / 4) - -// 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 s64 OSTime; +typedef u32 OSTick; -// 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) +typedef struct OSCalendarTime +{ + int sec; // seconds after the minute [0, 61] + int min; // minutes after the hour [0, 59] + int hour; // hours since midnight [0, 23] + int mday; // day of the month [1, 31] + int mon; // month since January [0, 11] + int year; // years in AD [1, ...] + int wday; // days since Sunday [0, 6] + int yday; // days since January 1 [0, 365] -#define USEC_MAX 1000 -#define MSEC_MAX 1000 -#define MONTH_MAX 12 -#define WEEK_DAY_MAX 7 -#define YEAR_DAY_MAX 365 + int msec; // milliseconds after the second [0,999] + int usec; // microseconds after the millisecond [0,999] +} OSCalendarTime; -#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) +OSTime OSGetTime(void); +OSTick OSGetTick(void); -#define BIAS 0xB2575 +OSTime __OSGetSystemTime(void); +OSTime __OSTimeToSystemTime(OSTime time); -#define __OSSystemTime (OSTime*)0x800030D8 +void OSTicksToCalendarTime(OSTime time, OSCalendarTime *cal); +OSTime OSCalendarTimeToTicks(const OSCalendarTime *cal); #ifdef __cplusplus } #endif - -#endif // _DOLPHIN_OSTIME_H_ +#endif diff --git a/include/dolphin/os/init/__start.h b/include/dolphin/os/init/__start.h new file mode 100644 index 000000000..3c84bc243 --- /dev/null +++ b/include/dolphin/os/init/__start.h @@ -0,0 +1,46 @@ +#ifndef _DOLPHIN__START +#define _DOLPHIN__START + +#include "dolphin/db.h" +#include "types.h" + +#define PAD3_BUTTON_ADDR 0x800030E4 +#define OS_RESET_RESTART 0 +#define EXCEPTIONMASK_ADDR 0x80000044 +#define BOOTINFO2_ADDR 0x800000F4 +#define OS_BI2_DEBUGFLAG_OFFSET 0xC +#define ARENAHI_ADDR 0x80000034 +#define DEBUGFLAG_ADDR 0x800030E8 +#define DVD_DEVICECODE_ADDR 0x800030E6 + +#define MSR_FP 0x2000 + +extern void InitMetroTRK(); + +u16 Pad3Button : PAD3_BUTTON_ADDR; +static u8 Debug_BBA = 0; + +extern void memset(void *, int, int); +extern int main(int argc, char *argv[]); +extern void exit(int); +extern void __init_user(void); +extern void OSInit(void); +extern void DBInit(void); +extern void OSResetSystem(BOOL reset, u32 resetCode, BOOL forceMenu); +extern void __OSCacheInit(void); +extern void __OSPSInit(void); + +__declspec(section ".init") extern void __check_pad3(void); +__declspec(section ".init") extern void __set_debug_bba(void); +__declspec(section ".init") extern u8 __get_debug_bba(void); +__declspec(section ".init") extern void __start(void); +__declspec(section ".init") extern void __init_registers(void); +__declspec(section ".init") extern void __init_data(void); +__declspec(section ".init") extern void __init_hardware(void); +__declspec(section ".init") extern void __flush_cache(void *address, unsigned int size); + +__declspec(section ".init") extern char _stack_addr[]; +__declspec(section ".init") extern char _SDA_BASE_[]; +__declspec(section ".init") extern char _SDA2_BASE_[]; + +#endif // _DOLPHIN__START \ No newline at end of file diff --git a/include/dolphin/pad.h b/include/dolphin/pad.h index d966b8094..117c10e76 100644 --- a/include/dolphin/pad.h +++ b/include/dolphin/pad.h @@ -14,8 +14,8 @@ extern "C" { #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_CHAN0_BIT 0x80000000 @@ -23,30 +23,31 @@ extern "C" { #define PAD_CHAN2_BIT 0x20000000 #define PAD_CHAN3_BIT 0x10000000 -#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_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 PAD_ERR_NOT_READY -2 +#define PAD_ERR_TRANSFER -3 #define RES_WIRELESS_LITE 0x40000 -typedef struct PADStatus { +typedef struct PADStatus +{ /* 0x00 */ u16 button; /* 0x02 */ s8 stickX; /* 0x03 */ s8 stickY; @@ -59,7 +60,8 @@ typedef struct PADStatus { /* 0x0A */ s8 err; } PADStatus; -typedef struct PADClampRegion { +typedef struct PADClampRegion +{ u8 minTrigger; u8 maxTrigger; s8 minStick; diff --git a/include/dolphin/sipriv.h b/include/dolphin/sipriv.h new file mode 100644 index 000000000..8f971da1a --- /dev/null +++ b/include/dolphin/sipriv.h @@ -0,0 +1,42 @@ +#ifndef _DOLPHIN_SIPRIV +#define _DOLPHIN_SIPRIV + +#include "dolphin/os.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*SICallback)(s32 chan, u32 sr, OSContext* context); +typedef void (*SITypeAndStatusCallback)(s32 chan, u32 type); + +void SIInit(void); +u32 SIGetStatus(s32 chan); + +BOOL SIBusy(void); +BOOL SIIsChanBusy(s32 chan); + +BOOL SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, + SICallback callback, OSTime delay); +u32 SISync(void); + +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 SIRegisterPollingHandler(__OSInterruptHandler handler); +BOOL SIUnregisterPollingHandler(__OSInterruptHandler handler); + +u32 SIGetType(s32 chan); +u32 SIGetTypeAsync(s32 chan, SITypeAndStatusCallback callback); +u32 SIDecodeType(u32 type); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_SIPRIV \ No newline at end of file diff --git a/include/dolphin/tcp/tcp.h b/include/dolphin/tcp/tcp.h new file mode 100644 index 000000000..2de25604f --- /dev/null +++ b/include/dolphin/tcp/tcp.h @@ -0,0 +1,29 @@ +#ifndef _DOLPHIN_TCP_H_ +#define _DOLPHIN_TCP_H_ + +#include + +typedef struct TCPHeader { + u16 src; + u16 dst; + s32 seq; + s32 ack; + u16 flag; + u16 win; + u16 sum; + u16 urg; +} TCPHeader; + +typedef struct TCPResetInfo { + u8 addr[6]; + u8 dstAddr[4]; + u8 srcAddr[4]; + u16 dstPort; + u16 srcPort; + s32 seq; + s32 ack; + u16 flag; + u16 id; +} TCPResetInfo; + +#endif diff --git a/include/dolphin/thp.h b/include/dolphin/thp.h new file mode 100644 index 000000000..abdab02b8 --- /dev/null +++ b/include/dolphin/thp.h @@ -0,0 +1,129 @@ +#ifndef _DOLPHIN_THP_H +#define _DOLPHIN_THP_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef u8 THPSample; + typedef s16 THPCoeff; + typedef float THPQuantTab[64]; + + typedef struct _THPHuffmanTab + { + u8 quick[32]; + u8 increment[32]; + u8 *Vij; + s32 maxCode[18]; + s32 valPtr[18]; + u8 Vij1; + u8 pad[11]; + } THPHuffmanTab; + + typedef struct _THPComponent + { + u8 quantizationTableSelector; + u8 DCTableSelector; + u8 ACTableSelector; + THPCoeff predDC; + } THPComponent; + + typedef struct _THPFileInfo + { + THPQuantTab quantTabs[3]; + THPHuffmanTab huffmanTabs[4]; + THPComponent components[3]; + u16 xPixelSize; + u16 yPixelSize; + u16 MCUsPerRow; + u16 decompressedY; + u8 *c; + u32 currByte; + u32 cnt; + u8 validHuffmanTabs; + u8 RST; + u16 nMCU; + u16 currMCU; + u8 *dLC[3]; + } THPFileInfo; + + typedef struct + { + u32 offsetNextChannel; + u32 sampleSize; + s16 lCoef[8][2]; + s16 rCoef[8][2]; + s16 lYn1; + s16 lYn2; + s16 rYn1; + s16 rYn2; + } THPAudioRecordHeader; + + typedef struct + { + u8 *encodeData; + u32 offsetNibbles; + u8 predictor; + u8 scale; + s16 yn1; + s16 yn2; + } THPAudioDecodeInfo; + + BOOL THPInit(); + s32 THPVideoDecode(void *file, void *tileY, void *tileU, void *tileV, void *work); + u32 THPAudioDecode(s16 *audioBuffer, u8 *audioFrame, s32 flag); + + s32 __THPAudioGetNewSample(THPAudioDecodeInfo *); + void __THPAudioInitialize(THPAudioDecodeInfo *, u8 *); + + void __THPSetupBuffers(void); + u8 __THPReadFrameHeader(void); + u8 __THPReadScaneHeader(void); + u8 __THPReadQuantizationTable(void); + u8 __THPReadHuffmanTableSpecification(void); + void __THPHuffGenerateSizeTable(void); + void __THPHuffGenerateCodeTable(void); + void __THPHuffGenerateDecoderTables(u8 tabIndex); + void __THPRestartDefinition(void); + void __THPPrepBitStream(void); + static void __THPDecompressYUV(void *, void *, void *); + void __THPGQRRestore(void); + void __THPDecompressiMCURow512x448(void); + void __THPDecompressiMCURow640x480(void); + void __THPDecompressiMCURowNxN(void); + void __THPInverseDCTNoYPos(THPCoeff *, u32); + void __THPHuffDecodeDCTCompY(THPFileInfo *, THPCoeff *); + void __THPHuffDecodeDCTCompU(THPFileInfo *, THPCoeff *); + void __THPHuffDecodeDCTCompV(THPFileInfo *, THPCoeff *); + + static const u8 __THPJpegNaturalOrder[80] = { + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63}; + + static const f64 __THPAANScaleFactor[8] = { + 1.0f, + 1.387039845f, + 1.306562965f, + 1.175875602f, + 1.0f, + 0.785694958f, + 0.541196100f, + 0.275899379f, + }; + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/include/dolphin/types.h b/include/dolphin/types.h index b77602b10..e402fc670 100644 --- a/include/dolphin/types.h +++ b/include/dolphin/types.h @@ -1,47 +1,46 @@ -#ifndef _DOLPHIN_TYPES_H_ -#define _DOLPHIN_TYPES_H_ +#ifndef DOLPHIN_TYPES_H +#define DOLPHIN_TYPES_H typedef signed char s8; -typedef unsigned char u8; -typedef signed short int s16; -typedef unsigned short int u16; +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 signed long long int s64; -typedef unsigned long long int u64; +typedef unsigned long long u64; +typedef unsigned long size_t; + +typedef volatile u8 vu8; +typedef volatile u16 vu16; +typedef volatile u32 vu32; +typedef volatile u64 vu64; +typedef volatile s8 vs8; +typedef volatile s16 vs16; +typedef volatile s32 vs32; +typedef volatile s64 vs64; typedef float f32; typedef double f64; - -typedef char* Ptr; +typedef volatile f32 vf32; +typedef volatile f64 vf64; typedef int BOOL; -#define FALSE 0 +#ifndef TRUE #define TRUE 1 +#endif // TRUE -#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 ATTRIBUTE_ALIGN(num) __attribute__((aligned(num))) - -#define INT_MAX 2147483647 +#ifndef FALSE +#define FALSE 0 +#endif // FALSE #ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else // __cplusplus #define NULL ((void*)0) -#endif - -#include "stdio.h" -#include "stdarg.h" -#include "string.h" -#include "ctype.h" - -#include "cmath" +#endif // __cplusplus +#endif // NULL -#endif +#endif \ No newline at end of file diff --git a/include/dolphin/vi.h b/include/dolphin/vi.h index af4184426..a2daddeda 100644 --- a/include/dolphin/vi.h +++ b/include/dolphin/vi.h @@ -1,7 +1,174 @@ -#ifndef _DOLPHIN_VI_H_ -#define _DOLPHIN_VI_H_ +#ifndef _DOLPHIN_VI_H +#define _DOLPHIN_VI_H -#include -#include +#ifdef __cplusplus +extern "C" +{ +#endif // ifdef __cplusplus + +#include "types.h" + +#define VI_DISPLAY_PIX_SZ 2 + +#define VI_INTERLACE 0 +#define VI_NON_INTERLACE 1 +#define VI_PROGRESSIVE 2 +#define VI_3D 3 + +#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 + +#define VI_TVMODE(FMT, INT) (((FMT) << 2) + (INT)) + +typedef enum +{ + 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 + + VI_TVMODE_PAL_INT = VI_TVMODE(VI_PAL, VI_INTERLACE), // 4 + VI_TVMODE_PAL_DS = VI_TVMODE(VI_PAL, VI_NON_INTERLACE), // 5 + + VI_TVMODE_MPAL_INT = VI_TVMODE(VI_MPAL, VI_INTERLACE), // 8 + VI_TVMODE_MPAL_DS = VI_TVMODE(VI_MPAL, VI_NON_INTERLACE), // 9 + + VI_TVMODE_DEBUG_INT = VI_TVMODE(VI_DEBUG, VI_INTERLACE), // 12 + + 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 + + VI_TVMODE_EURGB60_INT = VI_TVMODE(VI_EURGB60, VI_INTERLACE), // 20 + VI_TVMODE_EURGB60_DS = VI_TVMODE(VI_EURGB60, VI_NON_INTERLACE), // 21 + + 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, // progressive scan + VI_XFBMODE_DF // interlaced +} VIXFBMode; + +// Structure to use with timing in vi.c (size 0x28). +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; + +// Structure to use with HorVer in vi.c (size 0x58). +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; + +#define VI_FIELD_ABOVE 1 +#define VI_FIELD_BELOW 0 + +// Maximum screen space +#define VI_MAX_WIDTH_NTSC 720 +#define VI_MAX_HEIGHT_NTSC 480 + +#define VI_MAX_WIDTH_PAL 720 +#define VI_MAX_HEIGHT_PAL 574 + +#define VI_MAX_WIDTH_MPAL 720 +#define VI_MAX_HEIGHT_MPAL 480 + +#define VI_MAX_WIDTH_EURGB60 VI_MAX_WIDTH_NTSC +#define VI_MAX_HEIGHT_EURGB60 VI_MAX_HEIGHT_NTSC + +#define VI_DTV_STAT (55) + +typedef void (*VIRetraceCallback)(u32 retraceCount); +typedef void (*VIPositionCallback)(s16 x, s16 y); + +#define VIPadFrameBufferWidth(width) ((u16)(((u16)(width) + 15) & ~15)) + +void VIInit(void); +void VIFlush(void); +void *VIGetNextFrameBuffer(); +void VIWaitForRetrace(void); + +void VIConfigure(const struct _GXRenderModeObj *rm); +void VIConfigurePan(u16 PanPosX, u16 PanPosY, u16 PanSizeX, u16 PanSizeY); +void VISetNextFrameBuffer(void *fb); +void *VIGetCurrentFrameBuffer(); + +void __VIGetCurrentPosition(s16* x, s16* y); + +VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback callback); +VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback callback); + +void VISetBlack(BOOL black); +u32 VIGetRetraceCount(); +u32 VIGetNextField(); +u32 VIGetCurrentLine(); +u32 VIGetTvFormat(); + +u32 VIGetDTVStatus(); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus #endif diff --git a/include/dolphin/vi/vitypes.h b/include/dolphin/vi/vitypes.h index 983a89b7e..51be069e3 100644 --- a/include/dolphin/vi/vitypes.h +++ b/include/dolphin/vi/vitypes.h @@ -3,38 +3,42 @@ #include -#define VI_TVMODE(format, interlace) (((format) << 2) + (interlace)) +#define VI_TVMODE(format, interlace) (((format) << 2) + (interlace)) -#define VI_INTERLACE 0 +#define VI_INTERLACE 0 #define VI_NON_INTERLACE 1 -#define VI_PROGRESSIVE 2 +#define VI_PROGRESSIVE 2 -#define VI_NTSC 0 -#define VI_PAL 1 -#define VI_MPAL 2 -#define VI_DEBUG 3 +#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; +#define VI_EURGB60 5 + +// Already declared in vi.h? + +// 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); diff --git a/include/inline/fastmath.h b/include/inline/fastmath.h index c293bbba2..88af178bb 100644 --- a/include/inline/fastmath.h +++ b/include/inline/fastmath.h @@ -23,7 +23,7 @@ psq_l fp0, 0(src), 0, 0; /* Load src->x and src->y into fp0. */ \ psq_l fp1, 8(src), 1, 0; /* Load src->z only into fp1. */ \ psq_st fp0, 0(dst), 0, 0; /* Store fp0 into dst->x and dst->y. */ \ - psq_st fp1, 8(dst), 1, 0; /* Store only the first half of fp1 into dst->z. */ \ + psq_st fp1, 8(dst), 1, 0; /* Store only the first half of fp1 into dst->z. */ \ } // I can't figure out how to get this as a C-style inline function, so use this in an ASM function or block. diff --git a/include/macros.h b/include/macros.h new file mode 100644 index 000000000..05f9f76c5 --- /dev/null +++ b/include/macros.h @@ -0,0 +1,80 @@ +#ifndef MACROS_H +#define MACROS_H + +#define MAX(x, y) ((x) > (y) ? (x) : (y)) +#define MIN(x, y) ((x) < (y) ? (x) : (y)) + +#define CLAMP(low, high, x) \ + ((x) > (high) ? (high) : ((x) < (low) ? (low) : (x))) + +#define ROUND_UP(x, align) (((x) + (align)-1) & (-(align))) +#define ROUND_UP_PTR(x, align) \ + ((void *)((((u32)(x)) + (align)-1) & (~((align)-1)))) + +#define ROUND_DOWN(x, align) ((x) & (-(align))) +#define ROUND_DOWN_PTR(x, align) ((void *)(((u32)(x)) & (~((align)-1)))) + +#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0])) +#define STRING_SIZE(x) (sizeof(x) - 1) // for char arrays, subtract 1 to act as null terminator? + +#define CLEAR_PATH(x) __memclr((x), sizeof((x))) + +#define ALIGN(x) __attribute__((aligned(x))) +#define ATTRIBUTE_ALIGN(x) __attribute__((aligned(x))) +#ifdef __MWERKS__ +#define DECL_SECTION(x) __declspec(section x) +#define DECL_WEAK __declspec(weak) +#define DONT_INLINE __attribute__((never_inline)) +#else +#define DECL_SECTION(x) +#define DECL_WEAK __attribute__((weak)) +#define DONT_INLINE __attribute__((noinline)) +#endif + +// Align X to the previous N bytes (N must be power of two) +#define ALIGN_PREV(X, N) ((X) & ~((N)-1)) +// Align X to the next N bytes (N must be power of two) +#define ALIGN_NEXT(X, N) ALIGN_PREV(((X) + (N)-1), N) +#define IS_ALIGNED(X, N) (((X) & ((N)-1)) == 0) +#define IS_NOT_ALIGNED(X, N) (((X) & ((N)-1)) != 0) + +#define READU32_BE(ptr, offset) \ + (((u32)ptr[offset] << 24) | ((u32)ptr[offset + 1] << 16) | ((u32)ptr[offset + 2] << 8) | (u32)ptr[offset + 3]); + +#define FLAG_ON(V, F) (((V) & (F)) == 0) +#define FLAG_OFF(V, F) (((V) & (F))) + +// Codewarrior tricks for matching decomp +// (Functions are given prototypes for -requireprotos) +#ifdef __MWERKS__ +// Force BSS order +#define CW_FORCE_BSS(module, ...) \ + void fake_function(...); \ + void FORCE_BSS##module##x(void); \ + void FORCE_BSS##module##x(void) \ + { \ + fake_function(__VA_ARGS__); \ + } +// Force strings into pool +#define CW_FORCE_STRINGS(module, ...) \ + void fake_function(...); \ + void FORCE_STRINGS##module(void); \ + void FORCE_STRINGS##module(void) \ + { \ + fake_function(__VA_ARGS__); \ + } +#define ASM asm +#else +#define CW_FORCE_BSS(module, ...) +#define CW_FORCE_STRINGS(module, ...) +#define ASM +#endif + +// For VSCode +#ifdef __INTELLISENSE__ +#define asm +#define __attribute__(x) +#define __declspec(x) +#endif + +#endif diff --git a/include/mathHelper.h b/include/mathHelper.h new file mode 100644 index 000000000..0ff0d8e21 --- /dev/null +++ b/include/mathHelper.h @@ -0,0 +1,14 @@ +#ifndef MATHHELPER_H +#define MATHHELPER_H + +#include + + +inline void QuaternionReset(Quaternion *pDest) +{ + const Quaternion q = {0.0f, 0.0f, 0.0f, 1.0f}; + *pDest = q; +} + + +#endif \ No newline at end of file diff --git a/include/rwsdk/rwplcore.h b/include/rwsdk/rwplcore.h index 20d679042..12a9352b0 100644 --- a/include/rwsdk/rwplcore.h +++ b/include/rwsdk/rwplcore.h @@ -2,7 +2,7 @@ #define RWPLCORE_H #include -#include +//#include #define rwBIGENDIAN diff --git a/include/std/bitset.h b/include/std/bitset.h new file mode 100644 index 000000000..c813f2f13 --- /dev/null +++ b/include/std/bitset.h @@ -0,0 +1,116 @@ +#ifndef MSL_BITSET_H_ +#define MSL_BITSET_H_ + +#include +#include +#include +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/abort_exit.h" + +namespace std +{ + // TODO: where does this go? + inline void __msl_error(const char *param_0) + { + fprintf(stderr, param_0); + abort(); + } + + template + class __bitset_base + { + public: + __bitset_base(); + + void set(size_t pos, bool val); + void reset(size_t pos); + bool test(size_t pos) const; + bool any() const; + private: + size_t data[N]; + }; + + template + __bitset_base::__bitset_base() + { + std::fill(data, data + N, 0); + } + + template + bool __bitset_base::any() const + { + for (size_t i = 0; i < N; i++) + { + if (data[i] != 0) + return true; + } + return false; + } + + template + bool __bitset_base::test(size_t pos) const + { + size_t i = pos / (sizeof(size_t) * 8); + size_t mask = 1 << (pos % (sizeof(size_t) * 8)); + return data[i] & mask; + } + + template + void __bitset_base::set(size_t pos, bool val) + { + size_t i = pos / (sizeof(size_t) * 8); + size_t mask = 1 << (pos % (sizeof(size_t) * 8)); + if (val) + { + data[i] |= mask; + } + else + { + data[i] &= ~mask; + } + } + + template + void __bitset_base::reset(size_t pos) + { + size_t i = pos / (sizeof(size_t) * 8); + size_t mask = 1 << (pos % (sizeof(size_t) * 8)); + data[i] &= ~mask; + } + + template + class bitset : private __bitset_base<(N - 1) / (sizeof(size_t) * 8) + 1> + { + public: + typedef __bitset_base<(N - 1) / (sizeof(size_t) * 8) + 1> base; + + bitset() {} + bool any() const { return base::any(); } + void set(size_t pos, bool val) + { + if (pos >= N) + { + __msl_error("index out of range of bitset::set"); + } + base::set(pos, val); + } + void reset(size_t pos) + { + if (pos >= N) + { + __msl_error("index out of range of bitset::reset"); + } + base::reset(pos); + } + bool test(size_t pos) const + { + if (pos >= N) + { + __msl_error("index out of range of bitset::test"); + } + return base::test(pos); + } + + }; +} // namespace std + +#endif \ No newline at end of file diff --git a/include/std/math.h b/include/std/math.h new file mode 100644 index 000000000..bc2d3f27a --- /dev/null +++ b/include/std/math.h @@ -0,0 +1,79 @@ +#ifndef STD_MATH_H +#define STD_MATH_H + +// TODO: Get rid of this file, it should use the one from MSL_C instead + +#include +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h" +#include "types.h" + +#ifdef __cplusplus +namespace std +{ +#endif + +#if __MWERKS__ > 0x2301 +extern inline float sqrtf(float x) +{ + static const double _half = .5f; + static const double _three = 3.0f; + if (x > 0.0f) + { + double xd = (double)x; + double guess = __frsqrte(xd); // returns an approximation to + guess = _half * guess * (_three - guess * guess * xd); // now have 12 sig bits + guess = _half * guess * (_three - guess * guess * xd); // now have 24 sig bits + guess = _half * guess * (_three - guess * guess * xd); // now have 32 sig bits + return (float)(xd * guess); + } + else if (x < 0.0) + { + return NAN; + } + else if (isnan(x)) + { + return NAN; + } + else + { + return x; + } +} +#else +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; +} +#endif + +extern inline float inv_sqrtf(float x) { + return 1.0f / sqrtf(x); +} + +#ifdef __cplusplus +extern inline float fabsf(float x) { return ::fabs(x); } +extern inline float fabs(float x) { return fabsf(x); } + +extern inline float atan2f(float y, float x) { return ::atan2(y, x); } +extern inline float cosf(float x) { return ::cos(x); } +extern inline float sinf(float x) { return ::sin(x); } +extern inline float tanf(float x) { return ::tan(x); } +extern inline float tan(float x) { return tanf(x); } +#endif +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/types.h b/include/types.h index c2c1c166d..84a3b6ec0 100644 --- a/include/types.h +++ b/include/types.h @@ -1,6 +1,8 @@ #ifndef BFBB_TYPES_H #define BFBB_TYPES_H +#include "macros.h" + // Note: only include this header inside BFBB-related headers/source code files. // Don't include this in any RenderWare, system, bink, etc. files @@ -41,4 +43,53 @@ typedef double F64; #define WEAK __declspec(weak) +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 size_t; +typedef unsigned long long u64; + +typedef unsigned short ushort; +typedef unsigned int uint; + +typedef volatile u8 vu8; +typedef volatile u16 vu16; +typedef volatile u32 vu32; +typedef volatile u64 vu64; +typedef volatile s8 vs8; +typedef volatile s16 vs16; +typedef volatile s32 vs32; +typedef volatile s64 vs64; + +typedef float f32; +typedef double f64; +typedef volatile f32 vf32; +typedef volatile f64 vf64; + +typedef int BOOL; + +typedef int unknown; + +#ifndef __cplusplus +typedef unsigned short wchar_t; +typedef wchar_t wint_t; +#endif + +// Basic defines to allow newer-like C++ code to be written +#define TRUE 1 +#define FALSE 0 + +#define nullptr 0 +#define null 0 + +#ifndef NULL +#define NULL 0 #endif + +#define UINT32_MAX 0xffffffff + +#endif // !TYPES_H \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/exception b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/exception similarity index 100% rename from include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/exception rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/exception diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/exception.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/exception.h similarity index 100% rename from include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/exception.h rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/exception.h diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/new similarity index 100% rename from include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/new diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/new.h similarity index 94% rename from include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new.h rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/new.h index a347550ef..62c08045c 100644 --- a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new.h +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/new.h @@ -1,7 +1,7 @@ #ifndef _NEW_H #define _NEW_H -#include +#include #include namespace std diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h new file mode 100644 index 000000000..1ded27ed9 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h @@ -0,0 +1,20 @@ +#ifndef _MSL_FILE_POS_H +#define _MSL_FILE_POS_H + +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + + int fseek(FILE *stream, fpos_t offset, int whence); + int _fseek(FILE *stream, fpos_t offset, int whence); + int ftell(FILE *stream); + int _ftell(FILE *stream); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/abort_exit.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/abort_exit.h new file mode 100644 index 000000000..dad87c708 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/abort_exit.h @@ -0,0 +1,17 @@ +#ifndef ABORT_EXIT_H +#define ABORT_EXIT_H + +#ifdef __cplusplus +extern "C" +{ +#endif // ifdef __cplusplus + +void abort(); +void exit(int status); +void __exit(int status); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/alloc.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/alloc.h new file mode 100644 index 000000000..a189b1814 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/alloc.h @@ -0,0 +1,8 @@ +#ifndef _MSL_ALLOC_H +#define _MSL_ALLOC_H + +#include "types.h" + +void free(void*); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h new file mode 100644 index 000000000..aa8b8cae0 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h @@ -0,0 +1,90 @@ +#ifndef _MSL_COMMON_ANSI_FILES_H +#define _MSL_COMMON_ANSI_FILES_H + +#include "types.h" + +typedef unsigned long __file_handle; +typedef unsigned long fpos_t; +typedef struct _IO_FILE _IO_FILE, *P_IO_FILE; + +#define __ungetc_buffer_size 2 + +enum __file_kinds { __closed_file, __disk_file, __console_file, __unavailable_file }; + +enum __file_orientation { __unoriented, __char_oriented, __wide_oriented }; + +typedef struct __file_modes { + u32 open_mode : 2; + u32 io_mode : 3; + u32 buffer_mode : 2; + u32 file_kind : 3; + +#ifdef _MSL_WIDE_CHAR + u32 file_orientation : 2; +#endif /* _MSL_WIDE_CHAR */ + + u32 binary_io : 1; +} file_modes; + +enum __io_states { __neutral, __writing, __reading, __rereading }; + +typedef struct __file_states { + u32 io_state : 3; + u32 free_buffer : 1; + + u8 eof; + u8 error; +} file_states; + +typedef void* __ref_con; +typedef void (*__idle_proc)(void); +typedef int (*__pos_proc)(__file_handle file, fpos_t* position, int mode, __ref_con ref_con); +typedef int (*__io_proc)(__file_handle file, char* buff, size_t* count, __ref_con ref_con); +typedef int (*__close_proc)(__file_handle file); + +struct _IO_FILE { + __file_handle mHandle; // _00 + file_modes mMode; // _04 + file_states mState; // _08 + u8 mIsDynamicallyAllocated; // _0C + u8 mCharBuffer; // _0D + u8 mCharBufferOverflow; // _0E + u8 mUngetcBuffer[__ungetc_buffer_size]; // _0F + wchar_t mUngetcWideBuffer[__ungetc_buffer_size]; // _12 + u32 mPosition; // _18 + char* mBuffer; // _1C + u32 mBufferSize; // _20 + char* mBufferPtr; // _24 + u32 mBufferLength; // _28 + u32 mBufferAlignment; // _2C + u32 mBufferLength2; // _30 + u32 mBufferPosition; // _34 + __pos_proc positionFunc; // _38 + __io_proc readFunc; // _3C + __io_proc writeFunc; // _40 + __close_proc closeFunc; // _44 + __ref_con ref_con; // _48 + _IO_FILE* mNextFile; // _4C +}; + +typedef struct _IO_FILE FILE; + +extern FILE __files[4]; + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +void __convert_from_newlines(char *buffer, size_t *length); + +int fflush(FILE* __stream); +void free(void*); +int __flush_buffer(FILE* file, size_t* length); +void __prep_buffer(FILE* file); +u32 __flush_all(); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_fp.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_fp.h new file mode 100644 index 000000000..95fc4409b --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_fp.h @@ -0,0 +1,40 @@ +#ifndef _MSL_C_ANSI_FP_H +#define _MSL_C_ANSI_FP_H + +#include "types.h" +#include "math.h" +#include "float.h" +#include "fdlibm.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h" + +#define SIGDIGLEN 36 + +typedef struct decimal { + char sign; + char unk1; + s16 exp; + struct { + u8 length; + u8 text[36]; + u8 unk41; + } sig; +} decimal; + +typedef struct decform { + char style; + char unk1; + short digits; +} decform; + +void __ull2dec(decimal*, u64); +void __timesdec(decimal*, const decimal*, const decimal*); +void __str2dec(decimal*, const char*, short); +void __two_exp(decimal*, long); +BOOL __equals_dec(const decimal*, const decimal*); +BOOL __less_dec(const decimal*, const decimal*); +void __minus_dec(decimal*, const decimal*, const decimal*); +void __num2dec_internal(decimal*, double); +void __num2dec(const decform*, double, decimal*); +double __dec2num(const decimal*); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_params.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_params.h new file mode 100644 index 000000000..2d25687a6 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_params.h @@ -0,0 +1,14 @@ +#ifndef ANSI_PARAMS_H +#define ANSI_PARAMS_H + +#define _MSL_CANT_THROW __attribute__((nothrow)) + +#define _MSL_THROW throw() + +#ifndef _MSL_LOCALDATA +#define _MSL_LOCALDATA(_a) _a +#endif + +#define __std(ref) ref + +#endif // ANSI_PARAMS_H \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/arith.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/arith.h new file mode 100644 index 000000000..1c0053537 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/arith.h @@ -0,0 +1,24 @@ +#ifndef _MSL_COMMON_ARITH_H +#define _MSL_COMMON_ARITH_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + int quot; /* quotient */ + int rem; /* remainder */ +} div_t; + +long abs(long __x); +long labs(long __x); +div_t div(s32 __numer, s32 __denom); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/bsearch.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/bsearch.h new file mode 100644 index 000000000..05f918130 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/bsearch.h @@ -0,0 +1,18 @@ +#ifndef MSL_BSEARCH_H +#define MSL_BSEARCH_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif // ifdef __cplusplus + +void *bsearch(const void *key, const void *base0, size_t nmemb, size_t size, + int (*compar)(const void *, const void *)); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cmath b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/cmath similarity index 100% rename from include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cmath rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/cmath diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h new file mode 100644 index 000000000..cc80ccbab --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h @@ -0,0 +1,32 @@ +#ifndef _MSL_CRITICAL_REGIONS_H +#define _MSL_CRITICAL_REGIONS_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +enum critical_regions { + atexit_funcs_access, + malloc_pool_access, + stdin_access, + stdout_access, + stderr_access, + files_access, + console_status_access, + signal_funcs_access, + thread_access, + num_critical_regions +}; + +void __init_critical_regions(void); +void __kill_critical_regions(void); +void __begin_critical_region(int region); +void __end_critical_region(int region); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdlib b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/cstdlib similarity index 100% rename from include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdlib rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/cstdlib diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/cstring similarity index 100% rename from include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/cstring diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ctype_api.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ctype_api.h new file mode 100644 index 000000000..e39701f18 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ctype_api.h @@ -0,0 +1,36 @@ +#ifndef _MSL_CTYPE_API_H +#define _MSL_CTYPE_API_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +int isprint(int c); + +extern unsigned char __ctype_map[256]; +extern unsigned char __lower_map[256]; +extern unsigned char __upper_map[256]; + +#define __control_char 0x01 +#define __motion_char 0x02 +#define __space_char 0x04 +#define __punctuation 0x08 +#define __digit 0x10 +#define __hex_digit 0x20 +#define __lower_case 0x40 +#define __upper_case 0x80 + +#define __letter (__lower_case | __upper_case) +#define __alphanumeric (__letter | __digit) +#define __graphic (__alphanumeric | __punctuation) +#define __printable (__graphic | __space_char) +#define __whitespace (__motion_char | __space_char) +#define __control (__motion_char | __control_char) + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/direct_io.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/direct_io.h new file mode 100644 index 000000000..4679ca0ab --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/direct_io.h @@ -0,0 +1,10 @@ +#ifndef _MSL_DIRECT_IO_H +#define _MSL_DIRECT_IO_H + +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +// fread +size_t fwrite(const void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_io.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_io.h new file mode 100644 index 000000000..d649b4936 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_io.h @@ -0,0 +1,10 @@ +#ifndef _MSL_FILE_IO_H +#define _MSL_FILE_IO_H + +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +int fclose(FILE* file); +int fflush(FILE* file); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_struc.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_struc.h new file mode 100644 index 000000000..a4ec16d7d --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_struc.h @@ -0,0 +1,10 @@ +#ifndef _MSL_COMMON_FILE_STRUC_H +#define _MSL_COMMON_FILE_STRUC_H +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +#define stdin &(__files[0]) +#define stdout &(__files[1]) +#define stderr &(__files[2]) + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/locale_api.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/locale_api.h new file mode 100644 index 000000000..70f19d7e7 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/locale_api.h @@ -0,0 +1,9 @@ +#ifndef _MSL_LOCALE_API_H +#define _MSL_LOCALE_API_H + +#include "types.h" + +typedef int (*__decode_mbyte)(wchar_t*, const char*, size_t); +typedef int (*__encode_mbyte)(char*, wchar_t); + +#endif \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h new file mode 100644 index 000000000..45d502265 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h @@ -0,0 +1,93 @@ +#ifndef _MSL_MATH_API_H +#define _MSL_MATH_API_H + +#include "types.h" +#include "fdlibm.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +int __fpclassifyf(float); +int __signbitd(double); +int __fpclassifyd(double); + +#ifndef MATH_INLINE +#define MATH_INLINE inline +#endif + +MATH_INLINE int __fpclassifyf(f32 x) +{ + switch ((*(s32*)&x) & 0x7f800000) + { + case 0x7f800000: + { + if ((*(s32*)&x) & 0x007fffff) + return 1; + else + return 2; + break; + } + case 0: + { + if ((*(s32*)&x) & 0x007fffff) + return 5; + else + return 3; + break; + } + } + return 4; +} + +MATH_INLINE int __fpclassifyd(f64 x) +{ + switch (__HI(x) & 0x7ff00000) + { + case 0x7ff00000: + { + if ((__HI(x) & 0x000fffff) || (__LO(x) & 0xffffffff)) + return 1; + else + return 2; + break; + } + case 0: + { + if ((__HI(x) & 0x000fffff) || (__LO(x) & 0xffffffff)) + return 5; + else + return 3; + break; + } + } + return 4; +} + +MATH_INLINE float cosf(float __x) +{ + return cos((double)__x); +} + +MATH_INLINE float sinf(float __x) +{ + return sin((double)__x); +} + +MATH_INLINE float tanf(float __x) +{ + return tan((double)__x); +} + +#define fpclassify(x) \ + ((sizeof(x) == sizeof(float)) ? __fpclassifyf((float)(x)) : __fpclassifyd((double)(x))) + +#define isinf(x) ((fpclassify(x) == 2)) +#define isnan(x) ((fpclassify(x) == 1)) +#define isfinite(x) ((fpclassify(x) > 2)) + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mbstring.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mbstring.h new file mode 100644 index 000000000..0c1fb5a54 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mbstring.h @@ -0,0 +1,21 @@ +#ifndef _MSL_MBSTRING_H +#define _MSL_MBSTRING_H + +#include "types.h" +#ifdef __cplusplus +extern "C" { +#endif + +int __mbtowc_noconv(wchar_t*, const char*, size_t); +int __wctomb_noconv(char*, wchar_t); +size_t wcstombs(char* s, const wchar_t* pwcs, size_t n); +int mbstowcs(wchar_t* pwc, const char* s, size_t n); +int wctomb(char* s, wchar_t wchar); +static int unicode_to_UTF8(char* s, wchar_t wchar); +int mbtowc(wchar_t* pwc, const char* s, size_t n); +static int is_utf8_complete(const char* s, size_t n); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mem_funcs.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mem_funcs.h new file mode 100644 index 000000000..6d62aebbc --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mem_funcs.h @@ -0,0 +1,11 @@ +#ifndef _MSL_MEM_FUNCS_H +#define _MSL_MEM_FUNCS_H + +#include "types.h" + +void __copy_longs_aligned(void* dst, const void* src, size_t len); +void __copy_longs_rev_aligned(void* dst, const void* src, size_t len); +void __copy_longs_unaligned(void* dst, const void* src, size_t len); +void __copy_longs_rev_unaligned(void* dst, const void* src, size_t len); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h new file mode 100644 index 000000000..7ef4118f9 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h @@ -0,0 +1,8 @@ +#ifndef _MSL_MATH_API_H +#define _MSL_MATH_API_H + +extern void (*__stdio_exit)(void); + +void __stdio_atexit(); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/printf.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/printf.h new file mode 100644 index 000000000..ce88b029b --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/printf.h @@ -0,0 +1,25 @@ +#ifndef _MSL_PRINTF_H +#define _MSL_PRINTF_H + +#include "stdarg.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/file_struc.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +void printf(const char*, ...); +// printf_s +int fprintf(FILE*, const char* format, ...); +// fprintf_s +int vprintf(const char*, va_list); +// vprintf_s +// vfprintf +// vfprintf_s +int vsnprintf(char*, size_t, const char*, va_list); +// vsnprintf_s +int vsprintf(char*, const char*, va_list); +// vsprintf_s +int snprintf(char*, size_t, const char*, ...); +// snprintf_s +int sprintf(char*, const char*, ...); +// sprintf_s + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/rand.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/rand.h new file mode 100644 index 000000000..7ca4d5904 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/rand.h @@ -0,0 +1,17 @@ +#ifndef _MSL_RAND_H +#define _MSL_RAND_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +int rand(); +void srand(u32 seed); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/scanf.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/scanf.h new file mode 100644 index 000000000..e9a5e7b6e --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/scanf.h @@ -0,0 +1,18 @@ +#ifndef _MSL_SCANF_H +#define _MSL_SCANF_H + +#include "stdarg.h" + +// fscanf +// fscanf_s +// vscanf +// scanf +// scanf_s +// vfscanf +// vfscanf_s +int vsscanf(const char*, const char*, va_list); +// vsscanf_s +int sscanf(const char*, const char*, ...); +// sscanf_s + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/secure_error.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/secure_error.h new file mode 100644 index 000000000..e47145557 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/secure_error.h @@ -0,0 +1,10 @@ +#ifndef _MSL_SECURE_ERROR_H +#define _MSL_SECURE_ERROR_H + +#include "types.h" + +typedef void (*msl_constraint_handler)(int, int, int); + +void __msl_runtime_constraint_violation_s(int param1, int param2, int param3); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/signal.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/signal.h new file mode 100644 index 000000000..37d6709fd --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/signal.h @@ -0,0 +1,17 @@ +#ifndef SIGNAL_H +#define SIGNAL_H + +#ifdef __cplusplus +extern "C" +{ +#endif // ifdef __cplusplus + +typedef void (*__signal_func_ptr)(int); + +int raise(int); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif // SIGNAL_H \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/size_t.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/size_t.h similarity index 100% rename from include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/size_t.h rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/size_t.h diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h new file mode 100644 index 000000000..308903bdf --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h @@ -0,0 +1,38 @@ +#ifndef _STDIO_API_H +#define _STDIO_API_H + +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +enum __ReadProcActions { __GetAChar, __UngetAChar, __TestForError }; + +enum __WReadProcActions { __GetAwChar, __UngetAwChar, __TestForwcsError }; + +typedef struct { + char* CharStr; + size_t MaxCharCount; + size_t CharsWritten; +} __OutStrCtrl; + +typedef struct { + char* NextChar; + int NullCharDetected; +} __InStrCtrl; + +typedef struct { + wchar_t* wCharStr; + size_t MaxCharCount; + size_t CharsWritten; +} __wOutStrCtrl; + +typedef struct { + wchar_t* wNextChar; + int wNullCharDetected; +} __wInStrCtrl; + +// __fread +size_t __fwrite(const void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile); +int __StringRead(void*, int, int); +// wint_t __wStringRead(void*, wint_t, int); + +#endif // STDIO_API_H diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdlib.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/stdlib.h similarity index 71% rename from include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdlib.h rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/stdlib.h index ffd0d5c7c..01945d6c1 100644 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdlib.h +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/stdlib.h @@ -1,7 +1,7 @@ #ifndef _MSL_STDLIB #define _MSL_STDLIB -#include +#include #ifdef __cplusplus extern "C" { @@ -9,7 +9,7 @@ extern "C" { int rand(void); int atoi(const char* nptr); -double atof(const char* nptr); +double atof(const char*); // double (const char*)? void exit(int __status); void qsort(void*, size_t, size_t, int (*)(const void*, const void*)); long abs(long n); diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtold.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtold.h new file mode 100644 index 000000000..b4458967e --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtold.h @@ -0,0 +1,6 @@ +#ifndef _MSL_STRTOLD_H +#define _MSL_STRTOLD_H + +long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, int* chars_scanned, int* overflow); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtoul.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtoul.h new file mode 100644 index 000000000..73d273d16 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtoul.h @@ -0,0 +1,20 @@ +#ifndef _MSL_STRTOUL_H +#define _MSL_STRTOUL_H + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned long strtoul(const char* str, char** end, int base); +unsigned long __strtoul(int base, int max_width, int (*ReadProc)(void*, int, int), + void* ReadProcArg, int* chars_scanned, int* negative, int* overflow); +unsigned long long __strtoull(int base, int max_width, int (*ReadProc)(void*, int, int), + void* ReadProcArg, int* chars_scanned, int* negative, int* overflow); +int atoi(const char* str); +char* strtok(char* str, const char* delimiters); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/time.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/time.h similarity index 100% rename from include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/time.h rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/time.h diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/wchar_io.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/wchar_io.h new file mode 100644 index 000000000..984294c4a --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/wchar_io.h @@ -0,0 +1,9 @@ +#ifndef _MSL_WCHAR_IO_H +#define _MSL_WCHAR_IO_H + +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +int fwide(FILE* stream, int mode); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/PPC_EABI/math_ppc.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/PPC_EABI/math_ppc.h new file mode 100644 index 000000000..a281719c0 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/PPC_EABI/math_ppc.h @@ -0,0 +1,18 @@ +#ifndef _MATH_PPC_H +#define _MATH_PPC_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif +f64 nan(const char *); +f32 cosf(f32 __x); +f32 sinf(f32 __x); +f32 tanf(f32 __x); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/custconn/CircleBuffer.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/custconn/CircleBuffer.h new file mode 100644 index 000000000..cdc396efc --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/custconn/CircleBuffer.h @@ -0,0 +1,24 @@ +#ifndef TRK_CIRCLE_BUFFER_H +#define TRK_CIRCLE_BUFFER_H + +#include "types.h" + +typedef struct CircleBuffer { + u8* unk0; + u8* unk4; + u8* unk8; + u32 unkC; + u32 mBytesToRead; + u32 mBytesToWrite; + uint mSection; + u32 unk1C; +} CircleBuffer; + +u32 CBGetBytesAvailableForRead(CircleBuffer* cb); +u32 CBGetBytesAvailableForWrite(CircleBuffer* cb); +void CircleBufferInitialize(CircleBuffer* cb, u8* buf, u32 size); +void CircleBufferTerminate(CircleBuffer* cb); +int CircleBufferWriteBytes(CircleBuffer* cb, u8* buf, u32 size); +int CircleBufferReadBytes(CircleBuffer* cb, u8* buf, u32 size); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/custconn/cc_gdev.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/custconn/cc_gdev.h new file mode 100644 index 000000000..218cbe27f --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/custconn/cc_gdev.h @@ -0,0 +1,23 @@ +#ifndef TRK_CC_GDEV_H +#define TRK_CC_GDEV_H + +#include "types.h" +#include "NdevExi2A/DebuggerDriver.h" + +// TODO: figure out what these values represent +typedef enum { GDEV_RESULT_10009 = -10009, GDEV_RESULT_10005 = -10005, GDEV_RESULT_10001 = -10001 } UnkGdevEnum; + +void OutputData(); +BOOL IsInitialized(); +int gdev_cc_initialize(u8** flagOut, OSInterruptHandler handler); +int gdev_cc_shutdown(); +int gdev_cc_open(); +int gdev_cc_close(); +int gdev_cc_read(u8* dest, int size); +int gdev_cc_write(const u8* src, int size); +int gdev_cc_pre_continue(); +int gdev_cc_post_stop(); +int gdev_cc_peek(); +int gdev_cc_initinterrupts(); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dispatch.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dispatch.h new file mode 100644 index 000000000..8da561ef0 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dispatch.h @@ -0,0 +1,25 @@ +#ifndef _METROTRK_DISPATCH_H +#define _METROTRK_DISPATCH_H + +#include "types.h" + +typedef struct MessageBuffer { + u8 filler[0x10]; + u8 commandId; +} MessageBuffer; + +extern u32 TRKDoConnect(MessageBuffer*); +extern u32 TRKDoDisconnect(MessageBuffer*); +extern u32 TRKDoReset(MessageBuffer*); +extern u32 TRKDoOverride(MessageBuffer*); +extern u32 TRKDoReadMemory(MessageBuffer*); +extern u32 TRKDoWriteMemory(MessageBuffer*); +extern u32 TRKDoReadRegisters(MessageBuffer*); +extern u32 TRKDoWriteRegisters(MessageBuffer*); +extern u32 TRKDoSetOption(MessageBuffer*); +extern u32 TRKDoContinue(MessageBuffer*); +extern u32 TRKDoStep(MessageBuffer*); +extern u32 TRKDoStop(MessageBuffer*); +extern void SetBufferPosition(MessageBuffer*, u32); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dolphin_trk.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dolphin_trk.h new file mode 100644 index 000000000..d46e6c7ce --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dolphin_trk.h @@ -0,0 +1,16 @@ +#ifndef METROTRK_DOLPHIN_TRK_H +#define METROTRK_DOLPHIN_TRK_H +#include "types.h" +#ifdef __cplusplus +extern "C" { +#endif + +void InitMetroTRK(void); +void InitMetroTRK_BBA(void); + +void EnableMetroTRKInterrupts(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/target_options.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/target_options.h new file mode 100644 index 000000000..af197e3d0 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/target_options.h @@ -0,0 +1,9 @@ +#ifndef _TRK_TARGET_OPTIONS_H +#define _TRK_TARGET_OPTIONS_H + +#include "types.h" + +void SetUseSerialIO(u8); +u8 GetUseSerialIO(void); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trk.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trk.h new file mode 100644 index 000000000..e11a7854c --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trk.h @@ -0,0 +1,219 @@ +#ifndef _DOLPHIN_TRK_H +#define _DOLPHIN_TRK_H + +#include "types.h" +#include "Dolphin/db.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +/* TRK */ + +#define TRK_DISPATCH_CMD_CONNECT 1 /* Connect to the console */ +#define TRK_DISPATCH_CMD_DISCONNECT 2 /* Disconnect from the console */ +#define TRK_DISPATCH_CMD_RESET 3 /* Reset the debugger */ +#define TRK_DISPATCH_CMD_GETVERSION 4 /* Get debugger version */ +#define TRK_DISPATCH_CMD_GETSUPPORTMASK 5 /* Get Support Mask */ +#define TRK_DISPATCH_CMD_OVERRIDE 7 /* Override? */ +#define TRK_DISPATCH_CMD_READMEM 16 /* Reading from memory */ +#define TRK_DISPATCH_CMD_WRITEMEM 17 /* Writing to memory */ +#define TRK_DISPATCH_CMD_READREGS 18 /* Read a register value */ +#define TRK_DISPATCH_CMD_WRITEREGS 19 /* Set a register */ +#define TRK_DISPATCH_CMD_SETOPTION 23 /* Set an option? */ +#define TRK_DISPATCH_CMD_CONTINUE 24 /* Continue debugging */ +#define TRK_DISPATCH_CMD_STEP 25 /* Step through an instruction */ +#define TRK_DISPATCH_CMD_STOP 26 /* Stop the debugger */ + +typedef struct _TRK_Msg { + u8 _00[8]; // _00 + u32 mMsgLength; // _08 + u32 _0C; // _0C + u32 mMsg; // _10 +} TRK_Msg; + +/** + * @size{0xC} + */ +typedef struct TRKEvent { + int mEventType; + int _04; + int mBufferIndex; +} TRKEvent; + +/** + * @size{0x28} + */ +typedef struct TRKEventQueue { + u8 _00[4]; + int mCurrEvtID; + int mNextSlotToOverwrite; + TRKEvent mEvents[2]; + u32 _24; /* max of 0x100? */ +} TRKEventQueue; + +/** + * @size{0xA4} + */ +typedef struct TRKState { + u32 _00; + u32 _04; + u32 _08; + u32 _0C; + u32 _10; + u32 _14; + u32 _18; + u32 _1C; + u32 _20; + u32 _24; + u32 _28; + u32 _2C; + u32 _30; + u32 _34; + u32 _38; + u32 _3C; + u32 _40; + u32 _44; + u32 _48; + u32 _4C; + u32 _50; + u32 _54; + u32 _58; + u32 _5C; + u32 _60; + u32 _64; + u32 _68; + u32 _6C; + u32 _70; + u32 _74; + u32 _78; + u32 _7C; + u32 _80; + u32 _84; + u32 _88; + u32 _8C; + u32 _90; + u32 _94; + BOOL mIsStopped; + u32 _9C; + u32 _A0; + u32 _A4; + u32 _A8; + u32 _AC; +} TRKState; + +typedef struct TRKBuffer { + u8 _00[4]; + u32 _04; + s32 _08; + u32 _0C; + u32 _10; + u8 mBuffer[0x87C]; /* _10 */ +} TRKBuffer; +typedef enum { TRKSuccess = 0, TRKError100 = 0x100, TRKError301 = 0x301, TRKError302 = 0x302 } TRKResult; + +extern BOOL gTRKBigEndian; + +u32 TRKDoConnect(TRKBuffer*); +u32 TRKDoDisconnect(TRKBuffer*); +u32 TRKDoReset(TRKBuffer*); +u32 TRKDoVersions(TRKBuffer*); +u32 TRKDoSupportMask(TRKBuffer*); +u32 TRKDoOverride(TRKBuffer*); +u32 TRKDoReadMemory(TRKBuffer*); +u32 TRKDoWriteMemory(TRKBuffer*); +u32 TRKDoReadRegisters(TRKBuffer*); +u32 TRKDoWriteRegisters(TRKBuffer*); +u32 TRKDoSetOption(TRKBuffer*); +u32 TRKDoContinue(TRKBuffer*); +u32 TRKDoStep(TRKBuffer*); +u32 TRKDoStop(TRKBuffer*); + +void InitMetroTRK(void); +void InitMetroTRK_BBA(void); +void EnableMetroTRKInterrupts(void); + +void TRKDestructEvent(TRKEvent*); +TRKResult TRKDispatchMessage(TRKBuffer*); +void* TRKGetBuffer(int); +void TRKReleaseBuffer(int); +void TRKGetInput(); +BOOL TRKGetNextEvent(TRKEvent*); + +TRKResult TRKTargetContinue(void); +TRKResult TRKTargetInterrupt(TRKEvent*); +BOOL TRKTargetStopped(); +void TRKTargetSetStopped(uint); +TRKResult TRKTargetSupportRequest(); + +TRKResult TRKAppendBuffer_ui8(TRKBuffer*, u8*, int); +TRKResult TRKSetBufferPosition(TRKBuffer*, u32); + +TRKResult TRKMessageSend(TRK_Msg*); +void TRKSwapAndGo(void); +TRKResult TRKWriteUARTN(const void* bytes, u32 length); +TRKResult TRKInitializeNub(void); +TRKResult TRKTerminateNub(void); +void TRKNubWelcome(void); +void TRKNubMainLoop(void); + +TRKResult TRKInitializeMutex(void*); +TRKResult TRKAcquireMutex(void*); +TRKResult TRKReleaseMutex(void*); +void* TRK_memcpy(void* dst, const void* src, size_t n); + +TRKResult TRKInitializeEventQueue(); +TRKResult TRKInitializeMessageBuffers(); +TRKResult TRKInitializeDispatcher(); +TRKResult InitializeProgramEndTrap(); +TRKResult TRKInitializeSerialHandler(); +TRKResult TRKInitializeTarget(); + +/* EXI2 */ +void UnreserveEXI2Port(void); +void ReserveEXI2Port(void); + +/* MW */ +void MWTRACE(u8, char*, ...); + +/* UART */ +typedef int UARTError; + +enum { + kUARTNoError = 0, + kUARTUnknownBaudRate, + kUARTConfigurationError, + kUARTBufferOverflow, /* specified buffer was too small */ + kUARTNoData /* no data available from polling */ +}; + +typedef enum { + kBaudHWSet = -1, /* use HW settings such as DIP switches */ + kBaud300 = 300, /* valid baud rates */ + kBaud600 = 600, + kBaud1200 = 1200, + kBaud1800 = 1800, + kBaud2000 = 2000, + kBaud2400 = 2400, + kBaud3600 = 3600, + kBaud4800 = 4800, + kBaud7200 = 7200, + kBaud9600 = 9600, + kBaud19200 = 19200, + kBaud38400 = 38400, + kBaud57600 = 57600, + kBaud115200 = 115200, + kBaud230400 = 230400 +} UARTBaudRate; + +UARTError InitializeUART(UARTBaudRate baudRate); +TRKResult TRKInitializeIntDrivenUART(unknown, unknown, unknown, void*); +void usr_put_initialize(); +void TRKTargetSetInputPendingPtr(void*); +extern void* gTRKInputPendingPtr; + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/Gecko_ExceptionPPC.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/Gecko_ExceptionPPC.h new file mode 100644 index 000000000..749e4ea57 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/Gecko_ExceptionPPC.h @@ -0,0 +1,231 @@ +#ifndef _RUNTIME_GECKO_EXCEPTIONPPC_H +#define _RUNTIME_GECKO_EXCEPTIONPPC_H + +#include "types.h" + +typedef u8 exaction_type; + +#define EXACTION_ENDBIT 0x80 +#define EXACTION_MASK 0x7F + +// EXAction structs + +#define EXACTION_ENDOFLIST 0 +#define EXACTION_BRANCH 1 + +typedef struct ex_branch { + exaction_type action; + u8 unused; + u16 target; +} ex_branch; + +#define EXACTION_DESTROYLOCAL 2 + +typedef struct ex_destroylocal { + exaction_type action; + u8 unused; + s16 local; + void* dtor; +} ex_destroylocal; + +#define EXACTION_DESTROYLOCALCOND 3 + +typedef struct ex_destroylocalcond { + exaction_type action; + u8 dlc_field; + s16 cond; + s16 local; + void* dtor; +} ex_destroylocalcond; + +#define ex_destroylocalcond_MakeField(regcond) (((regcond) << 7)) +#define ex_destroylocalcond_GetRegCond(field) ((field) >> 7) + +#define EXACTION_DESTROYLOCALPOINTER 4 + +typedef struct ex_destroylocalpointer { + exaction_type action; + u8 dlp_field; + s16 pointer; + void* dtor; +} ex_destroylocalpointer; + +#define ex_destroylocalpointer_MakeField(regpointer) (((regpointer) << 7)) +#define ex_destroylocalpointer_GetRegPointer(field) ((field) >> 7) + +#define EXACTION_DESTROYLOCALARRAY 5 + +typedef struct ex_destroylocalarray { + exaction_type action; + u8 unused; + s16 localarray; + u16 elements; + u16 element_size; + void* dtor; +} ex_destroylocalarray; + +#define EXACTION_DESTROYBASE 6 +#define EXACTION_DESTROYMEMBER 7 + +typedef struct ex_destroymember { + exaction_type action; + u8 dm_field; + s16 objectptr; + s32 offset; + void* dtor; +} ex_destroymember; + +#define ex_destroymember_MakeField(regpointer) (((regpointer) << 7)) +#define ex_destroymember_GetRegPointer(field) ((field) >> 7) + +#define EXACTION_DESTROYMEMBERCOND 8 + +typedef struct ex_destroymembercond { + exaction_type action; + u8 dmc_field; + s16 cond; + s16 objectptr; + s32 offset; + void* dtor; +} ex_destroymembercond; + +#define ex_destroymembercond_MakeField(regcond, regpointer) (((regcond) << 7) | (((regpointer)&0x1) << 6)) +#define ex_destroymembercond_GetRegCond(field) ((field) >> 7) +#define ex_destroymembercond_GetRegPointer(field) (((field) >> 6) & 0x1) + +#define EXACTION_DESTROYMEMBERARRAY 9 + +typedef struct ex_destroymemberarray { + exaction_type action; + u8 dma_field; + s16 objectptr; + s32 offset; + s32 elements; + s32 element_size; + void* dtor; +} ex_destroymemberarray; + +#define ex_destroymemberarray_MakeField(regpointer) (((regpointer) << 7)) +#define ex_destroymemberarray_GetRegPointer(field) ((field) >> 7) + +#define EXACTION_DELETEPOINTER 10 + +typedef struct ex_deletepointer { + exaction_type action; + u8 dp_field; + s16 objectptr; + void* deletefunc; +} ex_deletepointer; + +#define ex_deletepointer_MakeField(regpointer) (((regpointer) << 7)) +#define ex_deletepointer_GetRegPointer(field) ((field) >> 7) + +#define EXACTION_DELETEPOINTERCOND 11 + +typedef struct ex_deletepointercond { + exaction_type action; + u8 dpc_field; + s16 cond; + s16 objectptr; + void* deletefunc; +} ex_deletepointercond; + +#define ex_deletepointercond_MakeField(regcond, regpointer) (((regcond) << 7) | (((regpointer)&0x1) << 6)) +#define ex_deletepointercond_GetRegCond(field) ((field) >> 7) +#define ex_deletepointercond_GetRegPointer(field) (((field) >> 6) & 0x1) + +#define EXACTION_CATCHBLOCK 12 + +typedef struct ex_catchblock { + exaction_type action; + u8 unused; + char* catch_type; + u16 catch_pcoffset; + s16 cinfo_ref; +} ex_catchblock; + +#define EXACTION_ACTIVECATCHBLOCK 13 + +typedef struct ex_activecatchblock { + exaction_type action; + u8 unused; + s16 cinfo_ref; +} ex_activecatchblock; + +#define EXACTION_TERMINATE 14 + +typedef struct ex_terminate { + exaction_type action; + u8 unused; +} ex_terminate; + +#define EXACTION_SPECIFICATION 15 + +typedef struct ex_specification { + exaction_type action; + u8 unused; + u16 specs; + s32 pcoffset; + s32 cinfo_ref; + char* spec[]; +} ex_specification; + +#define EXACTION_CATCHBLOCK_32 16 + +typedef struct ex_catchblock_32 { + exaction_type action; + u8 unused; + char* catch_type; + s32 catch_pcoffset; + s32 cinfo_ref; +} ex_catchblock_32; + +// Other structs + +typedef struct ExceptionRangeSmall { + u16 start; + u16 end; + u16 action; +} ExceptionRangeSmall; + +typedef struct ExceptionTableSmall { + u16 et_field; + ExceptionRangeSmall ranges[0]; +} ExceptionTableSmall; + +typedef struct ExceptionRangeLarge { + u32 start; + u16 size; + u16 action; +} ExceptionRangeLarge; + +typedef struct ExceptionTableLarge { + u16 et_field; + u16 et_field2; + ExceptionRangeLarge ranges[]; +} ExceptionTableLarge; + +#define ET_MakeField(savedGPRs, savedFPRs, savedCR, hasframeptr, isLarge) \ + (((savedGPRs) << 11) | ((savedFPRs & 0x1f) << 6) | ((savedCR & 0x1) << 5) | ((hasframeptr & 0x1) << 4) | ((isLarge & 1) << 3)) + +#define ET_GetSavedGPRs(field) ((field) >> 11) +#define ET_GetSavedFPRs(field) (((field) >> 6) & 0x1f) +#define ET_GetSavedCR(field) (((field) >> 5) & 0x1) +#define ET_GetHasFramePtr(field) (((field) >> 4) & 0x1) +#define ET_IsLargeTable(field) (((field) >> 3) & 0x1) +#define ET_ClearLargeBit(field) ((field) & ~(1 << 3)) +#define ET_SetLargeBit(field) ((field) | (1 << 3)) + +#define ET_HasElfVector(field) (((field) >> 1) & 0x1) + +typedef struct ExceptionTableIndex { + u32 functionoffset; + u32 eti_field; + u32 exceptionoffset; +} ExceptionTableIndex; + +#define ETI_MakeField(direct, fsize) ((((s32)(direct)) << 31) | ((fsize)&0x7fffffff)) +#define ETI_GetDirectStore(field) ((field) >> 31) +#define ETI_GetFunctionSize(field) ((field)&0x7fffffff) + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/MWCPlusPlusLib.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/MWCPlusPlusLib.h new file mode 100644 index 000000000..5dcb01bef --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/MWCPlusPlusLib.h @@ -0,0 +1,46 @@ +#ifndef _RUNTIME_MWCPLUSLIB_H +#define _RUNTIME_MWCPLUSLIB_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define CTORARG_TYPE int +#define CTORARG_PARTIAL (0) +#define CTORARG_COMPLETE (1) + +#define CTORCALL_COMPLETE(ctor, objptr) (((void (*)(void *, CTORARG_TYPE))ctor)(objptr, CTORARG_COMPLETE)) + +#define DTORARG_TYPE int + +#define DTORCALL_COMPLETE(dtor, objptr) (((void (*)(void *, DTORARG_TYPE))dtor)(objptr, -1)) +#define DTORCALL_PARTIAL(dtor, objptr) (((void (*)(void *, DTORARG_TYPE))dtor)(objptr, 0)) + +typedef void *ConstructorDestructor; + +typedef struct PTMF +{ + long this_delta; // self-explanatory + long v_offset; // vtable offset + union + { + void *f_addr; // function address + long ve_offset; // virtual function entry offset (of vtable) + } f_data; +} PTMF; + +extern void __construct_array(void *ptr, ConstructorDestructor ctor, ConstructorDestructor dtor, size_t size, size_t n); +extern void __destroy_arr(void *block, ConstructorDestructor *dtor, size_t size, size_t n); +extern void *__construct_new_array(void *block, ConstructorDestructor ctor, ConstructorDestructor dtor_arg, size_t size, size_t n); +extern void __destroy_new_array(void *block, ConstructorDestructor dtor); +extern void __destroy_new_array2(); +extern void __destroy_new_array3(); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/NMWException.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/NMWException.h new file mode 100644 index 000000000..692055e35 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/NMWException.h @@ -0,0 +1,34 @@ +#ifndef _NMWEXCEPTION +#define _NMWEXCEPTION + +#include "types.h" +#include "exception" //#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef s16 vbase_ctor_arg_type; +typedef char local_cond_type; + +typedef struct CatchInfo { + void* location; + void* typeinfo; + void* dtor; + void* sublocation; + s32 pointercopy; + void* stacktop; +} CatchInfo; + +void __unregister_fragment(int fragmentID); +// struct __eti_init_info* info +int __register_fragment(void* info, char* TOC); +void* __register_global_object(void* object, void* destructor, void* regmem); +void __destroy_global_chain(void); +extern char __throw_catch_compare(const char* throwtype, const char* catchtype, s32* offset_result); + +#ifdef __cplusplus +} +#endif + +#endif // _NMWEXCEPTION diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__init_cpp_exceptions.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__init_cpp_exceptions.h new file mode 100644 index 000000000..2ee636c3f --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__init_cpp_exceptions.h @@ -0,0 +1,14 @@ +#pragma once + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void __init_cpp_exceptions(void); +void __fini_cpp_exceptions(void); + +#ifdef __cplusplus +} +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__mem.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__mem.h new file mode 100644 index 000000000..198d2b446 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__mem.h @@ -0,0 +1,16 @@ +#ifndef RUNTIME_MEM_H +#define RUNTIME_MEM_H +#include "macros.h" +#include "types.h" +#ifdef __cplusplus +extern "C" { +#endif + +DECL_SECTION(".init") void* memcpy(void* dest, const void* src, size_t n); +DECL_SECTION(".init") void __fill_mem(void* dest, int val, size_t count); +DECL_SECTION(".init") void* memset(void* dest, int val, size_t count); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h new file mode 100644 index 000000000..e8ad606c4 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h @@ -0,0 +1,74 @@ +#ifndef __PPC_EABI_LINKER +#define __ppc_eabi_linker + +#include "macros.h" + +DECL_SECTION(".init") extern char _stack_addr[]; +DECL_SECTION(".init") extern char _stack_end[]; +DECL_SECTION(".init") extern char _heap_addr[]; +DECL_SECTION(".init") extern char _heap_end[]; +DECL_SECTION(".init") extern const char _fextabindex_rom[]; +DECL_SECTION(".init") extern char _fextabindex[]; +DECL_SECTION(".init") extern char _eextabindex[]; + +DECL_SECTION(".init") extern char _SDA_BASE_[]; + +DECL_SECTION(".init") extern char _SDA2_BASE_[]; + +typedef struct __rom_copy_info { + char* rom; + char* addr; + unsigned int size; +} __rom_copy_info; + +DECL_SECTION(".init") extern __rom_copy_info _rom_copy_info[]; + +typedef struct __bss_init_info { + char* addr; + unsigned int size; +} __bss_init_info; + +DECL_SECTION(".init") extern __bss_init_info _bss_init_info[]; + +typedef struct __eti_init_info { + void* eti_start; + void* eti_end; + void* code_start; + unsigned long code_size; +} __eti_init_info; + +DECL_SECTION(".init") extern __eti_init_info _eti_init_info[]; +DECL_SECTION(".init") extern const char _f_init_rom[]; +DECL_SECTION(".init") extern char _f_init[]; +DECL_SECTION(".init") extern char _e_init[]; +DECL_SECTION(".init") extern const char _f_text_rom[]; +DECL_SECTION(".init") extern char _f_text[]; +DECL_SECTION(".init") extern char _e_text[]; +DECL_SECTION(".init") extern const char _f_rodata_rom[]; +DECL_SECTION(".init") extern char _f_rodata[]; +DECL_SECTION(".init") extern char _e_rodata[]; +DECL_SECTION(".init") extern const char _fextab_rom[]; +DECL_SECTION(".init") extern char _fextab[]; +DECL_SECTION(".init") extern char _eextab[]; +DECL_SECTION(".init") extern const char _f_data_rom[]; +DECL_SECTION(".init") extern char _f_data[]; +DECL_SECTION(".init") extern char _e_data[]; +DECL_SECTION(".init") extern char _f_bss[]; +DECL_SECTION(".init") extern char _e_bss[]; +DECL_SECTION(".init") extern const char _f_sdata_rom[]; +DECL_SECTION(".init") extern char _f_sdata[]; +DECL_SECTION(".init") extern char _e_sdata[]; +DECL_SECTION(".init") extern char _f_sbss[]; +DECL_SECTION(".init") extern char _e_sbss[]; +DECL_SECTION(".init") extern const char _f_sdata2_rom[]; +DECL_SECTION(".init") extern char _f_sdata2[]; +DECL_SECTION(".init") extern char _e_sdata2[]; +DECL_SECTION(".init") extern char _f_sbss2[]; +DECL_SECTION(".init") extern char _e_sbss2[]; +DECL_SECTION(".init") extern const char _f_PPC_EMB_sdata0_rom[]; +DECL_SECTION(".init") extern char _f_PPC_EMB_sdata0[]; +DECL_SECTION(".init") extern char _e_PPC_EMB_sdata0[]; +DECL_SECTION(".init") extern char _f_PPC_EMB_sbss0[]; +DECL_SECTION(".init") extern char _e_PPC_EMB_sbss0[]; + +#endif // __PPC_EABI_LINKER diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__va_arg.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__va_arg.h new file mode 100644 index 000000000..6b9fc6e47 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__va_arg.h @@ -0,0 +1,13 @@ +#ifndef _RUNTIME_VA_ARG_H +#define _RUNTIME_VA_ARG_H +#include "types.h" +struct va_list { + char mG_register; + char mFloat_register; + char mPadding[2]; + char* mInput_arg_area; + char* mReg_save_area; +}; + +void *__va_arg(struct va_list *v_list, s32 type); +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/global_destructor_chain.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/global_destructor_chain.h new file mode 100644 index 000000000..52046c89c --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/global_destructor_chain.h @@ -0,0 +1,26 @@ +#ifndef _GLOBALDESTRUCTORCHAIN +#define _GLOBALDESTRUCTORCHAIN + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct DestructorChain { + struct DestructorChain* next; + void* destructor; + void* object; +} DestructorChain; + +void* __register_global_object(void* object, void* destructor, void* registration); + +void __destroy_global_chain(void); + +int __register_atexit(void (*)(void)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/runtime.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/runtime.h new file mode 100644 index 000000000..184bfe0e3 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/runtime.h @@ -0,0 +1,19 @@ +#ifndef _DOLPHIN_RUNTIME_H +#define _DOLPHIN_RUNTIME_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +unsigned long __cvt_fp2unsigned(f64); +// TODO: The rest + +void* __copy(char*, char*, size_t); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/algorithm b/libs/PowerPC_EABI_Support/include/algorithm new file mode 100644 index 000000000..c535a8fd4 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/algorithm @@ -0,0 +1,51 @@ +#ifndef _STD_ALGORITHM_H +#define _STD_ALGORITHM_H + +#include "types.h" + +#include + +namespace std +{ + template + inline s32 + __distance(InputIterator first, InputIterator last, input_iterator_tag) + { + s32 result = 0; + for (; first != last; ++first) + ++result; + return result; + } + + template + inline s32 + distance(InputIterator first, InputIterator last) + { + input_iterator_tag tag; + return __distance(first, last, tag); + } + + template + inline InputIterator find_if(InputIterator first, InputIterator last, Predicate p) + { + for (; first != last && !p(*first); ++first) + { + } + return first; + } + + template + ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, const Element &value, Predicate predicate); + + template + inline void fill(ForwardIt first, ForwardIt last, const T &value) + { + for (; first != last; ++first) + { + *first = value; + } + } + +} // namespace std + +#endif diff --git a/libs/PowerPC_EABI_Support/include/ctype.h b/libs/PowerPC_EABI_Support/include/ctype.h new file mode 100644 index 000000000..0937a8f7f --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/ctype.h @@ -0,0 +1,54 @@ +#ifndef _CTYPE_H +#define _CTYPE_H + +#include "types.h" +#include "locale.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ctype_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +__declspec(weak) int isalpha(int __c); +__declspec(weak) int isdigit(int __c); +__declspec(weak) int isspace(int __c); +__declspec(weak) int isupper(int __c); +__declspec(weak) int isxdigit(int __c); + +__declspec(weak) int tolower(int __c); +__declspec(weak) int toupper(int __c); + +// added underscore to avoid naming conflicts +inline int _isalpha(int c) +{ + return (int)(__ctype_map[(u8)c] & __letter); +} +inline int _isdigit(int c) +{ + return (int)(__ctype_map[(u8)c] & __digit); +} +inline int _isspace(int c) +{ + return (int)(__ctype_map[(u8)c] & __whitespace); +} +inline int _isupper(int c) +{ + return (int)(__ctype_map[(u8)c] & __upper_case); +} +inline int _isxdigit(int c) +{ + return (int)(__ctype_map[(u8)c] & __hex_digit); +} +inline int _tolower(int c) +{ + return (c == -1 ? -1 : (int)__lower_map[(u8)c]); +} +inline int _toupper(int c) +{ + return (c == -1 ? -1 : (int)__upper_map[(u8)c]); +} + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/PowerPC_EABI_Support/include/errno.h b/libs/PowerPC_EABI_Support/include/errno.h new file mode 100644 index 000000000..7a28c1ef4 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/errno.h @@ -0,0 +1,59 @@ +#ifndef _ERRNO_H +#define _ERRNO_H + +#ifdef __cplusplus +extern "C" { +#endif + +// Error constants +#define E2BIG 7 +#define EACCES 13 +#define EAGAIN 11 +#define EBADF 9 +#define EBUSY 16 +#define ECHILD 10 +#define EDEADLK 35 +#define EDEADLOCK EDEADLK +#define EDOM 33 +#define EEXIST 17 +#define EFAULT 14 +#define EFBIG 27 +#define EFPOS 40 +#define EILSEQ 88 +#define EINTR 4 +#define EINVAL 22 +#define EIO 5 +#define EISDIR 21 +#define EMFILE 24 +#define EMLINK 31 +#define ENFILE 23 +#define ENAMETOOLONG 36 +#define ENODEV 19 +#define ENOENT 2 +#define ENOERR 0 +#define ENOEXEC 8 +#define ENOLCK 77 +#define ENOMEM 12 +#define ENOSPC 28 +#define ENOSYS 38 +#define ENOTDIR 20 +#define ENOTEMPTY 39 +#define ENOTTY 25 +#define ENXIO 6 +#define EPERM 1 +#define EPIPE 32 +#define ERANGE 34 +#define EROFS 30 +#define ESIGPARM 26 +#define ESPIPE 29 +#define ESRCH 3 +#define EUNKNOWN 99 +#define EXDEV 18 + +extern int errno; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/PowerPC_EABI_Support/include/exception b/libs/PowerPC_EABI_Support/include/exception new file mode 100644 index 000000000..8daa7e3c7 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/exception @@ -0,0 +1,20 @@ +#ifndef _EXCEPTION +#define _EXCEPTION + +namespace std +{ + static void dthandler(); + static void duhandler(); + extern void terminate(); + extern void unexpected(); + typedef void (*terminate_handler)(); + typedef void (*unexpected_handler)(); + extern terminate_handler thandler; + extern unexpected_handler uhandler; + + class exception + { + }; +} + +#endif \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/include/extras.h b/libs/PowerPC_EABI_Support/include/extras.h new file mode 100644 index 000000000..0ca683907 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/extras.h @@ -0,0 +1,14 @@ +#ifndef _EXTRAS_H +#define _EXTRAS_H +#include "types.h" +#ifdef __cplusplus +extern "C" { +#endif + +int stricmp(const char*, const char*); +int strnicmp(const char *s1, const char *s2, int n); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/PowerPC_EABI_Support/include/fdlibm.h b/libs/PowerPC_EABI_Support/include/fdlibm.h new file mode 100644 index 000000000..f2e5097c8 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/fdlibm.h @@ -0,0 +1,230 @@ +#ifndef _FDLIBM_H +#define _FDLIBM_H + +/* @(#)fdlibm.h 1.5 04/04/22 */ +/* + * ==================================================== + * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. + * + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +/* Sometimes it's necessary to define __LITTLE_ENDIAN explicitly + but these catch some common cases. */ + +#if defined(i386) || defined(i486) || defined(intel) || defined(x86) || defined(i86pc) || defined(__alpha) || defined(__osf__) +#define __LITTLE_ENDIAN +#endif + +#ifdef __LITTLE_ENDIAN +#define __HI(x) *(1 + (int*)&x) +#define __LO(x) *(int*)&x +#define __HIp(x) *(1 + (int*)x) +#define __LOp(x) *(int*)x +#else +#define __HI(x) *(int*)&x +#define __LO(x) *(1 + (int*)&x) +#define __HIp(x) *(int*)x +#define __LOp(x) *(1 + (int*)x) +#endif + +// TODO: should __STDC__ actually be defined? +// #ifdef __STDC__ +#define __P(p) p +// #else +// #define __P(p) () +// #endif + +/* + * ANSI/POSIX + */ + +extern int signgam; + +#define MAXFLOAT ((float)3.40282346638528860e+38) + +enum fdversion { fdlibm_ieee = -1, fdlibm_svid, fdlibm_xopen, fdlibm_posix }; + +#define _LIB_VERSION_TYPE enum fdversion +#define _LIB_VERSION _fdlib_version + +/* if global variable _LIB_VERSION is not desirable, one may + * change the following to be a constant by: + * #define _LIB_VERSION_TYPE const enum version + * In that case, after one initializes the value _LIB_VERSION (see + * s_lib_version.c) during compile time, it cannot be modified + * in the middle of a program + */ +extern _LIB_VERSION_TYPE _LIB_VERSION; + +#define _IEEE_ fdlibm_ieee +#define _SVID_ fdlibm_svid +#define _XOPEN_ fdlibm_xopen +#define _POSIX_ fdlibm_posix + +struct exception { + int type; + char* name; + double arg1; + double arg2; + double retval; +}; + +#define HUGE MAXFLOAT + +/* + * set X_TLOSS = pi*2**52, which is possibly defined in + * (one may replace the following line by "#include ") + */ + +#define X_TLOSS 1.41484755040568800000e+16 + +#define DOMAIN 1 +#define SING 2 +#define OVERFLOW 3 +#define UNDERFLOW 4 +#define TLOSS 5 +#define PLOSS 6 + +/* + * ANSI/POSIX + */ +extern double acos __P((double)); +extern double asin __P((double)); +extern double atan __P((double)); +extern double atan2 __P((double, double)); +extern double cos __P((double)); +extern double sin __P((double)); +extern double tan __P((double)); + +extern double cosh __P((double)); +extern double sinh __P((double)); +extern double tanh __P((double)); + +extern double exp __P((double)); +extern double frexp __P((double, int*)); +extern double ldexp __P((double, int)); +extern double scalbn __P((double, int)); +extern double log __P((double)); +extern double log10 __P((double)); +extern double modf __P((double, double*)); + +extern double pow __P((double, double)); +extern double sqrt __P((double)); + +extern double ceil __P((double)); +extern double fabs __P((double)); +extern double floor __P((double)); +extern double fmod __P((double, double)); + +extern double erf __P((double)); +extern double erfc __P((double)); +extern double gamma __P((double)); +extern double hypot __P((double, double)); +extern int isnan __P((double)); +extern int finite __P((double)); +extern double j0 __P((double)); +extern double j1 __P((double)); +extern double jn __P((int, double)); +extern double lgamma __P((double)); +extern double y0 __P((double)); +extern double y1 __P((double)); +extern double yn __P((int, double)); + +extern double acosh __P((double)); +extern double asinh __P((double)); +extern double atanh __P((double)); +extern double cbrt __P((double)); +extern double logb __P((double)); +extern double nextafter __P((double, double)); +extern double remainder __P((double, double)); +#ifdef _SCALB_INT +extern double scalb __P((double, int)); +#else +extern double scalb __P((double, double)); +#endif + +extern int matherr __P((struct exception*)); + +/* + * IEEE Test Vector + */ +extern double significand __P((double)); + +/* + * Functions callable from C, intended to support IEEE arithmetic. + */ +extern double copysign __P((double, double)); +extern int ilogb __P((double)); +extern double rint __P((double)); +extern double scalbn __P((double, int)); + +/* + * BSD math library entry points + */ +extern double expm1 __P((double)); +extern double log1p __P((double)); + +/* + * Reentrant version of gamma & lgamma; passes signgam back by reference + * as the second argument; user must allocate space for signgam. + */ +#ifdef _REENTRANT +extern double gamma_r __P((double, int*)); +extern double lgamma_r __P((double, int*)); +#endif /* _REENTRANT */ + +/* ieee style elementary functions */ +extern double __ieee754_sqrt __P((double)); +extern double __ieee754_acos __P((double)); +extern double __ieee754_acosh __P((double)); +extern double __ieee754_log __P((double)); +extern double __ieee754_atanh __P((double)); +extern double __ieee754_asin __P((double)); +extern double __ieee754_atan2 __P((double, double)); +extern double __ieee754_exp __P((double)); +extern double __ieee754_cosh __P((double)); +extern double __ieee754_fmod __P((double, double)); +extern double __ieee754_pow __P((double, double)); +extern double __ieee754_lgamma_r __P((double, int*)); +extern double __ieee754_gamma_r __P((double, int*)); +extern double __ieee754_lgamma __P((double)); +extern double __ieee754_gamma __P((double)); +extern double __ieee754_log10 __P((double)); +extern double __ieee754_sinh __P((double)); +extern double __ieee754_hypot __P((double, double)); +extern double __ieee754_j0 __P((double)); +extern double __ieee754_j1 __P((double)); +extern double __ieee754_y0 __P((double)); +extern double __ieee754_y1 __P((double)); +extern double __ieee754_jn __P((int, double)); +extern double __ieee754_yn __P((int, double)); +extern double __ieee754_remainder __P((double, double)); +extern int __ieee754_rem_pio2 __P((double, double*)); +#ifdef _SCALB_INT +extern double __ieee754_scalb __P((double, int)); +#else +extern double __ieee754_scalb __P((double, double)); +#endif + +/* fdlibm kernel function */ +extern double __kernel_standard __P((double, double, int)); +extern double __kernel_sin __P((double, double, int)); +extern double __kernel_cos __P((double, double)); +extern double __kernel_tan __P((double, double, int)); +extern int __kernel_rem_pio2 __P((double*, double*, int, int, int, const int*)); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#include "math.h" + +#endif diff --git a/libs/PowerPC_EABI_Support/include/float.h b/libs/PowerPC_EABI_Support/include/float.h new file mode 100644 index 000000000..e90e6b5a8 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/float.h @@ -0,0 +1,59 @@ +#ifndef _FLOAT_H +#define _FLOAT_H + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +extern int __double_max[]; +extern int __extended_min[]; +extern int __extended_max[]; +extern int __float_max[]; +extern int __float_epsilon[]; + +#define FLT_MANT_DIG 24 +#define FLT_DIG 6 +#define FLT_MIN_EXP (-125) +#define FLT_MIN_10_EXP (-37) +#define FLT_MAX_EXP 128 +#define FLT_MAX_10_EXP 38 + +//#define FLT_MAX 0x1.fffffeP127F +//#define FLT_EPSILON 0x1.000000P-23F +#define FLT_MIN 0x1.000000P-126F + +#define FLT_MAX (*(float*)__float_max) +#define FLT_EPSILON (*(float*)__float_epsilon) + +#define DBL_MANT_DIG 53 +#define DBL_DIG 15 +#define DBL_MIN_EXP (-1021) +#define DBL_MIN_10_EXP (-308) +#define DBL_MAX_EXP 1024 +#define DBL_MAX_10_EXP 308 + +//#define DBL_MAX 0x1.fffffffffffffP1023 +#define DBL_EPSILON 0x1.0000000000000P-52 +#define DBL_MIN 0x1.0000000000000P-1022 + +#define DBL_MAX (*(double*)__double_max) + +#define LDBL_MANT_DIG 53 +#define LDBL_DIG 15 +#define LDBL_MIN_EXP (-1021) +#define LDBL_MIN_10_EXP (-308) +#define LDBL_MAX_EXP 1024 +#define LDBL_MAX_10_EXP 308 + +//#define LDBL_MAX 0x1.fffffffffffffP1023L +#define LDBL_EPSILON 0x1.0000000000000P-52L +//#define LDBL_MIN 0x1.0000000000000P-1022L + +#define LDBL_MAX (*(long double*)__extended_max) +#define LDBL_MIN (*(long double*)__extended_min) + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/functional b/libs/PowerPC_EABI_Support/include/functional new file mode 100644 index 000000000..9c74735b1 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/functional @@ -0,0 +1,20 @@ +#ifndef _STD_FUNCTIONAL_H +#define _STD_FUNCTIONAL_H + +#include "types.h" + +namespace std { +template +struct binary_function { + typedef LHS first_argument_type; + typedef RHS second_argument_type; + typedef Result result_type; +}; + +template +struct less : public binary_function { + bool operator()(const T& lhs, const T& rhs) const { return lhs < rhs; } +}; +} // namespace std + +#endif diff --git a/libs/PowerPC_EABI_Support/include/iterator b/libs/PowerPC_EABI_Support/include/iterator new file mode 100644 index 000000000..726024727 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/iterator @@ -0,0 +1,41 @@ +#ifndef _STD_ITERATOR_H +#define _STD_ITERATOR_H + +#include "types.h" + +namespace std { +typedef long ptrdiff_t; + +struct input_iterator_tag { +}; +struct output_iterator_tag { +}; +struct forward_iterator_tag : public input_iterator_tag { +}; +struct bidirectional_iterator_tag : public forward_iterator_tag { +}; +struct random_access_iterator_tag : public bidirectional_iterator_tag +{ +}; + +template +struct iterator_traits { + typedef typename Iterator::difference_type difference_type; + typedef typename Iterator::value_type value_type; + typedef typename Iterator::pointer pointer; + typedef typename Iterator::reference reference; + typedef typename Iterator::iterator_category iterator_category; +}; + +template +struct iterator { + typedef IteratorTag iterator_category; + typedef ValueType value_type; + typedef DifferenceType difference_type; + typedef Pointer pointer; + typedef Reference reference; +}; +} // namespace std + +#endif diff --git a/libs/PowerPC_EABI_Support/include/limits b/libs/PowerPC_EABI_Support/include/limits new file mode 100644 index 000000000..58b012269 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/limits @@ -0,0 +1,70 @@ +#ifndef _STD_LIMITS_H +#define _STD_LIMITS_H + +namespace std { +template +class numeric_limits { +public: + inline static T min(); + inline static T max(); +}; + +template <> +class numeric_limits { +public: + inline static char min() { return -0x80; } + inline static char max() { return 0x7F; } +}; + +template <> +class numeric_limits { +public: + inline static short min() { return -0x8000; } + inline static short max() { return 0x7FFF; } +}; + +template <> +class numeric_limits { +public: + inline static int min() { return -0x80000000; } + inline static int max() { return 0x7FFFFFFF; } +}; + +template <> +class numeric_limits { +public: + inline static long min() { return -0x80000000; } + inline static long max() { return 0x7FFFFFFF; } +}; + +template <> +class numeric_limits { +public: + inline static unsigned char min() { return 0x0; } + inline static unsigned char max() { return 0xFF; } +}; + +template <> +class numeric_limits { +public: + inline static unsigned short min() { return 0x0; } + inline static unsigned short max() { return 0xFFFF; } +}; + +template <> +class numeric_limits { +public: + inline static unsigned int min() { return 0x0; } + inline static unsigned int max() { return 0xFFFFFFFF; } +}; + +template <> +class numeric_limits { +public: + inline static unsigned long min() { return 0x0; } + inline static unsigned long max() { return 0xFFFFFFFF; } +}; + +} // namespace std + +#endif diff --git a/libs/PowerPC_EABI_Support/include/limits.h b/libs/PowerPC_EABI_Support/include/limits.h new file mode 100644 index 000000000..f8ffdbb5f --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/limits.h @@ -0,0 +1,36 @@ +#ifndef _LIMITS_H +#define _LIMITS_H +#include "types.h" +#ifdef __cplusplus +extern "C" { +#endif + +#define CHAR_BIT 8 + +#define SCHAR_MIN (-0x7F - 1) +#define SCHAR_MAX 0x7F +#define UCHAR_MAX 0xFF + +#define CHAR_MIN 0 +#define CHAR_MAX SCHAR_MAX + +#define SHRT_MIN (-0x7FFF - 1) +#define SHRT_MAX 0x7FFF +#define USHRT_MAX 0xFFFF + +#define INT_MIN (-0x7FFFFFFF - 1) +#define INT_MAX 0x7FFFFFFF +#define UINT_MAX 0xFFFFFFFF + +#define LONG_MIN (-0x7FFFFFFFL - 1) +#define LONG_MAX 0x7FFFFFFFL +#define ULONG_MAX 0xFFFFFFFFUL + +#define LLONG_MIN (-0x7FFFFFFFFFFFFFFFLL - 1) +#define LLONG_MAX 0x7FFFFFFFFFFFFFFFLL +#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/PowerPC_EABI_Support/include/locale.h b/libs/PowerPC_EABI_Support/include/locale.h new file mode 100644 index 000000000..12ca1d325 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/locale.h @@ -0,0 +1,129 @@ +#ifndef _LOCALE_H +#define _LOCALE_H + +#include "types.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int (*__decode_mbyte)(wchar_t*, const char*, size_t); +typedef int (*__encode_mbyte)(char*, wchar_t); + +struct lconv +{ + char* decimal_point; + char* thousands_sep; + char* grouping; + char* mon_decimal_point; + char* mon_thousands_sep; + char* mon_grouping; + char* positive_sign; + char* negative_sign; + char* currency_symbol; + char frac_digits; + char p_cs_precedes; + char n_cs_precedes; + char p_sep_by_space; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; + char* int_curr_symbol; + char int_frac_digits; + char int_p_cs_precedes; + char int_n_cs_precedes; + char int_p_sep_by_space; + char int_n_sep_by_space; + char int_p_sign_posn; + char int_n_sign_posn; +}; + +struct _loc_mon_cmpt +{ + char CmptName[8]; + char* mon_decimal_point; + char* mon_thousands_sep; + char* mon_grouping; + char* positive_sign; + char* negative_sign; + char* currency_symbol; + char frac_digits; + char p_cs_precedes; + char n_cs_precedes; + char p_sep_by_space; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; + char* int_curr_symbol; + char int_frac_digits; + char int_p_cs_precedes; + char int_n_cs_precedes; + char int_p_sep_by_space; + char int_n_sep_by_space; + char int_p_sign_posn; + char int_n_sign_posn; +}; + +struct _loc_num_cmpt +{ + char CmptName[8]; + char* decimal_point; + char* thousands_sep; + char* grouping; +}; + +struct _loc_time_cmpt +{ + char CmptName[8]; + char* am_pm; + char* DateTime_Format; + char* Twelve_hr_format; + char* Date_Format; + char* Time_Format; + char* Day_Names; + char* MonthNames; + char* TimeZone; +}; + +struct _loc_coll_cmpt +{ + char CmptName[8]; + int char_start_value; + int char_coll_tab_size; + short char_spec_accents; + unsigned short* char_coll_table_ptr; + unsigned short* wchar_coll_seq_ptr; +}; + +struct _loc_ctype_cmpt +{ + char CmptName[8]; + const unsigned short* ctype_map_ptr; + const unsigned char* upper_map_ptr; + const unsigned char* lower_map_ptr; + const unsigned short* wctype_map_ptr; + const wchar_t* wupper_map_ptr; + const wchar_t* wlower_map_ptr; + __decode_mbyte decode_mb; + __encode_mbyte encode_wc; +}; + +struct __locale +{ + struct __locale* next_locale; + char locale_name[48]; + struct _loc_coll_cmpt* coll_cmpt_ptr; + struct _loc_ctype_cmpt* ctype_cmpt_ptr; + struct _loc_mon_cmpt* mon_cmpt_ptr; + struct _loc_num_cmpt* num_cmpt_ptr; + struct _loc_time_cmpt* time_cmpt_ptr; +}; + +extern struct __locale _current_locale; +extern struct lconv __lconv; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/PowerPC_EABI_Support/include/math.h b/libs/PowerPC_EABI_Support/include/math.h new file mode 100644 index 000000000..edf13528a --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/math.h @@ -0,0 +1,99 @@ +#ifndef _MATH_H +#define _MATH_H + +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h" +#include "PowerPC_EABI_Support/MSL_C/PPC_EABI/math_ppc.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#ifndef __MWERKS__ +// Get clangd to shut up about __fabs being undefined. +#define __fabs(x) (x) +#define __fabsf(x) (x) +#define __frsqrte(x) (x) +#endif + +#define FABS(x) (float)__fabs(x) +// #define __frsqrtes opword + +#define SQUARE(v) ((v) * (v)) + +#define signbit(x) ((int)(__HI(x) & 0x80000000)) + +#define TAU 6.2831855f +#define PI 3.1415927f +#define HALF_PI 1.5707964f + +#define LONG_TAU 6.2831854820251465 + +extern int __float_nan[]; +extern int __float_huge[]; +extern int __double_huge[]; + +#define INFINITY (*(float*)__float_huge) +#define NAN (*(float*)__float_nan) +#define HUGE_VAL (*(double*)__double_huge) + +inline long double fabsl(long double x) +{ + return __fabs((double)x); +} + +inline double fabs(double x) +{ + return __fabs(x); +} + +double acos(double); +double asin(double); +double atan(double); +double atan2(double, double); +double ceil(double); +double floor(double); +float floorf(float x); +double frexp(double, int*); +double ldexp(double, int); +double sqrt(double); + +double pow(double, double); + +double log(double); +double log10(double); + +double fmod(double, double); + +double sin(double x); +double cos(double x); + +double __ieee754_acos(double); +double __ieee754_fmod(double, double); +double __ieee754_log(double); +double __ieee754_log10(double); +double __ieee754_pow(double, double); +double __ieee754_sqrt(double); +double __ieee754_atan2(double, double); +double __ieee754_asin(double); + +double scalbn(double, int); + +double __kernel_sin(double, double, int); +double __kernel_cos(double, double); +double __kernel_tan(double, double, int); + +int __ieee754_rem_pio2(double, double*); + +// static inline float atan2f(float y, float x) +// { +// return atan2(y, x); +// } + +// float sqrtf(float); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/mem.h b/libs/PowerPC_EABI_Support/include/mem.h new file mode 100644 index 000000000..a43890932 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/mem.h @@ -0,0 +1,20 @@ +#ifndef _MEM_H +#define _MEM_H + +#include "types.h" +#include "PowerPC_EABI_Support\Runtime\__mem.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +int memcmp(const void*, const void*, size_t); +void* __memrchr(const void* src, int val, size_t n); +void* memchr(const void* src, int val, size_t n); +void* memmove(void*, const void*, size_t); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/signal.h b/libs/PowerPC_EABI_Support/include/signal.h new file mode 100644 index 000000000..180ee669c --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/signal.h @@ -0,0 +1,18 @@ +#ifndef _SIGNAL_H +#define _SIGNAL_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*sig_func)(int sig); + +int raise(int sig); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/PowerPC_EABI_Support/include/stdarg.h b/libs/PowerPC_EABI_Support/include/stdarg.h new file mode 100644 index 000000000..5b4cc2185 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/stdarg.h @@ -0,0 +1,40 @@ + +#ifndef _STDARG_H_ +#define _STDARG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __MWERKS__ +typedef struct __va_list_struct +{ + char gpr; + char fpr; + char reserved[2]; + char *input_arg_area; + char *reg_save_area; +} __va_list[1]; +typedef __va_list va_list; + +#ifndef __MWERKS__ +extern void __builtin_va_info(va_list*); +#endif + +void* __va_arg(va_list v_list, unsigned char type); + +#define va_start(ap, fmt) ((void)fmt, __builtin_va_info(&ap)) +#define va_arg(ap, t) (*((t*)__va_arg(ap, _var_arg_typeof(t)))) +#define va_end(ap) (void)0 + +#else +typedef __builtin_va_list va_list; +#define va_start(v, l) __builtin_va_start(v, l) +#define va_end(v) __builtin_va_end(v) +#define va_arg(v, l) __builtin_va_arg(v, l) +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/PowerPC_EABI_Support/include/stddef.h b/libs/PowerPC_EABI_Support/include/stddef.h new file mode 100644 index 000000000..a0a90f9b4 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/stddef.h @@ -0,0 +1,6 @@ +#ifndef _MSL_STDDEF_H +#define _MSL_STDDEF_H + +#include + +#endif \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/include/stdio.h b/libs/PowerPC_EABI_Support/include/stdio.h new file mode 100644 index 000000000..1e8f9f66e --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/stdio.h @@ -0,0 +1,19 @@ +#ifndef _STDIO_H +#define _STDIO_H + +#include "types.h" +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/direct_io.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/file_io.h" +#include +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/scanf.h" + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/stdlib.h b/libs/PowerPC_EABI_Support/include/stdlib.h new file mode 100644 index 000000000..f573b4565 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/stdlib.h @@ -0,0 +1,20 @@ +#ifndef _STDLIB_H +#define _STDLIB_H + +#include "types.h" +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/alloc.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/arith.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/mbstring.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/rand.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/strtold.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/strtoul.h" + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/string.h b/libs/PowerPC_EABI_Support/include/string.h new file mode 100644 index 000000000..3d5f5cb5e --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/string.h @@ -0,0 +1,31 @@ +#ifndef _STRING_H +#define _STRING_H + +#include "types.h" +#include "mem.h" +#include "extras.h" +#ifdef __cplusplus +extern "C" { +#endif + +char* strcpy(char*, const char*); +char* strncpy(char*, const char*, size_t); + +char* strcat(char*, const char*); +char* strncat(char*, const char*, size_t); + +int strcmp(const char*, const char*); +int strncmp(const char*, const char*, size_t); +int strcmpi(const char* a, const char* b); +char* strchr(const char*, int); +char* strstr(const char*, const char*); +char* strrchr(const char* str, int chr); +size_t strlen(const char*); +long strtol(const char* str, char** end, int base); + +int __msl_strnicmp(const char* s1, const char* s2, int n); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/PowerPC_EABI_Support/include/utility b/libs/PowerPC_EABI_Support/include/utility new file mode 100644 index 000000000..223183a2c --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/utility @@ -0,0 +1,21 @@ +#ifndef _STD_PAIR_H +#define _STD_PAIR_H + +namespace std { +template +struct pair { + T1 first; + T2 second; +}; + +template <> +struct pair { + pair() + : first(0.0f) + , second(0.0f) {}; + float first; + float second; +}; +} // namespace std + +#endif diff --git a/libs/PowerPC_EABI_Support/include/wchar.h b/libs/PowerPC_EABI_Support/include/wchar.h new file mode 100644 index 000000000..2df951877 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/wchar.h @@ -0,0 +1,16 @@ +#ifndef _WCHAR_H +#define _WCHAR_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/wchar_io.h" + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/FILE_POS.C b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/FILE_POS.C new file mode 100644 index 000000000..b4b6d28d2 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/FILE_POS.C @@ -0,0 +1,130 @@ +#include "types.h" + +#ifndef _MSL_WIDE_CHAR +#define _MSL_WIDE_CHAR +#endif + +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h" +#include "errno.h" + +// define standard C file pointer location names +#define SEEK_SET (0) +#define SEEK_CUR (1) +#define SEEK_END (2) + +int _ftell(FILE* file) +{ + int charsInUndoBuffer = 0; + int position; + + u8 tmp_kind = file->mMode.file_kind; + if (!(tmp_kind == __disk_file || tmp_kind == __console_file) || file->mState.error) { + errno = 0x28; + return -1; + } + + if (file->mState.io_state == __neutral) + return (file->mPosition); + + position = file->mBufferPosition + (file->mBufferPtr - file->mBuffer); + + if (file->mState.io_state >= __rereading) { + charsInUndoBuffer = file->mState.io_state - __rereading + 1; + position -= charsInUndoBuffer; + } + + // got added in later it seems? + /*if (!file->mMode.binary_io) { + int n = file->mBufferPtr - file->mBuffer - charsInUndoBuffer; + u8* p = (u8*)file->mBuffer; + + while (n--) + if (*p++ == '\n') + position++; + }*/ + + return (position); +} + +int ftell(FILE* stream) +{ + int retval; + + __begin_critical_region(stdin_access); + retval = (long)_ftell(stream); + __end_critical_region(stdin_access); + return retval; +} + +int _fseek(FILE *file, fpos_t offset, int whence) +{ + fpos_t pos; + __pos_proc func; + + unsigned char fileKind = file->mMode.file_kind; + if (fileKind != 1 || file->mState.error != 0) { + errno = 0x28; + return -1; + } + + if (file->mState.io_state == 1) { + if (__flush_buffer(file, nullptr) != 0) { + file->mState.error = 1; + file->mBufferLength = 0; + errno = 0x28; + return -1; + } + } + + if (whence == SEEK_CUR) { + whence = SEEK_SET; + + if ((pos = _ftell(file)) < 0) + pos = 0; + + offset += pos; + } + + if ((whence != SEEK_END) && (file->mMode.io_mode != 3) && (file->mState.io_state == 2 || file->mState.io_state == 3)) { + if ((offset >= file->mPosition) || !(offset >= file->mBufferPosition)) { + file->mState.io_state = 0; + } else { + file->mBufferPtr = file->mBuffer + (offset - file->mBufferPosition); + file->mBufferLength = file->mPosition - offset; + file->mState.io_state = 2; + } + } else { + file->mState.io_state = 0; + } + + if (file->mState.io_state == 0) { + + if ((func = file->positionFunc) != nullptr && func(file->mHandle, &offset, whence, file->ref_con) != 0) + { + file->mState.error = 1; + file->mBufferLength = 0; + errno = 0x28; + return -1; + } + else + { + file->mState.eof = 0; + file->mPosition = offset; + file->mBufferLength = 0; + } + } + + return 0; +} + +int fseek(FILE *stream, fpos_t offset, int whence) +{ + fpos_t start; + int code; + start = offset; + __begin_critical_region(stdin_access); + code = _fseek(stream, start, whence); // 0 if successful, -1 if error + __end_critical_region(stdin_access); + return code; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/alloc.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/alloc.c new file mode 100644 index 000000000..016240ad6 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/alloc.c @@ -0,0 +1,452 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/alloc.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" + +typedef struct Block { + struct Block* prev; + struct Block* next; + unsigned long max_size; + unsigned long size; +} Block; + +typedef struct SubBlock { + unsigned long size; + Block* block; + struct SubBlock* prev; + struct SubBlock* next; +} SubBlock; + +struct FixSubBlock; + +typedef struct FixBlock { + struct FixBlock* prev_; + struct FixBlock* next_; + unsigned long client_size_; + struct FixSubBlock* start_; + unsigned long n_allocated_; +} FixBlock; + +typedef struct FixSubBlock { + FixBlock* block_; + struct FixSubBlock* next_; +} FixSubBlock; + +typedef struct FixStart { + FixBlock* tail_; + FixBlock* head_; +} FixStart; + +typedef struct __mem_pool_obj { + Block* start_; + FixStart fix_start[6]; +} __mem_pool_obj; + +typedef struct __mem_pool { + void* reserved[14]; +} __mem_pool; + +typedef signed long tag_word; + +typedef struct block_header { + tag_word tag; + struct block_header* prev; + struct block_header* next; +} block_header; + +typedef struct list_header { + block_header* rover; + block_header header; +} list_header; + +typedef struct heap_header { + struct heap_header* prev; + struct heap_header* next; +} heap_header; + +struct mem_pool_obj; +typedef void* (*sys_alloc_ptr)(unsigned long, struct mem_pool_obj*); +typedef void (*sys_free_ptr)(void*, struct mem_pool_obj*); + +typedef struct pool_options { + sys_alloc_ptr sys_alloc_func; + sys_free_ptr sys_free_func; + unsigned long min_heap_size; + int always_search_first; +} pool_options; + +typedef struct mem_pool_obj { + list_header free_list; + pool_options options; + heap_header* heap_list; + void* userData; + +} mem_pool_obj; + +mem_pool_obj __malloc_pool; +static int initialized = 0; + +static SubBlock* SubBlock_merge_prev(SubBlock*, SubBlock**); +static void SubBlock_merge_next(SubBlock*, SubBlock**); + +static const unsigned long fix_pool_sizes[] = { 4, 12, 20, 36, 52, 68 }; + +#define SubBlock_size(ths) ((ths)->size & 0xFFFFFFF8) +#define SubBlock_block(ths) ((Block*)((unsigned long)((ths)->block) & ~0x1)) +#define Block_size(ths) ((ths)->size & 0xFFFFFFF8) +#define Block_start(ths) (*(SubBlock**)((char*)(ths) + Block_size((ths)) - sizeof(unsigned long))) + +#define SubBlock_set_free(ths) \ + unsigned long this_size = SubBlock_size((ths)); \ + (ths)->size &= ~0x2; \ + *(unsigned long*)((char*)(ths) + this_size) &= ~0x4; \ + *(unsigned long*)((char*)(ths) + this_size - sizeof(unsigned long)) = this_size + +#define SubBlock_is_free(ths) !((ths)->size & 2) +#define SubBlock_set_size(ths, sz) \ + (ths)->size &= ~0xFFFFFFF8; \ + (ths)->size |= (sz)&0xFFFFFFF8; \ + if (SubBlock_is_free((ths))) \ + *(unsigned long*)((char*)(ths) + (sz) - sizeof(unsigned long)) = (sz) + +#define SubBlock_from_pointer(ptr) ((SubBlock*)((char*)(ptr)-8)) +#define FixSubBlock_from_pointer(ptr) ((FixSubBlock*)((char*)(ptr)-4)) + +#define FixBlock_client_size(ths) ((ths)->client_size_) +#define FixSubBlock_size(ths) (FixBlock_client_size((ths)->block_)) + +#define classify(ptr) (*(unsigned long*)((char*)(ptr) - sizeof(unsigned long)) & 1) +#define __msize_inline(ptr) \ + (!classify(ptr) ? FixSubBlock_size(FixSubBlock_from_pointer(ptr)) : SubBlock_size(SubBlock_from_pointer(ptr)) - 8) + +#define Block_empty(ths) (_sb = (SubBlock*)((char*)(ths) + 16)), SubBlock_is_free(_sb) && SubBlock_size(_sb) == Block_size((ths)) - 24 + +void Block_construct(void) +{ + // UNUSED FUNCTION +} + +void Block_subBlock(void) +{ + // UNUSED FUNCTION +} + +void Block_link(Block* ths, SubBlock* sb) +{ + SubBlock** st; + SubBlock_set_free(sb); + st = &Block_start(ths); + + if (*st != 0) { + sb->prev = (*st)->prev; + sb->prev->next = sb; + sb->next = *st; + (*st)->prev = sb; + *st = sb; + *st = SubBlock_merge_prev(*st, st); + SubBlock_merge_next(*st, st); + } else { + *st = sb; + sb->prev = sb; + sb->next = sb; + } + if (ths->max_size < SubBlock_size(*st)) + ths->max_size = SubBlock_size(*st); +} + +void Block_unlink(void) +{ + // UNUSED FUNCTION +} + +void Block_report(void) +{ + // UNUSED FUNCTION +} + +void SubBlock_construct(void) +{ + // UNUSED FUNCTION +} + +void SubBlock_split(void) +{ + // UNUSED FUNCTION +} + +static SubBlock* SubBlock_merge_prev(SubBlock* ths, SubBlock** start) +{ + unsigned long prevsz; + SubBlock* p; + + if (!(ths->size & 0x04)) { + prevsz = *(unsigned long*)((char*)ths - sizeof(unsigned long)); + if (prevsz & 0x2) + return ths; + p = (SubBlock*)((char*)ths - prevsz); + SubBlock_set_size(p, prevsz + SubBlock_size(ths)); + + if (*start == ths) + *start = (*start)->next; + ths->next->prev = ths->prev; + ths->next->prev->next = ths->next; + return p; + } + return ths; +} + +static void SubBlock_merge_next(SubBlock* pBlock, SubBlock** pStart) +{ + SubBlock* next_sub_block; + unsigned long this_cur_size; + + next_sub_block = (SubBlock*)((char*)pBlock + (pBlock->size & 0xFFFFFFF8)); + + if (!(next_sub_block->size & 2)) { + this_cur_size = (pBlock->size & 0xFFFFFFF8) + (next_sub_block->size & 0xFFFFFFF8); + + pBlock->size &= ~0xFFFFFFF8; + pBlock->size |= this_cur_size & 0xFFFFFFF8; + + if (!(pBlock->size & 2)) { + *(unsigned long*)((char*)(pBlock) + (this_cur_size)-4) = (this_cur_size); + } + + if (!(pBlock->size & 2)) { + *(unsigned long*)((char*)pBlock + this_cur_size) &= ~4; + } else { + *(unsigned long*)((char*)pBlock + this_cur_size) |= 4; + } + + if (*pStart == next_sub_block) { + *pStart = (*pStart)->next; + } + + if (*pStart == next_sub_block) { + *pStart = 0; + } + + next_sub_block->next->prev = next_sub_block->prev; + next_sub_block->prev->next = next_sub_block->next; + } +} + +void SubBlock_report(void) +{ + // UNUSED FUNCTION +} + +void link(void) +{ + // UNUSED FUNCTION +} + +static Block* __unlink(__mem_pool_obj* pool_obj, Block* bp) +{ + Block* result = bp->next; + if (result == bp) { + result = 0; + } + + if (pool_obj->start_ == bp) { + pool_obj->start_ = result; + } + + if (result != 0) { + result->prev = bp->prev; + result->prev->next = result; + } + + bp->next = 0; + bp->prev = 0; + return result; +} + +void link_new_block(void) +{ + // UNUSED FUNCTION +} + +void allocate_from_var_pools(void) +{ + // UNUSED FUNCTION +} + +void soft_allocate_from_var_pools(void) +{ + // UNUSED FUNCTION +} + +static void deallocate_from_var_pools(__mem_pool_obj* pool_obj, void* ptr) +{ + SubBlock* sb = SubBlock_from_pointer(ptr); + SubBlock* _sb; + + Block* bp = SubBlock_block(sb); + Block_link(bp, sb); + + if (Block_empty(bp)) { + __unlink(pool_obj, bp); + __sys_free(bp); + } +} + +void FixBlock_construct(void) +{ + // UNUSED FUNCTION +} + +void __init_pool_obj(__mem_pool* pool_obj) { memset(pool_obj, 0, sizeof(__mem_pool_obj)); } + +static __mem_pool* get_malloc_pool(void) +{ + static __mem_pool protopool; + static unsigned char init = 0; + if (!init) { + __init_pool_obj(&protopool); + init = 1; + } + + return &protopool; +} + +void allocate_from_fixed_pools(void) +{ + // UNUSED FUNCTION +} + +void deallocate_from_fixed_pools(__mem_pool_obj* pool_obj, void* ptr, unsigned long size) +{ + unsigned long i = 0; + FixSubBlock* p; + FixBlock* b; + FixStart* fs; + + while (size > fix_pool_sizes[i]) { + ++i; + } + + fs = &pool_obj->fix_start[i]; + p = FixSubBlock_from_pointer(ptr); + b = p->block_; + + if (b->start_ == 0 && fs->head_ != b) { + if (fs->tail_ == b) { + fs->head_ = fs->head_->prev_; + fs->tail_ = fs->tail_->prev_; + } else { + b->prev_->next_ = b->next_; + b->next_->prev_ = b->prev_; + b->next_ = fs->head_; + b->prev_ = b->next_->prev_; + b->prev_->next_ = b; + b->next_->prev_ = b; + fs->head_ = b; + } + } + + p->next_ = b->start_; + b->start_ = p; + + if (--b->n_allocated_ == 0) { + if (fs->head_ == b) { + fs->head_ = b->next_; + } + + if (fs->tail_ == b) { + fs->tail_ = b->prev_; + } + + b->prev_->next_ = b->next_; + b->next_->prev_ = b->prev_; + + if (fs->head_ == b) { + fs->head_ = 0; + } + + if (fs->tail_ == b) { + fs->tail_ = 0; + } + + deallocate_from_var_pools(pool_obj, b); + } +} + +void __report_on_pool_heap(void) +{ + // UNUSED FUNCTION +} + +void __report_on_heap(void) +{ + // UNUSED FUNCTION +} + +void __msize(void) +{ + // UNUSED FUNCTION +} + +void __pool_alloc(void) +{ + // UNUSED FUNCTION +} + +void __pool_free(__mem_pool* pool, void* ptr) +{ + __mem_pool_obj* pool_obj; + unsigned long size; + + if (ptr == 0) { + return; + } + + pool_obj = (__mem_pool_obj*)pool; + size = __msize_inline(ptr); + + if (size <= 68) { + deallocate_from_fixed_pools(pool_obj, ptr, size); + } else { + deallocate_from_var_pools(pool_obj, ptr); + } +} + +void __pool_realloc(void) +{ + // UNUSED FUNCTION +} + +void __pool_alloc_clear(void) +{ + // UNUSED FUNCTION +} + +void malloc(void) +{ + // UNUSED FUNCTION +} + +void free(void* ptr) +{ + __begin_critical_region(malloc_pool_access); + __pool_free(get_malloc_pool(), ptr); + __end_critical_region(malloc_pool_access); +} + +void realloc(void) +{ + // UNUSED FUNCTION +} + +void calloc(void) +{ + // UNUSED FUNCTION +} + +void __pool_free_all(void) +{ + // UNUSED FUNCTION +} + +void __malloc_free_all(void) +{ + // UNUSED FUNCTION +} \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ansi_files.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ansi_files.c new file mode 100644 index 000000000..a210e106f --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ansi_files.c @@ -0,0 +1,154 @@ +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" + +static char stdin_buff[0x100]; +static char stdout_buff[0x100]; +static char stderr_buff[0x100]; + +extern void fclose(FILE*); +extern int __read_console(u32, char*, u32*, void*); +extern int __write_console(u32, char*, u32*, void*); +extern int __close_console(u32); + +// clang-format off +FILE __files[4] = +{ + { 0, // _00 + 0, // _04, open_mode + 1, // _04, io_mode + 1, // _04, buffer_mode + 2, // _04, file_kind + 0, // _04, binary_io + 0, // _08, io_state + 0, // _08, free_buffer + 0, // _08, eof + 0, // _08, error + 0, // _0C + 0, // _0D + 0, // _0E + 0, // _0F + 0, // _10 + 0, // _12 + 0, // _14 + 0, // _18 + stdin_buff, // _1C + sizeof(stdin_buff), // _20 + stdin_buff, // _24 + 0, // _28 + 0, // _2C + 0, // _30 + 0, // _34 + nullptr, // _38 + &__read_console, // _3C + &__write_console, // _40 + &__close_console, // _44 + 0, // _48 + &__files[1] // _4C + }, + { 1, // _00 + 0, // _04, open_mode + 2, // _04, io_mode + 1, // _04, buffer_mode + 2, // _04, file_kind + 0, // _04, binary_io + 0, // _08, io_state + 0, // _08, free_buffer + 0, // _08, eof + 0, // _08, error + 0, // _0C + 0, // _0D + 0, // _0E + 0, // _0F + 0, // _10 + 0, // _12 + 0, // _14 + 0, // _18 + stdout_buff, // _1C + sizeof(stdout_buff), // _20 + stdout_buff, // _24 + 0, // _28 + 0, // _2C + 0, // _30 + 0, // _34 + nullptr, // _38 + &__read_console, // _3C + &__write_console, // _40 + &__close_console, // _44 + 0, // _48 + &__files[2] // _4C + }, + { 2, // _00 + 0, // _04, open_mode + 2, // _04, io_mode + 0, // _04, buffer_mode + 2, // _04, file_kind + 0, // _04, binary_io + 0, // _08, io_state + 0, // _08, free_buffer + 0, // _08, eof + 0, // _08, error + 0, // _0C + 0, // _0D + 0, // _0E + 0, // _0F + 0, // _10 + 0, // _12 + 0, // _14 + 0, // _18 + stderr_buff, // _1C + sizeof(stderr_buff), // _20 + stderr_buff, // _24 + 0, // _28 + 0, // _2C + 0, // _30 + 0, // _34 + nullptr, // _38 + &__read_console, // _3C + &__write_console, // _40 + &__close_console, // _44 + 0, // _48 + &__files[3] // _4C + }, +}; +// clang-format on + +void __close_all() +{ + FILE* p = &__files[0]; + FILE* plast; + + __begin_critical_region(stdin_access); + + while (p) { + if (p->mMode.file_kind != __closed_file) { + fclose(p); + } + + plast = p; + p = p->mNextFile; + if (plast->mIsDynamicallyAllocated) + free(plast); + else { + plast->mMode.file_kind = __unavailable_file; + if ((p != NULL) && p->mIsDynamicallyAllocated) + plast->mNextFile = nullptr; + } + } + + __end_critical_region(stdin_access); +} + +u32 __flush_all() +{ + u32 retval = 0; + FILE* __stream; + __stream = &__files[0]; + while (__stream) { + if ((__stream->mMode.file_kind) && (fflush(__stream))) { + retval = -1; + } + __stream = __stream->mNextFile; + }; + return retval; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/arith.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/arith.c new file mode 100644 index 000000000..fd9e3667a --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/arith.c @@ -0,0 +1,120 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/arith.h" + +long abs(long x) +{ + if (x < 0) + return -x; + else + return x; +} + +long labs(long x) +{ + // UNUSED FUNCTION + if (x < 0) + return -x; + else + return x; +} + +void llabs(void) +{ + // UNUSED FUNCTION +} + +div_t div(s32 __numer, s32 __denom) +{ + // UNUSED FUNCTION + int iVar1; + int iVar2; + int iVar3; + div_t ret; + + iVar2 = 1; + iVar3 = 1; + if (__numer < 0) + { + __numer = -__numer; + iVar2 = -1; + } + if (__denom < 0) + { + __denom = -__denom; + iVar3 = -1; + } + iVar1 = (__numer / __denom) * (iVar2 * iVar3); + + ret.quot = iVar1; + ret.rem = __numer * iVar2 - iVar3 * (iVar1 * __denom); + return ret; +} + +void ldiv(void) +{ + // UNUSED FUNCTION +} + +void lldiv(void) +{ + // UNUSED FUNCTION +} + +void __msl_add(void) +{ + // UNUSED FUNCTION +} + +void __msl_ladd(void) +{ + // UNUSED FUNCTION +} + +void __lladd(void) +{ + // UNUSED FUNCTION +} + +void __msl_mul(void) +{ + // UNUSED FUNCTION +} + +void __msl_lmul(void) +{ + // UNUSED FUNCTION +} + +void __llmul(void) +{ + // UNUSED FUNCTION +} + +void __msl_div(void) +{ + // UNUSED FUNCTION +} + +void __msl_ldiv(void) +{ + // UNUSED FUNCTION +} + +void __lldiv(void) +{ + // UNUSED FUNCTION +} + +void __msl_mod(void) +{ + // UNUSED FUNCTION +} + +void __msl_lmod(void) +{ + // UNUSED FUNCTION +} + +void __llmod(void) +{ + // UNUSED FUNCTION +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/bsearch.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/bsearch.c new file mode 100644 index 000000000..d8ea8e560 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/bsearch.c @@ -0,0 +1,40 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/bsearch.h" + +void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *)) +{ + int cmp; + size_t lower, upper; + size_t index; + const void *p; + + if (key == NULL || base == NULL || nmemb == 0 || size == 0 || compar == NULL) + return NULL; + + p = base; + cmp = (*compar)(key, p); + if(cmp == 0) + return (void *)p; + + if(cmp < 0) + return NULL; + + lower = 1; + upper = nmemb - 1; + + while (lower <= upper) + { + index = (lower + upper) / 2; + p = (const char *)base + (size * index); + cmp = (*compar)(key, p); + + if (cmp == 0) + return (void *)p; + if (cmp < 0) + upper = index - 1; + else + lower = index + 1; + } + + return NULL; +} \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/buffer_io.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/buffer_io.c new file mode 100644 index 000000000..9e3ed8afb --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/buffer_io.c @@ -0,0 +1,53 @@ +#ifndef _MSL_WIDE_CHAR +#define _MSL_WIDE_CHAR +#endif + +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" +#include "types.h" + +void __convert_from_newlines(char *buffer, size_t *length) +{ + return; +} + +void __convert_to_newlines() +{ + // UNUSED +} + +void __prep_buffer(FILE *file) +{ + file->mBufferPtr = file->mBuffer; + file->mBufferLength = file->mBufferSize; + file->mBufferLength = file->mBufferLength - (file->mPosition & file->mBufferAlignment); + file->mBufferPosition = file->mPosition; + return; +} + +int __flush_buffer(FILE *file, size_t *length) +{ + size_t bufferLen; + int writeCode; + char binmode; + + bufferLen = file->mBufferPtr - file->mBuffer; + if (bufferLen) { + file->mBufferLength = bufferLen; + + if (file->mMode.binary_io == 0) { + __convert_from_newlines(file->mBuffer, &file->mBufferLength); + } + + writeCode = file->writeFunc(file->mHandle, file->mBuffer, &file->mBufferLength, file->ref_con); + if (length) { + *length = file->mBufferLength; + } + if (writeCode) { + return writeCode; + } + file->mPosition += file->mBufferLength; + } + + __prep_buffer(file); + return 0; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ctype.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ctype.c new file mode 100644 index 000000000..bc673a86d --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ctype.c @@ -0,0 +1,137 @@ +#include "ctype.h" +#include "types.h" + +#define octrl 0x01 +#define omotn 0x02 +#define ospac 0x04 +#define opunc 0x08 +#define odigi 0x10 +#define ohexd 0x20 +#define olowc 0x40 +#define ouppc 0x80 +#define odhex ohexd | odigi +#define ouhex ohexd | ouppc +#define olhex ohexd | olowc + +unsigned char __ctype_map[256] = { + octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, omotn, omotn, omotn, omotn, + omotn, octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, + octrl, octrl, octrl, octrl, octrl, octrl, ospac, opunc, opunc, opunc, opunc, opunc, opunc, + opunc, opunc, opunc, opunc, opunc, opunc, opunc, opunc, opunc, odhex, odhex, odhex, odhex, + odhex, odhex, odhex, odhex, odhex, odhex, opunc, opunc, opunc, opunc, opunc, opunc, opunc, + ouhex, ouhex, ouhex, ouhex, ouhex, ouhex, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, + ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, + opunc, opunc, opunc, opunc, opunc, opunc, olhex, olhex, olhex, olhex, olhex, olhex, olowc, + olowc, olowc, olowc, olowc, olowc, olowc, olowc, olowc, olowc, olowc, olowc, olowc, olowc, + olowc, olowc, olowc, olowc, olowc, olowc, opunc, opunc, opunc, opunc, octrl +}; + +unsigned char __lower_map[256] = { + 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, 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, 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, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +}; + +unsigned char __upper_map[256] = { + 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, 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, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +}; + +void isalnum(void) +{ + // UNUSED FUNCTION +} + +int isalpha(int c) +{ + return (int)(__ctype_map[(u8)c] & __letter); +} + +void iscntrl(void) +{ + // UNUSED FUNCTION +} + +BOOL isdigit(int c) +{ + { + return (int)(__ctype_map[(u8)c] & __digit); + } +} + +void isgraph(void) +{ + // UNUSED FUNCTION +} + +BOOL islower(unsigned char c) +{ + return __ctype_map[c] & olowc; +} + +// void isprint(void) +// { +// // UNUSED FUNCTION +// } + +void ispunct(void) +{ + // UNUSED FUNCTION +} + +int isspace(int c) +{ + return (int)(__ctype_map[(u8)c] & __whitespace); +} + +BOOL isupper(int c) +{ + return (int)(__ctype_map[(u8)c] & __upper_case); +} + +BOOL isxdigit(int c) +{ + return (int)(__ctype_map[(u8)c] & __hex_digit); +} + +int tolower(int c) +{ + return (c == -1 ? -1 : (int)__lower_map[(u8)c]); +} + +int toupper(int c) +{ + return (c == -1 ? -1 : (int)__upper_map[(u8)c]); +} + +void iswblank(void) +{ + // UNUSED FUNCTION +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/direct_io.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/direct_io.c new file mode 100644 index 000000000..4364c3533 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/direct_io.c @@ -0,0 +1,143 @@ +#include "types.h" + +#ifndef _MSL_WIDE_CHAR +#define _MSL_WIDE_CHAR +#endif + +#include "wchar.h" +#include "stdio.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" + +void fread(void) +{ + // UNUSED FUNCTION +} + + +void __fread(void) +{ + // UNUSED FUNCTION +} + +size_t fwrite(const void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile) +{ + size_t retval; + + __begin_critical_region(stdin_access); + retval = __fwrite(pPtr, memb_size, num_memb, pFile); + __end_critical_region(stdin_access); + + return retval; +} + +size_t __fwrite(const void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile) +{ + unsigned char* cur_ptr; + size_t num_bytes, rem_bytes, bytes_written; + int res, buff; + + if (fwide(pFile, 0) == 0) { + fwide(pFile, -1); + } + + rem_bytes = memb_size * num_memb; + + if (rem_bytes == 0 || pFile->mState.error || pFile->mMode.file_kind == 0) { + return 0; + } + + if (pFile->mMode.file_kind == 2) { + __stdio_atexit(); + } + + buff = (!pFile->mMode.binary_io || pFile->mMode.buffer_mode == 2 || pFile->mMode.buffer_mode == 1); + + if (pFile->mState.io_state == 0 && pFile->mMode.io_mode & 2) { + if (pFile->mMode.io_mode & 4) { + if (fseek(pFile, 0, 2)) { + return 0; + } + } + + pFile->mState.io_state = 1; + __prep_buffer(pFile); + } + + if (pFile->mState.io_state != 1) { + pFile->mState.error = 1; + pFile->mBufferLength = 0; + return 0; + } + + cur_ptr = (unsigned char*)pPtr; + bytes_written = 0; + + if (rem_bytes && (pFile->mBufferPtr != pFile->mBuffer || buff)) { + pFile->mBufferLength = pFile->mBufferSize - (pFile->mBufferPtr - pFile->mBuffer); + + do { + unsigned char* nw = 0; + num_bytes = pFile->mBufferLength; + + if (num_bytes > rem_bytes) { + num_bytes = rem_bytes; + } + + if (pFile->mMode.buffer_mode == 1 && num_bytes) { + if ((nw = (unsigned char*)__memrchr(cur_ptr, '\n', num_bytes)) != 0) { + num_bytes = nw + 1 - cur_ptr; + } + } + + if (num_bytes != 0) { + memcpy(pFile->mBufferPtr, cur_ptr, num_bytes); + cur_ptr += num_bytes; + bytes_written += num_bytes; + rem_bytes -= num_bytes; + pFile->mBufferPtr += num_bytes; + pFile->mBufferLength -= num_bytes; + } + + if (pFile->mBufferLength == 0 || nw != 0 || (!pFile->mMode.buffer_mode)) { + res = __flush_buffer(pFile, 0); + + if (res != 0) { + pFile->mState.error = 1; + pFile->mBufferLength = 0; + rem_bytes = 0; + break; + } + } + + } while (rem_bytes && buff); + } + + if (rem_bytes && buff == 0) { + unsigned char* save_buf = (unsigned char*)pFile->mBuffer; + size_t save_size = pFile->mBufferSize; + + pFile->mBuffer = (char*)cur_ptr; + pFile->mBufferSize = rem_bytes; + pFile->mBufferPtr = (char*)cur_ptr + rem_bytes; + + if (__flush_buffer(pFile, &num_bytes) != 0) { + pFile->mState.error = 1; + pFile->mBufferLength = 0; + } + + bytes_written += num_bytes; + + pFile->mBuffer = (char*)save_buf; + pFile->mBufferSize = save_size; + __prep_buffer(pFile); + pFile->mBufferLength = 0; + } + + if (pFile->mMode.buffer_mode != 2) { + pFile->mBufferLength = 0; + } + + return (bytes_written + memb_size - 1) / memb_size; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/errno.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/errno.c new file mode 100644 index 000000000..afee599b7 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/errno.c @@ -0,0 +1,3 @@ +#include "errno.h" + +int errno; diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/extras.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/extras.c new file mode 100644 index 000000000..6e056b18c --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/extras.c @@ -0,0 +1,401 @@ +#include "types.h" +#include "ctype.h" + +void strdup(void) +{ + // UNUSED FUNCTION +} + +void _strdup(void) +{ + // UNUSED FUNCTION +} + +void strlwr(void) +{ + // UNUSED FUNCTION +} + +void _strlwr(void) +{ + // UNUSED FUNCTION +} + +void ultoa(void) +{ + // UNUSED FUNCTION +} + +void _ultoa(void) +{ + // UNUSED FUNCTION +} + +void gcvt(void) +{ + // UNUSED FUNCTION +} + +void _gcvt(void) +{ + // UNUSED FUNCTION +} + +void heapmin(void) +{ + // UNUSED FUNCTION +} + +void _heapmin(void) +{ + // UNUSED FUNCTION +} + +int stricmp(char* param_1, char* param_2) +{ + s8 a_var; + s8 b_var; + + do { + a_var = *param_1; + param_1++; + b_var = _tolower(a_var); + + a_var = *param_2; + param_2++; + a_var = _tolower(a_var); + + if (b_var < a_var) { + return -1; + } + if (b_var > a_var) { + return 1; + } + } while (b_var != 0); + return 0; +} + +void _stricmp(void) +{ + // UNUSED FUNCTION +} + +int strnicmp(const char *s1, const char *s2, int n) +{ + return __msl_strnicmp(s1, s2, n); +} + +void _strnicmp(void) +{ + // UNUSED FUNCTION +} + +void strupr(void) +{ + // UNUSED FUNCTION +} + +void _strupr(void) +{ + // UNUSED FUNCTION +} + +void strdate(void) +{ + // UNUSED FUNCTION +} + +void _strdate(void) +{ + // UNUSED FUNCTION +} + +void strset(void) +{ + // UNUSED FUNCTION +} + +void _strset(void) +{ + // UNUSED FUNCTION +} + +void strnset(void) +{ + // UNUSED FUNCTION +} + +void _strnset(void) +{ + // UNUSED FUNCTION +} + +void strspnp(void) +{ + // UNUSED FUNCTION +} + +void _strspnp(void) +{ + // UNUSED FUNCTION +} + +void strncasecmp(void) +{ + // UNUSED FUNCTION +} + +void _strncasecmp(void) +{ + // UNUSED FUNCTION +} + +void strcmpi(void) +{ + // UNUSED FUNCTION +} + +void _strcmpi(void) +{ + // UNUSED FUNCTION +} + +void strncmpi(void) +{ + // UNUSED FUNCTION +} + +void _strncmpi(void) +{ + // UNUSED FUNCTION +} + +void strcasecmp(void) +{ + // UNUSED FUNCTION +} + +void _strcasecmp(void) +{ + // UNUSED FUNCTION +} + +void _stricoll(void) +{ + // UNUSED FUNCTION +} + +void _strncoll(void) +{ + // UNUSED FUNCTION +} + +void _strnicoll(void) +{ + // UNUSED FUNCTION +} + +void stricoll(void) +{ + // UNUSED FUNCTION +} + +void strncoll(void) +{ + // UNUSED FUNCTION +} + +void strnicoll(void) +{ + // UNUSED FUNCTION +} + +void itoa(void) +{ + // UNUSED FUNCTION +} + +void _itoa(void) +{ + // UNUSED FUNCTION +} + +void strrev(void) +{ + // UNUSED FUNCTION +} + +void _strrev(void) +{ + // UNUSED FUNCTION +} + +void filelength(void) +{ + // UNUSED FUNCTION +} + +void _filelength(void) +{ + // UNUSED FUNCTION +} + +void chsize(void) +{ + // UNUSED FUNCTION +} + +void _chsize(void) +{ + // UNUSED FUNCTION +} + +void wtoi(void) +{ + // UNUSED FUNCTION +} + +void _wtoi(void) +{ + // UNUSED FUNCTION +} + +void wcslwr(void) +{ + // UNUSED FUNCTION +} + +void _wcslwr(void) +{ + // UNUSED FUNCTION +} + +void wcsupr(void) +{ + // UNUSED FUNCTION +} + +void _wcsupr(void) +{ + // UNUSED FUNCTION +} + +void wcsicmp(void) +{ + // UNUSED FUNCTION +} + +void _wcsicmp(void) +{ + // UNUSED FUNCTION +} + +void wcsnicmp(void) +{ + // UNUSED FUNCTION +} + +void _wcsnicmp(void) +{ + // UNUSED FUNCTION +} + +void wcsrev(void) +{ + // UNUSED FUNCTION +} + +void _wcsrev(void) +{ + // UNUSED FUNCTION +} + +void wcsset(void) +{ + // UNUSED FUNCTION +} + +void _wcsset(void) +{ + // UNUSED FUNCTION +} + +void wcsnset(void) +{ + // UNUSED FUNCTION +} + +void _wcsnset(void) +{ + // UNUSED FUNCTION +} + +void wcsspnp(void) +{ + // UNUSED FUNCTION +} + +void _wcsspnp(void) +{ + // UNUSED FUNCTION +} + +void wcsdup(void) +{ + // UNUSED FUNCTION +} + +void _wcsdup(void) +{ + // UNUSED FUNCTION +} + +void wstrrev(void) +{ + // UNUSED FUNCTION +} + +void _wstrrev(void) +{ + // UNUSED FUNCTION +} + +void _wcsicoll(void) +{ + // UNUSED FUNCTION +} + +void _wcsncoll(void) +{ + // UNUSED FUNCTION +} + +void _wcsnicoll(void) +{ + // UNUSED FUNCTION +} + +void wcsicoll(void) +{ + // UNUSED FUNCTION +} + +void wcsncoll(void) +{ + // UNUSED FUNCTION +} + +void wcsnicoll(void) +{ + // UNUSED FUNCTION +} + +void itow(void) +{ + // UNUSED FUNCTION +} + +void _itow(void) +{ + // UNUSED FUNCTION +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/file_io.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/file_io.c new file mode 100644 index 000000000..ae3b5d100 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/file_io.c @@ -0,0 +1,93 @@ +#include "types.h" +#include "string.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +int fclose(FILE* file) +{ + int flush_result, close_result; + + if (file == nullptr) + return (-1); + if (file->mMode.file_kind == __closed_file) + return (0); + + flush_result = fflush(file); + + close_result = (*file->closeFunc)(file->mHandle); + + file->mMode.file_kind = __closed_file; + file->mHandle = 0; + + if (file->mState.free_buffer) + free(file->mBuffer); + return ((flush_result || close_result) ? -1 : 0); +} + +int fflush(FILE* file) +{ + u32 pos; + + if (file == nullptr) { + return __flush_all(); + } + + if (file->mState.error != 0 || file->mMode.file_kind == __closed_file) { + return -1; + } + + if (file->mMode.io_mode == 1) { + return 0; + } + + if (file->mState.io_state >= 3) { + file->mState.io_state = 2; + } + + if (file->mState.io_state == 2) { + file->mBufferLength = 0; + } + + if (file->mState.io_state != 1) { + file->mState.io_state = 0; + return 0; + } + + if (file->mMode.file_kind != __disk_file || (pos = ftell(file)) < 0) + pos = 0; + + if (__flush_buffer(file, 0) != 0) { + file->mState.error = 1; + file->mBufferLength = 0; + return -1; + } + + file->mState.io_state = 0; + file->mPosition = pos; + file->mBufferLength = 0; + return 0; +} + +int __msl_strnicmp(const char *s1, const char *s2, int n) +{ + int i; + char c1, c2; + + for (i = 0; i < n; i++) { + c1 = tolower(*s1++); + c2 = tolower(*s2++); + + if(c1 < c2) { + return -1; + } + + if (c1 > c2) { + return 1; + } + + if(c1 == '\0') { + return 0; + } + } + return 0; + +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/float.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/float.c new file mode 100644 index 000000000..1aa55ea34 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/float.c @@ -0,0 +1,8 @@ +long __float_nan[] = { 0x7FFFFFFF }; +long __float_huge[] = { 0x7F800000 }; +long __double_max[] = { 0x7FEFFFFF, 0xFFFFFFFF }; +long __double_huge[] = { 0x7FF00000, 0 }; +long __extended_min[] = { 0x00100000, 0 }; +long __extended_max[] = { 0x7FEFFFFF, 0xFFFFFFFF }; +long __float_max[] = { 0x7F7FFFFF }; +long __float_epsilon[] = { 0x34000000 }; diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/locale.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/locale.c new file mode 100644 index 000000000..7b7961b9e --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/locale.c @@ -0,0 +1,33 @@ +#include "types.h" + +typedef struct { + char* _0; + char* _4; + char* _8; + char* _C; + char* _10; + char* _14; + char* _18; + char* _1C; + char* _20; + char _24; + char _25; + char _26; + char _27; + char _28; + char _29; + char _2A; + char* _2C; + char _30; + char _31; + char _32; + char _33; + char _34; + char _35; + char _36; +} lconv; + +lconv __lconv + = { ".", "", "", "", "", "", "", "", "", 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, "", 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F }; + +const char* dummy = "C"; diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mbstring.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mbstring.c new file mode 100644 index 000000000..ae40b6f31 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mbstring.c @@ -0,0 +1,260 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/mbstring.h" + +void mblen(void) +{ + // UNUSED FUNCTION +} + +static int is_utf8_complete(const char* s, size_t n) +{ + if (n == 0) { // must have more than zero characters + return -1; + } + + if (s[0] == 0x00) { // first char is 0 + return 0; + } + + if ((s[0] & 0x80) == 0x00) { + return (1); + } else if ((s[0] & 0xe0) == 0xc0) { + if (n >= 2) { + if ((*(s + 1) & 0x80) == 0x80) { + return 2; + } + return -1; + } + return -2; + } else if ((s[0] & 0xf0) == 0xe0) { + if (n >= 3) { + if ((s[1] & 0x80) == 0x80) { + if ((s[2] & 0x80) == 0x80) { + return 3; + } + } + return -1; + } else if ((n == 2 && ((s[1] & 0x80) == 0x80)) || n == 1) { + return -2; + } + return -1; + } else { + return (-1); + } +} + +static int utf8_to_unicode(wchar_t *pwc, const char *s, size_t n) +{ + int number_of_bytes; + int isUTF8; + char *source; + u16 result_chr = 0; + + if (!s) + { + return 0; + } + + if (n <= 0) + { + return -1; + } + + number_of_bytes = is_utf8_complete(s, n); + if (number_of_bytes < 0) + { + return -1; + } + + source = (char *)s; + switch (number_of_bytes) + { + case 3: + result_chr |= (*source++ & 0x0f); + result_chr <<= 6; + case 2: + result_chr |= (*source++ & 0x3f); + result_chr <<= 6; + case 1: + result_chr |= (*source++ & 0x7f); + } + + if (result_chr == 0) + { + isUTF8 = 0; + } + else if (result_chr < 0x00000080) + { + isUTF8 = 1; + } + else if (result_chr < 0x00000800) + { + isUTF8 = 2; + } + else + { + isUTF8 = 3; + } + + if (isUTF8 != number_of_bytes) + { + return -1; + } + if (pwc) + { + *pwc = result_chr; + } + + return number_of_bytes; +} + +int mbtowc(wchar_t *pwc, const char *s, size_t n) { return utf8_to_unicode(pwc, s, n); } + +inline static int unicode_to_UTF8(char* s, wchar_t wchar) +{ + int number_of_bytes; + wchar_t wide_char; + char* target_ptr; + char first_byte_mark[4] = { 0x00, 0x00, 0xc0, 0xe0 }; + + if (!s) + return (0); + + wide_char = wchar; + if (wide_char < 0x0080) + number_of_bytes = 1; + else if (wide_char < 0x0800) + number_of_bytes = 2; + else + number_of_bytes = 3; + + target_ptr = s + number_of_bytes; + + switch (number_of_bytes) { + case 3: + *--target_ptr = (wide_char & 0x003f) | 0x80; + wide_char >>= 6; + case 2: + *--target_ptr = (wide_char & 0x003f) | 0x80; + wide_char >>= 6; + case 1: + *--target_ptr = wide_char | first_byte_mark[number_of_bytes]; + } + + return number_of_bytes; +} + +inline int wctomb(char* s, wchar_t wchar) { return (unicode_to_UTF8(s, wchar)); } + +inline int mbstowcs(wchar_t* pwc, const char* s, size_t n) +{ + u32 result_chr; + int number_of_bytes = 0; + int isUTF8; + char* source; + + if (!s) { + number_of_bytes = 0; + return (number_of_bytes); + } + + if (n <= 0) { + number_of_bytes = -1; + return (number_of_bytes); + } + + isUTF8 = is_utf8_complete(s, n); + if (isUTF8 < 0) { + number_of_bytes = -1; + return number_of_bytes; + } + + source = (char*)s; + switch (isUTF8) { + case 3: + result_chr = (*source & 0x1f); + source++; + number_of_bytes = (result_chr << 6) & 0x3C0; + case 2: + result_chr = number_of_bytes | (*source & 0x3f); + source++; + number_of_bytes = (result_chr << 6) & 0xFFC0; + case 1: + result_chr = number_of_bytes | (*source & 0x7f); + source++; + number_of_bytes = result_chr & 0xFFFF; + } + + result_chr = number_of_bytes & 0xFFFF; + + if (!(result_chr)) { + result_chr = 0; + } else if (result_chr < 0x00000080) { + result_chr = 1; + } else if (result_chr < 0x00000800) { + result_chr = 2; + } else { + result_chr = 3; + } + + if ((int)result_chr != isUTF8) { + number_of_bytes = -1; + return (number_of_bytes); + } + if (pwc) { + *pwc = number_of_bytes; + } + return isUTF8; +} + +size_t wcstombs(char* s, const wchar_t* pwcs, size_t n) +{ + int chars_written = 0; + int result; + char temp[3]; + wchar_t* source; + + if (!s || !pwcs) + return (0); + + source = (wchar_t*)pwcs; + while (chars_written <= n) { + if (!*source) { + *(s + chars_written) = '\0'; + break; + } else { + result = wctomb(temp, *source++); + if ((chars_written + result) <= n) { + strncpy(s + chars_written, temp, result); + chars_written += result; + } else + break; + } + } + + return chars_written; +} + +void mbrlen(void) +{ + // UNUSED FUNCTION +} + +void mbrtowc(void) +{ + // UNUSED FUNCTION +} + +void wcrtomb(void) +{ + // UNUSED FUNCTION +} + +void mbsrtowcs(void) +{ + // UNUSED FUNCTION +} + +void wcsrtombs(void) +{ + // UNUSED FUNCTION +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem.c new file mode 100644 index 000000000..e5a397182 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem.c @@ -0,0 +1,105 @@ +#include "types.h" +#include "mem.h" + +void *memmove(void *dst, const void *src, size_t len) +{ + const char *csrc; + char *cdst; + + int reverse = (u32)src < (u32)dst; + + if (len >= 32) + { + if (((int)dst ^ (int)src) & 3) + { + if (!reverse) + { + __copy_longs_unaligned(dst, src, len); + } + else + { + __copy_longs_rev_unaligned(dst, src, len); + } + } + else + { + if (!reverse) + { + __copy_longs_aligned(dst, src, len); + } + else + { + __copy_longs_rev_aligned(dst, src, len); + } + } + + return dst; + } + else + { + if (!reverse) + { + for (csrc = (const char *)src - 1, cdst = (char *)dst - 1, len++; --len;) + { + *++cdst = *++csrc; + } + } + else + { + for (csrc = (const char *)src + len, cdst = (char *)dst + len, len++; --len;) + { + *--cdst = *--csrc; + } + } + } + + return dst; +} + +void *memchr(const void *src, int val, size_t n) +{ + const u8 *p; + u32 v = val & 0xFF; + + for (p = (u8 *)src - 1, n++; --n;) + { + if ((*++p & 0xFF) == v) + { + return (void *)p; + } + } + + return NULL; +} + +void *__memrchr(const void *src, int val, size_t n) +{ + const u8 *p; + u32 v = val & 0xFF; + + for (p = (u8 *)src + n, n++; --n;) + { + if (*--p == v) + { + return (void *)p; + } + } + + return NULL; +} + +int memcmp(const void *src1, const void *src2, size_t n) +{ + const u8 *p1; + const u8 *p2; + + for (p1 = (const u8 *)src1 - 1, p2 = (const u8 *)src2 - 1, n++; --n;) + { + if (*++p1 != *++p2) + { + return (*p1 < *p2) ? -1 : 1; + } + } + + return 0; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem_funcs.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem_funcs.c new file mode 100644 index 000000000..bfa043e1e --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem_funcs.c @@ -0,0 +1,217 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/mem_funcs.h" + +#define srcCharPtr ((unsigned char*)pSrc) +#define destCharPtr ((unsigned char*)pDest) +#define srcLongPtr ((unsigned long*)pSrc) +#define destLongPtr ((unsigned long*)pDest) + +void __copy_mem(void) +{ + // UNUSED FUNCTION +} + +void __move_mem(void) +{ + // UNUSED FUNCTION +} + +void __copy_longs_aligned(void* pDest, const void* pSrc, unsigned long len) +{ + unsigned long i = (-(unsigned long)pDest) & 3; + srcCharPtr = ((unsigned char*)pSrc) - 1; + destCharPtr = ((unsigned char*)pDest) - 1; + + if (i != 0) { + len -= i; + + do { + *++(destCharPtr) = *++(srcCharPtr); + } while (--i); + } + + srcLongPtr = ((unsigned long*)(srcCharPtr + 1)) - 1; + destLongPtr = ((unsigned long*)(destCharPtr + 1)) - 1; + + i = len >> 5; + + if (i != 0) { + do { + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + } while (--i); + } + + i = (len & 31) >> 2; + + if (i != 0) { + do { + *++(destLongPtr) = *++(srcLongPtr); + } while (--i); + } + + srcCharPtr = ((unsigned char*)(srcLongPtr + 1)) - 1; + destCharPtr = ((unsigned char*)(destLongPtr + 1)) - 1; + + len &= 3; + + if (len != 0) { + do + *++(destCharPtr) = *++(srcCharPtr); + while (--len); + } +} + +void __copy_longs_rev_aligned(void* pDest, const void* pSrc, unsigned long len) +{ + unsigned long i; + srcCharPtr = ((unsigned char*)pSrc) + len; + destCharPtr = ((unsigned char*)pDest) + len; + i = ((unsigned long)destCharPtr) & 3; + + if (i != 0) { + len -= i; + + do { + *--destCharPtr = *--srcCharPtr; + } while (--i); + } + + i = len >> 5; + + if (i != 0) { + do { + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + } while (--i); + } + + i = (len & 31) >> 2; + + if (i != 0) { + do { + *--destLongPtr = *--srcLongPtr; + } while (--i); + } + + len &= 3; + + if (len != 0) { + do { + *--destCharPtr = *--srcCharPtr; + } while (--len); + } +} + +void __copy_longs_unaligned(void* pDest, const void* pSrc, unsigned long len) +{ + unsigned long i, v1, v2; + unsigned int src, ls, rs; + + i = (-(unsigned long)pDest) & 3; + srcCharPtr = ((unsigned char*)pSrc) - 1; + destCharPtr = ((unsigned char*)pDest) - 1; + + if (i != 0) { + len -= i; + + do { + *++destCharPtr = *++srcCharPtr; + } while (--i); + } + + src = ((unsigned int)(srcCharPtr + 1)) & 3; + ls = src << 3; + rs = 32 - ls; + + srcCharPtr -= src; + + srcLongPtr = ((unsigned long*)(srcCharPtr + 1)) - 1; + destLongPtr = ((unsigned long*)(destCharPtr + 1)) - 1; + + i = len >> 3; + v1 = *++srcLongPtr; + + do { + v2 = *++srcLongPtr; + *++destLongPtr = (v1 << ls) | (v2 >> rs); + v1 = *++srcLongPtr; + *++destLongPtr = (v2 << ls) | (v1 >> rs); + } while (--i); + + if (len & 4) { + v2 = *++srcLongPtr; + *++destLongPtr = (v1 << ls) | (v2 >> rs); + } + + srcCharPtr = ((unsigned char*)(srcLongPtr + 1)) - 1; + destCharPtr = ((unsigned char*)(destLongPtr + 1)) - 1; + + len &= 3; + + if (len != 0) { + srcCharPtr -= 4 - src; + do { + *++destCharPtr = *++srcCharPtr; + } while (--len); + } +} + +void __copy_longs_rev_unaligned(void* pDest, const void* pSrc, unsigned long len) +{ + unsigned long i, v1, v2; + unsigned int src, ls, rs; + + srcCharPtr = ((unsigned char*)pSrc) + len; + destCharPtr = ((unsigned char*)pDest) + len; + i = ((unsigned long)pDest) & 3; + + if (i != 0) { + len -= i; + + do { + *--destCharPtr = *--srcCharPtr; + } while (--i); + } + + src = ((unsigned int)(srcCharPtr)) & 3; + ls = src << 3; + rs = 32 - ls; + + srcCharPtr += 4 - src; + + i = len >> 3; + v1 = *--srcLongPtr; + + do { + v2 = *--srcLongPtr; + *--destLongPtr = (v2 << ls) | (v1 >> rs); + v1 = *--srcLongPtr; + *--destLongPtr = (v1 << ls) | (v2 >> rs); + } while (--i); + + if (len & 4) { + v2 = *--srcLongPtr; + *--destLongPtr = (v2 << ls) | (v1 >> rs); + } + + len &= 3; + + if (len != 0) { + srcCharPtr += src; + do { + *--destCharPtr = *--srcCharPtr; + } while (--len); + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/misc_io.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/misc_io.c new file mode 100644 index 000000000..dc4b05c1e --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/misc_io.c @@ -0,0 +1,25 @@ +extern void (*__stdio_exit)(void); + +extern void __close_all(void); + +void clearerr(void) +{ + // UNUSED FUNCTION +} + +void feof(void) +{ + // UNUSED FUNCTION +} + +void ferror(void) +{ + // UNUSED FUNCTION +} + +void perror(void) +{ + // UNUSED FUNCTION +} + +void __stdio_atexit(void) { __stdio_exit = __close_all; } diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/printf.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/printf.c new file mode 100644 index 000000000..039757e64 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/printf.c @@ -0,0 +1,1250 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_fp.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/secure_error.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" +#include "ctype.h" +#include "math.h" +#include "mem.h" +#include "stdarg.h" +#include "string.h" +#include "stdio.h" +#include "stdlib.h" + +#define TARGET_FLOAT_BITS 64 +#define TARGET_FLOAT_BYTES (TARGET_FLOAT_BITS / 8) +#define TARGET_FLOAT_MAX_EXP LDBL_MAX_EXP +#define TARGET_FLOAT_MANT_DIG LDBL_MANT_DIG +#define TARGET_FLOAT_IMPLICIT_J_BIT 1 +#define TARGET_FLOAT_MANT_BITS (TARGET_FLOAT_MANT_DIG - TARGET_FLOAT_IMPLICIT_J_BIT) +#define TARGET_FLOAT_EXP_BITS (TARGET_FLOAT_BITS - TARGET_FLOAT_MANT_BITS - 1) + +typedef long long intmax_t; + +#define PTRDIFF __typeof__((char*)0 - (char*)0) +typedef PTRDIFF ptrdiff_t; + +enum justification_options { left_justification, right_justification, zero_fill }; + +enum sign_options { only_minus, sign_always, space_holder }; + +enum argument_options { + normal_argument, + char_argument, + short_argument, + long_argument, + long_long_argument, + long_double_argument, + wchar_argument +}; + +typedef struct { + unsigned char justification_options; // _0 + unsigned char sign_options; // _1 + unsigned char precision_specified; // _2 + unsigned char alternate_form; // _3 + unsigned char argument_options; // _4 + unsigned char conversion_char; // _5 + int field_width; // _8 + int precision; // _C +} print_format; + +static const char* parse_format(const char* format_string, va_list* arg, print_format* format) +{ + print_format f; + const char* s = format_string; + int c; + int flag_found; + f.justification_options = right_justification; + f.sign_options = only_minus; + f.precision_specified = 0; + f.alternate_form = 0; + f.argument_options = normal_argument; + f.field_width = 0; + f.precision = 0; + + if ((c = *++s) == '%') { + f.conversion_char = c; + *format = f; + return ((const char*)s + 1); + } + + for (;;) { + flag_found = 1; + + switch (c) { + case '-': + f.justification_options = left_justification; + break; + case '+': + f.sign_options = sign_always; + break; + case ' ': + if (f.sign_options != sign_always) { + f.sign_options = space_holder; + } + break; + case '#': + f.alternate_form = 1; + break; + case '0': + if (f.justification_options != left_justification) { + f.justification_options = zero_fill; + } + break; + default: + flag_found = 0; + break; + } + + if (flag_found) { + c = *++s; + } else { + break; + } + } + + if (c == '*') { + if ((f.field_width = va_arg(*arg, int)) < 0) { + f.justification_options = left_justification; + f.field_width = -f.field_width; + } + + c = *++s; + } else { + while (isdigit(c)) { + f.field_width = (f.field_width * 10) + (c - '0'); + c = *++s; + } + } + + if (f.field_width > 509) { + f.conversion_char = 0xFF; + *format = f; + return ((const char*)s + 1); + } + + if (c == '.') { + f.precision_specified = 1; + + if ((c = *++s) == '*') { + if ((f.precision = va_arg(*arg, int)) < 0) { + f.precision_specified = 0; + } + + c = *++s; + } else { + while (isdigit(c)) { + f.precision = (f.precision * 10) + (c - '0'); + c = *++s; + } + } + } + + flag_found = 1; + + switch (c) { + case 'h': + f.argument_options = short_argument; + + if (s[1] == 'h') { + f.argument_options = char_argument; + c = *++s; + } + + break; + + case 'l': + f.argument_options = long_argument; + + if (s[1] == 'l') { + f.argument_options = long_long_argument; + c = *++s; + } + + break; + + case 'L': + f.argument_options = long_double_argument; + break; + default: + flag_found = 0; + break; + } + + if (flag_found) { + c = *++s; + } + + f.conversion_char = c; + + switch (c) { + case 'd': + case 'i': + case 'u': + case 'o': + case 'x': + case 'X': + if (f.argument_options == long_double_argument) { + f.conversion_char = 0xFF; + break; + } + + if (!f.precision_specified) { + f.precision = 1; + } else if (f.justification_options == zero_fill) { + f.justification_options = right_justification; + } + break; + + case 'f': + case 'F': + if (f.argument_options == short_argument || f.argument_options == long_long_argument) { + f.conversion_char = 0xFF; + break; + } + + if (!f.precision_specified) { + f.precision = 6; + } + break; + + case 'a': + case 'A': + if (!f.precision_specified) { + f.precision = 0xD; + } + + if (f.argument_options == short_argument || f.argument_options == long_long_argument || f.argument_options == char_argument) { + f.conversion_char = 0xFF; + } + + break; + + case 'g': + case 'G': + if (!f.precision) { + f.precision = 1; + } + + case 'e': + case 'E': + if (f.argument_options == short_argument || f.argument_options == long_long_argument || f.argument_options == char_argument) { + f.conversion_char = 0xFF; + break; + } + + if (!f.precision_specified) { + f.precision = 6; + } + break; + + case 'p': + f.conversion_char = 'x'; + f.alternate_form = 1; + f.argument_options = long_argument; + f.precision = 8; + break; + + case 'c': + if (f.argument_options == long_argument) { + f.argument_options = wchar_argument; + } else { + if (f.precision_specified || f.argument_options != normal_argument) { + f.conversion_char = 0xFF; + } + } + + break; + + case 's': + if (f.argument_options == long_argument) { + f.argument_options = wchar_argument; + } else { + if (f.argument_options != normal_argument) { + f.conversion_char = 0xFF; + } + } + + break; + + case 'n': + if (f.argument_options == long_double_argument) { + f.conversion_char = 0xFF; + } + + break; + + default: + f.conversion_char = 0xFF; + break; + } + + *format = f; + return ((const char*)s + 1); +} + +static char* long2str(long num, char* buff, print_format format) +{ + unsigned long unsigned_num, base; + char* p; + int n, digits; + int minus = 0; + unsigned_num = num; + minus = 0; + + p = buff; + *--p = 0; + digits = 0; + + if (!num && !format.precision && !(format.alternate_form && format.conversion_char == 'o')) { + return p; + } + + switch (format.conversion_char) { + case 'd': + case 'i': + base = 10; + + if (num < 0) { + unsigned_num = -unsigned_num; + minus = 1; + } + break; + + case 'o': + base = 8; + format.sign_options = only_minus; + break; + + case 'u': + base = 10; + format.sign_options = only_minus; + break; + + case 'x': + case 'X': + base = 16; + format.sign_options = only_minus; + break; + } + + do { + n = unsigned_num % base; + unsigned_num /= base; + + if (n < 10) { + n += '0'; + } else { + n -= 10; + + if (format.conversion_char == 'x') { + n += 'a'; + } else { + n += 'A'; + } + } + + *--p = n; + ++digits; + } while (unsigned_num != 0); + + if (base == 8 && format.alternate_form && *p != '0') { + *--p = '0'; + ++digits; + } + + if (format.justification_options == zero_fill) { + format.precision = format.field_width; + + if (minus || format.sign_options != only_minus) + --format.precision; + + if (base == 16 && format.alternate_form) + format.precision -= 2; + } + + if (buff - p + format.precision > 509) + return (0); + + while (digits < format.precision) { + *--p = '0'; + ++digits; + } + + if (base == 16 && format.alternate_form) { + *--p = format.conversion_char; + *--p = '0'; + } + + if (minus) { + *--p = '-'; + } else if (format.sign_options == sign_always) { + *--p = '+'; + } else if (format.sign_options == space_holder) { + *--p = ' '; + } + + return p; +} + +static char* longlong2str(long long num, char* pBuf, print_format fmt) +{ + unsigned long long unsigned_num, base; + char* p; + int n, digits; + int minus = 0; + unsigned_num = num; + minus = 0; + p = pBuf; + *--p = 0; + digits = 0; + + if (!num && !fmt.precision && !(fmt.alternate_form && fmt.conversion_char == 'o')) { + return p; + } + + switch (fmt.conversion_char) { + case 'd': + case 'i': + base = 10; + + if (num < 0) { + unsigned_num = -unsigned_num; + minus = 1; + } + break; + case 'o': + base = 8; + fmt.sign_options = only_minus; + break; + case 'u': + base = 10; + fmt.sign_options = only_minus; + break; + case 'x': + case 'X': + base = 16; + fmt.sign_options = only_minus; + break; + } + + do { + n = unsigned_num % base; + unsigned_num /= base; + + if (n < 10) { + n += '0'; + } else { + n -= 10; + if (fmt.conversion_char == 'x') { + n += 'a'; + } else { + n += 'A'; + } + } + + *--p = n; + ++digits; + } while (unsigned_num != 0); + + if (base == 8 && fmt.alternate_form && *p != '0') { + *--p = '0'; + ++digits; + } + + if (fmt.justification_options == zero_fill) { + fmt.precision = fmt.field_width; + + if (minus || fmt.sign_options != only_minus) { + --fmt.precision; + } + + if (base == 16 && fmt.alternate_form) { + fmt.precision -= 2; + } + } + + if (pBuf - p + fmt.precision > 509) { + return 0; + } + + while (digits < fmt.precision) { + *--p = '0'; + ++digits; + } + + if (base == 16 && fmt.alternate_form) { + *--p = fmt.conversion_char; + *--p = '0'; + } + + if (minus) { + *--p = '-'; + } else if (fmt.sign_options == sign_always) { + *--p = '+'; + } else if (fmt.sign_options == space_holder) { + *--p = ' '; + } + + return p; +} + +static char* double2hex(long double num, char* buff, print_format format) +{ + char *p, *q; + char working_byte; + long double ld; + short* sptr; + short snum; + long exp; + print_format exp_format; + int hex_precision; + decform form; + decimal dec; + + p = buff; + ld = num; + sptr = (short*)&ld; + + if (format.precision > 509) { + return 0; + } + + form.style = (char)0; + form.digits = 0x20; + __num2dec(&form, num, &dec); + + if (*dec.sig.text == 'I') { + if (*sptr & 0x8000) { + p = buff - 5; + if (format.conversion_char == 'A') + strcpy(p, "-INF"); + else + strcpy(p, "-inf"); + } else { + p = buff - 4; + if (format.conversion_char == 'A') + strcpy(p, "INF"); + else + strcpy(p, "inf"); + } + + return p; + } else if (*dec.sig.text == 'N') { + if (*(char*)&num & 0x80) { + p = buff - 5; + if (format.conversion_char == 'A') + strcpy(p, "-NAN"); + else + strcpy(p, "-nan"); + } else { + p = buff - 4; + if (format.conversion_char == 'A') + strcpy(p, "NAN"); + else + strcpy(p, "nan"); + } + + return p; + } + + exp_format.justification_options = right_justification; + exp_format.sign_options = sign_always; + exp_format.precision_specified = 0; + exp_format.alternate_form = 0; + exp_format.argument_options = normal_argument; + exp_format.field_width = 0; + exp_format.precision = 1; + exp_format.conversion_char = 'd'; + + snum = (*sptr & 0x7ff0) >> 4; + + exp = snum - 0x3FF; + + p = long2str(exp, buff, exp_format); + if (format.conversion_char == 'a') + *--p = 'p'; + else + *--p = 'P'; + + q = (char*)# + + for (hex_precision = format.precision; hex_precision >= 1; --hex_precision) { + working_byte = *(q + (hex_precision / 2) + 1); + if (hex_precision % 2) + working_byte = working_byte & 0x0f; + else + working_byte = (working_byte >> 4) & 0x0f; + + if (working_byte < 10) { + working_byte += '0'; + } else { + working_byte -= 10; + + if (format.conversion_char == 'a') { + working_byte += 'a'; + } else { + working_byte += 'A'; + } + } + + *--p = working_byte; + } + + if (format.precision || format.alternate_form) { + *--p = '.'; + } + + *--p = '1'; + + if (format.conversion_char == 'a') { + *--p = 'x'; + } else { + *--p = 'X'; + } + + *--p = '0'; + + if (*sptr & 0x8000) { + *--p = '-'; + } else if (format.sign_options == sign_always) { + *--p = '+'; + } else if (format.sign_options == space_holder) { + *--p = ' '; + } + + return p; +} + +static void round_decimal(decimal* dec, int new_length) +{ + char c; + char* p; + int carry; + + if (new_length < 0) { + return_zero: + dec->exp = 0; + dec->sig.length = 1; + *dec->sig.text = '0'; + return; + } + + if (new_length >= dec->sig.length) { + return; + } + + p = (char*)dec->sig.text + new_length + 1; + c = *--p - '0'; + + if (c == 5) { + char* q = &((char*)dec->sig.text)[dec->sig.length]; + + while (--q > p && *q == '0') + ; + carry = (q == p) ? p[-1] & 1 : 1; + } else { + carry = (c > 5); + } + + while (new_length != 0) { + c = *--p - '0' + carry; + + if ((carry = (c > 9)) != 0 || c == 0) { + --new_length; + } else { + *p = c + '0'; + break; + } + } + + if (carry != 0) { + dec->exp += 1; + dec->sig.length = 1; + *dec->sig.text = '1'; + return; + } else if (new_length == 0) { + goto return_zero; + } + + dec->sig.length = new_length; +} + +static char* float2str(long double num, char* buff, print_format format) +{ + decimal dec; + decform form; + char* p; + char* q; + int n, digits, sign; + int int_digits, frac_digits; + + if (format.precision > 509) { + return 0; + } + + form.style = 0; + form.digits = 0x20; + __num2dec(&form, num, &dec); + p = (char*)dec.sig.text + dec.sig.length; + + while (dec.sig.length > 1 && *--p == '0') { + --dec.sig.length; + ++dec.exp; + } + + switch (*dec.sig.text) { + case '0': + dec.exp = 0; + break; + case 'I': + if (num < 0) { + p = buff - 5; + + if (isupper(format.conversion_char)) { + strcpy(p, "-INF"); + } else { + strcpy(p, "-inf"); + } + } else { + p = buff - 4; + if (isupper(format.conversion_char)) { + strcpy(p, "INF"); + } else { + strcpy(p, "inf"); + } + } + + return p; + + case 'N': + if (dec.sign) { + p = buff - 5; + + if (isupper(format.conversion_char)) { + strcpy(p, "-NAN"); + } else { + strcpy(p, "-nan"); + } + } else { + p = buff - 4; + if (isupper(format.conversion_char)) { + strcpy(p, "NAN"); + } else { + strcpy(p, "nan"); + } + } + + return p; + } + + dec.exp += dec.sig.length - 1; + p = buff; + *--p = 0; + + switch (format.conversion_char) { + case 'g': + case 'G': + + if (dec.sig.length > format.precision) { + round_decimal(&dec, format.precision); + } + + if (dec.exp < -4 || dec.exp >= format.precision) { + if (format.alternate_form) { + --format.precision; + } else { + format.precision = dec.sig.length - 1; + } + + if (format.conversion_char == 'g') { + format.conversion_char = 'e'; + } else { + format.conversion_char = 'E'; + } + + goto e_format; + } + + if (format.alternate_form) { + format.precision -= dec.exp + 1; + } else { + if ((format.precision = dec.sig.length - (dec.exp + 1)) < 0) { + format.precision = 0; + } + } + + goto f_format; + + case 'e': + case 'E': + e_format: + + if (dec.sig.length > format.precision + 1) { + round_decimal(&dec, format.precision + 1); + } + + n = dec.exp; + sign = '+'; + + if (n < 0) { + n = -n; + sign = '-'; + } + + for (digits = 0; n || digits < 2; ++digits) { + *--p = n % 10 + '0'; + n /= 10; + } + + *--p = sign; + *--p = format.conversion_char; + + if (buff - p + format.precision > 509) { + return 0; + } + + if (dec.sig.length < format.precision + 1) { + for (n = format.precision + 1 - dec.sig.length + 1; --n;) { + *--p = '0'; + } + } + + for (n = dec.sig.length, q = (char*)dec.sig.text + dec.sig.length; --n;) { + *--p = *--q; + } + + if (format.precision || format.alternate_form) { + *--p = '.'; + } + + *--p = *dec.sig.text; + + if (dec.sign) + *--p = '-'; + else if (format.sign_options == sign_always) + *--p = '+'; + else if (format.sign_options == space_holder) + *--p = ' '; + + break; + + case 'f': + case 'F': + f_format: + + if ((frac_digits = -dec.exp + dec.sig.length - 1) < 0) + frac_digits = 0; + + if (frac_digits > format.precision) { + round_decimal(&dec, dec.sig.length - (frac_digits - format.precision)); + + if ((frac_digits = -dec.exp + dec.sig.length - 1) < 0) + frac_digits = 0; + } + + if ((int_digits = dec.exp + 1) < 0) + int_digits = 0; + + if (int_digits + frac_digits > 509) + return 0; + + q = (char*)dec.sig.text + dec.sig.length; + + for (digits = 0; digits < (format.precision - frac_digits); ++digits) + *--p = '0'; + + for (digits = 0; digits < frac_digits && digits < dec.sig.length; ++digits) + *--p = *--q; + + for (; digits < frac_digits; ++digits) + *--p = '0'; + + if (format.precision || format.alternate_form) + *--p = '.'; + + if (int_digits) { + for (digits = 0; digits < int_digits - dec.sig.length; ++digits) { + *--p = '0'; + } + + for (; digits < int_digits; ++digits) { + *--p = *--q; + } + } else { + *--p = '0'; + } + + if (dec.sign) { + *--p = '-'; + } else if (format.sign_options == sign_always) { + *--p = '+'; + } else if (format.sign_options == space_holder) { + *--p = ' '; + } + + break; + } + + return p; +} + +static int __pformatter(void* (*WriteProc)(void*, const char*, size_t), void* WriteProcArg, const char* format_str, va_list arg) +{ + int num_chars, chars_written, field_width; + const char* format_ptr; + const char* curr_format; + print_format format; + long long_num; + long long long_long_num; + long double long_double_num; + char buff[512]; + char* buff_ptr; + char* string_end; + char fill_char = ' '; + + format_ptr = format_str; + chars_written = 0; + + while (*format_ptr) { + if (!(curr_format = strchr(format_ptr, '%'))) { + num_chars = strlen(format_ptr); + chars_written += num_chars; + + if (num_chars && !(*WriteProc)(WriteProcArg, format_ptr, num_chars)) { + return -1; + } + + break; + } + + num_chars = curr_format - format_ptr; + chars_written += num_chars; + + if (num_chars && !(*WriteProc)(WriteProcArg, format_ptr, num_chars)) { + return -1; + } + + format_ptr = curr_format; + format_ptr = parse_format(format_ptr, (va_list*)arg, &format); + + switch (format.conversion_char) { + case 'd': + case 'i': + if (format.argument_options == long_argument) { + long_num = va_arg(arg, long); + } else if (format.argument_options == long_long_argument) { + long_long_num = va_arg(arg, long long); + } else { + long_num = va_arg(arg, int); + } + + if (format.argument_options == short_argument) { + long_num = (short)long_num; + } + + if (format.argument_options == char_argument) { + long_num = (signed char)long_num; + } + + if ((format.argument_options == long_long_argument)) { + if (!(buff_ptr = longlong2str(long_long_num, buff + 512, format))) { + goto conversion_error; + } + } else { + if (!(buff_ptr = long2str(long_num, buff + 512, format))) { + goto conversion_error; + } + } + + num_chars = buff + 512 - 1 - buff_ptr; + break; + + case 'o': + case 'u': + case 'x': + case 'X': + if (format.argument_options == long_argument) { + long_num = va_arg(arg, unsigned long); + } else if (format.argument_options == long_long_argument) { + long_long_num = va_arg(arg, long long); + } else { + long_num = va_arg(arg, unsigned int); + } + + if (format.argument_options == short_argument) { + long_num = (unsigned short)long_num; + } + + if (format.argument_options == char_argument) { + long_num = (unsigned char)long_num; + } + + if ((format.argument_options == long_long_argument)) { + if (!(buff_ptr = longlong2str(long_long_num, buff + 512, format))) { + goto conversion_error; + } + } else { + if (!(buff_ptr = long2str(long_num, buff + 512, format))) { + goto conversion_error; + } + } + + num_chars = buff + 512 - 1 - buff_ptr; + break; + + case 'f': + case 'F': + case 'e': + case 'E': + case 'g': + case 'G': + if (format.argument_options == long_double_argument) { + long_double_num = va_arg(arg, long double); + } else { + long_double_num = va_arg(arg, double); + } + + if (!(buff_ptr = float2str(long_double_num, buff + 512, format))) { + goto conversion_error; + } + + num_chars = buff + 512 - 1 - buff_ptr; + break; + + case 'a': + case 'A': + if (format.argument_options == long_double_argument) { + long_double_num = va_arg(arg, long double); + } else { + long_double_num = va_arg(arg, double); + } + + if (!(buff_ptr = double2hex(long_double_num, buff + 512, format))) { + goto conversion_error; + } + + num_chars = buff + 512 - 1 - buff_ptr; + break; + + case 's': + if (format.argument_options == wchar_argument) { + wchar_t* wcs_ptr = va_arg(arg, wchar_t*); + + if (wcs_ptr == NULL) { + wcs_ptr = L""; + } + + if ((num_chars = wcstombs(buff, wcs_ptr, sizeof(buff))) < 0) { + goto conversion_error; + } + + buff_ptr = &buff[0]; + } else { + buff_ptr = va_arg(arg, char*); + } + + if (buff_ptr == NULL) { + buff_ptr = ""; + } + + if (format.alternate_form) { + num_chars = (unsigned char)*buff_ptr++; + + if (format.precision_specified && num_chars > format.precision) { + num_chars = format.precision; + } + } else if (format.precision_specified) { + num_chars = format.precision; + + if ((string_end = (char*)memchr((unsigned char*)buff_ptr, 0, num_chars)) != 0) { + num_chars = string_end - buff_ptr; + } + } else { + num_chars = strlen(buff_ptr); + } + + break; + + case 'n': + buff_ptr = va_arg(arg, char*); + + switch (format.argument_options) { + case normal_argument: + *(int*)buff_ptr = chars_written; + break; + case short_argument: + *(short*)buff_ptr = chars_written; + break; + case long_argument: + *(long*)buff_ptr = chars_written; + break; + case long_long_argument: + *(long long*)buff_ptr = chars_written; + break; + } + + continue; + + case 'c': + buff_ptr = buff; + *buff_ptr = va_arg(arg, int); + num_chars = 1; + break; + + case '%': + buff_ptr = buff; + *buff_ptr = '%'; + num_chars = 1; + break; + + case 0xFF: + default: + conversion_error: + num_chars = strlen(curr_format); + chars_written += num_chars; + + if (num_chars && !(*WriteProc)(WriteProcArg, curr_format, num_chars)) { + return -1; + } + + return chars_written; + break; + } + + field_width = num_chars; + + if (format.justification_options != left_justification) { + fill_char = (format.justification_options == zero_fill) ? '0' : ' '; + + if (((*buff_ptr == '+') || (*buff_ptr == '-') || (*buff_ptr == ' ')) && (fill_char == '0')) { + if ((*WriteProc)(WriteProcArg, buff_ptr, 1) == 0) { + return -1; + } + + ++buff_ptr; + num_chars--; + } + + while (field_width < format.field_width) { + if ((*WriteProc)(WriteProcArg, &fill_char, 1) == 0) { + return -1; + } + + ++field_width; + } + } + + if (num_chars && !(*WriteProc)(WriteProcArg, buff_ptr, num_chars)) { + return -1; + } + + if (format.justification_options == left_justification) { + while (field_width < format.field_width) { + char blank = ' '; + + if ((*WriteProc)(WriteProcArg, &blank, 1) == 0) { + return -1; + } + + ++field_width; + } + } + + chars_written += field_width; + } + + return chars_written; +} + +static void* __FileWrite(void* pFile, const char* pBuffer, size_t char_num) +{ + return (fwrite(pBuffer, 1, char_num, (FILE*)pFile) == char_num ? pFile : 0); +} + +static void* __StringWrite(void* pCtrl, const char* pBuffer, size_t char_num) +{ + size_t chars; + __OutStrCtrl* ctrl = (__OutStrCtrl*)pCtrl; + void* res; + + chars = ((ctrl->CharsWritten + char_num) <= ctrl->MaxCharCount) ? char_num : ctrl->MaxCharCount - ctrl->CharsWritten; + res = memcpy(ctrl->CharStr + ctrl->CharsWritten, pBuffer, chars); + ctrl->CharsWritten += chars; + return (void*)1; +} + +void printf(const char* format, ...) +{ + // UNUSED FUNCTION +} + +int fprintf(FILE* file, const char* format, ...) +{ + int ret; + va_list args; + + if (fwide(file, -1) >= 0) { + return -1; + } + + __begin_critical_region(stdin_access); + + va_start(args, format); + ret = __pformatter(&__FileWrite, file, format, args); + va_end(args); + __end_critical_region(stdin_access); + return ret; +} + +int vprintf(const char* pFormat, va_list arg) +{ + int ret; + + if (fwide(stdout, -1) >= 0) { + return -1; + } + + __begin_critical_region(stdin_access); + ret = __pformatter(&__FileWrite, (void*)stdout, pFormat, arg); + __end_critical_region(stdin_access); + return ret; +} + +void vfprintf(void) +{ + // UNUSED FUNCTION +} + +int vsnprintf(char* s, size_t n, const char* format, va_list arg) +{ + int end; + __OutStrCtrl osc; + osc.CharStr = s; + osc.MaxCharCount = n; + osc.CharsWritten = 0; + + end = __pformatter(&__StringWrite, &osc, format, arg); + + if (s) { + s[(end < n) ? end : n - 1] = '\0'; + } + + return end; +} + +int vsprintf(char* s, const char* format, va_list arg) { return vsnprintf(s, 0xFFFFFFFF, format, arg); } + +int snprintf(char* s, size_t n, const char* format, ...) +{ + va_list args; + va_start(args, format); + return vsnprintf(s, n, format, args); +} + +int sprintf(char* s, const char* format, ...) +{ + va_list args; + va_start(args, format); + return vsnprintf(s, 0xFFFFFFFF, format, args); +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/rand.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/rand.c new file mode 100644 index 000000000..f6ed2b702 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/rand.c @@ -0,0 +1,14 @@ +#include "types.h" + +static u32 next = 1; + +int rand() +{ + next = next * 1103515245 + 12345; + return ((next >> 16) & 0x7fff); +} + +void srand(u32 seed) +{ + next = seed; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/scanf.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/scanf.c new file mode 100644 index 000000000..1393de9ed --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/scanf.c @@ -0,0 +1,670 @@ +#include "math.h" +#include "stdarg.h" +#include "ctype.h" +#include "stdio.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h" + +typedef long long intmax_t; + +#define PTRDIFF __typeof__((char*)0 - (char*)0) +typedef PTRDIFF ptrdiff_t; + +enum argument_options { + normal_argument, + char_argument, + short_argument, + long_argument, + long_long_argument, + double_argument, + long_double_argument, + wchar_argument +}; + +typedef unsigned char char_map[32]; + +typedef struct { + unsigned char suppress_assignment; + unsigned char field_width_specified; + unsigned char argument_options; + unsigned char conversion_char; + int field_width; + char_map char_set; +} scan_format; + +#define set_char_map(map, ch) map[(unsigned char)ch >> 3] |= (1 << (ch & 7)) +#define tst_char_map(map, ch) (map[(unsigned char)ch >> 3] & (1 << (ch & 7))) + +static const char* parse_format(const char* format_string, scan_format* format) +{ + const char* s = format_string; + int c; + int flag_found, invert; + scan_format f = { 0, 0, normal_argument, 0, 2147483647, { 0 } }; + + if (((c = *++s) == '%')) { + f.conversion_char = c; + *format = f; + return ((const char*)s + 1); + } + + if (c == '*') { + f.suppress_assignment = 1; + c = *++s; + } + + if (isdigit(c)) { + f.field_width = 0; + + do { + f.field_width = (f.field_width * 10) + (c - '0'); + c = *++s; + } while (isdigit(c)); + + if (f.field_width == 0) { + f.conversion_char = 0xFF; + *format = f; + return ((const char*)s + 1); + } + + f.field_width_specified = 1; + } + + flag_found = 1; + + switch (c) { + case 'h': + f.argument_options = short_argument; + + if (s[1] == 'h') { + f.argument_options = char_argument; + c = *++s; + } + + break; + case 'l': + f.argument_options = long_argument; + + if (s[1] == 'l') { + f.argument_options = long_long_argument; + c = *++s; + } + break; + case 'L': + f.argument_options = long_double_argument; + break; + default: + flag_found = 0; + } + + if (flag_found) { + c = *++s; + } + + f.conversion_char = c; + + switch (c) { + case 'd': + case 'i': + case 'u': + case 'o': + case 'x': + case 'X': + if (f.argument_options == long_double_argument) { + f.conversion_char = 0xFF; + break; + } + + break; + + case 'a': + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + if (f.argument_options == char_argument || f.argument_options == short_argument || f.argument_options == long_long_argument) { + f.conversion_char = 0xFF; + break; + } + + if (f.argument_options == long_argument) { + f.argument_options = double_argument; + } + + break; + + case 'p': + f.argument_options = long_argument; + f.conversion_char = 'x'; + break; + + case 'c': + if (f.argument_options == long_argument) { + f.argument_options = wchar_argument; + } else { + if (f.argument_options != normal_argument) { + f.conversion_char = 0xFF; + } + } + + break; + + case 's': + if (f.argument_options == long_argument) { + f.argument_options = wchar_argument; + } else { + if (f.argument_options != normal_argument) { + f.conversion_char = 0xFF; + } + } + + { + int i; + unsigned char* p; + + for (i = sizeof(f.char_set), p = f.char_set; i; --i) { + *p++ = 0xFF; + } + + f.char_set[1] = 0xC1; + f.char_set[4] = 0xFE; + } + + break; + + case 'n': + break; + + case '[': + if (f.argument_options == long_argument) { + f.argument_options = wchar_argument; + } else { + if (f.argument_options != normal_argument) { + f.conversion_char = 0xFF; + } + } + + c = *++s; + invert = 0; + + if (c == '^') { + invert = 1; + c = *++s; + } + + if (c == ']') { + set_char_map(f.char_set, ']'); + c = *++s; + } + + while (c && c != ']') { + int d; + set_char_map(f.char_set, c); + + if (*(s + 1) == '-' && (d = *(s + 2)) != 0 && d != ']') { + while (++c <= d) { + set_char_map(f.char_set, c); + } + + c = *(s += 3); + } else { + c = *++s; + } + } + + if (!c) { + f.conversion_char = 0xFF; + break; + } + + if (invert) { + int i; + unsigned char* p; + + for (i = sizeof(f.char_set), p = f.char_set; i; --i, ++p) { + *p = ~*p; + } + + break; + } + + break; + default: + f.conversion_char = 0xFF; + break; + } + + *format = f; + return ((const char*)s + 1); +} + +static int __sformatter(int (*ReadProc)(void*, int, int), void* ReadProcArg, const char* format_str, va_list arg) +{ + int num_chars, chars_read, items_assigned, conversions; + int base, negative, overflow; + const char* format_ptr; + char format_char; + char c; + scan_format format; + long long_num; + unsigned long u_long_num; + long long long_long_num; + unsigned long long u_long_long_num; + long double long_double_num; + char* arg_ptr; + int terminate = 0; + + format_ptr = format_str; + chars_read = 0; + items_assigned = 0; + conversions = 0; + + while (!terminate && (format_char = *format_ptr) != 0) { + if (isspace(format_char)) { + do { + format_char = *++format_ptr; + } while (isspace(format_char)); + + while (isspace(c = (*ReadProc)(ReadProcArg, 0, __GetAChar))) + ++chars_read; + + (*ReadProc)(ReadProcArg, c, __UngetAChar); + + continue; + } + + if (format_char != '%') { + if ((c = (*ReadProc)(ReadProcArg, 0, __GetAChar)) != (unsigned char)format_char) { + (*ReadProc)(ReadProcArg, c, __UngetAChar); + goto exit; + } + + chars_read++; + format_ptr++; + + continue; + } + + format_ptr = parse_format(format_ptr, &format); + + if (!format.suppress_assignment && format.conversion_char != '%') { + arg_ptr = va_arg(arg, char*); + } else { + arg_ptr = 0; + } + + if ((format.conversion_char != 'n') && (*ReadProc)(ReadProcArg, 0, __TestForError)) { + terminate = 1; + goto exit; + } + + switch (format.conversion_char) { + case 'd': + base = 10; + goto signed_int; + case 'i': + base = 0; + signed_int: + if ((format.argument_options == long_long_argument)) + u_long_long_num = __strtoull(base, format.field_width, ReadProc, ReadProcArg, &num_chars, &negative, &overflow); + else + u_long_num = __strtoul(base, format.field_width, ReadProc, ReadProcArg, &num_chars, &negative, &overflow); + + if (!num_chars) { + goto exit; + } + + chars_read += num_chars; + + if ((format.argument_options == long_long_argument)) + long_long_num = (negative ? -u_long_long_num : u_long_long_num); + else + long_num = (negative ? -u_long_num : u_long_num); + + signed_int_assign: + + if (arg_ptr) { + switch (format.argument_options) { + case normal_argument: + *(int*)arg_ptr = long_num; + break; + case char_argument: + *(signed char*)arg_ptr = long_num; + break; + case short_argument: + *(short*)arg_ptr = long_num; + break; + case long_argument: + *(long*)arg_ptr = long_num; + break; + case long_long_argument: + *(long long*)arg_ptr = long_long_num; + break; + } + + items_assigned++; + } + + conversions++; + break; + case 'o': + base = 8; + goto unsigned_int; + case 'u': + base = 10; + goto unsigned_int; + case 'x': + case 'X': + base = 16; + unsigned_int: + if ((format.argument_options == long_long_argument)) + u_long_long_num = __strtoull(base, format.field_width, ReadProc, ReadProcArg, &num_chars, &negative, &overflow); + else + u_long_num = __strtoul(base, format.field_width, ReadProc, ReadProcArg, &num_chars, &negative, &overflow); + + if (!num_chars) { + goto exit; + } + + chars_read += num_chars; + + if (negative) { + if (format.argument_options == long_long_argument) + u_long_long_num = -u_long_long_num; + else + u_long_num = -u_long_num; + } + + unsigned_int_assign: + + if (arg_ptr) { + switch (format.argument_options) { + case normal_argument: + *(unsigned int*)arg_ptr = u_long_num; + break; + case char_argument: + *(unsigned char*)arg_ptr = u_long_num; + break; + case short_argument: + *(unsigned short*)arg_ptr = u_long_num; + break; + case long_argument: + *(unsigned long*)arg_ptr = u_long_num; + break; + case long_long_argument: + *(unsigned long long*)arg_ptr = u_long_long_num; + break; + } + + items_assigned++; + } + + conversions++; + break; + case 'a': + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + flt: + long_double_num = __strtold(format.field_width, ReadProc, ReadProcArg, &num_chars, &overflow); + + if (!num_chars) { + goto exit; + } + + chars_read += num_chars; + + assign_float: + + if (arg_ptr) { + switch (format.argument_options) { + case normal_argument: + *(float*)arg_ptr = long_double_num; + break; + case double_argument: + *(double*)arg_ptr = long_double_num; + break; + case long_double_argument: + *(long double*)arg_ptr = long_double_num; + break; + } + + items_assigned++; + } + + conversions++; + break; + + case 'c': + + if (!format.field_width_specified) + format.field_width = 1; + + if (arg_ptr) { + int rval; + num_chars = 0; + + while (format.field_width-- && ((rval = ((*ReadProc)(ReadProcArg, 0, __GetAChar))) != -1)) { + c = rval; + + if (format.argument_options == wchar_argument) { + mbtowc(((wchar_t*)arg_ptr), (char*)(&c), 1); + (wchar_t*)arg_ptr++; + } else { + *arg_ptr++ = c; + } + num_chars++; + } + + if (!num_chars) { + goto exit; + } + + chars_read += num_chars; + + items_assigned++; + } else { + num_chars = 0; + + while (format.field_width-- && ((c = ((*ReadProc)(ReadProcArg, 0, __GetAChar))) != -1)) { + num_chars++; + } + if (!num_chars) + goto exit; + } + + conversions++; + break; + case '%': + while (isspace(c = (*ReadProc)(ReadProcArg, 0, __GetAChar))) + chars_read++; + + if (c != '%') { + (*ReadProc)(ReadProcArg, c, __UngetAChar); + goto exit; + } + + chars_read++; + break; + case 's': + c = (*ReadProc)(ReadProcArg, 0, __GetAChar); + while (isspace(c)) { + chars_read++; + c = (*ReadProc)(ReadProcArg, 0, __GetAChar); + } + + (*ReadProc)(ReadProcArg, c, __UngetAChar); + case '[': + if (arg_ptr) { + num_chars = 0; + + while (format.field_width-- && ((c = ((*ReadProc)(ReadProcArg, 0, __GetAChar))) != -1) + && tst_char_map(format.char_set, c)) { + if (format.argument_options == wchar_argument) { + mbtowc(((wchar_t*)arg_ptr), (char*)&c, 1); + arg_ptr = (char*)((wchar_t*)arg_ptr + 1); + } else { + *arg_ptr++ = c; + } + num_chars++; + } + + if (!num_chars) { + (*ReadProc)(ReadProcArg, c, __UngetAChar); + goto exit; + } + + chars_read += num_chars; + + if (format.argument_options == wchar_argument) + *(wchar_t*)arg_ptr = L'\0'; + else + *arg_ptr = 0; + + items_assigned++; + } else { + num_chars = 0; + + while (format.field_width-- && ((c = ((*ReadProc)(ReadProcArg, 0, __GetAChar))) != -1) + && tst_char_map(format.char_set, c)) { + + num_chars++; + } + + if (!num_chars) { + (*ReadProc)(ReadProcArg, c, __UngetAChar); + break; + } + chars_read += num_chars; + } + + if (format.field_width >= 0) + (*ReadProc)(ReadProcArg, c, __UngetAChar); + + conversions++; + break; + case 'n': + if (arg_ptr) + switch (format.argument_options) { + case normal_argument: + *(int*)arg_ptr = chars_read; + break; + case short_argument: + *(short*)arg_ptr = chars_read; + break; + case long_argument: + *(long*)arg_ptr = chars_read; + break; + case char_argument: + *(char*)arg_ptr = chars_read; + break; + case long_long_argument: + *(long long*)arg_ptr = chars_read; + break; + } + continue; + case 0xFF: + default: + goto exit; + } + } + +exit: + + if ((*ReadProc)(ReadProcArg, 0, __TestForError) && conversions == 0) + return -1; + + return items_assigned; +} + +void __FileRead(void) +{ + // UNUSED FUNCTION +} + +int __StringRead(void* pPtr, int ch, int act) +{ + char ret; + __InStrCtrl* Iscp = (__InStrCtrl*)pPtr; + + switch (act) { + case __GetAChar: + ret = *(Iscp->NextChar); + + if (ret == '\0') { + Iscp->NullCharDetected = 1; + return -1; + } else { + Iscp->NextChar++; + return (unsigned char)ret; + } + + case __UngetAChar: + if (Iscp->NullCharDetected == 0) { + Iscp->NextChar--; + } else { + Iscp->NullCharDetected = 0; + } + + return ch; + + case __TestForError: + return Iscp->NullCharDetected; + } + + return 0; +} + +void fscanf(void) +{ + // UNUSED FUNCTION +} + +void vscanf(void) +{ + // UNUSED FUNCTION +} + +void scanf(void) +{ + // UNUSED FUNCTION +} + +void vfscanf(void) +{ + // UNUSED FUNCTION +} + +inline int isspace_string(const char* s) +{ + int i = 0; + + while (s[i] != '\0') { + if (!isspace(s[i++])) + return 0; + } + + return 1; +} + +inline int vsscanf(const char* s, const char* format, va_list arg) +{ + __InStrCtrl isc; + isc.NextChar = (char*)s; + + if ((s == 0) || (*isc.NextChar == '\0')) { + return -1; + } + + isc.NullCharDetected = 0; + return __sformatter(&__StringRead, (void*)&isc, format, arg); +} + +int sscanf(const char* s, const char* pFormat, ...) +{ + va_list args; + va_start(args, pFormat); + return vsscanf(s, pFormat, args); +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/signal.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/signal.c new file mode 100644 index 000000000..22584b4f5 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/signal.c @@ -0,0 +1,39 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/signal.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_params.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/abort_exit.h" + +__signal_func_ptr signal_funcs[6]; + +int raise(int sig) +{ + __signal_func_ptr signal_func; + + if (sig < 1 || sig > 6) + { + return -1; + } + + __begin_critical_region(stderr_access); + signal_func = signal_funcs[sig - 1]; + + if (signal_func != ((__std(__signal_func_ptr))1)) + { + signal_funcs[sig - 1] = ((__std(__signal_func_ptr))0); + } + + __end_critical_region(stderr_access); + + if (signal_func == ((__std(__signal_func_ptr))1) || (signal_func == ((__std(__signal_func_ptr))0) && sig == 1)) + { + return 0; + } + + if (signal_func == ((__std(__signal_func_ptr))0)) + { + exit(0); + } + + (*signal_func)(sig); + return 0; +} \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/string.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/string.c new file mode 100644 index 000000000..d70c70bbc --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/string.c @@ -0,0 +1,306 @@ +#include "types.h" +//#define K1 0x80808080 +//#define K2 0xFEFEFEFF + +size_t(strlen)(const char* str) +{ + size_t len = -1; + u8* p = (u8*)str - 1; + + do + len++; + while (*++p); + return (len); +} + +char*(strcpy)(char* dst, const char* src) +{ + register u8 *destb, *fromb; + register u32 w, t, align; + + u32 K1, K2; + + fromb = (u8*)src; + destb = (u8*)dst; + + if ((align = ((int)fromb & 3)) != ((int)destb & 3)) { + goto bytecopy; + } + + if (align) { + if ((*destb = *fromb) == 0) + return (dst); + for (align = 3 - align; align; align--) { + if ((*(++destb) = *(++fromb)) == 0) + return (dst); + } + ++destb; + ++fromb; + } + + w = *((int*)(fromb)); + + K2 = 0xFEFEFEFF; + t = w + K2; + + K1 = 0x80808080; + + t &= K1; + if (t) + goto bytecopy; + --((int*)(destb)); + + do { + *(++((int*)(destb))) = w; + w = *(++((int*)(fromb))); + + t = w + K2; + t &= K1; + if (t) + goto adjust; + } while (1); + +adjust: + ++((int*)(destb)); +bytecopy: + if ((*destb = *fromb) == 0) + return dst; + do { + if ((*(++destb) = *(++fromb)) == 0) + return dst; + } while (1); + + return dst; +} + +char* strncpy(char* dst, const char* src, size_t n) +{ + const unsigned char* p = (const unsigned char*)src - 1; + unsigned char* q = (unsigned char*)dst - 1; + unsigned char zero = 0; + + n++; + + while (--n) + if (!(*++q = *++p)) { + while (--n) + *++q = 0; + break; + } + return (dst); +} + +char* strcat(char* dst, const char* src) +{ + const u8* p = (u8*)src - 1; + u8* q = (u8*)dst - 1; + + while (*++q) + ; + + q--; + + while (*++q = *++p) + ; + + return (dst); +} + +void strncat(void) +{ + // UNUSED FUNCTION +} + +int strcmp(const char* str1, const char* str2) +{ + // bless metrowerks for this implementation + + register u8* left = (u8*)str1; + register u8* right = (u8*)str2; + u32 align, l1, r1, x; + + u32 K1, K2; + + l1 = *left; + r1 = *right; + if (l1 - r1) { + return (l1 - r1); + } + + if ((align = ((int)left & 3)) != ((int)right & 3)) { + goto bytecopy; + } + if (align) { + if (l1 == 0) { + return 0; + } + for (align = 3 - align; align; align--) { + l1 = *(++left); + r1 = *(++right); + if (l1 - r1) { + return (l1 - r1); + } + if (l1 == 0) { + return 0; + } + } + left++; + right++; + } + + l1 = *(int*)left; + r1 = *(int*)right; + + K1 = 0x80808080; + K2 = 0xFEFEFEFF; + + x = l1 + K2; + if (x & K1) { + goto adjust; + } + while (l1 == r1) { + l1 = *(++((int*)(left))); + r1 = *(++((int*)(right))); + x = l1 + K2; + if (x & K1) { + goto adjust; + } + } + if (l1 > r1) + return 1; + return -1; + +adjust: + l1 = *left; + r1 = *right; + if (l1 - r1) { + return (l1 - r1); + } +bytecopy: + if (l1 == 0) { + return 0; + } + do { + l1 = *(++left); + r1 = *(++right); + if (l1 - r1) { + return (l1 - r1); + } + if (l1 == 0) { + return 0; + } + } while (1); +} + +int strncmp(const char* str1, const char* str2, size_t n) +{ + const u8* p1 = (u8*)str1 - 1; + const u8* p2 = (u8*)str2 - 1; + u32 c1, c2; + + n++; + + while (--n) + if ((c1 = *++p1) != (c2 = *++p2)) + return (c1 - c2); + else if (!c1) + break; + return 0; +} + +char* strchr(const char* str, int chr) +{ + const u8* p = (u8*)str - 1; + u32 c = (chr & 0xFF); + u32 ch; + + while (ch = *++p) + if (ch == c) + return ((char*)p); + + return (c ? 0 : (char*)p); +} + +void strcoll(void) +{ + // UNUSED FUNCTION +} + +void strxfrm(void) +{ + // UNUSED FUNCTION +} + +char* strrchr(const char* str, int chr) +{ + const u8* p = (u8*)str - 1; + const u8* q = 0; + u32 c = (chr & 0xFF); + u32 ch; + + while (ch = *++p) + if (ch == c) + q = p; + + if (q) + return ((char*)q); + + return (c ? 0 : (char*)p); +} + +void strpbrk(void) +{ + // UNUSED FUNCTION +} + +void strspn(void) +{ + // UNUSED FUNCTION +} + +void strcspn(void) +{ + // UNUSED FUNCTION +} + +void strtok(void) +{ + // UNUSED FUNCTION +} + +char* strstr(const char *str, const char *pat) { + unsigned char* s1 = (unsigned char*)str - 1; + unsigned char* p1 = (unsigned char*)pat - 1; + unsigned long firstc, c1, c2; + + if ((pat == 0) || (!(firstc = *++p1))) { + return ((char*)str); + } + + while (c1 = *++s1) { + if (c1 == firstc) { + const unsigned char* s2 = s1 - 1; + const unsigned char* p2 = p1 - 1; + + while ((c1 = *++s2) == (c2 = *++p2) && c1) { + + } + + if (!c2) { + return ((char*)s1); + } + } + } + + return NULL; +} + +void strerror(void) +{ + // UNUSED FUNCTION +} + +void __strerror(void) +{ + // UNUSED FUNCTION +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtold.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtold.c new file mode 100644 index 000000000..20072c860 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtold.c @@ -0,0 +1,703 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/strtold.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_fp.h" +#include "PowerPC_EABI_Support/MSL_C/PPC_EABI/math_ppc.h" +#include "errno.h" +#include "locale.h" +#include "ctype.h" +#include "math.h" +#include "mem.h" +#include "limits.h" + +#define TARGET_FLOAT_BITS 64 +#define TARGET_FLOAT_BYTES (TARGET_FLOAT_BITS / 8) +#define TARGET_FLOAT_MAX_EXP LDBL_MAX_EXP +#define TARGET_FLOAT_MANT_DIG LDBL_MANT_DIG +#define TARGET_FLOAT_IMPLICIT_J_BIT 1 +#define TARGET_FLOAT_MANT_BITS (TARGET_FLOAT_MANT_DIG - TARGET_FLOAT_IMPLICIT_J_BIT) +#define TARGET_FLOAT_EXP_BITS (TARGET_FLOAT_BITS - TARGET_FLOAT_MANT_BITS - 1) + +enum scan_states +{ + start = 0x0001, + sig_start = 0x0002, + leading_sig_zeroes = 0x0004, + int_digit_loop = 0x0008, + frac_start = 0x0010, + frac_digit_loop = 0x0020, + sig_end = 0x0040, + exp_start = 0x0080, + leading_exp_digit = 0x0100, + leading_exp_zeroes = 0x0200, + exp_digit_loop = 0x0400, + finished = 0x0800, + failure = 0x1000, + nan_state = 0x2000, + infin_state = 0x4000, + hex_state = 0x8000 +}; + +enum hex_scan_states +{ + not_hex = 0x0000, + hex_start = 0x0001, + hex_leading_sig_zeroes = 0x0002, + hex_int_digit_loop = 0x0004, + hex_frac_digit_loop = 0x0008, + hex_sig_end = 0x0010, + hex_exp_start = 0x0020, + hex_leading_exp_digit = 0x0040, + hex_leading_exp_zeroes = 0x0080, + hex_exp_digit_loop = 0x0100 +}; + +#define final_state(scan_state) (scan_state & (finished | failure)) +#define success(scan_state) \ + (scan_state & (leading_sig_zeroes | int_digit_loop | frac_digit_loop | leading_exp_zeroes | \ + exp_digit_loop | finished)) +#define hex_success(count, scan_state) \ + (count - 1 > 2 && \ + scan_state & (hex_leading_sig_zeroes | hex_int_digit_loop | hex_frac_digit_loop | \ + hex_leading_exp_zeroes | hex_exp_digit_loop)) + +#define fetch() (count++, (*ReadProc)(ReadProcArg, 0, __GetAChar)) +#define unfetch(c) (*ReadProc)(ReadProcArg, c, __UngetAChar) + +long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, + int* chars_scanned, int* overflow) +{ + int scan_state = start; + int hex_scan_state = not_hex; + int count = 0; + int spaces = 0; + int c; + decimal d = { 0, 0, 0, { 0, "" } }; + int sig_negative = 0; + int exp_negative = 0; + long exp_value = 0; + int exp_adjust = 0; + long double result; + int sign_detected = 0; + + unsigned char* chptr = (unsigned char*)&result; + unsigned char uch, uch1; + int ui; + int chindex; + int NibbleIndex; + int expsign = 0; + int exp_digits = 0; + int intdigits = 0; + int RadixPointFound = 0; + short exponent = 0; + int dot; + + dot = *(unsigned char*)(__lconv).decimal_point; + + *overflow = 0; + c = fetch(); + + while (count <= max_width && c != -1 && !final_state(scan_state)) + { + switch (scan_state) + { + case start: + if (isspace(c)) + { + c = fetch(); + count--; + spaces++; + break; + } + + switch (toupper(c)) + { + case '-': + sig_negative = 1; + + case '+': + c = fetch(); + sign_detected = 1; + break; + case 'I': + c = fetch(); + scan_state = infin_state; + break; + + case 'N': + c = fetch(); + scan_state = nan_state; + break; + + default: + scan_state = sig_start; + break; + } + break; + + case infin_state: + { + int i = 1; + char model[] = "INFINITY"; + + while ((i < 8) && (toupper(c) == model[i])) + { + i++; + c = fetch(); + } + + if ((i == 3) || (i == 8)) + { + if (sig_negative) + { + result = -INFINITY; + } + else + { + result = INFINITY; + } + + *chars_scanned = spaces + i + sign_detected; + return result; + } + else + { + scan_state = failure; + } + + break; + } + + case nan_state: + { + int i = 1, j = 0; + char model[] = "NAN("; + char nan_arg[32] = ""; + while ((i < 4) && (toupper(c) == model[i])) + { + i++; + c = fetch(); + } + + if ((i == 3) || (i == 4)) + { + if (i == 4) + { + while ((j < 32) && (isdigit(c) || isalpha(c))) + { + nan_arg[j++] = c; + c = fetch(); + } + + if (c != ')') + { + scan_state = failure; + break; + } + else + { + j++; + } + } + nan_arg[j] = '\0'; + + if (sig_negative) + { + result = -NAN; + } + else + { + result = NAN; + } + + *chars_scanned = spaces + i + j + sign_detected; + return result; + } + else + { + scan_state = failure; + } + break; + } + + case sig_start: + if (c == dot) + { + scan_state = frac_start; + c = fetch(); + break; + } + if (!isdigit(c)) + { + scan_state = failure; + break; + } + + if (c == '0') + { + c = fetch(); + if (toupper(c) == 'X') + { + scan_state = hex_state; + hex_scan_state = hex_start; + } + else + { + scan_state = leading_sig_zeroes; + } + break; + } + + scan_state = int_digit_loop; + break; + + case leading_sig_zeroes: + if (c == '0') + { + c = fetch(); + + break; + } + scan_state = int_digit_loop; + break; + + case int_digit_loop: + if (!isdigit(c)) + { + if (c == dot) + { + scan_state = frac_digit_loop; + c = fetch(); + } + else + { + scan_state = sig_end; + } + break; + } + if (d.sig.length < 20) + { + d.sig.text[d.sig.length++] = c; + } + else + { + exp_adjust++; + } + + c = fetch(); + break; + + case frac_start: + if (!isdigit(c)) + { + scan_state = failure; + break; + } + + scan_state = frac_digit_loop; + break; + + case frac_digit_loop: + if (!isdigit(c)) + { + scan_state = sig_end; + break; + } + + if (d.sig.length < 20) + { + if (c != '0' || d.sig.length) + { + d.sig.text[d.sig.length++] = c; + } + + exp_adjust--; + } + c = fetch(); + break; + + case sig_end: + if (toupper(c) == 'E') + { + scan_state = exp_start; + c = fetch(); + break; + } + scan_state = finished; + break; + + case exp_start: + if (c == '+') + { + c = fetch(); + } + else if (c == '-') + { + c = fetch(); + exp_negative = 1; + } + + scan_state = leading_exp_digit; + break; + + case leading_exp_digit: + if (!isdigit(c)) + { + scan_state = failure; + break; + } + + if (c == '0') + { + scan_state = leading_exp_zeroes; + c = fetch(); + break; + } + + scan_state = exp_digit_loop; + break; + + case leading_exp_zeroes: + if (c == '0') + { + c = fetch(); + break; + } + + scan_state = exp_digit_loop; + break; + + case exp_digit_loop: + if (!isdigit(c)) + { + scan_state = finished; + break; + } + + exp_value = exp_value * 10 + (c - '0'); + if (exp_value > SHRT_MAX) + { + *overflow = 1; + } + + c = fetch(); + break; + + case hex_state: + { + switch (hex_scan_state) + { + case hex_start: + for (chindex = 0; chindex < 8; chindex++) + { + *(chptr + chindex) = '\0'; + } + NibbleIndex = 2; + hex_scan_state = hex_leading_sig_zeroes; + c = fetch(); + break; + + case hex_leading_sig_zeroes: + if (c == '0') + { + c = fetch(); + break; + } + + hex_scan_state = hex_int_digit_loop; + break; + + case hex_int_digit_loop: + if (!isxdigit(c)) + { + if (c == dot) + { + hex_scan_state = hex_frac_digit_loop; + c = fetch(); + } + else + { + hex_scan_state = hex_sig_end; + } + break; + } + + if (NibbleIndex < 17) + { + intdigits++; + uch = *(chptr + NibbleIndex / 2); + ui = toupper(c); + + if (ui >= 'A') + { + ui = ui - 'A' + 10; + } + else + { + ui -= '0'; + } + + uch1 = ui; + + if ((NibbleIndex % 2) != 0) + { + uch |= uch1; + } + else + { + uch |= uch1 << 4; + } + + *(chptr + NibbleIndex++ / 2) = uch; + c = fetch(); + } + + else + { + c = fetch(); + } + + break; + + case hex_frac_digit_loop: + if (!isxdigit(c)) + { + hex_scan_state = hex_sig_end; + break; + } + + if (NibbleIndex < 17) + { + uch = *(chptr + NibbleIndex / 2); + ui = toupper(c); + + if (ui >= 'A') + { + ui = ui - 'A' + 10; + } + else + { + ui -= '0'; + } + + uch1 = ui; + + if ((NibbleIndex % 2) != 0) + { + uch |= uch1; + } + else + { + uch |= uch1 << 4; + } + + *(chptr + NibbleIndex++ / 2) = uch; + c = fetch(); + } + else + { + c = fetch(); + } + break; + + case hex_sig_end: + if (toupper(c) == 'P') + { + hex_scan_state = hex_exp_start; + exp_digits++; + c = fetch(); + } + else + { + scan_state = finished; + } + + break; + + case hex_exp_start: + exp_digits++; + if (c == '-') + { + expsign = 1; + } + else if (c != '+') + { + c = unfetch(c); + exp_digits--; + } + + hex_scan_state = hex_leading_exp_digit; + c = fetch(); + break; + + case hex_leading_exp_digit: + if (!isdigit(c)) + { + scan_state = failure; + break; + } + + if (c == '0') + { + exp_digits++; + hex_scan_state = hex_leading_exp_zeroes; + c = fetch(); + break; + } + + hex_scan_state = hex_exp_digit_loop; + break; + case hex_exp_digit_loop: + if (!isdigit(c)) + { + scan_state = finished; + break; + } + + exponent = exponent * 10 + (c - '0'); + + if (exp_value > SHRT_MAX) + { + *overflow = 1; + } + + exp_digits++; + c = fetch(); + + break; + } + } + break; + } + } + + if (!success(scan_state)) + { + count = 0; + *chars_scanned = 0; + } + else + { + count--; + *chars_scanned = count + spaces; + } + + unfetch(c); + + if (hex_scan_state == not_hex) + { + if (exp_negative) + { + exp_value = -exp_value; + } + + { + int n = d.sig.length; + unsigned char* p = &d.sig.text[n]; + + while (n-- && *--p == '0') + { + exp_adjust++; + } + + d.sig.length = n + 1; + + if (d.sig.length == 0) + { + d.sig.text[d.sig.length++] = '0'; + } + } + + exp_value += exp_adjust; + + if (exp_value < SHRT_MIN || exp_value > SHRT_MAX) + { + *overflow = 1; + } + + if (*overflow) + { + if (exp_negative) + { + return 0.0; + } + else + { + return sig_negative ? -HUGE_VAL : HUGE_VAL; + } + } + + d.exp = exp_value; + + result = __dec2num(&d); + + if (result != 0.0 && result < LDBL_MIN) + { + *overflow = 1; + } + else if (result > LDBL_MAX) + { + *overflow = 1; + result = HUGE_VAL; + } + + if (sig_negative && success(scan_state)) + { + result = -result; + } + + return result; + } + else + { + unsigned long long* uptr = (unsigned long long*)&result; + + if (result) + { + if (expsign) + { + exponent = -exponent; + } + + while ((*(short*)(&result) & 0x00f0) != 0x0010) + { + *uptr >>= 1; + exponent++; + } + + exponent += 4 * (intdigits - 1); + *(short*)&result &= 0x000f; + *(short*)(&result) |= ((exponent + 1023) << 4); + + *chars_scanned = spaces + sign_detected + NibbleIndex + 1 + exp_digits; + if (result != 0.0 && result < LDBL_MIN) + { + *overflow = 1; + result = 0.0; + } + else if (result > LDBL_MAX) + { + *overflow = 1; + result = HUGE_VAL; + } + if (sig_negative) + { + *(short*)(&result) |= 0x8000; + } + } + else + { + result = 0.0; + } + return result; + } +} + +void strtold(void) +{ + // UNUSED FUNCTION +} + +void strtod(void) +{ + // UNUSED FUNCTION +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtoul.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtoul.c new file mode 100644 index 000000000..5019f7213 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtoul.c @@ -0,0 +1,353 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/strtoul.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h" +#include "ctype.h" +#include "errno.h" +#include "limits.h" + +enum scan_states { + start = 0x01, + check_for_zero = 0x02, + leading_zero = 0x04, + need_digit = 0x08, + digit_loop = 0x10, + finished = 0x20, + failure = 0x40 +}; + +#define final_state(scan_state) (scan_state & (finished | failure)) +#define success(scan_state) (scan_state & (leading_zero | digit_loop | finished)) +#define fetch() (count++, (*ReadProc)(ReadProcArg, 0, __GetAChar)) +#define unfetch(c) (*ReadProc)(ReadProcArg, c, __UngetAChar) + +unsigned long __strtoul(int base, int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, int* chars_scanned, int* negative, + int* overflow) +{ + int scan_state = start; + int count = 0; + int spaces = 0; + unsigned long value = 0; + unsigned long value_max = 0; + int c; + + *negative = *overflow = 0; + + if (base < 0 || base == 1 || base > 36 || max_width < 1) { + scan_state = failure; + } else { + c = fetch(); + } + + if (base != 0) { + value_max = ULONG_MAX / base; + } + + while (count <= max_width && c != -1 && !final_state(scan_state)) { + switch (scan_state) { + case start: + if (isspace(c)) { + c = fetch(); + count--; + spaces++; + break; + } + + if (c == '+') { + c = fetch(); + } else if (c == '-') { + c = fetch(); + *negative = 1; + } + + scan_state = check_for_zero; + break; + + case check_for_zero: + if (base == 0 || base == 16) { + if (c == '0') { + scan_state = leading_zero; + c = fetch(); + break; + } + } + + scan_state = need_digit; + break; + + case 4: + if (c == 'X' || c == 'x') { + base = 16; + scan_state = need_digit; + c = fetch(); + break; + } + + if (base == 0) { + base = 8; + } + + scan_state = digit_loop; + break; + + case need_digit: + case digit_loop: + if (base == 0) { + base = 10; + } + + if (!value_max) { + value_max = ULONG_MAX / base; + } + + if (isdigit(c)) { + if ((c -= '0') >= base) { + if (scan_state == digit_loop) { + scan_state = finished; + } else { + scan_state = failure; + } + + c += '0'; + break; + } + } else if (!isalpha(c) || (toupper(c) - 'A' + 10) >= base) { + if (scan_state == digit_loop) { + scan_state = finished; + } else { + scan_state = failure; + } + + break; + } else { + c = toupper(c) - 'A' + 10; + } + + if (value > value_max) { + *overflow = 1; + } + + value *= base; + + if (c > (ULONG_MAX - value)) { + *overflow = 1; + } + + value += c; + scan_state = digit_loop; + c = fetch(); + break; + } + } + + if (!success(scan_state)) { + count = value = *chars_scanned = 0; + } else { + count--; + *chars_scanned = count + spaces; + } + + unfetch(c); + return value; +} + +unsigned long long __strtoull(int base, int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, int* chars_scanned, + int* negative, int* overflow) +{ + int scan_state = start; + int count = 0; + int spaces = 0; + unsigned long long value = 0; + unsigned long long value_max = 0; + unsigned long long ullmax = ULLONG_MAX; + int c; + + *negative = *overflow = 0; + + if (base < 0 || base == 1 || base > 36 || max_width < 1) { + scan_state = failure; + } else { + c = fetch(); + } + + if (base != 0) { + value_max = ullmax / base; + } + + while (count <= max_width && c != -1 && !final_state(scan_state)) { + switch (scan_state) { + case start: + if (isspace(c)) { + c = fetch(); + count--; + spaces++; + break; + } + + if (c == '+') { + c = fetch(); + } else if (c == '-') { + c = fetch(); + *negative = 1; + } + + scan_state = check_for_zero; + break; + + case check_for_zero: + if (base == 0 || base == 16) { + if (c == '0') { + scan_state = leading_zero; + c = fetch(); + break; + } + } + + scan_state = need_digit; + break; + + case leading_zero: + if (c == 'X' || c == 'x') { + base = 16; + scan_state = need_digit; + c = fetch(); + break; + } + + if (base == 0) { + base = 8; + } + + scan_state = digit_loop; + break; + + case need_digit: + case digit_loop: + if (base == 0) { + base = 10; + } + + if (!value_max) { + value_max = ullmax / base; + } + + if (isdigit(c)) { + if ((c -= '0') >= base) { + if (scan_state == digit_loop) { + scan_state = finished; + } else { + scan_state = failure; + } + + c += '0'; + break; + } + } else if (!isalpha(c) || (toupper(c) - 'A' + 10) >= base) { + if (scan_state == digit_loop) { + scan_state = finished; + } else { + scan_state = failure; + } + + break; + } else { + c = toupper(c) - 'A' + 10; + } + + if (value > value_max) { + *overflow = 1; + } + + value *= base; + + if (c > (ullmax - value)) { + *overflow = 1; + } + + value += c; + scan_state = digit_loop; + c = fetch(); + break; + } + } + + if (!success(scan_state)) { + count = value = *chars_scanned = 0; + + } else { + count--; + *chars_scanned = count + spaces; + } + + unfetch(c); + return value; +} + +unsigned long strtoul(const char* str, char** end, int base) +{ + unsigned long value; + int count, negative, overflow; + + __InStrCtrl isc; + isc.NextChar = (char*)str; + isc.NullCharDetected = 0; + + value = __strtoul(base, 0x7FFFFFFF, &__StringRead, (void*)&isc, &count, &negative, &overflow); + + if (end) { + *end = (char*)str + count; + } + + if (overflow) { + value = ULONG_MAX; + errno = 0x22; + } else if (negative) { + value = -value; + } + + return value; +} + +void strtoull(void) +{ + // UNUSED FUNCTION +} + +long strtol(const char* str, char** end, int base) +{ + unsigned long uvalue; + long svalue; + int count, negative, overflow; + + __InStrCtrl isc; + isc.NextChar = (char*)str; + isc.NullCharDetected = 0; + + uvalue = __strtoul(base, 0x7FFFFFFF, &__StringRead, (void*)&isc, &count, &negative, &overflow); + + if (end) { + *end = (char*)str + count; + } + + if (overflow || (!negative && uvalue > LONG_MAX) || (negative && uvalue > -LONG_MIN)) { + svalue = (negative ? -LONG_MIN : LONG_MAX); + errno = ERANGE; + } else { + svalue = (negative ? (long)-uvalue : (long)uvalue); + } + + return svalue; +} + +void strtoll(void) +{ + // UNUSED FUNCTION +} + +int atoi(const char* str) +{ + // UNUSED FUNCTION +} + +void atol(void) +{ + // UNUSED FUNCTION +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/wchar_io.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/wchar_io.c new file mode 100644 index 000000000..da6a0378a --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/wchar_io.c @@ -0,0 +1,82 @@ +#include "types.h" + +#ifndef _MSL_WIDE_CHAR +#define _MSL_WIDE_CHAR +#endif + +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +void putwc(void) +{ + // UNUSED FUNCTION +} + +void putwchar(void) +{ + // UNUSED FUNCTION +} + +void fputwc(void) +{ + // UNUSED FUNCTION +} + +void getwc(void) +{ + // UNUSED FUNCTION +} + +void getwchar(void) +{ + // UNUSED FUNCTION +} + +void fgetwc(void) +{ + // UNUSED FUNCTION +} + +void ungetwc(void) +{ + // UNUSED FUNCTION +} + +void fputws(void) +{ + // UNUSED FUNCTION +} + +void fgetws(void) +{ + // UNUSED FUNCTION +} + +int fwide(FILE* stream, int mode) +{ + int res; + int orientation; + + if (stream == nullptr || stream->mMode.file_kind == __closed_file) + return 0; + + orientation = stream->mMode.file_orientation; + switch (orientation) { + case __unoriented: + if (mode > 0) + stream->mMode.file_orientation = __wide_oriented; + else if (mode < 0) + stream->mMode.file_orientation = __char_oriented; + + res = mode; + break; + + case __wide_oriented: + res = 1; + break; + + case __char_oriented: + res = -1; + break; + } + return res; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c new file mode 100644 index 000000000..40d8aaa60 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c @@ -0,0 +1,117 @@ + +/* @(#)e_asin.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_asin(x) + * Method : + * Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ... + * we approximate asin(x) on [0,0.5] by + * asin(x) = x + x*x^2*R(x^2) + * where + * R(x^2) is a rational approximation of (asin(x)-x)/x^3 + * and its remez error is bounded by + * |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75) + * + * For x in [0.5,1] + * asin(x) = pi/2-2*asin(sqrt((1-x)/2)) + * Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2; + * then for x>0.98 + * asin(x) = pi/2 - 2*(s+s*z*R(z)) + * = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo) + * For x<=0.98, let pio4_hi = pio2_hi/2, then + * f = hi part of s; + * c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z) + * and + * asin(x) = pi/2 - 2*(s+s*z*R(z)) + * = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo) + * = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c)) + * + * Special cases: + * if x is NaN, return x itself; + * if |x|>1, return NaN with invalid signal. + * + */ + +#include "fdlibm.h" +#include "math.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif + one + = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ + huge = 1.000e+300, pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ + pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */ + pio4_hi = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */ + /* coefficient for R(x^2) */ + pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */ + pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */ + pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */ + pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */ + pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */ + pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */ + qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */ + qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ + qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ + qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ + +#ifdef __STDC__ +double __ieee754_asin(double x) +#else +double __ieee754_asin(x) double x; +#endif +{ + double t, w, p, q, c, r, s; + int hx, ix; + hx = __HI(x); + ix = hx & 0x7fffffff; + if (ix >= 0x3ff00000) { /* |x|>= 1 */ + if (((ix - 0x3ff00000) | __LO(x)) == 0) + /* asin(1)=+-pi/2 with inexact */ + return x * pio2_hi + x * pio2_lo; + return NAN; /* asin(|x|>1) is NaN */ + } else if (ix < 0x3fe00000) { /* |x|<0.5 */ + if (ix < 0x3e400000) { /* if |x| < 2**-27 */ + if (huge + x > one) + return x; /* return x with inexact if x!=0*/ + } else + t = x * x; + p = t * (pS0 + t * (pS1 + t * (pS2 + t * (pS3 + t * (pS4 + t * pS5))))); + q = one + t * (qS1 + t * (qS2 + t * (qS3 + t * qS4))); + w = p / q; + return x + x * w; + } + /* 1> |x|>= 0.5 */ + w = one - fabs(x); + t = w * 0.5; + p = t * (pS0 + t * (pS1 + t * (pS2 + t * (pS3 + t * (pS4 + t * pS5))))); + q = one + t * (qS1 + t * (qS2 + t * (qS3 + t * qS4))); + s = sqrt(t); + if (ix >= 0x3FEF3333) { /* if |x| > 0.975 */ + w = p / q; + t = pio2_hi - (2.0 * (s + s * w) - pio2_lo); + } else { + w = s; + __LO(w) = 0; + c = (t - w * w) / (s + w); + r = p / q; + p = 2.0 * s * r - (pio2_lo - 2.0 * c); + q = pio4_hi - 2.0 * w; + t = pio4_hi - (p - q); + } + if (hx > 0) + return t; + else + return -t; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c new file mode 100644 index 000000000..4b75220c1 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c @@ -0,0 +1,143 @@ + +/* @(#)e_atan2.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* __ieee754_atan2(y,x) + * Method : + * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x). + * 2. Reduce x to positive by (if x and y are unexceptional): + * ARG (x+iy) = arctan(y/x) ... if x > 0, + * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0, + * + * Special cases: + * + * ATAN2((anything), NaN ) is NaN; + * ATAN2(NAN , (anything) ) is NaN; + * ATAN2(+-0, +(anything but NaN)) is +-0 ; + * ATAN2(+-0, -(anything but NaN)) is +-pi ; + * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2; + * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ; + * ATAN2(+-(anything but INF and NaN), -INF) is +-pi; + * ATAN2(+-INF,+INF ) is +-pi/4 ; + * ATAN2(+-INF,-INF ) is +-3pi/4; + * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2; + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif + tiny + = 1.0e-300, + zero = 0.0, pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */ + pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */ + pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */ + pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */ + +#ifdef __STDC__ +double __ieee754_atan2(double y, double x) +#else +double __ieee754_atan2(y, x) double y, x; +#endif +{ + double z; + int k, m, hx, hy, ix, iy; + unsigned lx, ly; + + hx = __HI(x); + ix = hx & 0x7fffffff; + lx = __LO(x); + hy = __HI(y); + iy = hy & 0x7fffffff; + ly = __LO(y); + if (((ix | ((lx | -lx) >> 31)) > 0x7ff00000) || ((iy | ((ly | -ly) >> 31)) > 0x7ff00000)) /* x or y is NaN */ + return x + y; + if ((hx - 0x3ff00000 | lx) == 0) + return atan(y); /* x=1.0 */ + m = ((hy >> 31) & 1) | ((hx >> 30) & 2); /* 2*sign(x)+sign(y) */ + + /* when y = 0 */ + if ((iy | ly) == 0) { + switch (m) { + case 0: + case 1: + return y; /* atan(+-0,+anything)=+-0 */ + case 2: + return pi + tiny; /* atan(+0,-anything) = pi */ + case 3: + return -pi - tiny; /* atan(-0,-anything) =-pi */ + } + } + /* when x = 0 */ + if ((ix | lx) == 0) + return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny; + + /* when x is INF */ + if (ix == 0x7ff00000) { + if (iy == 0x7ff00000) { + switch (m) { + case 0: + return pi_o_4 + tiny; /* atan(+INF,+INF) */ + case 1: + return -pi_o_4 - tiny; /* atan(-INF,+INF) */ + case 2: + return 3.0 * pi_o_4 + tiny; /*atan(+INF,-INF)*/ + case 3: + return -3.0 * pi_o_4 - tiny; /*atan(-INF,-INF)*/ + } + } else { + switch (m) { + case 0: + return zero; /* atan(+...,+INF) */ + case 1: + return -zero; /* atan(-...,+INF) */ + case 2: + return pi + tiny; /* atan(+...,-INF) */ + case 3: + return -pi - tiny; /* atan(-...,-INF) */ + } + } + } + /* when y is INF */ + if (iy == 0x7ff00000) + return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny; + + /* compute y/x */ + k = (iy - ix) >> 20; + if (k > 60) + z = pi_o_2 + 0.5 * pi_lo; /* |y/x| > 2**60 */ + else if (hx < 0 && k < -60) + z = 0.0; /* |y|/x < -2**60 */ + else + z = atan(__fabs(y / x)); /* safe to do y/x */ + switch (m) { + case 0: + return z; /* atan(+,+) */ + case 1: + __HI(z) ^= 0x80000000; + return z; /* atan(-,+) */ + case 2: + return pi - (z - pi_lo); /* atan(+,-) */ + default: /* case 3 */ + return (z - pi_lo) - pi; /* atan(-,-) */ + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c new file mode 100644 index 000000000..90e9f2918 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c @@ -0,0 +1,162 @@ + +/* @(#)e_exp.c 1.6 04/04/22 */ +/* + * ==================================================== + * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. + * + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_exp(x) + * Returns the exponential of x. + * + * Method + * 1. Argument reduction: + * Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658. + * Given x, find r and integer k such that + * + * x = k*ln2 + r, |r| <= 0.5*ln2. + * + * Here r will be represented as r = hi-lo for better + * accuracy. + * + * 2. Approximation of exp(r) by a special rational function on + * the interval [0,0.34658]: + * Write + * R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ... + * We use a special Remes algorithm on [0,0.34658] to generate + * a polynomial of degree 5 to approximate R. The maximum error + * of this polynomial approximation is bounded by 2**-59. In + * other words, + * R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5 + * (where z=r*r, and the values of P1 to P5 are listed below) + * and + * | 5 | -59 + * | 2.0+P1*z+...+P5*z - R(z) | <= 2 + * | | + * The computation of exp(r) thus becomes + * 2*r + * exp(r) = 1 + ------- + * R - r + * r*R1(r) + * = 1 + r + ----------- (for better accuracy) + * 2 - R1(r) + * where + * 2 4 10 + * R1(r) = r - (P1*r + P2*r + ... + P5*r ). + * + * 3. Scale back to obtain exp(x): + * From step 1, we have + * exp(x) = 2^k * exp(r) + * + * Special cases: + * exp(INF) is INF, exp(NaN) is NaN; + * exp(-INF) is 0, and + * for finite argument, only exp(0)=1 is exact. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Misc. info. + * For IEEE double + * if x > 7.09782712893383973096e+02 then exp(x) overflow + * if x < -7.45133219101941108420e+02 then exp(x) underflow + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +one = 1.0, +halF[2] = {0.5,-0.5,}, +huge = 1.0e+300, +twom1000= 9.33263618503218878990e-302, /* 2**-1000=0x01700000,0*/ +o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */ +u_threshold= -7.45133219101941108420e+02, /* 0xc0874910, 0xD52D3051 */ +ln2HI[2] ={ 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */ + -6.93147180369123816490e-01,},/* 0xbfe62e42, 0xfee00000 */ +ln2LO[2] ={ 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */ + -1.90821492927058770002e-10,},/* 0xbdea39ef, 0x35793c76 */ +invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */ +P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ +P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ +P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ +P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ +P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ + +#ifdef __STDC__ +double __ieee754_exp(double x) /* default IEEE double exp */ +#else +double __ieee754_exp(x) /* default IEEE double exp */ + double x; +#endif +{ + double y, hi, lo, c, t; + int k, xsb; + unsigned hx; + + hx = __HI(x); /* high word of x */ + xsb = (hx >> 31) & 1; /* sign bit of x */ + hx &= 0x7fffffff; /* high word of |x| */ + + /* filter out non-finite argument */ + if (hx >= 0x40862E42) { /* if |x|>=709.78... */ + if (hx >= 0x7ff00000) { + if (((hx & 0xfffff) | __LO(x)) != 0) + return x + x; /* NaN */ + else + return (xsb == 0) ? x : 0.0; /* exp(+-inf)={inf,0} */ + } + if (x > o_threshold) + return huge * huge; /* overflow */ + if (x < u_threshold) + return twom1000 * twom1000; /* underflow */ + } + + /* argument reduction */ + if (hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ + if (hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ + hi = x - ln2HI[xsb]; + lo = ln2LO[xsb]; + k = 1 - xsb - xsb; + } else { + k = (int)(invln2 * x + halF[xsb]); + t = k; + hi = x - t * ln2HI[0]; /* t*ln2HI is exact here */ + lo = t * ln2LO[0]; + } + x = hi - lo; + } else if (hx < 0x3e300000) { /* when |x|<2**-28 */ + if (huge + x > one) + return one + x; /* trigger inexact */ + } else + k = 0; + + /* x is now in primary range */ + t = x * x; + c = x - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5)))); + if (k == 0) + return one - ((x * c) / (c - 2.0) - x); + else + y = one - ((lo - (x * c) / (2.0 - c)) - hi); + if (k >= -1021) { + __HI(y) += (k << 20); /* add k to y's exponent */ + return y; + } else { + __HI(y) += ((k + 1000) << 20); /* add k to y's exponent */ + return y * twom1000; + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c new file mode 100644 index 000000000..8ebc894ba --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c @@ -0,0 +1,167 @@ + +/* @(#)e_fmod.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * __ieee754_fmod(x,y) + * Return x mod y in exact arithmetic + * Method: shift and subtract + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double one = 1.0, Zero[] = { + 0.0, + -0.0, +}; +#else +static double one = 1.0, Zero[] = { + 0.0, + -0.0, +}; +#endif + +#ifdef __STDC__ +double __ieee754_fmod(double x, double y) +#else +double __ieee754_fmod(x, y) double x, y; +#endif +{ + int n, hx, hy, hz, ix, iy, sx, i; + unsigned lx, ly, lz; + + hx = __HI(x); /* high word of x */ + lx = __LO(x); /* low word of x */ + hy = __HI(y); /* high word of y */ + ly = __LO(y); /* low word of y */ + sx = hx & 0x80000000; /* sign of x */ + hx ^= sx; /* |x| */ + hy &= 0x7fffffff; /* |y| */ + + /* purge off exception values */ + if ((hy | ly) == 0 || (hx >= 0x7ff00000) || /* y=0,or x not finite */ + ((hy | ((ly | -ly) >> 31)) > 0x7ff00000)) /* or y is NaN */ + return (x * y) / (x * y); + if (hx <= hy) { + if ((hx < hy) || (lx < ly)) + return x; /* |x|<|y| return x */ + if (lx == ly) + return Zero[(unsigned)sx >> 31]; /* |x|=|y| return x*0*/ + } + + /* determine ix = ilogb(x) */ + if (hx < 0x00100000) { /* subnormal x */ + if (hx == 0) { + for (ix = -1043, i = lx; i > 0; i <<= 1) + ix -= 1; + } else { + for (ix = -1022, i = (hx << 11); i > 0; i <<= 1) + ix -= 1; + } + } else + ix = (hx >> 20) - 1023; + + /* determine iy = ilogb(y) */ + if (hy < 0x00100000) { /* subnormal y */ + if (hy == 0) { + for (iy = -1043, i = ly; i > 0; i <<= 1) + iy -= 1; + } else { + for (iy = -1022, i = (hy << 11); i > 0; i <<= 1) + iy -= 1; + } + } else + iy = (hy >> 20) - 1023; + + /* set up {hx,lx}, {hy,ly} and align y to x */ + if (ix >= -1022) + hx = 0x00100000 | (0x000fffff & hx); + else { /* subnormal x, shift x to normal */ + n = -1022 - ix; + if (n <= 31) { + hx = (hx << n) | (lx >> (32 - n)); + lx <<= n; + } else { + hx = lx << (n - 32); + lx = 0; + } + } + if (iy >= -1022) + hy = 0x00100000 | (0x000fffff & hy); + else { /* subnormal y, shift y to normal */ + n = -1022 - iy; + if (n <= 31) { + hy = (hy << n) | (ly >> (32 - n)); + ly <<= n; + } else { + hy = ly << (n - 32); + ly = 0; + } + } + + /* fix point fmod */ + n = ix - iy; + while (n--) { + hz = hx - hy; + lz = lx - ly; + if (lx < ly) + hz -= 1; + if (hz < 0) { + hx = hx + hx + (lx >> 31); + lx = lx + lx; + } else { + if ((hz | lz) == 0) /* return sign(x)*0 */ + return Zero[(unsigned)sx >> 31]; + hx = hz + hz + (lz >> 31); + lx = lz + lz; + } + } + hz = hx - hy; + lz = lx - ly; + if (lx < ly) + hz -= 1; + if (hz >= 0) { + hx = hz; + lx = lz; + } + + /* convert back to floating value and restore the sign */ + if ((hx | lx) == 0) /* return sign(x)*0 */ + return Zero[(unsigned)sx >> 31]; + while (hx < 0x00100000) { /* normalize x */ + hx = hx + hx + (lx >> 31); + lx = lx + lx; + iy -= 1; + } + if (iy >= -1022) { /* normalize output */ + hx = ((hx - 0x00100000) | ((iy + 1023) << 20)); + __HI(x) = hx | sx; + __LO(x) = lx; + } else { /* subnormal output */ + n = -1022 - iy; + if (n <= 20) { + lx = (lx >> n) | ((unsigned)hx << (32 - n)); + hx >>= n; + } else if (n <= 31) { + lx = (hx << (32 - n)) | (lx >> n); + hx = sx; + } else { + lx = hx >> (n - 32); + hx = sx; + } + __HI(x) = hx | sx; + __LO(x) = lx; + x *= one; /* create necessary signal */ + } + return x; /* exact output */ +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c new file mode 100644 index 000000000..4b2340097 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c @@ -0,0 +1,157 @@ +/* @(#)e_log.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_log(x) + * Return the logrithm of x + * + * Method : + * 1. Argument Reduction: find k and f such that + * x = 2^k * (1+f), + * where sqrt(2)/2 < 1+f < sqrt(2) . + * + * 2. Approximation of log(1+f). + * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) + * = 2s + 2/3 s**3 + 2/5 s**5 + ....., + * = 2s + s*R + * We use a special Reme algorithm on [0,0.1716] to generate + * a polynomial of degree 14 to approximate R The maximum error + * of this polynomial approximation is bounded by 2**-58.45. In + * other words, + * 2 4 6 8 10 12 14 + * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s + * (the values of Lg1 to Lg7 are listed in the program) + * and + * | 2 14 | -58.45 + * | Lg1*s +...+Lg7*s - R(z) | <= 2 + * | | + * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. + * In order to guarantee error in log below 1ulp, we compute log + * by + * log(1+f) = f - s*(f - R) (if f is not too large) + * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy) + * + * 3. Finally, log(x) = k*ln2 + log(1+f). + * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) + * Here ln2 is split into two floating point number: + * ln2_hi + ln2_lo, + * where n*ln2_hi is always exact for |n| < 2000. + * + * Special cases: + * log(x) is NaN with signal if x < 0 (including -INF) ; + * log(+INF) is +INF; log(0) is -INF with signal; + * log(NaN) is that NaN with no signal. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" +#include "errno.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif + ln2_hi + = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ + ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ + two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */ + Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ + Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ + Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ + Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ + Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ + Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ + Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ + +static double zero = 0.0; + +#ifdef __STDC__ +double __ieee754_log(double x) +#else +double __ieee754_log(x) double x; +#endif +{ + double hfsq, f, s, z, R, w, t1, t2, dk; + int k, hx, i, j; + unsigned lx; + + hx = __HI(x); /* high word of x */ + lx = __LO(x); /* low word of x */ + + k = 0; + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx & 0x7fffffff) | lx) == 0) + return -two54 / zero; /* log(+-0)=-inf */ + if (hx < 0) { + errno = 33; + return (x - x) / zero; + } /* log(-#) = NaN */ + k -= 54; + x *= two54; /* subnormal number, scale up x */ + hx = __HI(x); /* high word of x */ + } + if (hx >= 0x7ff00000) + return x + x; + k += (hx >> 20) - 1023; + hx &= 0x000fffff; + i = (hx + 0x95f64) & 0x100000; + __HI(x) = hx | (i ^ 0x3ff00000); /* normalize x or x/2 */ + k += (i >> 20); + f = x - 1.0; + if ((0x000fffff & (2 + hx)) < 3) { /* |f| < 2**-20 */ + if (f == zero) + if (k == 0) + return zero; + else { + dk = (double)k; + return dk * ln2_hi + dk * ln2_lo; + } + R = f * f * (0.5 - 0.33333333333333333 * f); + if (k == 0) + return f - R; + else { + dk = (double)k; + return dk * ln2_hi - ((R - dk * ln2_lo) - f); + } + } + s = f / (2.0 + f); + dk = (double)k; + z = s * s; + i = hx - 0x6147a; + w = z * z; + j = 0x6b851 - hx; + t1 = w * (Lg2 + w * (Lg4 + w * Lg6)); + t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7))); + i |= j; + R = t2 + t1; + if (i > 0) { + hfsq = 0.5 * f * f; + if (k == 0) + return f - (hfsq - s * (hfsq + R)); + else + return dk * ln2_hi - ((hfsq - (s * (hfsq + R) + dk * ln2_lo)) - f); + } else { + if (k == 0) + return f - s * (f - R); + else + return dk * ln2_hi - ((s * (f - R) - dk * ln2_lo) - f); + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log10.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log10.c new file mode 100644 index 000000000..2f2ddffa3 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log10.c @@ -0,0 +1,99 @@ + +/* @(#)e_log10.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_log10(x) + * Return the base 10 logarithm of x + * + * Method : + * Let log10_2hi = leading 40 bits of log10(2) and + * log10_2lo = log10(2) - log10_2hi, + * ivln10 = 1/log(10) rounded. + * Then + * n = ilogb(x), + * if(n<0) n = n+1; + * x = scalbn(x,-n); + * log10(x) := n*log10_2hi + (n*log10_2lo + ivln10*log(x)) + * + * Note 1: + * To guarantee log10(10**n)=n, where 10**n is normal, the rounding + * mode must set to Round-to-Nearest. + * Note 2: + * [1/log(10)] rounded to 53 bits has error .198 ulps; + * log10 is monotonic at all binary break points. + * + * Special cases: + * log10(x) is NaN with signal if x < 0; + * log10(+INF) is +INF with no signal; log10(0) is -INF with signal; + * log10(NaN) is that NaN with no signal; + * log10(10**N) = N for N=0,1,...,22. + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "fdlibm.h" +#include "errno.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif + two54 + = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ + ivln10 = 4.34294481903251816668e-01, /* 0x3FDBCB7B, 0x1526E50E */ + log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */ + log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */ + +static double zero = 0.0; + +#ifdef __STDC__ +double __ieee754_log10(double x) +#else +double __ieee754_log10(x) double x; +#endif +{ + double y, z; + int i, k, hx; + unsigned lx; + + hx = __HI(x); /* high word of x */ + lx = __LO(x); /* low word of x */ + + k = 0; + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx & 0x7fffffff) | lx) == 0) { + errno = 33; + return -two54 / zero; + } /* log(+-0)=-inf */ + if (hx < 0) { + errno = 33; + return (x - x) / zero; + } /* log(-#) = NaN */ + k -= 54; + x *= two54; /* subnormal number, scale up x */ + hx = __HI(x); /* high word of x */ + } + if (hx >= 0x7ff00000) + return x + x; + k += (hx >> 20) - 1023; + i = ((unsigned)k & 0x80000000) >> 31; + hx = (hx & 0x000fffff) | ((0x3ff - i) << 20); + y = (double)(k + i); + __HI(x) = hx; + z = y * log10_2lo + ivln10 * __ieee754_log(x); + return z + y * log10_2hi; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c new file mode 100644 index 000000000..5f9af1132 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c @@ -0,0 +1,408 @@ +//======================================================================== +// +// e_pow.c +// +// Part of the standard mathematical function library +// +//======================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//======================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jlarmour +// Contributors: +// Date: 2001-07-20 +// Purpose: +// Description: +// Usage: +// +//####DESCRIPTIONEND#### +// +//======================================================================== + +// CONFIGURATION + +/* @(#)e_pow.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_pow(x,y) return x**y + * + * n + * Method: Let x = 2 * (1+f) + * 1. Compute and return log2(x) in two pieces: + * log2(x) = w1 + w2, + * where w1 has 53-24 = 29 bit trailing zeros. + * 2. Perform y*log2(x) = n+y' by simulating muti-precision + * arithmetic, where |y'|<=0.5. + * 3. Return x**y = 2**n*exp(y'*log2) + * + * Special cases: + * 1. (anything) ** 0 is 1 + * 2. (anything) ** 1 is itself + * 3. (anything) ** NAN is NAN + * 4. NAN ** (anything except 0) is NAN + * 5. +-(|x| > 1) ** +INF is +INF + * 6. +-(|x| > 1) ** -INF is +0 + * 7. +-(|x| < 1) ** +INF is +0 + * 8. +-(|x| < 1) ** -INF is +INF + * 9. +-1 ** +-INF is NAN + * 10. +0 ** (+anything except 0, NAN) is +0 + * 11. -0 ** (+anything except 0, NAN, odd integer) is +0 + * 12. +0 ** (-anything except 0, NAN) is +INF + * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF + * 14. -0 ** (odd integer) = -( +0 ** (odd integer) ) + * 15. +INF ** (+anything except 0,NAN) is +INF + * 16. +INF ** (-anything except 0,NAN) is +0 + * 17. -INF ** (anything) = -0 ** (-anything) + * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer) + * 19. (-anything except 0 and inf) ** (non-integer) is NAN + * + * Accuracy: + * pow(x,y) returns x**y nearly rounded. In particular + * pow(integer,integer) + * always returns the correct integer provided it is + * representable. + * + * Constants : + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "types.h" +#include "errno.h" +#include "math.h" +#include "fdlibm.h" + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double +#else +static double +#endif +bp[] = {1.0, 1.5,}, +dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */ +dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */ +zero = 0.0, +one = 1.0, +two = 2.0, +two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */ +huge = 1.0e300, +tiny = 1.0e-300, + /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ +L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */ +L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */ +L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */ +L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */ +L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */ +L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */ +P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ +P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ +P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ +P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ +P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */ +lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ +lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */ +lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */ +ovt = 8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */ +cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */ +cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */ +cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/ +ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */ +ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/ +ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ + +#ifdef __STDC__ +double __ieee754_pow(double x, double y) +#else +double __ieee754_pow(x, y) double x, y; +#endif +{ + double z, ax, z_h, z_l, p_h, p_l; + double y1, t1, t2, r, s, t, u, v, w; + double qqq; // necessary temp + int i0, i1, i, j, k, yisint, n; + int hx, hy, ix, iy; + u32 lx, ly; + + i0 = ((*(int*)&one) >> 29) ^ 1; + i1 = 1 - i0; + hx = __HI(x); + lx = __LO(x); + hy = __HI(y); + ly = __LO(y); + ix = hx & 0x7fffffff; + iy = hy & 0x7fffffff; + + /* y==zero: x**0 = 1 */ + if ((iy | ly) == 0) + return one; + + /* +-NaN return x+y */ + if (ix > 0x7ff00000 || ((ix == 0x7ff00000) && (lx != 0)) || iy > 0x7ff00000 || ((iy == 0x7ff00000) && (ly != 0))) + return x + y; + + /* determine if y is an odd int when x < 0 + * yisint = 0 ... y is not an integer + * yisint = 1 ... y is an odd int + * yisint = 2 ... y is an even int + */ + yisint = 0; + if (hx < 0) { + if (iy >= 0x43400000) + yisint = 2; /* even integer y */ + else if (iy >= 0x3ff00000) { + k = (iy >> 20) - 0x3ff; /* exponent */ + if (k > 20) { + j = ly >> (52 - k); + if ((j << (52 - k)) == ly) + yisint = 2 - (j & 1); + } else if (ly == 0) { + j = iy >> (20 - k); + if ((j << (20 - k)) == iy) + yisint = 2 - (j & 1); + } + } + } + + /* special value of y */ + if (ly == 0) { + if (iy == 0x7ff00000) { /* y is +-inf */ + if (((ix - 0x3ff00000) | lx) == 0) + return y - y; /* inf**+-1 is NaN */ + else if (ix >= 0x3ff00000) /* (|x|>1)**+-inf = inf,0 */ + return (hy >= 0) ? y : zero; + else /* (|x|<1)**-,+inf = inf,0 */ + return (hy < 0) ? -y : zero; + } + if (iy == 0x3ff00000) { /* y is +-1 */ + if (hy < 0) + return one / x; + else + return x; + } + if (hy == 0x40000000) + return x * x; /* y is 2 */ + if (hy == 0x3fe00000) { /* y is 0.5 */ + if (hx >= 0) /* x >= +0 */ + return sqrt(x); + } + } + + ax = __fabs(x); + qqq = ax; /*x is +-0,+-inf,+-1*/ + /* special value of x */ + if (lx == 0) { + if (ix == 0x7ff00000 || ix == 0 || ix == 0x3ff00000) { + z = qqq; /*x is +-0,+-inf,+-1*/ + if (hy < 0) + z = one / z; /* z = (1/|x|) */ + if (hx < 0) { + if (((ix - 0x3ff00000) | yisint) == 0) { + z = (z - z) / (z - z); /* (-1)**non-int is NaN */ + } else if (yisint == 1) + z = -z; /* (x<0)**odd = -(|x|**odd) */ + } + return z; + } + } + + /* (x<0)**(non-int) is NaN */ + /* CYGNUS LOCAL: This used to be + if((((hx>>31)+1)|yisint)==0) return (x-x)/(x-x); + but ANSI C says a right shift of a signed negative quantity is + implementation defined. */ + + if (((((int)hx >> 31) + 1) | yisint) == 0) { + errno = 33; + return (double)NAN; + }; + + /* |y| is huge */ + if (iy > 0x41e00000) { /* if |y| > 2**31 */ + if (iy > 0x43f00000) { /* if |y| > 2**64, must o/uflow */ + if (ix <= 0x3fefffff) + return (hy < 0) ? huge * huge : tiny * tiny; + if (ix >= 0x3ff00000) + return (hy > 0) ? huge * huge : tiny * tiny; + } + /* over/underflow if x is not close to one */ + if (ix < 0x3fefffff) + return (hy < 0) ? huge * huge : tiny * tiny; + if (ix > 0x3ff00000) + return (hy > 0) ? huge * huge : tiny * tiny; + /* now |1-x| is tiny <= 2**-20, suffice to compute + log(x) by x-x^2/2+x^3/3-x^4/4 */ + t = x - 1; /* t has 20 trailing zeros */ + w = (t * t) * (0.5 - t * (0.3333333333333333333333 - t * 0.25)); + u = ivln2_h * t; /* ivln2_h has 21 sig. bits */ + v = t * ivln2_l - w * ivln2; + t1 = u + v; + __LO(t1) = 0; + t2 = v - (t1 - u); + } else { + double s2, s_h, s_l, t_h, t_l; + n = 0; + /* take care subnormal number */ + if (ix < 0x00100000) { + ax *= two53; + n -= 53; + ix = __HI(ax); + } + n += ((ix) >> 20) - 0x3ff; + j = ix & 0x000fffff; + /* determine interval */ + ix = j | 0x3ff00000; /* normalize ix */ + if (j <= 0x3988E) + k = 0; /* |x|> 1) | 0x20000000) + 0x00080000 + (k << 18); + t_l = ax - (t_h - bp[k]); + s_l = v * ((u - s_h * t_h) - s_h * t_l); + /* compute log(ax) */ + s2 = s * s; + r = s2 * s2 * (L1 + s2 * (L2 + s2 * (L3 + s2 * (L4 + s2 * (L5 + s2 * L6))))); + r += s_l * (s_h + s); + s2 = s_h * s_h; + t_h = 3.0 + s2 + r; + __LO(t_h) = 0; + t_l = r - ((t_h - 3.0) - s2); + /* u+v = s*(1+...) */ + u = s_h * t_h; + v = s_l * t_h + t_l * s; + /* 2/(3log2)*(s+...) */ + p_h = u + v; + __LO(p_h) = 0; + p_l = v - (p_h - u); + z_h = cp_h * p_h; /* cp_h+cp_l = 2/(3*log2) */ + z_l = cp_l * p_h + p_l * cp + dp_l[k]; + /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ + t = (double)n; + t1 = (((z_h + z_l) + dp_h[k]) + t); + __LO(t1) = 0; + t2 = z_l - (((t1 - t) - dp_h[k]) - z_h); + } + + s = one; /* s (sign of result -ve**odd) = -1 else = 1 */ + if (((((int)hx >> 31) + 1) | (yisint - 1)) == 0) + s = -one; /* (-ve)**(odd int) */ + + /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ + y1 = y; + __LO(y1) = 0; + p_l = (y - y1) * t1 + y * t2; + p_h = y1 * t1; + z = p_l + p_h; + j = __HI(z); + i = __LO(z); + if (j >= 0x40900000) { /* z >= 1024 */ + if (((j - 0x40900000) | i) != 0) /* if z > 1024 */ + return s * huge * huge; /* overflow */ + else { + if (p_l + ovt > z - p_h) + return s * huge * huge; /* overflow */ + } + } else if ((j & 0x7fffffff) >= 0x4090cc00) { /* z <= -1075 */ + if (((j - 0xc090cc00) | i) != 0) /* z < -1075 */ + return s * tiny * tiny; /* underflow */ + else { + if (p_l <= z - p_h) + return s * tiny * tiny; /* underflow */ + } + } + /* + * compute 2**(p_h+p_l) + */ + i = j & 0x7fffffff; + k = (i >> 20) - 0x3ff; + n = 0; + if (i > 0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */ + n = j + (0x00100000 >> (k + 1)); + k = ((n & 0x7fffffff) >> 20) - 0x3ff; /* new k for n */ + t = zero; + __HI(t) = (n & ~(0x000fffff >> k)); + n = ((n & 0x000fffff) | 0x00100000) >> (20 - k); + if (j < 0) + n = -n; + p_h -= t; + } + t = p_l + p_h; + __LO(t) = 0; + u = t * lg2_h; + v = (p_l - (t - p_h)) * lg2 + t * lg2_l; + z = u + v; + w = v - (z - u); + t = z * z; + t1 = z - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5)))); + r = (z * t1) / (t1 - two) - (w + z * w); + z = one - (r - z); + j = __HI(z); + j += (n << 20); + if ((j >> 20) <= 0) + z = ldexp(z, n); /* subnormal output */ + else + __HI(z) += (n << 20); + return s * z; +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ + +// EOF e_pow.c diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c new file mode 100644 index 000000000..86e0cd14e --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c @@ -0,0 +1,181 @@ + +/* @(#)e_rem_pio2.c 1.4 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* __ieee754_rem_pio2(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + * use __kernel_rem_pio2() + */ + +#include "fdlibm.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h" + +/* + * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi + */ +#ifdef __STDC__ +static const int two_over_pi[] = { +#else +static int two_over_pi[] = { +#endif + 0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, 0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, + 0x246E3A, 0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, 0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, + 0x7026B4, 0x5F7E41, 0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8, 0x97FFDE, 0x05980F, 0xEF2F11, + 0x8B5A0A, 0x6D1F6D, 0x367ECF, 0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5, 0xF17B3D, 0x0739F7, + 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, 0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, 0x91615E, + 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, 0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, +}; + +#ifdef __STDC__ +static const int npio2_hw[] = { +#else +static int npio2_hw[] = { +#endif + 0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C, 0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, + 0x4032D97C, 0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A, 0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, + 0x4042106C, 0x4042D97C, 0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB, 0x404858EB, 0x404921FB, +}; + +/* + * invpio2: 53 bits of 2/pi + * pio2_1: first 33 bit of pi/2 + * pio2_1t: pi/2 - pio2_1 + * pio2_2: second 33 bit of pi/2 + * pio2_2t: pi/2 - (pio2_1+pio2_2) + * pio2_3: third 33 bit of pi/2 + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) + */ + +#ifdef __STDC__ +static const double +#else +static double +#endif + zero + = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ + half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ + two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ + invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ + pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ + pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */ + pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */ + pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */ + pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */ + pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */ + +#ifdef __STDC__ +int __ieee754_rem_pio2(double x, double* y) +#else +int __ieee754_rem_pio2(x, y) double x, y[]; +#endif +{ + double z, w, t, r, fn; + double tx[3]; + int e0, i, j, nx, n, ix, hx; + + hx = __HI(x); /* high word of x */ + ix = hx & 0x7fffffff; + if (ix <= 0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */ + { + y[0] = x; + y[1] = 0; + return 0; + } + if (ix < 0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */ + if (hx > 0) { + z = x - pio2_1; + if (ix != 0x3ff921fb) { /* 33+53 bit pi is good enough */ + y[0] = z - pio2_1t; + y[1] = (z - y[0]) - pio2_1t; + } else { /* near pi/2, use 33+33+53 bit pi */ + z -= pio2_2; + y[0] = z - pio2_2t; + y[1] = (z - y[0]) - pio2_2t; + } + return 1; + } else { /* negative x */ + z = x + pio2_1; + if (ix != 0x3ff921fb) { /* 33+53 bit pi is good enough */ + y[0] = z + pio2_1t; + y[1] = (z - y[0]) + pio2_1t; + } else { /* near pi/2, use 33+33+53 bit pi */ + z += pio2_2; + y[0] = z + pio2_2t; + y[1] = (z - y[0]) + pio2_2t; + } + return -1; + } + } + if (ix <= 0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */ + t = fabs(x); + n = (int)(t * invpio2 + half); + fn = (double)n; + r = t - fn * pio2_1; + w = fn * pio2_1t; /* 1st round good to 85 bit */ + if (n < 32 && ix != npio2_hw[n - 1]) { + y[0] = r - w; /* quick check no cancellation */ + } else { + j = ix >> 20; + y[0] = r - w; + i = j - (((__HI(y[0])) >> 20) & 0x7ff); + if (i > 16) { /* 2nd iteration needed, good to 118 */ + t = r; + r = t - fn * pio2_2; + w = fn * pio2_2t - ((t - r) - fn * pio2_2); + y[0] = r - w; + i = j - (((__HI(y[0])) >> 20) & 0x7ff); + if (i > 49) { /* 3rd iteration need, 151 bits acc */ + t = r; /* will cover all possible cases */ + w = fn * pio2_3; + r = t - w; + w = fn * pio2_3t - ((t - r) - w); + y[0] = r - w; + } + } + } + y[1] = (r - y[0]) - w; + if (hx < 0) { + y[0] = -y[0]; + y[1] = -y[1]; + return -n; + } else + return n; + } + /* + * all other (large) arguments + */ + if (ix >= 0x7ff00000) { /* x is inf or NaN */ + y[0] = y[1] = x - x; + return 0; + } + /* set z = scalbn(|x|,ilogb(x)-23) */ + __LO(z) = __LO(x); + e0 = (ix >> 20) - 1046; /* e0 = ilogb(z)-23; */ + __HI(z) = ix - (e0 << 20); + for (i = 0; i < 2; i++) { + tx[i] = (double)((int)(z)); + z = (z - tx[i]) * two24; + } + tx[2] = z; + nx = 3; + while (tx[nx - 1] == zero) + nx--; /* skip zero term */ + n = __kernel_rem_pio2(tx, y, e0, nx, 2, two_over_pi); + if (hx < 0) { + y[0] = -y[0]; + y[1] = -y[1]; + return -n; + } + return n; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_sqrt.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_sqrt.c new file mode 100644 index 000000000..fdef23781 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_sqrt.c @@ -0,0 +1,462 @@ +/* @(#)e_sqrt.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_sqrt(x) + * Return correctly rounded sqrt. + * ------------------------------------------ + * | Use the hardware sqrt if you have one | + * ------------------------------------------ + * Method: + * Bit by bit method using integer arithmetic. (Slow, but portable) + * 1. Normalization + * Scale x to y in [1,4) with even powers of 2: + * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then + * sqrt(x) = 2^k * sqrt(y) + * 2. Bit by bit computation + * Let q = sqrt(y) truncated to i bit after binary point (q = 1), + * i 0 + * i+1 2 + * s = 2*q , and y = 2 * ( y - q ). (1) + * i i i i + * + * To compute q from q , one checks whether + * i+1 i + * + * -(i+1) 2 + * (q + 2 ) <= y. (2) + * i + * -(i+1) + * If (2) is false, then q = q ; otherwise q = q + 2 . + * i+1 i i+1 i + * + * With some algebric manipulation, it is not difficult to see + * that (2) is equivalent to + * -(i+1) + * s + 2 <= y (3) + * i i + * + * The advantage of (3) is that s and y can be computed by + * i i + * the following recurrence formula: + * if (3) is false + * + * s = s , y = y ; (4) + * i+1 i i+1 i + * + * otherwise, + * -i -(i+1) + * s = s + 2 , y = y - s - 2 (5) + * i+1 i i+1 i i + * + * One may easily use induction to prove (4) and (5). + * Note. Since the left hand side of (3) contain only i+2 bits, + * it does not necessary to do a full (53-bit) comparison + * in (3). + * 3. Final rounding + * After generating the 53 bits result, we compute one more bit. + * Together with the remainder, we can decide whether the + * result is exact, bigger than 1/2ulp, or less than 1/2ulp + * (it will never equal to 1/2ulp). + * The rounding mode can be detected by checking whether + * huge + tiny is equal to huge, and whether huge - tiny is + * equal to huge for some floating point number "huge" and "tiny". + * + * Special cases: + * sqrt(+-0) = +-0 ... exact + * sqrt(inf) = inf + * sqrt(-ve) = NaN ... with invalid signal + * sqrt(NaN) = NaN ... with invalid signal for signaling NaN + * + * Other methods : see the appended file at the end of the program below. + *--------------- + */ + +#include "fdlibm.h" +#include "errno.h" +#include "math.h" + +#ifdef __STDC__ +static const double one = 1.0, tiny = 1.0e-300; +#else +static double one = 1.0, tiny = 1.0e-300; +#endif + +#ifdef __STDC__ +double __ieee754_sqrt(double x) +#else +double __ieee754_sqrt(x) double x; +#endif +{ + double z; + int sign = (int)0x80000000; + unsigned r, t1, s1, ix1, q1; + int ix0, s0, q, m, t, i; + + ix0 = __HI(x); /* high word of x */ + ix1 = __LO(x); /* low word of x */ + + /* take care of Inf and NaN */ + if ((ix0 & 0x7ff00000) == 0x7ff00000) { + errno = 33; + return x * x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf + sqrt(-inf)=sNaN */ + } + /* take care of zero */ + if (ix0 <= 0) { + if (((ix0 & (~sign)) | ix1) == 0) + return x; /* sqrt(+-0) = +-0 */ + else if (ix0 < 0) { + errno = 33; + return NAN; + } /* sqrt(-ve) = sNaN */ + } + /* normalize x */ + m = (ix0 >> 20); + if (m == 0) { /* subnormal x */ + while (ix0 == 0) { + m -= 21; + ix0 |= (ix1 >> 11); + ix1 <<= 21; + } + for (i = 0; (ix0 & 0x00100000) == 0; i++) + ix0 <<= 1; + m -= i - 1; + ix0 |= (ix1 >> (32 - i)); + ix1 <<= i; + } + m -= 1023; /* unbias exponent */ + ix0 = (ix0 & 0x000fffff) | 0x00100000; + if (m & 1) { /* odd m, double x to make it even */ + ix0 += ix0 + ((ix1 & sign) >> 31); + ix1 += ix1; + } + m >>= 1; /* m = [m/2] */ + + /* generate sqrt(x) bit by bit */ + ix0 += ix0 + ((ix1 & sign) >> 31); + ix1 += ix1; + q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */ + r = 0x00200000; /* r = moving bit from right to left */ + + while (r != 0) { + t = s0 + r; + if (t <= ix0) { + s0 = t + r; + ix0 -= t; + q += r; + } + ix0 += ix0 + ((ix1 & sign) >> 31); + ix1 += ix1; + r >>= 1; + } + + r = sign; + while (r != 0) { + t1 = s1 + r; + t = s0; + if ((t < ix0) || ((t == ix0) && (t1 <= ix1))) { + s1 = t1 + r; + if (((t1 & sign) == sign) && (s1 & sign) == 0) + s0 += 1; + ix0 -= t; + if (ix1 < t1) + ix0 -= 1; + ix1 -= t1; + q1 += r; + } + ix0 += ix0 + ((ix1 & sign) >> 31); + ix1 += ix1; + r >>= 1; + } + + /* use floating add to find out rounding direction */ + if ((ix0 | ix1) != 0) { + z = one - tiny; /* trigger inexact flag */ + if (z >= one) { + z = one + tiny; + if (q1 == (unsigned)0xffffffff) { + q1 = 0; + q += 1; + } else if (z > one) { + if (q1 == (unsigned)0xfffffffe) + q += 1; + q1 += 2; + } else + q1 += (q1 & 1); + } + } + ix0 = (q >> 1) + 0x3fe00000; + ix1 = q1 >> 1; + if ((q & 1) == 1) + ix1 |= sign; + ix0 += (m << 20); + __HI(z) = ix0; + __LO(z) = ix1; + return z; +} + +/* +Other methods (use floating-point arithmetic) +------------- +(This is a copy of a drafted paper by Prof W. Kahan +and K.C. Ng, written in May, 1986) + + Two algorithms are given here to implement sqrt(x) + (IEEE double precision arithmetic) in software. + Both supply sqrt(x) correctly rounded. The first algorithm (in + Section A) uses newton iterations and involves four divisions. + The second one uses reciproot iterations to avoid division, but + requires more multiplications. Both algorithms need the ability + to chop results of arithmetic operations instead of round them, + and the INEXACT flag to indicate when an arithmetic operation + is executed exactly with no roundoff error, all part of the + standard (IEEE 754-1985). The ability to perform shift, add, + subtract and logical AND operations upon 32-bit words is needed + too, though not part of the standard. + +A. sqrt(x) by Newton Iteration + + (1) Initial approximation + + Let x0 and x1 be the leading and the trailing 32-bit words of + a floating point number x (in IEEE double format) respectively + + 1 11 52 ...widths + ------------------------------------------------------ + x: |s| e | f | + ------------------------------------------------------ + msb lsb msb lsb ...order + + + ------------------------ ------------------------ + x0: |s| e | f1 | x1: | f2 | + ------------------------ ------------------------ + + By performing shifts and subtracts on x0 and x1 (both regarded + as integers), we obtain an 8-bit approximation of sqrt(x) as + follows. + + k := (x0>>1) + 0x1ff80000; + y0 := k - T1[31&(k>>15)]. ... y ~ sqrt(x) to 8 bits + Here k is a 32-bit integer and T1[] is an integer array containing + correction terms. Now magically the floating value of y (y's + leading 32-bit word is y0, the value of its trailing word is 0) + approximates sqrt(x) to almost 8-bit. + + Value of T1: + static int T1[32]= { + 0, 1024, 3062, 5746, 9193, 13348, 18162, 23592, + 29598, 36145, 43202, 50740, 58733, 67158, 75992, 85215, + 83599, 71378, 60428, 50647, 41945, 34246, 27478, 21581, + 16499, 12183, 8588, 5674, 3403, 1742, 661, 130,}; + + (2) Iterative refinement + + Apply Heron's rule three times to y, we have y approximates + sqrt(x) to within 1 ulp (Unit in the Last Place): + + y := (y+x/y)/2 ... almost 17 sig. bits + y := (y+x/y)/2 ... almost 35 sig. bits + y := y-(y-x/y)/2 ... within 1 ulp + + + Remark 1. + Another way to improve y to within 1 ulp is: + + y := (y+x/y) ... almost 17 sig. bits to 2*sqrt(x) + y := y - 0x00100006 ... almost 18 sig. bits to sqrt(x) + + 2 + (x-y )*y + y := y + 2* ---------- ...within 1 ulp + 2 + 3y + x + + + This formula has one division fewer than the one above; however, + it requires more multiplications and additions. Also x must be + scaled in advance to avoid spurious overflow in evaluating the + expression 3y*y+x. Hence it is not recommended uless division + is slow. If division is very slow, then one should use the + reciproot algorithm given in section B. + + (3) Final adjustment + + By twiddling y's last bit it is possible to force y to be + correctly rounded according to the prevailing rounding mode + as follows. Let r and i be copies of the rounding mode and + inexact flag before entering the square root program. Also we + use the expression y+-ulp for the next representable floating + numbers (up and down) of y. Note that y+-ulp = either fixed + point y+-1, or multiply y by nextafter(1,+-inf) in chopped + mode. + + I := FALSE; ... reset INEXACT flag I + R := RZ; ... set rounding mode to round-toward-zero + z := x/y; ... chopped quotient, possibly inexact + If(not I) then { ... if the quotient is exact + if(z=y) { + I := i; ... restore inexact flag + R := r; ... restore rounded mode + return sqrt(x):=y. + } else { + z := z - ulp; ... special rounding + } + } + i := TRUE; ... sqrt(x) is inexact + If (r=RN) then z=z+ulp ... rounded-to-nearest + If (r=RP) then { ... round-toward-+inf + y = y+ulp; z=z+ulp; + } + y := y+z; ... chopped sum + y0:=y0-0x00100000; ... y := y/2 is correctly rounded. + I := i; ... restore inexact flag + R := r; ... restore rounded mode + return sqrt(x):=y. + + (4) Special cases + + Square root of +inf, +-0, or NaN is itself; + Square root of a negative number is NaN with invalid signal. + + +B. sqrt(x) by Reciproot Iteration + + (1) Initial approximation + + Let x0 and x1 be the leading and the trailing 32-bit words of + a floating point number x (in IEEE double format) respectively + (see section A). By performing shifs and subtracts on x0 and y0, + we obtain a 7.8-bit approximation of 1/sqrt(x) as follows. + + k := 0x5fe80000 - (x0>>1); + y0:= k - T2[63&(k>>14)]. ... y ~ 1/sqrt(x) to 7.8 bits + + Here k is a 32-bit integer and T2[] is an integer array + containing correction terms. Now magically the floating + value of y (y's leading 32-bit word is y0, the value of + its trailing word y1 is set to zero) approximates 1/sqrt(x) + to almost 7.8-bit. + + Value of T2: + static int T2[64]= { + 0x1500, 0x2ef8, 0x4d67, 0x6b02, 0x87be, 0xa395, 0xbe7a, 0xd866, + 0xf14a, 0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f, + 0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d, + 0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0, + 0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989, + 0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd, + 0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e, + 0x1527f,0x1334a,0x11051,0xe951, 0xbe01, 0x8e0d, 0x5924, 0x1edd,}; + + (2) Iterative refinement + + Apply Reciproot iteration three times to y and multiply the + result by x to get an approximation z that matches sqrt(x) + to about 1 ulp. To be exact, we will have + -1ulp < sqrt(x)-z<1.0625ulp. + + ... set rounding mode to Round-to-nearest + y := y*(1.5-0.5*x*y*y) ... almost 15 sig. bits to 1/sqrt(x) + y := y*((1.5-2^-30)+0.5*x*y*y)... about 29 sig. bits to 1/sqrt(x) + ... special arrangement for better accuracy + z := x*y ... 29 bits to sqrt(x), with z*y<1 + z := z + 0.5*z*(1-z*y) ... about 1 ulp to sqrt(x) + + Remark 2. The constant 1.5-2^-30 is chosen to bias the error so that + (a) the term z*y in the final iteration is always less than 1; + (b) the error in the final result is biased upward so that + -1 ulp < sqrt(x) - z < 1.0625 ulp + instead of |sqrt(x)-z|<1.03125ulp. + + (3) Final adjustment + + By twiddling y's last bit it is possible to force y to be + correctly rounded according to the prevailing rounding mode + as follows. Let r and i be copies of the rounding mode and + inexact flag before entering the square root program. Also we + use the expression y+-ulp for the next representable floating + numbers (up and down) of y. Note that y+-ulp = either fixed + point y+-1, or multiply y by nextafter(1,+-inf) in chopped + mode. + + R := RZ; ... set rounding mode to round-toward-zero + switch(r) { + case RN: ... round-to-nearest + if(x<= z*(z-ulp)...chopped) z = z - ulp; else + if(x<= z*(z+ulp)...chopped) z = z; else z = z+ulp; + break; + case RZ:case RM: ... round-to-zero or round-to--inf + R:=RP; ... reset rounding mod to round-to-+inf + if(x=(z+ulp)*(z+ulp) ...rounded up) z = z+ulp; + break; + case RP: ... round-to-+inf + if(x>(z+ulp)*(z+ulp)...chopped) z = z+2*ulp; else + if(x>z*z ...chopped) z = z+ulp; + break; + } + + Remark 3. The above comparisons can be done in fixed point. For + example, to compare x and w=z*z chopped, it suffices to compare + x1 and w1 (the trailing parts of x and w), regarding them as + two's complement integers. + + ...Is z an exact square root? + To determine whether z is an exact square root of x, let z1 be the + trailing part of z, and also let x0 and x1 be the leading and + trailing parts of x. + + If ((z1&0x03ffffff)!=0) ... not exact if trailing 26 bits of z!=0 + I := 1; ... Raise Inexact flag: z is not exact + else { + j := 1 - [(x0>>20)&1] ... j = logb(x) mod 2 + k := z1 >> 26; ... get z's 25-th and 26-th + fraction bits + I := i or (k&j) or ((k&(j+j+1))!=(x1&3)); + } + R:= r ... restore rounded mode + return sqrt(x):=z. + + If multiplication is cheaper then the foregoing red tape, the + Inexact flag can be evaluated by + + I := i; + I := (z*z!=x) or I. + + Note that z*z can overwrite I; this value must be sensed if it is + True. + + Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be + zero. + + -------------------- + z1: | f2 | + -------------------- + bit 31 bit 0 + + Further more, bit 27 and 26 of z1, bit 0 and 1 of x1, and the odd + or even of logb(x) have the following relations: + + ------------------------------------------------- + bit 27,26 of z1 bit 1,0 of x1 logb(x) + ------------------------------------------------- + 00 00 odd and even + 01 01 even + 10 10 odd + 10 00 even + 11 01 even + ------------------------------------------------- + + (4) Special cases (see (4) of Section A). + + */ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c new file mode 100644 index 000000000..616f4ba9e --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c @@ -0,0 +1,93 @@ + +/* @(#)k_cos.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * __kernel_cos( x, y ) + * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164 + * Input x is assumed to be bounded by ~pi/4 in magnitude. + * Input y is the tail of x. + * + * Algorithm + * 1. Since cos(-x) = cos(x), we need only to consider positive x. + * 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0. + * 3. cos(x) is approximated by a polynomial of degree 14 on + * [0,pi/4] + * 4 14 + * cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x + * where the remez error is + * + * | 2 4 6 8 10 12 14 | -58 + * |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2 + * | | + * + * 4 6 8 10 12 14 + * 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then + * cos(x) = 1 - x*x/2 + r + * since cos(x+y) ~ cos(x) - sin(x)*y + * ~ cos(x) - x*y, + * a correction term is necessary in cos(x) and hence + * cos(x+y) = 1 - (x*x/2 - (r - x*y)) + * For better accuracy when x > 0.3, let qx = |x|/4 with + * the last 32 bits mask off, and if x > 0.78125, let qx = 0.28125. + * Then + * cos(x+y) = (1-qx) - ((x*x/2-qx) - (r-x*y)). + * Note that 1-qx and (x*x/2-qx) is EXACT here, and the + * magnitude of the latter is at least a quarter of x*x/2, + * thus, reducing the rounding error in the subtraction. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif + one + = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ + C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */ + C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */ + C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */ + C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */ + C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */ + C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */ + +#ifdef __STDC__ +double __kernel_cos(double x, double y) +#else +double __kernel_cos(x, y) double x, y; +#endif +{ + double a, hz, z, r, qx; + int ix; + ix = __HI(x) & 0x7fffffff; /* ix = |x|'s high word*/ + if (ix < 0x3e400000) { /* if x < 2**27 */ + if (((int)x) == 0) + return one; /* generate inexact */ + } + z = x * x; + r = z * (C1 + z * (C2 + z * (C3 + z * (C4 + z * (C5 + z * C6))))); + if (ix < 0x3FD33333) /* if |x| < 0.3 */ + return one - (0.5 * z - (z * r - x * y)); + else { + if (ix > 0x3fe90000) { /* x > 0.78125 */ + qx = 0.28125; + } else { + __HI(qx) = ix - 0x00200000; /* x/4 */ + __LO(qx) = 0; + } + hz = 0.5 * z - qx; + a = one - qx; + return a - (hz - (z * r - x * y)); + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c new file mode 100644 index 000000000..ec31cfd8b --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c @@ -0,0 +1,355 @@ + +#ifndef _No_Floating_Point +/* @(#)k_rem_pio2.c 1.2 95/01/04 */ +/* $Id: k_rem_pio2.c,v 1.2.14.1 2002/01/31 15:24:13 ceciliar Exp $ */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2) + * double x[],y[]; int e0,nx,prec; int ipio2[]; + * + * __kernel_rem_pio2 return the last three digits of N with + * y = x - N*pi/2 + * so that |y| < pi/2. + * + * The method is to compute the integer (mod 8) and fraction parts of + * (2/pi)*x without doing the full multiplication. In general we + * skip the part of the product that are known to be a huge integer ( + * more accurately, = 0 mod 8 ). Thus the number of operations are + * independent of the exponent of the input. + * + * (2/pi) is represented by an array of 24-bit integers in ipio2[]. + * + * Input parameters: + * x[] The input value (must be positive) is broken into nx + * pieces of 24-bit integers in double precision format. + * x[i] will be the i-th 24 bit of x. The scaled exponent + * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0 + * match x's up to 24 bits. + * + * Example of breaking a double positive z into x[0]+x[1]+x[2]: + * e0 = ilogb(z)-23 + * z = ldexp(z,-e0) + * for i = 0,1,2 + * x[i] = floor(z) + * z = (z-x[i])*2**24 + * + * + * y[] ouput result in an array of double precision numbers. + * The dimension of y[] is: + * 24-bit precision 1 + * 53-bit precision 2 + * 64-bit precision 2 + * 113-bit precision 3 + * The actual value is the sum of them. Thus for 113-bit + * precison, one may have to do something like: + * + * long double t,w,r_head, r_tail; + * t = (long double)y[2] + (long double)y[1]; + * w = (long double)y[0]; + * r_head = t+w; + * r_tail = w - (r_head - t); + * + * e0 The exponent of x[0] + * + * nx dimension of x[] + * + * prec an integer indicating the precision: + * 0 24 bits (single) + * 1 53 bits (double) + * 2 64 bits (extended) + * 3 113 bits (quad) + * + * ipio2[] + * integer array, contains the (24*i)-th to (24*i+23)-th + * bit of 2/pi after binary point. The corresponding + * floating value is + * + * ipio2[i] * 2^(-24(i+1)). + * + * External function: + * double ldexp(), floor(); + * + * + * Here is the description of some local variables: + * + * jk jk+1 is the initial number of terms of ipio2[] needed + * in the computation. The recommended value is 2,3,4, + * 6 for single, double, extended,and quad. + * + * jz local integer variable indicating the number of + * terms of ipio2[] used. + * + * jx nx - 1 + * + * jv index for pointing to the suitable ipio2[] for the + * computation. In general, we want + * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8 + * is an integer. Thus + * e0-3-24*jv >= 0 or (e0-3)/24 >= jv + * Hence jv = max(0,(e0-3)/24). + * + * jp jp+1 is the number of terms in PIo2[] needed, jp = jk. + * + * q[] double array with integral value, representing the + * 24-bits chunk of the product of x and 2/pi. + * + * q0 the corresponding exponent of q[0]. Note that the + * exponent for q[i] would be q0-24*i. + * + * PIo2[] double precision array, obtained by cutting pi/2 + * into 24 bits chunks. + * + * f[] ipio2[] in floating point + * + * iq[] integer array by breaking up q[] in 24-bits chunk. + * + * fq[] final product of x*(2/pi) in fq[0],..,fq[jk] + * + * ih integer. If >0 it indicates q[] is >= 0.5, hence + * it also indicates the *sign* of the result. + * + */ + +/* + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const int init_jk[] = { 2, 3, 4, 6 }; +/* initial value for jk */ /*- cc 020130 -*/ +#else +static int init_jk[] = { 2, 3, 4, 6 }; /*- cc 020130 -*/ +#endif + +#ifdef __STDC__ +static const double PIo2[] = { +#else +static double PIo2[] = { +#endif + 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */ + 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */ + 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */ + 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */ + 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */ + 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */ + 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */ + 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */ +}; + +#ifdef __STDC__ +static const double +#else +static double +#endif + zero + = 0.0, + one = 1.0, two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ + twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */ + +#ifdef __STDC__ +int __kernel_rem_pio2(double* x, double* y, int e0, int nx, int prec, const int* ipio2) /*- cc 020130 -*/ +#else +int __kernel_rem_pio2(x, y, e0, nx, prec, ipio2) /*- cc 020130 -*/ + double x[], + y[]; +int e0, nx, prec; +int ipio2[]; /*- cc 020130 -*/ +#endif +{ + int jz, jx, jv, jp, jk, carry, n, iq[20], i, j, k, m, q0, ih; /*- cc 020130 -*/ + double z, fw, f[20], fq[20], q[20]; + + /* initialize jk*/ + jk = init_jk[prec]; + jp = jk; + + /* determine jx,jv,q0, note that 3>q0 */ + jx = nx - 1; + jv = (e0 - 3) / 24; + if (jv < 0) + jv = 0; + q0 = e0 - 24 * (jv + 1); + + /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ + j = jv - jx; + m = jx + jk; + for (i = 0; i <= m; i++, j++) + f[i] = (j < 0) ? zero : (double)ipio2[j]; + + /* compute q[0],q[1],...q[jk] */ + for (i = 0; i <= jk; i++) { + for (j = 0, fw = 0.0; j <= jx; j++) + fw += x[j] * f[jx + i - j]; + q[i] = fw; + } + + jz = jk; +recompute: + /* distill q[] into iq[] reversingly */ + for (i = 0, j = jz, z = q[jz]; j > 0; i++, j--) { + fw = (double)((int)(twon24 * z)); /*- cc 020130 -*/ + iq[i] = (int)(z - two24 * fw); /*- cc 020130 -*/ + z = q[j - 1] + fw; + } + + /* compute n */ + z = ldexp(z, q0); /* actual value of z */ + z -= 8.0 * floor(z * 0.125); /* trim off integer >= 8 */ + n = (int)z; /*- cc 020130 -*/ + z -= (double)n; + ih = 0; + if (q0 > 0) { /* need iq[jz-1] to determine n */ + i = (iq[jz - 1] >> (24 - q0)); + n += i; + iq[jz - 1] -= i << (24 - q0); + ih = iq[jz - 1] >> (23 - q0); + } else if (q0 == 0) + ih = iq[jz - 1] >> 23; + else if (z >= 0.5) + ih = 2; + + if (ih > 0) { /* q > 0.5 */ + n += 1; + carry = 0; + for (i = 0; i < jz; i++) { /* compute 1-q */ + j = iq[i]; + if (carry == 0) { + if (j != 0) { + carry = 1; + iq[i] = 0x1000000 - j; + } + } else + iq[i] = 0xffffff - j; + } + if (q0 > 0) { /* rare case: chance is 1 in 12 */ + switch (q0) { + case 1: + iq[jz - 1] &= 0x7fffff; + break; + case 2: + iq[jz - 1] &= 0x3fffff; + break; + } + } + if (ih == 2) { + z = one - z; + if (carry != 0) + z -= ldexp(one, q0); + } + } + + /* check if recomputation is needed */ + if (z == zero) { + j = 0; + for (i = jz - 1; i >= jk; i--) + j |= iq[i]; + if (j == 0) { /* need recomputation */ + for (k = 1; iq[jk - k] == 0; k++) + ; /* k = no. of terms needed */ + + for (i = jz + 1; i <= jz + k; i++) { /* add q[jz+1] to q[jz+k] */ + f[jx + i] = (double)ipio2[jv + i]; + for (j = 0, fw = 0.0; j <= jx; j++) + fw += x[j] * f[jx + i - j]; + q[i] = fw; + } + jz += k; + goto recompute; + } + } + + /* chop off zero terms */ + if (z == 0.0) { + jz -= 1; + q0 -= 24; + while (iq[jz] == 0) { + jz--; + q0 -= 24; + } + } else { /* break z into 24-bit if necessary */ + z = ldexp(z, -q0); + if (z >= two24) { + fw = (double)((int)(twon24 * z)); /*- cc 020130 -*/ + iq[jz] = (int)(z - two24 * fw); /*- cc 020130 -*/ + jz += 1; + q0 += 24; + iq[jz] = (int)fw; /*- cc 020130 -*/ + } else + iq[jz] = (int)z; /*- cc 020130 -*/ + } + + /* convert integer "bit" chunk to floating-point value */ + fw = ldexp(one, q0); + for (i = jz; i >= 0; i--) { + q[i] = fw * (double)iq[i]; + fw *= twon24; + } + + /* compute PIo2[0,...,jp]*q[jz,...,0] */ + for (i = jz; i >= 0; i--) { + for (fw = 0.0, k = 0; k <= jp && k <= jz - i; k++) + fw += PIo2[k] * q[i + k]; + fq[jz - i] = fw; + } + + /* compress fq[] into y[] */ + switch (prec) { + case 0: + fw = 0.0; + for (i = jz; i >= 0; i--) + fw += fq[i]; + y[0] = (ih == 0) ? fw : -fw; + break; + case 1: + case 2: + fw = 0.0; + for (i = jz; i >= 0; i--) + fw += fq[i]; + y[0] = (ih == 0) ? fw : -fw; + fw = fq[0] - fw; + for (i = 1; i <= jz; i++) + fw += fq[i]; + y[1] = (ih == 0) ? fw : -fw; + break; + case 3: /* painful */ + for (i = jz; i > 0; i--) { + fw = fq[i - 1] + fq[i]; + fq[i] += fq[i - 1] - fw; + fq[i - 1] = fw; + } + for (i = jz; i > 1; i--) { + fw = fq[i - 1] + fq[i]; + fq[i] += fq[i - 1] - fw; + fq[i - 1] = fw; + } + for (fw = 0.0, i = jz; i >= 2; i--) + fw += fq[i]; + if (ih == 0) { + y[0] = fq[0]; + y[1] = fq[1]; + y[2] = fw; + } else { + y[0] = -fq[0]; + y[1] = -fq[1]; + y[2] = -fw; + } + } + return n & 7; +} +#endif /* _No_Floating_Point */ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c new file mode 100644 index 000000000..14c628cd3 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c @@ -0,0 +1,80 @@ + +/* @(#)k_sin.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __kernel_sin( x, y, iy) + * kernel sin function on [-pi/4, pi/4], pi/4 ~ 0.7854 + * Input x is assumed to be bounded by ~pi/4 in magnitude. + * Input y is the tail of x. + * Input iy indicates whether y is 0. (if iy=0, y assume to be 0). + * + * Algorithm + * 1. Since sin(-x) = -sin(x), we need only to consider positive x. + * 2. if x < 2^-27 (hx<0x3e400000 0), return x with inexact if x!=0. + * 3. sin(x) is approximated by a polynomial of degree 13 on + * [0,pi/4] + * 3 13 + * sin(x) ~ x + S1*x + ... + S6*x + * where + * + * |sin(x) 2 4 6 8 10 12 | -58 + * |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2 + * | x | + * + * 4. sin(x+y) = sin(x) + sin'(x')*y + * ~ sin(x) + (1-x*x/2)*y + * For better accuracy, let + * 3 2 2 2 2 + * r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6)))) + * then 3 2 + * sin(x) = x + (S1*x + (x *(r-y/2)+y)) + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif + half + = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ + S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */ + S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */ + S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */ + S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */ + S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */ + S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */ + +#ifdef __STDC__ +double __kernel_sin(double x, double y, int iy) +#else +double __kernel_sin(x, y, iy) double x, y; +int iy; /* iy=0 if y is zero */ +#endif +{ + double z, r, v; + int ix; + ix = __HI(x) & 0x7fffffff; /* high word of x */ + if (ix < 0x3e400000) /* |x| < 2**-27 */ + { + if ((int)x == 0) + return x; + } /* generate inexact */ + z = x * x; + v = z * x; + r = S2 + z * (S3 + z * (S4 + z * (S5 + z * S6))); + if (iy == 0) + return x + v * (S1 + z * r); + else + return x - ((z * (half * y - v * r) - y) - v * S1); +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c new file mode 100644 index 000000000..86dba2f09 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c @@ -0,0 +1,181 @@ +//=========================================================================== +// +// k_tan.c +// +// Part of the standard mathematical function library +// +//=========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jlarmour +// Contributors: jlarmour +// Date: 1998-02-13 +// Purpose: +// Description: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// Derived from code with the following copyright + +/* @(#)k_tan.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __kernel_tan( x, y, k ) + * kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854 + * Input x is assumed to be bounded by ~pi/4 in magnitude. + * Input y is the tail of x. + * Input k indicates whether tan (if k=1) or + * -1/tan (if k= -1) is returned. + * + * Algorithm + * 1. Since tan(-x) = -tan(x), we need only to consider positive x. + * 2. if x < 2^-28 (hx<0x3e300000 0), return x with inexact if x!=0. + * 3. tan(x) is approximated by a odd polynomial of degree 27 on + * [0,0.67434] + * 3 27 + * tan(x) ~ x + T1*x + ... + T13*x + * where + * + * |tan(x) 2 4 26 | -59.2 + * |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2 + * | x | + * + * Note: tan(x+y) = tan(x) + tan'(x)*y + * ~ tan(x) + (1+x*x)*y + * Therefore, for better accuracy in computing tan(x+y), let + * 3 2 2 2 2 + * r = x *(T2+x *(T3+x *(...+x *(T12+x *T13)))) + * then + * 3 2 + * tan(x+y) = x + (T1*x + (x *(r+y)+y)) + * + * 4. For x in [0.67434,pi/4], let y = pi/4 - x, then + * tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y)) + * = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y))) + */ + +#include "fdlibm.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h" +static const double one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ + pio4 = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */ + pio4lo = 3.06161699786838301793e-17, /* 0x3C81A626, 0x33145C07 */ + T[] = { + 3.33333333333334091986e-01, /* 0x3FD55555, 0x55555563 */ + 1.33333333333201242699e-01, /* 0x3FC11111, 0x1110FE7A */ + 5.39682539762260521377e-02, /* 0x3FABA1BA, 0x1BB341FE */ + 2.18694882948595424599e-02, /* 0x3F9664F4, 0x8406D637 */ + 8.86323982359930005737e-03, /* 0x3F8226E3, 0xE96E8493 */ + 3.59207910759131235356e-03, /* 0x3F6D6D22, 0xC9560328 */ + 1.45620945432529025516e-03, /* 0x3F57DBC8, 0xFEE08315 */ + 5.88041240820264096874e-04, /* 0x3F4344D8, 0xF2F26501 */ + 2.46463134818469906812e-04, /* 0x3F3026F7, 0x1A8D1068 */ + 7.81794442939557092300e-05, /* 0x3F147E88, 0xA03792A6 */ + 7.14072491382608190305e-05, /* 0x3F12B80F, 0x32F0A7E9 */ + -1.85586374855275456654e-05, /* 0xBEF375CB, 0xDB605373 */ + 2.59073051863633712884e-05, /* 0x3EFB2A70, 0x74BF7AD4 */ + }; + +double __kernel_tan(double x, double y, int iy) +{ + double z, r, v, w, s; + int ix, hx; + hx = __HI(x); /* high word of x */ + ix = hx & 0x7fffffff; /* high word of |x| */ + if (ix < 0x3e300000) /* x < 2**-28 */ + { + if ((int)x == 0) { /* generate inexact */ + if (((ix | __LO(x)) | (iy + 1)) == 0) { + double ret = fabs(x); + return one / ret; + } else + return (iy == 1) ? x : -one / x; + } + } + if (ix >= 0x3FE59428) { /* |x|>=0.6744 */ + if (hx < 0) { + x = -x; + y = -y; + } + z = pio4 - x; + w = pio4lo - y; + x = z + w; + y = 0.0; + } + z = x * x; + w = z * z; + /* Break x^5*(T[1]+x^2*T[2]+...) into + * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) + + * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12])) + */ + r = T[1] + w * (T[3] + w * (T[5] + w * (T[7] + w * (T[9] + w * T[11])))); + v = z * (T[2] + w * (T[4] + w * (T[6] + w * (T[8] + w * (T[10] + w * T[12]))))); + s = z * x; + r = y + z * (s * (r + v) + y); + r += T[0] * s; + w = x + r; + if (ix >= 0x3FE59428) { + v = (double)iy; + return (double)(1 - ((hx >> 30) & 2)) * (v - 2.0 * (x - (w * w / (w + v) - r))); + } + if (iy == 1) + return w; + else { /* if allow error up to 2 ulp, + simply return -1.0/(x+r) here */ + /* compute -1.0/(x+r) accurately */ + double a, t; + z = w; + __LO(z) = 0; + v = r - (z - x); /* z+v = r+x */ + t = a = -1.0 / w; /* a = -1.0/w */ + __LO(t) = 0; + s = 1.0 + t * z; + return t + a * (s + t * v); + } +} + +// EOF k_tan.c diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c new file mode 100644 index 000000000..f3435bc81 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c @@ -0,0 +1,143 @@ + +/* @(#)s_atan.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* atan(x) + * Method + * 1. Reduce x to positive by atan(x) = -atan(-x). + * 2. According to the integer k=4t+0.25 chopped, t=x, the argument + * is further reduced to one of the following intervals and the + * arctangent of t is evaluated by the corresponding formula: + * + * [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...) + * [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) ) + * [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) ) + * [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) ) + * [39/16,INF] atan(x) = atan(INF) + atan( -1/t ) + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double atanhi[] = { +#else +static double atanhi[] = { +#endif + 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */ + 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */ + 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */ + 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */ +}; + +#ifdef __STDC__ +static const double atanlo[] = { +#else +static double atanlo[] = { +#endif + 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */ + 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */ + 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */ + 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */ +}; + +#ifdef __STDC__ +static const double aT[] = { +#else +static double aT[] = { +#endif + 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */ + -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */ + 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */ + -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */ + 9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */ + -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */ + 6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */ + -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */ + 4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */ + -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */ + 1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */ +}; + +#ifdef __STDC__ +static const double +#else +static double +#endif + one + = 1.0, + huge = 1.0e300; + +#ifdef __STDC__ +double atan(double x) +#else +double atan(x) double x; +#endif +{ + double w, s1, s2, z; + int ix, hx, id; + + hx = __HI(x); + ix = hx & 0x7fffffff; + if (ix >= 0x44100000) { /* if |x| >= 2^66 */ + if (ix > 0x7ff00000 || (ix == 0x7ff00000 && (__LO(x) != 0))) + return x + x; /* NaN */ + if (hx > 0) + return atanhi[3] + atanlo[3]; + else + return -atanhi[3] - atanlo[3]; + } + if (ix < 0x3fdc0000) { /* |x| < 0.4375 */ + if (ix < 0x3e200000) { /* |x| < 2^-29 */ + if (huge + x > one) + return x; /* raise inexact */ + } + id = -1; + } else { + x = __fabs(x); + if (ix < 0x3ff30000) { /* |x| < 1.1875 */ + if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */ + id = 0; + x = (2.0 * x - one) / (2.0 + x); + } else { /* 11/16<=|x|< 19/16 */ + id = 1; + x = (x - one) / (x + one); + } + } else { + if (ix < 0x40038000) { /* |x| < 2.4375 */ + id = 2; + x = (x - 1.5) / (one + 1.5 * x); + } else { /* 2.4375 <= |x| < 2^66 */ + id = 3; + x = -1.0 / x; + } + } + } + /* end of argument reduction */ + z = x * x; + w = z * z; + /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ + s1 = z * (aT[0] + w * (aT[2] + w * (aT[4] + w * (aT[6] + w * (aT[8] + w * aT[10]))))); + s2 = w * (aT[1] + w * (aT[3] + w * (aT[5] + w * (aT[7] + w * aT[9])))); + if (id < 0) + return x - x * (s1 + s2); + else { + z = atanhi[id] - ((x * (s1 + s2) - atanlo[id]) - x); + return (hx < 0) ? -z : z; + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c new file mode 100644 index 000000000..08f180a42 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c @@ -0,0 +1,90 @@ + +/* @(#)s_ceil.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * ceil(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to ceil(x). + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double huge = 1.0e300; +#else +static double huge = 1.0e300; +#endif + +#ifdef __STDC__ +double ceil(double x) +#else +double ceil(x) double x; +#endif +{ + int i0, i1, j0; + unsigned i, j; + i0 = __HI(x); + i1 = __LO(x); + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; + if (j0 < 20) { + if (j0 < 0) { /* raise inexact if x != 0 */ + if (huge + x > 0.0) { /* return 0*sign(x) if |x|<1 */ + if (i0 < 0) { + i0 = 0x80000000; + i1 = 0; + } else if ((i0 | i1) != 0) { + i0 = 0x3ff00000; + i1 = 0; + } + } + } else { + i = (0x000fffff) >> j0; + if (((i0 & i) | i1) == 0) + return x; /* x is integral */ + if (huge + x > 0.0) { /* raise inexact flag */ + if (i0 > 0) + i0 += (0x00100000) >> j0; + i0 &= (~i); + i1 = 0; + } + } + } else if (j0 > 51) { + if (j0 == 0x400) + return x + x; /* inf or NaN */ + else + return x; /* x is integral */ + } else { + i = ((unsigned)(0xffffffff)) >> (j0 - 20); + if ((i1 & i) == 0) + return x; /* x is integral */ + if (huge + x > 0.0) { /* raise inexact flag */ + if (i0 > 0) { + if (j0 == 20) + i0 += 1; + else { + j = i1 + (1 << (52 - j0)); + if (j < i1) + i0 += 1; /* got a carry */ + i1 = j; + } + } + i1 &= (~i); + } + } + __HI(x) = i0; + __LO(x) = i1; + return x; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c new file mode 100644 index 000000000..8476b36e1 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c @@ -0,0 +1,30 @@ + +/* @(#)s_copysign.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * copysign(double x, double y) + * copysign(x,y) returns a value with the magnitude of x and + * with the sign bit of y. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +double copysign(double x, double y) +#else +double copysign(x, y) double x, y; +#endif +{ + __HI(x) = (__HI(x) & 0x7fffffff) | (__HI(y) & 0x80000000); + return x; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c new file mode 100644 index 000000000..f1b3111d9 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c @@ -0,0 +1,82 @@ + +/* @(#)s_cos.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* cos(x) + * Return cosine function of x. + * + * kernel function: + * __kernel_sin ... sine function on [-pi/4,pi/4] + * __kernel_cos ... cosine function on [-pi/4,pi/4] + * __ieee754_rem_pio2 ... argument reduction routine + * + * Method. + * Let S,C and T denote the sin, cos and tan respectively on + * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 + * in [-pi/4 , +pi/4], and let n = k mod 4. + * We have + * + * n sin(x) cos(x) tan(x) + * ---------------------------------------------------------- + * 0 S C T + * 1 C -S -1/T + * 2 -S -C T + * 3 -C S -1/T + * ---------------------------------------------------------- + * + * Special cases: + * Let trig be any of sin, cos, or tan. + * trig(+-INF) is NaN, with signals; + * trig(NaN) is that NaN; + * + * Accuracy: + * TRIG(x) returns trig(x) nearly rounded + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +double cos(double x) +#else +double cos(x) double x; +#endif +{ + double y[2], z = 0.0; + int n, ix; + + /* High word of x. */ + ix = __HI(x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if (ix <= 0x3fe921fb) + return __kernel_cos(x, z); + + /* cos(Inf or NaN) is NaN */ + else if (ix >= 0x7ff00000) + return x - x; + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2(x, y); + switch (n & 3) { + case 0: + return __kernel_cos(y[0], y[1]); + case 1: + return -__kernel_sin(y[0], y[1], 1); + case 2: + return -__kernel_cos(y[0], y[1]); + default: + return __kernel_sin(y[0], y[1], 1); + } + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c new file mode 100644 index 000000000..b0198e3b3 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c @@ -0,0 +1,89 @@ + +/* @(#)s_floor.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * floor(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to floor(x). + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double huge = 1.0e300; +#else +static double huge = 1.0e300; +#endif + +#ifdef __STDC__ +double floor(double x) +#else +double floor(x) double x; +#endif +{ + int i0, i1, j0; + unsigned i, j; + i0 = __HI(x); + i1 = __LO(x); + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; + if (j0 < 20) { + if (j0 < 0) { /* raise inexact if x != 0 */ + if (huge + x > 0.0) { /* return 0*sign(x) if |x|<1 */ + if (i0 >= 0) { + i0 = i1 = 0; + } else if (((i0 & 0x7fffffff) | i1) != 0) { + i0 = 0xbff00000; + i1 = 0; + } + } + } else { + i = (0x000fffff) >> j0; + if (((i0 & i) | i1) == 0) + return x; /* x is integral */ + if (huge + x > 0.0) { /* raise inexact flag */ + if (i0 < 0) + i0 += (0x00100000) >> j0; + i0 &= (~i); + i1 = 0; + } + } + } else if (j0 > 51) { + if (j0 == 0x400) + return x + x; /* inf or NaN */ + else + return x; /* x is integral */ + } else { + i = ((unsigned)(0xffffffff)) >> (j0 - 20); + if ((i1 & i) == 0) + return x; /* x is integral */ + if (huge + x > 0.0) { /* raise inexact flag */ + if (i0 < 0) { + if (j0 == 20) + i0 += 1; + else { + j = i1 + (1 << (52 - j0)); + if (j < i1) + i0 += 1; /* got a carry */ + i1 = j; + } + } + i1 &= (~i); + } + } + __HI(x) = i0; + __LO(x) = i1; + return x; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c new file mode 100644 index 000000000..c91b7d9ea --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c @@ -0,0 +1,58 @@ + +/* @(#)s_frexp.c 1.4 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * for non-zero x + * x = frexp(arg,&exp); + * return a double fp quantity x such that 0.5 <= |x| <1.0 + * and the corresponding binary exponent "exp". That is + * arg = x*2^exp. + * If arg is inf, 0.0, or NaN, then frexp(arg,&exp) returns arg + * with *exp=0. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif + two54 + = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */ + +#ifdef __STDC__ +double frexp(double x, int* eptr) +#else +double frexp(x, eptr) double x; +int* eptr; +#endif +{ + int hx, ix, lx; + hx = __HI(x); + ix = 0x7fffffff & hx; + lx = __LO(x); + *eptr = 0; + if (ix >= 0x7ff00000 || ((ix | lx) == 0)) + return x; /* 0,inf,nan */ + if (ix < 0x00100000) { /* subnormal */ + x *= two54; + hx = __HI(x); + ix = hx & 0x7fffffff; + *eptr = -54; + } + *eptr += (ix >> 20) - 1022; + hx = (hx & 0x800fffff) | 0x3fe00000; + __HI(x) = hx; + return x; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c new file mode 100644 index 000000000..74609e3fd --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c @@ -0,0 +1,63 @@ +#ifndef _No_Floating_Point +/* @(#)s_ldexp.c 1.2 95/01/04 */ +/* $Id: s_ldexp.c,v 1.3.14.1 2002/01/31 15:24:14 ceciliar Exp $ */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h" /* for isfinite macro */ +static const double + + two54 + = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ + twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ + big = 1.0e+300, tiny = 1.0e-300; + +double ldexp(double x, int n) +{ + s32 k, hx, lx; /*- cc 020130 -*/ + if (!isfinite(x) || x == 0.0) + return x; + + hx = __HI(x); + lx = __LO(x); + k = (hx & 0x7ff00000) >> 20; /* extract exponent */ + if (k == 0) { /* 0 or subnormal x */ + if ((lx | (hx & 0x7fffffff)) == 0) + return x; /* +-0 */ + x *= two54; + hx = __HI(x); + k = ((hx & 0x7ff00000) >> 20) - 54; + if (n < -50000) + return tiny * x; /*underflow*/ + } + if (k == 0x7ff) + return x + x; /* NaN or Inf */ + k = k + n; + if (k > 0x7fe) + return big * copysign(big, x); /* overflow */ + if (k > 0) /* normal result */ + { + __HI(x) = (hx & 0x800fffff) | (k << 20); + return x; + } + if (k <= -54) + if (n > 50000) /* in case integer overflow in n+k */ + return big * copysign(big, x); /*overflow*/ + else + return tiny * copysign(tiny, x); /*underflow*/ + k += 54; /* subnormal result */ + __HI(x) = (hx & 0x800fffff) | (k << 20); + return x * twom54; +} + +/* changed __finite to __isfinite to match new naming convention 141097 bds */ +#endif /* _No_Floating_Point */ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c new file mode 100644 index 000000000..0c4e40137 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c @@ -0,0 +1,79 @@ + +/* @(#)s_modf.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * modf(double x, double *iptr) + * return fraction part of x, and return x's integral part in *iptr. + * Method: + * Bit twiddling. + * + * Exception: + * No exception. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double one = 1.0; +#else +static double one = 1.0; +#endif + +#ifdef __STDC__ +double modf(double x, double* iptr) +#else +double modf(x, iptr) double x, *iptr; +#endif +{ + int i0, i1, j0; + unsigned i; + i0 = __HI(x); /* high x */ + i1 = __LO(x); /* low x */ + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; /* exponent of x */ + if (j0 < 20) { /* integer part in high x */ + if (j0 < 0) { /* |x|<1 */ + __HIp(iptr) = i0 & 0x80000000; + __LOp(iptr) = 0; /* *iptr = +-0 */ + return x; + } else { + i = (0x000fffff) >> j0; + if (((i0 & i) | i1) == 0) { /* x is integral */ + *iptr = x; + __HI(x) &= 0x80000000; + __LO(x) = 0; /* return +-0 */ + return x; + } else { + __HIp(iptr) = i0 & (~i); + __LOp(iptr) = 0; + return x - *iptr; + } + } + } else if (j0 > 51) { /* no fraction part */ + *iptr = x * one; + __HI(x) &= 0x80000000; + __LO(x) = 0; /* return +-0 */ + return x; + } else { /* fraction part in low x */ + i = ((unsigned)(0xffffffff)) >> (j0 - 20); + if ((i1 & i) == 0) { /* x is integral */ + *iptr = x; + __HI(x) &= 0x80000000; + __LO(x) = 0; /* return +-0 */ + return x; + } else { + __HIp(iptr) = i0; + __LOp(iptr) = i1 & (~i); + return x - *iptr; + } + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c new file mode 100644 index 000000000..af4273ad2 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c @@ -0,0 +1,82 @@ + +/* @(#)s_sin.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* sin(x) + * Return sine function of x. + * + * kernel function: + * __kernel_sin ... sine function on [-pi/4,pi/4] + * __kernel_cos ... cose function on [-pi/4,pi/4] + * __ieee754_rem_pio2 ... argument reduction routine + * + * Method. + * Let S,C and T denote the sin, cos and tan respectively on + * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 + * in [-pi/4 , +pi/4], and let n = k mod 4. + * We have + * + * n sin(x) cos(x) tan(x) + * ---------------------------------------------------------- + * 0 S C T + * 1 C -S -1/T + * 2 -S -C T + * 3 -C S -1/T + * ---------------------------------------------------------- + * + * Special cases: + * Let trig be any of sin, cos, or tan. + * trig(+-INF) is NaN, with signals; + * trig(NaN) is that NaN; + * + * Accuracy: + * TRIG(x) returns trig(x) nearly rounded + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +double sin(double x) +#else +double sin(x) double x; +#endif +{ + double y[2], z = 0.0; + int n, ix; + + /* High word of x. */ + ix = __HI(x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if (ix <= 0x3fe921fb) + return __kernel_sin(x, z, 0); + + /* sin(Inf or NaN) is NaN */ + else if (ix >= 0x7ff00000) + return x - x; + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2(x, y); + switch (n & 3) { + case 0: + return __kernel_sin(y[0], y[1], 1); + case 1: + return __kernel_cos(y[0], y[1]); + case 2: + return -__kernel_sin(y[0], y[1], 1); + default: + return -__kernel_cos(y[0], y[1]); + } + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c new file mode 100644 index 000000000..a2feba55f --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c @@ -0,0 +1,73 @@ + +/* @(#)s_tan.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* tan(x) + * Return tangent function of x. + * + * kernel function: + * __kernel_tan ... tangent function on [-pi/4,pi/4] + * __ieee754_rem_pio2 ... argument reduction routine + * + * Method. + * Let S,C and T denote the sin, cos and tan respectively on + * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 + * in [-pi/4 , +pi/4], and let n = k mod 4. + * We have + * + * n sin(x) cos(x) tan(x) + * ---------------------------------------------------------- + * 0 S C T + * 1 C -S -1/T + * 2 -S -C T + * 3 -C S -1/T + * ---------------------------------------------------------- + * + * Special cases: + * Let trig be any of sin, cos, or tan. + * trig(+-INF) is NaN, with signals; + * trig(NaN) is that NaN; + * + * Accuracy: + * TRIG(x) returns trig(x) nearly rounded + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +double tan(double x) +#else +double tan(x) double x; +#endif +{ + double y[2], z = 0.0; + int n, ix; + + /* High word of x. */ + ix = __HI(x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if (ix <= 0x3fe921fb) + return __kernel_tan(x, z, 1); + + /* tan(Inf or NaN) is NaN */ + else if (ix >= 0x7ff00000) + return x - x; /* NaN */ + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2(x, y); + return __kernel_tan(y[0], y[1], 1 - ((n & 1) << 1)); /* 1 -- n even + -1 -- n odd */ + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c new file mode 100644 index 000000000..7f229356d --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c @@ -0,0 +1,15 @@ +extern double __ieee754_asin(); + +double asin(double __x) { return (double)__ieee754_asin(); } + +/* +.loc_0x0: + stwu r1, -0x10(r1) + mflr r0 + stw r0, 0x14(r1) + bl -0x35C8 + lwz r0, 0x14(r1) + mtlr r0 + addi r1, r1, 0x10 + blr +*/ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c new file mode 100644 index 000000000..b87b4a81d --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c @@ -0,0 +1,15 @@ +extern double __ieee754_atan2(); + +double atan2(double __x, double __y) { return (double)__ieee754_atan2(); } + +/* +.loc_0x0: + stwu r1, -0x10(r1) + mflr r0 + stw r0, 0x14(r1) + bl -0x33B0 + lwz r0, 0x14(r1) + mtlr r0 + addi r1, r1, 0x10 + blr +*/ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c new file mode 100644 index 000000000..bfd7e50f9 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c @@ -0,0 +1,15 @@ +extern double __ieee754_exp(); + +double exp(double __x) { return (double)__ieee754_exp(); } + +/* +.loc_0x0: + stwu r1, -0x10(r1) + mflr r0 + stw r0, 0x14(r1) + bl -0x3140 + lwz r0, 0x14(r1) + mtlr r0 + addi r1, r1, 0x10 + blr +*/ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c new file mode 100644 index 000000000..c51a18dc2 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c @@ -0,0 +1,15 @@ +extern double __ieee754_fmod(); + +double fmod(double __x, double __y) { return (double)__ieee754_fmod(); } + +/* +.loc_0x0: + stwu r1, -0x10(r1) + mflr r0 + stw r0, 0x14(r1) + bl -0x2F3C + lwz r0, 0x14(r1) + mtlr r0 + addi r1, r1, 0x10 + blr +*/ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log10.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log10.c new file mode 100644 index 000000000..62495bbd1 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log10.c @@ -0,0 +1,15 @@ +extern double __ieee754_log10(); + +double log10(double __x) { return (double)__ieee754_log10(); } + +/* +.loc_0x0: + stwu r1, -0x10(r1) + mflr r0 + stw r0, 0x14(r1) + bl -0x29A4 + lwz r0, 0x14(r1) + mtlr r0 + addi r1, r1, 0x10 + blr +*/ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c new file mode 100644 index 000000000..4454adb97 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c @@ -0,0 +1,15 @@ +extern double __ieee754_pow(); + +double pow(double __x, double __y) { return (double)__ieee754_pow(); } + +/* +.loc_0x0: + stwu r1, -0x10(r1) + mflr r0 + stw r0, 0x14(r1) + bl -0x28B4 + lwz r0, 0x14(r1) + mtlr r0 + addi r1, r1, 0x10 + blr +*/ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_sqrt.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_sqrt.c new file mode 100644 index 000000000..909f7cb51 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_sqrt.c @@ -0,0 +1,15 @@ +extern double __ieee754_sqrt(); + +double sqrt(double __x) { return (double)__ieee754_sqrt(); } + +/* +.loc_0x0: + stwu r1, -0x10(r1) + mflr r0 + stw r0, 0x14(r1) + bl -0x29C + lwz r0, 0x14(r1) + mtlr r0 + addi r1, r1, 0x10 + blr +*/ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/ansi_fp.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/ansi_fp.c new file mode 100644 index 000000000..1cb1d9c57 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/ansi_fp.c @@ -0,0 +1,779 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_fp.h" +#include "ctype.h" +#include "limits.h" + +static int __count_trailing_zerol(unsigned long x) +{ + int result = 0; + int bits_not_checked = sizeof(unsigned long) * CHAR_BIT; + int n = bits_not_checked / 2; + int mask_size = n; + unsigned long mask = (~0UL) >> (bits_not_checked - n); + + while (bits_not_checked) { + if (!(x & mask)) { + result += mask_size; + x >>= mask_size; + bits_not_checked -= mask_size; + } else if (mask == 1) { + break; + } + + if (n > 1) { + n /= 2; + } + + if (mask > 1) { + mask >>= n; + mask_size -= n; + } + } + return result; +} + +static int __count_trailing_zero(double x) +{ + unsigned long* l = (unsigned long*)&x; + + if (l[1] != 0) { + return __count_trailing_zerol(l[1]); + } + + return (int)(sizeof(unsigned long) * CHAR_BIT + __count_trailing_zerol(l[0] | 0x00100000)); +} + +static int __must_round(const decimal* d, int digits) +{ + u8 const* i = d->sig.text + digits; + + if (*i > 5) { + return 1; + } + + if (*i < 5) { + return -1; + } + + { + u8 const* e = d->sig.text + d->sig.length; + + for (i++; i < e; i++) { + if (*i != 0) { + return 1; + } + } + } + + if (d->sig.text[digits - 1] & 1) { + return 1; + } + + return -1; +} + +static void __dorounddecup(decimal* d, int digits) +{ + u8* b = d->sig.text; + u8* i = b + digits - 1; + + while (1) { + if (*i < 9) { + *i += 1; + break; + } + if (i == b) { + *i = 1; + d->exp++; + break; + } + *i-- = 0; + } +} + +static void __rounddec(decimal* d, int digits) +{ + int unkBool; + if (digits <= 0 || digits >= d->sig.length) + return; + + unkBool = __must_round(d, digits); + d->sig.length = digits; + + if (unkBool >= 0) { + __dorounddecup(d, digits); + } + + +} + +void __ull2dec(decimal* result, u64 val) +{ + result->sign = 0; + + if (val == 0) { + result->exp = 0; + result->sig.length = 1; + result->sig.text[0] = 0; + return; + } + + if (val < 0) { + val = -val; + result->sign = 1; + } + + result->sig.length = 0; + + for (; val != 0; val /= 10) { + result->sig.text[result->sig.length++] = (u8)(val % 10); + } + + { + u8* i = result->sig.text; + u8* j = result->sig.text + result->sig.length; + + for (; i < --j; ++i) { + u8 t = *i; + *i = *j; + *j = t; + } + } + + result->exp = result->sig.length - 1; +} + +void __timesdec(decimal* result, const decimal* x, const decimal* y) +{ + u32 accumulator = 0; + u8 mantissa[SIGDIGLEN * 2]; + int i = x->sig.length + y->sig.length - 1; + u8* pDigit; + u8* ip = mantissa + i + 1; + u8* ep = ip; + + result->sign = 0; + + for (; i > 0; i--) { + int k = y->sig.length - 1; + int j = i - k - 1; + int l; + int t; + const u8* jp; + const u8* kp; + + if (j < 0) { + j = 0; + k = i - 1; + } + + jp = x->sig.text + j; + kp = y->sig.text + k; + l = k + 1; + t = x->sig.length - j; + + if (l > t) + l = t; + + for (; l > 0; --l, ++jp, --kp) { + accumulator += *jp * *kp; + } + + *--ip = (u8)(accumulator % 10); + accumulator /= 10; + } + + result->exp = (short)(x->exp + y->exp); + + if (accumulator) { + *--ip = (u8)(accumulator); + result->exp++; + } + + for (i = 0; i < SIGDIGLEN && ip < ep; ++i, ++ip) { + result->sig.text[i] = *ip; + } + result->sig.length = (u8)(i); + + if (ip < ep && *ip >= 5) { + if (*ip == 5) { + u8* jp = ip + 1; + for (; jp < ep; jp++) { + if (*jp != 0) + goto round; + } + if ((ip[-1] & 1) == 0) + return; + } + round: + __dorounddecup(result, result->sig.length); + } +} + +void __str2dec(decimal* d, const char* s, short exp) +{ + int i; + + d->exp = exp; + d->sign = 0; + + for (i = 0; i < SIGDIGLEN && *s;) { + d->sig.text[i++] = *s++ - '0'; + } + d->sig.length = i; + + if (*s != 0) { + if (*s < 5) + return; + if (*s > 5) + goto round; + + { + const char* p = s + 1; + + for (; *p != 0; p++) { + if (*p != '0') + goto round; + } + + if ((d->sig.text[i - 1] & 1) == 0) + return; + } + round: + __dorounddecup(d, d->sig.length); + } +} + +void __two_exp(decimal* result, long exp) +{ + switch (exp) { + case -64: + __str2dec(result, "542101086242752217003726400434970855712890625", -20); + return; + case -53: + __str2dec(result, "11102230246251565404236316680908203125", -16); + return; + case -32: + __str2dec(result, "23283064365386962890625", -10); + return; + case -16: + __str2dec(result, "152587890625", -5); + return; + case -8: + __str2dec(result, "390625", -3); + return; + case -7: + __str2dec(result, "78125", -3); + return; + case -6: + __str2dec(result, "15625", -2); + return; + case -5: + __str2dec(result, "3125", -2); + return; + case -4: + __str2dec(result, "625", -2); + return; + case -3: + __str2dec(result, "125", -1); + return; + case -2: + __str2dec(result, "25", -1); + return; + case -1: + __str2dec(result, "5", -1); + return; + case 0: + __str2dec(result, "1", 0); + return; + case 1: + __str2dec(result, "2", 0); + return; + case 2: + __str2dec(result, "4", 0); + return; + case 3: + __str2dec(result, "8", 0); + return; + case 4: + __str2dec(result, "16", 1); + return; + case 5: + __str2dec(result, "32", 1); + return; + case 6: + __str2dec(result, "64", 1); + return; + case 7: + __str2dec(result, "128", 2); + return; + case 8: + __str2dec(result, "256", 2); + return; + } + + { + decimal x2, temp; + + __two_exp(&x2, exp / 2); + __timesdec(result, &x2, &x2); + + if (exp & 1) { + temp = *result; + if (exp > 0) { + __str2dec(&x2, "2", 0); + } else { + __str2dec(&x2, "5", -1); + } + __timesdec(result, &temp, &x2); + } + } +} + +BOOL __equals_dec(const decimal* x, const decimal* y) +{ + if (x->sig.text[0] == 0) { + if (y->sig.text[0] == 0) + return TRUE; + return FALSE; + } + if (y->sig.text[0] == 0) { + if (x->sig.text[0] == 0) + return TRUE; + return FALSE; + } + + if (x->exp == y->exp) { + int i; + int l = x->sig.length; + + if (l > y->sig.length) { + l = y->sig.length; + } + + for (i = 0; i < l; i++) { + if (x->sig.text[i] != y->sig.text[i]) { + return FALSE; + } + } + + if (l == x->sig.length) { + for (; i < y->sig.length; ++i) { + if (y->sig.text[i] != 0) { + return FALSE; + } + } + } else { + for (; i < x->sig.length; ++i) { + if (x->sig.text[i] != 0) { + return FALSE; + } + } + } + + return TRUE; + } + return FALSE; +} + +BOOL __less_dec(const decimal* x, const decimal* y) +{ + if (x->sig.text[0] == 0) { + if (y->sig.text[0] != 0) + return TRUE; + return FALSE; + } + + if (y->sig.text[0] == 0) { + return FALSE; + } + + if (x->exp == y->exp) { + int i; + int l = x->sig.length; + + if (l > y->sig.length) { + l = y->sig.length; + } + + for (i = 0; i < l; i++) { + if (x->sig.text[i] < y->sig.text[i]) { + return TRUE; + } else if (y->sig.text[i] < x->sig.text[i]) { + return FALSE; + } + } + + if (l == x->sig.length) { + for (; i < y->sig.length; i++) { + if (y->sig.text[i] != 0) { + return TRUE; + } + } + } + return FALSE; + } + + return x->exp < y->exp; +} + +void __minus_dec(decimal* z, const decimal* x, const decimal* y) +{ + int zlen, dexp; + u8 *ib, *i, *ie; + u8 const *jb, *j, *jn; + + *z = *x; + + if (y->sig.text[0] == 0) + return; + + zlen = z->sig.length; + if (zlen < y->sig.length) + zlen = y->sig.length; + + dexp = z->exp - y->exp; + zlen += dexp; + + if (zlen > SIGDIGLEN) + zlen = SIGDIGLEN; + + while (z->sig.length < zlen) { + z->sig.text[z->sig.length++] = 0; + } + + ib = z->sig.text; + i = ib + zlen; + + if (y->sig.length + dexp < zlen) { + i = ib + (y->sig.length + dexp); + } + + jb = y->sig.text; + j = jb + (i - ib - dexp); + jn = j; + + while (i > ib && j > jb) { + i--; + j--; + if (*i < *j) { + u8* k = i - 1; + while (*k == 0) + k--; + while (k != i) { + --*k; + *++k += 10; + } + } + *i -= *j; + } + + if (jn - jb < y->sig.length) { + BOOL round_down = FALSE; + if (*jn < 5) + round_down = TRUE; + else if (*jn == 5) { + u8 const* ibPtr = y->sig.text + y->sig.length; + + for (j = jn + 1; j < ibPtr; j++) { + if (*j != 0) + goto done; + } + i = ib + (jn - jb) + dexp - 1; + if (*i & 1) + round_down = 1; + } + if (round_down) { + if (*i < 1) { + u8* k = i - 1; + while (*k == 0) + k--; + while (k != i) { + --*k; + *++k += 10; + } + } + *i -= 1; + } + } +done: + for (i = ib; *i == 0; ++i) { } + + if (i > ib) { + u8 dl = (u8)(i - ib); + z->exp -= dl; + ie = ib + z->sig.length; + for (; i < ie; ++i, ++ib) + *ib = *i; + z->sig.length -= dl; + } + + ib = z->sig.text; + for (i = ib + z->sig.length; i > ib;) { + i--; + if (*i != 0) + break; + } + z->sig.length = (u8)(i - ib + 1); +} + +void __num2dec_internal(decimal* d, double x) +{ + s8 sign = (s8)(signbit(x) != 0); + + if (x == 0) { + d->sign = sign; + d->exp = 0; + d->sig.length = 1; + d->sig.text[0] = 0; + return; + } + + if (!isfinite(x)) { + d->sign = sign; + d->exp = 0; + d->sig.length = 1; + d->sig.text[0] = fpclassify(x) == 1 ? 'N' : 'I'; + return; + } + + if (sign != 0) { + x = -x; + } + + { + int exp; + double frac = frexp(x, &exp); + long num_bits_extract = DBL_MANT_DIG - __count_trailing_zero(frac); + double integer; + decimal int_d, pow2_d; + + __two_exp(&pow2_d, exp - num_bits_extract); + frac = modf(ldexp(frac, num_bits_extract), &integer); + __ull2dec(&int_d, (u64)integer); + __timesdec(d, &int_d, &pow2_d); + d->sign = sign; + } +} + +void __num2dec(const decform* form, double x, decimal* d) +{ + short digits = form->digits; + int i; + __num2dec_internal(d, x); + + if (d->sig.text[0] > 9) { + return; + } + + if (digits > SIGDIGLEN) { + digits = SIGDIGLEN; + } + + __rounddec(d, digits); + + while (d->sig.length < digits) { + d->sig.text[d->sig.length++] = 0; + } + + d->exp -= d->sig.length - 1; + + for (i = 0; i < d->sig.length; i++) { + d->sig.text[i] += '0'; + } +} + +double __dec2num(const decimal* d) +{ + if (d->sig.length <= 0) { + return copysign(0.0, d->sign == 0 ? 1.0 : -1.0); + } + + switch (d->sig.text[0]) { + case '0': + return copysign(0.0, d->sign == 0 ? 1.0 : -1.0); + case 'I': + return copysign((double)INFINITY, d->sign == 0 ? 1.0 : -1.0); + case 'N': { + double result; + u64* ll = (u64*)&result; + + *ll = 0x7FF0000000000000; + if (d->sign) + *ll |= 0x8000000000000000; + + if (d->sig.length == 1) + *ll |= 0x8000000000000; + else { + unsigned char* p = (unsigned char*)&result + 1; + int placed_non_zero = 0; + int low = 1; + int i; + int e = d->sig.length; + if (e > 14) + e = 14; + + for (i = 1; i < e; ++i) { + unsigned char c = d->sig.text[i]; + + if (isdigit(c)) { + c -= '0'; + } else { + c = (unsigned char)(tolower(c) - 'a' + 10); + } + + if (c != 0) { + placed_non_zero = 1; + } + + if (low) { + *p++ |= c; + } else { + *p = (unsigned char)(c << 4); + } + + low = !low; + } + + if (!placed_non_zero) { + *ll |= 0x0008000000000000; + } + } + + return result; + } + } + + { + static double pow_10[8] = { 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8 }; + + decimal dec = *d; + u8* i = dec.sig.text; + u8* e = i + dec.sig.length; + double first_guess; + int exponent; + + for (; i < e; ++i) + *i -= '0'; + dec.exp += dec.sig.length - 1; + exponent = dec.exp; + + i = dec.sig.text; + first_guess = *i++; + + while (i < e) { + u32 ival = 0; + int j; + double temp1, temp2; + int ndig = (int)(e - i) % 8; + + if (ndig == 0) + ndig = 8; + + for (j = 0; j < ndig; ++j, ++i) { + ival = ival * 10 + *i; + } + + temp1 = first_guess * pow_10[ndig - 1]; + temp2 = temp1 + ival; + + if (ival != 0 && temp1 == temp2) + break; + + first_guess = temp2; + exponent -= ndig; + } + + if (exponent < 0) { + first_guess /= pow(5.0, -exponent); + } else { + first_guess *= pow(5.0, exponent); + } + + first_guess = ldexp(first_guess, exponent); + + if (isinf(first_guess)) { + decimal max; + __str2dec(&max, "179769313486231580793729011405303420", 308); + if (__less_dec(&max, &dec)) + goto done; + first_guess = DBL_MAX; + } + + { + decimal feedback1; + + __num2dec_internal(&feedback1, first_guess); + + if (__equals_dec(&feedback1, &dec)) { + goto done; + } + + if (__less_dec(&feedback1, &dec)) { + + decimal feedback2, difflow, diffhigh; + double next_guess = first_guess; + u64* ull = (u64*)&next_guess; + ++*ull; + + if (isinf(next_guess)) { + first_guess = next_guess; + goto done; + } + + __num2dec_internal(&feedback2, next_guess); + + while (__less_dec(&feedback2, &dec)) { + feedback1 = feedback2; + first_guess = next_guess; + ++*ull; + if (isinf(next_guess)) { + first_guess = next_guess; + goto done; + } + __num2dec_internal(&feedback2, next_guess); + } + + __minus_dec(&difflow, &dec, &feedback1); + __minus_dec(&diffhigh, &feedback2, &dec); + + if (__equals_dec(&difflow, &diffhigh)) { + if (*(u64*)&first_guess & 1) { + first_guess = next_guess; + } + } else if (!__less_dec(&difflow, &diffhigh)) { + first_guess = next_guess; + } + } else { + decimal feedback2, difflow, diffhigh; + double next_guess = first_guess; + unsigned long long* ull = (unsigned long long*)&next_guess; + --*ull; + + __num2dec_internal(&feedback2, next_guess); + + while (__less_dec(&dec, &feedback2)) { + feedback1 = feedback2; + first_guess = next_guess; + --*ull; + __num2dec_internal(&feedback2, next_guess); + } + + __minus_dec(&difflow, &dec, &feedback2); + __minus_dec(&diffhigh, &feedback1, &dec); + + if (__equals_dec(&difflow, &diffhigh)) { + if (*(unsigned long long*)&first_guess & 1) { + first_guess = next_guess; + } + } else if (__less_dec(&difflow, &diffhigh)) { + first_guess = next_guess; + } + } + } + done: + if (dec.sign) { + first_guess = -first_guess; + } + return first_guess; + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c new file mode 100644 index 000000000..9d427a732 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c @@ -0,0 +1,57 @@ +#include "types.h" + +s32 InitializeUART(u32); /* extern */ +s32 OSGetConsoleType(); /* extern */ +s32 WriteUARTN(s32, s32); /* extern */ +s32 __TRK_write_console(s32, s32, s32*, s32); /* extern */ + +BOOL __write_console(s32 arg0, s32 arg1, s32* arg2, s32 arg3) +{ + + if ((OSGetConsoleType() & 0x20000000) == 0) { + if (__init_uart_console() != 0) { + return TRUE; + } + if (WriteUARTN(arg1, *arg2) != 0) { + *arg2 = 0; + return TRUE; + } + } + __TRK_write_console(arg0, arg1, arg2, arg3); + return FALSE; +} + +int __close_console() +{ + return 0; +} + +int __init_uart_console(void) +{ + static BOOL initialized; + int ret = 0; + + if (initialized == 0) { + ret = InitializeUART(0xE100); + if (ret == 0) { + initialized = 1; + } + } + + return ret; +} + +void __delete_file(void) +{ + // UNUSED FUNCTION +} + +void __rename_file(void) +{ + // UNUSED FUNCTION +} + +void __temp_file_name(void) +{ + // UNUSED FUNCTION +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/abort_exit.c b/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/abort_exit.c new file mode 100644 index 000000000..634c65d93 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/abort_exit.c @@ -0,0 +1,70 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/signal.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/abort_exit.h" + +void __destroy_global_chain(void); +void _ExitProcess(void); + +extern void (*_dtors[])(void); + +static void (*__console_exit)(void); +void (*__stdio_exit)(void); +static int __atexit_curr_func; +int __aborting; + +static void (*__atexit_funcs[64])(void); + +void abort(void) +{ + raise(1); + __aborting = 1; + exit(1); +} + +void atexit(void) +{ + // UNUSED FUNCTION +} + +void __atexit(void) +{ + // UNUSED FUNCTION +} + +void exit(int status) +{ + int i; + void (**dtor)(void); + + if (!__aborting) { + __begin_critical_region(atexit_funcs_access); + __end_critical_region(atexit_funcs_access); + __destroy_global_chain(); + dtor = _dtors; + while (*dtor != NULL) { + (*dtor)(); + dtor++; + } + if (__stdio_exit != NULL) { + __stdio_exit(); + __stdio_exit = NULL; + } + } + __exit(status); +} + +void __exit(int status) +{ + __begin_critical_region(atexit_funcs_access); + while (__atexit_curr_func > 0) + __atexit_funcs[--__atexit_curr_func](); + __end_critical_region(atexit_funcs_access); + __kill_critical_regions(); + if (__console_exit != NULL) + { + + __console_exit(); + __console_exit = NULL; + } + _ExitProcess(); +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/critical_regions.gamecube.c b/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/critical_regions.gamecube.c new file mode 100644 index 000000000..9cbd811b7 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/critical_regions.gamecube.c @@ -0,0 +1,10 @@ +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" + +void __init_critical_regions(void) { return; } + +void __kill_critical_regions(void) { return; } + +void __begin_critical_region(int region) { return; } + +void __end_critical_region(int region) { return; } diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/math_ppc.c b/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/math_ppc.c new file mode 100644 index 000000000..ae9047d99 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/math_ppc.c @@ -0,0 +1,520 @@ +#define MATH_INLINE +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h" +#include "fdlibm.h" + +// Generated via math_api.h +// int __fpclassifyf(float x); + +// Generated via math_api.h +// int __fpclassifyd(double x); + +/*double scalbn(double x, int y) +{ + // UNUSED FUNCTION +} + +void scalbln(void) +{ + // UNUSED FUNCTION +} + +void acosl(void) +{ + // UNUSED FUNCTION +} + +void asinl(void) +{ + // UNUSED FUNCTION +} + +void atanl(void) +{ + // UNUSED FUNCTION +} + +void atan2l(void) +{ + // UNUSED FUNCTION +} + +void cosl(void) +{ + // UNUSED FUNCTION +} + +void sinl(void) +{ + // UNUSED FUNCTION +} + +void tanl(void) +{ + // UNUSED FUNCTION +} + +void coshl(void) +{ + // UNUSED FUNCTION +} + +void sinhl(void) +{ + // UNUSED FUNCTION +} + +void tanhl(void) +{ + // UNUSED FUNCTION +} + +void acoshl(void) +{ + // UNUSED FUNCTION +} + +void asinhl(void) +{ + // UNUSED FUNCTION +} + +void atanhl(void) +{ + // UNUSED FUNCTION +} + +void expl(void) +{ + // UNUSED FUNCTION +} + +void frexpl(void) +{ + // UNUSED FUNCTION +} + +void ldexpl(void) +{ + // UNUSED FUNCTION +} + +void logl(void) +{ + // UNUSED FUNCTION +} + +void log10l(void) +{ + // UNUSED FUNCTION +} + +void modfl(void) +{ + // UNUSED FUNCTION +} + +void exp2l(void) +{ + // UNUSED FUNCTION +} + +void expm1l(void) +{ + // UNUSED FUNCTION +} + +void log1pl(void) +{ + // UNUSED FUNCTION +} + +void log2l(void) +{ + // UNUSED FUNCTION +} + +void logbl(void) +{ + // UNUSED FUNCTION +} + +void scalbnl(void) +{ + // UNUSED FUNCTION +} + +void scalblnl(void) +{ + // UNUSED FUNCTION +} + +void fabsl(void) +{ + // UNUSED FUNCTION +} + +void powl(void) +{ + // UNUSED FUNCTION +} + +void sqrtl(void) +{ + // UNUSED FUNCTION +} + +void hypotl(void) +{ + // UNUSED FUNCTION +} + +void erfl(void) +{ + // UNUSED FUNCTION +} + +void erfcl(void) +{ + // UNUSED FUNCTION +} + +void gammal(void) +{ + // UNUSED FUNCTION +} + +void lgammal(void) +{ + // UNUSED FUNCTION +} + +void nextafterl(void) +{ + // UNUSED FUNCTION +} + +void ceill(void) +{ + // UNUSED FUNCTION +} + +void floorl(void) +{ + // UNUSED FUNCTION +} + +void nearbyintl(void) +{ + // UNUSED FUNCTION +} + +void rintl(void) +{ + // UNUSED FUNCTION +} + +void lrintl(void) +{ + // UNUSED FUNCTION +} + +void llrintl(void) +{ + // UNUSED FUNCTION +} + +void truncl(void) +{ + // UNUSED FUNCTION +} + +void fmodl(void) +{ + // UNUSED FUNCTION +} + +void remainderl(void) +{ + // UNUSED FUNCTION +} + +void copysignl(void) +{ + // UNUSED FUNCTION +} + +void remquol(void) +{ + // UNUSED FUNCTION +} + +void fdiml(void) +{ + // UNUSED FUNCTION +} + +void fmaxl(void) +{ + // UNUSED FUNCTION +} + +void fminl(void) +{ + // UNUSED FUNCTION +} + +void acosf(void) +{ + // UNUSED FUNCTION +} + +void asinf(void) +{ + // UNUSED FUNCTION +} + +void atanf(void) +{ + // UNUSED FUNCTION +} + +void atan2f(void) +{ + // UNUSED FUNCTION +}*/ + + +/*void coshf(void) +{ + // UNUSED FUNCTION +} + +void sinhf(void) +{ + // UNUSED FUNCTION +} + +void tanhf(void) +{ + // UNUSED FUNCTION +} + +void expf(void) +{ + // UNUSED FUNCTION +} + +void frexpf(void) +{ + // UNUSED FUNCTION +} + +void ldexpf(void) +{ + // UNUSED FUNCTION +} + +void logf(void) +{ + // UNUSED FUNCTION +} + +void log10f(void) +{ + // UNUSED FUNCTION +} + +void fabsf(void) +{ + // UNUSED FUNCTION +} + +void powf(void) +{ + // UNUSED FUNCTION +} + +void ceilf(void) +{ + // UNUSED FUNCTION +} + +void floorf(void) +{ + // UNUSED FUNCTION +} + +void fmodf(void) +{ + // UNUSED FUNCTION +} + +void log2f(void) +{ + // UNUSED FUNCTION +} + +void sqrtf(void) +{ + // UNUSED FUNCTION +} + +void _inv_sqrtf(void) +{ + // UNUSED FUNCTION +}*/ + +/*extern inline double fabs(double x) +{ + return __fabs(x); +}*/ + +/*void modff(float f1, float* fp) +{ + // UNUSED FUNCTION +} + +void acoshf(void) +{ + // UNUSED FUNCTION +} + +void asinhf(void) +{ + // UNUSED FUNCTION +} + +void atanhf(void) +{ + // UNUSED FUNCTION +} + +void exp2f(void) +{ + // UNUSED FUNCTION +} + +void expm1f(void) +{ + // UNUSED FUNCTION +} + +void log1pf(void) +{ + // UNUSED FUNCTION +} + +void logbf(void) +{ + // UNUSED FUNCTION +} + +void scalbnf(void) +{ + // UNUSED FUNCTION +} + +void scalblnf(void) +{ + // UNUSED FUNCTION +} + +void hypotf(void) +{ + // UNUSED FUNCTION +} + +void erff(void) +{ + // UNUSED FUNCTION +} + +void erfcf(void) +{ + // UNUSED FUNCTION +} + +void gammaf(void) +{ + // UNUSED FUNCTION +} + +void lgammaf(void) +{ + // UNUSED FUNCTION +} + +void nextafterf(void) +{ + // UNUSED FUNCTION +} + +void nearbyintf(void) +{ + // UNUSED FUNCTION +} + +void rintf(void) +{ + // UNUSED FUNCTION +} + +void lrintf(void) +{ + // UNUSED FUNCTION +} + +void llroundf(void) +{ + // UNUSED FUNCTION +} + +void llrintf(void) +{ + // UNUSED FUNCTION +} + +void truncf(void) +{ + // UNUSED FUNCTION +} + +void remainderf(void) +{ + // UNUSED FUNCTION +} + +void copysignf(void) +{ + // UNUSED FUNCTION +} + +void remquof(void) +{ + // UNUSED FUNCTION +} + +void fdimf(void) +{ + // UNUSED FUNCTION +} + +void fmaxf(void) +{ + // UNUSED FUNCTION +} + +void fminf(void) +{ + // UNUSED FUNCTION +} + +void log2(void) +{ + // UNUSED FUNCTION +} + +void exp2(void) +{ + // UNUSED FUNCTION +}*/ diff --git a/libs/PowerPC_EABI_Support/src/Runtime/CPlusLibPPC.cp b/libs/PowerPC_EABI_Support/src/Runtime/CPlusLibPPC.cp new file mode 100644 index 000000000..b9efdad8b --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/CPlusLibPPC.cp @@ -0,0 +1,41 @@ +#include "types.h" +extern "C"{ + +void* __copy(char *dest, char *src, size_t size) +{ + char *p; + + if (dest && size) { + p = dest; + do { + *p = *src; + ++p; + ++src; + --size; + } while (size); + } + + return(dest); +} + +void __init_arr(void) +{ + // UNUSED FUNCTION +} + +void __new_arr(void) +{ + // UNUSED FUNCTION +} + +void __del_arr(void) +{ + // UNUSED FUNCTION +} + +void __dc_arr(void) +{ + // UNUSED FUNCTION +} + +} diff --git a/libs/PowerPC_EABI_Support/src/Runtime/GCN_mem_alloc.c b/libs/PowerPC_EABI_Support/src/Runtime/GCN_mem_alloc.c new file mode 100644 index 000000000..8bd49fcdf --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/GCN_mem_alloc.c @@ -0,0 +1,36 @@ +#include "types.h" +#include "Dolphin/os.h" + +static void InitDefaultHeap() +{ + void* arenaLo; + void* arenaHi; + + OSReport("GCN_Mem_Alloc.c : InitDefaultHeap. No Heap Available\n"); + OSReport("Metrowerks CW runtime library initializing default heap\n"); + + 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); +} + +// unused +void __sys_alloc() +{ +} + +__declspec(weak) extern void __sys_free(void* ptr) +{ + if (__OSCurrHeap == -1) { + InitDefaultHeap(); + } + OSFreeToHeap(__OSCurrHeap, ptr); +} diff --git a/libs/PowerPC_EABI_Support/src/Runtime/Gecko_ExceptionPPC.cp b/libs/PowerPC_EABI_Support/src/Runtime/Gecko_ExceptionPPC.cp new file mode 100644 index 000000000..293c10010 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/Gecko_ExceptionPPC.cp @@ -0,0 +1,891 @@ +#include "PowerPC_EABI_Support/Runtime/Gecko_ExceptionPPC.h" +#include "PowerPC_EABI_Support/Runtime/MWCPlusPlusLib.h" +#include "PowerPC_EABI_Support/Runtime/NMWException.h" +#include "PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h" + + +#define RETURN_ADDRESS 4 + +union MWE_GeckoVector64 { + double d; + float f[2]; +}; + +typedef union MWE_GeckoVector64 MWE_GeckoVector64; + +struct GeckoFPRContext { + double d; + MWE_GeckoVector64 v; +}; + +typedef struct GeckoFPRContext GeckoFPRContext; + +typedef struct ThrowContext { + GeckoFPRContext FPR[32]; + long GPR[32]; + long CR; + char* SP; + char* FP; + char* throwSP; + char* returnaddr; + char* throwtype; + void* location; + void* dtor; + CatchInfo *catchinfo; +} ThrowContext; + +typedef ThrowContext* ThrowContextPtr; + +typedef struct MWExceptionInfo { + ExceptionTableSmall* exception_record; + char* current_function; + char* action_pointer; + char* code_section; + char* data_section; + char* TOC; +} MWExceptionInfo; + +typedef struct FragmentInfo { + ExceptionTableIndex* exception_start; + ExceptionTableIndex* exception_end; + char* code_start; + char* code_end; + char* data_start; + char* data_end; + char* TOC; + int active; +} FragmentInfo; + +typedef struct ProcessInfo { + __eti_init_info* exception_info; + char* TOC; + int active; +} ProcessInfo; + +typedef struct ActionIterator { + MWExceptionInfo info; + char* current_SP; + char* current_FP; + long current_R31; +} ActionIterator; + +#define MAXFRAGMENTS 32 +static ProcessInfo fragmentinfo[MAXFRAGMENTS]; + +typedef void (*DeleteFunc)(void *); + + + +//Likely a fakematch +#pragma schedule once +int __register_fragment(struct __eti_init_info* info, char* TOC){ + + ProcessInfo* f = fragmentinfo; + int i; + + for(i = 0; i < MAXFRAGMENTS; i++, f++){ + if(f->active == 0){ + f->exception_info = info; + f->TOC = TOC; + f->active = 1; + return i; + } + } + + return -1; +} +#pragma schedule twice + +void __unregister_fragment(int fragmentID){ + ProcessInfo* f; + + if(fragmentID >= 0 && fragmentID < MAXFRAGMENTS){ + f = &fragmentinfo[fragmentID]; + f->exception_info = 0; + f->TOC = 0; + f->active = 0; + } +} + +static int ExPPC_FindExceptionFragment(char* returnaddr, FragmentInfo* frag) +{ + ProcessInfo* f; + int i; + __eti_init_info* eti_info; + + for(i = 0, f = fragmentinfo; i < MAXFRAGMENTS; ++i, ++f){ + if(f->active){ + eti_info = f->exception_info; + while (1) { + if(eti_info->code_size == 0) break; + if(returnaddr >= eti_info->code_start && returnaddr < (char*)eti_info->code_start+eti_info->code_size) { + frag->exception_start = (ExceptionTableIndex*)eti_info->eti_start; + frag->exception_end = (ExceptionTableIndex*)eti_info->eti_end; + frag->code_start = 0; + frag->code_end = 0; + frag->data_start = 0; + frag->data_end = 0; + frag->TOC = f->TOC; + frag->active = f->active; + return 1; + } + eti_info++; + } + } + } + + return 0; +} + + +static void ExPPC_FindExceptionRecord(char* returnaddr, MWExceptionInfo* info){ + FragmentInfo* fragment; + FragmentInfo frag; + ExceptionTableIndex *exceptionindex,*p; + unsigned long returnoffset; + long i,m,n; + + info->exception_record=0; + info->action_pointer=0; + + if ((ExPPC_FindExceptionFragment(returnaddr, &frag)) == 0) return; + fragment = &frag; + + info->code_section = fragment->code_start; + info->data_section = fragment->data_start; + info->TOC = fragment->TOC; + + returnoffset = returnaddr-fragment->code_start; + exceptionindex = fragment->exception_start; + for(i = 0, n = fragment->exception_end-fragment->exception_start;;){ + if(i > n) return; + p = &exceptionindex[m = (i+n)/2]; + + if(returnoffset < p->functionoffset){ + n = m - 1; + }else if(returnoffset > p->functionoffset + ETI_GetFunctionSize(p->eti_field)){ + i = m + 1; + }else break; + } + info->current_function = fragment->code_start + p->functionoffset; + info->exception_record = ETI_GetDirectStore(p->eti_field) ? (ExceptionTableSmall*)(&p->exceptionoffset) : (ExceptionTableSmall*)(fragment->data_start + p->exceptionoffset); + + returnoffset -= p->functionoffset; + + if (ET_IsLargeTable(info->exception_record->et_field)){ + ExceptionTableLarge* etl = (ExceptionTableLarge*)info->exception_record; + ExceptionRangeLarge* erl; + + for(erl = etl->ranges; erl->start != 0; erl++){ + unsigned long range_end = erl->start + (erl->size * 4); + + if (erl->start <= returnoffset && range_end >= returnoffset){ + info->action_pointer = (char*)etl + erl->action; + break; + } + } + }else{ + ExceptionTableSmall* ets = (ExceptionTableSmall*)info->exception_record; + ExceptionRangeSmall* ers; + + for(ers = ets->ranges; ers->start != 0; ers++){ + if(ers->start <= returnoffset && ers->end >= returnoffset){ + info->action_pointer = (char*)ets + ers->action; + break; + } + } + + } +} + +static long ExPPC_PopR31(char *SP,MWExceptionInfo *info){ + double* FPR_save_area; + long* GPR_save_area; + int saved_GPRs, saved_FPRs; + + saved_FPRs = ET_GetSavedFPRs(info->exception_record->et_field); + FPR_save_area = (double*)(SP-saved_FPRs * 8); + saved_GPRs = ET_GetSavedGPRs(info->exception_record->et_field); + GPR_save_area = (long*)FPR_save_area; + + return GPR_save_area[-1]; +} + +static exaction_type ExPPC_CurrentAction(const ActionIterator* iter){ + if(iter->info.action_pointer == 0){ + return EXACTION_ENDOFLIST; + } + + return ((ex_destroylocal*)iter->info.action_pointer)->action & EXACTION_MASK; +} + +static exaction_type ExPPC_NextAction(ActionIterator* iter){ + exaction_type action; + + for(;;){ + if(iter->info.action_pointer == 0 || ((action = ((ex_destroylocal*)iter->info.action_pointer)->action) & EXACTION_ENDBIT) != 0){ + char* return_addr, *callers_SP; + + callers_SP = *(char**)iter->current_SP; + + if(ET_GetSavedGPRs(iter->info.exception_record->et_field)){ + iter->current_R31 = ExPPC_PopR31(callers_SP, &iter->info); + } + + return_addr = *(char**)(callers_SP + RETURN_ADDRESS); + + ExPPC_FindExceptionRecord(return_addr, &iter->info); + + if(iter->info.exception_record == 0){ + std::terminate(); + } + + iter->current_SP = callers_SP; + iter->current_FP = (ET_GetHasFramePtr(iter->info.exception_record->et_field)) ? (char*)iter->current_R31 : iter->current_SP; + + if(iter->info.action_pointer == 0) continue; + }else{ + switch(action){ + case EXACTION_DESTROYLOCAL: + iter->info.action_pointer += sizeof(ex_destroylocal); + break; + case EXACTION_DESTROYLOCALCOND: + iter->info.action_pointer += sizeof(ex_destroylocalcond); + break; + case EXACTION_DESTROYLOCALPOINTER: + iter->info.action_pointer += sizeof(ex_destroylocalpointer); + break; + case EXACTION_DESTROYLOCALARRAY: + iter->info.action_pointer += sizeof(ex_destroylocalarray); + break; + case EXACTION_DESTROYBASE: + case EXACTION_DESTROYMEMBER: + iter->info.action_pointer += sizeof(ex_destroymember); + break; + case EXACTION_DESTROYMEMBERCOND: + iter->info.action_pointer += sizeof(ex_destroymembercond); + break; + case EXACTION_DESTROYMEMBERARRAY: + iter->info.action_pointer += sizeof(ex_destroymemberarray); + break; + case EXACTION_DELETEPOINTER: + iter->info.action_pointer += sizeof(ex_deletepointer); + break; + case EXACTION_DELETEPOINTERCOND: + iter->info.action_pointer += sizeof(ex_deletepointercond); + break; + case EXACTION_CATCHBLOCK: + iter->info.action_pointer += sizeof(ex_catchblock); + break; + case EXACTION_CATCHBLOCK_32: + iter->info.action_pointer += sizeof(ex_catchblock_32); + break; + case EXACTION_ACTIVECATCHBLOCK: + iter->info.action_pointer += sizeof(ex_activecatchblock); + break; + case EXACTION_SPECIFICATION: + iter->info.action_pointer += sizeof(ex_specification) + ((ex_specification*)iter->info.action_pointer)->specs * sizeof(void*); + break; + default: + std::terminate(); + } + } + + action = ((ex_destroylocal*)iter->info.action_pointer)->action & EXACTION_MASK; + + if(action == EXACTION_BRANCH){ + iter->info.action_pointer = ((char*)iter->info.exception_record) + ((ex_branch*)iter->info.action_pointer)->target; + action = ((ex_destroylocal*)iter->info.action_pointer)->action & EXACTION_MASK; + } + return action; + } +} + +static char* ExPPC_PopStackFrame(ThrowContext* context, MWExceptionInfo* info){ + char *SP, *callers_SP; + double* FPR_save_area; + long* GPR_save_area; + int saved_GPRs, saved_FPRs; + GeckoFPRContext* Vector_save_area; + int i, j; + + SP = context->SP; + callers_SP = *(char**)SP; + saved_FPRs = ET_GetSavedFPRs(info->exception_record->et_field); + + if(ET_HasElfVector(info->exception_record->et_field)){ + Vector_save_area = (GeckoFPRContext *)(callers_SP - saved_FPRs*16); + FPR_save_area = (double*)Vector_save_area; + }else{ + FPR_save_area = (double*)(callers_SP - saved_FPRs*8); + } + + if (ET_HasElfVector(info->exception_record->et_field)){ + for(i = 32 - saved_FPRs, j = 0; i < 32; ++i, ++j){ + context->FPR[i].v.f[0] = Vector_save_area[j].v.f[0]; + context->FPR[i].v.f[1] = Vector_save_area[j].v.f[1]; + context->FPR[i].d = Vector_save_area[j].d; + } + }else{ + for(i = 32 - saved_FPRs, j = 0; i < 32; ++i, ++j){ + context->FPR[i].d = FPR_save_area[j]; + } + } + + saved_GPRs = ET_GetSavedGPRs(info->exception_record->et_field); + GPR_save_area = (long*)FPR_save_area; + GPR_save_area -= saved_GPRs; + + for(i = 32 - saved_GPRs, j = 0; i < 32; ++i, ++j){ + context->GPR[i] = GPR_save_area[j]; + } + + context->SP = callers_SP; + return *(char**)(callers_SP + RETURN_ADDRESS); +} + +static void ExPPC_DestroyLocal(ThrowContext* context, const ex_destroylocal* ex){ + DTORCALL_COMPLETE(ex->dtor, context->FP + ex->local); +} + +static void ExPPC_DestroyLocalCond(ThrowContext* context, const ex_destroylocalcond* ex){ + int cond = ex_destroylocalcond_GetRegCond(ex->dlc_field) ? (local_cond_type)context->GPR[ex->cond] : *(local_cond_type*)(context->FP + ex->cond); + + if(cond){ + DTORCALL_COMPLETE(ex->dtor, context->FP + ex->local); + } +} + +static void ExPPC_DestroyLocalPointer(ThrowContext* context, const ex_destroylocalpointer* ex){ + void *pointer = ex_destroylocalpointer_GetRegPointer(ex->dlp_field) ? (void*)context->GPR[ex->pointer] : *(void**)(context->FP + ex->pointer); + + DTORCALL_COMPLETE(ex->dtor, pointer); +} + +static void ExPPC_DestroyLocalArray(ThrowContext* context, const ex_destroylocalarray* ex){ + char* ptr = context->FP + ex->localarray; + long n = ex->elements; + long size = ex->element_size; + + for(ptr = ptr + size*n; n > 0; n--){ + ptr -= size; + DTORCALL_COMPLETE(ex->dtor, ptr); + } +} + +static void ExPPC_DestroyMember(ThrowContext* context, const ex_destroymember* ex){ + char *objectptr = ex_destroymember_GetRegPointer(ex->dm_field) ? (char*)context->GPR[ex->objectptr] : *(char**)(context->FP + ex->objectptr); + + DTORCALL_COMPLETE(ex->dtor,objectptr + ex->offset); +} + +static void ExPPC_DestroyBase(ThrowContext* context, const ex_destroymember* ex){ + char* objectptr = ex_destroymember_GetRegPointer(ex->dm_field) ? (char*)context->GPR[ex->objectptr] : *(char**)(context->FP + ex->objectptr); + + DTORCALL_PARTIAL(ex->dtor,objectptr + ex->offset); +} + +static void ExPPC_DestroyMemberCond(ThrowContext* context, const ex_destroymembercond* ex){ + char* objectptr = ex_destroymembercond_GetRegPointer(ex->dmc_field) ? (char*)context->GPR[ex->objectptr] : *(char**)(context->FP + ex->objectptr); + int cond = ex_destroymembercond_GetRegCond(ex->dmc_field) ? (vbase_ctor_arg_type)context->GPR[ex->cond] : *(vbase_ctor_arg_type*)(context->FP + ex->cond); + + if(cond){ + DTORCALL_PARTIAL(ex->dtor, objectptr + ex->offset); + } +} + +static void ExPPC_DestroyMemberArray(ThrowContext* context, const ex_destroymemberarray* ex){ + char* ptr = ex_destroymemberarray_GetRegPointer(ex->dma_field) ? (char*)context->GPR[ex->objectptr] : *(char**)(context->FP + ex->objectptr); + long n = ex->elements; + long size = ex->element_size; + + ptr += ex->offset; + + for(ptr = ptr + size*n; n > 0; n--){ + ptr -= size; + DTORCALL_COMPLETE(ex->dtor, ptr); + } +} + +static void ExPPC_DeletePointer(ThrowContext* context, const ex_deletepointer* ex){ + char* objectptr = ex_deletepointer_GetRegPointer(ex->dp_field) ? (char*)context->GPR[ex->objectptr] : *(char**)(context->FP + ex->objectptr); + + ((DeleteFunc)ex->deletefunc)(objectptr); +} + +static void ExPPC_DeletePointerCond(ThrowContext* context, const ex_deletepointercond* ex){ + char* objectptr = ex_deletepointercond_GetRegPointer(ex->dpc_field) ? (char*)context->GPR[ex->objectptr] : *(char**)(context->FP + ex->objectptr); + int cond = ex_deletepointercond_GetRegCond(ex->dpc_field) ? (local_cond_type)context->GPR[ex->cond] : *(local_cond_type*)(context->FP+ex->cond); + + if(cond){ + ((DeleteFunc)ex->deletefunc)(objectptr); + } +} + +static void ExPPC_UnwindStack(ThrowContext* context, MWExceptionInfo* info, void* catcher){ + exaction_type action; + + #pragma exception_terminate + + for(;;){ + if(info->action_pointer == 0){ + char* return_addr; + + return_addr = ExPPC_PopStackFrame(context, info); + ExPPC_FindExceptionRecord(return_addr, info); + + if(info->exception_record == 0){ + std::terminate(); + } + + context->FP = (ET_GetHasFramePtr(info->exception_record->et_field)) ? (char*)context->GPR[31] : context->SP; + continue; + } + + action = ((ex_destroylocal*)info->action_pointer)->action; + + switch(action & EXACTION_MASK){ + case EXACTION_BRANCH: + info->action_pointer = ((char*)info->exception_record) + ((ex_branch*)info->action_pointer)->target; + break; + case EXACTION_DESTROYLOCAL: + ExPPC_DestroyLocal(context, (ex_destroylocal*)info->action_pointer); + info->action_pointer += sizeof(ex_destroylocal); + break; + case EXACTION_DESTROYLOCALCOND: + ExPPC_DestroyLocalCond(context, (ex_destroylocalcond*)info->action_pointer); + info->action_pointer += sizeof(ex_destroylocalcond); + break; + case EXACTION_DESTROYLOCALPOINTER: + ExPPC_DestroyLocalPointer(context, (ex_destroylocalpointer*)info->action_pointer); + info->action_pointer += sizeof(ex_destroylocalpointer); + break; + case EXACTION_DESTROYLOCALARRAY: + ExPPC_DestroyLocalArray(context, (ex_destroylocalarray*)info->action_pointer); + info->action_pointer += sizeof(ex_destroylocalarray); + break; + case EXACTION_DESTROYBASE: + ExPPC_DestroyBase(context, (ex_destroymember*)info->action_pointer); + info->action_pointer += sizeof(ex_destroymember); + break; + case EXACTION_DESTROYMEMBER: + ExPPC_DestroyMember(context, (ex_destroymember*)info->action_pointer); + info->action_pointer += sizeof(ex_destroymember); + break; + case EXACTION_DESTROYMEMBERCOND: + ExPPC_DestroyMemberCond(context, (ex_destroymembercond*)info->action_pointer); + info->action_pointer += sizeof(ex_destroymembercond); + break; + case EXACTION_DESTROYMEMBERARRAY: + ExPPC_DestroyMemberArray(context, (ex_destroymemberarray*)info->action_pointer); + info->action_pointer += sizeof(ex_destroymemberarray); + break; + case EXACTION_DELETEPOINTER: + ExPPC_DeletePointer(context, (ex_deletepointer*)info->action_pointer); + info->action_pointer += sizeof(ex_deletepointer); + break; + case EXACTION_DELETEPOINTERCOND: + ExPPC_DeletePointerCond(context, (ex_deletepointercond*)info->action_pointer); + info->action_pointer += sizeof(ex_deletepointercond); + break; + case EXACTION_CATCHBLOCK: + if(catcher == (void *)info->action_pointer) return; + info->action_pointer += sizeof(ex_catchblock); + break; + case EXACTION_CATCHBLOCK_32: + if(catcher == (void *)info->action_pointer) return; + info->action_pointer += sizeof(ex_catchblock_32); + break; + case EXACTION_ACTIVECATCHBLOCK: + { + CatchInfo* catchinfo; + + catchinfo = (CatchInfo*)(context->FP + ((ex_activecatchblock*)info->action_pointer)->cinfo_ref); + + if (catchinfo->dtor){ + if (context->location == catchinfo->location){ + context->dtor = catchinfo->dtor; + }else{ + DTORCALL_COMPLETE(catchinfo->dtor, catchinfo->location); + } + } + info->action_pointer += sizeof(ex_activecatchblock); + } + break; + case EXACTION_SPECIFICATION: + if(catcher == (void*)info->action_pointer) return; + info->action_pointer += sizeof(ex_specification) + ((ex_specification*)info->action_pointer)->specs * sizeof(void*); + break; + default: + std::terminate(); + } + + if(action & EXACTION_ENDBIT) info->action_pointer = 0; + } +} + +static int ExPPC_IsInSpecification(char* extype, ex_specification* spec){ + long i, offset; + + for(i = 0; i < spec->specs; i++){ + if(__throw_catch_compare(extype, spec->spec[i], &offset)) return 1; + } + + return 0; +} + +//unused +extern void __unexpected(CatchInfo* catchinfo){ +} + +static asm void ExPPC_LongJump(register ThrowContext* context, register void* newRTOC, register void* newPC){ + nofralloc + + mr r8, newPC + mr RTOC, newRTOC + lwz r0, context->CR + mtcrf 255, r0 + + lmw r13, context->GPR[13] + + la r7, context->FPR[14].v + psq_lx fp14, 0, r7, 0, 0 + lfd fp14, context->FPR[14].d + + la r7, context->FPR[15].v + psq_lx fp15, 0, r7, 0, 0 + lfd fp15, context->FPR[15].d + + la r7, context->FPR[16].v + psq_lx fp16, 0, r7, 0, 0 + lfd fp16, context->FPR[16].d + + la r7, context->FPR[17].v + psq_lx fp17, 0, r7, 0, 0 + lfd fp17, context->FPR[17].d + + la r7, context->FPR[18].v + psq_lx fp18, 0, r7, 0, 0 + lfd fp18, context->FPR[18].d + + la r7, context->FPR[19].v + psq_lx fp19, 0, r7, 0, 0 + lfd fp19, context->FPR[19].d + + la r7, context->FPR[20].v + psq_lx fp20, 0, r7, 0, 0 + lfd fp20, context->FPR[20].d + + la r7, context->FPR[21].v + psq_lx fp21, 0, r7, 0, 0 + lfd fp21, context->FPR[21].d + + la r7, context->FPR[22].v + psq_lx fp22, 0, r7, 0, 0 + lfd fp22, context->FPR[22].d + + la r7, context->FPR[23].v + psq_lx fp23, 0, r7, 0, 0 + lfd fp23, context->FPR[23].d + + la r7, context->FPR[24].v + psq_lx fp24, 0, r7, 0, 0 + lfd fp24, context->FPR[24].d + + la r7, context->FPR[25].v + psq_lx fp25, 0, r7, 0, 0 + lfd fp25, context->FPR[25].d + + la r7, context->FPR[26].v + psq_lx fp26, 0, r7, 0, 0 + lfd fp26, context->FPR[26].d + + la r7, context->FPR[27].v + psq_lx fp27, 0, r7, 0, 0 + lfd fp27, context->FPR[27].d + + la r7, context->FPR[28].v + psq_lx fp28, 0, r7, 0, 0 + lfd fp28, context->FPR[28].d + + la r7, context->FPR[29].v + psq_lx fp29, 0, r7, 0, 0 + lfd fp29, context->FPR[29].d + + la r7, context->FPR[30].v + psq_lx fp30, 0, r7, 0, 0 + lfd fp30, context->FPR[30].d + + la r7, context->FPR[31].v + psq_lx fp31, 0, r7, 0, 0 + lfd fp31, context->FPR[31].d + + mtlr r8 + + lwz SP, context->throwSP + lwz r3, context->SP + lwz r3, 0(r3) + stw r3, 0(SP) + blr +} + +static void ExPPC_HandleUnexpected(ThrowContext* context, MWExceptionInfo* info, ex_specification* unexp){ + CatchInfo* catchinfo; + + #pragma exception_terminate + + ExPPC_UnwindStack(context, info, unexp); + + catchinfo = (CatchInfo*)(context->FP + unexp->cinfo_ref); + catchinfo->location = context->location; + catchinfo->typeinfo = context->throwtype; + catchinfo->dtor = context->dtor; + catchinfo->stacktop = unexp; + + ExPPC_LongJump(context, info->TOC, info->current_function + unexp->pcoffset); +} + +static void ExPPC_ThrowHandler(ThrowContext* context){ + ActionIterator iter; + MWExceptionInfo info; + exaction_type action; + CatchInfo* catchinfo; + long offset; + + ExPPC_FindExceptionRecord(context->returnaddr, &info); + + if(info.exception_record == 0){ + std::terminate(); + } + + context->FP = (ET_GetHasFramePtr(info.exception_record->et_field)) ? (char*)context->GPR[31] : context->SP; + + if(context->throwtype == 0){ + iter.info = info; + iter.current_SP = context->SP; + iter.current_FP = context->FP; + iter.current_R31 = context->GPR[31]; + + for(action = ExPPC_CurrentAction(&iter);; action = ExPPC_NextAction(&iter)){ + switch(action){ + case EXACTION_ACTIVECATCHBLOCK: + break; + case EXACTION_ENDOFLIST: + case EXACTION_DESTROYLOCAL: + case EXACTION_DESTROYLOCALCOND: + case EXACTION_DESTROYLOCALPOINTER: + case EXACTION_DESTROYLOCALARRAY: + case EXACTION_DESTROYBASE: + case EXACTION_DESTROYMEMBER: + case EXACTION_DESTROYMEMBERCOND: + case EXACTION_DESTROYMEMBERARRAY: + case EXACTION_DELETEPOINTER: + case EXACTION_DELETEPOINTERCOND: + case EXACTION_CATCHBLOCK: + case EXACTION_CATCHBLOCK_32: + case EXACTION_SPECIFICATION: + continue; + case EXACTION_TERMINATE: + default: + std::terminate(); + } + break; + } + + catchinfo = (CatchInfo*)(iter.current_FP + ((ex_activecatchblock*)iter.info.action_pointer)->cinfo_ref); + context->throwtype = (char*)catchinfo->typeinfo; + context->location = catchinfo->location; + context->dtor = 0; + context->catchinfo = catchinfo; + }else{ + context->catchinfo = 0L; + } + + iter.info = info; + iter.current_SP = context->SP; + iter.current_FP = context->FP; + iter.current_R31 = context->GPR[31]; + + for(action = ExPPC_CurrentAction(&iter);; action = ExPPC_NextAction(&iter)){ + switch(action){ + case EXACTION_CATCHBLOCK_32: + if(__throw_catch_compare(context->throwtype, ((ex_catchblock_32*)iter.info.action_pointer)->catch_type, &offset)){ + break; + } + continue; + case EXACTION_CATCHBLOCK: + if(__throw_catch_compare(context->throwtype, ((ex_catchblock*)iter.info.action_pointer)->catch_type, &offset)){ + break; + } + continue; + case EXACTION_SPECIFICATION: + if(!ExPPC_IsInSpecification(context->throwtype, (ex_specification*)iter.info.action_pointer)){ + ExPPC_HandleUnexpected(context, &info, (ex_specification *)iter.info.action_pointer); + } + continue; + case EXACTION_ENDOFLIST: + case EXACTION_DESTROYLOCAL: + case EXACTION_DESTROYLOCALCOND: + case EXACTION_DESTROYLOCALPOINTER: + case EXACTION_DESTROYLOCALARRAY: + case EXACTION_DESTROYBASE: + case EXACTION_DESTROYMEMBER: + case EXACTION_DESTROYMEMBERCOND: + case EXACTION_DESTROYMEMBERARRAY: + case EXACTION_DELETEPOINTER: + case EXACTION_DELETEPOINTERCOND: + case EXACTION_ACTIVECATCHBLOCK: + continue; + case EXACTION_TERMINATE: + default: + std::terminate(); + } + break; + } + + if (action == EXACTION_CATCHBLOCK_32) { + ex_catchblock_32* catchblock_32; + catchblock_32 = (ex_catchblock_32*)iter.info.action_pointer; + + ExPPC_UnwindStack(context, &info, catchblock_32); + + catchinfo = (CatchInfo*)(context->FP + catchblock_32->cinfo_ref); + catchinfo->location = context->location; + catchinfo->typeinfo = context->throwtype; + catchinfo->dtor = context->dtor; + + if(*context->throwtype == '*'){ + catchinfo->sublocation = &catchinfo->pointercopy; + catchinfo->pointercopy = *(long*)context->location + offset; + }else{ + catchinfo->sublocation = (char*)context->location + offset; + } + + ExPPC_LongJump(context, info.TOC, info.current_function + catchblock_32->catch_pcoffset); + }else{ + ex_catchblock* catchblock; + + catchblock = (ex_catchblock*)iter.info.action_pointer; + ExPPC_UnwindStack(context, &info, catchblock); + + catchinfo = (CatchInfo*)(context->FP+catchblock->cinfo_ref); + catchinfo->location = context->location; + catchinfo->typeinfo = context->throwtype; + catchinfo->dtor = context->dtor; + + if(*context->throwtype == '*'){ + catchinfo->sublocation = &catchinfo->pointercopy; + catchinfo->pointercopy = *(long*)context->location+offset; + }else{ + catchinfo->sublocation = (char*)context->location+offset; + } + + ExPPC_LongJump(context, info.TOC, info.current_function + catchblock->catch_pcoffset); + } +} + +asm void __throw(char* throwtype, void* location, void* dtor){ + ThrowContext throwcontext; + + fralloc + + stmw r13, throwcontext.GPR[13] + + stfd fp14, throwcontext.FPR[14].d + la r3, throwcontext.FPR[14].v + psq_stx fp14, 0, r3,0,0 + + stfd fp15, throwcontext.FPR[15].d + la r3, throwcontext.FPR[15].v + psq_stx fp15, 0, r3, 0, 0 + + stfd fp16, throwcontext.FPR[16].d + la r3, throwcontext.FPR[16].v + psq_stx fp16, 0, r3, 0, 0 + + stfd fp17, throwcontext.FPR[17].d + la r3, throwcontext.FPR[17].v + psq_stx fp17, 0, r3, 0, 0 + + stfd fp18, throwcontext.FPR[18].d + la r3, throwcontext.FPR[18].v + psq_stx fp18, 0, r3, 0, 0 + + stfd fp19, throwcontext.FPR[19].d + la r3, throwcontext.FPR[19].v + psq_stx fp19, 0, r3, 0, 0 + + stfd fp20, throwcontext.FPR[20].d + la r3, throwcontext.FPR[20].v + psq_stx fp20, 0, r3, 0, 0 + + stfd fp21, throwcontext.FPR[21].d + la r3, throwcontext.FPR[21].v + psq_stx fp21, 0, r3, 0, 0 + + stfd fp22, throwcontext.FPR[22].d + la r3, throwcontext.FPR[22].v + psq_stx fp22, 0, r3, 0, 0 + + stfd fp23, throwcontext.FPR[23].d + la r3, throwcontext.FPR[23].v + psq_stx fp23, 0, r3, 0, 0 + + stfd fp24, throwcontext.FPR[24].d + la r3, throwcontext.FPR[24].v + psq_stx fp24, 0, r3, 0, 0 + + stfd fp25, throwcontext.FPR[25].d + la r3, throwcontext.FPR[25].v + psq_stx fp25, 0, r3, 0, 0 + + stfd fp26, throwcontext.FPR[26].d + la r3, throwcontext.FPR[26].v + psq_stx fp26, 0, r3, 0, 0 + + stfd fp27, throwcontext.FPR[27].d + la r3, throwcontext.FPR[27].v + psq_stx fp27, 0, r3, 0, 0 + + stfd fp28, throwcontext.FPR[28].d + la r3, throwcontext.FPR[28].v + psq_stx fp28, 0, r3, 0, 0 + + stfd fp29, throwcontext.FPR[29].d + la r3, throwcontext.FPR[29].v + psq_stx fp29, 0, r3, 0, 0 + + stfd fp30, throwcontext.FPR[30].d + la r3, throwcontext.FPR[30].v + psq_stx fp30, 0, r3, 0, 0 + + stfd fp31, throwcontext.FPR[31].d + la r3, throwcontext.FPR[31].v + psq_stx fp31, 0, r3, 0, 0 + + + mfcr r3 + stw r3, throwcontext.CR; + + lwz r3, 0(sp) + lwz r4, RETURN_ADDRESS(r3) + stw r3, throwcontext.SP; + stw r3, throwcontext.throwSP; + stw r4, throwcontext.returnaddr; + + lwz r3,throwtype + stw r3, throwcontext.throwtype + lwz r3,location + stw r3, throwcontext.location + lwz r3,dtor + stw r3, throwcontext.dtor + la r3, throwcontext + bl ExPPC_ThrowHandler + nop + frfree + blr +} + +//unused +void __end__catch(CatchInfo* catchinfo){ +} diff --git a/libs/PowerPC_EABI_Support/src/Runtime/NMWException.cp b/libs/PowerPC_EABI_Support/src/Runtime/NMWException.cp new file mode 100644 index 000000000..bef12ad6c --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/NMWException.cp @@ -0,0 +1,91 @@ +#include "PowerPC_EABI_Support/Runtime/NMWException.h" +#include "PowerPC_EABI_Support/Runtime/MWCPlusPlusLib.h" + +#pragma exceptions on + +extern "C" +{ + void abort(); +} + +namespace std +{ + static void dthandler() + { + abort(); + } + + terminate_handler thandler = dthandler; + + static void duhandler() + { + terminate(); + } + + unexpected_handler uhandler = duhandler; + + extern void terminate() + { + thandler(); + } + + extern void unexpected() { + uhandler(); + } +} + +extern "C" char __throw_catch_compare(const char* throwtype, const char* catchtype, s32* offset_result) +{ + return 0; +} + +extern "C" void *__construct_new_array(void *block, ConstructorDestructor ctor, ConstructorDestructor dtor_arg, size_t size, size_t n) +{ + return 0 ; +} + +class __partial_array_destructor +{ +private: + void *p; + size_t size; + size_t n; + void *dtor; + +public: + size_t i; + + __partial_array_destructor(void *array, size_t elementsize, size_t nelements, void *destructor) + { + p = array; + size = elementsize; + n = nelements; + dtor = destructor; + i = n; + } + + ~__partial_array_destructor() + { + char *ptr; + + if (i < n && dtor) + { + for (ptr = (char *)p + size * i; i > 0; i--) + { + ptr -= size; + DTORCALL_COMPLETE(dtor, ptr); + } + } + } +}; + + +extern "C" void __construct_array(void *ptr, void *ctor, void *dtor, size_t size, size_t n) +{ + +} + +extern "C" void __destroy_arr(void *block, ConstructorDestructor *dtor, size_t size, size_t n) +{ + +} diff --git a/libs/PowerPC_EABI_Support/src/Runtime/__init_cpp_exceptions.cpp b/libs/PowerPC_EABI_Support/src/Runtime/__init_cpp_exceptions.cpp new file mode 100644 index 000000000..617b7374d --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/__init_cpp_exceptions.cpp @@ -0,0 +1,37 @@ +#include "types.h" +#include "PowerPC_EABI_Support/Runtime/NMWException.h" +#include "PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h" +#include "PowerPC_EABI_Support/Runtime/__init_cpp_exceptions.h" + +static int fragmentID = -2; + +extern char *GetR2() ; + +void __init_cpp_exceptions() +{ + if ((s32)fragmentID == -2) { + char* R2 = GetR2(); + fragmentID = __register_fragment(&_eti_init_info, R2); + } +} + +// clang-format on +void __fini_cpp_exceptions() +{ + if ((s32)fragmentID != -2) { + __unregister_fragment(fragmentID); + fragmentID = -2; + } +} + +// clang-format off +asm char* GetR2() +{ + nofralloc + mr r3, r2 + blr +} + +__declspec(section ".ctors") extern void* const __init_cpp_exceptions_reference = __init_cpp_exceptions; +__declspec(section ".dtors") extern void* const __destroy_global_chain_reference = __destroy_global_chain; +__declspec(section ".dtors") extern void* const __fini_cpp_exceptions_reference = __fini_cpp_exceptions; \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/Runtime/__mem.c b/libs/PowerPC_EABI_Support/src/Runtime/__mem.c new file mode 100644 index 000000000..51d788a94 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/__mem.c @@ -0,0 +1,102 @@ +#include +#include + +void *memcpy(void *dst, const void *src, size_t n) +{ + u8 *__src; + u8 *__dst; + int i; + + if (src >= dst) + { + __src = ((u8 *)src) - 1; + __dst = ((u8 *)dst) - 1; + i = n + 1; + while (--i) + { + *((u8 *)++__dst) = *((u8 *)++__src); + } + return dst; + } + else + { + __src = ((u8 *)src) + n; + __dst = ((u8 *)dst) + n; + i = n + 1; + while (--i) + { + *((u8 *)--__dst) = *((u8 *)--__src); + } + return dst; + } +} +void __fill_mem(void *dst, int c, size_t n) +{ + u8 *cdest; + u32 *idest; + u32 i; + u32 cval; + + cval = (u8)c; + cdest = (u8 *)dst - 1; + + if (n >= 32) + { + i = ~(u32)cdest & 3; + if (i != 0) + { + n = n - i; + do + { + *(++cdest) = (u8)cval; + } while (--i); + } + if (cval != 0) + { + cval = cval << 24 | cval << 16 | cval << 8 | cval; + } + + idest = (u32 *)(cdest - 3); + i = n >> 5; + if (i != 0) + { + do + { + idest[1] = cval; // 4 + idest[2] = cval; // 8 + idest[3] = cval; // c + idest[4] = cval; // 10 + idest[5] = cval; // 14 + idest[6] = cval; // 18 + idest[7] = cval; // 1c + *(idest += 8) = cval; // 20 + } while (--i); + } + + i = (n >> 2) & 7; + + if (i != 0) + { + do + { + *++idest = cval; + } while (--i); + } + + cdest = (u8 *)idest + 3; + n &= 3; + } + if (n != 0) + { + do + { + *++cdest = (u8)cval; + } while (--n); + } +} + +void *memset(void *dst, int c, size_t n) +{ + __fill_mem(dst, c, n); + return dst; +} \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/Runtime/__va_arg.c b/libs/PowerPC_EABI_Support/src/Runtime/__va_arg.c new file mode 100644 index 000000000..e06cf858e --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/__va_arg.c @@ -0,0 +1,44 @@ +#include "types.h" +#include "PowerPC_EABI_Support/Runtime/__va_arg.h" + +void* __va_arg(struct va_list* v_list, s32 type) +{ + char* addr; + char* reg = &(v_list->mG_register); + s32 g_reg = v_list->mG_register; + s32 maxsize = 8; + s32 size = 4; + s32 increment = 1; + s32 even = 0; + s32 fpr_offset = 0; + s32 regsize = 4; + + if (type == 3) { + reg = &(v_list->mFloat_register); + g_reg = v_list->mFloat_register; + size = 8; + fpr_offset = 32; + regsize = 8; + } + if (type == 2) { + size = 8; + maxsize--; + if (g_reg & 1) + even = 1; + increment = 2; + } + if (g_reg < maxsize) { + g_reg += even; + addr = v_list->mReg_save_area + fpr_offset + (g_reg * regsize); + *reg = g_reg + increment; + } else { + *reg = 8; + addr = v_list->mInput_arg_area; + addr = (char*)(((u32)(addr) + ((size)-1)) & ~((size)-1)); + v_list->mInput_arg_area = addr + size; + } + if (type == 0) + addr = *((char**)addr); + + return addr; +} diff --git a/libs/PowerPC_EABI_Support/src/Runtime/global_destructor_chain.c b/libs/PowerPC_EABI_Support/src/Runtime/global_destructor_chain.c new file mode 100644 index 000000000..c017fde19 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/global_destructor_chain.c @@ -0,0 +1,32 @@ +#include "PowerPC_EABI_Support/Runtime/global_destructor_chain.h" +#include "PowerPC_EABI_Support/Runtime/MWCPlusPlusLib.h" + +DestructorChain *__global_destructor_chain; + +void *__register_global_object(void *object, void *destructor, void *regmem) +{ + ((DestructorChain *)regmem)->next = __global_destructor_chain; + ((DestructorChain *)regmem)->destructor = destructor; + ((DestructorChain *)regmem)->object = object; + __global_destructor_chain = (DestructorChain *)regmem; + + return object; +} + +void __destroy_global_chain(void) +{ + DestructorChain *iter; + + while ((iter = __global_destructor_chain) != 0) + { + __global_destructor_chain = iter->next; + DTORCALL_COMPLETE(iter->destructor, iter->object); + } +} + +// unused +int __register_atexit(void (*func)(void)) +{ +} + +__declspec(section ".dtors") static void *const __destroy_global_chain_reference = __destroy_global_chain; diff --git a/libs/PowerPC_EABI_Support/src/Runtime/ptmf.c b/libs/PowerPC_EABI_Support/src/Runtime/ptmf.c new file mode 100644 index 000000000..ce716ecf4 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/ptmf.c @@ -0,0 +1,104 @@ +// presumably, ptmf = pointer to member function + +typedef struct PTMF { + long this_delta; // self-explanatory + long v_offset; // vtable offset + union { + void* f_addr; // function address + long ve_offset; // virtual function entry offset (of vtable) + } f_data; +} PTMF; + +const PTMF __ptmf_null = { 0, 0, 0 }; + +long __ptmf_test(PTMF *ptmf); +long __ptmf_cmpr(PTMF *ptmf1, PTMF *ptmf2); +void __ptmf_scall(...); + +// clang-format off +asm long __ptmf_test(register PTMF* ptmf) +{ + nofralloc + lwz r5, PTMF.this_delta(r3) + lwz r6, PTMF.v_offset(r3) + lwz r7, PTMF.f_data(r3) + li r3, 0x1 + cmpwi r5, 0 + cmpwi cr6, r6, 0 + cmpwi cr7, r7, 0 + bnelr- + bnelr- cr6 + bnelr- cr7 + li r3, 0 + blr +} + + +asm long __ptmf_cmpr(PTMF *ptmf1, PTMF *ptmf2) +{ + nofralloc + lwz r5, PTMF.this_delta(r3) + lwz r6, PTMF.this_delta(r4) + lwz r7, PTMF.v_offset(r3) + lwz r8, PTMF.v_offset(r4) + lwz r9, PTMF.f_data(r3) + lwz r10, PTMF.f_data(r4) + li r3, 1 + cmpw r5, r6 + cmpw cr6, r7, r8 + cmpw cr7, r9, r10 + bnelr- + bnelr- cr6 + bnelr- cr7 + li r3, 0 + blr +} + + +/*void __ptmf_call(void) +{ + // UNUSED FUNCTION +}*/ + +/*void __ptmf_call4(void) +{ + // UNUSED FUNCTION +}*/ + +asm void __ptmf_scall(...) +{ + nofralloc + lwz r0, PTMF.this_delta(r12) + lwz r11, PTMF.v_offset(r12) + lwz r12, PTMF.f_data(r12) + add r3, r3, r0 + cmpwi r11, 0 + blt- cr0, loc_0x20 + lwzx r12, r3, r12 + lwzx r12, r12, r11 + loc_0x20: + mtctr r12 + bctr +} + +// clang-format on +asm void __ptmf_scall4(...) +{ + nofralloc + lwz r0, PTMF.this_delta(r12) + lwz r11, PTMF.v_offset(r12) + lwz r12, PTMF.f_data(r12) + add r4, r4, r0 + cmpwi r11, 0 + blt- cr0, loc_0x20 + lwzx r12, r4, r12 + lwzx r12, r12, r11 + loc_0x20: + mtctr r12 + bctr +} + +/*void __ptmf_cast(void) +{ + // UNUSED FUNCTION +}*/ diff --git a/libs/PowerPC_EABI_Support/src/Runtime/runtime.c b/libs/PowerPC_EABI_Support/src/Runtime/runtime.c new file mode 100644 index 000000000..68cb136c6 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/runtime.c @@ -0,0 +1,920 @@ +#ifdef __cplusplus +extern "C" { +#endif + +/* macros for GPR/FPR resting and saving */ +#define SAVE_FPR(reg) _savefpr_##reg +#define RESTORE_FPR(reg) _restfpr_##reg +#define SAVE_GPR(reg) _savegpr_##reg +#define RESTORE_GPR(reg) _restgpr_##reg +#define ENTRY_SAVE_FPR(reg) entry SAVE_FPR(reg) +#define ENTRY_RESTORE_FPR(reg) entry RESTORE_FPR(reg) +#define ENTRY_SAVE_GPR(reg) entry SAVE_GPR(reg) +#define ENTRY_RESTORE_GPR(reg) entry RESTORE_GPR(reg) +#define SAVE_FPR2(reg) _savef##reg +#define RESTORE_FPR2(reg) _restf##reg +#define ENTRY_SAVE_FPR2(reg) +#define ENTRY_RESTORE_FPR2(reg) + +#define save_restore_reg r11 + +asm void __div2u(void); +asm void __div2i(void); +asm void __mod2u(void); +asm void __mod2i(void); +asm void __shl2i(void); +asm void __shr2u(void); +asm void __shr2i(void); +asm void __cvt_sll_dbl(void); +asm void __cvt_ull_dbl(void); +asm void __cvt_sll_flt(void); +asm void __cvt_ull_flt(void); +asm void __cvt_dbl_usll(void); +asm void __cvt_dbl_ull(void); + +void SAVE_FPR(14)(void); +void SAVE_FPR(15)(void); +void SAVE_FPR(16)(void); +void SAVE_FPR(17)(void); +void SAVE_FPR(18)(void); +void SAVE_FPR(19)(void); +void SAVE_FPR(20)(void); +void SAVE_FPR(21)(void); +void SAVE_FPR(22)(void); +void SAVE_FPR(23)(void); +void SAVE_FPR(24)(void); +void SAVE_FPR(25)(void); +void SAVE_FPR(26)(void); +void SAVE_FPR(27)(void); +void SAVE_FPR(28)(void); +void SAVE_FPR(29)(void); +void SAVE_FPR(30)(void); +void SAVE_FPR(31)(void); +void SAVE_FPR2(14)(void); +void SAVE_FPR2(15)(void); +void SAVE_FPR2(16)(void); +void SAVE_FPR2(17)(void); +void SAVE_FPR2(18)(void); +void SAVE_FPR2(19)(void); +void SAVE_FPR2(20)(void); +void SAVE_FPR2(21)(void); +void SAVE_FPR2(22)(void); +void SAVE_FPR2(23)(void); +void SAVE_FPR2(24)(void); +void SAVE_FPR2(25)(void); +void SAVE_FPR2(26)(void); +void SAVE_FPR2(27)(void); +void SAVE_FPR2(28)(void); +void SAVE_FPR2(29)(void); +void SAVE_FPR2(30)(void); +void SAVE_FPR2(31)(void); +void RESTORE_FPR(14)(void); +void RESTORE_FPR(15)(void); +void RESTORE_FPR(16)(void); +void RESTORE_FPR(17)(void); +void RESTORE_FPR(18)(void); +void RESTORE_FPR(19)(void); +void RESTORE_FPR(20)(void); +void RESTORE_FPR(21)(void); +void RESTORE_FPR(22)(void); +void RESTORE_FPR(23)(void); +void RESTORE_FPR(24)(void); +void RESTORE_FPR(25)(void); +void RESTORE_FPR(26)(void); +void RESTORE_FPR(27)(void); +void RESTORE_FPR(28)(void); +void RESTORE_FPR(29)(void); +void RESTORE_FPR(30)(void); +void RESTORE_FPR(31)(void); +void RESTORE_FPR2(14)(void); +void RESTORE_FPR2(15)(void); +void RESTORE_FPR2(16)(void); +void RESTORE_FPR2(17)(void); +void RESTORE_FPR2(18)(void); +void RESTORE_FPR2(19)(void); +void RESTORE_FPR2(20)(void); +void RESTORE_FPR2(21)(void); +void RESTORE_FPR2(22)(void); +void RESTORE_FPR2(23)(void); +void RESTORE_FPR2(24)(void); +void RESTORE_FPR2(25)(void); +void RESTORE_FPR2(26)(void); +void RESTORE_FPR2(27)(void); +void RESTORE_FPR2(28)(void); +void RESTORE_FPR2(29)(void); +void RESTORE_FPR2(30)(void); +void RESTORE_FPR2(31)(void); +void SAVE_GPR(14)(void); +void SAVE_GPR(15)(void); +void SAVE_GPR(16)(void); +void SAVE_GPR(17)(void); +void SAVE_GPR(18)(void); +void SAVE_GPR(19)(void); +void SAVE_GPR(20)(void); +void SAVE_GPR(21)(void); +void SAVE_GPR(22)(void); +void SAVE_GPR(23)(void); +void SAVE_GPR(24)(void); +void SAVE_GPR(25)(void); +void SAVE_GPR(26)(void); +void SAVE_GPR(27)(void); +void SAVE_GPR(28)(void); +void SAVE_GPR(29)(void); +void SAVE_GPR(30)(void); +void SAVE_GPR(31)(void); +void RESTORE_GPR(14)(void); +void RESTORE_GPR(15)(void); +void RESTORE_GPR(16)(void); +void RESTORE_GPR(17)(void); +void RESTORE_GPR(18)(void); +void RESTORE_GPR(19)(void); +void RESTORE_GPR(20)(void); +void RESTORE_GPR(21)(void); +void RESTORE_GPR(22)(void); +void RESTORE_GPR(23)(void); +void RESTORE_GPR(24)(void); +void RESTORE_GPR(25)(void); +void RESTORE_GPR(26)(void); +void RESTORE_GPR(27)(void); +void RESTORE_GPR(28)(void); +void RESTORE_GPR(29)(void); +void RESTORE_GPR(30)(void); +void RESTORE_GPR(31)(void); + +static const unsigned long __constants[] = { + 0x00000000, 0x00000000, 0x41F00000, 0x00000000, 0x41E00000, 0x00000000, +}; + +asm unsigned long __cvt_fp2unsigned(register double d) +{ + nofralloc stwu r1, -16(r1)lis r4, __constants @h ori r4, r4, __constants @l li r3, 0 lfd fp0, + 0(r4)lfd fp3, 8(r4)lfd fp4, 16(r4)fcmpu cr0, fp1, fp0 fcmpu cr6, fp1, fp3 blt cr0, + @exit addi r3, r3, -1 bge cr6, @exit fcmpu cr7, fp1, fp4 fmr fp2, fp1 blt cr7, @1 fsub fp2, + fp1, fp4 @1 fctiwz fp2, fp2 stfd fp2, 8(r1)lwz r3, 12(r1)blt cr7, @exit addis r3, r3, + -0x8000 @exit : addi r1, r1, 16 blr +} + +static asm void __save_fpr(void) +{ + nofralloc ENTRY_SAVE_FPR(14) ENTRY_SAVE_FPR2(14) stfd fp14, + -144(save_restore_reg)ENTRY_SAVE_FPR(15) ENTRY_SAVE_FPR2(15) stfd fp15, + -136(save_restore_reg)ENTRY_SAVE_FPR(16) ENTRY_SAVE_FPR2(16) stfd fp16, + -128(save_restore_reg)ENTRY_SAVE_FPR(17) ENTRY_SAVE_FPR2(17) stfd fp17, + -120(save_restore_reg)ENTRY_SAVE_FPR(18) ENTRY_SAVE_FPR2(18) stfd fp18, + -112(save_restore_reg)ENTRY_SAVE_FPR(19) ENTRY_SAVE_FPR2(19) stfd fp19, + -104(save_restore_reg)ENTRY_SAVE_FPR(20) ENTRY_SAVE_FPR2(20) stfd fp20, + -96(save_restore_reg)ENTRY_SAVE_FPR(21) ENTRY_SAVE_FPR2(21) stfd fp21, + -88(save_restore_reg)ENTRY_SAVE_FPR(22) ENTRY_SAVE_FPR2(22) stfd fp22, + -80(save_restore_reg)ENTRY_SAVE_FPR(23) ENTRY_SAVE_FPR2(23) stfd fp23, + -72(save_restore_reg)ENTRY_SAVE_FPR(24) ENTRY_SAVE_FPR2(24) stfd fp24, + -64(save_restore_reg)ENTRY_SAVE_FPR(25) ENTRY_SAVE_FPR2(25) stfd fp25, + -56(save_restore_reg)ENTRY_SAVE_FPR(26) ENTRY_SAVE_FPR2(26) stfd fp26, + -48(save_restore_reg)ENTRY_SAVE_FPR(27) ENTRY_SAVE_FPR2(27) stfd fp27, + -40(save_restore_reg)ENTRY_SAVE_FPR(28) ENTRY_SAVE_FPR2(28) stfd fp28, + -32(save_restore_reg)ENTRY_SAVE_FPR(29) ENTRY_SAVE_FPR2(29) stfd fp29, + -24(save_restore_reg)ENTRY_SAVE_FPR(30) ENTRY_SAVE_FPR2(30) stfd fp30, + -16(save_restore_reg)ENTRY_SAVE_FPR(31) ENTRY_SAVE_FPR2(31) stfd fp31, + -8(save_restore_reg)blr +} + +static asm void __restore_fpr(void) +{ + nofralloc ENTRY_RESTORE_FPR(14) ENTRY_RESTORE_FPR2(14) lfd fp14, + -144(save_restore_reg)ENTRY_RESTORE_FPR(15) ENTRY_RESTORE_FPR2(15) lfd fp15, + -136(save_restore_reg)ENTRY_RESTORE_FPR(16) ENTRY_RESTORE_FPR2(16) lfd fp16, + -128(save_restore_reg)ENTRY_RESTORE_FPR(17) ENTRY_RESTORE_FPR2(17) lfd fp17, + -120(save_restore_reg)ENTRY_RESTORE_FPR(18) ENTRY_RESTORE_FPR2(18) lfd fp18, + -112(save_restore_reg)ENTRY_RESTORE_FPR(19) ENTRY_RESTORE_FPR2(19) lfd fp19, + -104(save_restore_reg)ENTRY_RESTORE_FPR(20) ENTRY_RESTORE_FPR2(20) lfd fp20, + -96(save_restore_reg)ENTRY_RESTORE_FPR(21) ENTRY_RESTORE_FPR2(21) lfd fp21, + -88(save_restore_reg)ENTRY_RESTORE_FPR(22) ENTRY_RESTORE_FPR2(22) lfd fp22, + -80(save_restore_reg)ENTRY_RESTORE_FPR(23) ENTRY_RESTORE_FPR2(23) lfd fp23, + -72(save_restore_reg)ENTRY_RESTORE_FPR(24) ENTRY_RESTORE_FPR2(24) lfd fp24, + -64(save_restore_reg)ENTRY_RESTORE_FPR(25) ENTRY_RESTORE_FPR2(25) lfd fp25, + -56(save_restore_reg)ENTRY_RESTORE_FPR(26) ENTRY_RESTORE_FPR2(26) lfd fp26, + -48(save_restore_reg)ENTRY_RESTORE_FPR(27) ENTRY_RESTORE_FPR2(27) lfd fp27, + -40(save_restore_reg)ENTRY_RESTORE_FPR(28) ENTRY_RESTORE_FPR2(28) lfd fp28, + -32(save_restore_reg)ENTRY_RESTORE_FPR(29) ENTRY_RESTORE_FPR2(29) lfd fp29, + -24(save_restore_reg)ENTRY_RESTORE_FPR(30) ENTRY_RESTORE_FPR2(30) lfd fp30, + -16(save_restore_reg)ENTRY_RESTORE_FPR(31) ENTRY_RESTORE_FPR2(31) lfd fp31, + -8(save_restore_reg)blr +} + +static asm void __save_gpr(void) +{ + nofralloc ENTRY_SAVE_GPR(14) stw r14, -72(save_restore_reg)ENTRY_SAVE_GPR(15) stw r15, + -68(save_restore_reg)ENTRY_SAVE_GPR(16) stw r16, + -64(save_restore_reg)ENTRY_SAVE_GPR(17) stw r17, + -60(save_restore_reg)ENTRY_SAVE_GPR(18) stw r18, + -56(save_restore_reg)ENTRY_SAVE_GPR(19) stw r19, + -52(save_restore_reg)ENTRY_SAVE_GPR(20) stw r20, + -48(save_restore_reg)ENTRY_SAVE_GPR(21) stw r21, + -44(save_restore_reg)ENTRY_SAVE_GPR(22) stw r22, + -40(save_restore_reg)ENTRY_SAVE_GPR(23) stw r23, + -36(save_restore_reg)ENTRY_SAVE_GPR(24) stw r24, + -32(save_restore_reg)ENTRY_SAVE_GPR(25) stw r25, + -28(save_restore_reg)ENTRY_SAVE_GPR(26) stw r26, + -24(save_restore_reg)ENTRY_SAVE_GPR(27) stw r27, + -20(save_restore_reg)ENTRY_SAVE_GPR(28) stw r28, + -16(save_restore_reg)ENTRY_SAVE_GPR(29) stw r29, + -12(save_restore_reg)ENTRY_SAVE_GPR(30) stw r30, + -8(save_restore_reg)ENTRY_SAVE_GPR(31) stw r31, -4(save_restore_reg)blr +} + +static asm void __restore_gpr(void) +{ + nofralloc ENTRY_RESTORE_GPR(14) lwz r14, -72(save_restore_reg)ENTRY_RESTORE_GPR(15) lwz r15, + -68(save_restore_reg)ENTRY_RESTORE_GPR(16) lwz r16, + -64(save_restore_reg)ENTRY_RESTORE_GPR(17) lwz r17, + -60(save_restore_reg)ENTRY_RESTORE_GPR(18) lwz r18, + -56(save_restore_reg)ENTRY_RESTORE_GPR(19) lwz r19, + -52(save_restore_reg)ENTRY_RESTORE_GPR(20) lwz r20, + -48(save_restore_reg)ENTRY_RESTORE_GPR(21) lwz r21, + -44(save_restore_reg)ENTRY_RESTORE_GPR(22) lwz r22, + -40(save_restore_reg)ENTRY_RESTORE_GPR(23) lwz r23, + -36(save_restore_reg)ENTRY_RESTORE_GPR(24) lwz r24, + -32(save_restore_reg)ENTRY_RESTORE_GPR(25) lwz r25, + -28(save_restore_reg)ENTRY_RESTORE_GPR(26) lwz r26, + -24(save_restore_reg)ENTRY_RESTORE_GPR(27) lwz r27, + -20(save_restore_reg)ENTRY_RESTORE_GPR(28) lwz r28, + -16(save_restore_reg)ENTRY_RESTORE_GPR(29) lwz r29, + -12(save_restore_reg)ENTRY_RESTORE_GPR(30) lwz r30, + -8(save_restore_reg)ENTRY_RESTORE_GPR(31) lwz r31, -4(save_restore_reg)blr +} + +asm void __div2u(void) +{ + nofralloc cmpwi cr0, r3, 0 cntlzw r0, r3 cntlzw r9, r4 bne cr0, lab1 addi r0, r9, + 32 lab1 : cmpwi cr0, + r5, + 0 cntlzw r9, + r5 cntlzw r10, + r6 bne cr0, + lab2 addi r9, + r10, + 32 lab2 : cmpw cr0, + r0, + r9 subfic r10, + r0, + 64 bgt cr0, + lab9 addi r9, + r9, + 1 subfic r9, + r9, + 64 add r0, + r0, + r9 subf r9, + r9, + r10 mtctr r9 cmpwi cr0, + r9, + 32 addi r7, + r9, + -32 blt cr0, + lab3 srw r8, + r3, + r7 li r7, + 0 b lab4 lab3 : srw r8, + r4, + r9 subfic r7, + r9, + 32 slw r7, + r3, + r7 or r8, + r8, + r7 srw r7, + r3, + r9 lab4 : cmpwi cr0, + r0, + 32 addic r9, + r0, + -32 blt cr0, + lab5 slw r3, + r4, + r9 li r4, + 0 b lab6 lab5 : slw r3, + r3, + r0 subfic r9, + r0, + 32 srw r9, + r4, + r9 or r3, + r3, + r9 slw r4, + r4, + r0 lab6 : li r10, + -1 addic r7, + r7, + 0 lab7 + : adde r4, + r4, + r4 adde r3, + r3, + r3 adde r8, + r8, + r8 adde r7, + r7, + r7 subfc r0, + r6, + r8 subfe.r9, + r5, + r7 blt cr0, + lab8 mr r8, + r0 mr r7, + r9 addic r0, + r10, + 1 lab8 : bdnz lab7 adde r4, + r4, + r4 adde r3, + r3, + r3 blr lab9 : li r4, + 0 li r3, + 0 blr +} + +#pragma push +#pragma optimization_level 0 +#pragma optimizewithasm off +asm void __div2i(void) +{ + nofralloc stwu r1, -16(r1)rlwinm.r9, r3, 0, 0, 0 beq cr0, positive1 subfic r4, r4, 0 subfze r3, + r3 positive1 : stw r9, + 8(r1)rlwinm.r10, + r5, + 0, + 0, + 0 beq cr0, + positive2 subfic r6, + r6, + 0 subfze r5, + r5 positive2 : stw r10, + 12(r1)cmpwi cr0, + r3, + 0 cntlzw r0, + r3 cntlzw r9, + r4 bne cr0, + lab1 addi r0, + r9, + 32 lab1 : cmpwi cr0, + r5, + 0 cntlzw r9, + r5 cntlzw r10, + r6 bne cr0, + lab2 addi r9, + r10, + 32 lab2 : cmpw cr0, + r0, + r9 subfic r10, + r0, + 64 bgt cr0, + lab9 addi r9, + r9, + 1 subfic r9, + r9, + 64 add r0, + r0, + r9 subf r9, + r9, + r10 mtctr r9 cmpwi cr0, + r9, + 32 addi r7, + r9, + -32 blt cr0, + lab3 srw r8, + r3, + r7 li r7, + 0 b lab4 lab3 : srw r8, + r4, + r9 subfic r7, + r9, + 32 slw r7, + r3, + r7 or r8, + r8, + r7 srw r7, + r3, + r9 lab4 : cmpwi cr0, + r0, + 32 addic r9, + r0, + -32 blt cr0, + lab5 slw r3, + r4, + r9 li r4, + 0 b lab6 lab5 + : slw r3, + r3, + r0 subfic r9, + r0, + 32 srw r9, + r4, + r9 or r3, + r3, + r9 slw r4, + r4, + r0 lab6 : li r10, + -1 addic r7, + r7, + 0 lab7 : adde r4, + r4, + r4 adde r3, + r3, + r3 adde r8, + r8, + r8 adde r7, + r7, + r7 subfc r0, + r6, + r8 subfe.r9, + r5, + r7 blt cr0, + lab8 mr r8, + r0 mr r7, + r9 addic r0, + r10, + 1 lab8 : bdnz lab7 adde r4, + r4, + r4 adde r3, + r3, + r3 lwz r9, + 8(r1)lwz r10, + 12(r1) xor.r7, + r9, + r10 beq func_end cmpwi cr0, + r9, + 0 subfic r4, + r4, + 0 subfze r3, + r3 + + no_adjust : b func_end + + lab9 : li r4, + 0 li r3, + 0 func_end : addi r1, + r1, + 16 blr +} +#pragma pop + +#pragma push +#pragma optimization_level 0 +#pragma optimizewithasm off +asm void __mod2u(void) +{ + nofralloc cmpwi cr0, r3, 0 cntlzw r0, r3 cntlzw r9, r4 bne cr0, lab1 addi r0, r9, + 32 lab1 : cmpwi cr0, + r5, + 0 cntlzw r9, + r5 cntlzw r10, + r6 bne cr0, + lab2 addi r9, + r10, + 32 lab2 : cmpw cr0, + r0, + r9 subfic r10, + r0, + 64 bgtlr cr0 addi r9, + r9, + 1 subfic r9, + r9, + 64 add r0, + r0, + r9 subf r9, + r9, + r10 mtctr r9 cmpwi cr0, + r9, + 32 addi r7, + r9, + -32 blt cr0, + lab3 srw r8, + r3, + r7 li r7, + 0 b lab4 lab3 : srw r8, + r4, + r9 subfic r7, + r9, + 32 slw r7, + r3, + r7 or r8, + r8, + r7 srw r7, + r3, + r9 lab4 : cmpwi cr0, + r0, + 32 addic r9, + r0, + -32 blt cr0, + lab5 slw r3, + r4, + r9 li r4, + 0 b lab6 lab5 : slw r3, + r3, + r0 subfic r9, + r0, + 32 srw r9, + r4, + r9 or r3, + r3, + r9 slw r4, + r4, + r0 lab6 : li r10, + -1 addic r7, + r7, + 0 lab7 + : adde r4, + r4, + r4 adde r3, + r3, + r3 adde r8, + r8, + r8 adde r7, + r7, + r7 subfc r0, + r6, + r8 subfe.r9, + r5, + r7 blt cr0, + lab8 mr r8, + r0 mr r7, + r9 addic r0, + r10, + 1 lab8 : bdnz lab7 mr r4, + r8 mr r3, + r7 blr lab9 : blr +} +#pragma pop + +#pragma push +#pragma optimization_level 0 +#pragma optimizewithasm off +asm void __mod2i(void) +{ + nofralloc + + cmpwi cr7, + r3, 0 bge cr7, positive1 subfic r4, r4, 0 subfze r3, + r3 positive1 : cmpwi cr0, + r5, + 0 bge cr0, + positive2 subfic r6, + r6, + 0 subfze r5, + r5 positive2 : cmpwi cr0, + r3, + 0 cntlzw r0, + r3 cntlzw r9, + r4 bne cr0, + lab1 addi r0, + r9, + 32 lab1 : cmpwi cr0, + r5, + 0 cntlzw r9, + r5 cntlzw r10, + r6 bne cr0, + lab2 addi r9, + r10, + 32 lab2 : cmpw cr0, + r0, + r9 subfic r10, + r0, + 64 bgt cr0, + lab9 addi r9, + r9, + 1 subfic r9, + r9, + 64 add r0, + r0, + r9 subf r9, + r9, + r10 mtctr r9 cmpwi cr0, + r9, + 32 addi r7, + r9, + -32 blt cr0, + lab3 srw r8, + r3, + r7 li r7, + 0 b lab4 lab3 : srw r8, + r4, + r9 subfic r7, + r9, + 32 slw r7, + r3, + r7 or r8, + r8, + r7 srw r7, + r3, + r9 lab4 : cmpwi cr0, + r0, + 32 addic r9, + r0, + -32 blt cr0, + lab5 slw r3, + r4, + r9 li r4, + 0 b lab6 lab5 + : slw r3, + r3, + r0 subfic r9, + r0, + 32 srw r9, + r4, + r9 or r3, + r3, + r9 slw r4, + r4, + r0 lab6 : li r10, + -1 addic r7, + r7, + 0 lab7 : adde r4, + r4, + r4 adde r3, + r3, + r3 adde r8, + r8, + r8 adde r7, + r7, + r7 subfc r0, + r6, + r8 subfe.r9, + r5, + r7 blt cr0, + lab8 mr r8, + r0 mr r7, + r9 addic r0, + r10, + 1 lab8 : bdnz lab7 mr r4, + r8 mr r3, + r7 lab9 : bgelr cr7 subfic r4, + r4, + 0 subfze r3, + r3 no_adjust : blr +} +#pragma pop + +asm void __shl2i(void) +{ + nofralloc subfic r8, r5, 32 subic r9, r5, 32 slw r3, r3, r5 srw r10, r4, r8 or r3, r3, + r10 slw r10, r4, r9 or r3, r3, r10 slw r4, r4, r5 blr +} + +//unused +asm void __shr2u(void) +{ + nofralloc subfic r8, r5, 32 subic r9, r5, 32 srw r4, r4, r5 slw r10, r3, r8 or r4, r4, + r10 srw r10, r3, r9 or r4, r4, r10 srw r3, r3, r5 blr +} + +asm void __shr2i(void) +{ + subfic r8, r5, 0x20 addic.r9, r5, -0x20 srw r4, r4, r5 slw r10, r3, r8 or r4, r4, r10 sraw r10, + r3, r9 ble L_802BA610 or r4, r4, r10 L_802BA610 : sraw r3, r3, r5 blr +} + +asm void __cvt_sll_dbl(void) +{ + // clang-format off + stwu r1, -0x10(r1) + rlwinm. r5, r3, 0, 0, 0 + beq- lbl_802b2b1c + subfic r4, r4, 0x0 + subfze r3, r3 +lbl_802b2b1c: + or. r7, r3, r4 + li r6, 0x0 + beq- lbl_802b2ba4 + cntlzw r7, r3 + cntlzw r8, r4 + rlwinm r9, r7, 0x1a, 0, 4 + srawi r9, r9, 0x1f + and r9, r9, r8 + add r7, r7, r9 + subfic r8, r7, 0x20 + addic r9, r7, -0x20 + slw r3, r3, r7 + srw r10, r4, r8 + or r3, r3, r10 + slw r10, r4, r9 + or r3, r3, r10 + slw r4, r4, r7 + subf r6, r7, r6 + clrlwi r7, r4, 0x15 + cmpwi r7, 0x400 + addi r6, r6, 0x43e + blt- lbl_802b2b8c + bgt- lbl_802b2b80 + rlwinm. r7, r4, 0, 0x14, 0x14 + beq- lbl_802b2b8c +lbl_802b2b80: + addic r4, r4, 0x800 + addze r3, r3 + addze r6, r6 +lbl_802b2b8c: + rotlwi r4, r4, 0x15 + rlwimi r4, r3, 0x15, 0, 0xa + rlwinm r3, r3, 0x15, 0xc, 0x1f + slwi r6, r6, 0x14 + or r3, r6, r3 + or r3, r5, r3 +lbl_802b2ba4: + stw r3, 8(r1) + stw r4, 0xc(r1) + lfd f1, 8(r1) + addi r1, r1, 0x10 + frfree + blr + // clang-format on +} + +//unused +asm void __cvt_ull_dbl(void) +{ +} + +asm void __cvt_sll_flt(void) +{ + stwu r1, -0x10(r1)clrrwi.r5, r3, 31 beq L_802BA62C subfic r4, r4, 0x0 subfze r3, + r3 L_802BA62C : or.r7, r3, r4 li r6, 0x0 beq L_802BA6B4 cntlzw r7, r3 cntlzw r8, + r4 extlwi r9, r7, 5, 26 srawi r9, r9, 31 and r9, r9, r8 add r7, r7, r9 subfic r8, r7, + 0x20 addic r9, r7, -0x20 slw r3, r3, r7 srw r10, r4, r8 or r3, r3, r10 slw r10, r4, + r9 or r3, r3, r10 slw r4, r4, r7 subf r6, r7, r6 clrlwi r7, r4, 21 cmpwi r7, 0x400 addi r6, + r6, 0x43e blt L_802BA69C bgt L_802BA690 rlwinm.r7, r4, 0, 20, + 20 beq L_802BA69C L_802BA690 : addic r4, + r4, + 0x800 addze r3, + r3 addze r6, + r6 L_802BA69C : rotrwi r4, + r4, + 11 rlwimi r4, + r3, + 21, + 0, + 10 extrwi r3, + r3, + 20, + 1 slwi r6, + r6, + 20 or r3, + r6, + r3 or r3, + r5, + r3 L_802BA6B4 : stw r3, + 0x8(r1)stw r4, + 0xc(r1)lfd f1, + 0x8(r1)frsp f1, + f1 addi r1, + r1, + 0x10 blr +} + +//unused +asm void __cvt_ull_flt(void) +{ +} + +//unused +asm void __cvt_dbl_usll(void) +{ + nofralloc stwu r1, -16(r1)stfd f1, 8(r1)lwz r3, 8(r1)lwz r4, 12(r1)rlwinm r5, r3, 12, 21, + 31 cmpli cr0, 0, r5, 1023 bge cr0, not_fraction li r3, 0 li r4, + 0 b func_end not_fraction : mr r6, + r3 rlwinm r3, + r3, + 0, + 12, + 31 oris r3, + r3, + 0x0010 addi r5, + r5, + -1075 cmpwi cr0, + r5, + 0 bge cr0, + left neg r5, + r5 subfic r8, + r5, + 32 subic r9, + r5, + 32 srw r4, + r4, + r5 slw r10, + r3, + r8 or r4, + r4, + r10 srw r10, + r3, + r9 or r4, + r4, + r10 srw r3, + r3, + r5 b around left : cmpwi cr0, + r5, + 10 ble + no_overflow rlwinm.r6, + r6, + 0, + 0, + 0 beq cr0, + max_positive lis r3, + 0x8000 li r4, + 0 b func_end max_positive + : lis r3, + 0x7FFF ori r3, + r3, + 0xFFFF li r4, + -1 b func_end no_overflow : subfic r8, + r5, + 32 subic r9, + r5, + 32 slw r3, + r3, + r5 srw r10, + r4, + r8 or r3, + r3, + r10 slw r10, + r4, + r9 or r3, + r3, + r10 slw r4, + r4, + r5 around : rlwinm.r6, + r6, + 0, + 0, + 0 beq cr0, + positive subfic r4, + r4, + 0 subfze r3, + r3 positive : func_end : addi r1, + r1, + 16 blr +} + +void __cvt_dbl_ull(void) +{ + nofralloc stwu r1, -0x10(r1)stfd f1, 8(r1)lwz r3, 8(r1)lwz r4, 0xC(r1)extrwi r5, r3, 11, + 1 cmplwi r5, + 0x3FF bge loc_80518FB4 + + loc_80518FA8 : li r3, + 0 li r4, + 0 b end + + loc_80518FB4 : clrrwi.r6, + r3, + 31 bne loc_80518FA8 clrlwi r3, + r3, + 12 oris r3, + r3, + 0x10 addi r5, + r5, + -0x433 cmpwi r5, + 0 bge loc_80518FF8 neg r5, + r5 subfic r8, + r5, + 0x20 addic r9, + r5, + -0x20 srw r4, + r4, + r5 slw r10, + r3, + r8 or r4, + r4, + r10 srw r10, + r3, + r9 or r4, + r4, + r10 srw r3, + r3, + r5 b end + + loc_80518FF8 : cmpwi r5, + 0xB ble + loc_8051900C li r3, + -1 li r4, + -1 b end + + loc_8051900C : subfic r8, + r5, + 0x20 addic r9, + r5, + -0x20 slw r3, + r3, + r5 srw r10, + r4, + r8 or r3, + r3, + r10 slw r10, + r4, + r9 or r3, + r3, + r10 slw r4, + r4, + r5 + + end : addi r1, + r1, + 0x10 blr +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/runtime3/READ_ME.txt b/libs/PowerPC_EABI_Support/src/runtime3/READ_ME.txt new file mode 100644 index 000000000..b2a060cb8 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/runtime3/READ_ME.txt @@ -0,0 +1,6 @@ +These files are files that have issues that need to be fixed before the file can be +added back into the "Runtime" folder. + +These are outside of the scope of what I am aiming to do at the moment. + +- Colin \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/runtime3/runtime.c b/libs/PowerPC_EABI_Support/src/runtime3/runtime.c new file mode 100644 index 000000000..68cb136c6 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/runtime3/runtime.c @@ -0,0 +1,920 @@ +#ifdef __cplusplus +extern "C" { +#endif + +/* macros for GPR/FPR resting and saving */ +#define SAVE_FPR(reg) _savefpr_##reg +#define RESTORE_FPR(reg) _restfpr_##reg +#define SAVE_GPR(reg) _savegpr_##reg +#define RESTORE_GPR(reg) _restgpr_##reg +#define ENTRY_SAVE_FPR(reg) entry SAVE_FPR(reg) +#define ENTRY_RESTORE_FPR(reg) entry RESTORE_FPR(reg) +#define ENTRY_SAVE_GPR(reg) entry SAVE_GPR(reg) +#define ENTRY_RESTORE_GPR(reg) entry RESTORE_GPR(reg) +#define SAVE_FPR2(reg) _savef##reg +#define RESTORE_FPR2(reg) _restf##reg +#define ENTRY_SAVE_FPR2(reg) +#define ENTRY_RESTORE_FPR2(reg) + +#define save_restore_reg r11 + +asm void __div2u(void); +asm void __div2i(void); +asm void __mod2u(void); +asm void __mod2i(void); +asm void __shl2i(void); +asm void __shr2u(void); +asm void __shr2i(void); +asm void __cvt_sll_dbl(void); +asm void __cvt_ull_dbl(void); +asm void __cvt_sll_flt(void); +asm void __cvt_ull_flt(void); +asm void __cvt_dbl_usll(void); +asm void __cvt_dbl_ull(void); + +void SAVE_FPR(14)(void); +void SAVE_FPR(15)(void); +void SAVE_FPR(16)(void); +void SAVE_FPR(17)(void); +void SAVE_FPR(18)(void); +void SAVE_FPR(19)(void); +void SAVE_FPR(20)(void); +void SAVE_FPR(21)(void); +void SAVE_FPR(22)(void); +void SAVE_FPR(23)(void); +void SAVE_FPR(24)(void); +void SAVE_FPR(25)(void); +void SAVE_FPR(26)(void); +void SAVE_FPR(27)(void); +void SAVE_FPR(28)(void); +void SAVE_FPR(29)(void); +void SAVE_FPR(30)(void); +void SAVE_FPR(31)(void); +void SAVE_FPR2(14)(void); +void SAVE_FPR2(15)(void); +void SAVE_FPR2(16)(void); +void SAVE_FPR2(17)(void); +void SAVE_FPR2(18)(void); +void SAVE_FPR2(19)(void); +void SAVE_FPR2(20)(void); +void SAVE_FPR2(21)(void); +void SAVE_FPR2(22)(void); +void SAVE_FPR2(23)(void); +void SAVE_FPR2(24)(void); +void SAVE_FPR2(25)(void); +void SAVE_FPR2(26)(void); +void SAVE_FPR2(27)(void); +void SAVE_FPR2(28)(void); +void SAVE_FPR2(29)(void); +void SAVE_FPR2(30)(void); +void SAVE_FPR2(31)(void); +void RESTORE_FPR(14)(void); +void RESTORE_FPR(15)(void); +void RESTORE_FPR(16)(void); +void RESTORE_FPR(17)(void); +void RESTORE_FPR(18)(void); +void RESTORE_FPR(19)(void); +void RESTORE_FPR(20)(void); +void RESTORE_FPR(21)(void); +void RESTORE_FPR(22)(void); +void RESTORE_FPR(23)(void); +void RESTORE_FPR(24)(void); +void RESTORE_FPR(25)(void); +void RESTORE_FPR(26)(void); +void RESTORE_FPR(27)(void); +void RESTORE_FPR(28)(void); +void RESTORE_FPR(29)(void); +void RESTORE_FPR(30)(void); +void RESTORE_FPR(31)(void); +void RESTORE_FPR2(14)(void); +void RESTORE_FPR2(15)(void); +void RESTORE_FPR2(16)(void); +void RESTORE_FPR2(17)(void); +void RESTORE_FPR2(18)(void); +void RESTORE_FPR2(19)(void); +void RESTORE_FPR2(20)(void); +void RESTORE_FPR2(21)(void); +void RESTORE_FPR2(22)(void); +void RESTORE_FPR2(23)(void); +void RESTORE_FPR2(24)(void); +void RESTORE_FPR2(25)(void); +void RESTORE_FPR2(26)(void); +void RESTORE_FPR2(27)(void); +void RESTORE_FPR2(28)(void); +void RESTORE_FPR2(29)(void); +void RESTORE_FPR2(30)(void); +void RESTORE_FPR2(31)(void); +void SAVE_GPR(14)(void); +void SAVE_GPR(15)(void); +void SAVE_GPR(16)(void); +void SAVE_GPR(17)(void); +void SAVE_GPR(18)(void); +void SAVE_GPR(19)(void); +void SAVE_GPR(20)(void); +void SAVE_GPR(21)(void); +void SAVE_GPR(22)(void); +void SAVE_GPR(23)(void); +void SAVE_GPR(24)(void); +void SAVE_GPR(25)(void); +void SAVE_GPR(26)(void); +void SAVE_GPR(27)(void); +void SAVE_GPR(28)(void); +void SAVE_GPR(29)(void); +void SAVE_GPR(30)(void); +void SAVE_GPR(31)(void); +void RESTORE_GPR(14)(void); +void RESTORE_GPR(15)(void); +void RESTORE_GPR(16)(void); +void RESTORE_GPR(17)(void); +void RESTORE_GPR(18)(void); +void RESTORE_GPR(19)(void); +void RESTORE_GPR(20)(void); +void RESTORE_GPR(21)(void); +void RESTORE_GPR(22)(void); +void RESTORE_GPR(23)(void); +void RESTORE_GPR(24)(void); +void RESTORE_GPR(25)(void); +void RESTORE_GPR(26)(void); +void RESTORE_GPR(27)(void); +void RESTORE_GPR(28)(void); +void RESTORE_GPR(29)(void); +void RESTORE_GPR(30)(void); +void RESTORE_GPR(31)(void); + +static const unsigned long __constants[] = { + 0x00000000, 0x00000000, 0x41F00000, 0x00000000, 0x41E00000, 0x00000000, +}; + +asm unsigned long __cvt_fp2unsigned(register double d) +{ + nofralloc stwu r1, -16(r1)lis r4, __constants @h ori r4, r4, __constants @l li r3, 0 lfd fp0, + 0(r4)lfd fp3, 8(r4)lfd fp4, 16(r4)fcmpu cr0, fp1, fp0 fcmpu cr6, fp1, fp3 blt cr0, + @exit addi r3, r3, -1 bge cr6, @exit fcmpu cr7, fp1, fp4 fmr fp2, fp1 blt cr7, @1 fsub fp2, + fp1, fp4 @1 fctiwz fp2, fp2 stfd fp2, 8(r1)lwz r3, 12(r1)blt cr7, @exit addis r3, r3, + -0x8000 @exit : addi r1, r1, 16 blr +} + +static asm void __save_fpr(void) +{ + nofralloc ENTRY_SAVE_FPR(14) ENTRY_SAVE_FPR2(14) stfd fp14, + -144(save_restore_reg)ENTRY_SAVE_FPR(15) ENTRY_SAVE_FPR2(15) stfd fp15, + -136(save_restore_reg)ENTRY_SAVE_FPR(16) ENTRY_SAVE_FPR2(16) stfd fp16, + -128(save_restore_reg)ENTRY_SAVE_FPR(17) ENTRY_SAVE_FPR2(17) stfd fp17, + -120(save_restore_reg)ENTRY_SAVE_FPR(18) ENTRY_SAVE_FPR2(18) stfd fp18, + -112(save_restore_reg)ENTRY_SAVE_FPR(19) ENTRY_SAVE_FPR2(19) stfd fp19, + -104(save_restore_reg)ENTRY_SAVE_FPR(20) ENTRY_SAVE_FPR2(20) stfd fp20, + -96(save_restore_reg)ENTRY_SAVE_FPR(21) ENTRY_SAVE_FPR2(21) stfd fp21, + -88(save_restore_reg)ENTRY_SAVE_FPR(22) ENTRY_SAVE_FPR2(22) stfd fp22, + -80(save_restore_reg)ENTRY_SAVE_FPR(23) ENTRY_SAVE_FPR2(23) stfd fp23, + -72(save_restore_reg)ENTRY_SAVE_FPR(24) ENTRY_SAVE_FPR2(24) stfd fp24, + -64(save_restore_reg)ENTRY_SAVE_FPR(25) ENTRY_SAVE_FPR2(25) stfd fp25, + -56(save_restore_reg)ENTRY_SAVE_FPR(26) ENTRY_SAVE_FPR2(26) stfd fp26, + -48(save_restore_reg)ENTRY_SAVE_FPR(27) ENTRY_SAVE_FPR2(27) stfd fp27, + -40(save_restore_reg)ENTRY_SAVE_FPR(28) ENTRY_SAVE_FPR2(28) stfd fp28, + -32(save_restore_reg)ENTRY_SAVE_FPR(29) ENTRY_SAVE_FPR2(29) stfd fp29, + -24(save_restore_reg)ENTRY_SAVE_FPR(30) ENTRY_SAVE_FPR2(30) stfd fp30, + -16(save_restore_reg)ENTRY_SAVE_FPR(31) ENTRY_SAVE_FPR2(31) stfd fp31, + -8(save_restore_reg)blr +} + +static asm void __restore_fpr(void) +{ + nofralloc ENTRY_RESTORE_FPR(14) ENTRY_RESTORE_FPR2(14) lfd fp14, + -144(save_restore_reg)ENTRY_RESTORE_FPR(15) ENTRY_RESTORE_FPR2(15) lfd fp15, + -136(save_restore_reg)ENTRY_RESTORE_FPR(16) ENTRY_RESTORE_FPR2(16) lfd fp16, + -128(save_restore_reg)ENTRY_RESTORE_FPR(17) ENTRY_RESTORE_FPR2(17) lfd fp17, + -120(save_restore_reg)ENTRY_RESTORE_FPR(18) ENTRY_RESTORE_FPR2(18) lfd fp18, + -112(save_restore_reg)ENTRY_RESTORE_FPR(19) ENTRY_RESTORE_FPR2(19) lfd fp19, + -104(save_restore_reg)ENTRY_RESTORE_FPR(20) ENTRY_RESTORE_FPR2(20) lfd fp20, + -96(save_restore_reg)ENTRY_RESTORE_FPR(21) ENTRY_RESTORE_FPR2(21) lfd fp21, + -88(save_restore_reg)ENTRY_RESTORE_FPR(22) ENTRY_RESTORE_FPR2(22) lfd fp22, + -80(save_restore_reg)ENTRY_RESTORE_FPR(23) ENTRY_RESTORE_FPR2(23) lfd fp23, + -72(save_restore_reg)ENTRY_RESTORE_FPR(24) ENTRY_RESTORE_FPR2(24) lfd fp24, + -64(save_restore_reg)ENTRY_RESTORE_FPR(25) ENTRY_RESTORE_FPR2(25) lfd fp25, + -56(save_restore_reg)ENTRY_RESTORE_FPR(26) ENTRY_RESTORE_FPR2(26) lfd fp26, + -48(save_restore_reg)ENTRY_RESTORE_FPR(27) ENTRY_RESTORE_FPR2(27) lfd fp27, + -40(save_restore_reg)ENTRY_RESTORE_FPR(28) ENTRY_RESTORE_FPR2(28) lfd fp28, + -32(save_restore_reg)ENTRY_RESTORE_FPR(29) ENTRY_RESTORE_FPR2(29) lfd fp29, + -24(save_restore_reg)ENTRY_RESTORE_FPR(30) ENTRY_RESTORE_FPR2(30) lfd fp30, + -16(save_restore_reg)ENTRY_RESTORE_FPR(31) ENTRY_RESTORE_FPR2(31) lfd fp31, + -8(save_restore_reg)blr +} + +static asm void __save_gpr(void) +{ + nofralloc ENTRY_SAVE_GPR(14) stw r14, -72(save_restore_reg)ENTRY_SAVE_GPR(15) stw r15, + -68(save_restore_reg)ENTRY_SAVE_GPR(16) stw r16, + -64(save_restore_reg)ENTRY_SAVE_GPR(17) stw r17, + -60(save_restore_reg)ENTRY_SAVE_GPR(18) stw r18, + -56(save_restore_reg)ENTRY_SAVE_GPR(19) stw r19, + -52(save_restore_reg)ENTRY_SAVE_GPR(20) stw r20, + -48(save_restore_reg)ENTRY_SAVE_GPR(21) stw r21, + -44(save_restore_reg)ENTRY_SAVE_GPR(22) stw r22, + -40(save_restore_reg)ENTRY_SAVE_GPR(23) stw r23, + -36(save_restore_reg)ENTRY_SAVE_GPR(24) stw r24, + -32(save_restore_reg)ENTRY_SAVE_GPR(25) stw r25, + -28(save_restore_reg)ENTRY_SAVE_GPR(26) stw r26, + -24(save_restore_reg)ENTRY_SAVE_GPR(27) stw r27, + -20(save_restore_reg)ENTRY_SAVE_GPR(28) stw r28, + -16(save_restore_reg)ENTRY_SAVE_GPR(29) stw r29, + -12(save_restore_reg)ENTRY_SAVE_GPR(30) stw r30, + -8(save_restore_reg)ENTRY_SAVE_GPR(31) stw r31, -4(save_restore_reg)blr +} + +static asm void __restore_gpr(void) +{ + nofralloc ENTRY_RESTORE_GPR(14) lwz r14, -72(save_restore_reg)ENTRY_RESTORE_GPR(15) lwz r15, + -68(save_restore_reg)ENTRY_RESTORE_GPR(16) lwz r16, + -64(save_restore_reg)ENTRY_RESTORE_GPR(17) lwz r17, + -60(save_restore_reg)ENTRY_RESTORE_GPR(18) lwz r18, + -56(save_restore_reg)ENTRY_RESTORE_GPR(19) lwz r19, + -52(save_restore_reg)ENTRY_RESTORE_GPR(20) lwz r20, + -48(save_restore_reg)ENTRY_RESTORE_GPR(21) lwz r21, + -44(save_restore_reg)ENTRY_RESTORE_GPR(22) lwz r22, + -40(save_restore_reg)ENTRY_RESTORE_GPR(23) lwz r23, + -36(save_restore_reg)ENTRY_RESTORE_GPR(24) lwz r24, + -32(save_restore_reg)ENTRY_RESTORE_GPR(25) lwz r25, + -28(save_restore_reg)ENTRY_RESTORE_GPR(26) lwz r26, + -24(save_restore_reg)ENTRY_RESTORE_GPR(27) lwz r27, + -20(save_restore_reg)ENTRY_RESTORE_GPR(28) lwz r28, + -16(save_restore_reg)ENTRY_RESTORE_GPR(29) lwz r29, + -12(save_restore_reg)ENTRY_RESTORE_GPR(30) lwz r30, + -8(save_restore_reg)ENTRY_RESTORE_GPR(31) lwz r31, -4(save_restore_reg)blr +} + +asm void __div2u(void) +{ + nofralloc cmpwi cr0, r3, 0 cntlzw r0, r3 cntlzw r9, r4 bne cr0, lab1 addi r0, r9, + 32 lab1 : cmpwi cr0, + r5, + 0 cntlzw r9, + r5 cntlzw r10, + r6 bne cr0, + lab2 addi r9, + r10, + 32 lab2 : cmpw cr0, + r0, + r9 subfic r10, + r0, + 64 bgt cr0, + lab9 addi r9, + r9, + 1 subfic r9, + r9, + 64 add r0, + r0, + r9 subf r9, + r9, + r10 mtctr r9 cmpwi cr0, + r9, + 32 addi r7, + r9, + -32 blt cr0, + lab3 srw r8, + r3, + r7 li r7, + 0 b lab4 lab3 : srw r8, + r4, + r9 subfic r7, + r9, + 32 slw r7, + r3, + r7 or r8, + r8, + r7 srw r7, + r3, + r9 lab4 : cmpwi cr0, + r0, + 32 addic r9, + r0, + -32 blt cr0, + lab5 slw r3, + r4, + r9 li r4, + 0 b lab6 lab5 : slw r3, + r3, + r0 subfic r9, + r0, + 32 srw r9, + r4, + r9 or r3, + r3, + r9 slw r4, + r4, + r0 lab6 : li r10, + -1 addic r7, + r7, + 0 lab7 + : adde r4, + r4, + r4 adde r3, + r3, + r3 adde r8, + r8, + r8 adde r7, + r7, + r7 subfc r0, + r6, + r8 subfe.r9, + r5, + r7 blt cr0, + lab8 mr r8, + r0 mr r7, + r9 addic r0, + r10, + 1 lab8 : bdnz lab7 adde r4, + r4, + r4 adde r3, + r3, + r3 blr lab9 : li r4, + 0 li r3, + 0 blr +} + +#pragma push +#pragma optimization_level 0 +#pragma optimizewithasm off +asm void __div2i(void) +{ + nofralloc stwu r1, -16(r1)rlwinm.r9, r3, 0, 0, 0 beq cr0, positive1 subfic r4, r4, 0 subfze r3, + r3 positive1 : stw r9, + 8(r1)rlwinm.r10, + r5, + 0, + 0, + 0 beq cr0, + positive2 subfic r6, + r6, + 0 subfze r5, + r5 positive2 : stw r10, + 12(r1)cmpwi cr0, + r3, + 0 cntlzw r0, + r3 cntlzw r9, + r4 bne cr0, + lab1 addi r0, + r9, + 32 lab1 : cmpwi cr0, + r5, + 0 cntlzw r9, + r5 cntlzw r10, + r6 bne cr0, + lab2 addi r9, + r10, + 32 lab2 : cmpw cr0, + r0, + r9 subfic r10, + r0, + 64 bgt cr0, + lab9 addi r9, + r9, + 1 subfic r9, + r9, + 64 add r0, + r0, + r9 subf r9, + r9, + r10 mtctr r9 cmpwi cr0, + r9, + 32 addi r7, + r9, + -32 blt cr0, + lab3 srw r8, + r3, + r7 li r7, + 0 b lab4 lab3 : srw r8, + r4, + r9 subfic r7, + r9, + 32 slw r7, + r3, + r7 or r8, + r8, + r7 srw r7, + r3, + r9 lab4 : cmpwi cr0, + r0, + 32 addic r9, + r0, + -32 blt cr0, + lab5 slw r3, + r4, + r9 li r4, + 0 b lab6 lab5 + : slw r3, + r3, + r0 subfic r9, + r0, + 32 srw r9, + r4, + r9 or r3, + r3, + r9 slw r4, + r4, + r0 lab6 : li r10, + -1 addic r7, + r7, + 0 lab7 : adde r4, + r4, + r4 adde r3, + r3, + r3 adde r8, + r8, + r8 adde r7, + r7, + r7 subfc r0, + r6, + r8 subfe.r9, + r5, + r7 blt cr0, + lab8 mr r8, + r0 mr r7, + r9 addic r0, + r10, + 1 lab8 : bdnz lab7 adde r4, + r4, + r4 adde r3, + r3, + r3 lwz r9, + 8(r1)lwz r10, + 12(r1) xor.r7, + r9, + r10 beq func_end cmpwi cr0, + r9, + 0 subfic r4, + r4, + 0 subfze r3, + r3 + + no_adjust : b func_end + + lab9 : li r4, + 0 li r3, + 0 func_end : addi r1, + r1, + 16 blr +} +#pragma pop + +#pragma push +#pragma optimization_level 0 +#pragma optimizewithasm off +asm void __mod2u(void) +{ + nofralloc cmpwi cr0, r3, 0 cntlzw r0, r3 cntlzw r9, r4 bne cr0, lab1 addi r0, r9, + 32 lab1 : cmpwi cr0, + r5, + 0 cntlzw r9, + r5 cntlzw r10, + r6 bne cr0, + lab2 addi r9, + r10, + 32 lab2 : cmpw cr0, + r0, + r9 subfic r10, + r0, + 64 bgtlr cr0 addi r9, + r9, + 1 subfic r9, + r9, + 64 add r0, + r0, + r9 subf r9, + r9, + r10 mtctr r9 cmpwi cr0, + r9, + 32 addi r7, + r9, + -32 blt cr0, + lab3 srw r8, + r3, + r7 li r7, + 0 b lab4 lab3 : srw r8, + r4, + r9 subfic r7, + r9, + 32 slw r7, + r3, + r7 or r8, + r8, + r7 srw r7, + r3, + r9 lab4 : cmpwi cr0, + r0, + 32 addic r9, + r0, + -32 blt cr0, + lab5 slw r3, + r4, + r9 li r4, + 0 b lab6 lab5 : slw r3, + r3, + r0 subfic r9, + r0, + 32 srw r9, + r4, + r9 or r3, + r3, + r9 slw r4, + r4, + r0 lab6 : li r10, + -1 addic r7, + r7, + 0 lab7 + : adde r4, + r4, + r4 adde r3, + r3, + r3 adde r8, + r8, + r8 adde r7, + r7, + r7 subfc r0, + r6, + r8 subfe.r9, + r5, + r7 blt cr0, + lab8 mr r8, + r0 mr r7, + r9 addic r0, + r10, + 1 lab8 : bdnz lab7 mr r4, + r8 mr r3, + r7 blr lab9 : blr +} +#pragma pop + +#pragma push +#pragma optimization_level 0 +#pragma optimizewithasm off +asm void __mod2i(void) +{ + nofralloc + + cmpwi cr7, + r3, 0 bge cr7, positive1 subfic r4, r4, 0 subfze r3, + r3 positive1 : cmpwi cr0, + r5, + 0 bge cr0, + positive2 subfic r6, + r6, + 0 subfze r5, + r5 positive2 : cmpwi cr0, + r3, + 0 cntlzw r0, + r3 cntlzw r9, + r4 bne cr0, + lab1 addi r0, + r9, + 32 lab1 : cmpwi cr0, + r5, + 0 cntlzw r9, + r5 cntlzw r10, + r6 bne cr0, + lab2 addi r9, + r10, + 32 lab2 : cmpw cr0, + r0, + r9 subfic r10, + r0, + 64 bgt cr0, + lab9 addi r9, + r9, + 1 subfic r9, + r9, + 64 add r0, + r0, + r9 subf r9, + r9, + r10 mtctr r9 cmpwi cr0, + r9, + 32 addi r7, + r9, + -32 blt cr0, + lab3 srw r8, + r3, + r7 li r7, + 0 b lab4 lab3 : srw r8, + r4, + r9 subfic r7, + r9, + 32 slw r7, + r3, + r7 or r8, + r8, + r7 srw r7, + r3, + r9 lab4 : cmpwi cr0, + r0, + 32 addic r9, + r0, + -32 blt cr0, + lab5 slw r3, + r4, + r9 li r4, + 0 b lab6 lab5 + : slw r3, + r3, + r0 subfic r9, + r0, + 32 srw r9, + r4, + r9 or r3, + r3, + r9 slw r4, + r4, + r0 lab6 : li r10, + -1 addic r7, + r7, + 0 lab7 : adde r4, + r4, + r4 adde r3, + r3, + r3 adde r8, + r8, + r8 adde r7, + r7, + r7 subfc r0, + r6, + r8 subfe.r9, + r5, + r7 blt cr0, + lab8 mr r8, + r0 mr r7, + r9 addic r0, + r10, + 1 lab8 : bdnz lab7 mr r4, + r8 mr r3, + r7 lab9 : bgelr cr7 subfic r4, + r4, + 0 subfze r3, + r3 no_adjust : blr +} +#pragma pop + +asm void __shl2i(void) +{ + nofralloc subfic r8, r5, 32 subic r9, r5, 32 slw r3, r3, r5 srw r10, r4, r8 or r3, r3, + r10 slw r10, r4, r9 or r3, r3, r10 slw r4, r4, r5 blr +} + +//unused +asm void __shr2u(void) +{ + nofralloc subfic r8, r5, 32 subic r9, r5, 32 srw r4, r4, r5 slw r10, r3, r8 or r4, r4, + r10 srw r10, r3, r9 or r4, r4, r10 srw r3, r3, r5 blr +} + +asm void __shr2i(void) +{ + subfic r8, r5, 0x20 addic.r9, r5, -0x20 srw r4, r4, r5 slw r10, r3, r8 or r4, r4, r10 sraw r10, + r3, r9 ble L_802BA610 or r4, r4, r10 L_802BA610 : sraw r3, r3, r5 blr +} + +asm void __cvt_sll_dbl(void) +{ + // clang-format off + stwu r1, -0x10(r1) + rlwinm. r5, r3, 0, 0, 0 + beq- lbl_802b2b1c + subfic r4, r4, 0x0 + subfze r3, r3 +lbl_802b2b1c: + or. r7, r3, r4 + li r6, 0x0 + beq- lbl_802b2ba4 + cntlzw r7, r3 + cntlzw r8, r4 + rlwinm r9, r7, 0x1a, 0, 4 + srawi r9, r9, 0x1f + and r9, r9, r8 + add r7, r7, r9 + subfic r8, r7, 0x20 + addic r9, r7, -0x20 + slw r3, r3, r7 + srw r10, r4, r8 + or r3, r3, r10 + slw r10, r4, r9 + or r3, r3, r10 + slw r4, r4, r7 + subf r6, r7, r6 + clrlwi r7, r4, 0x15 + cmpwi r7, 0x400 + addi r6, r6, 0x43e + blt- lbl_802b2b8c + bgt- lbl_802b2b80 + rlwinm. r7, r4, 0, 0x14, 0x14 + beq- lbl_802b2b8c +lbl_802b2b80: + addic r4, r4, 0x800 + addze r3, r3 + addze r6, r6 +lbl_802b2b8c: + rotlwi r4, r4, 0x15 + rlwimi r4, r3, 0x15, 0, 0xa + rlwinm r3, r3, 0x15, 0xc, 0x1f + slwi r6, r6, 0x14 + or r3, r6, r3 + or r3, r5, r3 +lbl_802b2ba4: + stw r3, 8(r1) + stw r4, 0xc(r1) + lfd f1, 8(r1) + addi r1, r1, 0x10 + frfree + blr + // clang-format on +} + +//unused +asm void __cvt_ull_dbl(void) +{ +} + +asm void __cvt_sll_flt(void) +{ + stwu r1, -0x10(r1)clrrwi.r5, r3, 31 beq L_802BA62C subfic r4, r4, 0x0 subfze r3, + r3 L_802BA62C : or.r7, r3, r4 li r6, 0x0 beq L_802BA6B4 cntlzw r7, r3 cntlzw r8, + r4 extlwi r9, r7, 5, 26 srawi r9, r9, 31 and r9, r9, r8 add r7, r7, r9 subfic r8, r7, + 0x20 addic r9, r7, -0x20 slw r3, r3, r7 srw r10, r4, r8 or r3, r3, r10 slw r10, r4, + r9 or r3, r3, r10 slw r4, r4, r7 subf r6, r7, r6 clrlwi r7, r4, 21 cmpwi r7, 0x400 addi r6, + r6, 0x43e blt L_802BA69C bgt L_802BA690 rlwinm.r7, r4, 0, 20, + 20 beq L_802BA69C L_802BA690 : addic r4, + r4, + 0x800 addze r3, + r3 addze r6, + r6 L_802BA69C : rotrwi r4, + r4, + 11 rlwimi r4, + r3, + 21, + 0, + 10 extrwi r3, + r3, + 20, + 1 slwi r6, + r6, + 20 or r3, + r6, + r3 or r3, + r5, + r3 L_802BA6B4 : stw r3, + 0x8(r1)stw r4, + 0xc(r1)lfd f1, + 0x8(r1)frsp f1, + f1 addi r1, + r1, + 0x10 blr +} + +//unused +asm void __cvt_ull_flt(void) +{ +} + +//unused +asm void __cvt_dbl_usll(void) +{ + nofralloc stwu r1, -16(r1)stfd f1, 8(r1)lwz r3, 8(r1)lwz r4, 12(r1)rlwinm r5, r3, 12, 21, + 31 cmpli cr0, 0, r5, 1023 bge cr0, not_fraction li r3, 0 li r4, + 0 b func_end not_fraction : mr r6, + r3 rlwinm r3, + r3, + 0, + 12, + 31 oris r3, + r3, + 0x0010 addi r5, + r5, + -1075 cmpwi cr0, + r5, + 0 bge cr0, + left neg r5, + r5 subfic r8, + r5, + 32 subic r9, + r5, + 32 srw r4, + r4, + r5 slw r10, + r3, + r8 or r4, + r4, + r10 srw r10, + r3, + r9 or r4, + r4, + r10 srw r3, + r3, + r5 b around left : cmpwi cr0, + r5, + 10 ble + no_overflow rlwinm.r6, + r6, + 0, + 0, + 0 beq cr0, + max_positive lis r3, + 0x8000 li r4, + 0 b func_end max_positive + : lis r3, + 0x7FFF ori r3, + r3, + 0xFFFF li r4, + -1 b func_end no_overflow : subfic r8, + r5, + 32 subic r9, + r5, + 32 slw r3, + r3, + r5 srw r10, + r4, + r8 or r3, + r3, + r10 slw r10, + r4, + r9 or r3, + r3, + r10 slw r4, + r4, + r5 around : rlwinm.r6, + r6, + 0, + 0, + 0 beq cr0, + positive subfic r4, + r4, + 0 subfze r3, + r3 positive : func_end : addi r1, + r1, + 16 blr +} + +void __cvt_dbl_ull(void) +{ + nofralloc stwu r1, -0x10(r1)stfd f1, 8(r1)lwz r3, 8(r1)lwz r4, 0xC(r1)extrwi r5, r3, 11, + 1 cmplwi r5, + 0x3FF bge loc_80518FB4 + + loc_80518FA8 : li r3, + 0 li r4, + 0 b end + + loc_80518FB4 : clrrwi.r6, + r3, + 31 bne loc_80518FA8 clrlwi r3, + r3, + 12 oris r3, + r3, + 0x10 addi r5, + r5, + -0x433 cmpwi r5, + 0 bge loc_80518FF8 neg r5, + r5 subfic r8, + r5, + 0x20 addic r9, + r5, + -0x20 srw r4, + r4, + r5 slw r10, + r3, + r8 or r4, + r4, + r10 srw r10, + r3, + r9 or r4, + r4, + r10 srw r3, + r3, + r5 b end + + loc_80518FF8 : cmpwi r5, + 0xB ble + loc_8051900C li r3, + -1 li r4, + -1 b end + + loc_8051900C : subfic r8, + r5, + 0x20 addic r9, + r5, + -0x20 slw r3, + r3, + r5 srw r10, + r4, + r8 or r3, + r3, + r10 slw r10, + r4, + r9 or r3, + r3, + r10 slw r4, + r4, + r5 + + end : addi r1, + r1, + 0x10 blr +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libs/dolphin/OdemuExi2/DebuggerDriver.c b/libs/dolphin/OdemuExi2/DebuggerDriver.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ai/ai.c b/libs/dolphin/ai/ai.c new file mode 100644 index 000000000..a351534ba --- /dev/null +++ b/libs/dolphin/ai/ai.c @@ -0,0 +1,354 @@ +#include "dolphin/ai.h" +#include "dolphin/hw_regs.h" +#include "dolphin/os.h" + +const char* __AIVersion = "<< Dolphin SDK - AI\trelease build: Apr 17 2003 12:33:54 (0x2301) >>"; + +static AISCallback __AIS_Callback = NULL; +static AIDCallback __AID_Callback = NULL; +static u8* __CallbackStack; +static u8* __OldStack; +static volatile s32 __AI_init_flag = FALSE; +static volatile s32 __AID_Active = FALSE; + +static OSTime bound_32KHz; +static OSTime bound_48KHz; +static OSTime min_wait; +static OSTime max_wait; +static OSTime buffer; + +void __AISHandler(s16 interrupt, OSContext* context); +void __AIDHandler(s16 interrupt, OSContext* context); +void __AICallbackStackSwitch(register AIDCallback cb); +void __AI_SRC_INIT(void); + +AIDCallback AIRegisterDMACallback(AIDCallback callback) +{ + s32 oldInts; + AIDCallback ret; + + ret = __AID_Callback; + oldInts = OSDisableInterrupts(); + __AID_Callback = callback; + OSRestoreInterrupts(oldInts); + return ret; +} + +void AIInitDMA(u32 addr, u32 length) +{ + s32 oldInts; + oldInts = OSDisableInterrupts(); + __DSPRegs[24] = (u16)((__DSPRegs[24] & ~0x3FF) | (addr >> 16)); + __DSPRegs[25] = (u16)((__DSPRegs[25] & ~0xFFE0) | (0xffff & addr)); + __DSPRegs[27] = (u16)((__DSPRegs[27] & ~0x7FFF) | (u16)((length >> 5) & 0xFFFF)); + OSRestoreInterrupts(oldInts); +} + +void AIStartDMA() +{ + __DSPRegs[27] |= 0x8000; +} + +void AIStopDMA(void) +{ + __DSPRegs[27] &= ~0x8000; +} + +void AISetStreamPlayState(u32 state) +{ + s32 oldInts; + u8 volRight; + u8 volLeft; + + if (state == AIGetStreamPlayState()) + { + return; + } + if ((AIGetStreamSampleRate() == 0U) && (state == 1)) + { + volRight = AIGetStreamVolRight(); + volLeft = AIGetStreamVolLeft(); + AISetStreamVolRight(0); + AISetStreamVolLeft(0); + oldInts = OSDisableInterrupts(); + __AI_SRC_INIT(); + __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20; + __AIRegs[0] = (__AIRegs[0] & ~1) | 1; + OSRestoreInterrupts(oldInts); + AISetStreamVolLeft(volRight); + AISetStreamVolRight(volLeft); + } + else + { + __AIRegs[0] = (__AIRegs[0] & ~1) | state; + } +} + +u32 AIGetStreamPlayState() +{ + return __AIRegs[0] & 1; +} + +void AISetDSPSampleRate(u32 rate) +{ + u32 state; + s32 oldInts; + u8 left; + u8 right; + u32 sampleRate; + + if (rate == AIGetDSPSampleRate()) + { + return; + } + + __AIRegs[0] &= ~0x40; + if (rate == 0) + { + left = AIGetStreamVolLeft(); + right = AIGetStreamVolRight(); + state = AIGetStreamPlayState(); + sampleRate = AIGetStreamSampleRate(); + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + oldInts = OSDisableInterrupts(); + __AI_SRC_INIT(); + __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20; + __AIRegs[0] = (__AIRegs[0] & ~2) | (sampleRate * 2); + __AIRegs[0] = (__AIRegs[0] & ~1) | state; + __AIRegs[0] |= 0x40; + OSRestoreInterrupts(oldInts); + AISetStreamVolLeft(left); + AISetStreamVolRight(right); + } +} + +u32 AIGetDSPSampleRate() +{ + return ((__AIRegs[0] >> 6) & 1) ^ 1; +} + +void __AI_set_stream_sample_rate(u32 rate) +{ + s32 oldInts; + s32 state; + u8 left; + u8 right; + s32 temp_r26; + + if (rate == AIGetStreamSampleRate()) + { + return; + } + state = AIGetStreamPlayState(); + left = AIGetStreamVolLeft(); + right = AIGetStreamVolRight(); + AISetStreamVolRight(0); + AISetStreamVolLeft(0); + temp_r26 = __AIRegs[0] & 0x40; + __AIRegs[0] &= ~0x40; + oldInts = OSDisableInterrupts(); + __AI_SRC_INIT(); + __AIRegs[0] |= temp_r26; + __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20; + __AIRegs[0] = (__AIRegs[0] & ~2) | (rate * 2); + OSRestoreInterrupts(oldInts); + AISetStreamPlayState(state); + AISetStreamVolLeft(left); + AISetStreamVolRight(right); +} + +u32 AIGetStreamSampleRate() +{ + return (__AIRegs[0] >> 1) & 1; +} + +void AISetStreamVolLeft(u8 volume) +{ + __AIRegs[1] = (__AIRegs[1] & ~0xFF) | (volume & 0xFF); +} + +u8 AIGetStreamVolLeft() +{ + return __AIRegs[1]; +} + +void AISetStreamVolRight(u8 volume) +{ + __AIRegs[1] = (__AIRegs[1] & ~0xFF00) | ((volume & 0xFF) << 8); +} + +u8 AIGetStreamVolRight() +{ + return __AIRegs[1] >> 8; +} + +void AIInit(u8* stack) +{ + if (__AI_init_flag == TRUE) + { + return; + } + + 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); + __AIRegs[3] = 0; + __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20; + __AI_set_stream_sample_rate(1); + AISetDSPSampleRate(0); + __AIS_Callback = 0; + __AID_Callback = 0; + __CallbackStack = stack; + __OSSetInterruptHandler(5, __AIDHandler); + __OSUnmaskInterrupts(0x04000000); + __OSSetInterruptHandler(8, __AISHandler); + __OSUnmaskInterrupts(0x800000); + __AI_init_flag = TRUE; +} + +void __AISHandler(s16 interrupt, OSContext* context) +{ + OSContext tmpContext; + __AIRegs[0] |= 8; + OSClearContext(&tmpContext); + OSSetCurrentContext(&tmpContext); + if (__AIS_Callback != NULL) + { + __AIS_Callback(__AIRegs[2]); + } + OSClearContext(&tmpContext); + OSSetCurrentContext(context); +} + +void __AIDHandler(s16 interrupt, OSContext* context) +{ + OSContext tempContext; + u32 temp = __DSPRegs[5]; + __DSPRegs[5] = (temp & ~0xA0) | 8; + OSClearContext(&tempContext); + OSSetCurrentContext(&tempContext); + if (__AID_Callback && !__AID_Active) + { + __AID_Active = TRUE; + if (__CallbackStack) + { + __AICallbackStackSwitch(__AID_Callback); + } + else + { + __AID_Callback(); + } + + __AID_Active = FALSE; + } + + OSClearContext(&tempContext); + OSSetCurrentContext(context); +} + +// clang-format off +asm void __AICallbackStackSwitch(register AIDCallback cb) { + // Allocate stack frame + fralloc + + // Store current stack + lis r5, __OldStack@ha + addi r5, r5, __OldStack@l + stw r1, 0(r5) + + // Load stack for callback + lis r5, __CallbackStack@ha + addi r5, r5, __CallbackStack@l + lwz r1,0(r5) + + // Move stack down 8 bytes + subi r1, r1, 8 + // Call callback + mtlr cb + blrl + + // Restore old stack + lis r5, __OldStack @ha + addi r5, r5, __OldStack@l + lwz r1,0(r5) + + // Free stack frame + frfree + + blr +} +// clang-format on + +void __AI_SRC_INIT(void) +{ + OSTime rising_32khz = 0; + OSTime rising_48khz = 0; + OSTime diff = 0; + OSTime t1 = 0; + OSTime temp = 0; + u32 temp0 = 0; + u32 temp1 = 0; + u32 done = 0; + u32 volume = 0; + u32 Init_Cnt = 0; + u32 walking = 0; + + walking = 0; + Init_Cnt = 0; + temp = 0; + + while (!done) + { + __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20; + __AIRegs[0] &= ~2; + __AIRegs[0] = (__AIRegs[0] & ~1) | 1; + + temp0 = __AIRegs[2]; + + while (temp0 == __AIRegs[2]) + ; + rising_32khz = OSGetTime(); + + __AIRegs[0] = (__AIRegs[0] & ~2) | 2; + __AIRegs[0] = (__AIRegs[0] & ~1) | 1; + + temp1 = __AIRegs[2]; + while (temp1 == __AIRegs[2]) + ; + + rising_48khz = OSGetTime(); + + diff = rising_48khz - rising_32khz; + __AIRegs[0] &= ~2; + __AIRegs[0] &= ~1; + + if (diff < (bound_32KHz - buffer)) + { + temp = min_wait; + done = 1; + ++Init_Cnt; + } + else if (diff >= (bound_32KHz + buffer) && diff < (bound_48KHz - buffer)) + { + temp = max_wait; + done = 1; + ++Init_Cnt; + } + else + { + done = 0; + walking = 1; + ++Init_Cnt; + } + } + + while ((rising_48khz + temp) > OSGetTime()) + ; +} \ No newline at end of file diff --git a/libs/dolphin/ar/ar.c b/libs/dolphin/ar/ar.c new file mode 100644 index 000000000..c3ed78946 --- /dev/null +++ b/libs/dolphin/ar/ar.c @@ -0,0 +1,383 @@ +#include "dolphin/ar/ar.h" + +#include "dolphin/hw_regs.h" +#include "dolphin/os.h" + +static const char* __ARVersion = + "<< Dolphin SDK - AR\trelease build: Apr 17 2003 12:33:55 (0x2301) >>"; + +static ARCallback __AR_Callback; +static u32 __AR_Size; +static u32 __AR_InternalSize; +static u32 __AR_ExpansionSize; + +static u32 __AR_StackPointer; +static u32 __AR_FreeBlocks; +static u32* __AR_BlockLength; + +static volatile BOOL __AR_init_flag = FALSE; + +static void __ARHandler(__OSInterrupt interrupt, OSContext* context); +static void __ARChecksize(void); +static void __ARClearArea(u32 start_addr, u32 length); + +ARCallback ARRegisterDMACallback(ARCallback callback) +{ + ARCallback oldCb; + BOOL enabled; + oldCb = __AR_Callback; + enabled = OSDisableInterrupts(); + __AR_Callback = callback; + OSRestoreInterrupts(enabled); + return oldCb; +} + +void ARStartDMA(u32 type, u32 mainmem_addr, u32 aram_addr, u32 length) +{ + BOOL enabled; + + enabled = OSDisableInterrupts(); + + __DSPRegs[16] = (u16)(__DSPRegs[16] & ~0x3ff) | (u16)(mainmem_addr >> 16); + __DSPRegs[17] = (u16)(__DSPRegs[17] & ~0xffe0) | (u16)(mainmem_addr & 0xffff); + __DSPRegs[18] = (u16)(__DSPRegs[18] & ~0x3ff) | (u16)(aram_addr >> 16); + __DSPRegs[19] = (u16)(__DSPRegs[19] & ~0xffe0) | (u16)(aram_addr & 0xffff); + __DSPRegs[20] = (u16)((__DSPRegs[20] & ~0x8000) | (type << 15)); + __DSPRegs[20] = (u16)(__DSPRegs[20] & ~0x3ff) | (u16)(length >> 16); + __DSPRegs[21] = (u16)(__DSPRegs[21] & ~0xffe0) | (u16)(length & 0xffff); + OSRestoreInterrupts(enabled); +} + +u32 ARAlloc(u32 length) +{ + u32 tmp; + BOOL enabled; + + enabled = OSDisableInterrupts(); + tmp = __AR_StackPointer; + __AR_StackPointer += length; + *__AR_BlockLength = length; + __AR_BlockLength++; + __AR_FreeBlocks--; + OSRestoreInterrupts(enabled); + + return tmp; +} + +u32 ARFree(u32* length) +{ + BOOL old; + + old = OSDisableInterrupts(); + + __AR_BlockLength--; + + if (length) + { + *length = *__AR_BlockLength; + } + + __AR_StackPointer -= *__AR_BlockLength; + + __AR_FreeBlocks++; + + OSRestoreInterrupts(old); + + return __AR_StackPointer; +} + +u32 ARInit(u32* stack_index_addr, u32 num_entries) +{ + BOOL old; + u16 refresh; + + if (__AR_init_flag == TRUE) + { + return 0x4000; + } + + OSRegisterVersion(__ARVersion); + + old = OSDisableInterrupts(); + + __AR_Callback = NULL; + + __OSSetInterruptHandler(__OS_INTERRUPT_DSP_ARAM, __ARHandler); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_DSP_ARAM); + + __AR_StackPointer = 0x4000; + __AR_FreeBlocks = num_entries; + __AR_BlockLength = stack_index_addr; + + refresh = (u16)(__DSPRegs[13] & 0x000000ff); + + __DSPRegs[13] = (u16)((__DSPRegs[13] & ~0x000000ff) | (refresh & 0x000000ff)); + + __ARChecksize(); + + __AR_init_flag = TRUE; + + OSRestoreInterrupts(old); + + return __AR_StackPointer; +} + +static void __ARHandler(__OSInterrupt interrupt, OSContext* context) +{ + OSContext exceptionContext; + u16 tmp; + + tmp = __DSPRegs[5]; + tmp = (u16)((tmp & ~0x00000088) | 0x20); + __DSPRegs[5] = tmp; + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + if (__AR_Callback) + { + (*__AR_Callback)(); + } + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +#define RoundUP32(x) (((u32)(x) + 32 - 1) & ~(32 - 1)) + +static void __ARWriteDMA(u32 mmem_addr, u32 aram_addr, u32 length) +{ + u16 tmp; + __DSPRegs[16] = (u16)((__DSPRegs[16] & ~0x03ff) | (u16)(mmem_addr >> 16)); + __DSPRegs[16 + 1] = (u16)((__DSPRegs[16 + 1] & ~0xffe0) | (u16)(mmem_addr & 0xffff)); + + __DSPRegs[18] = (u16)((__DSPRegs[18] & ~0x03ff) | (u16)(aram_addr >> 16)); + __DSPRegs[18 + 1] = (u16)((__DSPRegs[18 + 1] & ~0xffe0) | (u16)(aram_addr & 0xffff)); + + __DSPRegs[20] = (u16)(__DSPRegs[20] & ~0x8000); + + __DSPRegs[20] = (u16)((__DSPRegs[20] & ~0x03ff) | (u16)(length >> 16)); + __DSPRegs[20 + 1] = (u16)((__DSPRegs[20 + 1] & ~0xffe0) | (u16)(length & 0xffff)); + + while (__DSPRegs[5] & 0x0200) + { + } + + tmp = __DSPRegs[5]; + tmp = (u16)((tmp & ~(0x00000080 | 0x00000008)) | 0x00000020); + __DSPRegs[5] = tmp; +} + +static void __ARReadDMA(u32 mmem_addr, u32 aram_addr, u32 length) +{ + u16 tmp; + __DSPRegs[16] = (u16)((__DSPRegs[16] & ~0x03ff) | (u16)(mmem_addr >> 16)); + __DSPRegs[16 + 1] = (u16)((__DSPRegs[16 + 1] & ~0xffe0) | (u16)(mmem_addr & 0xffff)); + + __DSPRegs[18] = (u16)((__DSPRegs[18] & ~0x03ff) | (u16)(aram_addr >> 16)); + __DSPRegs[18 + 1] = (u16)((__DSPRegs[18 + 1] & ~0xffe0) | (u16)(aram_addr & 0xffff)); + + __DSPRegs[20] = (u16)(__DSPRegs[20] | 0x8000); + + __DSPRegs[20] = (u16)((__DSPRegs[20] & ~0x03ff) | (u16)(length >> 16)); + __DSPRegs[20 + 1] = (u16)((__DSPRegs[20 + 1] & ~0xffe0) | (u16)(length & 0xffff)); + + while (__DSPRegs[5] & 0x0200) + { + } + + tmp = __DSPRegs[5]; + tmp = (u16)((tmp & ~(0x00000080 | 0x00000008)) | 0x00000020); + __DSPRegs[5] = tmp; +} + +static void __ARChecksize(void) +{ + 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]; + + u32* test_data; + u32* dummy_data; + u32* buffer; + u32* save1; + u32* save2; + u32* save3; + u32* save4; + u32* save5; + + u16 ARAM_mode = 0; + u32 ARAM_size = 0; + + u32 i; + + while (!(__DSPRegs[11] & 1)) + ; + + ARAM_mode = 3; + ARAM_size = __AR_InternalSize = 0x1000000; + __DSPRegs[9] = (u16)((__DSPRegs[9] & ~(0x00000007 | 0x00000038)) | 0x20 | 2 | 1); + + test_data = (u32*)(RoundUP32((u32)(test_data_pad))); + dummy_data = (u32*)(RoundUP32((u32)(dummy_data_pad))); + buffer = (u32*)(RoundUP32((u32)(buffer_pad))); + + save1 = (u32*)(RoundUP32((u32)(save_pad_1))); + save2 = (u32*)(RoundUP32((u32)(save_pad_2))); + save3 = (u32*)(RoundUP32((u32)(save_pad_3))); + save4 = (u32*)(RoundUP32((u32)(save_pad_4))); + save5 = (u32*)(RoundUP32((u32)(save_pad_5))); + + for (i = 0; i < 8; i++) + { + *(test_data + i) = 0xdeadbeef; + *(dummy_data + i) = 0xbad0bad0; + } + + DCFlushRange((void*)test_data, 0x20); + DCFlushRange((void*)dummy_data, 0x20); + + __AR_ExpansionSize = 0; + + DCInvalidateRange((void*)save1, 0x20); + __ARReadDMA((u32)save1, ARAM_size + 0, 0x20); + PPCSync(); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0000000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) + { + DCInvalidateRange((void*)save2, 0x20); + __ARReadDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + PPCSync(); + + DCInvalidateRange((void*)save3, 0x20); + __ARReadDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + PPCSync(); + + DCInvalidateRange((void*)save4, 0x20); + __ARReadDMA((u32)save4, ARAM_size + 0x0000200, 0x20); + PPCSync(); + + DCInvalidateRange((void*)save5, 0x20); + __ARReadDMA((u32)save5, ARAM_size + 0x0400000, 0x20); + PPCSync(); + + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0200000, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0200000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) + { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + + ARAM_mode |= 0 << 1; + ARAM_size += 0x0200000; + __AR_ExpansionSize = 0x0200000; + } + else + { + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x1000000, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x1000000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) + { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + + ARAM_mode |= 4 << 1; + ARAM_size += 0x0400000; + __AR_ExpansionSize = 0x0400000; + } + else + { + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0000200, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0000200, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) + { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + + ARAM_mode |= 8 << 1; + ARAM_size += 0x0800000; + __AR_ExpansionSize = 0x0800000; + } + else + { + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0400000, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0400000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) + { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + __ARWriteDMA((u32)save4, ARAM_size + 0x0000200, 0x20); + + ARAM_mode |= 12 << 1; + ARAM_size += 0x1000000; + __AR_ExpansionSize = 0x1000000; + } + else + { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + __ARWriteDMA((u32)save4, ARAM_size + 0x0000200, 0x20); + __ARWriteDMA((u32)save5, ARAM_size + 0x0400000, 0x20); + + ARAM_mode |= 16 << 1; + ARAM_size += 0x2000000; + __AR_ExpansionSize = 0x2000000; + } + } + } + } + __DSPRegs[9] = (u16)((__DSPRegs[9] & ~(0x07 | 0x38)) | ARAM_mode); + } + + *(u32*)OSPhysicalToUncached(0x00D0) = ARAM_size; + + __AR_Size = ARAM_size; +} \ No newline at end of file diff --git a/libs/dolphin/ar/arq.c b/libs/dolphin/ar/arq.c new file mode 100644 index 000000000..504a89159 --- /dev/null +++ b/libs/dolphin/ar/arq.c @@ -0,0 +1,271 @@ + +#include +#include + +#include "dolphin/ax/__ax.h" + +#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 17 2003 12:33:56 (0x2301) >>"; +#endif + +static ARQRequest* __ARQRequestQueueHi; +static ARQRequest* __ARQRequestTailHi; +static ARQRequest* __ARQRequestQueueLo; +static ARQRequest* __ARQRequestTailLo; +static ARQRequest* __ARQRequestQueueTemp; +static ARQRequest* __ARQRequestTailTemp; +static ARQRequest* __ARQRequestPendingHi; +static ARQRequest* __ARQRequestPendingLo; +static ARQCallback __ARQCallbackHi; +static ARQCallback __ARQCallbackLo; +static u32 __ARQChunkSize; +static BOOL __ARQ_init_flag; + +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; + } + + if (__ARQRequestQueueHi) + { + if (__ARQRequestQueueHi->type == 0) + { + ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->source, + __ARQRequestQueueHi->dest, __ARQRequestQueueHi->length); + } + else + { + ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->dest, + __ARQRequestQueueHi->source, __ARQRequestQueueHi->length); + } + __ARQCallbackHi = __ARQRequestQueueHi->callback; + __ARQRequestPendingHi = __ARQRequestQueueHi; + __ARQRequestQueueHi = __ARQRequestQueueHi->next; + } + + if (__ARQRequestPendingHi == 0) + { + __ARQServiceQueueLo(); + } +} + +void ARQInit(void) +{ + if (__ARQ_init_flag != TRUE) + { + OSRegisterVersion(__ARQVersion); + + __ARQRequestQueueHi = __ARQRequestQueueLo = NULL; + __ARQChunkSize = 0x1000; + ARRegisterDMACallback(__ARQInterruptServiceRoutine); + __ARQRequestPendingHi = NULL; + __ARQRequestPendingLo = NULL; + __ARQCallbackHi = NULL; + __ARQCallbackLo = NULL; + __ARQ_init_flag = TRUE; + } +} + +void ARQPostRequest(ARQRequest* request, u32 owner, u32 type, u32 priority, u32 source, u32 dest, + u32 length, ARQCallback callback) +{ + BOOL enabled; + + request->next = NULL; + request->owner = owner; + request->type = type; + request->source = source; + request->dest = dest; + request->length = length; + + if (callback) + { + request->callback = callback; + } + else + { + request->callback = (ARQCallback)&__ARQCallbackHack; + } + + enabled = OSDisableInterrupts(); + + switch (priority) + { + case ARQ_PRIORITY_LOW: + + if (__ARQRequestQueueLo) + { + __ARQRequestTailLo->next = request; + } + else + { + __ARQRequestQueueLo = request; + } + __ARQRequestTailLo = request; + + break; + + case ARQ_PRIORITY_HIGH: + + if (__ARQRequestQueueHi) + { + __ARQRequestTailHi->next = request; + } + else + { + __ARQRequestQueueHi = request; + } + + __ARQRequestTailHi = request; + + break; + } + + if ((__ARQRequestPendingHi == NULL) && (__ARQRequestPendingLo == NULL)) + { + if (__ARQRequestQueueHi) + { + if (__ARQRequestQueueHi->type == 0) + { + ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->source, + __ARQRequestQueueHi->dest, __ARQRequestQueueHi->length); + } + else + { + ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->dest, + __ARQRequestQueueHi->source, __ARQRequestQueueHi->length); + } + __ARQCallbackHi = __ARQRequestQueueHi->callback; + __ARQRequestPendingHi = __ARQRequestQueueHi; + __ARQRequestQueueHi = __ARQRequestQueueHi->next; + } + + if (__ARQRequestPendingHi == NULL) + { + __ARQServiceQueueLo(); + } + } + + OSRestoreInterrupts(enabled); +} + +void ARQRemoveRequest(ARQRequest* request) +{ + ARQRequest* thisRequest; + BOOL level; + + level = OSDisableInterrupts(); + __ARQRequestQueueTemp = NULL; + __ARQRequestTailTemp = NULL; + for (thisRequest = __ARQRequestQueueHi; thisRequest; thisRequest = thisRequest->next) + { + if (thisRequest != request) + { + if (!__ARQRequestQueueTemp) + { + __ARQRequestQueueTemp = thisRequest; + __ARQRequestTailTemp = thisRequest; + } + else + { + __ARQRequestTailTemp->next = thisRequest; + __ARQRequestTailTemp = thisRequest; + } + } + } + + __ARQRequestQueueHi = __ARQRequestQueueTemp; + __ARQRequestTailHi = __ARQRequestTailTemp; + __ARQRequestQueueTemp = NULL; + __ARQRequestTailTemp = NULL; + for (thisRequest = __ARQRequestQueueLo; thisRequest; thisRequest = thisRequest->next) + { + if (thisRequest != request) + { + if (!__ARQRequestQueueTemp) + { + __ARQRequestQueueTemp = thisRequest; + __ARQRequestTailTemp = thisRequest; + } + else + { + __ARQRequestTailTemp->next = thisRequest; + __ARQRequestTailTemp = thisRequest; + } + } + } + + __ARQRequestQueueLo = __ARQRequestQueueTemp; + __ARQRequestTailLo = __ARQRequestTailTemp; + OSRestoreInterrupts(level); +} + +void ARQFlushQueue(void) +{ + BOOL level; + + level = OSDisableInterrupts(); + __ARQRequestQueueHi = NULL; + __ARQRequestTailHi = NULL; + __ARQRequestQueueLo = NULL; + __ARQRequestTailLo = NULL; + + OSRestoreInterrupts(level); +} diff --git a/libs/dolphin/ax/AX.c b/libs/dolphin/ax/AX.c new file mode 100644 index 000000000..ab015fffc --- /dev/null +++ b/libs/dolphin/ax/AX.c @@ -0,0 +1,43 @@ +#include +#include + +#include "dolphin/ax/__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 17 2003 12:33:57 (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/libs/dolphin/ax/AXAlloc.c b/libs/dolphin/ax/AXAlloc.c new file mode 100644 index 000000000..8c7d0ef74 --- /dev/null +++ b/libs/dolphin/ax/AXAlloc.c @@ -0,0 +1,256 @@ +#include +#include + +#include "dolphin/ax/__ax.h" + +static AXVPB* __AXStackHead[AX_PRIORITY_STACKS]; +static AXVPB* __AXStackTail[AX_PRIORITY_STACKS]; + +static AXVPB* __AXCallbackStack; + +AXVPB* __AXGetStackHead(u32 priority) +{ + 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 __AXAllocInit(void) +{ +#ifdef DEBUG + OSReport("Initializing AXAlloc code module\n"); +#endif + u32 i; + + __AXCallbackStack = NULL; + for (i = 0; i < AX_PRIORITY_STACKS; i++) + { + __AXStackHead[i] = __AXStackTail[i] = 0; + } +} + +void __AXAllocQuit(void) +{ +#ifdef DEBUG + OSReport("Shutting down AXAlloc code module\n"); +#endif + u32 i; + + __AXCallbackStack = NULL; + for (i = 0; i < AX_PRIORITY_STACKS; i++) + { + __AXStackHead[i] = __AXStackTail[i] = 0; + } +} + +void __AXPushFreeStack(AXVPB* p) +{ + 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; + + 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) +// { +// 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; + +// 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) +{ + int old; + + old = OSDisableInterrupts(); + __AXRemoveFromStack(p); + if (p->pb.state == 1) + { + p->depop = 1; + } + __AXSetPBDefault(p); + __AXPushFreeStack(p); + OSRestoreInterrupts(old); +} + +AXVPB* AXAcquireVoice(u32 priority, void (*callback)(void*), u32 userContext) +{ + // priority r25 + // userContext r 28 + // AXStackHead r26 + int old; // r31 + AXVPB* p; // r30 + u32 i; // r29 + + old = OSDisableInterrupts(); + p = (void*)(u32)&__AXStackHead[0]->next; + if (p != 0) + { + __AXStackHead[0] = __AXStackHead[0]->next; + } + + if (p == 0) + { + for (i = 1; i < priority; i++) + { + p = NULL; + if (__AXStackHead[i]) + { + if (__AXStackHead[i] == __AXStackTail[i]) + { + p = __AXStackHead[i]; + __AXStackHead[i] = __AXStackTail[i] = 0; + } + else if (__AXStackTail[i]) + { + p = __AXStackTail[i]; + __AXStackTail[i] = p->prev; + __AXStackTail[i]->next = 0; + } + } + if (p) + { + if (p->pb.state == 1) + { + p->depop = 1; + } + if (p->callback != 0) + { + p->callback(p); + } + break; + } + } + } + if (p) + { + p->next = __AXStackHead[i]; + p->prev = 0; + if (p->next) + { + __AXStackHead[i]->prev = p; + __AXStackHead[i] = p; + } + else + { + __AXStackTail[i] = p; + __AXStackHead[i] = p; + } + p->priority = i; + p->callback = callback; + p->userContext = userContext; + __AXSetPBDefault(p); + } + OSRestoreInterrupts(old); + return p; +} diff --git a/libs/dolphin/ax/AXAux.c b/libs/dolphin/ax/AXAux.c new file mode 100644 index 000000000..25af19bf0 --- /dev/null +++ b/libs/dolphin/ax/AXAux.c @@ -0,0 +1,184 @@ +#include +#include + +#include "dolphin/ax/__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; +} diff --git a/libs/dolphin/ax/AXCL.c b/libs/dolphin/ax/AXCL.c new file mode 100644 index 000000000..4487e3cb8 --- /dev/null +++ b/libs/dolphin/ax/AXCL.c @@ -0,0 +1,226 @@ +#include +#include + +#include "dolphin/ax/__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(); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 0x2E44; + + switch (__AXClMode) + { + case 0: + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 0x546; + break; + case 1: + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 0x5E6; + break; + case 2: + break; + default: + ASSERTMSGLINE(193, 0, "Unknown AX mode!"); + } + + data = (u32)__AXGetPBs(); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + + if (__AXClMode == 2) + { + __AXGetAuxAInput(&data); + if (data != 0) + { + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXGetAuxAInputDpl2(&data); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXGetAuxAOutput(&data); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXGetAuxAOutputDpl2R(&data); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXGetAuxAOutputDpl2Ls(&data); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXGetAuxAOutputDpl2Rs(&data); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 0xDED; + } + *__AXClWrite = data; + __AXClWrite++; + __AXGetAuxBForDPL2(&data); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXGetAuxBOutputDPL2(&data); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 0xDED; + } + else + { + __AXGetAuxAInput(&data); + + if (data != 0) + { + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXGetAuxAOutput(&data); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 0xDED; + } + + __AXGetAuxBInput(&data); + if (data != 0) + { + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 0xDED; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXGetAuxBOutput(&data); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + } + } + + if (__AXCompressor) + { + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 0xBB8; + } + + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 0x2710; + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 2; + DCFlushRange(pCommandList, 0x300); +} + +void __AXClInit(void) +{ +#ifdef DEBUG + OSReport("Initializing AXCL code module\n"); +#endif + __AXClMode = 0; + __AXCommandListPosition = 0; + __AXClWrite = (void*)&__AXCommandList; + __AXCompressor = 1; +} + +void __AXClQuit(void) +{ +#ifdef DEBUG + OSReport("Shutting down AXCL code module\n"); +#endif +} diff --git a/libs/dolphin/ax/AXComp.c b/libs/dolphin/ax/AXComp.c new file mode 100644 index 000000000..af66e256f --- /dev/null +++ b/libs/dolphin/ax/AXComp.c @@ -0,0 +1,287 @@ +#include +#include + +#include "dolphin/ax/__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/libs/dolphin/ax/AXOut.c b/libs/dolphin/ax/AXOut.c new file mode 100644 index 000000000..7ead2b859 --- /dev/null +++ b/libs/dolphin/ax/AXOut.c @@ -0,0 +1,243 @@ +#include +#include +#include + +#include "dolphin/ax/__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; +} + +static void __AXDSPResumeCallback(void* task) +{ + if (__AXOutDspReady == 2) + { + __AXOutDspReady = 0; + __AXOutNewFrame((u32)(OSGetTime() - __AXOsTime) / 4); + return; + } + __AXOutDspReady = 1U; +} + +static void __AXDSPDoneCallback(void* task) +{ + __AXDSPDoneFlag = 1; + OSWakeupThread(&__AXOutThreadQueue); +} + +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(void (*callback)()) +{ + __AXUserFrameCallback = callback; +} diff --git a/libs/dolphin/ax/AXProf.c b/libs/dolphin/ax/AXProf.c new file mode 100644 index 000000000..2bd94b928 --- /dev/null +++ b/libs/dolphin/ax/AXProf.c @@ -0,0 +1,24 @@ +#include +#include + +#include "dolphin/ax/__ax.h" + +// .sbss +static AXPROFILE* __AXProfile; +static u32 __AXMaxProfiles; +static u32 __AXCurrentProfile; +static u32 __AXProfileInitialized; + +AXPROFILE* __AXGetCurrentProfile(void) +{ + AXPROFILE* profile; + + if (__AXProfileInitialized != 0U) + { + profile = &__AXProfile[__AXCurrentProfile]; + __AXCurrentProfile += 1; + __AXCurrentProfile %= __AXMaxProfiles; + return profile; + } + return 0; +} diff --git a/libs/dolphin/ax/AXSPB.c b/libs/dolphin/ax/AXSPB.c new file mode 100644 index 000000000..9a22f943c --- /dev/null +++ b/libs/dolphin/ax/AXSPB.c @@ -0,0 +1,94 @@ +#include +#include + +#include "dolphin/ax/__ax.h" + +// .bss +static struct _AXSPB __AXStudio ATTRIBUTE_ALIGN(32); + +// .sbss +static long __AXSpbAL; +static long __AXSpbAR; +static long __AXSpbAS; +static long __AXSpbAAL; +static long __AXSpbAAR; +static long __AXSpbAAS; +static long __AXSpbABL; +static long __AXSpbABR; +static long __AXSpbABS; + +u32 __AXGetStudio(void) +{ + return (u32)&__AXStudio; +} + +void __AXDepopFade(long* hostSum, long* dspVolume, s16* dspDelta) +{ + int frames; + long 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/libs/dolphin/ax/AXVPB.c b/libs/dolphin/ax/AXVPB.c new file mode 100644 index 000000000..b91ad2e30 --- /dev/null +++ b/libs/dolphin/ax/AXVPB.c @@ -0,0 +1,1299 @@ +#include +#include + +#include "dolphin/ax/__ax.h" + +static unsigned long __AXSrcCycles[5] = { 0x00000DF8, 0x00000F78, 0x000014B8, 0x000019F8, + 0x000019F8 }; + +static unsigned long __AXMixCycles[32] = { + 0x000005BE, 0x00000B7C, 0x00000B7C, 0x0000113A, 0x000008B6, 0x00000E74, 0x00000E74, 0x00001432, + 0x000009A6, 0x0000134C, 0x0000134C, 0x00001CF2, 0x00000E97, 0x0000183D, 0x0000183D, 0x000021E3, + 0x00000B7C, 0x00001432, 0x00000B7C, 0x00001432, 0x00000B7C, 0x00000B7C, 0x00000B7C, 0x00000B7C, + 0x0000134C, 0x000021E3, 0x0000134C, 0x000021E3, 0x0000134C, 0x000021E3, 0x0000134C, 0x000021E3 +}; + +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(0xA1, (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: 0xC0) + 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); + 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_ = 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 = (u16*)&ppbDsp->dpop; + src = (u16*)&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 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); + } + 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); + } +} + +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 lessDspCycles) +{ + u32 cycles; + u32 i; + AXVPB* pvpb; + + __AXNumVoices = 0; + DCInvalidateRange(__AXPB, sizeof(__AXPB)); + DCInvalidateRange(__AXITD, sizeof(__AXITD)); + cycles = (__AXGetCommandListCycles() + 0x10000) - 0x55F0 + lessDspCycles; + for (i = 31; i; i--) + { + for (pvpb = __AXGetStackHead(i); pvpb; pvpb = pvpb->next) + { + if (pvpb->depop != 0U) + { + __AXDepopVoice(&__AXPB[pvpb->index]); + } + if ((pvpb->pb.state == 1) || (pvpb->updateCounter != 0U)) + { + cycles = __AXSrcCycles[pvpb->pb.src.ratioHi] + __AXMixCycles[pvpb->pb.mixerCtrl] + + 0x8C + cycles; + 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 != 0U) + { + __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 = 0xA4; + 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; +} + +void __AXVPBInit(void) +{ + u32 i; + AXPB* ppb; + AXPBITDBUFFER* ppbi; + AXPBU* ppbu; + AXVPB* pvpb; + +#ifdef DEBUG + OSReport("Initializing AXVPB code module\n"); +#endif + __AXMaxDspCycles = OS_BUS_CLOCK / 400; + __AXRecDspCycles = 0U; + memset(__AXPB, 0, sizeof(__AXPB)); + memset(__AXITD, 0, sizeof(__AXITD)); + memset(__AXVPB, 0, sizeof(__AXVPB)); + for (i = 0; i < AX_MAX_VOICES; i++) + { + ppb = &__AXPB[i]; + ppbi = &__AXITD[i]; + ppbu = &__AXUpdates[i]; + pvpb = &__AXVPB[i]; + ASSERTLINE(0x2F6, (u32)ppb ^ 0x1F); + ASSERTLINE(0x2F7, (u32)ppbi ^ 0x1F); + ASSERTLINE(0x2F8, (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 + 0xC0) >> 16); + pvpb->pb.nextLo = (u16)((u32)((char*)ppb + 0xC0)); + ppb->nextHi = (u16)((u32)((char*)ppb + 0xC0) >> 16); + ppb->nextLo = (u16)((u32)((char*)ppb + 0xC0)); + } + 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); + __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) +{ + int old; + AXPB* ppb; + + ASSERTLINE(0x35E, p); + ASSERTLINE(0x35F, 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) +{ + int 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) +{ + int old; + + old = OSDisableInterrupts(); + p->pb.type = type; + p->sync |= AX_SYNC_FLAG_COPYTYPE; + OSRestoreInterrupts(old); +} + +void AXSetVoiceMix(AXVPB* p, AXPBMIX* mix) +{ + int old; + u16 mixerCtrl; + u16* dst; + u16* src; + + src = + (u16*)&mix; //! @bug? This is a pointer (to) a pointer and is not what you want if you want to copy the information, no? + dst = (u16*)&p->pb.mix; + + 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; + *(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; + } + mixerCtrl = 0; + if (__AXClMode == 4) + { + if ((mix->vAuxAL != 0) || (mix->vAuxAR != 0)) + { + mixerCtrl |= 1; + } + if ((mix->vAuxBL != 0) || (mix->vAuxBR != 0)) + { + mixerCtrl |= 16; + } + if ((mix->vDeltaL != 0) || (mix->vDeltaR != 0) || (mix->vDeltaAuxAL != 0) || + (mix->vDeltaAuxAR != 0) || (mix->vDeltaAuxAS != 0) || (mix->vDeltaAuxBL != 0) || + (mix->vDeltaAuxBR != 0)) + { + mixerCtrl |= 8; + } + } + else + { + if ((mix->vAuxAL != 0) || (mix->vAuxAR != 0)) + { + mixerCtrl |= 1; + } + if ((mix->vAuxBL != 0) || (mix->vAuxBR != 0)) + { + mixerCtrl |= 2; + } + if ((mix->vS != 0) || (mix->vAuxAS != 0) || (mix->vAuxBS != 0)) + { + mixerCtrl |= 4; + } + if ((mix->vDeltaL != 0) || (mix->vDeltaR != 0) || (mix->vDeltaS != 0) || + (mix->vDeltaAuxAL != 0) || (mix->vDeltaAuxAR != 0) || (mix->vDeltaAuxAS != 0) || + (mix->vDeltaAuxBL != 0) || (mix->vDeltaAuxBR != 0) || (mix->vDeltaAuxBS != 0)) + { + mixerCtrl |= 8; + } + } + p->pb.mixerCtrl = mixerCtrl; + p->sync |= (AX_SYNC_FLAG_COPYAXPBMIX | AX_SYNC_FLAG_COPYMXRCTRL); + OSRestoreInterrupts(old); +} + +void AXSetVoiceItdOn(AXVPB* p) +{ + int 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) +{ + int 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) +{ + int old; + + old = OSDisableInterrupts(); + p->updateMS++; + p->sync |= AX_SYNC_FLAG_COPYUPDATE; + ASSERTMSGLINE(0x431, p->updateMS <= 4, "PB updates cannot exceed 5ms\n"); + OSRestoreInterrupts(old); +} + +void AXSetVoiceUpdateWrite(AXVPB* p, u16 param, u16 data) +{ + int old; + + old = OSDisableInterrupts(); + p->updateCounter += 2; + ASSERTMSGLINE(0x43F, 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) +{ + int 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) +{ + int 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) +{ + int old; + + old = OSDisableInterrupts(); + p->pb.ve.currentDelta = delta; + p->sync |= AX_SYNC_FLAG_SWAPVOL; + OSRestoreInterrupts(old); +} + +void AXSetVoiceFir(AXVPB* p, AXPBFIR* fir) +{ + int 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) +{ + int 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(0x4BA, (addr->loopAddressLo & 0xF) > 1, + "*** loop address on ADPCM frame header! ***\n"); + ASSERTMSGLINE(0x4BF, (addr->endAddressLo & 0xF) > 1, + "*** end address on ADPCM frame header! ***\n"); + ASSERTMSGLINE(0x4C4, (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(0x4F0, 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) +{ + int old; + + old = OSDisableInterrupts(); + p->pb.addr.loopFlag = loop; + p->sync |= AX_SYNC_FLAG_COPYLOOP; + OSRestoreInterrupts(old); +} + +void AXSetVoiceLoopAddr(AXVPB* p, u32 addr) +{ + int old; + + old = OSDisableInterrupts(); + p->pb.addr.loopAddressHi = (addr >> 0x10U); + p->pb.addr.loopAddressLo = (addr); + p->sync |= AX_SYNC_FLAG_COPYLOOPADDR; + OSRestoreInterrupts(old); +} + +void AXSetVoiceEndAddr(AXVPB* p, u32 addr) +{ + int old; + + old = OSDisableInterrupts(); + p->pb.addr.endAddressHi = (addr >> 0x10U); + p->pb.addr.endAddressLo = (addr); + p->sync |= AX_SYNC_FLAG_COPYENDADDR; + OSRestoreInterrupts(old); +} + +void AXSetVoiceCurrentAddr(AXVPB* p, u32 addr) +{ + int old; + + old = OSDisableInterrupts(); + p->pb.addr.currentAddressHi = (addr >> 0x10U); + p->pb.addr.currentAddressLo = (addr); + p->sync |= AX_SYNC_FLAG_COPYCURADDR; + OSRestoreInterrupts(old); +} + +void AXSetVoiceAdpcm(AXVPB* p, AXPBADPCM* adpcm) +{ + int 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_) +{ + int 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; + int 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) +{ + int 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 AXSetMaxDspCycles(u32 cycles) +{ + __AXMaxDspCycles = cycles; +} + +u32 AXGetMaxDspCycles(void) +{ + return __AXMaxDspCycles; +} + +u32 AXGetDspCycles(void) +{ + return __AXRecDspCycles; +} diff --git a/libs/dolphin/ax/DSPCode.c b/libs/dolphin/ax/DSPCode.c new file mode 100644 index 000000000..c13f4c0ec --- /dev/null +++ b/libs/dolphin/ax/DSPCode.c @@ -0,0 +1,211 @@ +#include +#include + +u16 axDspSlaveLength = (AX_DSP_SLAVE_LENGTH*2); + +u16 axDspSlave[AX_DSP_SLAVE_LENGTH] ATTRIBUTE_ALIGN(32) = { + 0x0000, 0x0000, 0x029F, 0x0BDB, 0x029F, 0x0BEA, 0x029F, 0x0C06, 0x029F, 0x0C15, 0x029F, 0x0C1B, 0x029F, 0x0C47, 0x029F, 0x0C4D, + 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, 0x055C, 0x0080, 0x0C00, 0x8E00, 0x8100, 0x8970, 0xB100, 0x0291, 0x007E, 0x0A11, 0xC100, + 0x0292, 0x007E, 0x009F, 0x0ACB, 0x4C00, 0x1C7E, 0x0213, 0x1C7E, 0x176F, 0x16FC, 0xFBAD, 0x16FD, 0x8080, 0x0021, 0x16FC, 0xBAAD, + 0x2EFD, 0x0021, 0x8100, 0x8970, 0x8E78, 0x2ECE, 0x2FCF, 0x009E, 0x0E44, 0x2ECD, 0x0E00, 0x2EC9, 0x009E, 0x0040, 0x2ECB, 0x0081, + 0x0E44, 0x0082, 0x0000, 0x009B, 0x009F, 0x009A, 0x0140, 0x8100, 0x8900, 0x8F00, 0x02BF, 0x055C, 0x193E, 0x193C, 0xB100, 0x193F, + 0x0294, 0x00A6, 0x005A, 0x1B5E, 0x029F, 0x00AE, 0x9900, 0x1B5E, 0x1B5C, 0x007B, 0x00AD, 0x4C00, 0x1B5E, 0x1B5C, 0x193E, 0x193C, + 0xB100, 0x193F, 0x0294, 0x00B8, 0x005A, 0x1B5E, 0x029F, 0x00C0, 0x9900, 0x1B5E, 0x1B5C, 0x007B, 0x00BF, 0x4C00, 0x1B5E, 0x1B5C, + 0x193E, 0x193C, 0xB100, 0x193F, 0x0294, 0x00CA, 0x005A, 0x1B5E, 0x029F, 0x00D2, 0x9900, 0x1B5E, 0x1B5C, 0x007B, 0x00D1, 0x4C00, + 0x1B5E, 0x1B5C, 0x0082, 0x0400, 0x193E, 0x193C, 0xB179, 0x0294, 0x00DD, 0x005A, 0x1B5E, 0x029F, 0x00E5, 0x9900, 0x1B5E, 0x1B5C, + 0x007B, 0x00E4, 0x4C00, 0x1B5E, 0x1B5C, 0x193E, 0x193C, 0xB179, 0x0294, 0x00EE, 0x005A, 0x1B5E, 0x029F, 0x00F6, 0x9900, 0x1B5E, + 0x1B5C, 0x007B, 0x00F5, 0x4C00, 0x1B5E, 0x1B5C, 0x193E, 0x193C, 0xB179, 0x0294, 0x00FF, 0x005A, 0x1B5E, 0x029F, 0x0107, 0x9900, + 0x1B5E, 0x1B5C, 0x007B, 0x0106, 0x4C00, 0x1B5E, 0x1B5C, 0x0082, 0x07C0, 0x193E, 0x193C, 0xB179, 0x0294, 0x0112, 0x005A, 0x1B5E, + 0x029F, 0x011A, 0x9900, 0x1B5E, 0x1B5C, 0x007B, 0x0119, 0x4C00, 0x1B5E, 0x1B5C, 0x193E, 0x193C, 0xB179, 0x0294, 0x0123, 0x005A, + 0x1B5E, 0x029F, 0x012B, 0x9900, 0x1B5E, 0x1B5C, 0x007B, 0x012A, 0x4C00, 0x1B5E, 0x1B5C, 0x193E, 0x193C, 0xB179, 0x0294, 0x0134, + 0x005A, 0x1B5E, 0x029F, 0x013C, 0x9900, 0x1B5E, 0x1B5C, 0x007B, 0x013B, 0x4C00, 0x1B5E, 0x1B5C, 0x029F, 0x0068, 0x0085, 0xFFFF, + 0x8150, 0x8940, 0x8E48, 0x00FA, 0x0E17, 0x00F8, 0x0E18, 0x0081, 0x0000, 0x02BF, 0x04F1, 0x00DA, 0x0E17, 0x00D8, 0x0E18, 0x8948, + 0x0081, 0x0400, 0x02BF, 0x04F1, 0x00DA, 0x0E17, 0x00D8, 0x0E18, 0x8948, 0x0081, 0x07C0, 0x02BF, 0x04F1, 0x029F, 0x0068, 0x0086, + 0x07C0, 0x02BF, 0x0484, 0x029F, 0x0068, 0x8100, 0x8E00, 0x191E, 0x191C, 0x2ECE, 0x2CCF, 0x16CD, 0x0000, 0x16C9, 0x0001, 0x16CB, + 0x0780, 0x02BF, 0x055C, 0x029F, 0x0068, 0x8100, 0x8970, 0x8E60, 0x2ECE, 0x2CCF, 0x16CD, 0x0E44, 0x16C9, 0x0000, 0x8900, 0x0D20, + 0x2DCB, 0x4C00, 0x1C80, 0x0080, 0x0280, 0x0081, 0x0000, 0x0082, 0x0140, 0x0083, 0x0E44, 0x0A00, 0x27C9, 0x03A0, 0x0004, 0x029C, + 0x018C, 0x2ECE, 0x2CCF, 0x16CD, 0x0E54, 0x16C9, 0x0000, 0x16CB, 0x0260, 0x009F, 0x00A0, 0x8F00, 0x007F, 0x01A6, 0x197E, 0x1B1A, + 0x197C, 0x1B1A, 0x1B5E, 0x1B5C, 0x7C00, 0x1B3E, 0x1B3C, 0x1C04, 0x029F, 0x0068, 0x8E70, 0x8960, 0x191F, 0x2ECE, 0x2CCF, 0x16CD, + 0x0C00, 0x16C9, 0x0000, 0x0503, 0x0340, 0xFFF0, 0x2FCB, 0x02BF, 0x055C, 0x0080, 0x0C00, 0x029F, 0x0068, 0x8100, 0x8970, 0x8E78, + 0x2ECE, 0x2FCF, 0x16CD, 0x0B80, 0x16C9, 0x0000, 0x16CB, 0x00C0, 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, 0x055C, 0x00DE, 0x0BA7, 0x00DF, 0x0BA8, 0x2ECE, 0x2FCF, 0x16CD, 0x03C0, 0x16C9, + 0x0000, 0x16CB, 0x0080, 0x8100, 0x8900, 0x00DE, 0x0B84, 0x009F, 0x0AFC, 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E15, 0x00DE, 0x0B85, + 0x009F, 0x0AFF, 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E16, 0x00DE, 0x0B86, 0x009F, 0x0ADC, 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E14, + 0x8100, 0x00DE, 0x0B9B, 0xB100, 0x0295, 0x023B, 0x8900, 0x00DF, 0x0B9E, 0x0300, 0x0CC0, 0x00FF, 0x0E40, 0x00DF, 0x0B9F, 0x0300, + 0x0CC0, 0x00FF, 0x0E41, 0x009F, 0x0CE0, 0x00FF, 0x0E42, 0x00FF, 0x0E43, 0x02BF, 0x055C, 0x00DE, 0x0B9C, 0x2ECE, 0x00DE, 0x0B9D, + 0x2ECF, 0x16CD, 0x0CC0, 0x16C9, 0x0000, 0x16CB, 0x0040, 0x02BF, 0x055C, 0x029F, 0x0068, 0x009F, 0x0CE0, 0x00FF, 0x0E42, 0x00FF, + 0x0E40, 0x00FF, 0x0E41, 0x00FF, 0x0E43, 0x02BF, 0x055C, 0x029F, 0x0068, 0x8E00, 0x00E0, 0x0E07, 0x0080, 0x0BA2, 0x0081, 0x03C0, + 0x0E05, 0x00FE, 0x0E04, 0x8900, 0x8150, 0x009F, 0x0B80, 0x007A, 0x025C, 0x193E, 0x4C49, 0x1C5E, 0x1A59, 0x0083, 0x0E05, 0x1B61, + 0x1B60, 0x00DE, 0x0B87, 0x0601, 0x0295, 0x0268, 0x029F, 0x0332, 0x00DE, 0x0E42, 0x00FE, 0x0E1C, 0x00C3, 0x0E15, 0x177F, 0x8F00, + 0x8A00, 0x8100, 0x8900, 0x00DE, 0x0BB3, 0x00DF, 0x0BB2, 0x1F1F, 0x4D00, 0x1481, 0x8D1E, 0x1FD8, 0x0098, 0x8000, 0x0080, 0x0E44, + 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, 0x0080, 0x0E44, 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, 0x00C3, 0x0E14, 0x8F00, 0x8D00, 0x8A00, 0x177F, + 0x8100, 0x00DE, 0x0B9B, 0xB100, 0x0295, 0x032A, 0x00DE, 0x0E42, 0x00FE, 0x0E43, 0x8100, 0x8900, 0x00DE, 0x0B9E, 0x00DF, 0x0BA0, + 0x8200, 0x0293, 0x0306, 0x7800, 0x029F, 0x0309, 0x0295, 0x0309, 0x7400, 0x00FE, 0x0B9E, 0x00DF, 0x0E43, 0x05E0, 0x4C00, 0x00FE, + 0x0E40, 0x8100, 0x8900, 0x00DE, 0x0B9F, 0x00DF, 0x0BA1, 0x8200, 0x0293, 0x031D, 0x7800, 0x029F, 0x0320, 0x0295, 0x0320, 0x7400, + 0x00FE, 0x0B9F, 0x00DF, 0x0E43, 0x05E0, 0x4C00, 0x00FE, 0x0E41, 0x029F, 0x0332, 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, 0x0254, 0x8E00, 0x8100, 0x00DE, 0x0B9B, 0xB100, 0x0295, 0x036A, 0x00DE, 0x0B9C, 0x00DC, 0x0B9D, 0x2ECE, 0x2CCF, + 0x8100, 0x00DE, 0x0E1C, 0x2ECD, 0x16C9, 0x0001, 0x16CB, 0x0040, 0x02BF, 0x055C, 0x8100, 0x8900, 0x00DE, 0x0B82, 0x00DF, 0x0B83, + 0x2ECE, 0x2FCF, 0x16CD, 0x0B80, 0x16C9, 0x0001, 0x16CB, 0x00C0, 0x02BF, 0x055C, 0x8100, 0x00DE, 0x0B80, 0x00DC, 0x0B81, 0xB100, + 0x0294, 0x0386, 0x00C0, 0x0E07, 0x029F, 0x0068, 0x2ECE, 0x2CCF, 0x16CD, 0x0B80, 0x16C9, 0x0000, 0x16CB, 0x00C0, 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, 0x055C, 0x00DE, 0x0BA7, 0x00DF, + 0x0BA8, 0x2ECE, 0x2FCF, 0x16CD, 0x03C0, 0x16C9, 0x0000, 0x16CB, 0x0080, 0x8100, 0x8900, 0x00DE, 0x0B84, 0x009F, 0x0AFC, 0x4C00, + 0x1C7E, 0x0213, 0x00FE, 0x0E15, 0x00DE, 0x0B85, 0x009F, 0x0AFF, 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E16, 0x00DE, 0x0B86, 0x009F, + 0x0ADC, 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E14, 0x8100, 0x00DE, 0x0B9B, 0xB100, 0x0295, 0x0403, 0x8900, 0x00DF, 0x0B9E, 0x0300, + 0x0CC0, 0x00FF, 0x0E40, 0x00DF, 0x0B9F, 0x0300, 0x0CC0, 0x00FF, 0x0E41, 0x009F, 0x0CE0, 0x00FF, 0x0E42, 0x00FF, 0x0E43, 0x02BF, + 0x055C, 0x00DE, 0x0B9C, 0x2ECE, 0x00DE, 0x0B9D, 0x2ECF, 0x16CD, 0x0CC0, 0x16C9, 0x0000, 0x16CB, 0x0040, 0x02BF, 0x055C, 0x00C0, + 0x0E07, 0x029F, 0x0249, 0x009F, 0x0CE0, 0x00FF, 0x0E42, 0x00FF, 0x0E40, 0x00FF, 0x0E41, 0x00FF, 0x0E43, 0x02BF, 0x055C, 0x00C0, + 0x0E07, 0x029F, 0x0249, 0x8E00, 0x0086, 0x0400, 0x8100, 0x8970, 0x191C, 0x2ECE, 0x2CCF, 0x1FC6, 0x2ECD, 0x16C9, 0x0001, 0x16CB, + 0x0780, 0x02BF, 0x055C, 0x02BF, 0x0484, 0x029F, 0x0068, 0x8E00, 0x0086, 0x07C0, 0x8100, 0x8970, 0x191C, 0x2ECE, 0x2CCF, 0x1FC6, + 0x2ECD, 0x16C9, 0x0001, 0x16CB, 0x0780, 0x02BF, 0x055C, 0x02BF, 0x0484, 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, 0x055C, 0x1105, 0x046C, 0x1F61, 0x1120, 0x045E, 0x8972, 0x195C, 0xF07B, 0x197D, 0xF131, 0x8139, 0x8900, + 0x6800, 0x2ECE, 0x2CCF, 0x1FFB, 0x2FCD, 0x0F01, 0x2FC9, 0x1FF9, 0x2FCB, 0x7200, 0x1F5E, 0x1F1C, 0x8100, 0x26C9, 0x02A0, 0x0004, + 0x029C, 0x046D, 0x029F, 0x0068, 0x029F, 0x0068, 0x029F, 0x0068, 0x029F, 0x0068, 0x16FC, 0xDCD1, 0x16FD, 0x0002, 0x16FB, 0x0001, + 0x029F, 0x0C56, 0x029F, 0x0045, 0x8E00, 0x191F, 0x191D, 0x1F5F, 0x1F1D, 0x2FCE, 0x2DCF, 0x8900, 0x1FA6, 0x2DCD, 0x0E00, 0x2EC9, + 0x8100, 0x009C, 0x00C0, 0x2CCB, 0x1CA0, 0x0081, 0x0E44, 0x4800, 0x1B3E, 0x1B3C, 0x0B00, 0x0099, 0x0060, 0x4B00, 0x1B3D, 0x0081, + 0x0E44, 0x1C06, 0x0083, 0x0000, 0x1C43, 0x27C9, 0x03A0, 0x0004, 0x029C, 0x04A5, 0x1109, 0x04DA, 0x8E00, 0x193A, 0x1938, 0x6900, + 0x2FCE, 0x2DCF, 0x8900, 0x193D, 0x2DCD, 0x16C9, 0x0000, 0x8100, 0x009C, 0x00C0, 0x2CCB, 0x0081, 0x0E44, 0x4800, 0x1B3E, 0x1B3C, + 0x0B00, 0x0960, 0x4B00, 0x1B3D, 0x0081, 0x0E44, 0x8F00, 0x80F0, 0x80C0, 0x6A00, 0x4800, 0x1117, 0x04D4, 0x80F0, 0x80C0, 0x6B32, + 0x4922, 0x80F0, 0x80C0, 0x6A3A, 0x482A, 0x80F0, 0x80C0, 0x6B32, 0x4922, 0x1B5F, 0x1B5D, 0x80F0, 0x80C0, 0x6A00, 0x4800, 0x1117, + 0x04E8, 0x80F0, 0x80C0, 0x6B32, 0x4922, 0x80F0, 0x80C0, 0x6A3A, 0x482A, 0x80F0, 0x80C0, 0x6B32, 0x4922, 0x1B5F, 0x1B5D, 0x1C05, + 0x02DF, 0x8E00, 0x009B, 0x0E44, 0x009D, 0x00C0, 0x02BF, 0x0541, 0x4900, 0x00FF, 0x0E1D, 0x00FD, 0x0E1E, 0x8900, 0x02BF, 0x055C, + 0x1104, 0x052C, 0x00DA, 0x0E1D, 0x00D8, 0x0E1E, 0x009B, 0x0EA4, 0x009D, 0x00C0, 0x02BF, 0x0541, 0x4900, 0x00FF, 0x0E1D, 0x00FD, + 0x0E1E, 0x0083, 0x0E44, 0x02BF, 0x054C, 0x8900, 0x00DA, 0x0E1D, 0x00D8, 0x0E1E, 0x009B, 0x0E44, 0x009D, 0x00C0, 0x02BF, 0x0541, + 0x4900, 0x00FF, 0x0E1D, 0x00FD, 0x0E1E, 0x0083, 0x0EA4, 0x02BF, 0x054C, 0x0000, 0x0000, 0x8E00, 0x8900, 0x00DA, 0x0E1D, 0x00D8, + 0x0E1E, 0x009B, 0x0EA4, 0x009D, 0x00C0, 0x02BF, 0x0541, 0x4900, 0x0083, 0x0E44, 0x02BF, 0x054C, 0x0083, 0x0EA4, 0x02BF, 0x054C, + 0x02DF, 0x8E00, 0x00FA, 0xFFCE, 0x00F8, 0xFFCF, 0x00FB, 0xFFCD, 0x16C9, 0x0000, 0x2DCB, 0x02DF, 0x8F00, 0x8D00, 0x8A00, 0x197A, + 0x1978, 0xA000, 0xB600, 0x1130, 0x055A, 0x9179, 0x4E6D, 0x197A, 0x4D43, 0xA039, 0xB629, 0x02DF, 0x26C9, 0x02A0, 0x0004, 0x029C, + 0x055C, 0x02DF, 0x26FE, 0x02C0, 0x8000, 0x029C, 0x0562, 0x02DF, 0x26FC, 0x02A0, 0x8000, 0x029C, 0x0568, 0x02DF, 0x26FC, 0x02A0, + 0x8000, 0x029C, 0x056E, 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, 0x8E00, 0x00D8, + 0x0E16, 0x195B, 0x1959, 0x8100, 0x195C, 0x0080, 0x0E44, 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, + 0x0E44, 0x0081, 0xFFDD, 0x0083, 0x0D80, 0x0064, 0x05E6, 0x1827, 0x1B07, 0x4A00, 0x1FFC, 0x1827, 0x1B07, 0x1579, 0x3500, 0x1827, + 0x1B07, 0x4100, 0x1B7E, 0x1827, 0x1B07, 0x1B7F, 0x0000, 0x0065, 0x05EC, 0x1827, 0x1B07, 0x0000, 0x0000, 0x0007, 0x187F, 0x0066, + 0x05F5, 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, 0x0620, 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, 0x8E00, 0x195B, 0x1959, 0x8100, 0x195C, 0x0080, 0x0E44, 0x195F, 0x195F, 0x195F, 0x1B1F, 0x185F, 0x1B1F, + 0x6B00, 0x1505, 0x4D00, 0x157E, 0x1C9F, 0x1CBD, 0x05E0, 0x9900, 0x7D00, 0x1CDD, 0x8900, 0x1FA5, 0x1502, 0x1CBF, 0x009A, 0x01FC, + 0x009E, 0x0E45, 0x0081, 0xFFDD, 0x0083, 0x0D80, 0x0064, 0x0697, 0x1827, 0x1B07, 0x4A00, 0x1B7E, 0x1827, 0x1B07, 0x1B7C, 0x0000, + 0x1827, 0x1B07, 0x0000, 0x0000, 0x1827, 0x1B07, 0x0000, 0x0000, 0x0065, 0x069D, 0x1827, 0x1B07, 0x0000, 0x0000, 0x0066, 0x06A2, + 0x4A00, 0x1B7E, 0x1B7C, 0x0004, 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, 0x00C1, 0x0E42, + 0x0082, 0x0D80, 0x8100, 0x1120, 0x06CF, 0x8900, 0x1940, 0x189E, 0x181B, 0x199A, 0x5400, 0x1F5E, 0x1959, 0xB000, 0xFB00, 0x8139, + 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, 0x00C0, 0x0E42, 0x0081, 0xFFDD, 0x1120, + 0x0714, 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, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, + 0x80E7, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x1C62, 0x00C4, 0x0E41, 0x00C5, + 0x0E09, 0x02BF, 0x80E7, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x1C62, 0x00C4, 0x0E41, + 0x00C5, 0x0E0C, 0x02BF, 0x80E7, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x1C62, + 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x80E7, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, 0x0081, 0x0B91, 0x00C2, 0x0E0E, + 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E0F, 0x02BF, 0x80E7, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, + 0x00C2, 0x0E08, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x80E7, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, 0x0081, + 0x0B8D, 0x00C2, 0x0E0B, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E0C, 0x02BF, 0x80E7, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, 0x00C0, 0x0E40, + 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E0F, 0x02BF, 0x80E7, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 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, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x80E7, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, + 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E0C, 0x02BF, 0x80E7, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, 0x00C0, + 0x0E43, 0x0081, 0x0B97, 0x00C2, 0x0E0A, 0x1C62, 0x1C80, 0x00C5, 0x0E0D, 0x02BF, 0x80E7, 0x00F8, 0x0BAF, 0x00FB, 0x0BB0, 0x02DF, + 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x80E7, 0x00F8, 0x0BA9, 0x00FB, + 0x0BAC, 0x00C0, 0x0E40, 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E0F, 0x02BF, 0x80E7, 0x00F8, 0x0BAB, + 0x00FB, 0x0BAE, 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x1C62, 0x1C80, 0x00C5, 0x0E0A, 0x02BF, 0x80E7, 0x00F8, 0x0BB1, + 0x00FB, 0x0BAF, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x80E7, + 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E0C, 0x02BF, + 0x80E7, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, 0x00C0, 0x0E40, 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E0F, + 0x02BF, 0x80E7, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x00C0, 0x0E43, 0x0081, 0x0B97, 0x00C2, 0x0E0A, 0x1C62, 0x1C80, 0x00C5, 0x0E0D, + 0x02BF, 0x80E7, 0x00F8, 0x0BAF, 0x00FB, 0x0BB0, 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x1C62, 0x02BF, 0x81F9, 0x00F8, + 0x0BB1, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x8282, + 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, + 0x0E09, 0x02BF, 0x8282, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x0083, 0x0E44, 0x00C4, + 0x0E41, 0x00C5, 0x0E0C, 0x02BF, 0x8282, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, + 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x8282, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, 0x0081, 0x0B91, + 0x00C2, 0x0E0E, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E0F, 0x02BF, 0x8282, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x02DF, 0x00C0, + 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x8282, 0x00F8, 0x0BA9, 0x00FB, + 0x0BAC, 0x00C0, 0x0E40, 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E0C, 0x02BF, 0x8282, 0x00F8, + 0x0BAA, 0x00FB, 0x0BAD, 0x00C0, 0x0E40, 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E0F, 0x02BF, + 0x8282, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E44, 0x00C4, 0x0E41, + 0x00C5, 0x0E09, 0x02BF, 0x8282, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E43, 0x0081, 0x0B97, 0x00C2, 0x0E0A, 0x0083, 0x0E44, + 0x02BF, 0x845D, 0x00F8, 0x0BAF, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, + 0x0E09, 0x02BF, 0x8282, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x0083, 0x0E44, 0x00C4, + 0x0E41, 0x00C5, 0x0E0C, 0x02BF, 0x8282, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, 0x00C0, 0x0E43, 0x0081, 0x0B97, 0x00C2, 0x0E0A, 0x0083, + 0x0E44, 0x1C80, 0x00C5, 0x0E0D, 0x02BF, 0x8282, 0x00F8, 0x0BAF, 0x00FB, 0x0BB0, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, + 0x0E08, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x8282, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, 0x0081, + 0x0B91, 0x00C2, 0x0E0E, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E0F, 0x02BF, 0x8282, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x0083, 0x0E44, 0x1C80, 0x00C5, 0x0E0A, 0x02BF, 0x8282, 0x00F8, 0x0BB1, 0x00FB, 0x0BAF, + 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x8282, 0x00F8, + 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x0083, 0x0E44, 0x00C0, 0x0E41, 0x00C5, 0x0E0C, 0x02BF, + 0x8282, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, 0x00C0, 0x0E40, 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, + 0x0E0F, 0x02BF, 0x8282, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x00C0, 0x0E43, 0x0081, 0x0B97, 0x00C2, 0x0E0A, 0x0083, 0x0E44, 0x1C80, + 0x00C5, 0x0E0D, 0x02BF, 0x8282, 0x00F8, 0x0BAF, 0x00FB, 0x0BB0, 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x0083, 0x0E44, + 0x02BF, 0x845D, 0x00F8, 0x0BB1, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E09, + 0x02BF, 0x80E7, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E43, 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x1C62, 0x1C80, 0x00C5, 0x0E0F, + 0x02BF, 0x80E7, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x1C62, 0x00C4, 0x0E41, + 0x00C5, 0x0E09, 0x02BF, 0x80E7, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E43, 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x1C62, 0x1C80, + 0x00C5, 0x0E0F, 0x02BF, 0x80E7, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x00C0, 0x0E40, 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x1C62, 0x00C4, + 0x0E41, 0x00C5, 0x0E0C, 0x02BF, 0x80E7, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, 0x0E0D, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BB0, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, + 0x0E09, 0x02BF, 0x8282, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E43, 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x0083, 0x0E44, 0x1C80, + 0x00C5, 0x0E0F, 0x02BF, 0x8282, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x0083, + 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x8282, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E43, 0x0081, 0x0B91, 0x00C2, + 0x0E0E, 0x0083, 0x0E44, 0x1C80, 0x00C5, 0x0E0F, 0x02BF, 0x8282, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x00C0, 0x0E40, 0x0081, 0x0B8D, + 0x00C2, 0x0E0B, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E0C, 0x02BF, 0x8282, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, 0x00C0, 0x0E43, + 0x0081, 0x0B99, 0x00C2, 0x0E0D, 0x0083, 0x0E44, 0x02BF, 0x845D, 0x00F8, 0x0BB0, 0x02DF, 0x0082, 0x013E, 0x01BD, 0x0249, 0x0413, + 0x0427, 0x0165, 0x0175, 0x0B02, 0x015F, 0x0478, 0x0474, 0x0476, 0x01AA, 0x043B, 0x047A, 0x0B7C, 0x0734, 0x0746, 0x0769, 0x078C, + 0x07C0, 0x07DD, 0x0810, 0x0843, 0x0892, 0x08A5, 0x08CA, 0x08EF, 0x0926, 0x0945, 0x097B, 0x09B1, 0x0A05, 0x0A27, 0x0734, 0x0734, + 0x0734, 0x0734, 0x0734, 0x0734, 0x0A65, 0x0A89, 0x0734, 0x0734, 0x0734, 0x0734, 0x0734, 0x0734, 0x0574, 0x0629, 0x06D3, 0x1000, + 0x1200, 0x1400, 0x8E00, 0x8100, 0x8970, 0x191C, 0x2ECE, 0x2CCF, 0x16CD, 0x0E80, 0x16C9, 0x0000, 0x16CB, 0x0100, 0x1F7E, 0x1F3C, + 0x8100, 0x26C9, 0x02A0, 0x0004, 0x029C, 0x0B11, 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, 0x0B2F, 0x8F00, 0x8A78, 0x8C68, 0xF100, 0x1A3F, 0x84E3, 0x107E, 0xF2E3, 0xF2E7, 0xF278, 0x6E68, 0xF132, + 0x1A3F, 0x119E, 0x0B4B, 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, 0x0B6B, 0x197F, 0x9930, 0x1B1E, 0x1B3F, 0x7D29, 0x1B5F, 0x1B5D, 0x8E00, 0x1FDB, 0x1F99, 0x2ECE, + 0x2CCF, 0x16CD, 0x0E80, 0x16C9, 0x0001, 0x16CB, 0x0100, 0x02BF, 0x055C, 0x1C04, 0x029F, 0x0068, 0x8E00, 0x8100, 0x8970, 0x191C, + 0x2ECE, 0x2CCF, 0x16CD, 0x07C0, 0x16C9, 0x0001, 0x16CB, 0x0500, 0x02BF, 0x055C, 0x8100, 0x8970, 0x191C, 0x2ECE, 0x2CCF, 0x16CD, + 0x07C0, 0x16C9, 0x0000, 0x8900, 0x0D20, 0x2DCB, 0x4C00, 0x1C80, 0x0080, 0x07C0, 0x0083, 0x0000, 0x1C43, 0x0A00, 0x27C9, 0x03A0, + 0x0004, 0x029C, 0x0B9E, 0x2ECE, 0x2CCF, 0x16CD, 0x07D0, 0x16C9, 0x0000, 0x16CB, 0x04E0, 0x8F00, 0x80F0, 0x80C0, 0x6A00, 0x4800, + 0x114F, 0x0BB9, 0x80F0, 0x80C0, 0x6B32, 0x4922, 0x80F0, 0x80C0, 0x6A3A, 0x482A, 0x80F0, 0x80C0, 0x6B32, 0x4922, 0x1B5F, 0x1B5D, + 0x80F0, 0x80C0, 0x6800, 0x7C00, 0x4A00, 0x114F, 0x0BD0, 0x80F0, 0x80C0, 0x6932, 0x7D00, 0x4B22, 0x80F0, 0x80C0, 0x683A, 0x7C00, + 0x4A2A, 0x80F0, 0x80C0, 0x6932, 0x7D00, 0x4B22, 0x1B5F, 0x1B5D, 0x1C04, 0x029F, 0x0068, 0x8E00, 0x16FC, 0xECC0, 0x1FCC, 0x1D9E, + 0x2EFD, 0x26FC, 0x02A0, 0x8000, 0x029C, 0x0BE1, 0x0000, 0x0000, 0x0000, 0x02FF, 0x8E00, 0x00F0, 0x0E17, 0x00FE, 0x0E18, 0x00FC, + 0x0E19, 0x1FCC, 0x1D9E, 0x16FC, 0xFEED, 0x2EFD, 0x26FC, 0x02A0, 0x8000, 0x029C, 0x0BF6, 0x00D0, 0x0E17, 0x00DE, 0x0E18, 0x00DC, + 0x0E19, 0x0000, 0x0000, 0x0000, 0x0000, 0x02FF, 0x8E00, 0x1DBC, 0x1DBE, 0x8100, 0x00DE, 0x0BB7, 0x0601, 0x0295, 0x0C12, 0x0E00, + 0x00FE, 0x0B87, 0x1FCD, 0x1F8D, 0x02FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x02FF, 0x8E00, 0x1DBC, 0x1DBE, 0x8100, 0x00DE, + 0x0BB7, 0x0601, 0x0295, 0x0C2A, 0x0E00, 0x00FE, 0x0B87, 0x1FCD, 0x1F8D, 0x02FF, 0x8100, 0x00DE, 0x0B88, 0x0601, 0x0295, 0x0C3C, + 0x00DE, 0x0BDA, 0x2EDA, 0x00DE, 0x0BDB, 0x2EDB, 0x00DE, 0x0BDC, 0x2EDC, 0x1FCD, 0x1F8D, 0x02FF, 0x00DE, 0x0BDA, 0x2EDA, 0x26DB, + 0x2EDB, 0x26DC, 0x2EDC, 0x8100, 0x1FCD, 0x1F8D, 0x02FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x02FF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x02FF, 0x0C64, 0x0C67, 0x0C9F, 0x0CA2, 0x8E00, 0x8100, 0x8900, 0x02BF, 0x0CA5, 0x27FF, 0x009E, 0x0C52, 0x4C00, 0x1C7E, + 0x0313, 0x1C7F, 0x176F, 0x0021, 0x029F, 0x0030, 0x0021, 0x8100, 0x8900, 0x02BF, 0x0CA5, 0x24FF, 0x02BF, 0x0CAB, 0x25FF, 0x02BF, + 0x0CAB, 0x27FF, 0x2ECE, 0x2CCF, 0x16C9, 0x0001, 0x2FCD, 0x2DCB, 0x8100, 0x8900, 0x02BF, 0x0CA5, 0x24FF, 0x1C9E, 0x1CBC, 0x02BF, + 0x0CAB, 0x25FF, 0x02BF, 0x0CAB, 0x27FF, 0x1CDF, 0x1CFD, 0x8100, 0x02BF, 0x0CA5, 0x26FF, 0x1C1E, 0x8900, 0x02BF, 0x0CAB, 0x20FF, + 0x1F5F, 0x02BF, 0x0CA5, 0x21FF, 0x02BF, 0x0CA5, 0x23FF, 0x26C9, 0x02A0, 0x0004, 0x029C, 0x0C97, 0x029F, 0x80B5, 0x0021, 0x029F, + 0x8000, 0x0021, 0x029F, 0x0045, 0x0021, 0x26FE, 0x02C0, 0x8000, 0x029C, 0x0CA5, 0x02DF, 0x27FE, 0x03C0, 0x8000, 0x029C, 0x0CAB, + 0x02DF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 +}; diff --git a/libs/dolphin/ax/__ax.h b/libs/dolphin/ax/__ax.h new file mode 100644 index 000000000..1fb0fb8d2 --- /dev/null +++ b/libs/dolphin/ax/__ax.h @@ -0,0 +1,67 @@ +#ifndef _DOLPHIN_AX_INTERNAL_H_ +#define _DOLPHIN_AX_INTERNAL_H_ + +#include + +// AXAlloc.c +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.c +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); + +// AXCL.c +extern u32 __AXClMode; + +u32 __AXGetCommandListCycles(void); +u32 __AXGetCommandListAddress(void); +void __AXWriteToCommandList(u16 data); +void __AXNextFrame(void* sbuffer, void* buffer); +void __AXClInit(void); +void __AXClQuit(void); + +// AXOut.c +void __AXOutNewFrame(u32 lessDspCycles); +void __AXOutAiCallback(void); +void __AXOutInitDSP(void); +void __AXOutInit(u32); +void __AXOutQuit(void); + +// AXProf.c +AXPROFILE* __AXGetCurrentProfile(void); + +// AXSPB.c +u32 __AXGetStudio(void); +void __AXDepopFade(long* hostSum, long* dspVolume, s16* dspDelta); +void __AXPrintStudio(void); +void __AXSPBInit(void); +void __AXSPBQuit(void); +void __AXDepopVoice(AXPB* p); + +// AXVPB.c +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); + +#endif // _DOLPHIN_AX_INTERNAL_H_ diff --git a/libs/dolphin/base/PPCArch.c b/libs/dolphin/base/PPCArch.c new file mode 100644 index 000000000..33dc03e67 --- /dev/null +++ b/libs/dolphin/base/PPCArch.c @@ -0,0 +1,263 @@ +#include +#include +#include + +union FpscrUnion +{ + f64 f; + struct + { + u32 fpscr_pad; + u32 fpscr; + } u; +}; + +void PPCMthid0(u32 newHID0); + +asm u32 PPCMfmsr(void) +{ + nofralloc mfmsr r3 blr +} + +asm void PPCMtmsr(register u32 newMSR) +{ + nofralloc mtmsr newMSR blr +} + +void PPCOrMsr(void) +{ + // UNUSED FUNCTION +} + +void PPCAndMsr(void) +{ + // UNUSED FUNCTION +} + +void PPCAndCMsr(void) +{ + // UNUSED FUNCTION +} + +asm u32 PPCMfhid0(void) +{ + nofralloc mfspr r3, HID0 blr +} + +asm void PPCMthid0(register u32 newHID0) +{ + nofralloc mtspr HID0, newHID0 blr +} + +void PPCMfhid1(void) +{ + // UNUSED FUNCTION +} + +asm u32 PPCMfl2cr(void) +{ + nofralloc mfspr r3, L2CR blr +} + +asm void PPCMtl2cr(register u32 newL2cr) +{ + nofralloc mtspr L2CR, newL2cr blr +} + +__declspec(weak) asm void PPCMtdec(register u32 newDec) +{ + nofralloc mtdec newDec blr +} + +void PPCMfdec(void) +{ + // UNUSED FUNCTION +} + +asm void PPCSync(void) +{ + nofralloc sc blr +} + +asm void PPCEieio(void) +{ + nofralloc mfmsr r5 rlwinm r6, r5, 0, 0x11, 0xf mtmsr r6 mfspr r3, hid0 ori r4, r3, 8 mtspr hid0, + r4 isync eieio isync + + mtspr hid0, + r3 mtmsr r5 isync + + blr +} + +__declspec(weak) asm void PPCHalt(void) //spins infinitely +{ + nofralloc + + sync + + _spin : nop li r3, + 0 nop b _spin + + // NEVER REACHED +} + +asm void PPCMfmmcr0(void) +{ + nofralloc mfspr r3, MMCR0 blr +} + +asm void PPCMtmmcr0(register u32 newMmcr0) +{ + nofralloc mtspr MMCR0, newMmcr0 blr +} + +asm void PPCMfmmcr1(void) +{ + nofralloc mfspr r3, MMCR1 blr +} + +asm void PPCMtmmcr1(register u32 newMmcr1) +{ + nofralloc mtspr MMCR1, newMmcr1 blr +} + +asm void PPCMfpmc1(void) +{ + nofralloc mfspr r3, PMC1 blr +} + +asm void PPCMtpmc1(register u32 newPmc1) +{ + nofralloc mtspr PMC1, newPmc1 blr +} + +asm void PPCMfpmc2(void) +{ + nofralloc mfspr r3, PMC2 blr +} + +asm void PPCMtpmc2(register u32 newPmc2) +{ + nofralloc mtspr PMC2, newPmc2 blr +} + +asm void PPCMfpmc3(void) +{ + nofralloc mfspr r3, PMC2 blr +} + +asm void PPCMtpmc3(register u32 newPmc3) +{ + nofralloc mtspr PMC3, newPmc3 blr +} + +asm void PPCMfpmc4(void) +{ + nofralloc mfspr r3, PMC4 blr +} + +asm void PPCMtpmc4(register u32 newPmc4) +{ + nofralloc mtspr PMC4, newPmc4 blr +} + +asm void PPCMfsia(void) +{ + nofralloc mfspr r3, SIA blr +} + +asm void PPCMtsia(register u32 newSia){ nofralloc mtspr SIA, newSia blr } + +u32 PPCMffpscr(void) +{ + union FpscrUnion m; + + asm + { + mffs f31 + stfd f31, m.f; + } + + return m.u.fpscr; +} + +void PPCMtfpscr(register u32 newFPSCR) +{ + union FpscrUnion m; + + asm + { + li r4, 0 + stw r4, m.u.fpscr_pad; + stw newFPSCR, m.u.fpscr + lfd f31, m.f + mtfsf 0xff, f31 + } +} + +asm u32 PPCMfhid2(void) +{ + nofralloc mfspr r3, 0x398 blr +} + +asm void PPCMthid2(register u32 newhid2) +{ + nofralloc mtspr 0x398, newhid2 blr +} + +asm u32 PPCMfwpar(void) +{ + nofralloc sync mfspr r3, WPAR blr +} + +asm void PPCMtwpar(register u32 newwpar) +{ + nofralloc mtspr WPAR, newwpar blr +} + +asm void PPCMfdmaU(void) +{ + nofralloc mfspr r3, DMA_U blr +} + +asm void PPCMfdmaL(void) +{ + nofralloc mfspr r3, DMA_L blr +} + +void PPCMtdmaU(void) +{ + // UNUSED FUNCTION +} + +void PPCMtdmaL(void) +{ + // UNUSED FUNCTION +} + +void PPCMfpvr(void) +{ + // UNUSED FUNCTION +} + +void PPCEnableSpeculation(void) +{ + // UNUSED FUNCTION +} + +void PPCDisableSpeculation(void) +{ + PPCMthid0(PPCMfhid0() | HID0_SPD); +} + +asm void PPCSetFpIEEEMode(void) +{ + nofralloc mtfsb0 4 * 7 + 1 blr +} + +asm void PPCSetFpNonIEEEMode(void) +{ + nofralloc mtfsb1 29 blr +} +// clang-format on \ No newline at end of file diff --git a/libs/dolphin/card/CARDBios.c b/libs/dolphin/card/CARDBios.c new file mode 100644 index 000000000..8988eac3c --- /dev/null +++ b/libs/dolphin/card/CARDBios.c @@ -0,0 +1,722 @@ +#include + +const char* __CARDVersion = + "<< Dolphin SDK - CARD\trelease build: Apr 17 2003 12:34:19 (0x2301) >>"; + +CARDControl __CARDBlock[2]; +DVDDiskID __CARDDiskNone; + +static u16 __CARDEncode; + +s32 __CARDReadStatus(s32 chan, u8* status); +s32 __CARDClearStatus(s32 chan); +void __CARDSetDiskID(const DVDDiskID* id); +static s32 Retry(s32 chan); +static BOOL OnReset(BOOL f); + +static OSResetFunctionInfo ResetFunctionInfo = { OnReset, 127 }; + +void __CARDDefaultApiCallback(s32 chan, s32 result) +{ +} + +void __CARDSyncCallback(s32 channel, s32 result) +{ + OSWakeupThread(&__CARDBlock[channel].threadQueue); +} + +void __CARDExtHandler(s32 chan, OSContext* context) +{ + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + if (card->attached) + { + card->attached = FALSE; + EXISetExiCallback(chan, 0); + OSCancelAlarm(&card->alarm); + callback = card->exiCallback; + + if (callback) + { + card->exiCallback = 0; + callback(chan, CARD_RESULT_NOCARD); + } + + if (card->result != CARD_RESULT_BUSY) + { + card->result = CARD_RESULT_NOCARD; + } + + callback = card->extCallback; + if (callback && CARD_MAX_MOUNT_STEP <= card->mountStep) + { + card->extCallback = 0; + callback(chan, CARD_RESULT_NOCARD); + } + } +} + +void __CARDExiHandler(s32 chan, OSContext* context) +{ + CARDControl* card; + CARDCallback callback; + u8 status; + s32 result; + + card = &__CARDBlock[chan]; + + OSCancelAlarm(&card->alarm); + + if (!card->attached) + { + return; + } + + if (!EXILock(chan, 0, 0)) + { + result = CARD_RESULT_FATAL_ERROR; + goto fatal; + } + + if ((result = __CARDReadStatus(chan, &status)) < 0 || (result = __CARDClearStatus(chan)) < 0) + { + goto error; + } + + if ((result = (status & 0x18) ? CARD_RESULT_IOERROR : CARD_RESULT_READY) == + CARD_RESULT_IOERROR && + --card->retry > 0) + { + result = Retry(chan); + if (result >= 0) + { + return; + } + goto fatal; + } + +error: + EXIUnlock(chan); + +fatal: + callback = card->exiCallback; + if (callback) + { + card->exiCallback = 0; + callback(chan, result); + } +} + +void __CARDTxHandler(s32 chan, OSContext* context) +{ + CARDControl* card; + CARDCallback callback; + BOOL err; + + card = &__CARDBlock[chan]; + err = !EXIDeselect(chan); + EXIUnlock(chan); + callback = card->txCallback; + if (callback) + { + card->txCallback = 0; + callback(chan, (!err && EXIProbe(chan)) ? CARD_RESULT_READY : CARD_RESULT_NOCARD); + } +} + +void __CARDUnlockedHandler(s32 chan, OSContext* context) +{ + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + callback = card->unlockCallback; + if (callback) + { + card->unlockCallback = 0; + callback(chan, EXIProbe(chan) ? CARD_RESULT_UNLOCKED : CARD_RESULT_NOCARD); + } +} + +s32 __CARDEnableInterrupt(s32 chan, BOOL enable) +{ + BOOL err; + u32 cmd; + + if (!EXISelect(chan, 0, 4)) + { + return CARD_RESULT_NOCARD; + } + + cmd = enable ? 0x81010000 : 0x81000000; + err = FALSE; + err |= !EXIImm(chan, &cmd, 2, 1, NULL); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; +} + +s32 __CARDReadStatus(s32 chan, u8* status) +{ + BOOL err; + u32 cmd; + + if (!EXISelect(chan, 0, 4)) + { + return CARD_RESULT_NOCARD; + } + + cmd = 0x83000000; + err = FALSE; + err |= !EXIImm(chan, &cmd, 2, 1, NULL); + err |= !EXISync(chan); + err |= !EXIImm(chan, status, 1, 0, NULL); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; +} + +s32 __CARDClearStatus(s32 chan) +{ + BOOL err; + u32 cmd; + + if (!EXISelect(chan, 0, 4)) + { + return CARD_RESULT_NOCARD; + } + + cmd = 0x89000000; + err = FALSE; + err |= !EXIImm(chan, &cmd, 1, 1, 0); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + + return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; +} + +static void TimeoutHandler(OSAlarm* alarm, OSContext* context) +{ + s32 chan; + CARDControl* card; + CARDCallback callback; + for (chan = 0; chan < 2; ++chan) + { + card = &__CARDBlock[chan]; + if (alarm == &card->alarm) + { + break; + } + } + + if (!card->attached) + { + return; + } + + EXISetExiCallback(chan, NULL); + callback = card->exiCallback; + if (callback) + { + card->exiCallback = 0; + callback(chan, CARD_RESULT_IOERROR); + } +} + +static s32 Retry(s32 chan) +{ + CARDControl* card; + card = &__CARDBlock[chan]; + + if (!EXISelect(chan, 0, 4)) + { + EXIUnlock(chan); + return CARD_RESULT_NOCARD; + } + + OSCancelAlarm(&card->alarm); + switch (card->cmd[0]) + { + case 0xF2: + OSSetAlarm(&card->alarm, OSMillisecondsToTicks(100), TimeoutHandler); + break; + case 0xF3: + break; + case 0xF4: + case 0xF1: + OSSetAlarm(&card->alarm, OSSecondsToTicks((OSTime)2) * (card->sectorSize / 0x2000), + TimeoutHandler); + break; + } + + if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1)) + { + EXIDeselect(chan); + EXIUnlock(chan); + return CARD_RESULT_NOCARD; + } + + if (card->cmd[0] == 0x52 && + !EXIImmEx(chan, (u8*)card->workArea + sizeof(CARDID), card->latency, 1)) + { + EXIDeselect(chan); + EXIUnlock(chan); + return CARD_RESULT_NOCARD; + } + + if (card->mode == 0xffffffff) + { + EXIDeselect(chan); + EXIUnlock(chan); + return CARD_RESULT_READY; + } + + if (!EXIDma(chan, card->buffer, (s32)((card->cmd[0] == 0x52) ? 512 : 128), card->mode, + __CARDTxHandler)) + { + EXIDeselect(chan); + EXIUnlock(chan); + return CARD_RESULT_NOCARD; + } + + return CARD_RESULT_READY; +} + +static void UnlockedCallback(s32 chan, s32 result) +{ + CARDCallback callback; + CARDControl* card; + + card = &__CARDBlock[chan]; + if (result >= 0) + { + card->unlockCallback = UnlockedCallback; + if (!EXILock(chan, 0, __CARDUnlockedHandler)) + { + result = CARD_RESULT_READY; + } + else + { + card->unlockCallback = 0; + result = Retry(chan); + } + } + + if (result < 0) + { + switch (card->cmd[0]) + { + case 0x52: + callback = card->txCallback; + if (callback) + { + card->txCallback = 0; + callback(chan, result); + } + + break; + case 0xF2: + case 0xF4: + case 0xF1: + callback = card->exiCallback; + if (callback) + { + card->exiCallback = 0; + callback(chan, result); + } + break; + } + } +} + +static s32 __CARDStart(s32 chan, CARDCallback txCallback, CARDCallback exiCallback) +{ + BOOL enabled; + CARDControl* card; + s32 result; + + enabled = OSDisableInterrupts(); + + card = &__CARDBlock[chan]; + if (!card->attached) + { + result = CARD_RESULT_NOCARD; + } + else + { + if (txCallback) + { + card->txCallback = txCallback; + } + if (exiCallback) + { + card->exiCallback = exiCallback; + } + card->unlockCallback = UnlockedCallback; + if (!EXILock(chan, 0, __CARDUnlockedHandler)) + { + result = CARD_RESULT_BUSY; + } + else + { + card->unlockCallback = 0; + + if (!EXISelect(chan, 0, 4)) + { + EXIUnlock(chan); + result = CARD_RESULT_NOCARD; + } + else + { + OSCancelAlarm(&card->alarm); + switch (card->cmd[0]) + { + case 0xF2: + OSSetAlarm(&card->alarm, OSMillisecondsToTicks(100), TimeoutHandler); + break; + case 0xF3: + break; + case 0xF4: + case 0xF1: + OSSetAlarm(&card->alarm, + OSSecondsToTicks((OSTime)2) * (card->sectorSize / 0x2000), + TimeoutHandler); + break; + } + result = CARD_RESULT_READY; + } + } + } + + OSRestoreInterrupts(enabled); + return result; +} + +#define AD1(x) ((u8)(((x) >> 17) & 0x7f)) +#define AD1EX(x) ((u8)(AD1(x) | 0x80)); +#define AD2(x) ((u8)(((x) >> 9) & 0xff)) +#define AD3(x) ((u8)(((x) >> 7) & 0x03)) +#define BA(x) ((u8)((x)&0x7f)) + +s32 __CARDReadSegment(s32 chan, CARDCallback callback) +{ + CARDControl* card; + s32 result; + + card = &__CARDBlock[chan]; + card->cmd[0] = 0x52; + card->cmd[1] = AD1(card->addr); + card->cmd[2] = AD2(card->addr); + card->cmd[3] = AD3(card->addr); + card->cmd[4] = BA(card->addr); + card->cmdlen = 5; + card->mode = 0; + card->retry = 0; + + result = __CARDStart(chan, callback, 0); + if (result == CARD_RESULT_BUSY) + { + result = CARD_RESULT_READY; + } + else if (result >= 0) + { + if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1) || + !EXIImmEx(chan, (u8*)card->workArea + sizeof(CARDID), card->latency, + 1) || // XXX use DMA if possible + !EXIDma(chan, card->buffer, 512, card->mode, __CARDTxHandler)) + { + card->txCallback = 0; + EXIDeselect(chan); + EXIUnlock(chan); + result = CARD_RESULT_NOCARD; + } + else + { + result = CARD_RESULT_READY; + } + } + return result; +} + +s32 __CARDWritePage(s32 chan, CARDCallback callback) +{ + CARDControl* card; + s32 result; + + card = &__CARDBlock[chan]; + card->cmd[0] = 0xF2; + card->cmd[1] = AD1(card->addr); + card->cmd[2] = AD2(card->addr); + card->cmd[3] = AD3(card->addr); + card->cmd[4] = BA(card->addr); + card->cmdlen = 5; + card->mode = 1; + card->retry = 3; + + result = __CARDStart(chan, 0, callback); + if (result == CARD_RESULT_BUSY) + { + result = CARD_RESULT_READY; + } + else if (result >= 0) + { + if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1) || + !EXIDma(chan, card->buffer, 128, card->mode, __CARDTxHandler)) + { + card->exiCallback = 0; + EXIDeselect(chan); + EXIUnlock(chan); + result = CARD_RESULT_NOCARD; + } + else + { + result = CARD_RESULT_READY; + } + } + return result; +} + +s32 __CARDEraseSector(s32 chan, u32 addr, CARDCallback callback) +{ + CARDControl* card; + s32 result; + + card = &__CARDBlock[chan]; + card->cmd[0] = 0xF1; + card->cmd[1] = AD1(addr); + card->cmd[2] = AD2(addr); + card->cmdlen = 3; + card->mode = -1; + card->retry = 3; + + result = __CARDStart(chan, 0, callback); + + if (result == CARD_RESULT_BUSY) + { + result = CARD_RESULT_READY; + } + else if (result >= 0) + { + if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1)) + { + card->exiCallback = NULL; + result = CARD_RESULT_NOCARD; + } + else + { + result = CARD_RESULT_READY; + } + + EXIDeselect(chan); + EXIUnlock(chan); + } + return result; +} + +void CARDInit(void) +{ + int chan; + + if (__CARDBlock[0].diskID && __CARDBlock[1].diskID) + { + return; + } + + __CARDEncode = OSGetFontEncode(); + + OSRegisterVersion(__CARDVersion); + + DSPInit(); + OSInitAlarm(); + + for (chan = 0; chan < 2; ++chan) + { + CARDControl* card = &__CARDBlock[chan]; + + card->result = CARD_RESULT_NOCARD; + OSInitThreadQueue(&card->threadQueue); + OSCreateAlarm(&card->alarm); + } + __CARDSetDiskID((DVDDiskID*)OSPhysicalToCached(0x0)); + + OSRegisterResetFunction(&ResetFunctionInfo); +} + +u16 __CARDGetFontEncode() +{ + return __CARDEncode; +} + +void __CARDSetDiskID(const DVDDiskID* id) +{ + __CARDBlock[0].diskID = id ? id : &__CARDDiskNone; + __CARDBlock[1].diskID = id ? id : &__CARDDiskNone; +} + +s32 __CARDGetControlBlock(s32 chan, CARDControl** pcard) +{ + BOOL enabled; + s32 result; + CARDControl* card; + + card = &__CARDBlock[chan]; + if (chan < 0 || chan >= 2 || card->diskID == NULL) + { + return CARD_RESULT_FATAL_ERROR; + } + + enabled = OSDisableInterrupts(); + if (!card->attached) + { + result = CARD_RESULT_NOCARD; + } + else if (card->result == CARD_RESULT_BUSY) + { + result = CARD_RESULT_BUSY; + } + else + { + card->result = CARD_RESULT_BUSY; + result = CARD_RESULT_READY; + card->apiCallback = 0; + *pcard = card; + } + OSRestoreInterrupts(enabled); + return result; +} + +s32 __CARDPutControlBlock(CARDControl* card, s32 result) +{ + BOOL enabled; + + enabled = OSDisableInterrupts(); + if (card->attached) + { + card->result = result; + } + else if (card->result == CARD_RESULT_BUSY) + { + card->result = result; + } + OSRestoreInterrupts(enabled); + return result; +} + +s32 CARDGetResultCode(s32 chan) +{ + CARDControl* card; + if (chan < 0 || chan >= 2) + { + return CARD_RESULT_FATAL_ERROR; + } + card = &__CARDBlock[chan]; + return card->result; +} + +s32 CARDFreeBlocks(s32 chan, s32* byteNotUsed, s32* filesNotUsed) +{ + CARDControl* card; + s32 result; + u16* fat; + CARDDir* dir; + CARDDir* ent; + u16 fileNo; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + { + return result; + } + + fat = __CARDGetFatBlock(card); + dir = __CARDGetDirBlock(card); + if (fat == 0 || dir == 0) + { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + + if (byteNotUsed) + { + *byteNotUsed = (s32)(card->sectorSize * fat[CARD_FAT_FREEBLOCKS]); + } + + if (filesNotUsed) + { + *filesNotUsed = 0; + for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) + { + ent = &dir[fileNo]; + if (ent->fileName[0] == 0xff) + { + ++*filesNotUsed; + } + } + } + + return __CARDPutControlBlock(card, CARD_RESULT_READY); +} + +s32 CARDGetEncoding(s32 chan, u16* encode) +{ + CARDControl* card; + CARDID* id; + s32 result; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + { + return result; + } + + id = card->workArea; + *encode = id->encode; + 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); +} + +s32 __CARDSync(s32 channel) +{ + CARDControl* card; + s32 result; + BOOL enabled; + + card = &__CARDBlock[channel]; + enabled = OSDisableInterrupts(); + + while ((result = CARDGetResultCode(channel)) == CARD_RESULT_BUSY) + { + OSSleepThread(&card->threadQueue); + } + + OSRestoreInterrupts(enabled); + return result; +} + +static BOOL OnReset(BOOL f) +{ + if (!f) + { + if (CARDUnmount(0) == CARD_RESULT_BUSY || CARDUnmount(1) == CARD_RESULT_BUSY) + { + return FALSE; + } + } + + return TRUE; +} \ No newline at end of file diff --git a/libs/dolphin/card/CARDBlock.c b/libs/dolphin/card/CARDBlock.c new file mode 100644 index 000000000..b6305f129 --- /dev/null +++ b/libs/dolphin/card/CARDBlock.c @@ -0,0 +1,159 @@ +#include +#include +#include +#include + +#include + +u16* __CARDGetFatBlock(CARDControl* card) { return card->currentFat; } + +static void WriteCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + u16* fat; + u16* fatBack; + + card = &__CARDBlock[chan]; + + if (result >= 0) { + fat = (u16*)((u8*)card->workArea + 0x6000); + fatBack = (u16*)((u8*)card->workArea + 0x8000); + + if (card->currentFat == fat) { + card->currentFat = fatBack; + memcpy(fatBack, fat, 0x2000); + } else { + card->currentFat = fat; + memcpy(fat, fatBack, 0x2000); + } + } + + if (card->apiCallback == NULL) { + __CARDPutControlBlock(card, result); + } + + callback = card->eraseCallback; + if (callback) { + card->eraseCallback = NULL; + callback(chan, result); + } +} + +static void EraseCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + u32 temp[2]; /* this compiler sucks */ + u16* fat; + u32 addr; + + card = &__CARDBlock[chan]; + if (result < 0) { + goto error; + } + + fat = __CARDGetFatBlock(card); + addr = ((u32)fat - (u32)card->workArea) / CARD_SYSTEM_BLOCK_SIZE * card->sectorSize; + result = __CARDWrite(chan, addr, CARD_SYSTEM_BLOCK_SIZE, fat, WriteCallback); + if (result < 0) { + goto error; + } + + return; + +error: + if (card->apiCallback == NULL) { + __CARDPutControlBlock(card, result); + } + callback = card->eraseCallback; + if (callback) { + card->eraseCallback = NULL; + callback(chan, result); + } +} + +s32 __CARDAllocBlock(s32 chan, u32 cBlock, CARDCallback callback) { + CARDControl* card; + u16* fat; + u16 iBlock; + u16 startBlock; + u16 prevBlock; + u16 count; + + card = &__CARDBlock[chan]; + if (!card->attached) { + return CARD_RESULT_NOCARD; + } + + fat = __CARDGetFatBlock(card); + if (fat[3] < cBlock) { + return CARD_RESULT_INSSPACE; + } + + fat[3] -= cBlock; + startBlock = 0xFFFF; + iBlock = fat[4]; + count = 0; + while (0 < cBlock) { + if (card->cBlock - 5 < ++count) { + return CARD_RESULT_BROKEN; + } + + iBlock++; + if (!CARDIsValidBlockNo(card, iBlock)) { + iBlock = 5; + } + + if (fat[iBlock] == 0x0000u) { + if (startBlock == 0xFFFF) { + startBlock = iBlock; + } else { + fat[prevBlock] = iBlock; + } + prevBlock = iBlock; + fat[iBlock] = 0xFFFF; + --cBlock; + } + } + fat[4] = iBlock; + card->startBlock = startBlock; + + return __CARDUpdateFatBlock(chan, fat, callback); +} + +s32 __CARDFreeBlock(s32 chan, u16 nBlock, CARDCallback callback) { + CARDControl* card; + u16* fat; + u16 nextBlock; + + card = card = &__CARDBlock[chan]; + if (!card->attached) { + return CARD_RESULT_NOCARD; + } + + fat = __CARDGetFatBlock(card); + while (nBlock != 0xFFFF) { + if (!CARDIsValidBlockNo(card, nBlock)) { + return CARD_RESULT_BROKEN; + } + + nextBlock = fat[nBlock]; + fat[nBlock] = 0; + nBlock = nextBlock; + ++fat[3]; + } + + return __CARDUpdateFatBlock(chan, fat, callback); +} + +s32 __CARDUpdateFatBlock(s32 chan, u16* fat, CARDCallback callback) { + CARDControl* card; + + card = &__CARDBlock[chan]; + ++fat[2]; + __CARDCheckSum(fat + 2, 0x1FFC, fat, fat + 1); + DCStoreRange(fat, 0x2000); + card->eraseCallback = callback; + + return __CARDEraseSector(chan, (((u32)fat - (u32)card->workArea) / 8192u) * card->sectorSize, + EraseCallback); +} diff --git a/libs/dolphin/card/CARDCheck.c b/libs/dolphin/card/CARDCheck.c new file mode 100644 index 000000000..9d0771cc9 --- /dev/null +++ b/libs/dolphin/card/CARDCheck.c @@ -0,0 +1,406 @@ +#include +#include +#include +#include + +#include +#include + +#include "string.h" + +#define __CARDGetDirCheck(dir) ((CARDDirCheck*)&(dir)[CARD_MAX_FILE]) + +void __CARDCheckSum(void* ptr, int length, u16* checksum, u16* checksumInv) +{ + u16* p; + int i; + + length /= sizeof(u16); + *checksum = *checksumInv = 0; + for (i = 0, p = ptr; i < length; i++, p++) + { + *checksum += *p; + *checksumInv += ~*p; + } + if (*checksum == 0xffff) + { + *checksum = 0; + } + if (*checksumInv == 0xffff) + { + *checksumInv = 0; + } +} + +static s32 VerifyID(CARDControl* card) +{ + CARDID* id; + u16 checksum; + u16 checksumInv; + OSSramEx* sramEx; + OSTime rand; + int i; + + id = card->workArea; + + if (id->deviceID != 0 || id->size != card->size) + { + return CARD_RESULT_BROKEN; + } + + __CARDCheckSum(id, sizeof(CARDID) - sizeof(u32), &checksum, &checksumInv); + if (id->checkSum != checksum || id->checkSumInv != checksumInv) + { + return CARD_RESULT_BROKEN; + } + + rand = *(OSTime*)&id->serial[12]; + sramEx = __OSLockSramEx(); + + for (i = 0; i < 12; i++) + { + rand = (rand * 1103515245 + 12345) >> 16; + if (id->serial[i] != (u8)(sramEx->flashID[card - __CARDBlock][i] + rand)) + { + __OSUnlockSramEx(FALSE); + return CARD_RESULT_BROKEN; + } + rand = ((rand * 1103515245 + 12345) >> 16) & 0x7FFF; + } + + __OSUnlockSramEx(FALSE); + if (id->encode != __CARDGetFontEncode()) + { + return CARD_RESULT_ENCODING; + } + + return CARD_RESULT_READY; +} + +static s32 VerifyDir(CARDControl* card, int* outCurrent) +{ + CARDDir* dir[2]; + CARDDirCheck* check[2]; + u16 checkSum; + u16 checkSumInv; + int i; + int errors; + int current; + + current = errors = 0; + for (i = 0; i < 2; i++) + { + dir[i] = (CARDDir*)((u8*)card->workArea + (1 + i) * CARD_SYSTEM_BLOCK_SIZE); + check[i] = __CARDGetDirCheck(dir[i]); + __CARDCheckSum(dir[i], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &checkSum, &checkSumInv); + if (check[i]->checkSum != checkSum || check[i]->checkSumInv != checkSumInv) + { + ++errors; + current = i; + card->currentDir = 0; + } + } + + if (0 == errors) + { + if (card->currentDir == 0) + { + if ((check[0]->checkCode - check[1]->checkCode) < 0) + { + current = 0; + } + else + { + current = 1; + } + card->currentDir = dir[current]; + memcpy(dir[current], dir[current ^ 1], CARD_SYSTEM_BLOCK_SIZE); + } + else + { + current = (card->currentDir == dir[0]) ? 0 : 1; + } + } + if (outCurrent) + { + *outCurrent = current; + } + return errors; +} + +static s32 VerifyFAT(CARDControl* card, int* outCurrent) +{ + u16* fat[2]; + u16* fatp; + u16 nBlock; + u16 cFree; + int i; + u16 checkSum; + u16 checkSumInv; + int errors; + int current; + + current = errors = 0; + for (i = 0; i < 2; i++) + { + fatp = fat[i] = (u16*)((u8*)card->workArea + (3 + i) * CARD_SYSTEM_BLOCK_SIZE); + + __CARDCheckSum(&fatp[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &checkSum, + &checkSumInv); + if (fatp[CARD_FAT_CHECKSUM] != checkSum || fatp[CARD_FAT_CHECKSUMINV] != checkSumInv) + { + ++errors; + current = i; + card->currentFat = 0; + continue; + } + + cFree = 0; + for (nBlock = CARD_NUM_SYSTEM_BLOCK; nBlock < card->cBlock; nBlock++) + { + if (fatp[nBlock] == CARD_FAT_AVAIL) + { + cFree++; + } + } + if (cFree != fatp[CARD_FAT_FREEBLOCKS]) + { + ++errors; + current = i; + card->currentFat = 0; + continue; + } + } + + if (0 == errors) + { + if (card->currentFat == 0) + { + if (((s16)fat[0][CARD_FAT_CHECKCODE] - (s16)fat[1][CARD_FAT_CHECKCODE]) < 0) + { + current = 0; + } + else + { + current = 1; + } + card->currentFat = fat[current]; + memcpy(fat[current], fat[current ^ 1], CARD_SYSTEM_BLOCK_SIZE); + } + else + { + current = (card->currentFat == fat[0]) ? 0 : 1; + } + } + if (outCurrent) + { + *outCurrent = current; + } + return errors; +} + +s32 __CARDVerify(CARDControl* card) +{ + s32 result; + int errors; + + result = VerifyID(card); + if (result < 0) + { + return result; + } + + errors = VerifyDir(card, NULL); + errors += VerifyFAT(card, NULL); + switch (errors) + { + case 0: + return CARD_RESULT_READY; + case 1: + return CARD_RESULT_BROKEN; + default: + return CARD_RESULT_BROKEN; + } +} + +s32 CARDCheckExAsync(s32 chan, s32* xferBytes, CARDCallback callback) +{ + CARDControl* card; + CARDDir* dir[2]; + u16* fat[2]; + u16* map; + s32 result; + int errors; + int currentFat; + int currentDir; + s32 fileNo; + u16 iBlock; + u16 cBlock; + u16 cFree; + BOOL updateFat = FALSE; + BOOL updateDir = FALSE; + BOOL updateOrphan = FALSE; + + if (xferBytes) + { + *xferBytes = 0; + } + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + { + return result; + } + + result = VerifyID(card); + if (result < 0) + { + return __CARDPutControlBlock(card, result); + } + + errors = VerifyDir(card, ¤tDir); + errors += VerifyFAT(card, ¤tFat); + if (1 < errors) + { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + + dir[0] = (CARDDir*)((u8*)card->workArea + (1 + 0) * CARD_SYSTEM_BLOCK_SIZE); + dir[1] = (CARDDir*)((u8*)card->workArea + (1 + 1) * CARD_SYSTEM_BLOCK_SIZE); + fat[0] = (u16*)((u8*)card->workArea + (3 + 0) * CARD_SYSTEM_BLOCK_SIZE); + fat[1] = (u16*)((u8*)card->workArea + (3 + 1) * CARD_SYSTEM_BLOCK_SIZE); + + switch (errors) + { + case 0: + break; + case 1: + if (!card->currentDir) + { + card->currentDir = dir[currentDir]; + memcpy(dir[currentDir], dir[currentDir ^ 1], CARD_SYSTEM_BLOCK_SIZE); + updateDir = TRUE; + } + else + { + card->currentFat = fat[currentFat]; + memcpy(fat[currentFat], fat[currentFat ^ 1], CARD_SYSTEM_BLOCK_SIZE); + updateFat = TRUE; + } + break; + } + + map = fat[currentFat ^ 1]; + memset(map, 0, CARD_SYSTEM_BLOCK_SIZE); + + for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) + { + CARDDir* ent; + + ent = &card->currentDir[fileNo]; + if (ent->gameName[0] == 0xff) + { + continue; + } + + for (iBlock = ent->startBlock, cBlock = 0; iBlock != 0xFFFF && cBlock < ent->length; + iBlock = card->currentFat[iBlock], ++cBlock) + { + if (!CARDIsValidBlockNo(card, iBlock) || 1 < ++map[iBlock]) + { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + } + if (cBlock != ent->length || iBlock != 0xFFFF) + { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + } + + cFree = 0; + for (iBlock = CARD_NUM_SYSTEM_BLOCK; iBlock < card->cBlock; iBlock++) + { + u16 nextBlock; + + nextBlock = card->currentFat[iBlock]; + if (map[iBlock] == 0) + { + if (nextBlock != CARD_FAT_AVAIL) + { + card->currentFat[iBlock] = CARD_FAT_AVAIL; + updateOrphan = TRUE; + } + cFree++; + } + else if (!CARDIsValidBlockNo(card, nextBlock) && nextBlock != 0xFFFF) + { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + } + if (cFree != card->currentFat[CARD_FAT_FREEBLOCKS]) + { + card->currentFat[CARD_FAT_FREEBLOCKS] = cFree; + updateOrphan = TRUE; + } + if (updateOrphan) + { + __CARDCheckSum(&card->currentFat[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), + &card->currentFat[CARD_FAT_CHECKSUM], + &card->currentFat[CARD_FAT_CHECKSUMINV]); + } + + memcpy(fat[currentFat ^ 1], fat[currentFat], CARD_SYSTEM_BLOCK_SIZE); + + if (updateDir) + { + if (xferBytes) + { + *xferBytes = CARD_SYSTEM_BLOCK_SIZE; + } + return __CARDUpdateDir(chan, callback); + } + + if (updateFat | updateOrphan) + { + if (xferBytes) + { + *xferBytes = CARD_SYSTEM_BLOCK_SIZE; + } + return __CARDUpdateFatBlock(chan, card->currentFat, callback); + } + + __CARDPutControlBlock(card, CARD_RESULT_READY); + if (callback) + { + BOOL enabled = OSDisableInterrupts(); + callback(chan, CARD_RESULT_READY); + OSRestoreInterrupts(enabled); + } + return CARD_RESULT_READY; +} + +s32 CARDCheckEx(s32 chan, s32* xferBytes) +{ + s32 result = CARDCheckExAsync(chan, xferBytes, __CARDSyncCallback); + if (result < 0 || xferBytes == 0) + { + return result; + } + + return __CARDSync(chan); +} + +s32 CARDCheck(s32 channel) +{ + s32 result; + s32 xferBytes; + + result = CARDCheckExAsync(channel, &xferBytes, __CARDSyncCallback); + + if (result < 0 || &xferBytes == nullptr) + { + return result; + } + + return __CARDSync(channel); +} \ No newline at end of file diff --git a/libs/dolphin/card/CARDCreate.c b/libs/dolphin/card/CARDCreate.c new file mode 100644 index 000000000..06132d90f --- /dev/null +++ b/libs/dolphin/card/CARDCreate.c @@ -0,0 +1,141 @@ +#include +#include +#include +#include + +#include + +static void CreateCallbackFat(s32 chan, s32 result) +{ + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + CARDCallback callback; + + card = &__CARDBlock[chan]; + callback = card->apiCallback; + card->apiCallback = 0; + if (result < 0) + { + goto error; + } + + dir = __CARDGetDirBlock(card); + ent = &dir[card->freeNo]; + memcpy(ent->gameName, card->diskID->gameName, sizeof(ent->gameName)); + memcpy(ent->company, card->diskID->company, sizeof(ent->company)); + ent->permission = CARD_ATTR_PUBLIC; + ent->copyTimes = 0; + ent->startBlock = card->startBlock; + + ent->bannerFormat = 0; + ent->iconAddr = 0xffffffff; + ent->iconFormat = 0; + ent->iconSpeed = 0; + ent->commentAddr = 0xffffffff; + + CARDSetIconSpeed(ent, 0, CARD_STAT_SPEED_FAST); + + card->fileInfo->offset = 0; + card->fileInfo->iBlock = ent->startBlock; + + ent->time = (u32)OSTicksToSeconds(OSGetTime()); + result = __CARDUpdateDir(chan, callback); + if (result < 0) + { + goto error; + } + return; + +error: + __CARDPutControlBlock(card, result); + if (callback) + { + callback(chan, result); + } +} + +s32 CARDCreateAsync(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo, + CARDCallback callback) +{ + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + u16 fileNo; + u16 freeNo; + u16* fat; + + if (strlen(fileName) > (u32)CARD_FILENAME_MAX) + { + return CARD_RESULT_NAMETOOLONG; + } + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + { + return result; + } + + if (size <= 0 || (size % card->sectorSize) != 0) + { + return CARD_RESULT_FATAL_ERROR; + } + + freeNo = (u16)-1; + dir = __CARDGetDirBlock(card); + for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) + { + ent = &dir[fileNo]; + if (ent->gameName[0] == 0xff) + { + if (freeNo == (u16)-1) + { + freeNo = fileNo; + } + } + else if (memcmp(ent->gameName, card->diskID->gameName, sizeof(ent->gameName)) == 0 && + memcmp(ent->company, card->diskID->company, sizeof(ent->company)) == 0 && + __CARDCompareFileName(ent, fileName)) + { + return __CARDPutControlBlock(card, CARD_RESULT_EXIST); + } + } + if (freeNo == (u16)-1) + { + return __CARDPutControlBlock(card, CARD_RESULT_NOENT); + } + + fat = __CARDGetFatBlock(card); + if (card->sectorSize * fat[CARD_FAT_FREEBLOCKS] < size) + { + return __CARDPutControlBlock(card, CARD_RESULT_INSSPACE); + } + + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + card->freeNo = freeNo; + ent = &dir[freeNo]; + ent->length = (u16)(size / card->sectorSize); + strncpy(ent->fileName, fileName, CARD_FILENAME_MAX); + + card->fileInfo = fileInfo; + fileInfo->chan = chan; + fileInfo->fileNo = freeNo; + + result = __CARDAllocBlock(chan, size / card->sectorSize, CreateCallbackFat); + if (result < 0) + { + return __CARDPutControlBlock(card, result); + } + return result; +} + +s32 CARDCreate(s32 channel, const char* fileName, u32 size, CARDFileInfo* fileInfo) +{ + s32 result = CARDCreateAsync(channel, fileName, size, fileInfo, __CARDSyncCallback); + if (result < 0) + { + return result; + } + return __CARDSync(channel); +} \ No newline at end of file diff --git a/libs/dolphin/card/CARDDelete.c b/libs/dolphin/card/CARDDelete.c new file mode 100644 index 000000000..2286e205e --- /dev/null +++ b/libs/dolphin/card/CARDDelete.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include + +#include + +static void DeleteCallback(s32 chan, s32 result) +{ + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + callback = card->apiCallback; + card->apiCallback = 0; + + if (result < 0) + { + goto error; + } + + result = __CARDFreeBlock(chan, card->startBlock, callback); + if (result < 0) + { + goto error; + } + return; + +error: + __CARDPutControlBlock(card, result); + if (callback) + { + callback(chan, result); + } +} + +s32 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; + + result = CARDDeleteAsync(chan, fileName, __CARDSyncCallback); + + if (result < 0) + { + return result; + } + return __CARDSync(chan); +} \ No newline at end of file diff --git a/libs/dolphin/card/CARDDir.c b/libs/dolphin/card/CARDDir.c new file mode 100644 index 000000000..1daecf8ef --- /dev/null +++ b/libs/dolphin/card/CARDDir.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include + +#include + +CARDDir* __CARDGetDirBlock(CARDControl* card) { return card->currentDir; } + +static void WriteCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + if (0 <= result) { + CARDDir* dir0 = (CARDDir*)((u8*)card->workArea + 0x2000); + CARDDir* dir1 = (CARDDir*)((u8*)card->workArea + 0x4000); + + if (card->currentDir == dir0) { + card->currentDir = dir1; + memcpy(dir1, dir0, 0x2000); + } else { + card->currentDir = dir0; + memcpy(dir0, dir1, 0x2000); + } + } + +error: + if (card->apiCallback == 0) { + __CARDPutControlBlock(card, result); + } + callback = card->eraseCallback; + if (callback) { + card->eraseCallback = 0; + callback(chan, result); + } +} + +static void EraseCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + CARDDir* dir; + u32 tmp[2]; + u32 addr; + + card = &__CARDBlock[chan]; + if (result < 0) { + goto error; + } + + dir = __CARDGetDirBlock(card); + addr = ((u32)dir - (u32)card->workArea) / 0x2000 * card->sectorSize; + result = __CARDWrite(chan, addr, 0x2000, dir, WriteCallback); + if (result < 0) { + goto error; + } + + return; + +error: + if (card->apiCallback == 0) { + __CARDPutControlBlock(card, result); + } + callback = card->eraseCallback; + if (callback) { + card->eraseCallback = 0; + callback(chan, result); + } +} + +s32 __CARDUpdateDir(s32 chan, CARDCallback callback) { + CARDControl* card; + CARDDirCheck* check; + u32 tmp[2]; + u32 addr; + CARDDir* dir; + + card = &__CARDBlock[chan]; + if (!card->attached) { + return CARD_RESULT_NOCARD; + } + + dir = __CARDGetDirBlock(card); + check = __CARDGetDirCheck(dir); + ++check->checkCode; + __CARDCheckSum(dir, 0x2000 - sizeof(u32), &check->checkSum, &check->checkSumInv); + DCStoreRange(dir, 0x2000); + + card->eraseCallback = callback; + addr = ((u32)dir - (u32)card->workArea) / 0x2000 * card->sectorSize; + return __CARDEraseSector(chan, addr, EraseCallback); +} diff --git a/libs/dolphin/card/CARDFormat.c b/libs/dolphin/card/CARDFormat.c new file mode 100644 index 000000000..a29eb05bb --- /dev/null +++ b/libs/dolphin/card/CARDFormat.c @@ -0,0 +1,138 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +static void FormatCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + if (result < 0) { + goto error; + } + + ++card->formatStep; + if (card->formatStep < CARD_NUM_SYSTEM_BLOCK) { + result = __CARDEraseSector(chan, (u32)card->sectorSize * card->formatStep, FormatCallback); + if (0 <= result) { + return; + } + } else if (card->formatStep < 2 * CARD_NUM_SYSTEM_BLOCK) { + int step = card->formatStep - CARD_NUM_SYSTEM_BLOCK; + result = __CARDWrite(chan, (u32)card->sectorSize * step, CARD_SYSTEM_BLOCK_SIZE, + (u8*)card->workArea + (CARD_SYSTEM_BLOCK_SIZE * step), FormatCallback); + if (result >= 0) { + return; + } + } else { + card->currentDir = (CARDDir*)((u8*)card->workArea + (1 + 0) * CARD_SYSTEM_BLOCK_SIZE); + memcpy(card->currentDir, (u8*)card->workArea + (1 + 1) * CARD_SYSTEM_BLOCK_SIZE, + CARD_SYSTEM_BLOCK_SIZE); + card->currentFat = (u16*)((u8*)card->workArea + (3 + 0) * CARD_SYSTEM_BLOCK_SIZE); + memcpy(card->currentFat, (u8*)card->workArea + (3 + 1) * CARD_SYSTEM_BLOCK_SIZE, + CARD_SYSTEM_BLOCK_SIZE); + } + +error: + callback = card->apiCallback; + card->apiCallback = 0; + __CARDPutControlBlock(card, result); + callback(chan, result); +} + +s32 __CARDFormatRegionAsync(s32 chan, u16 encode, CARDCallback callback) { + CARDControl* card; + CARDID* id; + CARDDir* dir; + u16* fat; + s16 i; + s32 result; + OSSram* sram; + OSSramEx* sramEx; + u16 viDTVStatus; + OSTime time; + OSTime rand; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + id = (CARDID*)card->workArea; + memset(id, 0xff, CARD_SYSTEM_BLOCK_SIZE); + viDTVStatus = __VIRegs[55]; + + id->encode = encode; + + sram = __OSLockSram(); + *(u32*)&id->serial[20] = sram->counterBias; + *(u32*)&id->serial[24] = sram->language; + __OSUnlockSram(FALSE); + + rand = time = OSGetTime(); + + sramEx = __OSLockSramEx(); + for (i = 0; i < 12; i++) { + rand = (rand * 1103515245 + 12345) >> 16; + id->serial[i] = (u8)(sramEx->flashID[chan][i] + rand); + rand = ((rand * 1103515245 + 12345) >> 16) & 0x7FFF; + } + __OSUnlockSramEx(FALSE); + + *(u32*)&id->serial[28] = viDTVStatus; + *(OSTime*)&id->serial[12] = time; + + id->deviceID = 0; + id->size = card->size; + __CARDCheckSum(id, sizeof(CARDID) - sizeof(u32), &id->checkSum, &id->checkSumInv); + + for (i = 0; i < 2; i++) { + CARDDirCheck* check; + + dir = (CARDDir*)((u8*)card->workArea + (1 + i) * CARD_SYSTEM_BLOCK_SIZE); + memset(dir, 0xff, CARD_SYSTEM_BLOCK_SIZE); + check = __CARDGetDirCheck(dir); + check->checkCode = i; + __CARDCheckSum(dir, CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &check->checkSum, + &check->checkSumInv); + } + for (i = 0; i < 2; i++) { + fat = (u16*)((u8*)card->workArea + (3 + i) * CARD_SYSTEM_BLOCK_SIZE); + memset(fat, 0x00, CARD_SYSTEM_BLOCK_SIZE); + fat[CARD_FAT_CHECKCODE] = (u16)i; + fat[CARD_FAT_FREEBLOCKS] = (u16)(card->cBlock - CARD_NUM_SYSTEM_BLOCK); + fat[CARD_FAT_LASTSLOT] = CARD_NUM_SYSTEM_BLOCK - 1; + __CARDCheckSum(&fat[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), + &fat[CARD_FAT_CHECKSUM], &fat[CARD_FAT_CHECKSUMINV]); + } + + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + DCStoreRange(card->workArea, CARD_WORKAREA_SIZE); + + card->formatStep = 0; + result = __CARDEraseSector(chan, (u32)card->sectorSize * card->formatStep, FormatCallback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + return result; +} + +s32 CARDFormatAsync(s32 chan, CARDCallback callback) { + return __CARDFormatRegionAsync(chan, __CARDGetFontEncode(), callback); +} + +s32 CARDFormat(s32 channel) +{ + s32 result = __CARDFormatRegionAsync(channel, __CARDGetFontEncode(), __CARDSyncCallback); + if (result < 0) + { + return result; + } + return __CARDSync(channel); +} \ No newline at end of file diff --git a/libs/dolphin/card/CARDMount.c b/libs/dolphin/card/CARDMount.c new file mode 100644 index 000000000..ee5dbb1a4 --- /dev/null +++ b/libs/dolphin/card/CARDMount.c @@ -0,0 +1,366 @@ +#include +#include +#include +#include + +#include +#include + +u8 GameChoice : (OS_BASE_CACHED | 0x000030E3); + +static u32 SectorSizeTable[8] = { + 8 * 1024, 16 * 1024, 32 * 1024, 64 * 1024, 128 * 1024, 256 * 1024, 0, 0, +}; + +static u32 LatencyTable[8] = { + 4, 8, 16, 32, 64, 128, 256, 512, +}; + +void __CARDMountCallback(s32 chan, s32 result); +static void DoUnmount(s32 chan, s32 result); + +static BOOL IsCard(u32 id) { + u32 size; + s32 sectorSize; + if (id & (0xFFFF0000) && (id != 0x80000004 || __CARDVendorID == 0xFFFF)) { + return FALSE; + } + + if ((id & 3) != 0) { + return FALSE; + } + + size = id & 0xfc; + switch (size) { + case 4: + case 8: + case 16: + case 32: + case 64: + case 128: + break; + default: + return FALSE; + break; + } + + sectorSize = SectorSizeTable[(id & 0x00003800) >> 11]; + if (sectorSize == 0) { + return FALSE; + } + + if ((size * 1024 * 1024 / 8) / sectorSize < 8) { + return FALSE; + } + + return TRUE; +} + +s32 CARDProbeEx(s32 chan, s32* memSize, s32* sectorSize) { + u32 id; + CARDControl* card; + BOOL enabled; + s32 result; + int probe; + + if (chan < 0 || 2 <= chan) { + return CARD_RESULT_FATAL_ERROR; + } + + if (GameChoice & 0x80) { + return CARD_RESULT_NOCARD; + } + + card = &__CARDBlock[chan]; + enabled = OSDisableInterrupts(); + + probe = EXIProbeEx(chan); + if (probe == -1) { + result = CARD_RESULT_NOCARD; + } else if (probe == 0) { + result = CARD_RESULT_BUSY; + } else if (card->attached) { + if (card->mountStep < 1) { + result = CARD_RESULT_BUSY; + } else { + if (memSize) { + *memSize = card->size; + } + if (sectorSize) { + *sectorSize = card->sectorSize; + } + result = CARD_RESULT_READY; + } + } else if ((EXIGetState(chan) & 8)) { + result = CARD_RESULT_WRONGDEVICE; + } else if (!EXIGetID(chan, 0, &id)) { + result = CARD_RESULT_BUSY; + } else if (IsCard(id)) { + if (memSize) { + *memSize = (s32)(id & 0xfc); + } + if (sectorSize) { + *sectorSize = SectorSizeTable[(id & 0x00003800) >> 11]; + } + result = CARD_RESULT_READY; + } else { + result = CARD_RESULT_WRONGDEVICE; + } + + OSRestoreInterrupts(enabled); + return result; +} + +static s32 DoMount(s32 chan) { + CARDControl* card; + u32 id; + u8 status; + s32 result; + OSSramEx* sram; + int i; + u8 checkSum; + int step; + + card = &__CARDBlock[chan]; + + if (card->mountStep == 0) { + if (EXIGetID(chan, 0, &id) == 0) { + result = CARD_RESULT_NOCARD; + } else if (IsCard(id)) { + result = CARD_RESULT_READY; + } else { + result = CARD_RESULT_WRONGDEVICE; + } + if (result < 0) { + goto error; + } + + card->cid = id; + + card->size = (u16)(id & 0xFC); + card->sectorSize = SectorSizeTable[(id & 0x00003800) >> 11]; + card->cBlock = (u16)((card->size * 1024 * 1024 / 8) / card->sectorSize); + card->latency = LatencyTable[(id & 0x00000700) >> 8]; + + result = __CARDClearStatus(chan); + if (result < 0) { + goto error; + } + result = __CARDReadStatus(chan, &status); + if (result < 0) { + goto error; + } + + if (!EXIProbe(chan)) { + result = CARD_RESULT_NOCARD; + goto error; + } + + if (!(status & 0x40)) { + result = __CARDUnlock(chan, card->id); + if (result < 0) { + goto error; + } + + checkSum = 0; + sram = __OSLockSramEx(); + for (i = 0; i < 12; i++) { + sram->flashID[chan][i] = card->id[i]; + checkSum += card->id[i]; + } + sram->flashIDCheckSum[chan] = (u8)~checkSum; + __OSUnlockSramEx(TRUE); + + return result; + } else { + card->mountStep = 1; + + checkSum = 0; + sram = __OSLockSramEx(); + for (i = 0; i < 12; i++) { + checkSum += sram->flashID[chan][i]; + } + __OSUnlockSramEx(FALSE); + if (sram->flashIDCheckSum[chan] != (u8)~checkSum) { + result = CARD_RESULT_IOERROR; + goto error; + } + } + } + + if (card->mountStep == 1) { + if (card->cid == 0x80000004) { + u16 vendorID; + + sram = __OSLockSramEx(); + vendorID = *(u16*)sram->flashID[chan]; + __OSUnlockSramEx(FALSE); + + if (__CARDVendorID == 0xffff || vendorID != __CARDVendorID) { + result = CARD_RESULT_WRONGDEVICE; + goto error; + } + } + + card->mountStep = 2; + + result = __CARDEnableInterrupt(chan, TRUE); + if (result < 0) { + goto error; + } + + EXISetExiCallback(chan, __CARDExiHandler); + EXIUnlock(chan); + DCInvalidateRange(card->workArea, CARD_WORKAREA_SIZE); + } + + step = card->mountStep - 2; + result = __CARDRead(chan, (u32)card->sectorSize * step, CARD_SYSTEM_BLOCK_SIZE, + (u8*)card->workArea + (CARD_SYSTEM_BLOCK_SIZE * step), __CARDMountCallback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + return result; + +error: + EXIUnlock(chan); + DoUnmount(chan, result); + return result; +} + +void __CARDMountCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + + switch (result) { + case CARD_RESULT_READY: + if (++card->mountStep < CARD_MAX_MOUNT_STEP) { + result = DoMount(chan); + if (0 <= result) { + return; + } + } else { + result = __CARDVerify(card); + } + break; + case CARD_RESULT_UNLOCKED: + card->unlockCallback = __CARDMountCallback; + if (!EXILock(chan, 0, __CARDUnlockedHandler)) { + return; + } + card->unlockCallback = 0; + + result = DoMount(chan); + if (0 <= result) { + return; + } + break; + case CARD_RESULT_IOERROR: + case CARD_RESULT_NOCARD: + DoUnmount(chan, result); + break; + } + + callback = card->apiCallback; + card->apiCallback = 0; + __CARDPutControlBlock(card, result); + callback(chan, result); +} + +s32 CARDMountAsync(s32 chan, void *workArea, CARDCallback detachCallback, + CARDCallback attachCallback) +{ + CARDControl* card; + BOOL enabled; + + if (chan < 0 || 2 <= chan) { + return CARD_RESULT_FATAL_ERROR; + } + if (GameChoice & 0x80) { + return CARD_RESULT_NOCARD; + } + card = &__CARDBlock[chan]; + + enabled = OSDisableInterrupts(); + if (card->result == CARD_RESULT_BUSY) { + OSRestoreInterrupts(enabled); + return CARD_RESULT_BUSY; + } + + if (!card->attached && (EXIGetState(chan) & 0x08)) { + OSRestoreInterrupts(enabled); + return CARD_RESULT_WRONGDEVICE; + } + + card->result = CARD_RESULT_BUSY; + card->workArea = workArea; + card->extCallback = detachCallback; + card->apiCallback = attachCallback ? attachCallback : __CARDDefaultApiCallback; + card->exiCallback = 0; + + if (!card->attached && !EXIAttach(chan, __CARDExtHandler)) { + card->result = CARD_RESULT_NOCARD; + OSRestoreInterrupts(enabled); + return CARD_RESULT_NOCARD; + } + + card->mountStep = 0; + card->attached = TRUE; + EXISetExiCallback(chan, 0); + OSCancelAlarm(&card->alarm); + + card->currentDir = 0; + card->currentFat = 0; + + OSRestoreInterrupts(enabled); + + card->unlockCallback = __CARDMountCallback; + if (!EXILock(chan, 0, __CARDUnlockedHandler)) { + return CARD_RESULT_READY; + } + card->unlockCallback = 0; + + return DoMount(chan); +} + +s32 CARDMount(s32 channel, void *workArea, CARDCallback detachCallback) +{ + s32 result = CARDMountAsync(channel, workArea, detachCallback, __CARDSyncCallback); + if (result < 0) + { + return result; + } + + return __CARDSync(channel); +} + +static void DoUnmount(s32 chan, s32 result) { + CARDControl* card; + BOOL enabled; + + card = &__CARDBlock[chan]; + enabled = OSDisableInterrupts(); + if (card->attached) { + EXISetExiCallback(chan, 0); + EXIDetach(chan); + OSCancelAlarm(&card->alarm); + card->attached = FALSE; + card->result = result; + card->mountStep = 0; + } + OSRestoreInterrupts(enabled); +} + +s32 CARDUnmount(s32 chan) { + CARDControl* card; + s32 result; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + DoUnmount(chan, CARD_RESULT_NOCARD); + return CARD_RESULT_READY; +} diff --git a/libs/dolphin/card/CARDNet.c b/libs/dolphin/card/CARDNet.c new file mode 100644 index 000000000..17d61f429 --- /dev/null +++ b/libs/dolphin/card/CARDNet.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include + +#include + +u16 __CARDVendorID = 0xFFFF; +u8 __CARDPermMask = 28; + +// 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); +} diff --git a/libs/dolphin/card/CARDOpen.c b/libs/dolphin/card/CARDOpen.c new file mode 100644 index 000000000..fc305321e --- /dev/null +++ b/libs/dolphin/card/CARDOpen.c @@ -0,0 +1,209 @@ +#include +#include +#include +#include + +#include + +BOOL __CARDCompareFileName(CARDDir *ent, const char *fileName) +{ + char *entName; + char c1; + char c2; + int n; + + entName = (char *)ent->fileName; + n = CARD_FILENAME_MAX; + while (0 <= --n) + { + if ((c1 = *entName++) != (c2 = *fileName++)) + { + return FALSE; + } + else if (c2 == '\0') + { + return TRUE; + } + } + + if (*fileName == '\0') + { + return TRUE; + } + + return FALSE; +} + +s32 __CARDAccess(CARDControl *card, CARDDir *ent) +{ + const DVDDiskID *diskID = card->diskID; + if (ent->gameName[0] == 0xFF) + { + return CARD_RESULT_NOFILE; + } + + if (diskID == &__CARDDiskNone || (memcmp(ent->gameName, diskID->gameName, 4) == 0 && + memcmp(ent->company, diskID->company, 2) == 0)) + { + return CARD_RESULT_READY; + } + + return CARD_RESULT_NOPERM; +} + +s32 __CARDIsWritable(CARDControl *card, CARDDir *entry) +{ + const DVDDiskID *diskID = card->diskID; + s32 result; + u8 perm; + + result = __CARDAccess(card, entry); + if (result == CARD_RESULT_NOPERM) + { + perm = (u8)(entry->permission & __CARDPermMask); + + if ((perm & 0x20) && (memcmp(entry->gameName, __CARDDiskNone.gameName, 4) == 0 && memcmp(entry->company, __CARDDiskNone.company, 2) == 0)) + { + return CARD_RESULT_READY; + } + + if ((perm & 0x40) && (memcmp(entry->gameName, __CARDDiskNone.gameName, 4) == 0 && memcmp(entry->company, diskID->company, 2) == 0)) + { + return CARD_RESULT_READY; + } + } + return result; +} + +s32 __CARDIsReadable(CARDControl* card, CARDDir* entry) +{ + s32 result = __CARDIsWritable(card, entry); + + if (result == CARD_RESULT_NOPERM && (entry->permission & 0x4)) { + return CARD_RESULT_READY; + } + + return result; +} + +s32 __CARDGetFileNo(CARDControl *card, const char *fileName, s32 *pfileNo) +{ + CARDDir *dir; + CARDDir *ent; + s32 fileNo; + s32 result; + + if (!card->attached) + { + return CARD_RESULT_NOCARD; + } + + dir = __CARDGetDirBlock(card); + for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) + { + ent = &dir[fileNo]; + result = __CARDAccess(card, ent); + if (result < 0) + { + continue; + } + if (__CARDCompareFileName(ent, fileName)) + { + *pfileNo = fileNo; + return CARD_RESULT_READY; + } + } + + return CARD_RESULT_NOFILE; +} + +s32 CARDFastOpen(s32 chan, s32 fileno, CARDFileInfo *fileinfo) +{ + CARDControl *card; + CARDDir *dir; + CARDDir *ent; + s32 result; + + if (fileno < 0 || fileno >= 127) + { + return CARD_RESULT_FATAL_ERROR; + } + fileinfo->chan = -1; + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + { + return result; + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileno]; + result = __CARDIsReadable(card, ent); + + if (0 <= result) + { + 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 CARDOpen(s32 chan, const char *fileName, CARDFileInfo *fileInfo) +{ + CARDControl *card; + CARDDir *dir; + CARDDir *ent; + s32 result; + s32 fileNo; + + fileInfo->chan = -1; + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + { + return result; + } + result = __CARDGetFileNo(card, fileName, &fileNo); + if (0 <= result) + { + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + if (!CARDIsValidBlockNo(card, ent->startBlock)) + { + result = CARD_RESULT_BROKEN; + } + else + { + fileInfo->chan = chan; + fileInfo->fileNo = fileNo; + fileInfo->offset = 0; + fileInfo->iBlock = ent->startBlock; + } + } + return __CARDPutControlBlock(card, result); +} + +s32 CARDClose(CARDFileInfo *fileInfo) +{ + CARDControl *card; + s32 result; + + result = __CARDGetControlBlock(fileInfo->chan, &card); + if (result < 0) + { + return result; + } + + fileInfo->chan = -1; + return __CARDPutControlBlock(card, CARD_RESULT_READY); +} + +BOOL __CARDIsOpened(CARDControl *card, s32 fileNo) { return FALSE; } diff --git a/libs/dolphin/card/CARDRdwr.c b/libs/dolphin/card/CARDRdwr.c new file mode 100644 index 000000000..1bf19a08b --- /dev/null +++ b/libs/dolphin/card/CARDRdwr.c @@ -0,0 +1,125 @@ +#include +#include +#include +#include + +#include + +static void BlockReadCallback(s32 chan, s32 result) +{ + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + if (result < 0) + { + goto error; + } + + card->xferred += CARD_SEG_SIZE; + + card->addr += CARD_SEG_SIZE; + (u8*)card->buffer += CARD_SEG_SIZE; + if (--card->repeat <= 0) + { + goto error; + } + + result = __CARDReadSegment(chan, BlockReadCallback); + if (result < 0) + { + goto error; + } + return; + +error: + if (card->apiCallback == 0) + { + __CARDPutControlBlock(card, result); + } + callback = card->xferCallback; + if (callback) + { + card->xferCallback = 0; + callback(chan, result); + } +} + +s32 __CARDRead(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback) +{ + CARDControl* card; + card = &__CARDBlock[chan]; + if (!card->attached) + { + return CARD_RESULT_NOCARD; + } + + card->xferCallback = callback; + card->repeat = (int)(length / CARD_SEG_SIZE); + card->addr = addr; + card->buffer = dst; + + return __CARDReadSegment(chan, BlockReadCallback); +} + +static void BlockWriteCallback(s32 chan, s32 result) +{ + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + if (result < 0) + { + goto error; + } + + card->xferred += CARD_PAGE_SIZE; + + card->addr += CARD_PAGE_SIZE; + (u8*)card->buffer += CARD_PAGE_SIZE; + if (--card->repeat <= 0) + { + goto error; + } + + result = __CARDWritePage(chan, BlockWriteCallback); + if (result < 0) + { + goto error; + } + return; + +error: + if (card->apiCallback == 0) + { + __CARDPutControlBlock(card, result); + } + callback = card->xferCallback; + if (callback) + { + card->xferCallback = 0; + callback(chan, result); + } +} + +s32 __CARDWrite(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback) +{ + CARDControl* card; + card = &__CARDBlock[chan]; + if (!card->attached) + { + return CARD_RESULT_NOCARD; + } + + card->xferCallback = callback; + card->repeat = (int)(length / CARD_PAGE_SIZE); + card->addr = addr; + card->buffer = dst; + + return __CARDWritePage(chan, BlockWriteCallback); +} + +s32 CARDGetXferredBytes(s32 chan) +{ + return __CARDBlock[chan].xferred; +} diff --git a/libs/dolphin/card/CARDRead.c b/libs/dolphin/card/CARDRead.c new file mode 100644 index 000000000..4ec0e21d8 --- /dev/null +++ b/libs/dolphin/card/CARDRead.c @@ -0,0 +1,151 @@ +#include +#include +#include +#include + +#include + +s32 __CARDSeek(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDControl** pcard) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + u16* fat; + + result = __CARDGetControlBlock(fileInfo->chan, &card); + if (result < 0) { + return result; + } + + if (!CARDIsValidBlockNo(card, fileInfo->iBlock) || + card->cBlock * card->sectorSize <= fileInfo->offset) { + return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR); + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileInfo->fileNo]; + if (ent->length * card->sectorSize <= offset || + ent->length * card->sectorSize < offset + length) { + return __CARDPutControlBlock(card, CARD_RESULT_LIMIT); + } + + card->fileInfo = fileInfo; + fileInfo->length = length; + if (offset < fileInfo->offset) { + fileInfo->offset = 0; + fileInfo->iBlock = ent->startBlock; + if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + } + fat = __CARDGetFatBlock(card); + while (fileInfo->offset < TRUNC(offset, card->sectorSize)) { + fileInfo->offset += card->sectorSize; + fileInfo->iBlock = fat[fileInfo->iBlock]; + if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + } + + fileInfo->offset = offset; + + *pcard = card; + return CARD_RESULT_READY; +} + +static void ReadCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + u16* fat; + CARDFileInfo* fileInfo; + s32 length; + + card = &__CARDBlock[chan]; + if (result < 0) { + goto error; + } + + fileInfo = card->fileInfo; + if (fileInfo->length < 0) { + result = CARD_RESULT_CANCELED; + goto error; + } + + length = (s32)TRUNC(fileInfo->offset + card->sectorSize, card->sectorSize) - fileInfo->offset; + fileInfo->length -= length; + if (fileInfo->length <= 0) { + goto error; + } + + fat = __CARDGetFatBlock(card); + fileInfo->offset += length; + fileInfo->iBlock = fat[fileInfo->iBlock]; + if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) { + result = CARD_RESULT_BROKEN; + goto error; + } + + result = __CARDRead(chan, card->sectorSize * (u32)fileInfo->iBlock, + (fileInfo->length < card->sectorSize) ? fileInfo->length : card->sectorSize, + card->buffer, ReadCallback); + if (result < 0) { + goto error; + } + + return; + +error: + callback = card->apiCallback; + card->apiCallback = 0; + __CARDPutControlBlock(card, result); + callback(chan, result); +} + +s32 CARDReadAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, + CARDCallback callback) { + CARDControl* card; + s32 result; + CARDDir* dir; + CARDDir* ent; + + if (OFFSET(offset, CARD_SEG_SIZE) != 0 || OFFSET(length, CARD_SEG_SIZE) != 0) { + return CARD_RESULT_FATAL_ERROR; + } + result = __CARDSeek(fileInfo, length, offset, &card); + if (result < 0) { + return result; + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileInfo->fileNo]; + result = __CARDIsReadable(card, ent); + + if (result < 0) + { + return __CARDPutControlBlock(card, result); + } + + DCInvalidateRange(buf, (u32)length); + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + + offset = (s32)OFFSET(fileInfo->offset, card->sectorSize); + length = (length < card->sectorSize - offset) ? length : card->sectorSize - offset; + result = __CARDRead(fileInfo->chan, card->sectorSize * (u32)fileInfo->iBlock + offset, length, + buf, ReadCallback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + return result; +} + +s32 CARDRead(CARDFileInfo *fileInfo, void *buffer, s32 length, s32 offset) +{ + s32 result = CARDReadAsync(fileInfo, buffer, length, offset, __CARDSyncCallback); + + if (result < 0) + { + return result; + } + + return __CARDSync(fileInfo->chan); +} \ No newline at end of file diff --git a/libs/dolphin/card/CARDRename.c b/libs/dolphin/card/CARDRename.c new file mode 100644 index 000000000..65205f062 --- /dev/null +++ b/libs/dolphin/card/CARDRename.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include + +#include + +s32 CARDRenameAsync(s32 chan, const char* old, const char* new, CARDCallback callback) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + int fileNo; + int newNo; + int oldNo; + + if (*old == 0xff || *new == 0xff || *old == 0x00 || *new == 0x00) { + return CARD_RESULT_FATAL_ERROR; + } + if (CARD_FILENAME_MAX < (u32)strlen(old) || CARD_FILENAME_MAX < (u32)strlen(new)) { + return CARD_RESULT_NAMETOOLONG; + } + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + newNo = oldNo = -1; + dir = __CARDGetDirBlock(card); + for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) { + ent = &dir[fileNo]; + if (ent->gameName[0] == 0xff) { + continue; + } + + if (memcmp(ent->gameName, card->diskID->gameName, sizeof(ent->gameName)) != 0 || + memcmp(ent->company, card->diskID->company, sizeof(ent->company)) != 0) { + continue; + } + + if (__CARDCompareFileName(ent, old)) { + oldNo = fileNo; + } + if (__CARDCompareFileName(ent, new)) { + newNo = fileNo; + } + } + + if (oldNo == -1) { + return __CARDPutControlBlock(card, CARD_RESULT_NOFILE); + } + if (newNo != -1) { + return __CARDPutControlBlock(card, CARD_RESULT_EXIST); + } + + ent = &dir[oldNo]; + result = __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; + + result = CARDRenameAsync(chan, old, new, __CARDSyncCallback); + + if (result < 0) + { + return result; + } + return __CARDSync(chan); +} \ No newline at end of file diff --git a/libs/dolphin/card/CARDStat.c b/libs/dolphin/card/CARDStat.c new file mode 100644 index 000000000..cca9c3d3e --- /dev/null +++ b/libs/dolphin/card/CARDStat.c @@ -0,0 +1,152 @@ +#include +#include +#include +#include + +#include + +static void UpdateIconOffsets(CARDDir* ent, CARDStat* stat) { + u32 offset; + BOOL iconTlut; + int i; + + offset = ent->iconAddr; + if (offset == 0xffffffff) { + stat->bannerFormat = 0; + stat->iconFormat = 0; + stat->iconSpeed = 0; + offset = 0; + } + + iconTlut = FALSE; + switch (CARDGetBannerFormat(ent)) { + case CARD_STAT_BANNER_C8: + stat->offsetBanner = offset; + offset += CARD_BANNER_WIDTH * CARD_BANNER_HEIGHT; + stat->offsetBannerTlut = offset; + offset += 2 * 256; + break; + case CARD_STAT_BANNER_RGB5A3: + stat->offsetBanner = offset; + offset += 2 * CARD_BANNER_WIDTH * CARD_BANNER_HEIGHT; + stat->offsetBannerTlut = 0xffffffff; + break; + default: + stat->offsetBanner = 0xffffffff; + stat->offsetBannerTlut = 0xffffffff; + break; + } + for (i = 0; i < CARD_ICON_MAX; ++i) { + switch (CARDGetIconFormat(ent, i)) { + case CARD_STAT_ICON_C8: + stat->offsetIcon[i] = offset; + offset += CARD_ICON_WIDTH * CARD_ICON_HEIGHT; + iconTlut = TRUE; + break; + case CARD_STAT_ICON_RGB5A3: + stat->offsetIcon[i] = offset; + offset += 2 * CARD_ICON_WIDTH * CARD_ICON_HEIGHT; + break; + default: + stat->offsetIcon[i] = 0xffffffff; + break; + } + } + if (iconTlut) { + stat->offsetIconTlut = offset; + offset += 2 * 256; + } else { + stat->offsetIconTlut = 0xffffffff; + } + stat->offsetData = offset; +} + +s32 CARDGetStatus(s32 chan, s32 fileNo, CARDStat* stat) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + + if (fileNo < 0 || CARD_MAX_FILE <= fileNo) { + return CARD_RESULT_FATAL_ERROR; + } + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + result = __CARDIsReadable(card, ent); + + if (result >= 0) { + memcpy(stat->gameName, ent->gameName, sizeof(stat->gameName)); + memcpy(stat->company, ent->company, sizeof(stat->company)); + stat->length = (u32)ent->length * card->sectorSize; + memcpy(stat->fileName, ent->fileName, CARD_FILENAME_MAX); + stat->time = ent->time; + + stat->bannerFormat = ent->bannerFormat; + stat->iconAddr = ent->iconAddr; + stat->iconFormat = ent->iconFormat; + stat->iconSpeed = ent->iconSpeed; + stat->commentAddr = ent->commentAddr; + + UpdateIconOffsets(ent, stat); + } + return __CARDPutControlBlock(card, result); +} + +s32 CARDSetStatusAsync(s32 chan, s32 fileNo, CARDStat* stat, CARDCallback callback) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + + if (fileNo < 0 || CARD_MAX_FILE <= fileNo || + (stat->iconAddr != 0xffffffff && CARD_READ_SIZE <= stat->iconAddr) || + (stat->commentAddr != 0xffffffff && + CARD_SYSTEM_BLOCK_SIZE - CARD_COMMENT_SIZE < stat->commentAddr % CARD_SYSTEM_BLOCK_SIZE)) { + return CARD_RESULT_FATAL_ERROR; + } + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + result = __CARDIsWritable(card, ent); + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + + ent->bannerFormat = stat->bannerFormat; + ent->iconAddr = stat->iconAddr; + ent->iconFormat = stat->iconFormat; + ent->iconSpeed = stat->iconSpeed; + ent->commentAddr = stat->commentAddr; + UpdateIconOffsets(ent, stat); + + if (ent->iconAddr == 0xffffffff) { + CARDSetIconSpeed(ent, 0, CARD_STAT_SPEED_FAST); + } + + ent->time = (u32)OSTicksToSeconds(OSGetTime()); + result = __CARDUpdateDir(chan, callback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + return result; +} + +s32 CARDSetStatus(s32 channel, s32 fileNo, CARDStat *state) +{ + s32 result = CARDSetStatusAsync(channel, fileNo, state, __CARDSyncCallback); + if (result < 0) + { + return result; + } + + return __CARDSync(channel); +} diff --git a/libs/dolphin/card/CARDStatEx.c b/libs/dolphin/card/CARDStatEx.c new file mode 100644 index 000000000..681ab52e3 --- /dev/null +++ b/libs/dolphin/card/CARDStatEx.c @@ -0,0 +1,125 @@ +#include +#include +#include + +s32 __CARDGetStatusEx(s32 chan, s32 fileNo, CARDDir* dirent) +{ + 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; + + 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; +} diff --git a/libs/dolphin/card/CARDUnlock.c b/libs/dolphin/card/CARDUnlock.c new file mode 100644 index 000000000..a2fbb50c7 --- /dev/null +++ b/libs/dolphin/card/CARDUnlock.c @@ -0,0 +1,419 @@ +#include + +static void InitCallback(void* task); +static void DoneCallback(void* task); + +static u8 CardData[] ALIGN(32) = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x02, 0xFF, 0x00, 0x21, + 0x13, 0x06, 0x12, 0x03, 0x12, 0x04, 0x13, 0x05, 0x00, 0x92, 0x00, 0xFF, 0x00, 0x88, 0xFF, 0xFF, + 0x00, 0x89, 0xFF, 0xFF, 0x00, 0x8A, 0xFF, 0xFF, 0x00, 0x8B, 0xFF, 0xFF, 0x8F, 0x00, 0x02, 0xBF, + 0x00, 0x88, 0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x00, 0x16, 0xFB, 0x00, 0x01, 0x02, 0xBF, + 0x00, 0x8E, 0x25, 0xFF, 0x03, 0x80, 0xFF, 0x00, 0x02, 0x94, 0x00, 0x27, 0x02, 0xBF, 0x00, 0x8E, + 0x1F, 0xDF, 0x24, 0xFF, 0x02, 0x40, 0x0F, 0xFF, 0x00, 0x98, 0x04, 0x00, 0x00, 0x9A, 0x00, 0x10, + 0x00, 0x99, 0x00, 0x00, 0x8E, 0x00, 0x02, 0xBF, 0x00, 0x94, 0x02, 0xBF, 0x86, 0x44, 0x02, 0xBF, + 0x00, 0x88, 0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x03, 0x16, 0xFB, 0x00, 0x01, 0x8F, 0x00, + 0x02, 0xBF, 0x00, 0x8E, 0x03, 0x80, 0xCD, 0xD1, 0x02, 0x94, 0x00, 0x48, 0x27, 0xFF, 0x03, 0x80, + 0x00, 0x01, 0x02, 0x95, 0x00, 0x5A, 0x03, 0x80, 0x00, 0x02, 0x02, 0x95, 0x80, 0x00, 0x02, 0x9F, + 0x00, 0x48, 0x00, 0x21, 0x8E, 0x00, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, + 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC5, 0xFF, 0xFF, + 0x03, 0x40, 0x0F, 0xFF, 0x1C, 0x9F, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC7, 0xFF, 0xFF, 0x02, 0xBF, + 0x00, 0x8E, 0x00, 0xC6, 0xFF, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC0, 0xFF, 0xFF, 0x02, 0xBF, + 0x00, 0x8E, 0x20, 0xFF, 0x03, 0x40, 0x0F, 0xFF, 0x1F, 0x5F, 0x02, 0xBF, 0x00, 0x8E, 0x21, 0xFF, + 0x02, 0xBF, 0x00, 0x8E, 0x23, 0xFF, 0x12, 0x05, 0x12, 0x06, 0x02, 0x9F, 0x80, 0xB5, 0x00, 0x21, + 0x27, 0xFC, 0x03, 0xC0, 0x80, 0x00, 0x02, 0x9D, 0x00, 0x88, 0x02, 0xDF, 0x27, 0xFE, 0x03, 0xC0, + 0x80, 0x00, 0x02, 0x9C, 0x00, 0x8E, 0x02, 0xDF, 0x2E, 0xCE, 0x2C, 0xCF, 0x00, 0xF8, 0xFF, 0xCD, + 0x00, 0xF9, 0xFF, 0xC9, 0x00, 0xFA, 0xFF, 0xCB, 0x26, 0xC9, 0x02, 0xC0, 0x00, 0x04, 0x02, 0x9D, + 0x00, 0x9C, 0x02, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +typedef struct DecodeParameters +{ + u8* inputAddr; + u32 inputLength; + u32 aramAddr; + u8* outputAddr; +} DecodeParameters; + +static unsigned long int next = 1; + +static int CARDRand(void) +{ + next = next * 1103515245 + 12345; + return (int)((unsigned int)(next / 65536) % 32768); +} + +static u32 GetInitVal(void) +{ + u32 tmp = 0; + u32 tick; + + tick = OSGetTick(); + next = tmp; + tmp = 0x7fec8000; + tmp |= CARDRand(); + tmp &= 0xfffff000; + return tmp; +} + +static u32 exnor(u32 data, u32 lshift) +{ + u32 wk; + u32 w; + u32 i; + + w = data; + for (i = 0; i < lshift; i++) + { + // 1bit Left Shift + wk = ~(w ^ (w << 7) ^ (w << 15) ^ (w << 23)); + w = (w << 1) | ((wk >> 30) & 0x00000002); + // printf("i=%d, w=%8x\n", i, w); + } + return w; +} + +static u32 bitrev(u32 data) +{ + u32 wk; + u32 i; + u32 k = 0; + u32 j = 1; + + wk = 0; + for (i = 0; i < 32; i++) + { + if (i > 15) + { + if (i == 31) + { + wk |= (((data & (0x01 << 31)) >> 31) & 0x01); + } + else + { + wk |= ((data & (0x01 << i)) >> j); + j += 2; + } + } + else + { + wk |= ((data & (0x01 << i)) << (31 - i - k)); + k++; + } + } + return wk; +} + +#define SEC_AD1(x) ((u8)(((x) >> 29) & 0x03)) +#define SEC_AD2(x) ((u8)(((x) >> 21) & 0xff)) +#define SEC_AD3(x) ((u8)(((x) >> 19) & 0x03)) +#define SEC_BA(x) ((u8)(((x) >> 12) & 0x7f)) + +static s32 ReadArrayUnlock(s32 chan, u32 data, void* rbuf, s32 rlen, s32 mode) +{ + CARDControl* card; + BOOL err; + u8 cmd[5]; + + card = &__CARDBlock[chan]; + if (!EXISelect(chan, 0, 4)) + { + return CARD_RESULT_NOCARD; + } + + data &= 0xfffff000; + memset(cmd, 0, 5); + cmd[0] = 0x52; + if (mode == 0) + { + cmd[1] = SEC_AD1(data); + cmd[2] = SEC_AD2(data); + cmd[3] = SEC_AD3(data); + cmd[4] = SEC_BA(data); + } + else + { + cmd[1] = (u8)((data & 0xff000000) >> 24); + cmd[2] = (u8)((data & 0x00ff0000) >> 16); + } + + err = FALSE; + err |= !EXIImmEx(chan, cmd, 5, 1); + err |= !EXIImmEx(chan, (u8*)card->workArea + (u32)sizeof(CARDID), card->latency, 1); + err |= !EXIImmEx(chan, rbuf, rlen, 0); + err |= !EXIDeselect(chan); + + return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; +} + +// Calculate Dummy Read Length, 4-32Bytes +static s32 DummyLen(void) +{ + u32 tick; + u32 wk; + s32 tmp; + u32 max; + + wk = 1; + max = 0; + tick = OSGetTick(); + next = tick; + + tmp = CARDRand(); + tmp &= 0x0000001f; + tmp += 1; + while ((tmp < 4) && (max < 10)) + { + tick = OSGetTick(); + tmp = (s32)(tick << wk); + wk++; + if (wk > 16) + { + wk = 1; + } + next = tmp; + tmp = CARDRand(); + tmp &= 0x0000001f; + tmp += 1; + max++; + } + if (tmp < 4) + { + tmp = 4; + } + + return tmp; +} + +s32 __CARDUnlock(s32 chan, u8 flashID[12]) +{ + u32 init_val; + u32 data = 0; + + s32 dummy; + s32 rlen; + u32 rshift; + + u8 fsts; + u32 wk, wk1; + u32 w; + u32 i; + u32 Ans1 = 0; + u32 Ans2 = 0; + u32* dp; + u8 rbuf[64]; + u32 para1A = 0; + u32 para1B = 0; + u32 para2A = 0; + u32 para2B = 0; + + CARDControl* card; + DSPTaskInfo* task; + DecodeParameters* param; + u8* input; + u8* output; + + card = &__CARDBlock[chan]; + task = &card->task; + param = (DecodeParameters*)card->workArea; + input = (u8*)((u8*)param + sizeof(DecodeParameters)); + input = (u8*)OSRoundUp32B(input); + output = input + 32; + + fsts = 0; + init_val = GetInitVal(); + + dummy = DummyLen(); + rlen = dummy; + if (ReadArrayUnlock(chan, init_val, rbuf, rlen, 0) < 0) + { + return CARD_RESULT_NOCARD; + } + + rshift = (u32)(dummy * 8 + 1); + wk = data; + for (i = 0; i < rshift; i++) + { + wk = ~(w ^ (w >> 7) ^ (w >> 15) ^ (w >> 23)); + w = (w >> 1) | ((wk << 30) & 0x40000000); + } + + wk1 = ~(wk ^ (wk >> 7) ^ (wk >> 15) ^ (wk >> 23)); + card->scramble = (wk | ((wk1 << 31) & 0x80000000)); + card->scramble = bitrev(card->scramble); + dummy = DummyLen(); + rlen = 20 + dummy; + data = 0; + if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) + { + return CARD_RESULT_NOCARD; + } + dp = (u32*)rbuf; + para1A = *dp++; + para1B = *dp++; + Ans1 = *dp++; + para2A = *dp++; + para2B = *dp++; + para1A = (para1A ^ card->scramble); + rshift = 32; + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + para1B = (para1B ^ card->scramble); + rshift = 32; + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + Ans1 ^= card->scramble; + rshift = 32; + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + para2A = (para2A ^ card->scramble); + rshift = 32; + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + para2B = (para2B ^ card->scramble); + rshift = (u32)(dummy * 8); + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + rshift = 32 + 1; + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + + *(u32*)&input[0] = para2A; + *(u32*)&input[4] = para2B; + + param->inputAddr = input; + param->inputLength = 8; + param->outputAddr = output; + param->aramAddr = 0; + + DCFlushRange(input, 8); + DCInvalidateRange(output, 4); + DCFlushRange(param, sizeof(DecodeParameters)); + + task->priority = 255; + task->iram_mmem_addr = (u16*)OSPhysicalToCached(CardData); + task->iram_length = 0x160; + task->iram_addr = 0; + task->dsp_init_vector = 0x10; + task->init_cb = InitCallback; + task->res_cb = NULL; + task->done_cb = DoneCallback; + task->req_cb = NULL; + DSPAddTask(task); + + dp = (u32*)flashID; + *dp++ = para1A; + *dp++ = para1B; + *dp = Ans1; + + return CARD_RESULT_READY; +} + +static void InitCallback(void* _task) +{ + s32 chan; + CARDControl* card; + DSPTaskInfo* task; + DecodeParameters* param; + + task = _task; + for (chan = 0; chan < 2; ++chan) + { + card = &__CARDBlock[chan]; + if ((DSPTaskInfo*)&card->task == task) + { + break; + } + } + param = (DecodeParameters*)card->workArea; + + DSPSendMailToDSP(0xff000000); + while (DSPCheckMailToDSP()) + ; + + DSPSendMailToDSP((u32)param); + while (DSPCheckMailToDSP()) + ; +} + +static void DoneCallback(void* _task) +{ + u8 rbuf[64]; + u32 data; + s32 dummy; + s32 rlen; + u32 rshift; + + u8 unk; + u32 wk, wk1; + u32 Ans2; + + s32 chan; + CARDControl* card; + s32 result; + DSPTaskInfo* task; + DecodeParameters* param; + + u8* input; + u8* output; + task = _task; + for (chan = 0; chan < 2; ++chan) + { + card = &__CARDBlock[chan]; + if ((DSPTaskInfo*)&card->task == task) + { + break; + } + } + + param = (DecodeParameters*)card->workArea; + input = (u8*)((u8*)param + sizeof(DecodeParameters)); + input = (u8*)OSRoundUp32B(input); + output = input + 32; + + Ans2 = *(u32*)output; + dummy = DummyLen(); + rlen = dummy; + data = ((Ans2 ^ card->scramble) & 0xffff0000); + if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) + { + EXIUnlock(chan); + __CARDMountCallback(chan, CARD_RESULT_NOCARD); + return; + } + + rshift = (u32)((dummy + 4 + card->latency) * 8 + 1); + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + + dummy = DummyLen(); + rlen = dummy; + data = (((Ans2 << 16) ^ card->scramble) & 0xffff0000); + if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) + { + EXIUnlock(chan); + __CARDMountCallback(chan, CARD_RESULT_NOCARD); + return; + } + result = __CARDReadStatus(chan, &unk); + if (!EXIProbe(chan)) + { + EXIUnlock(chan); + __CARDMountCallback(chan, CARD_RESULT_NOCARD); + return; + } + if (result == CARD_RESULT_READY && !(unk & 0x40)) + { + EXIUnlock(chan); + result = CARD_RESULT_IOERROR; + } + __CARDMountCallback(chan, result); +} \ No newline at end of file diff --git a/libs/dolphin/card/CARDWrite.c b/libs/dolphin/card/CARDWrite.c new file mode 100644 index 000000000..a077a9621 --- /dev/null +++ b/libs/dolphin/card/CARDWrite.c @@ -0,0 +1,128 @@ +#include + +static void EraseCallback(s32 chan, s32 result); + +static void WriteCallback(s32 chan, s32 result) +{ + CARDControl* card; + CARDCallback callback; + u16* fat; + CARDDir* dir; + CARDDir* ent; + CARDFileInfo* fileInfo; + + card = &__CARDBlock[chan]; + if (result < 0) + { + goto error; + } + + fileInfo = card->fileInfo; + if (fileInfo->length < 0) + { + result = CARD_RESULT_CANCELED; + goto error; + } + + fileInfo->length -= card->sectorSize; + if (fileInfo->length <= 0) + { + dir = __CARDGetDirBlock(card); + ent = &dir[fileInfo->fileNo]; + ent->time = (u32)OSTicksToSeconds(OSGetTime()); + callback = card->apiCallback; + card->apiCallback = 0; + result = __CARDUpdateDir(chan, callback); + } + else + { + fat = __CARDGetFatBlock(card); + fileInfo->offset += card->sectorSize; + fileInfo->iBlock = fat[fileInfo->iBlock]; + if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) + { + result = CARD_RESULT_BROKEN; + goto error; + } + result = __CARDEraseSector(chan, card->sectorSize * (u32)fileInfo->iBlock, EraseCallback); + } + + if (result < 0) + { + goto error; + } + return; + +error: + callback = card->apiCallback; + card->apiCallback = 0; + __CARDPutControlBlock(card, result); + callback(chan, result); +} + +static void EraseCallback(s32 chan, s32 result) +{ + CARDControl* card; + CARDCallback callback; + CARDFileInfo* fileInfo; + + card = &__CARDBlock[chan]; + if (result < 0) + { + goto error; + } + + fileInfo = card->fileInfo; + result = __CARDWrite(chan, card->sectorSize * (u32)fileInfo->iBlock, card->sectorSize, + card->buffer, WriteCallback); + if (result < 0) + { + goto error; + } + return; + +error: + callback = card->apiCallback; + card->apiCallback = 0; + __CARDPutControlBlock(card, result); + callback(chan, result); +} + +s32 CARDWriteAsync(CARDFileInfo* fileInfo, const void* buf, s32 length, s32 offset, + CARDCallback callback) +{ + CARDControl* card; + s32 result; + CARDDir* dir; + CARDDir* ent; + + result = __CARDSeek(fileInfo, length, offset, &card); + if (result < 0) + { + return result; + } + + if (OFFSET(offset, card->sectorSize) != 0 || OFFSET(length, card->sectorSize) != 0) + { + return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR); + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileInfo->fileNo]; + result = __CARDIsWritable(card, ent); + if (result < 0) + { + return __CARDPutControlBlock(card, result); + } + + DCStoreRange((void*)buf, (u32)length); + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + card->buffer = (void*)buf; + result = + __CARDEraseSector(fileInfo->chan, card->sectorSize * (u32)fileInfo->iBlock, EraseCallback); + if (result < 0) + { + __CARDPutControlBlock(card, result); + } + return result; +} diff --git a/libs/dolphin/card/__card.h b/libs/dolphin/card/__card.h new file mode 100644 index 000000000..f4e4de2f0 --- /dev/null +++ b/libs/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/libs/dolphin/db/db.c b/libs/dolphin/db/db.c new file mode 100644 index 000000000..7ce0322f3 --- /dev/null +++ b/libs/dolphin/db/db.c @@ -0,0 +1,46 @@ +#include +#include + +DBInterface *__DBInterface = NULL; +int DBVerbose; + +extern void __DBExceptionStart(); +extern void __DBExceptionEnd(); +extern void __DBExceptionSetNumber(); + +void DBInit(void) +{ + __DBInterface = (DBInterface *)OSPhysicalToCached(OS_DBINTERFACE_ADDR); + __DBInterface->ExceptionDestination = (void (*)())OSCachedToPhysical(__DBExceptionDestination); + DBVerbose = TRUE; +} + +void __DBExceptionDestinationAux(void) +{ + u32 *contextAddr = (void *)0x00C0; + OSContext *context = (OSContext *)OSPhysicalToCached(*contextAddr); + + OSReport("DBExceptionDestination\n"); + OSDumpContext(context); + PPCHalt(); +} + +/* clang-format off */ +asm void __DBExceptionDestination(void) { + nofralloc + mfmsr r3 + ori r3, r3, 0x10|0x20 + mtmsr r3 + + b __DBExceptionDestinationAux +} +/* clang-format on */ + +BOOL __DBIsExceptionMarked(__OSException exception) +{ + u32 mask = 1 << exception; + + return (BOOL)(__DBInterface->exceptionMask & mask); +} + +void DBPrintf(char *format, ...) {} \ No newline at end of file diff --git a/libs/dolphin/dsp/dsp.c b/libs/dolphin/dsp/dsp.c new file mode 100644 index 000000000..7459587bb --- /dev/null +++ b/libs/dolphin/dsp/dsp.c @@ -0,0 +1,115 @@ +#include "dolphin/dsp.h" +#include "dolphin/os.h" + +#include "dolphin/hw_regs.h" + +#ifdef __cplusplus +extern "C" { +#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 17 2003 12:34:16 (0x2301) >>"; +#endif + +static s32 __DSP_init_flag = 0; +extern DSPTaskInfo* __DSP_tmp_task; +extern DSPTaskInfo* __DSP_last_task; +extern DSPTaskInfo* __DSP_first_task; +extern DSPTaskInfo* __DSP_curr_task; + +extern void __DSPHandler(__OSInterrupt, OSContext*); +extern void __DSP_debug_printf(const char* fmt, ...); +extern void __DSP_boot_task(DSPTaskInfo* task); + +u32 DSPCheckMailToDSP(void) +{ + return (__DSPRegs[0] >> 0xF) & 1; +} + +u32 DSPCheckMailFromDSP(void) +{ + return (__DSPRegs[2] >> 0xF) & 1; +} + +u32 DSPReadMailFromDSP() +{ + u16 reg1; + u16 reg2; + reg1 = __DSPRegs[2]; + reg2 = __DSPRegs[3]; + return reg1 << 16 | reg2; +} + +void DSPSendMailToDSP(u32 mail) +{ + __DSPRegs[0] = mail >> 16; + __DSPRegs[1] = mail; +} + +void DSPInit(void) +{ + u32 oldInt; + u16 reg; + __DSP_debug_printf("DSPInit(): Build Date: %s %s\n", "Apr 17 2003", "12:34:16"); + + if (__DSP_init_flag == 1) + { + return; + } + OSRegisterVersion(__DSPVersion); + oldInt = OSDisableInterrupts(); + __OSSetInterruptHandler(7, __DSPHandler); + __OSUnmaskInterrupts(0x1000000); + reg = __DSPRegs[5]; + reg = (reg & ~0xA8) | 0x800; + __DSPRegs[5] = reg; + reg = __DSPRegs[5]; + reg = reg & ~0xAC; + __DSPRegs[5] = reg; + __DSP_tmp_task = 0; + __DSP_curr_task = 0; + __DSP_last_task = 0; + __DSP_first_task = 0; + __DSP_init_flag = 1; + OSRestoreInterrupts(oldInt); +} + +int DSPCheckInit() +{ + return __DSP_init_flag; +} + +// it's possible to override this function but it wasn't done with DECL_WEAK(according to the symbol map) +DECL_WEAK DSPTaskInfo* DSPAddTask(DSPTaskInfo* task) +{ + u32 oldInt; + oldInt = OSDisableInterrupts(); + __DSP_insert_task(task); + task->state = 0; + task->flags = 1; + OSRestoreInterrupts(oldInt); + if (task == __DSP_first_task) + { + __DSP_boot_task(task); + } + + return task; +} + +DSPTaskInfo* DSPCancelTask(DSPTaskInfo* task) +{ + BOOL old; + + old = OSDisableInterrupts(); + + task->flags |= 2; + + OSRestoreInterrupts(old); + return task; +} + +#ifdef __cplusplus +} +#endif diff --git a/libs/dolphin/dsp/dsp_debug.c b/libs/dolphin/dsp/dsp_debug.c new file mode 100644 index 000000000..4559926db --- /dev/null +++ b/libs/dolphin/dsp/dsp_debug.c @@ -0,0 +1,6 @@ +#include "types.h" + +void __DSP_debug_printf(const char *fmt, ...) +{ + // UNUSED(fmt); +} \ No newline at end of file diff --git a/libs/dolphin/dsp/dsp_task.c b/libs/dolphin/dsp/dsp_task.c new file mode 100644 index 000000000..69a54084d --- /dev/null +++ b/libs/dolphin/dsp/dsp_task.c @@ -0,0 +1,426 @@ +#include "dolphin/dsp.h" +#include "dolphin/hw_regs.h" + +DSPTaskInfo* __DSP_curr_task; +DSPTaskInfo* __DSP_first_task; +DSPTaskInfo* __DSP_last_task; +DSPTaskInfo* __DSP_tmp_task; +DSPTaskInfo* __DSP_rude_task; + +BOOL __DSP_rude_task_pending; + +DECL_WEAK void __DSPHandler(__OSInterrupt, OSContext* context) +{ + DSPTaskInfo* tmp_task; + OSContext exceptionContext; + u16 tmp; + u32 mail; + + tmp = __DSPRegs[5]; + tmp = (u16)(tmp & ~0x28) | 0x80; + __DSPRegs[5] = tmp; + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + while (!DSPCheckMailFromDSP()) + ; + mail = DSPReadMailFromDSP(); + + if ((__DSP_curr_task->flags & DSP_TASK_FLAG_CANCEL) && (mail == 0xDCD10002)) + { + mail = 0xDCD10003; + } + + switch (mail) + { + case 0xDCD10000: + __DSP_curr_task->state = DSP_TASK_STATE_RUN; + + if (__DSP_curr_task->init_cb) + { + (*(__DSP_curr_task->init_cb))((void*)(__DSP_curr_task)); + } + break; + case 0xDCD10001: + __DSP_curr_task->state = DSP_TASK_STATE_RUN; + if (__DSP_curr_task->res_cb) + { + (*(__DSP_curr_task->res_cb))((void*)(__DSP_curr_task)); + } + break; + case 0xDCD10002: + if (__DSP_rude_task_pending) + { + if (__DSP_curr_task == __DSP_rude_task) + { + DSPSendMailToDSP(0xCDD10003); + while (DSPCheckMailToDSP()) + { + } + + __DSP_rude_task = NULL; + __DSP_rude_task_pending = FALSE; + + if (__DSP_curr_task->res_cb) + { + (*(__DSP_curr_task->res_cb))((void*)(__DSP_curr_task)); + } + + break; + } + else + { + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP()) + ; + __DSP_exec_task(__DSP_curr_task, __DSP_rude_task); + + __DSP_curr_task->state = DSP_TASK_STATE_YIELD; + __DSP_curr_task = __DSP_rude_task; + + __DSP_rude_task = NULL; + __DSP_rude_task_pending = FALSE; + + break; + } + } + + if (__DSP_curr_task->next == NULL) + { + if (__DSP_curr_task == __DSP_first_task) + { + DSPSendMailToDSP(0xCDD10003); + while (DSPCheckMailToDSP()) + ; + + if (__DSP_curr_task->res_cb) + { + (*(__DSP_curr_task->res_cb))((void*)(__DSP_curr_task)); + } + } + else + { + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP()) + { + } + + __DSP_exec_task(__DSP_curr_task, __DSP_first_task); + + __DSP_curr_task->state = DSP_TASK_STATE_YIELD; + __DSP_curr_task = __DSP_first_task; + } + } + else + { + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP()) + { + } + + __DSP_exec_task(__DSP_curr_task, __DSP_curr_task->next); + + __DSP_curr_task->state = DSP_TASK_STATE_YIELD; + __DSP_curr_task = __DSP_curr_task->next; + } + break; + case 0xDCD10003: + if (__DSP_rude_task_pending) + { + if (__DSP_curr_task->done_cb) + { + (*(__DSP_curr_task->done_cb))((void*)(__DSP_curr_task)); + } + + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP()) + ; + + __DSP_exec_task(NULL, __DSP_rude_task); + + __DSP_remove_task(__DSP_curr_task); + __DSP_curr_task = __DSP_rude_task; + + __DSP_rude_task = NULL; + __DSP_rude_task_pending = FALSE; + + break; + } + + if (__DSP_curr_task->next == NULL) + { + if (__DSP_curr_task == __DSP_first_task) + { + if (__DSP_curr_task->done_cb) + { + (*(__DSP_curr_task->done_cb))((void*)(__DSP_curr_task)); + } + + DSPSendMailToDSP(0xCDD10002); + while (DSPCheckMailToDSP()) + ; + + __DSP_curr_task->state = DSP_TASK_STATE_DONE; + + __DSP_remove_task(__DSP_curr_task); + } + else + { + if (__DSP_curr_task->done_cb) + { + (*(__DSP_curr_task->done_cb))((void*)(__DSP_curr_task)); + } + + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP()) + ; + + __DSP_curr_task->state = DSP_TASK_STATE_DONE; + __DSP_exec_task(NULL, __DSP_first_task); + + __DSP_curr_task = __DSP_first_task; + __DSP_remove_task(__DSP_last_task); + } + } + else + { + if (__DSP_curr_task->done_cb) + { + (*(__DSP_curr_task->done_cb))((void*)(__DSP_curr_task)); + } + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP()) + ; + + __DSP_curr_task->state = DSP_TASK_STATE_DONE; + __DSP_exec_task(NULL, __DSP_curr_task->next); + + __DSP_curr_task = __DSP_curr_task->next; + __DSP_remove_task(__DSP_curr_task->prev); + } + break; + + case 0xDCD10004: + + if (__DSP_curr_task->req_cb) + { + (*(__DSP_curr_task->req_cb))((void*)(__DSP_curr_task)); + } + break; + default: + break; + } + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +void __DSP_exec_task(DSPTaskInfo* curr, DSPTaskInfo* next) +{ + if (curr) + { + DSPSendMailToDSP((u32)(curr->dram_mmem_addr)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(curr->dram_length)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(curr->dram_addr)); + while (DSPCheckMailToDSP()) + ; + } + else + { + DSPSendMailToDSP((u32)(0)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(0)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(0)); + while (DSPCheckMailToDSP()) + ; + } + + DSPSendMailToDSP((u32)(next->iram_mmem_addr)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(next->iram_length)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(next->iram_addr)); + while (DSPCheckMailToDSP()) + ; + + if (DSP_TASK_STATE_INIT == next->state) + { + DSPSendMailToDSP((u32)(next->dsp_init_vector)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(0)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(0)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(0)); + while (DSPCheckMailToDSP()) + ; + } + else + { + DSPSendMailToDSP((u32)(next->dsp_resume_vector)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(next->dram_mmem_addr)); + while (DSPCheckMailToDSP()) + ; + + DSPSendMailToDSP((u32)(next->dram_length)); + while (DSPCheckMailToDSP()) + ; + + DSPSendMailToDSP((u32)(next->dram_addr)); + while (DSPCheckMailToDSP()) + ; + } +} + +#define MSG_BASE 0x80F30000 +void __DSP_boot_task(DSPTaskInfo* task) +{ + volatile u32 mail; + + while (!DSPCheckMailFromDSP()) + ; + + mail = DSPReadMailFromDSP(); + + DSPSendMailToDSP(MSG_BASE | 0xA001); + while (DSPCheckMailToDSP()) + { + } + DSPSendMailToDSP((u32)(task->iram_mmem_addr)); + while (DSPCheckMailToDSP()) + { + } + + DSPSendMailToDSP(MSG_BASE | 0xC002); + while (DSPCheckMailToDSP()) + { + } + DSPSendMailToDSP((u32)(task->iram_addr & 0xffff)); + while (DSPCheckMailToDSP()) + { + } + + DSPSendMailToDSP(MSG_BASE | 0xA002); + while (DSPCheckMailToDSP()) + { + } + DSPSendMailToDSP(task->iram_length); + while (DSPCheckMailToDSP()) + { + } + + DSPSendMailToDSP(MSG_BASE | 0xB002); + while (DSPCheckMailToDSP()) + { + } + DSPSendMailToDSP(0x00000000); + while (DSPCheckMailToDSP()) + { + } + + DSPSendMailToDSP(MSG_BASE | 0xD001); + while (DSPCheckMailToDSP()) + { + } + DSPSendMailToDSP((u32)(0xffff & task->dsp_init_vector)); + while (DSPCheckMailToDSP()) + { + } + + __DSP_debug_printf("DSP is booting task: 0x%08X\n", task); + __DSP_debug_printf("__DSP_boot_task() : IRAM MMEM ADDR: 0x%08X\n", + (u32)(task->iram_mmem_addr)); + __DSP_debug_printf("__DSP_boot_task() : IRAM DSP ADDR : 0x%08X\n", (u32)(task->iram_addr)); + __DSP_debug_printf("__DSP_boot_task() : IRAM LENGTH : 0x%08X\n", (u32)(task->iram_length)); + __DSP_debug_printf("__DSP_boot_task() : DRAM MMEM ADDR: 0x%08X\n", (u32)(task->dram_length)); + __DSP_debug_printf("__DSP_boot_task() : Start Vector : 0x%08X\n", + (u32)(task->dsp_init_vector)); +} + +void __DSP_insert_task(DSPTaskInfo* task) +{ + DSPTaskInfo* temp; + + if (__DSP_first_task == NULL) + { + __DSP_first_task = __DSP_last_task = __DSP_curr_task = task; + task->next = task->prev = NULL; + } + else + { + temp = __DSP_first_task; + + while (temp) + { + if (task->priority < temp->priority) + { + task->prev = temp->prev; + temp->prev = task; + task->next = temp; + if (task->prev == NULL) + { + __DSP_first_task = task; + } + else + { + (task->prev)->next = task; + } + break; + } + temp = temp->next; + } + + if (temp == NULL) + { + __DSP_last_task->next = task; + task->next = NULL; + task->prev = __DSP_last_task; + __DSP_last_task = task; + } + } +} + +void __DSP_remove_task(DSPTaskInfo* task) +{ + task->flags = DSP_TASK_FLAG_CLEARALL; + task->state = DSP_TASK_STATE_DONE; + + if (__DSP_first_task == task) + { + if (task->next) + { + __DSP_first_task = (task->next); + task->next->prev = NULL; + } + else + { + __DSP_first_task = __DSP_last_task = __DSP_curr_task = NULL; + } + } + else if (__DSP_last_task == task) + { + __DSP_last_task = (task->prev); + task->prev->next = NULL; + __DSP_curr_task = __DSP_first_task; + } + else + { + __DSP_curr_task = task->next; + task->prev->next = task->next; + task->next->prev = task->prev; + } +} \ No newline at end of file diff --git a/libs/dolphin/dvd/dvd.c b/libs/dolphin/dvd/dvd.c new file mode 100644 index 000000000..30b70e61e --- /dev/null +++ b/libs/dolphin/dvd/dvd.c @@ -0,0 +1,1664 @@ +#include +#include +#include +#include +#include + +const char* __DVDVersion = "<< Dolphin SDK - DVD\trelease build: Jul 23 2003 11:27:57 (0x2301) >>"; +// need to be "<< Dolphin SDK - DSP\trelease build: Apr 17 2003 12:34:16 (0x2301) >>" + +typedef void (*stateFunc)(DVDCommandBlock* block); +stateFunc LastState; + +static DVDBB2 BB2 ALIGN(32); +static DVDDiskID CurrDiskID ALIGN(32); +static DVDCommandBlock* executing; +static DVDDiskID* IDShouldBe; +static OSBootInfo* bootInfo; +static BOOL autoInvalidation = TRUE; +static volatile BOOL PauseFlag = FALSE; +static volatile BOOL PausingFlag = FALSE; +static volatile BOOL AutoFinishing = FALSE; +static volatile BOOL FatalErrorFlag = FALSE; +static vu32 CurrCommand; +static vu32 Canceling = FALSE; +static DVDCBCallback CancelCallback; +static vu32 ResumeFromHere = 0; +static vu32 CancelLastError; +static vu32 LastError; +static vs32 NumInternalRetry = 0; +static volatile BOOL ResetRequired; +static volatile BOOL CancelAllSyncComplete = FALSE; +static volatile BOOL FirstTimeInBootrom = FALSE; + +static DVDCommandBlock DummyCommandBlock; +static OSAlarm ResetAlarm; + +static BOOL DVDInitialized = FALSE; + +/* States */ +static void stateReadingFST(); +static void stateTimeout(); +static void stateGettingError(); +static void stateGoToRetry(); +static void stateCheckID(); +static void stateCheckID3(); +static void stateCheckID2a(); +static void stateCheckID2(); +static void stateCoverClosed(); +static void stateCoverClosed_CMD(); +static void stateCoverOpen(); +static void stateMotorStopped(); +static void stateReady(); +static void stateBusy(); + +/* Callbacks */ +static void cbForStateReadingFST(u32 intType); +static void cbForStateError(u32 intType); +static void cbForStateGettingError(u32 intType); +static void cbForUnrecoveredError(u32 intType); +static void cbForUnrecoveredErrorRetry(u32 intType); +static void cbForStateGoToRetry(u32 intType); +static void cbForStateCheckID2a(u32 intType); +static void cbForStateCheckID1(u32 intType); +static void cbForStateCheckID2(u32 intType); +static void cbForStateCheckID3(u32 intType); +static void cbForStateCoverClosed(u32 intType); +static void cbForStateMotorStopped(u32 intType); +static void cbForStateBusy(u32 intType); +static void cbForCancelStreamSync(s32 result, DVDCommandBlock* block); +static void cbForCancelSync(s32 result, DVDCommandBlock* block); +static void cbForCancelAllSync(s32 result, DVDCommandBlock* block); + +static void defaultOptionalCommandChecker(DVDCommandBlock* block, DVDLowCallback cb); + +static DVDOptionalCommandChecker checkOptionalCommand = defaultOptionalCommandChecker; + +static void defaultOptionalCommandChecker(DVDCommandBlock* block, DVDLowCallback cb) +{ +} + +void DVDInit() +{ + if (DVDInitialized) + { + return; + } + + OSRegisterVersion(__DVDVersion); + DVDInitialized = TRUE; + __DVDFSInit(); + __DVDClearWaitingQueue(); + __DVDInitWA(); + bootInfo = (OSBootInfo*)OSPhysicalToCached(0x0000); + IDShouldBe = &(bootInfo->DVDDiskID); + __OSSetInterruptHandler(21, __DVDInterruptHandler); + __OSUnmaskInterrupts(0x400); + OSInitThreadQueue(&__DVDThreadQueue); + __DIRegs[0] = 0x2a; + __DIRegs[1] = 0; + if (bootInfo->magic == 0xE5207C22) + { + OSReport("load fst\n"); + __fstLoad(); + } + else if (bootInfo->magic != 0xD15EA5E) + { + FirstTimeInBootrom = TRUE; + } +} + +static void stateReadingFST() +{ + LastState = (stateFunc)stateReadingFST; + + if (bootInfo->FSTMaxLength < BB2.FSTLength) + { +#line 650 + OSHalt("DVDChangeDisk(): FST in the new disc is too big. "); + } + + DVDLowRead(bootInfo->FSTLocation, OSRoundUp32B(BB2.FSTLength), BB2.FSTPosition, + cbForStateReadingFST); +} + +static void cbForStateReadingFST(u32 intType) +{ + DVDCommandBlock* finished; + + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if (intType & 1) + { + NumInternalRetry = 0; + __DVDFSInit(); + finished = executing; + executing = &DummyCommandBlock; + finished->state = 0; + if (finished->callback) + { + (finished->callback)(0, finished); + } + + stateReady(); + } + else + { + stateGettingError(); + } +} + +inline static void stateError(u32 error) +{ + __DVDStoreErrorCode(error); + DVDLowStopMotor(cbForStateError); +} + +static void cbForStateError(u32 intType) +{ + DVDCommandBlock* finished; + + if (intType == 16) + { + executing->state = -1; + 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(); + + return; +} + +static void stateTimeout() +{ + __DVDStoreErrorCode(0x1234568); + DVDReset(); + cbForStateError(0); +} + +static void stateGettingError() +{ + DVDLowRequestError(cbForStateGettingError); +} + +static u32 CategorizeError(u32 error) +{ + if (error == 0x20400) + { + LastError = error; + return 1; + } + + error &= 0xffffff; + + if ((error == 0x62800) || (error == 0x23a00) || (error == 0xb5a01)) + { + return 0; + } + + ++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; + } + } +} + +inline static BOOL CheckCancel(u32 resume) +{ + DVDCommandBlock* finished; + + if (Canceling) + { + ResumeFromHere = resume; + Canceling = FALSE; + + finished = executing; + executing = &DummyCommandBlock; + + finished->state = 10; + if (finished->callback) + (*finished->callback)(-3, finished); + if (CancelCallback) + (CancelCallback)(0, finished); + stateReady(); + return TRUE; + } + return FALSE; +} + +static void cbForStateGettingError(u32 intType) +{ + u32 error; + u32 status; + u32 errorCategory; + u32 resume; + + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if (intType & 2) + { + executing->state = -1; + stateError(0x1234567); + return; + } + + error = __DIRegs[8]; + status = error & 0xff000000; + + errorCategory = CategorizeError(error); + + if (errorCategory == 1) + { + executing->state = -1; + stateError(error); + 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 (CheckCancel(resume)) + return; + + if (errorCategory == 2) + { + __DVDStoreErrorCode(error); + stateGoToRetry(); + 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 + { + executing->state = -1; + stateError(0x1234567); + return; + } +} + +static void cbForUnrecoveredError(u32 intType) +{ + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if (intType & 1) + { + stateGoToRetry(); + return; + } + + DVDLowRequestError(cbForUnrecoveredErrorRetry); +} + +static void cbForUnrecoveredErrorRetry(u32 intType) +{ + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + executing->state = -1; + + if (intType & 2) + { + __DVDStoreErrorCode(0x1234567); + DVDLowStopMotor(cbForStateError); + return; + } + + __DVDStoreErrorCode(__DIRegs[8]); + DVDLowStopMotor(cbForStateError); +} + +static void stateGoToRetry() +{ + DVDLowStopMotor(cbForStateGoToRetry); +} + +static void cbForStateGoToRetry(u32 intType) +{ + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if (intType & 2) + { + executing->state = -1; + stateError(0x1234567); + return; + } + + NumInternalRetry = 0; + + if ((CurrCommand == 4) || (CurrCommand == 5) || (CurrCommand == 13) || (CurrCommand == 15)) + { + ResetRequired = TRUE; + } + + if (!CheckCancel(2)) + { + executing->state = 11; + stateMotorStopped(); + } +} + +static void stateCheckID() +{ + switch (CurrCommand) + { + case 3: + if (DVDCompareDiskID(&CurrDiskID, executing->id)) + { + memcpy(IDShouldBe, &CurrDiskID, sizeof(DVDDiskID)); + + executing->state = 1; + DCInvalidateRange(&BB2, sizeof(DVDBB2)); + LastState = stateCheckID2a; + stateCheckID2a(executing); + return; + } + else + { + DVDLowStopMotor(cbForStateCheckID1); + } + break; + + default: + if (memcmp(&CurrDiskID, IDShouldBe, sizeof(DVDDiskID))) + { + DVDLowStopMotor(cbForStateCheckID1); + } + else + { + LastState = stateCheckID3; + stateCheckID3(executing); + } + break; + } +} + +static void stateCheckID3() +{ + DVDLowAudioBufferConfig(IDShouldBe->streaming, 10, cbForStateCheckID3); +} + +static void stateCheckID2a() +{ + DVDLowAudioBufferConfig(IDShouldBe->streaming, 10, cbForStateCheckID2a); +} + +static void cbForStateCheckID2a(u32 intType) +{ + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if (intType & 1) + { + NumInternalRetry = 0; + stateCheckID2(executing); + return; + } + + DVDLowRequestError(cbForStateGettingError); +} + +static void stateCheckID2() +{ + DVDLowRead(&BB2, OSRoundUp32B(sizeof(BB2)), 0x420, cbForStateCheckID2); +} + +static void cbForStateCheckID1(u32 intType) +{ + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if (intType & 2) + { + executing->state = -1; + stateError(0x1234567); + return; + } + + NumInternalRetry = 0; + + if (!CheckCancel(1)) + { + executing->state = 6; + stateMotorStopped(); + } +} + +static void cbForStateCheckID2(u32 intType) +{ + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if (intType & 1) + { + NumInternalRetry = 0; + + stateReadingFST(); + } + else + { + stateGettingError(); + } +} + +static void cbForStateCheckID3(u32 intType) +{ + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if (intType & 1) + { + NumInternalRetry = 0; + + if (!CheckCancel(0)) + { + executing->state = 1; + stateBusy(executing); + } + } + else + { + stateGettingError(); + } +} + +static void AlarmHandler(OSAlarm* alarm, OSContext* context) +{ + DVDReset(); + DCInvalidateRange(&CurrDiskID, sizeof(DVDDiskID)); + LastState = stateCoverClosed_CMD; + stateCoverClosed_CMD(executing); +} + +static void stateCoverClosed() +{ + DVDCommandBlock* finished; + + switch (CurrCommand) + { + case 5: + case 4: + case 13: + case 15: + __DVDClearWaitingQueue(); + finished = executing; + executing = &DummyCommandBlock; + if (finished->callback) + { + (finished->callback)(-4, finished); + } + stateReady(); + break; + + default: + DVDReset(); + OSCreateAlarm(&ResetAlarm); + OSSetAlarm(&ResetAlarm, OSMillisecondsToTicks(1150), AlarmHandler); + break; + } +} + +static void stateCoverClosed_CMD(DVDCommandBlock* block) +{ + DVDLowReadDiskID(&CurrDiskID, cbForStateCoverClosed); +} + +static void cbForStateCoverClosed(u32 intType) +{ + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if (intType & 1) + { + NumInternalRetry = 0; + stateCheckID(); + } + else + { + stateGettingError(); + } +} + +static void stateMotorStopped(void) +{ + DVDLowWaitCoverClose(cbForStateMotorStopped); +} + +static void cbForStateMotorStopped(u32 intType) +{ + __DIRegs[1] = 0; + executing->state = 3; + stateCoverClosed(); +} + +static void stateReady() +{ + DVDCommandBlock* finished; + + if (!__DVDCheckWaitingQueue()) + { + executing = (DVDCommandBlock*)NULL; + return; + } + + if (PauseFlag) + { + PausingFlag = TRUE; + executing = (DVDCommandBlock*)NULL; + return; + } + + executing = __DVDPopWaitingQueue(); + + if (FatalErrorFlag) + { + executing->state = -1; + finished = executing; + executing = &DummyCommandBlock; + if (finished->callback) + { + (finished->callback)(-1, finished); + } + stateReady(); + return; + } + + CurrCommand = executing->command; + + if (ResumeFromHere) + { + switch (ResumeFromHere) + { + case 2: + executing->state = 11; + stateMotorStopped(); + break; + case 3: + executing->state = 4; + stateMotorStopped(); + break; + + case 4: + executing->state = 5; + stateMotorStopped(); + break; + case 1: + case 7: + case 6: + executing->state = 3; + stateCoverClosed(); + break; + + case 5: + executing->state = -1; + stateError(CancelLastError); + break; + } + + ResumeFromHere = 0; + } + else + { + executing->state = 1; + stateBusy(executing); + } +} + +static void stateBusy(DVDCommandBlock* block) +{ + DVDCommandBlock* finished; + LastState = stateBusy; + switch (block->command) + { + case 5: + __DIRegs[1] = __DIRegs[1]; + block->currTransferSize = sizeof(DVDDiskID); + DVDLowReadDiskID(block->addr, cbForStateBusy); + break; + case 1: + case 4: + if (!block->length) + { + finished = executing; + executing = &DummyCommandBlock; + finished->state = 0; + if (finished->callback) + { + finished->callback(0, finished); + } + stateReady(); + } + else + { + __DIRegs[1] = __DIRegs[1]; + block->currTransferSize = block->length - block->transferredSize > 0x80000 ? + 0x80000 : + block->length - block->transferredSize; + DVDLowRead((void*)((u8*)block->addr + block->transferredSize), block->currTransferSize, + block->offset + block->transferredSize, cbForStateBusy); + } + break; + case 2: + __DIRegs[1] = __DIRegs[1]; + DVDLowSeek(block->offset, cbForStateBusy); + break; + case 3: + DVDLowStopMotor(cbForStateBusy); + break; + case 15: + DVDLowStopMotor(cbForStateBusy); + break; + case 6: + __DIRegs[1] = __DIRegs[1]; + if (AutoFinishing) + { + executing->currTransferSize = 0; + DVDLowRequestAudioStatus(0, cbForStateBusy); + } + else + { + executing->currTransferSize = 1; + DVDLowAudioStream(0, block->length, block->offset, cbForStateBusy); + } + break; + case 7: + __DIRegs[1] = __DIRegs[1]; + DVDLowAudioStream(0x10000, 0, 0, cbForStateBusy); + break; + case 8: + __DIRegs[1] = __DIRegs[1]; + AutoFinishing = TRUE; + DVDLowAudioStream(0, 0, 0, cbForStateBusy); + break; + case 9: + __DIRegs[1] = __DIRegs[1]; + DVDLowRequestAudioStatus(0, cbForStateBusy); + break; + case 10: + __DIRegs[1] = __DIRegs[1]; + DVDLowRequestAudioStatus(0x10000, cbForStateBusy); + break; + case 11: + __DIRegs[1] = __DIRegs[1]; + DVDLowRequestAudioStatus(0x20000, cbForStateBusy); + break; + case 12: + __DIRegs[1] = __DIRegs[1]; + DVDLowRequestAudioStatus(0x30000, cbForStateBusy); + break; + case 13: + __DIRegs[1] = __DIRegs[1]; + DVDLowAudioBufferConfig(block->offset, block->length, cbForStateBusy); + break; + case 14: + __DIRegs[1] = __DIRegs[1]; + block->currTransferSize = sizeof(DVDDriveInfo); + DVDLowInquiry(block->addr, cbForStateBusy); + break; + default: + checkOptionalCommand(block, cbForStateBusy); + break; + } +} + +static u32 ImmCommand[] = { 0xffffffff, 0xffffffff, 0xffffffff }; +/* Somehow this got included even though the function is stripped? O.o */ +static char string_DVDChangeDiskAsyncMsg[] = + "DVDChangeDiskAsync(): You can't specify NULL to company name. \n"; +static u32 DmaCommand[] = { 0xffffffff }; + +inline static BOOL IsImmCommandWithResult(u32 command) +{ + u32 i; + + if (command == 9 || command == 10 || command == 11 || command == 12) + { + return TRUE; + } + + for (i = 0; i < sizeof(ImmCommand) / sizeof(ImmCommand[0]); i++) + { + if (command == ImmCommand[i]) + return TRUE; + } + + return FALSE; +} + +inline static BOOL IsDmaCommand(u32 command) +{ + u32 i; + + if (command == 1 || command == 4 || command == 5 || command == 14) + return TRUE; + + for (i = 0; i < sizeof(DmaCommand) / sizeof(DmaCommand[0]); i++) + { + if (command == DmaCommand[i]) + return TRUE; + } + + return FALSE; +} + +static void cbForStateBusy(u32 intType) +{ + DVDCommandBlock* finished; + + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if ((CurrCommand == 3) || (CurrCommand == 15)) + { + if (intType & 2) + { + executing->state = -1; + stateError(0x1234567); + return; + } + + NumInternalRetry = 0; + + if (CurrCommand == 15) + { + ResetRequired = TRUE; + } + + if (CheckCancel(7)) + { + return; + } + + executing->state = 7; + stateMotorStopped(); + return; + } + + if (IsDmaCommand(CurrCommand)) + { + executing->transferredSize += executing->currTransferSize - __DIRegs[6]; + } + + if (intType & 8) + { + Canceling = FALSE; + finished = executing; + executing = &DummyCommandBlock; + + finished->state = 10; + if (finished->callback) + (*finished->callback)(-3, finished); + if (CancelCallback) + (CancelCallback)(0, finished); + stateReady(); + + return; + } + + if (intType & 1) + { + NumInternalRetry = 0; + + if (CheckCancel(0)) + return; + + if (IsDmaCommand(CurrCommand)) + { + if (executing->transferredSize != executing->length) + { + stateBusy(executing); + return; + } + + finished = executing; + executing = &DummyCommandBlock; + + finished->state = 0; + if (finished->callback) + { + (finished->callback)((s32)finished->transferredSize, finished); + } + stateReady(); + } + else if (IsImmCommandWithResult(CurrCommand)) + { + s32 result; + + if ((CurrCommand == 11) || (CurrCommand == 10)) + { + result = (s32)(__DIRegs[8] << 2); + } + else + { + result = (s32)__DIRegs[8]; + } + finished = executing; + executing = &DummyCommandBlock; + + finished->state = 0; + if (finished->callback) + { + (finished->callback)(result, finished); + } + stateReady(); + } + else if (CurrCommand == 6) + { + if (executing->currTransferSize == 0) + { + if (__DIRegs[8] & 1) + { + finished = executing; + executing = &DummyCommandBlock; + + finished->state = 9; + if (finished->callback) + { + (finished->callback)(-2, finished); + } + stateReady(); + } + else + { + AutoFinishing = FALSE; + executing->currTransferSize = 1; + DVDLowAudioStream(0, executing->length, executing->offset, cbForStateBusy); + } + } + else + { + finished = executing; + executing = &DummyCommandBlock; + + finished->state = 0; + if (finished->callback) + { + (finished->callback)(0, finished); + } + stateReady(); + } + } + else + { + finished = executing; + executing = &DummyCommandBlock; + + finished->state = 0; + if (finished->callback) + { + (finished->callback)(0, finished); + } + stateReady(); + } + } + else + { + if (CurrCommand == 14) + { + executing->state = -1; + stateError(0x01234567); + return; + } + + if ((CurrCommand == 1 || CurrCommand == 4 || CurrCommand == 5 || CurrCommand == 14) && + (executing->transferredSize == executing->length)) + { + if (CheckCancel(0)) + { + return; + } + finished = executing; + executing = &DummyCommandBlock; + + finished->state = 0; + if (finished->callback) + { + (finished->callback)((s32)finished->transferredSize, finished); + } + stateReady(); + return; + } + + stateGettingError(); + } +} + +static BOOL issueCommand(s32 prio, DVDCommandBlock* block) +{ + BOOL level; + BOOL result; + + if (autoInvalidation && + (block->command == 1 || block->command == 4 || block->command == 5 || block->command == 14)) + { + DCInvalidateRange(block->addr, block->length); + } + + level = OSDisableInterrupts(); + + block->state = 2; + result = __DVDPushWaitingQueue(prio, block); + + if ((executing == (DVDCommandBlock*)NULL) && (PauseFlag == FALSE)) + { + stateReady(); + } + + OSRestoreInterrupts(level); + + return result; +} + +BOOL DVDReadAbsAsyncPrio(DVDCommandBlock* block, void* addr, s32 length, s32 offset, + DVDCBCallback callback, s32 prio) +{ + BOOL idle; + block->command = 1; + block->addr = addr; + block->length = length; + block->offset = offset; + block->transferredSize = 0; + block->callback = callback; + + idle = issueCommand(prio, block); + return idle; +} + +BOOL DVDReadAbsAsyncForBS(DVDCommandBlock* block, void* addr, s32 length, s32 offset, + DVDCBCallback callback) +{ + BOOL idle; + block->command = 4; + block->addr = addr; + block->length = length; + block->offset = offset; + block->transferredSize = 0; + block->callback = callback; + + idle = issueCommand(2, block); + return idle; +} + +BOOL DVDReadDiskID(DVDCommandBlock* block, DVDDiskID* diskID, DVDCBCallback callback) +{ + BOOL idle; + block->command = 5; + block->addr = diskID; + block->length = sizeof(DVDDiskID); + ; + block->offset = 0; + block->transferredSize = 0; + block->callback = callback; + + idle = issueCommand(2, block); + return idle; +} + +BOOL DVDPrepareStreamAbsAsync(DVDCommandBlock* block, u32 length, u32 offset, + DVDCBCallback callback) +{ + BOOL idle; + block->command = 6; + block->length = length; + block->offset = offset; + block->callback = callback; + + idle = issueCommand(1, block); + return idle; +} + +BOOL DVDCancelStreamAsync(DVDCommandBlock* block, DVDCBCallback callback) +{ + BOOL idle; + block->command = 7; + block->callback = callback; + idle = issueCommand(1, block); + return idle; +} + +s32 DVDCancelStream(DVDCommandBlock* block) +{ + BOOL result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDCancelStreamAsync(block, cbForCancelStreamSync); + + if (result == FALSE) + { + return -1; + } + + enabled = OSDisableInterrupts(); + + while (TRUE) + { + state = ((volatile DVDCommandBlock*)block)->state; + + if (state == 0 || state == -1 || state == 10) + { + retVal = (s32)block->transferredSize; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} +static void cbForCancelStreamSync(s32 result, DVDCommandBlock* block) +{ + block->transferredSize = (u32)result; + OSWakeupThread(&__DVDThreadQueue); +} +BOOL DVDStopStreamAtEndAsync(DVDCommandBlock* block, DVDCBCallback callback) +{ + BOOL idle; + + block->command = 8; + block->callback = callback; + + idle = issueCommand(1, block); + + return idle; +} +BOOL DVDGetStreamErrorStatusAsync(DVDCommandBlock* block, DVDCBCallback callback) +{ + BOOL idle; + + block->command = 9; + block->callback = callback; + + idle = issueCommand(1, block); + + return idle; +} +BOOL DVDGetStreamPlayAddrAsync(DVDCommandBlock* block, DVDCBCallback callback) +{ + BOOL idle; + + block->command = 10; + block->callback = callback; + + idle = issueCommand(1, block); + + return idle; +} +BOOL DVDInquiryAsync(DVDCommandBlock* block, DVDDriveInfo* info, DVDCBCallback callback) +{ + BOOL idle; + + block->command = 14; + block->addr = (void*)info; + block->length = sizeof(DVDDriveInfo); + block->transferredSize = 0; + block->callback = callback; + + idle = issueCommand(2, block); + + return idle; +} + +void DVDReset(void) +{ + DVDLowReset(); + __DIRegs[0] = 0x2a; + __DIRegs[1] = __DIRegs[1]; + ResetRequired = FALSE; + ResumeFromHere = 0; +} + +s32 DVDGetCommandBlockStatus(const DVDCommandBlock* block) +{ + BOOL enabled; + s32 retVal; + + enabled = OSDisableInterrupts(); + + if (block->state == 3) + { + retVal = 1; + } + else + { + retVal = block->state; + } + + OSRestoreInterrupts(enabled); + + return retVal; +} + +s32 DVDGetDriveStatus() +{ + BOOL enabled; + s32 retVal; + + enabled = OSDisableInterrupts(); + + if (FatalErrorFlag) + { + retVal = -1; + } + else if (PausingFlag) + { + retVal = 8; + } + else + { + if (executing == (DVDCommandBlock*)NULL) + { + retVal = 0; + } + else if (executing == &DummyCommandBlock) + { + retVal = 0; + } + else + { + retVal = DVDGetCommandBlockStatus(executing); + } + } + + OSRestoreInterrupts(enabled); + + return retVal; +} + +BOOL DVDSetAutoInvalidation(BOOL autoInval) +{ + BOOL prev; + prev = autoInvalidation; + autoInvalidation = autoInval; + return prev; +} + +void DVDPause(void) +{ + BOOL level; + level = OSDisableInterrupts(); + PauseFlag = TRUE; + if (executing == (DVDCommandBlock*)NULL) + { + PausingFlag = TRUE; + } + OSRestoreInterrupts(level); +} + +void DVDResume(void) +{ + BOOL level; + level = OSDisableInterrupts(); + PauseFlag = FALSE; + if (PausingFlag) + { + PausingFlag = FALSE; + stateReady(); + } + OSRestoreInterrupts(level); +} + +BOOL DVDCancelAsync(DVDCommandBlock* block, DVDCBCallback callback) +{ + BOOL enabled; + DVDLowCallback old; + DVDCommandBlock* + finished; // needed for stack? maybe it actually gets used but not bothered to figure that out + + enabled = OSDisableInterrupts(); + + switch (block->state) + { + case -1: + case 0: + case 10: + if (callback) + (*callback)(0, block); + break; + + case 1: + if (Canceling) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + + Canceling = TRUE; + CancelCallback = callback; + if (block->command == 4 || block->command == 1) + { + DVDLowBreak(); + } + break; + + case 2: + __DVDDequeueWaitingQueue(block); + block->state = 10; + if (block->callback) + (block->callback)(-3, block); + if (callback) + (*callback)(0, block); + break; + + case 3: + switch (block->command) + { + case 5: + case 4: + case 13: + case 15: + if (callback) + (*callback)(0, block); + break; + + 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; + + executing = &DummyCommandBlock; + + block->state = 10; + if (block->callback) + { + (block->callback)(-3, block); + } + if (callback) + { + (callback)(0, block); + } + stateReady(); + break; + } + + OSRestoreInterrupts(enabled); + return TRUE; +} + +s32 DVDCancel(DVDCommandBlock* block) +{ + BOOL result; + s32 state; + u32 command; + BOOL enabled; + + result = DVDCancelAsync(block, cbForCancelSync); + + if (result == FALSE) + { + return -1; + } + + enabled = OSDisableInterrupts(); + + for (;;) + { + state = ((volatile DVDCommandBlock*)block)->state; + + if ((state == 0) || (state == -1) || (state == 10)) + { + break; + } + + if (state == 3) + { + command = ((volatile DVDCommandBlock*)block)->command; + + if ((command == 4) || (command == 5) || (command == 13) || (command == 15)) + { + break; + } + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return 0; +} + +static void cbForCancelSync(s32 result, DVDCommandBlock* block) +{ + OSWakeupThread(&__DVDThreadQueue); +} + +inline BOOL DVDCancelAllAsync(DVDCBCallback callback) +{ + BOOL enabled; + DVDCommandBlock* p; + BOOL retVal; + + enabled = OSDisableInterrupts(); + DVDPause(); + + while ((p = __DVDPopWaitingQueue()) != 0) + { + DVDCancelAsync(p, NULL); + } + + if (executing) + retVal = DVDCancelAsync(executing, callback); + else + { + retVal = TRUE; + if (callback) + (*callback)(0, NULL); + } + + DVDResume(); + OSRestoreInterrupts(enabled); + return retVal; +} + +s32 DVDCancelAll(void) +{ + BOOL result; + BOOL enabled; + + enabled = OSDisableInterrupts(); + CancelAllSyncComplete = FALSE; + + result = DVDCancelAllAsync(cbForCancelAllSync); + + if (result == FALSE) + { + OSRestoreInterrupts(enabled); + return -1; + } + + for (;;) + { + if (CancelAllSyncComplete) + break; + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return 0; +} + +static void cbForCancelAllSync(s32 result, DVDCommandBlock* block) +{ + CancelAllSyncComplete = TRUE; + OSWakeupThread(&__DVDThreadQueue); +} + +DVDDiskID* DVDGetCurrentDiskID(void) +{ + return (DVDDiskID*)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 == (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 = 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); +} + +BOOL __DVDTestAlarm(OSAlarm* alarm) +{ + BOOL ret; + if (alarm == &ResetAlarm) + { + ret = TRUE; + } + else + { + ret = __DVDLowTestAlarm(alarm); + } + return ret; +} \ No newline at end of file diff --git a/libs/dolphin/dvd/dvdFatal.c b/libs/dolphin/dvd/dvdFatal.c new file mode 100644 index 000000000..43359a1a4 --- /dev/null +++ b/libs/dolphin/dvd/dvdFatal.c @@ -0,0 +1,112 @@ +#include "dolphin/dvd.h" +#include "dolphin/gx/GXStruct.h" +#include "dolphin/os.h" +#include "dolphin/vi.h" + +void __DVDPrintFatalMessage(void); + +static void (*FatalFunc)(void) = NULL; + +const char *Japanese = "\n\n\nエラーが発生しました。" + "\n\n本体のパワーボタンを押して電源をOFFにし、" + "\n本体の取扱説明書の指示に従ってください。"; + +const char *English = "\n\n\nAn error has occurred." + "\nTurn the power off and refer to the" + "\nNintendo GameCube Instruction Booklet" + "\nfor further instructions."; + +const char *const Europe[] = { + // English + "\n\n\nAn error has occurred." + "\nTurn the power off and refer to the" + "\nNintendo GameCube" + "\x99" + " Instruction Booklet" + "\nfor further instructions.", + + // German + "\n\n\nEin Fehler ist aufgetreten." + "\nBitte schalten Sie den NINTENDO GAMECUBE" + "\naus und lesen Sie die Bedienungsanleitung," + "\num weitere Informationen zu erhalten.", + + // French + "\n\n\nUne erreur est survenue." + "\nEteignez la console et r" + "\xe9" + "f" + "\xe9" + "rez-vous au" + "\nmanuel d'instructions NINTENDO GAMECUBE" + "\npour de plus amples informations.", + + // Spanish + "\n\n\nSe ha producido un error." + "\nApaga la consola y consulta el manual" + "\nde instrucciones de NINTENDO GAMECUBE" + "\npara obtener m" + "\xe1" + "s informaci" + "\xf3" + "n.", + + // Italian + "\n\n\nSi \xe8 verificato un errore." + "\nSpegni (OFF) e controlla il manuale" + "\nd'istruzioni del NINTENDO GAMECUBE" + "\nper ulteriori indicazioni.", + + // Dutch + "\n\n\nEr is een fout opgetreden." + "\nZet de NINTENDO GAMECUBE uit en" + "\nraadpleeg de handleiding van de" + "\nNintendo GameCube voor nadere" + "\ninstructies.", +}; + +static void ShowMessage(void) +{ + const char *message; + GXColor bg = {0, 0, 0, 0}; + GXColor fg = {255, 255, 255, 0}; + + if (VIGetTvFormat() == VI_NTSC) + { + if (OSGetFontEncode() == OS_FONT_ENCODE_SJIS) + { + message = Japanese; + } + else + { + message = English; + } + } + else + { + message = Europe[OSGetLanguage()]; + } + + OSFatal(fg, bg, message); +} + +BOOL DVDSetAutoFatalMessaging(BOOL enable) +{ + BOOL enabled; + BOOL prev; + + enabled = OSDisableInterrupts(); + prev = FatalFunc ? TRUE : FALSE; + FatalFunc = enable ? ShowMessage : NULL; + OSRestoreInterrupts(enabled); + return prev; +} + +void __DVDPrintFatalMessage(void) +{ + if (!FatalFunc) + { + return; + } + FatalFunc(); +} \ No newline at end of file diff --git a/libs/dolphin/dvd/dvderror.c b/libs/dolphin/dvd/dvderror.c new file mode 100644 index 000000000..a2f294393 --- /dev/null +++ b/libs/dolphin/dvd/dvderror.c @@ -0,0 +1,77 @@ +#include "dolphin/dvd.h" +#include "dolphin/OSRtcPriv.h" + +static u32 ErrorTable[] = { + 0, + 0x00023A00, + 0x00062800, + 0x00030200, + 0x00031100, + 0x00052000, + 0x00052001, + 0x00052100, + 0x00052400, + 0x00052401, + 0x00052402, + 0x000B5A01, + 0x00056300, + 0x00020401, + 0x00020400, + 0x00040800, + 0x00100007, + 0, +}; + +static u8 ErrorCode2Num(u32 errorCode) +{ + u32 i; + + for (i = 0; i < sizeof(ErrorTable) / sizeof(ErrorTable[0]); i++) + { + if (ErrorTable[i] == errorCode) + { + return (u8)i; + } + } + + if ((errorCode >= 0x00100000) && (errorCode <= 0x00100008)) + { + return 17; + } + + return 29; +} + +static u8 Convert(u32 error) +{ + u32 statusCode; + u32 errorCode; + u8 errorNum; + + if (error == 0x01234567) + return 255; + + if (error == 0x01234568) + return 254; + + statusCode = (error & 0xff000000) >> 24; + errorCode = error & 0x00ffffff; + + errorNum = ErrorCode2Num(errorCode); + if (statusCode >= 6) + statusCode = 6; + + return (u8)(statusCode * 30 + errorNum); +} + +void __DVDStoreErrorCode(u32 error) +{ + OSSramEx *sram; + u8 num; + + num = Convert(error); + + sram = __OSLockSramEx(); + sram->dvdErrorCode = num; + __OSUnlockSramEx(TRUE); +} \ No newline at end of file diff --git a/libs/dolphin/dvd/dvdfs.c b/libs/dolphin/dvd/dvdfs.c new file mode 100644 index 000000000..7b688f415 --- /dev/null +++ b/libs/dolphin/dvd/dvdfs.c @@ -0,0 +1,739 @@ +#include "dolphin/dvd.h" +#include "dolphin/os.h" +#include "dolphin/os/OSBootInfo.h" + +typedef struct FSTEntry FSTEntry; + +struct FSTEntry +{ + unsigned int isDirAndStringOff; + unsigned int parentOrPosition; + unsigned int nextEntryOrLength; +}; + +static OSBootInfo *BootInfo; +static FSTEntry *FstStart; +static char *FstStringStart; +static u32 MaxEntryNum; +static u32 currentDirectory = 0; +OSThreadQueue __DVDThreadQueue; +u32 __DVDLongFileNameFlag = 0; + +static void cbForReadAsync(s32 result, DVDCommandBlock *block); +static void cbForReadSync(s32 result, DVDCommandBlock *block); +static void cbForSeekAsync(s32 result, DVDCommandBlock *block); +static void cbForSeekSync(s32 result, DVDCommandBlock *block); +static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock *block); +static void cbForPrepareStreamSync(s32 result, DVDCommandBlock *block); + +void __DVDFSInit() +{ + BootInfo = (OSBootInfo *)OSPhysicalToCached(0); + FstStart = (FSTEntry *)BootInfo->FSTLocation; + + if (FstStart) + { + MaxEntryNum = FstStart[0].nextEntryOrLength; + FstStringStart = (char *)&(FstStart[MaxEntryNum]); + } +} + +/* For convenience */ +#define entryIsDir(i) (((FstStart[i].isDirAndStringOff & 0xff000000) == 0) ? FALSE : TRUE) +#define stringOff(i) (FstStart[i].isDirAndStringOff & ~0xff000000) +#define parentDir(i) (FstStart[i].parentOrPosition) +#define nextDir(i) (FstStart[i].nextEntryOrLength) +#define filePosition(i) (FstStart[i].parentOrPosition) +#define fileLength(i) (FstStart[i].nextEntryOrLength) + +static BOOL isSame(const char *path, const char *string) +{ + while (*string != '\0') + { + if (tolower(*path++) != tolower(*string++)) + { + return FALSE; + } + } + + if ((*path == '/') || (*path == '\0')) + { + return TRUE; + } + + return FALSE; +} + +s32 DVDConvertPathToEntrynum(const char *pathPtr) +{ + const char *ptr; + char *stringPtr; + BOOL isDir; + u32 length; + u32 dirLookAt; + u32 i; + const char *origPathPtr = pathPtr; + const char *extentionStart; + BOOL illegal; + BOOL extention; + + dirLookAt = currentDirectory; + + while (1) + { + + if (*pathPtr == '\0') + { + return (s32)dirLookAt; + } + else if (*pathPtr == '/') + { + dirLookAt = 0; + pathPtr++; + continue; + } + else if (*pathPtr == '.') + { + if (*(pathPtr + 1) == '.') + { + if (*(pathPtr + 2) == '/') + { + dirLookAt = parentDir(dirLookAt); + pathPtr += 3; + continue; + } + else if (*(pathPtr + 2) == '\0') + { + return (s32)parentDir(dirLookAt); + } + } + else if (*(pathPtr + 1) == '/') + { + pathPtr += 2; + continue; + } + else if (*(pathPtr + 1) == '\0') + { + return (s32)dirLookAt; + } + } + + if (__DVDLongFileNameFlag == 0) + { + extention = FALSE; + illegal = FALSE; + + for (ptr = pathPtr; (*ptr != '\0') && (*ptr != '/'); ptr++) + { + if (*ptr == '.') + { + if ((ptr - pathPtr > 8) || (extention == TRUE)) + { + illegal = TRUE; + break; + } + extention = TRUE; + extentionStart = ptr + 1; + } + else if (*ptr == ' ') + illegal = TRUE; + } + + if ((extention == TRUE) && (ptr - extentionStart > 3)) + illegal = TRUE; + + if (illegal) { + OSPanic(__FILE__, 383, + "DVDConvertEntrynumToPath(possibly DVDOpen or DVDChangeDir or DVDOpenDir): " + "specified directory or file (%s) doesn't match standard 8.3 format. This is a " + "temporary restriction and will be removed soon\n", + origPathPtr); + } + } + + else + { + for (ptr = pathPtr; (*ptr != '\0') && (*ptr != '/'); ptr++) + ; + } + + isDir = (*ptr == '\0') ? FALSE : TRUE; + length = (u32)(ptr - pathPtr); + + ptr = pathPtr; + + for (i = dirLookAt + 1; i < nextDir(dirLookAt); i = entryIsDir(i) ? nextDir(i) : (i + 1)) + { + if ((entryIsDir(i) == FALSE) && (isDir == TRUE)) + { + continue; + } + + stringPtr = FstStringStart + stringOff(i); + + if (isSame(ptr, stringPtr) == TRUE) + { + goto next_hier; + } + } + + return -1; + + next_hier: + if (!isDir) + { + return (s32)i; + } + + dirLookAt = i; + pathPtr += length + 1; + } +} + +BOOL DVDFastOpen(s32 entrynum, DVDFileInfo *fileInfo) +{ + if ((entrynum < 0) || (entrynum >= MaxEntryNum) || entryIsDir(entrynum)) + { + return FALSE; + } + + fileInfo->startAddr = filePosition(entrynum); + fileInfo->length = fileLength(entrynum); + fileInfo->callback = (DVDCallback)NULL; + fileInfo->cb.state = DVD_STATE_END; + + return TRUE; +} + +BOOL DVDOpen(const char *fileName, DVDFileInfo *fileInfo) +{ + s32 entry; + char currentDir[128]; + + entry = DVDConvertPathToEntrynum(fileName); + + if (0 > entry) + { + DVDGetCurrentDir(currentDir, 128); + OSReport("Warning: DVDOpen(): file '%s' was not found under %s.\n", fileName, currentDir); + return FALSE; + } + + if (entryIsDir(entry)) + { + return FALSE; + } + + fileInfo->startAddr = filePosition(entry); + fileInfo->length = fileLength(entry); + fileInfo->callback = (DVDCallback)NULL; + fileInfo->cb.state = DVD_STATE_END; + + return TRUE; +} + +BOOL DVDClose(DVDFileInfo *fileInfo) +{ + DVDCancel(&(fileInfo->cb)); + return TRUE; +} + +static u32 myStrncpy(char *dest, char *src, u32 maxlen) +{ + u32 i = maxlen; + + while ((i > 0) && (*src != 0)) + { + *dest++ = *src++; + i--; + } + + return (maxlen - i); +} + +static u32 entryToPath(u32 entry, char *path, u32 maxlen) +{ + char *name; + u32 loc; + + if (entry == 0) + { + return 0; + } + + name = FstStringStart + stringOff(entry); + + loc = entryToPath(parentDir(entry), path, maxlen); + + if (loc == maxlen) + { + return loc; + } + + *(path + loc++) = '/'; + + loc += myStrncpy(path + loc, name, maxlen - loc); + + return loc; +} + +static BOOL DVDConvertEntrynumToPath(s32 entrynum, char *path, u32 maxlen) +{ + u32 loc; + + loc = entryToPath((u32)entrynum, path, maxlen); + + if (loc == maxlen) + { + path[maxlen - 1] = '\0'; + return FALSE; + } + + if (entryIsDir(entrynum)) + { + if (loc == maxlen - 1) + { + path[loc] = '\0'; + return FALSE; + } + + path[loc++] = '/'; + } + + path[loc] = '\0'; + return TRUE; +} + +BOOL DVDGetCurrentDir(char *path, u32 maxlen) +{ + return DVDConvertEntrynumToPath((s32)currentDirectory, path, maxlen); +} + +BOOL DVDChangeDir(char *dirName) +{ + s32 entry; + entry = DVDConvertPathToEntrynum(dirName); + if ((entry < 0) || (entryIsDir(entry) == FALSE)) + { + return FALSE; + } + + currentDirectory = (u32)entry; + + return TRUE; +} + +BOOL DVDReadAsyncPrio(DVDFileInfo *fileInfo, void *addr, s32 length, s32 offset, + DVDCallback callback, s32 prio) +{ + + if (!((0 <= offset) && (offset < fileInfo->length))) + { +#line 746 + OSHalt("DVDReadAsync(): specified area is out of the file "); + } + + if (!((0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE))) + { +#line 752 + OSHalt("DVDReadAsync(): specified area is out of the file "); + } + + fileInfo->callback = callback; + DVDReadAbsAsyncPrio(&(fileInfo->cb), addr, length, (s32)(fileInfo->startAddr + offset), + cbForReadAsync, prio); + + return TRUE; +} +#ifndef offsetof +#define offsetof(type, memb) ((u32) & ((type *)0)->memb) +#endif + +static void cbForReadAsync(s32 result, DVDCommandBlock *block) +{ + DVDFileInfo *fileInfo; + + fileInfo = (DVDFileInfo *)((char *)block - offsetof(DVDFileInfo, cb)); + if (fileInfo->callback) + { + (fileInfo->callback)(result, fileInfo); + } +} + +s32 DVDReadPrio(DVDFileInfo *fileInfo, void *addr, s32 length, s32 offset, s32 prio) +{ + BOOL result; + DVDCommandBlock *block; + s32 state; + BOOL enabled; + s32 retVal; + + if (!((0 <= offset) && (offset < fileInfo->length))) + { +#line 816 + OSHalt("DVDRead(): specified area is out of the file "); + } + + if (!((0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE))) + { +#line 822 + OSHalt("DVDRead(): specified area is out of the file "); + } + + block = &(fileInfo->cb); + + result = DVDReadAbsAsyncPrio(block, addr, length, (s32)(fileInfo->startAddr + offset), + cbForReadSync, prio); + + if (result == FALSE) + { + return -1; + } + + enabled = OSDisableInterrupts(); + + while (1) + { + state = ((volatile DVDCommandBlock *)block)->state; + + if (state == DVD_STATE_END) + { + retVal = (s32)block->transferredSize; + break; + } + if (state == DVD_STATE_FATAL_ERROR) + { + retVal = DVD_RESULT_FATAL_ERROR; + break; + } + if (state == DVD_STATE_CANCELED) + { + retVal = DVD_RESULT_CANCELED; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +/* This is based on the revolution SDK, these may not match in all cases */ +static void cbForReadSync(s32 result, DVDCommandBlock *block) { OSWakeupThread(&__DVDThreadQueue); } +/* This is based on the revolution SDK, these may not match in all cases */ +BOOL DVDSeekAsyncPrio(DVDFileInfo *fileInfo, s32 offset, DVDCallback callback, s32 prio) +{ + if (!((0 <= offset) && (offset <= fileInfo->length))) + { + OSPanic(__FILE__, 0, "DVDSeek(): offset is out of the file "); + } + + fileInfo->callback = callback; + DVDSeekAbsAsyncPrio(&(fileInfo->cb), (s32)(fileInfo->startAddr + offset), cbForSeekAsync, + prio); + + return TRUE; +} +/* This is based on the revolution SDK, these may not match in all cases */ +static void cbForSeekAsync(s32 result, DVDCommandBlock *block) +{ + DVDFileInfo *fileInfo; + + fileInfo = (DVDFileInfo *)((char *)block - offsetof(DVDFileInfo, cb)); + + if (fileInfo->callback) + { + (fileInfo->callback)(result, fileInfo); + } +} +/* This is based on the revolution SDK, these may not match in all cases */ +s32 DVDSeekPrio(DVDFileInfo *fileInfo, s32 offset, s32 prio) +{ + BOOL result; + DVDCommandBlock *block; + s32 state; + BOOL enabled; + s32 retVal; + + block = &(fileInfo->cb); + + result = + DVDSeekAbsAsyncPrio(block, (s32)(fileInfo->startAddr + offset), cbForSeekSync, prio); + + 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 = DVD_RESULT_CANCELED; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} +/* This is based on the revolution SDK, these may not match in all cases */ +static void cbForSeekSync(s32 result, DVDCommandBlock *block) { OSWakeupThread(&__DVDThreadQueue); } + +/* This is based on the revolution SDK, these may not match in all cases */ +s32 DVDGetFileInfoStatus(DVDFileInfo *fileInfo) +{ + return DVDGetCommandBlockStatus(&fileInfo->cb); +} + +/* This is based on the revolution SDK, these may not match in all cases */ +BOOL DVDFastOpenDir(s32 entrynum, DVDDir *dir) +{ + + if ((entrynum < 0) || (entrynum >= MaxEntryNum) || !entryIsDir(entrynum)) + { + return FALSE; + } + + dir->entryNum = (u32)entrynum; + dir->location = (u32)entrynum + 1; + dir->next = nextDir(entrynum); + + return TRUE; +} + +/* This is based on the revolution SDK, these may not match in all cases */ +BOOL DVDOpenDir(char *dirName, DVDDir *dir) +{ + s32 entry; + char currentDir[128]; + entry = DVDConvertPathToEntrynum(dirName); + + if (entry < 0) + { + DVDGetCurrentDir(currentDir, 128); + OSReport("Warning: DVDOpenDir(): file '%s' was not found under %s.\n", dirName, currentDir); + return FALSE; + } + + if (!entryIsDir(entry)) + { + return FALSE; + } + + dir->entryNum = (u32)entry; + dir->location = (u32)entry + 1; + dir->next = nextDir(entry); + + return TRUE; +} + +BOOL DVDReadDir(DVDDir *dir, DVDDirEntry *dirent) +{ + u32 loc = dir->location; + if ((loc <= dir->entryNum) || (dir->next <= loc)) + return FALSE; + + dirent->entryNum = loc; + dirent->isDir = entryIsDir(loc); + dirent->name = FstStringStart + stringOff(loc); + + dir->location = entryIsDir(loc) ? nextDir(loc) : (loc + 1); + + return TRUE; +} + +/* This is based on the revolution SDK, these may not match in all cases */ +BOOL DVDCloseDir(DVDDir *dir) { return TRUE; } + +/* This is based on the revolution SDK, these may not match in all cases */ +void DVDRewindDir(DVDDir *dir) { dir->location = dir->entryNum + 1; } + +/* This is based on the revolution SDK, these may not match in all cases */ +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; + + start = fileInfo->startAddr + offset; + + if (!Is32KBAligned(start)) + { + OSPanic(__FILE__, 1189, + "DVDPrepareStreamAsync(): Specified start address (filestart(0x%x) + offset(0x%x)) is " + "not 32KB aligned", + fileInfo->startAddr, offset); + } + + if (length == 0) + length = fileInfo->length - offset; + + if (!Is32KBAligned(length)) + { + OSPanic(__FILE__, 1199, + "DVDPrepareStreamAsync(): Specified length (0x%x) is not a multiple of 32768(32*1024)", + length); + } + + if (!((offset < fileInfo->length) && (offset + length <= fileInfo->length))) + { + OSPanic(__FILE__, 1207, + "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)); + + if (fileInfo->callback) + { + (fileInfo->callback)(result, fileInfo); + } +} + +/* This is based on the revolution SDK, these may not match in all cases */ +s32 DVDPrepareStream(DVDFileInfo *fileInfo, u32 length, u32 offset) +{ + BOOL result; + DVDCommandBlock *block; + s32 state; + BOOL enabled; + s32 retVal; + u32 start; + start = fileInfo->startAddr + offset; + + if (!Is32KBAligned(start)) + { + OSPanic(__FILE__, 0, + "DVDPrepareStream(): Specified start address (filestart(0x%x) + offset(0x%x)) is not " + "32KB aligned", + fileInfo->startAddr, offset); + } + + if (length == 0) + length = fileInfo->length - offset; + + if (!Is32KBAligned(length)) + { + OSPanic(__FILE__, 0, + "DVDPrepareStream(): Specified length (0x%x) is not a multiple of 32768(32*1024)", + length); + } + + if (!((offset <= fileInfo->length) && (offset + length <= fileInfo->length))) + { + OSPanic( + __FILE__, 0, + "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 = DVD_RESULT_CANCELED; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +/* This is based on the revolution SDK, these may not match in all cases */ +static void cbForPrepareStreamSync(s32 result, DVDCommandBlock *block) +{ + OSWakeupThread(&__DVDThreadQueue); +} + +/* This is based on the revolution SDK, these may not match in all cases */ +s32 DVDGetTransferredSize(DVDFileInfo *fileinfo) +{ + s32 bytes; + DVDCommandBlock *cb; + + cb = &(fileinfo->cb); + + switch (cb->state) + { + case DVD_STATE_END: + 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: + bytes = (s32)cb->transferredSize; + break; + + case DVD_STATE_WAITING: + bytes = 0; + break; + + case DVD_STATE_BUSY: + bytes = (s32)(cb->transferredSize + (cb->currTransferSize - DVDLowGetLength())); + break; + + default: + break; + } + + return bytes; +} \ No newline at end of file diff --git a/libs/dolphin/dvd/dvdidutils.c b/libs/dolphin/dvd/dvdidutils.c new file mode 100644 index 000000000..f4cbe4118 --- /dev/null +++ b/libs/dolphin/dvd/dvdidutils.c @@ -0,0 +1,31 @@ +#include +#include + +#include + +BOOL DVDCompareDiskID(DVDDiskID *id1, DVDDiskID *id2) +{ + + if (id1->gameName[0] && id2->gameName[0] && strncmp(&id1->gameName[0], &id2->gameName[0], 4)) + { + return FALSE; + } + + if (!id1->company[0] || !id2->company[0] || strncmp(&id1->company[0], &id2->company[0], 2)) + { + return FALSE; + } + + if (id1->diskNumber != 0xff && id2->diskNumber != 0xff && id1->diskNumber != id2->diskNumber) + { + return FALSE; + } + + if (id1->gameVersion != 0xff && id2->gameVersion != 0xff && + id1->gameVersion != id2->gameVersion) + { + return FALSE; + } + + return TRUE; +} \ No newline at end of file diff --git a/libs/dolphin/dvd/dvdlow.c b/libs/dolphin/dvd/dvdlow.c new file mode 100644 index 000000000..c09c54eb9 --- /dev/null +++ b/libs/dolphin/dvd/dvdlow.c @@ -0,0 +1,515 @@ +#include "dolphin/dvd.h" +#include "dolphin/os.h" + +static BOOL FirstRead = TRUE; +static volatile BOOL StopAtNextInt = FALSE; +static u32 LastLength = 0; +static DVDLowCallback Callback = NULL; +static DVDLowCallback ResetCoverCallback = NULL; +static volatile OSTime LastResetEnd = 0; +static volatile u32 ResetOccurred = FALSE; +static volatile BOOL WaitingCoverClose = FALSE; +static BOOL Breaking = FALSE; +static volatile u32 WorkAroundType = 0; +static u32 WorkAroundSeekLocation = 0; +static volatile OSTime LastReadFinished = 0; +static OSTime LastReadIssued = 0; +static volatile BOOL LastCommandWasRead = FALSE; +static vu32 NextCommandNumber = 0; + +typedef struct DVDBuffer +{ + void *addr; + u32 length; + u32 offset; +} DVDBuffer; + +typedef struct DVDCommand +{ + s32 cmd; + void *addr; + u32 length; + u32 offset; + DVDLowCallback callback; +} DVDCommand; + +static DVDCommand CommandList[3]; +static OSAlarm AlarmForWA; +static OSAlarm AlarmForTimeout; +static OSAlarm AlarmForBreak; +static DVDBuffer Prev; +static DVDBuffer Curr; + +void __DVDInitWA() +{ + NextCommandNumber = 0; + CommandList[0].cmd = -1; + __DVDLowSetWAType(0, 0); + OSInitAlarm(); +} + +static void Read(void *addr, u32 length, u32 offset, DVDLowCallback callback); + +static BOOL ProcessNextCommand() +{ + s32 n = NextCommandNumber; + ASSERT(n < 3); + + if (CommandList[n].cmd == 1) + { + ++NextCommandNumber; + Read(CommandList[n].addr, CommandList[n].length, CommandList[n].offset, + CommandList[n].callback); + return TRUE; + } + else if (CommandList[n].cmd == 2) + { + ++NextCommandNumber; + DVDLowSeek(CommandList[n].offset, CommandList[n].callback); + return TRUE; + } + + return FALSE; +} + +void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext *context) +{ + DVDLowCallback cb; + OSContext exceptionContext; + u32 cause = 0; + u32 reg; + u32 intr; + u32 mask; + + 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].cmd = -1; + NextCommandNumber = 0; + } + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + if (cause) + { + cb = Callback; + Callback = NULL; + if (cb) + { + cb(cause); + } + + Breaking = FALSE; + } + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +static void AlarmHandler(OSAlarm *alarm, OSContext *context) +{ + BOOL error = ProcessNextCommand(); + ASSERTMSG(error != FALSE, "Failed assertion processed"); +} + +static void AlarmHandlerForTimeout(OSAlarm *alarm, OSContext *context) +{ + OSContext tmpContext; + DVDLowCallback callback; + __OSMaskInterrupts(0x400); + OSClearContext(&tmpContext); + OSSetCurrentContext(&tmpContext); + callback = Callback; + Callback = NULL; + if (callback != NULL) + { + callback(0x10); + } + OSClearContext(&tmpContext); + OSSetCurrentContext(context); +} + +static void SetTimeoutAlarm(OSTime timeout) +{ + OSCreateAlarm(&AlarmForTimeout); + OSSetAlarm(&AlarmForTimeout, timeout, AlarmHandlerForTimeout); +} + +static void Read(void *addr, u32 length, u32 offset, DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + LastCommandWasRead = TRUE; + Callback = callback; + LastReadIssued = __OSGetSystemTime(); + + __DIRegs[2] = 0xa8000000; + __DIRegs[3] = offset / 4; + __DIRegs[4] = length; + __DIRegs[5] = (u32)addr; + __DIRegs[6] = length; + LastLength = length; + __DIRegs[7] = 3; + + if (length > 0xa00000) + { + SetTimeoutAlarm(OSSecondsToTicks(20)); + } + else + { + SetTimeoutAlarm(OSSecondsToTicks(10)); + } +} + +BOOL HitCache(DVDBuffer *cur, DVDBuffer *prev) +{ + u32 uVar1 = (prev->offset + prev->length - 1) >> 15; + u32 uVar2 = (cur->offset >> 15); + u32 iVar3 = (DVDGetCurrentDiskID()->streaming ? TRUE : FALSE) ? 5 : 15; + + if ((uVar2 > uVar1 - 2) || (uVar2 < uVar1 + iVar3 + 3)) + { + return TRUE; + } + return FALSE; +} + +static void DoJustRead(void *addr, u32 length, u32 offset, DVDLowCallback callback) +{ + CommandList[0].cmd = -1; + NextCommandNumber = 0; + Read(addr, length, offset, callback); +} + +static void SeekTwiceBeforeRead(void *addr, u32 length, u32 offset, DVDLowCallback callback) +{ + u32 newOffset = offset & ~0x7FFF; + if (!newOffset) + { + newOffset = 0; + } + else + { + newOffset += WorkAroundSeekLocation; + } + CommandList[0].cmd = 2; + CommandList[0].offset = newOffset; + CommandList[0].callback = callback; + CommandList[1].cmd = 1; + CommandList[1].addr = addr; + CommandList[1].length = length; + CommandList[1].offset = offset; + CommandList[1].callback = callback; + CommandList[2].cmd = -1; + NextCommandNumber = 0; + DVDLowSeek(newOffset, callback); +} + +static void WaitBeforeRead(void *addr, u32 length, u32 offset, DVDLowCallback callback, + OSTime timeout) +{ + CommandList[0].cmd = 1; + CommandList[0].addr = addr; + CommandList[0].length = length; + CommandList[0].offset = offset; + CommandList[0].callback = callback; + CommandList[1].cmd = -1; + NextCommandNumber = 0; + OSCreateAlarm(&AlarmForWA); + OSSetAlarm(&AlarmForWA, timeout, AlarmHandler); +} + +BOOL DVDLowRead(void *addr, u32 length, u32 offset, DVDLowCallback callback) +{ + OSTime diff; + u32 prev; + + __DIRegs[6] = length; + Curr.addr = addr; + Curr.length = length; + Curr.offset = offset; + + if (WorkAroundType == 0) + { + DoJustRead(addr, length, offset, callback); + } + else if (WorkAroundType == 1) + { + if (FirstRead) + { + SeekTwiceBeforeRead(addr, length, offset, callback); + } + else + { + if (!HitCache(&Curr, &Prev)) + { + DoJustRead(addr, length, offset, callback); + } + else + { + prev = (Prev.offset + Prev.length - 1) >> 15; + if (prev == Curr.offset >> 15 || prev + 1 == Curr.offset >> 15) + { + diff = __OSGetSystemTime() - LastReadFinished; + if (OSMillisecondsToTicks(5) < diff) + { + DoJustRead(addr, length, offset, callback); + } + else + { + WaitBeforeRead(addr, length, offset, callback, + OSMillisecondsToTicks(5) - diff + OSMicrosecondsToTicks(500)); + } + } + else + { + SeekTwiceBeforeRead(addr, length, offset, callback); + } + } + } + } + return TRUE; +} + +BOOL DVDLowSeek(u32 offset, DVDLowCallback callback) +{ + ASSERTMSG(offset & 3, "DVDLowSeek(): offset must be a multiple of 4."); + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = 0xab000000; + __DIRegs[3] = offset / 4; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowWaitCoverClose(DVDLowCallback callback) +{ + Callback = callback; + WaitingCoverClose = TRUE; + StopAtNextInt = FALSE; + __DIRegs[1] = 2; + return TRUE; +} + +BOOL DVDLowReadDiskID(DVDDiskID *diskID, DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = 0xa8000040; + __DIRegs[3] = 0; + __DIRegs[4] = sizeof(DVDDiskID); + __DIRegs[5] = (u32)diskID; + __DIRegs[6] = sizeof(DVDDiskID); + __DIRegs[7] = 3; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowStopMotor(DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = 0xe3000000; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowRequestError(DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = 0xe0000000; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowInquiry(DVDDriveInfo *info, DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = 0x12000000; + __DIRegs[4] = sizeof(DVDDriveInfo); + __DIRegs[5] = (u32)info; + __DIRegs[6] = sizeof(DVDDriveInfo); + __DIRegs[7] = 3; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowAudioStream(u32 subcmd, u32 length, u32 offset, DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = subcmd | 0xe1000000; + __DIRegs[3] = offset >> 2; + __DIRegs[4] = length; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowRequestAudioStatus(u32 subcmd, DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = subcmd | 0xe2000000; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowAudioBufferConfig(BOOL enable, u32 size, DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = 0xe4000000 | (enable != 0 ? 0x10000 : 0) | size; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +void DVDLowReset() +{ + u32 reg; + OSTime resetStart; + + __DIRegs[1] = 2; + reg = __PIRegs[9]; + __PIRegs[9] = (reg & ~4) | 1; + + resetStart = __OSGetSystemTime(); + while ((__OSGetSystemTime() - resetStart) < OSMicrosecondsToTicks(12)) + ; + + __PIRegs[9] = reg | 5; + ResetOccurred = TRUE; + LastResetEnd = __OSGetSystemTime(); +} + +BOOL DVDLowBreak() +{ + StopAtNextInt = TRUE; + Breaking = TRUE; + return TRUE; +} + +DVDLowCallback DVDLowClearCallback() +{ + DVDLowCallback old; + __DIRegs[1] = 0; + old = Callback; + WaitingCoverClose = FALSE; + Callback = NULL; + return old; +} + +void __DVDLowSetWAType(u32 type, u32 location) +{ + BOOL enabled; + enabled = OSDisableInterrupts(); + WorkAroundType = type; + WorkAroundSeekLocation = location; + OSRestoreInterrupts(enabled); +} + +BOOL __DVDLowTestAlarm(OSAlarm *alarm) { + if(alarm == &AlarmForBreak) { + return TRUE; + } + if(alarm == &AlarmForTimeout) { + return TRUE; + } + + return FALSE; +} \ No newline at end of file diff --git a/libs/dolphin/dvd/dvdqueue.c b/libs/dolphin/dvd/dvdqueue.c new file mode 100644 index 000000000..54851a3c3 --- /dev/null +++ b/libs/dolphin/dvd/dvdqueue.c @@ -0,0 +1,159 @@ +#include "dolphin/dvd.h" + +#define MAX_QUEUES 4 +typedef struct +{ + DVDCommandBlock *next; + DVDCommandBlock *prev; +} DVDQueue; + +static DVDQueue WaitingQueue[MAX_QUEUES]; + +void __DVDClearWaitingQueue(void) +{ + u32 i; + + for (i = 0; i < MAX_QUEUES; i++) + { + DVDCommandBlock *q; + + q = (DVDCommandBlock *)&(WaitingQueue[i]); + q->next = q; + q->prev = q; + } +} + +BOOL __DVDPushWaitingQueue(s32 prio, DVDCommandBlock *block) +{ + BOOL enabled; + DVDCommandBlock *q; + + enabled = OSDisableInterrupts(); + + q = (DVDCommandBlock *)&(WaitingQueue[prio]); + + q->prev->next = block; + block->prev = q->prev; + block->next = q; + q->prev = block; + + OSRestoreInterrupts(enabled); + + return TRUE; +} + +static DVDCommandBlock *PopWaitingQueuePrio(s32 prio) +{ + DVDCommandBlock *tmp; + BOOL enabled; + DVDCommandBlock *q; + + enabled = OSDisableInterrupts(); + + q = (DVDCommandBlock *)&(WaitingQueue[prio]); + + tmp = q->next; + q->next = tmp->next; + tmp->next->prev = q; + + OSRestoreInterrupts(enabled); + + tmp->next = (DVDCommandBlock *)NULL; + tmp->prev = (DVDCommandBlock *)NULL; + + return tmp; +} + +DVDCommandBlock *__DVDPopWaitingQueue(void) +{ + u32 i; + BOOL enabled; + DVDCommandBlock *q; + + enabled = OSDisableInterrupts(); + + for (i = 0; i < MAX_QUEUES; i++) + { + q = (DVDCommandBlock *)&(WaitingQueue[i]); + if (q->next != q) + { + OSRestoreInterrupts(enabled); + return PopWaitingQueuePrio((s32)i); + } + } + + OSRestoreInterrupts(enabled); + + return (DVDCommandBlock *)NULL; +} + +BOOL __DVDCheckWaitingQueue(void) +{ + u32 i; + BOOL enabled; + DVDCommandBlock *q; + + enabled = OSDisableInterrupts(); + + for (i = 0; i < MAX_QUEUES; i++) + { + q = (DVDCommandBlock *)&(WaitingQueue[i]); + if (q->next != q) + { + OSRestoreInterrupts(enabled); + return TRUE; + } + } + + OSRestoreInterrupts(enabled); + + return FALSE; +} + +BOOL __DVDDequeueWaitingQueue(DVDCommandBlock *block) +{ + BOOL enabled; + DVDCommandBlock *prev; + DVDCommandBlock *next; + + enabled = OSDisableInterrupts(); + + prev = block->prev; + next = block->next; + + if ((prev == (DVDCommandBlock *)NULL) || (next == (DVDCommandBlock *)NULL)) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + + prev->next = next; + next->prev = prev; + + OSRestoreInterrupts(enabled); + + return TRUE; +} + +BOOL __DVDIsBlockInWaitingQueue(DVDCommandBlock *block) +{ + u32 i; + DVDCommandBlock *start; + DVDCommandBlock *q; + + for (i = 0; i < MAX_QUEUES; i++) + { + start = (DVDCommandBlock *)&(WaitingQueue[i]); + + if (start->next != start) + { + for (q = start->next; q != start; q = q->next) + { + if (q == block) + return TRUE; + } + } + } + + return FALSE; +} \ No newline at end of file diff --git a/libs/dolphin/dvd/emu_level2/fstload.c b/libs/dolphin/dvd/emu_level2/fstload.c new file mode 100644 index 000000000..14142137c --- /dev/null +++ b/libs/dolphin/dvd/emu_level2/fstload.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include + +static s32 status = 0; + +static u8 bb2Buf[OSRoundUp32B(sizeof(DVDBB2)) + 31]; +static DVDBB2 *bb2 = 0; +static DVDDiskID *idTmp = NULL; + +static void cb(s32 result, DVDCommandBlock *block) +{ + if (result > 0) + { + switch (status) + { + case 0: + status = 1; + DVDReadAbsAsyncForBS(block, bb2, OSRoundUp32B(sizeof(bb2)), 0x420, cb); + break; + case 1: + status = 2; + DVDReadAbsAsyncForBS(block, bb2->FSTAddress, OSRoundUp32B(bb2->FSTLength), bb2->FSTPosition, + cb); + } + } + else if (result == -1) + { + } + else if (result == -4) + { + status = 0; + DVDReset(); + DVDReadDiskID(block, idTmp, cb); + } +} + +void __fstLoad() +{ + OSBootInfo *bootInfo; + DVDDiskID *id; + u8 idTmpBuf[sizeof(DVDDiskID) + 31]; + static DVDCommandBlock block; + void *arenaHi; + + arenaHi = OSGetArenaHi(); + bootInfo = (OSBootInfo *)OSPhysicalToCached(0); + + idTmp = (DVDDiskID *)(OSRoundUp32B(idTmpBuf)); + bb2 = (DVDBB2 *)(OSRoundUp32B(bb2Buf)); + + DVDReset(); + DVDReadDiskID(&block, idTmp, cb); + while (DVDGetDriveStatus() != 0) + ; + + bootInfo->FSTLocation = bb2->FSTAddress; + bootInfo->FSTMaxLength = bb2->FSTMaxLength; + + id = &bootInfo->DVDDiskID; + + memcpy(id, idTmp, sizeof(DVDDiskID)); + OSReport("\n"); + OSReport(" Game Name ... %c%c%c%c\n", id->gameName[0], id->gameName[1], id->gameName[2], + id->gameName[3]); + OSReport(" Company ..... %c%c\n", id->company[0], id->company[1]); + OSReport(" Disk # ...... %d\n", id->diskNumber); + OSReport(" Game ver .... %d\n", id->gameVersion); + OSReport(" Streaming ... %s\n", (id->streaming == 0) ? "OFF" : "ON"); + OSReport("\n"); + OSSetArenaHi(bb2->FSTAddress); +} \ No newline at end of file diff --git a/libs/dolphin/eth/base64.c b/libs/dolphin/eth/base64.c new file mode 100644 index 000000000..a2c6b0053 --- /dev/null +++ b/libs/dolphin/eth/base64.c @@ -0,0 +1,70 @@ +#include + +static const char Base64[] = { + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" +}; + +char *__IPEncodeToBase64(void *_src, s32 len , char *dst) { + const u8 *src; + int i; + char *p; + + src = _src; + p = dst; + for (i = 0; i < len - len % 3; i += 3) { + *p++ = Base64[(src[i+0] >> 2) & 0x3f]; + *p++ = Base64[((src[i+0] & 0x3) << 4) | ((src[i+1] >> 4) & 0xf)]; + *p++ = Base64[((src[i+1] & 0xf) << 2) | ((src[i+2] >> 6) & 0x3)]; + *p++ = Base64[src[i+2] & 0x3f]; + } + + i = len - len % 3; + // Encode remaining characters + switch (len % 3) { + case 2: { + *p++ = Base64[(src[i+0] >> 2) & 0x3f]; + *p++ = Base64[((src[i+0] & 0x3) << 4) | ((src[i+1] >> 4) & 0xf)]; + *p++ = Base64[((src[i+1] & 0xf) << 2)]; + *p++ = '='; + break; + } + case 1: { + *p++ = Base64[(src[i+0] >> 2) & 0x3f]; + *p++ = Base64[((src[i+0] & 0x3) << 4)]; + *p++ = '='; + *p++ = '='; + break; + } + } + + return p; +} + +void *__IPDecodeFromBase64(const char *src, long len , void *_dst) { + u8 *dst; + int i; + u8 *p; + + dst = _dst; + p = dst; + for (i = 0; i < len; i += 4) { + int n0; + int n1; + int n2; + int n3; + n0 = strchr(Base64, src[i+0]) - Base64; + n1 = strchr(Base64, src[i+1]) - Base64; + *p++ = (n0 << 2) | (n1 >> 4) & 0x3; + + if (src[i+2] == '=') break; + + n2 = strchr(Base64, src[i+2]) - Base64; + *p++ = ((n1 << 4) & 0xff) | (n2 >> 2) & 0xf; + + if (src[i+3] == '=') break; + + n3 = strchr(Base64, src[i+3]) - Base64; + *p++ = ((n2 << 6) & 0xff) | (n3 & 0x3f); + } + return p; +} diff --git a/libs/dolphin/eth/eth.c b/libs/dolphin/eth/eth.c new file mode 100644 index 000000000..871352662 --- /dev/null +++ b/libs/dolphin/eth/eth.c @@ -0,0 +1,1031 @@ +#include + +#include +#include +#include +#include + +#include "types.h" + +#ifdef DEBUG +const char* __ETHVersion = "<< Dolphin SDK - ETH\tdebug build: Aug 5 2003 17:18:42 (0x2301) >>"; +#else +const char* __ETHVersion = "<< Dolphin SDK - ETH\trelease build: Aug 5 2003 17:18:42 (0x2301) >>"; +#endif + +static u8 broadcastheader[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +static u8 private_macaddr[6]; +static u8 __revid = 0; +static u16 __devid = 0xD107; +static u8 __acstart = 0x4E; +static OSThreadQueue threadQ; +static BOOL lockUpdate = FALSE; +static BOOL __sendbusy = FALSE; +static BOOL sendUpdate = FALSE; +static ETHStat ethstat; +static u16* protoarray = NULL; +static s32 protonum = 0; +static void* (*recvcallback0)(u16, s32, u8) = NULL; +static void (*recvcallback1)(u8*, s32) = NULL; +static BOOL recvcallbackUpdate = FALSE; +static void (*__sendcallback)(u8) = NULL; +static BOOL __recvpriorityflag = FALSE; +static u8* __sendadr = NULL; +static s32 __sendlen = 0; +static s32 __senddmalen = 0; +static s32 __sendimmlen = 0; +static u8 tmppool0[1536] ATTRIBUTE_ALIGN(32); +static u8 tmppool1[1536] ATTRIBUTE_ALIGN(32); +static u32 recvlen0 = 0; +static u32 recvlen1 = 0; + +typedef struct Descriptor { + u8 nextpacketL; + u8 packetlengthL : 4; + u8 nextpacketH : 4; + u8 packetLengthH; + u8 status; +} Descriptor; + +typedef struct Descriptor2 { + u16 nextpacket; + u16 packetlength; + u8 status; +} Descriptor2; + +static Descriptor2 d2; + +static u8* recvaddr = NULL; +static u16 rwp = 0; +static u16 rrp = 0; +static u8 mcastmap[8]; +static BOOL mcastUpdate = FALSE; + + +static BOOL lock(void); +static void unlock(void); + +static void recvsub0(void); +static void recvsub1(void); + +static void sendsub0(void); +static void sendsub1(s32 chan, OSContext* context); + +static void readbuffer0(u16 cmd); +static void readbuffer1(s32 chan, OSContext* context); +static void readbuffersub(s32 chan, OSContext* context); + +static void exiinthandler(s32 chan, OSContext* context); + +static inline u16 swap16(u16 val) { + u16 ret = __lhbrx(&val, 0); + return ret; +} + +static inline u8 higher(u16 val) { + return (val >> 8) & 0xff; +} + +static inline u8 lower(u16 val) { + return val & 0xff; +} + +static void waitexilock(void) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + while (TRUE) { + if (lock() != FALSE) { + OSRestoreInterrupts(enabled); + return; + } + + lockUpdate = TRUE; + OSSleepThread(&threadQ); + OSRestoreInterrupts(enabled); + } +} + +static void waitmicro(s32 usec) { + OSTick start; + OSTick interval; + + start = OSGetTick(); + interval = OSMicrosecondsToTicks(usec); + + while (TRUE) { + if (OSGetTick() - start >= interval) { + break; + } + } +} + +static u8 readEXIcmd(u8 cmd) { + u16 ethcmd; + u8 rdata; + + ethcmd = 0x0000 | (cmd << 8); + EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImm(0, &rdata, sizeof(rdata), EXI_READ, NULL); + EXISync(0); + EXIDeselect(0); + return rdata; +} + +static u8 readEXIcmdWait200Micro(u8 cmd) { + u16 ethcmd; + u8 rdata; + + ethcmd = 0x0000 | (cmd << 8); + EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImm(0, &rdata, sizeof(rdata), EXI_READ, NULL); + EXISync(0); + waitmicro(200); + EXIDeselect(0); + return rdata; +} + +static void writeEXIcmd(u8 cmd, u8 imr) { + BOOL ret; + u16 ethcmd; + + ethcmd = 0x4000 | (cmd << 8); + ret = EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImm(0, &imr, sizeof(imr), EXI_WRITE, NULL); + EXISync(0); + EXIDeselect(0); +} + +static void readEXIcmdLong(u8 cmd, void* address, s32 length) { + u16 ethcmd; + + ethcmd = cmd << 8; + EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImmEx(0, address, length, EXI_READ); + EXIDeselect(0); +} + +static void writeEXIcmdLong(u8 cmd, void* address, s32 length) { + BOOL ret; + u16 ethcmd; + + ethcmd = 0x4000 | (cmd << 8); + ret = EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImmEx(0, address, length, EXI_WRITE); + EXIDeselect(0); +} + +static void readcmdLong(u16 cmd, void* addr, s32 length) { + u32 ethcmd; + + ethcmd = 0x80000000 | (cmd << 8); + EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImmEx(0, addr, length, EXI_READ); + EXIDeselect(0); +} + +static void writecmdLong(u16 cmd, void* addr, s32 length) { + u32 ethcmd = 0xC0000000 | (cmd << 8); + EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImmEx(0, addr, length, EXI_WRITE); + EXIDeselect(0); +} + +static u8 readcmd(u16 cmd) { + u8 val; + + readcmdLong(cmd, &val, sizeof(val)); + return val; +} + +static void writecmd(u16 cmd, u8 val) { + writecmdLong(cmd, &val, sizeof(val)); +} + +static void StaOutput(unsigned int bit) { + writecmd(0x0060, bit * 2); + writecmd(0x0060, 8 + bit * 2); + writecmd(0x0060, 8 + bit * 2); + writecmd(0x0060, bit * 2); +} + +static u8 StaInput(void) { + unsigned char bit; + + writecmd(0x0060, 0x0C); + bit = readcmd(0x0060); + bit &= 1; + writecmd(0x0060, 0x04); + writecmd(0x0060, 0x04); + return bit; +} + +static u16 PhyRead(unsigned int regNo) { + int i; + u16 value; + + /* Clear command */ + for (i = 0; i < 32; i++) { + StaOutput(1); + } + + /* Enter read mode */ + StaOutput(0); + StaOutput(1); + StaOutput(1); + StaOutput(0); + StaOutput(0); + StaOutput(0); + StaOutput(0); + StaOutput(0); + StaOutput(0); + + /* Set register */ + StaOutput((regNo >> 4) & 1); + StaOutput((regNo >> 3) & 1); + StaOutput((regNo >> 2) & 1); + StaOutput((regNo >> 1) & 1); + StaOutput((regNo >> 0) & 1); + writecmd(0x0060, 4); + value = StaInput(); + value = StaInput(); + + /* Read value */ + value = 0; + for (i = 0; i < 16; i++) { + value = value + (StaInput() << (15 - i)); + } + + /* Clear command */ + for (i = 0; i < 32; i++) { + StaOutput(1); + } + + return value; +} + +static void PhyWrite(unsigned int regNo, u16 value) { + int i; + + /* Clear command */ + for (i = 0; i < 32; i++) { + StaOutput(1); + } + + /* Enter write mode */ + StaOutput(0); + StaOutput(1); + StaOutput(0); + StaOutput(1); + StaOutput(0); + StaOutput(0); + StaOutput(0); + StaOutput(0); + StaOutput(0); + + /* Set register */ + StaOutput((regNo >> 4) & 1); + StaOutput((regNo >> 3) & 1); + StaOutput((regNo >> 2) & 1); + StaOutput((regNo >> 1) & 1); + StaOutput((regNo >> 0) & 1); + + StaOutput(1); + StaOutput(0); + + /* Write value */ + for (i = 0; i < 16; i++) { + StaOutput((u8)((value >> (15 - i)) & 1)); + } + + /* Clear command */ + for (i = 0; i < 32; i++) { + StaOutput(1); + } +} + +static void reset(void) { + writecmd(0x0060, 0); + waitmicro(10000); + readEXIcmdWait200Micro(0x0F); + waitmicro(10000); + writecmd(0x0000, 1); + writecmd(0x0000, 0); +} + +static void recvinit(void) { + u8 ncrb; + u16 swapped; + + swapped = higher(0x0001) | (lower(0x0001) << 8); + writecmdLong(0x000A, &swapped, sizeof(swapped)); + writecmdLong(0x0016, &swapped, sizeof(swapped)); + writecmdLong(0x0018, &swapped, sizeof(swapped)); + + swapped = higher(0x000F) | (lower(0x000F) << 8); + writecmdLong(0x001A, &swapped, sizeof(swapped)); + + ncrb = readcmd(0x0001); + ncrb &= ~0b00000011; // ~3 + ncrb |= 0b00010000; // | 0x10 + writecmd(0x0001, ncrb); + writecmd(0x0000, 0x08); + writecmd(0x0032, 0x08); +} + +static void getdescriptor(u16 address) { + Descriptor d; + + readcmdLong(address, &d, sizeof(d)); + d2.nextpacket = (d.nextpacketH << 8) | d.nextpacketL; + d2.packetlength = (d.packetLengthH << 4) | d.packetlengthL; + d2.status = d.status; +} + +static u16 readcmd16(u8 cmd) { + u16 tmp16; + + readcmdLong(cmd, &tmp16, sizeof(tmp16)); + + return swap16(tmp16); +} + +static void writecmd16(u8 cmd, u16 val) { + u16 tmp16; + + tmp16 = swap16(val); + writecmdLong(cmd, &tmp16, sizeof(tmp16)); +} + +static void recvsub0(void) { + rwp = readcmd16(0x16); + rrp = readcmd16(0x18); + recvsub1(); +} + +static void recvsub1(void) { + u16 packettype; + s32 i; + u8 lrps; + u16 address; + + recvlen0 = recvlen1 = 0; + do { + while (rrp != rwp) { + address = (rrp & 0xFF) << 8; + getdescriptor(address); + readcmdLong(address + 0x10U, &packettype, sizeof(packettype)); + + if (protonum > 0) { + for (i = 0; i < protonum; i++) { + if (packettype == protoarray[i]) { + break; + } + } + + if (i == protonum) { + goto update_pointers; + } + } + + if (recvcallback0) { + lrps = d2.status; + recvaddr = (*recvcallback0)(packettype, d2.packetlength, lrps); + + if (recvaddr != NULL) { + if (address + 4U + d2.packetlength > 0x1000U) { + recvlen1 = address - 0x0FFCU + d2.packetlength; + recvlen0 = d2.packetlength - recvlen1; + } else { + recvlen0 = d2.packetlength; + recvlen1 = 0; + } + + readbuffer0(address + 4U); + return; + } + } + +update_pointers: + rrp = d2.nextpacket; + rwp = readcmd16(0x16); + } + + writecmd16(0x18, rwp); + writecmd(0x0009, 0x02); + rwp = readcmd16(0x16); + rrp = readcmd16(0x18); + } while (rwp != rrp); + + writeEXIcmd(0x02, 0xF8); + unlock(); +} + +static void readbuffer0(u16 cmd) { + u32 etcmd; + u32 length; + + length = OSRoundUp32B(recvlen0); + etcmd = 0x80000000 | (cmd << 8); + + EXISelect(0, 2, 5); + EXIImm(0, &etcmd, sizeof(etcmd), EXI_WRITE, NULL); + EXISync(0); + EXIDma(0, tmppool0, length, EXI_READ, recvlen1 != 0 ? &readbuffersub : &readbuffer1); +} + +static void readbuffersub(s32 chan, OSContext* context) { + u32 etcmd; + u32 length; + + length = OSRoundUp32B(recvlen1); + EXIDeselect(0); + + etcmd = 0x80000000 | (0x0100 << 8); + EXISelect(0, 2, 5); + EXIImm(0, &etcmd, sizeof(etcmd), EXI_WRITE, NULL); + EXISync(0); + EXIDma(0, tmppool1, length, EXI_READ, readbuffer1); + __ETHInterruptTime = OSGetTime() - __OSLastInterruptTime; +} + +static void readbuffer1(s32 chan, OSContext* context) { + EXIDeselect(0); + + DCInvalidateRange(tmppool0, OSRoundUp32B(recvlen0)); + if (recvlen1 != 0) { + DCInvalidateRange(tmppool1, OSRoundUp32B(recvlen1)); + } + + if (recvcallback1) { + memcpy(recvaddr, tmppool0, recvlen0); + if (recvlen1 != 0) { + memcpy(recvaddr + recvlen0, tmppool1, recvlen1); + } + __ETHFilter(recvaddr, d2.packetlength); + (*recvcallback1)(recvaddr, d2.packetlength); + } + + rrp = d2.nextpacket; + rwp = readcmd16(0x16); + recvsub1(); + __ETHInterruptTime = OSGetTime() - __OSLastInterruptTime; +} + +#include + +static void patchthru(void) { + u32 rnda; + u32 fa; + + writeEXIcmd(0x05, __acstart); + readEXIcmdLong(0x08, &rnda, sizeof(rnda)); + fa = hashfunc(rnda); + writeEXIcmdLong(0x09, &fa, sizeof(fa)); +} + +static void exiinthandler(s32 chan, OSContext* context) { + u8 ir; + u8 exiisr; + BOOL ret; + BOOL sendcbflag; + u8 ltps; + u8 lrps; + u8 result; + void (*callback)(u8); + + sendcbflag = FALSE; + ret = EXILock(0, 2, &exiinthandler); + if (ret != FALSE) { + exiisr = readEXIcmd(0x03); + writeEXIcmd(0x02, 0x00); + + switch (__cntlzw(exiisr)) { + case 0x18: { + writeEXIcmd(0x03, 0x80); + break; + } + + case 0x1A: { + writeEXIcmd(0x03, 0x20); + writeEXIcmd(0x02, 0xF8); + unlock(); + #ifdef DEBUG + OSPanic(__FILE__, 765, "exi cmderr\n"); + #endif + return; + } + + case 0x19: { + writeEXIcmd(0x03, 0x40); + writeEXIcmd(0x02, 0xF8); + unlock(); + return; + } + + case 0x1B: { + patchthru(); + writeEXIcmd(0x03, 0x10); + writeEXIcmd(0x02, 0xF8); + unlock(); + return; + } + + case 0x1C: { + result = readEXIcmd(0x0B); + writeEXIcmd(0x03, 0x08); + writeEXIcmd(0x02, 0xF8); + unlock(); + + if (result != 1) { + #ifdef DEBUG + OSPanic(__FILE__, 785, "ETHLIB: hash func error\n"); + #endif + } + + return; + } + } + + ir = readcmd(0x0009); + if (__recvpriorityflag == TRUE && (ir & 2) != 0) { + ethstat.rcvcount++; + recvsub0(); + __ETHInterruptTime = OSGetTime() - __OSLastInterruptTime; + } else { + switch (__cntlzw(ir)) { + case 0x18: { + ethstat.rbf++; + writecmd(0x0009, 0x80); + break; + } + + case 0x19: { + writecmd(0x0009, 0x40); + break; + } + + case 0x1A: { + ethstat.fifoe++; + writecmd(0x0009, 0x20); + break; + } + + case 0x1B: { + ethstat.te++; + //ASSERTLINE(816, __sendbusy); + __sendbusy = FALSE; + ltps = readcmd(0x0004); + + if ((ltps & 0x10) != 0) { + ethstat.tx_crs++; + } + + if ((ltps & 0x20) != 0) { + ethstat.tx_uf++; + } + + if ((ltps & 0x40) != 0) { + ethstat.tx_owc++; + } + + sendcbflag = TRUE; + writecmd(0x0009, 0x10); + break; + } + + case 0x1C: { + ethstat.re++; + + lrps = readcmd(0x0005); + if ((lrps & 1) != 0) { + ethstat.rx_bf++; + } + + if ((lrps & 2) != 0) { + ethstat.rx_crc++; + } + + if ((lrps & 4) != 0) { + ethstat.rx_fae++; + } + + if ((lrps & 8) != 0) { + ethstat.rx_fo++; + } + + if ((lrps & 0x10) != 0) { + ethstat.rx_rw++; + } + + if ((lrps & 0x40) != 0) { + ethstat.rx_rf++; + } + + writecmd(0x0009, 0x08); + break; + } + + case 0x1D: { + //ASSERTLINE(868, __sendbusy); + ethstat.sendcount++; + __sendbusy = FALSE; + sendcbflag = TRUE; + ltps = readcmd(0x0004); + writecmd(0x0009, 0x04); + break; + } + + case 0x1E: { + ethstat.rcvcount++; + recvsub0(); + return; + } + + case 0x1F: { + ethstat.cntof++; + writecmd(0x0009, 0x01); + break; + } + } + + writeEXIcmd(0x02, 0xF8); + unlock(); + + if (sendcbflag) { + callback = __sendcallback; + __sendcallback = NULL; + __ETHPostSend(ltps, callback, __sendadr); + } + + __ETHInterruptTime = OSGetTime() - __OSLastInterruptTime; + } + } +} + +s32 ETHInit(s32 mode) { + static BOOL initialized = FALSE; + u32 cid; + u8 fcsr; + u8 phy0r; + + if (initialized == FALSE) { + initialized = TRUE; + OSRegisterVersion(__ETHVersion); + } + + OSInitThreadQueue(&threadQ); + __SIRegs[15] = __SIRegs[15] & ~0x80000000; // turn on 32MHz EXI clock setting allowance + waitexilock(); + __sendbusy = FALSE; + memset(ðstat, 0, sizeof(ethstat)); + protoarray = NULL; + protonum = 0; + recvcallback0 = NULL; + recvcallback1 = NULL; + + cid = 0; + EXIGetID(0, 2, &cid); + if (cid != EXI_ETHER) { + unlock(); + OSReport("cid = %08x\n", cid); + return -1; + } else { + reset(); + readcmdLong(0x0020, private_macaddr, sizeof(private_macaddr)); + __revid = readEXIcmd(0x01); + writeEXIcmdLong(0x04, &__devid, sizeof(__devid)); + writeEXIcmd(0x05, __acstart); + + fcsr = readcmd(0x005B); + fcsr &= ~0x80; + writecmd(0x005B, fcsr); + writecmd(0x005E, 0x01); + + phy0r = readcmd(0x005C); + phy0r |= 0x04; + writecmd(0x005C, phy0r); + + writecmd(0x0001, 0x00); + writecmd(0x0003, 0x2E); + writecmd(0x0050, 0x80); + writecmd(0x0008, 0x00); + writeEXIcmd(0x02, 0xF8); + EXISetExiCallback(2, (EXICallback)&exiinthandler); + unlock(); + + return ETH_OK; + } +} + +void ETHSendAsync(void* addr, s32 length, void (*callback2)(u8)) { + BOOL disabled; + + //ASSERTLINE(985, !__sendbusy); + //ASSERTLINE(986, ((u32) addr % 32) == 0); + DCStoreRange(addr, length); + + disabled = OSDisableInterrupts(); + __sendbusy = TRUE; + __sendadr = addr; + __sendlen = length < 60 ? 60 : length; + __sendcallback = callback2; + sendUpdate = TRUE; + + if (lock()) { + unlock(); + } + + OSRestoreInterrupts(disabled); +} + +static void sendsub0(void) { + u32 etcmd; + + __senddmalen = OSRoundDown32B(__sendlen); + __sendimmlen = __sendlen - __senddmalen; + + etcmd = 0xC0000000 | (0x0048 << 8); + EXISelect(0, 2, 5); + EXIImm(0, &etcmd, sizeof(etcmd), EXI_WRITE, NULL); + EXISync(0); + EXIDma(0, __sendadr, __senddmalen, EXI_WRITE, &sendsub1); +} + +static void sendsub1(s32 chan, OSContext* context) { + u8 ncra; + + if (__sendimmlen != 0) { + EXIImmEx(0, __sendadr + __senddmalen, __sendimmlen, EXI_WRITE); + } + + EXIDeselect(0); + ncra = readcmd(0x0000); + //ASSERTLINE(1033, (ncra & ME_NCRA_TXFIFO) == 0); + ncra |= ME_NCRA_TXFIFO; + writecmd(0x0000, ncra); + unlock(); +} + +void ETHGetMACAddr(u8* macaddr) { + memcpy(macaddr, private_macaddr, sizeof(private_macaddr)); +} + +void ETHSetMACAddr(u8* macaddr) { + memcpy(private_macaddr, macaddr, sizeof(private_macaddr)); + waitexilock(); + writecmdLong(0x0020, private_macaddr, sizeof(private_macaddr)); + unlock(); +} + +void ETHSetRecvCallback(void* (*cb0)(u16, s32, u8), void (*cb1)(u8*, s32)) { + BOOL disabled; + + disabled = OSDisableInterrupts(); + recvcallback0 = cb0; + recvcallback1 = cb1; + recvcallbackUpdate = TRUE; + + if (lock()) { + unlock(); + } + + OSRestoreInterrupts(disabled); +} + +static BOOL linkState(void) { + u8 nways; + + nways = readcmd(0x0031); + if ((nways & 1) != 0 || (nways & 2) != 0) { + return TRUE; + } + + return FALSE; +} + +static BOOL ETHGetLinkState(void) { + BOOL ret; + + waitexilock(); + ret = linkState(); + unlock(); + return ret; +} + +static BOOL linkStateAsyncMain(BOOL* linkstateptr) { + if (EXILock(0, 2, NULL)) { + *linkstateptr = linkState(); + unlock(); + return TRUE; + } + + return FALSE; +} + +BOOL ETHGetLinkStateAsync(BOOL* status) { + //ASSERTLINE(1104, status); + return linkStateAsyncMain(status); +} + +s32 ETHGetNWAYMode(void) { + u8 nways; + + waitexilock(); + nways = readcmd(0x0031); + unlock(); + + if ((nways & 0x10) != 0) { + return 1; + } + + if ((nways & 0x20) != 0) { + return 2; + } + + if ((nways & 0x40) != 0) { + return 3; + } + + if ((nways & 0x80) != 0) { + return 4; + } + + return 5; +} + +void ETHSetProtoType(u16* array, s32 num) { + BOOL flag; + + //ASSERTLINE(1139, (num != 0 && array != NULL) || (num == 0 && array == NULL)); + flag = OSDisableInterrupts(); + protoarray = array; + protonum = num; + OSRestoreInterrupts(flag); +} + +void ETHGetStatus(ETHStat* stat) { + BOOL flag; + + //ASSERTLINE(1150, stat); + flag = OSDisableInterrupts(); + *stat = ethstat; + OSRestoreInterrupts(flag); +} + +s32 ETHGetLibraryVersion(void) { + return 0x506; +} + +s32 ETHGetBBAType(void) { + return 2; +} + +static u16 HashIndex(const u8* address) { + u32 crc; + u16 index; + u32 msb; + u8 byte; + s32 byteLen; + s32 bit; + s32 shift; + + crc = 0xFFFFFFFF; + index = 0; + + for (byteLen = 0; byteLen < 6; byteLen++, address++) { + byte = *address; + bit = 0; + for (bit = 0; bit < 8; bit++, byte >>= 1) { + msb = (crc >> 31) & 1; + crc = crc << 1; + + if (msb ^ (byte & 1)) { + crc ^= 0x04C11DB6; + crc |= 1; + } + } + } + + bit = 31; + for (shift = 5; shift >= 0; shift--, bit--) { + index |= ((crc >> bit) & 1) << shift; + } + + return index; +} + +void ETHAddMulticastAddress(const u8* macaddr) { + BOOL disabled; + u16 index; + u8 marNo; + u8 bitNo; + u8 ncrb; + + if (memcmp(macaddr, broadcastheader, sizeof(broadcastheader)) == 0) { + waitexilock(); + ncrb = readcmd(0x0001); + ncrb |= 4; + writecmd(0x0001, ncrb); + unlock(); + } else { + index = HashIndex(macaddr); + marNo = index / 8; + bitNo = index % 8; + disabled = OSDisableInterrupts(); + mcastmap[marNo] |= 1 << bitNo; + mcastUpdate = TRUE; + + if (lock()) { + unlock(); + } + + OSRestoreInterrupts(disabled); + } +} + +void ETHChangeIntPriority(BOOL flag) { + __recvpriorityflag = flag; +} + +u32 ETHGetREVID(void) { + u32 revid; + + waitexilock(); + revid = readEXIcmd(0x01); + unlock(); + return revid; +} + +void ETHClearMulticastAddresses(void) { + BOOL disabled; + + disabled = OSDisableInterrupts(); + memset(mcastmap, 0, sizeof(mcastmap)); + mcastUpdate = TRUE; + if (lock()) { + unlock(); + } + OSRestoreInterrupts(disabled); +} + +static void unlockcallback(s32 chan, OSContext* context) { + if (lock()) { + unlock(); + } +} + +static BOOL lock() { + return EXILock(0, 2, &unlockcallback); +} + +static void unlock(void) { + BOOL disabled; + + disabled = OSDisableInterrupts(); + + if (mcastUpdate) { + mcastUpdate = FALSE; + writecmdLong(0x0026, mcastmap, sizeof(mcastmap)); + } + + if (recvcallbackUpdate) { + recvcallbackUpdate = FALSE; + + if (recvcallback0 == NULL) { + writecmd(0x0000, 0x00); + writecmd(0x0008, 0x14); + } else { + //ASSERTLINE(1308, recvcallback0 != NULL && recvcallback1 != NULL); + writecmd(0x0008, 0xFF); + recvinit(); + } + } + + if (sendUpdate) { + sendUpdate = FALSE; + sendsub0(); + } else { + EXIUnlock(0); + if (lockUpdate) { + lockUpdate = FALSE; + OSWakeupThread(&threadQ); + } + } + + OSRestoreInterrupts(disabled); +} diff --git a/libs/dolphin/eth/ethsec.c b/libs/dolphin/eth/ethsec.c new file mode 100644 index 000000000..b86953b5e --- /dev/null +++ b/libs/dolphin/eth/ethsec.c @@ -0,0 +1,344 @@ +#include +#include +#include +#include +#include + +#include + +#define IP_MIN_HLEN (s32)sizeof(IPHeader) +#define TCP_MIN_HLEN (s32)sizeof(TCPHeader) + +static TCPResetInfo Ri; +static u8 SendBuf[82]; +static const u8 NintendoAddr[6] = { 0,9,191,0,0,0 }; + +extern u32 __OSGetDIConfig(void); +vu16 __OSDeviceCode : (OS_BASE_CACHED | 0x30E6); + +static inline BOOL CheckConsoleType() { + if (__OSGetDIConfig() == 0xFF) { + switch (__OSDeviceCode) { + case 0x8200: { + return TRUE; + } + case 0x8001: { + if (OSGetPhysicalMemSize() == 0x3000000) { + return TRUE; + } + return FALSE; + } + } + return FALSE; + } + + if ((OSGetConsoleType() & OS_CONSOLE_MASK) == 0) { + return FALSE; + } + + return TRUE; +} + +static s16 AT_IP4_IsMyAddrMask(u8 val) { return 0; } + +/*static inline BOOL IPIsLocalAddr(u32, const u8 *addr) { + return AT_IP4_IsMyAddrMask(*addr) != -1; +}*/ + +static u16 CalcIpCheckSum(IPHeader *ip) { + int len; + u32 sum; + u16 *p; + + sum = 0; + len = (ip->verlen & 0xf) << 2; + p = (u16*)ip; + + while (len > 0) { + sum += *p++; + len -= 2; + } + + sum = (sum & 0xffff) + (sum >> 16); + sum = ((sum & 0xffff) + (sum >> 16)); + return sum ^ 0xffff; +} + +static u16 CalcTcpCheckSum(IPHeader *ip, s32 len) { + s32 hlen; + u16 *p; + u32 sum = 0; + +#line 212 + ASSERT(IP_MIN_HLEN + TCP_MIN_HLEN <= len); +#line 215 + ASSERT(ip->proto == IP_PROTO_TCP); + + hlen = (ip->verlen & 0xf) << 2; + sum += ((u16*)ip->src)[0]; + sum += ((u16*)ip->src)[1]; + sum += ((u16*)ip->dst)[0]; + sum += ((u16*)ip->dst)[1]; + sum += 6; + sum += (u32)len - (u32)hlen; + + p = (u16*)((u32)ip+hlen); + len = len - hlen; + while (len > 1) { + sum += *p++; + len -= 2; + } + + if (len == 1) { + sum += *((u8*)p) * 0x100; + } + + sum = (sum & 0xffff) + (sum >> 16); + sum = (sum & 0xffff) + (sum >> 16); + return sum ^ 0xffff; +} + +static s32 GetTcpSegLen(IPHeader *ip, TCPHeader *tcp) { + s32 len = ip->len - ((ip->verlen & 0xf) << 2) - (s32)(((tcp->flag & 0xf000) >> 10)); + + if (tcp->flag & 2) { + len += 1; + } + + if (tcp->flag & 1) { + len += 1; + } + + return len; +} + +static BOOL VerifyPacket(IPHeader *ip) { + if(ip->verlen >> 4 != 4 || ip->len < ((ip->verlen & 0xf) << 2)) { + return TRUE; + } + + if (CalcIpCheckSum(ip) != 0) { + return TRUE; + } + + if ((ip->dst[0] & 0xf0) == 0xe0 || (ip->src[0] & 0xf0) == 0xe0 || + (ip->dst[0] & 0xf8) == 0xf0 || (ip->src[0] & 0xf8) == 0xf0) { + return TRUE; + } + + ASSERT(ip->proto == IP_PROTO_TCP); + if (CalcTcpCheckSum(ip, ip->len) != 0) { + return TRUE; + } + + return FALSE; +} + +static void CalcDigest(u8 *digest, TCPHeader *tcp) { + MD5Context context; + u64 secret; + + MD5Init(&context); + MD5Update(&context,(u8*)&tcp->seq,sizeof(tcp->seq)); + MD5Update(&context,(u8*)&tcp->ack,sizeof(tcp->ack)); + + secret = ((tcp->seq ^ tcp->ack) * 0x5DEECE66Dll + 0xb) % 0x1000000000000ll; + MD5Update(&context,(u8 *)&secret + 2, sizeof(secret) - 2); + MD5Final(digest,&context); +} + +BOOL __ETHFilter(u8 *buf, s32 len) { + ETHHeader *eh; + IPHeader *ip; + TCPHeader *tcp; + TCPResetInfo *ri; + u8 digest1[16]; + u8 digest2[16]; + + ri = &Ri; + if (CheckConsoleType()) { + return TRUE; + } + + eh = (ETHHeader *)buf; + if (eh->type != 0x800) { + return TRUE; + } + + if (memcmp(eh->src, NintendoAddr, 3) == 0) { + return TRUE; + } + + len = len - sizeof(ETHHeader); + ip = (IPHeader *)(eh + 1); + if (len < IP_MIN_HLEN || len < ip->len) { + return TRUE; + } + + if(ip->proto != IP_PROTO_TCP) { + return TRUE; + } + + tcp = (TCPHeader *)((u32)ip + ((ip->verlen & 0xf) << 2)); + if ((s32)(((tcp->flag & 0xf000) >> 10)) < TCP_MIN_HLEN) { + return TRUE; + } + + if (ip->len < ((ip->verlen & 0xf) << 2) + (s32)(((tcp->flag & 0xf000) >> 10))) { + return TRUE; + } + + if ((tcp->flag & 3) == 2) { + switch(tcp->src) { + case 0x76c: + case 0x35: + return TRUE; + } + + switch (tcp->dst) { + case 0x76c: + return TRUE; + } + + if (IPIsLocalAddr(0, ip->src) == FALSE) { + return TRUE; + } + + if (tcp->flag & 4) { + return TRUE; + } + + if (VerifyPacket(ip)) { + return TRUE; + } + + if (ri->flag == 0) { + memmove(ri->addr, eh->src, sizeof(ri->addr)); + memmove(ri->dstAddr, ip->dst, sizeof(ri->dstAddr)); + memmove(ri->srcAddr, ip->src, sizeof(ri->dstAddr)); + ri->dstPort = tcp->dst; + ri->srcPort = tcp->src; + + if ((tcp->flag & 0x10) == 0) { + ri->seq = 0; + ri->ack = tcp->seq + GetTcpSegLen(ip, tcp); + ri->flag = (0x10 | 0x2 | 0x1); + } + else { + ri->seq = tcp->ack; + ri->ack = 0; + ri->flag = (0x2 | 0x1); + } + ri->id = 0; + return TRUE; + } + ip->len = 0; + return FALSE; + } + + if ((tcp->flag & 3) == 3) { + if ((s32)(((tcp->flag & 0xf000) >> 10)) != TCP_MIN_HLEN) { + return TRUE; + } + + if (ip->len != 0x40) { + return TRUE; + } + + if (IPIsLocalAddr(0, ip->src) == FALSE) { + return TRUE; + } + + if (VerifyPacket(ip)) { + return TRUE; + } + + CalcDigest(digest1, tcp); + __IPDecodeFromBase64(tcp + 1, 0x18, digest2); + + if (memcmp(digest1, digest2, sizeof(digest1))) { + return TRUE; + } + ip->len = 0; + return FALSE; + } + return TRUE; +} + +BOOL __ETHPostSend(u8 ltps , void (*callback)(u8), void *prev) { + ETHHeader *eh; + IPHeader *ip; + TCPHeader *tcp; + TCPResetInfo *ri; + u8 digest[16]; + + ri = &Ri; + + if (ri->flag == 0) { + ri = NULL; + } + else if (prev != SendBuf) { + eh = prev; + ip = (IPHeader *)(eh + 1); + tcp = (TCPHeader *)(ip + 1); + if (*((u32*)ip->dst) == *((u32*)ri->srcAddr) && *((u32*)ip->src) == *((u32*)ri->dstAddr) + && tcp->src == ri->dstPort && tcp->dst == ri->srcPort) { + + if (tcp->flag & 4) { + ri->flag = 0; + ri = NULL; + } + else { + ri->seq = tcp->seq + GetTcpSegLen(ip, tcp); + ri->ack = tcp->ack; + ri->flag |= tcp->flag & 0x10; + + ri->id = ip->id - 0x4000; + if (ri->id == 0) { + ri->id = 1; + } + } + } + } + + if (ri != NULL && ri->id != 0) { + eh = (ETHHeader *)SendBuf; + ip = (IPHeader *)(eh + 1); + eh->type = 0x800; + memmove(SendBuf, ri, 6); + ETHGetMACAddr(eh->src); + + ip->verlen = 0x45; + ip->tos = 0; + ip->len = 0x40; + ip->id = ri->id; + ip->frag = 0x4000; + ip->ttl = 0xff; + ip->proto = IP_PROTO_TCP; + ip->sum = 0; + memmove(ip->dst, ri->srcAddr, sizeof(ip->dst)); + memmove(ip->src, ri->dstAddr, sizeof(ip->src)); + + + tcp = (TCPHeader *)((u32)ip + ((ip->verlen & 0xf) << 2)); + tcp->src = ri->dstPort; + tcp->dst = ri->srcPort; + tcp->seq = ri->seq; + tcp->ack = ri->ack; + tcp->flag = ri->flag & 0x3f | 0x5000; + tcp->win = 0; + tcp->sum = 0; + tcp->urg = 0; + + CalcDigest(digest, tcp); + __IPEncodeToBase64(digest, sizeof(digest), tcp + 1); + ip->sum = CalcIpCheckSum(ip); + tcp->sum = CalcTcpCheckSum(ip, ip->len); + ri->flag = 0; + ETHSendAsync(SendBuf, 0x4e, callback); + } + else if (callback) { + (*callback)(ltps); + } + return ETH_OK; +} diff --git a/libs/dolphin/eth/md5.c b/libs/dolphin/eth/md5.c new file mode 100644 index 000000000..11c6c616d --- /dev/null +++ b/libs/dolphin/eth/md5.c @@ -0,0 +1,285 @@ +/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + rights reserved. + + License to copy and use this software is granted provided that it + is identified as the "RSA Data Security, Inc. MD5 Message-Digest + Algorithm" in all material mentioning or referencing this software + or this function. + + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD5 Message-Digest Algorithm" in all material + mentioning or referencing the derived work. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + */ + +#include +#include + +/* Constants for MD5Transform routine. + */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +static void MD5Transform (u32 state[4], u8 block[64]); +static void Encode(u8* output, u32* input, u32 len); +static void Decode(u32* output, u8* input, u32 len); + +static u8 PADDING[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* F, G, H and I are basic MD5 functions. + */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. + */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +Rotation is separate from addition to prevent recomputation. + */ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (u32)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (u32)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (u32)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (u32)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +/* MD5 initialization. Begins an MD5 operation, writing a new context. + */ +void MD5Init(MD5_CTX *context) +/* context: context */ +{ + context->count[0] = context->count[1] = 0; + /* Load magic initialization constants. */ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* MD5 block update operation. Continues an MD5 message-digest + operation, processing another message block, and updating the + context. + */ +void MD5Update(MD5_CTX *context, u8 *input, u32 inputLen) +/* context: context */ +/* input: input block */ +/* inputlen: length of input block */ +{ + u32 i, index, partLen; + + /* Compute number of bytes mod 64 */ + index = (u32)((context->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + if ((context->count[0] += ((u32)inputLen << 3)) < ((u32)inputLen << 3)) + context->count[1]++; + context->count[1] += ((u32)inputLen >> 29); + partLen = 64 - index; + + /* Transform as many times as possible. */ + if (inputLen >= partLen) { + memcpy(&context->buffer[index], input, partLen); + MD5Transform(context->state, context->buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) { + MD5Transform (context->state, &input[i]); + } + + index = 0; + } else { + i = 0; + } + + /* Buffer remaining input */ + memcpy(&context->buffer[index], &input[i], inputLen - i); +} + +/* MD5 finalization. Ends an MD5 message-digest operation, writing the + the message digest and zeroizing the context. + */ +void MD5Final(u8 digest[16], MD5_CTX *context) +/* digest: message digest */ +/* context: context */ +{ + u8 bits[8]; + u32 index, padLen; + + /* Save number of bits */ + Encode (bits, context->count, 8); + + /* Pad out to 56 mod 64. */ + index = (u32)((context->count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + MD5Update (context, PADDING, padLen); + + /* Append length (before padding) */ + MD5Update (context, bits, 8); + + /* Store state in digest */ + Encode (digest, context->state, 16); + + /* Zeroize sensitive information. */ + memset(context, 0, sizeof(*context)); +} + +/* MD5 basic transformation. Transforms state based on block. + */ +static void MD5Transform (u32 state[4], u8 block[64]) +{ + u32 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode (x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information. */ + memset(x, 0, sizeof(x)); +} + +/* Encodes input (u32) into output (u8). Assumes len is + a multiple of 4. + */ +static void Encode(u8* output, u32* input, u32 len) +{ + u32 i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (u8)(input[i] & 0xff); + output[j+1] = (u8)((input[i] >> 8) & 0xff); + output[j+2] = (u8)((input[i] >> 16) & 0xff); + output[j+3] = (u8)((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (u8) into output (u32). Assumes len is + a multiple of 4. + */ +static void Decode(u32* output, u8* input, u32 len) +{ + u32 i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((u32)input[j]) | (((u32)input[j+1]) << 8) | + (((u32)input[j+2]) << 16) | (((u32)input[j+3]) << 24); +} diff --git a/libs/dolphin/exi/EXIBios.c b/libs/dolphin/exi/EXIBios.c new file mode 100644 index 000000000..66653a0a9 --- /dev/null +++ b/libs/dolphin/exi/EXIBios.c @@ -0,0 +1,854 @@ +#include "dolphin/os.h" +#include "dolphin/hw_regs.h" + +static const char *__EXIVersion = + "<< Dolphin SDK - EXI\trelease build: Apr 17 2003 12:33:17 (0x2301) >>"; + +#define MAX_DEV 3 +#define MAX_CHAN 3 + +#define REG_MAX 5 +#define REG(chan, idx) (__EXIRegs[((chan)*REG_MAX) + (idx)]) + +#define STATE_IDLE 0x00 +#define STATE_DMA 0x01 +#define STATE_IMM 0x02 +#define STATE_BUSY (STATE_DMA | STATE_IMM) +#define STATE_SELECTED 0x04 +#define STATE_ATTACHED 0x08 +#define STATE_LOCKED 0x10 + +#define EXI_0CR(tstart, dma, rw, tlen) \ + ((((u32)(tstart)) << 0) | (((u32)(dma)) << 1) | (((u32)(rw)) << 2) | (((u32)(tlen)) << 4)) + +#define CPR_CS(x) ((1u << (x)) << 7) +#define CPR_CLK(x) ((x) << 4) + +typedef struct EXIControl +{ + EXICallback exiCallback; + EXICallback tcCallback; + EXICallback extCallback; + vu32 state; + int immLen; + u8 *immBuf; + u32 dev; + u32 id; + s32 idTime; + int items; + struct + { + u32 dev; + EXICallback callback; + } queue[MAX_DEV]; +} EXIControl; + +static EXIControl Ecb[MAX_CHAN]; +static u32 IDSerialPort1; +s32 __EXIProbeStartTime[2] : (OS_BASE_CACHED | 0x30C0); + +#pragma scheduling off + +static void SetExiInterruptMask(s32 chan, EXIControl *exi) +{ + EXIControl *exi2; + + exi2 = &Ecb[2]; + switch (chan) + { + case 0: + if ((exi->exiCallback == 0 && exi2->exiCallback == 0) || (exi->state & STATE_LOCKED)) + { + __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_2_EXI); + } + else + { + __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_2_EXI); + } + break; + case 1: + if (exi->exiCallback == 0 || (exi->state & STATE_LOCKED)) + { + __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXI); + } + else + { + __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXI); + } + break; + case 2: + if (__OSGetInterruptHandler(__OS_INTERRUPT_PI_DEBUG) == 0 || (exi->state & STATE_LOCKED)) + { + __OSMaskInterrupts(OS_INTERRUPTMASK_PI_DEBUG); + } + else + { + __OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_DEBUG); + } + break; + } +} + +static void CompleteTransfer(s32 chan) +{ + EXIControl *exi = &Ecb[chan]; + u8 *buf; + u32 data; + int i; + int len; + + if (exi->state & STATE_BUSY) + { + if ((exi->state & STATE_IMM) && (len = exi->immLen)) + { + buf = exi->immBuf; + data = REG(chan, 4); + for (i = 0; i < len; i++) + { + *buf++ = (u8)((data >> ((3 - i) * 8)) & 0xff); + } + } + exi->state &= ~STATE_BUSY; + } +} + +BOOL EXIImm(s32 chan, void *buf, s32 len, u32 type, EXICallback callback) +{ + EXIControl *exi = &Ecb[chan]; + BOOL enabled; + + enabled = OSDisableInterrupts(); + if ((exi->state & STATE_BUSY) || !(exi->state & STATE_SELECTED)) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + + exi->tcCallback = callback; + if (exi->tcCallback) + { + EXIClearInterrupts(chan, FALSE, TRUE, FALSE); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_TC >> (3 * chan)); + } + + exi->state |= STATE_IMM; + + if (type != EXI_READ) + { + u32 data; + int i; + + data = 0; + for (i = 0; i < len; i++) + { + data |= ((u8 *)buf)[i] << ((3 - i) * 8); + } + REG(chan, 4) = data; + } + + exi->immBuf = buf; + exi->immLen = (type != EXI_WRITE) ? len : 0; + + REG(chan, 3) = EXI_0CR(1, 0, type, len - 1); + + OSRestoreInterrupts(enabled); + + return TRUE; +} + +BOOL EXIImmEx(s32 chan, void *buf, s32 len, u32 mode) +{ + s32 xLen; + + while (len) + { + xLen = (len < 4) ? len : 4; + if (!EXIImm(chan, buf, xLen, mode, NULL)) + { + return FALSE; + } + + if (!EXISync(chan)) + { + return FALSE; + } + + (u8 *)buf += xLen; + len -= xLen; + } + return TRUE; +} + +BOOL EXIDma(s32 chan, void *buf, s32 len, u32 type, EXICallback callback) +{ + EXIControl *exi = &Ecb[chan]; + BOOL enabled; + + enabled = OSDisableInterrupts(); + if ((exi->state & STATE_BUSY) || !(exi->state & STATE_SELECTED)) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + + exi->tcCallback = callback; + if (exi->tcCallback) + { + EXIClearInterrupts(chan, FALSE, TRUE, FALSE); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_TC >> (3 * chan)); + } + + exi->state |= STATE_DMA; + + REG(chan, 1) = (u32)buf & 0x3ffffe0; + REG(chan, 2) = (u32)len; + REG(chan, 3) = EXI_0CR(1, 1, type, 0); + + OSRestoreInterrupts(enabled); + + return TRUE; +} + +extern u32 __OSGetDIConfig(void); + +vu16 __OSDeviceCode : (OS_BASE_CACHED | 0x30E6); + +BOOL EXISync(s32 chan) +{ + EXIControl *exi = &Ecb[chan]; + BOOL rc = FALSE; + BOOL enabled; + + while (exi->state & STATE_SELECTED) + { + if (((REG(chan, 3) & 1) >> 0) == 0) + { + enabled = OSDisableInterrupts(); + if (exi->state & STATE_SELECTED) + { + CompleteTransfer(chan); + if (__OSGetDIConfig() != 0xff || ((OSGetConsoleType() & OS_CONSOLE_MASK) == OS_CONSOLE_TDEV) || exi->immLen != 4 || + (REG(chan, 0) & 0x00000070) != (EXI_FREQ_1M << 4) || + (REG(chan, 4) != EXI_USB_ADAPTER && REG(chan, 4) != EXI_IS_VIEWER && + REG(chan, 4) != 0x04220001) || + __OSDeviceCode == 0x8200) + { + rc = TRUE; + } + } + OSRestoreInterrupts(enabled); + break; + } + } + return rc; +} + +u32 EXIClearInterrupts(s32 chan, BOOL exi, BOOL tc, BOOL ext) +{ + u32 cpr; + u32 prev; + + prev = cpr = REG(chan, 0); + cpr &= 0x7f5; + if (exi) + cpr |= 2; + if (tc) + cpr |= 8; + if (ext) + cpr |= 0x800; + REG(chan, 0) = cpr; + return prev; +} + +EXICallback EXISetExiCallback(s32 chan, EXICallback exiCallback) +{ + EXIControl *exi = &Ecb[chan]; + EXICallback prev; + BOOL enabled; + + enabled = OSDisableInterrupts(); + prev = exi->exiCallback; + exi->exiCallback = exiCallback; + + if (chan != 2) + { + SetExiInterruptMask(chan, exi); + } + else + { + SetExiInterruptMask(0, &Ecb[0]); + } + + OSRestoreInterrupts(enabled); + return prev; +} + +void EXIProbeReset(void) +{ + __EXIProbeStartTime[0] = __EXIProbeStartTime[1] = 0; + Ecb[0].idTime = Ecb[1].idTime = 0; + __EXIProbe(0); + __EXIProbe(1); +} + +static BOOL __EXIProbe(s32 chan) +{ + EXIControl *exi = &Ecb[chan]; + BOOL enabled; + BOOL rc; + u32 cpr; + s32 t; + + if (chan == 2) + { + return TRUE; + } + + rc = TRUE; + enabled = OSDisableInterrupts(); + cpr = REG(chan, 0); + if (!(exi->state & EXI_STATE_ATTACHED)) + { + if (cpr & 0x00000800) + { + EXIClearInterrupts(chan, FALSE, FALSE, TRUE); + __EXIProbeStartTime[chan] = exi->idTime = 0; + } + + if (cpr & 0x00001000) + { + t = (s32)(OSTicksToMilliseconds(OSGetTime()) / 100) + 1; + if (__EXIProbeStartTime[chan] == 0) + { + __EXIProbeStartTime[chan] = t; + } + if (t - __EXIProbeStartTime[chan] < 300 / 100) + { + rc = FALSE; + } + } + else + { + __EXIProbeStartTime[chan] = exi->idTime = 0; + rc = FALSE; + } + } + else if (!(cpr & 0x00001000) || (cpr & 0x00000800)) + { + __EXIProbeStartTime[chan] = exi->idTime = 0; + rc = FALSE; + } + OSRestoreInterrupts(enabled); + + return rc; +} + +BOOL EXIProbe(s32 chan) +{ + EXIControl *exi = &Ecb[chan]; + BOOL rc; + u32 id; + + rc = __EXIProbe(chan); + if (rc && exi->idTime == 0) + { + rc = EXIGetID(chan, 0, &id) ? TRUE : FALSE; + } + return rc; +} + +s32 EXIProbeEx(s32 chan) +{ + if (EXIProbe(chan)) + { + return 1; + } + else if (__EXIProbeStartTime[chan] != 0) + { + return 0; + } + else + { + return -1; + } +} + +static BOOL __EXIAttach(s32 chan, EXICallback extCallback) +{ + EXIControl *exi = &Ecb[chan]; + BOOL enabled; + + enabled = OSDisableInterrupts(); + if ((exi->state & EXI_STATE_ATTACHED) || __EXIProbe(chan) == FALSE) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + + EXIClearInterrupts(chan, TRUE, FALSE, FALSE); + + exi->extCallback = extCallback; + __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT >> (3 * chan)); + exi->state |= STATE_ATTACHED; + OSRestoreInterrupts(enabled); + + return TRUE; +} + +BOOL EXIAttach(s32 chan, EXICallback extCallback) +{ + EXIControl *exi = &Ecb[chan]; + BOOL enabled; + BOOL rc; + + EXIProbe(chan); + + enabled = OSDisableInterrupts(); + if (exi->idTime == 0) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + rc = __EXIAttach(chan, extCallback); + OSRestoreInterrupts(enabled); + return rc; +} + +BOOL EXIDetach(s32 chan) +{ + EXIControl *exi = &Ecb[chan]; + BOOL enabled; + + enabled = OSDisableInterrupts(); + if (!(exi->state & STATE_ATTACHED)) + { + OSRestoreInterrupts(enabled); + return TRUE; + } + if ((exi->state & STATE_LOCKED) && exi->dev == 0) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + + exi->state &= ~STATE_ATTACHED; + __OSMaskInterrupts((OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_0_EXI) >> (3 * chan)); + OSRestoreInterrupts(enabled); + return TRUE; +} + +BOOL EXISelect(s32 chan, u32 dev, u32 freq) +{ + EXIControl *exi = &Ecb[chan]; + u32 cpr; + BOOL enabled; + + enabled = OSDisableInterrupts(); + if ((exi->state & STATE_SELECTED) || + chan != 2 && (dev == 0 && !(exi->state & STATE_ATTACHED) && !__EXIProbe(chan) || + !(exi->state & STATE_LOCKED) || (exi->dev != dev))) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + + exi->state |= STATE_SELECTED; + cpr = REG(chan, 0); + cpr &= 0x405; + cpr |= CPR_CS(dev) | CPR_CLK(freq); + REG(chan, 0) = cpr; + + if (exi->state & STATE_ATTACHED) + { + switch (chan) + { + case 0: + __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT); + break; + case 1: + __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXT); + break; + } + } + + OSRestoreInterrupts(enabled); + return TRUE; +} + +BOOL EXIDeselect(s32 chan) +{ + EXIControl *exi = &Ecb[chan]; + u32 cpr; + BOOL enabled; + + enabled = OSDisableInterrupts(); + if (!(exi->state & STATE_SELECTED)) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + exi->state &= ~STATE_SELECTED; + cpr = REG(chan, 0); + REG(chan, 0) = cpr & 0x405; + + if (exi->state & STATE_ATTACHED) + { + switch (chan) + { + case 0: + __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT); + break; + case 1: + __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXT); + break; + } + } + + OSRestoreInterrupts(enabled); + + if (chan != 2 && (cpr & CPR_CS(0))) + { + return __EXIProbe(chan) ? TRUE : FALSE; + } + + return TRUE; +} + +static void EXIIntrruptHandler(__OSInterrupt interrupt, OSContext *context) +{ + s32 chan; + EXIControl *exi; + EXICallback callback; + + chan = (interrupt - __OS_INTERRUPT_EXI_0_EXI) / 3; + exi = &Ecb[chan]; + EXIClearInterrupts(chan, TRUE, FALSE, FALSE); + callback = exi->exiCallback; + if (callback) + { + OSContext exceptionContext; + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + callback(chan, context); + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } +} + +static void TCIntrruptHandler(__OSInterrupt interrupt, OSContext *context) +{ + OSContext exceptionContext; + s32 chan; + EXIControl *exi; + EXICallback callback; + + chan = (interrupt - __OS_INTERRUPT_EXI_0_TC) / 3; + exi = &Ecb[chan]; + __OSMaskInterrupts(OS_INTERRUPTMASK(interrupt)); + EXIClearInterrupts(chan, FALSE, TRUE, FALSE); + callback = exi->tcCallback; + if (callback) + { + exi->tcCallback = 0; + CompleteTransfer(chan); + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + callback(chan, context); + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } +} + +static void EXTIntrruptHandler(__OSInterrupt interrupt, OSContext *context) +{ + s32 chan; + EXIControl *exi; + EXICallback callback; + + chan = (interrupt - __OS_INTERRUPT_EXI_0_EXT) / 3; + __OSMaskInterrupts((OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_0_EXI) >> (3 * chan)); + exi = &Ecb[chan]; + callback = exi->extCallback; + exi->state &= ~STATE_ATTACHED; + if (callback) + { + OSContext exceptionContext; + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + exi->extCallback = 0; + callback(chan, context); + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } +} + +void EXIInit(void) +{ + u32 id; + while (((REG(0, 3) & 0x1) == 1) || ((REG(1, 3) & 0x1) == 1) || ((REG(2, 3) & 0x1) == 1)) { + continue; + } + + __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_0_TC | OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_1_EXI + | OS_INTERRUPTMASK_EXI_1_TC | OS_INTERRUPTMASK_EXI_1_EXT | OS_INTERRUPTMASK_EXI_2_EXI | OS_INTERRUPTMASK_EXI_2_TC); + + REG(0, 0) = 0; + REG(1, 0) = 0; + REG(2, 0) = 0; + + REG(0, 0) = 0x00002000; + + __OSSetInterruptHandler(__OS_INTERRUPT_EXI_0_EXI, EXIIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_EXI_0_TC, TCIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_EXI_0_EXT, EXTIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_EXI_1_EXI, EXIIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_EXI_1_TC, TCIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_EXI_1_EXT, EXTIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_EXI_2_EXI, EXIIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_EXI_2_TC, TCIntrruptHandler); + + 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, &id) && id == 0x07010000) { + __OSEnableBarnacle(1, 0); + } else if (EXIGetID(1, 0, &id) && id == 0x07010000) { + __OSEnableBarnacle(0, 2); + } + + OSRegisterVersion(__EXIVersion); +} + +BOOL EXILock(s32 chan, u32 dev, EXICallback unlockedCallback) +{ + EXIControl *exi = &Ecb[chan]; + BOOL enabled; + int i; + + enabled = OSDisableInterrupts(); + if (exi->state & STATE_LOCKED) + { + if (unlockedCallback) + { + for (i = 0; i < exi->items; i++) + { + if (exi->queue[i].dev == dev) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + } + exi->queue[exi->items].callback = unlockedCallback; + exi->queue[exi->items].dev = dev; + exi->items++; + } + OSRestoreInterrupts(enabled); + return FALSE; + } + + exi->state |= STATE_LOCKED; + exi->dev = dev; + SetExiInterruptMask(chan, exi); + + OSRestoreInterrupts(enabled); + return TRUE; +} + +BOOL EXIUnlock(s32 chan) +{ + EXIControl *exi = &Ecb[chan]; + BOOL enabled; + EXICallback unlockedCallback; + + enabled = OSDisableInterrupts(); + if (!(exi->state & STATE_LOCKED)) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + exi->state &= ~STATE_LOCKED; + SetExiInterruptMask(chan, exi); + + if (0 < exi->items) + { + unlockedCallback = exi->queue[0].callback; + if (0 < --exi->items) + { + memmove(&exi->queue[0], &exi->queue[1], sizeof(exi->queue[0]) * exi->items); + } + unlockedCallback(chan, 0); + } + + OSRestoreInterrupts(enabled); + return TRUE; +} + +u32 EXIGetState(s32 chan) +{ + EXIControl *exi = &Ecb[chan]; + + return (u32)exi->state; +} + +static void UnlockedHandler(s32 chan, OSContext *context) +{ + u32 id; + + EXIGetID(chan, 0, &id); +} + +s32 EXIGetID(s32 chan, u32 dev, u32* id) +{ + EXIControl* exi = &Ecb[chan]; + BOOL err; + u32 cmd; + s32 startTime; + BOOL enabled; + BOOL interrupt; + + if (chan == 0 && dev == 2 && IDSerialPort1) { + *id = IDSerialPort1; + return 1; + } + + if (chan < 2 && dev == 0) { + if (!__EXIProbe(chan)) { + return 0; + } + + if (exi->idTime == __EXIProbeStartTime[chan]) { + *id = exi->id; + return exi->idTime; + } + + if (!__EXIAttach(chan, NULL)) { + return 0; + } + startTime = __EXIProbeStartTime[chan]; + } + + interrupt = OSDisableInterrupts(); + err = !EXILock(chan, dev, (chan < 2 && dev == 0) ? UnlockedHandler : NULL); + if (!err) { + err = !EXISelect(chan, dev, EXI_FREQ_1M); + if (!err) { + cmd = 0; + err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, NULL); + err |= !EXISync(chan); + err |= !EXIImm(chan, id, 4, EXI_READ, NULL); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + } + EXIUnlock(chan); + } + OSRestoreInterrupts(interrupt); + + if (chan < 2 && dev == 0) { + EXIDetach(chan); + enabled = OSDisableInterrupts(); + err |= (startTime != __EXIProbeStartTime[chan]); + if (!err) { + exi->id = *id; + exi->idTime = startTime; + } + OSRestoreInterrupts(enabled); + + return err ? 0 : exi->idTime; + } + + return err ? 0 : !0; +} + +s32 EXIGetType(s32 chan, u32 dev, u32 *type) { + u32 _type; + s32 probe; + + probe = EXIGetID(chan, dev, &_type); + if(probe == 0) + return probe; + + switch(_type & 0xffffff00) + { + case 0x4020100: + case 0x4020200: + case 0x4020300: + case 0x4060000: + *type = _type & 0xffffff00; + return probe; + } + + switch(_type & 0xffff0000) + { + case 0: + { + if ((_type & 0x3803)) + break; + + switch (_type & 0xfc) + { + case 4: + case 8: + case 16: + case 32: + case 64: + case 128: + *type = _type & 0xfc; + return probe; + } + break; + } + case 0x5070000: + *type = 0x5070000; + return probe; + } + *type = _type; + return probe; +} + +char* EXIGetTypeString(u32 type) +{ + switch (type) { + case EXI_MEMORY_CARD_59: + return "Memory Card 59"; + case EXI_MEMORY_CARD_123: + return "Memory Card 123"; + case EXI_MEMORY_CARD_251: + return "Memory Card 251"; + case EXI_MEMORY_CARD_507: + return "Memory Card 507"; + case EXI_MEMORY_CARD_1019: + return "Memory Card 1019"; + case EXI_MEMORY_CARD_2043: + 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: + return "Net Card"; + case EXI_ETHER_VIEWER: + return "Artist Ether"; + case EXI_MODEM: + return "Broadband Adapter"; + case EXI_STREAM_HANGER: + return "Stream Hanger"; + case EXI_IS_VIEWER: + return "IS-DOL-VIEWER"; + } +} + +#pragma scheduling reset diff --git a/libs/dolphin/exi/EXIUart.c b/libs/dolphin/exi/EXIUart.c new file mode 100644 index 000000000..8e8734a1a --- /dev/null +++ b/libs/dolphin/exi/EXIUart.c @@ -0,0 +1,202 @@ +#include "dolphin/os.h" + +#define EXI_TX 0x800400u +#define EXI_MAGIC 0xa5ff005a + +static s32 Chan; +static u32 Dev; +static u32 Enabled = 0; +static u32 BarnacleEnabled = 0; + +static BOOL ProbeBarnacle(s32 chan, u32 dev, u32 *revision) +{ + BOOL err; + u32 cmd; + + if (chan != 2 && dev == 0 && !EXIAttach(chan, NULL)) + { + return FALSE; + } + + err = !EXILock(chan, dev, NULL); + if (!err) + { + err = !EXISelect(chan, dev, EXI_FREQ_1M); + if (!err) + { + cmd = 0x20011300; + err = FALSE; + err |= !EXIImm(chan, &cmd, 4, EXI_WRITE, NULL); + err |= !EXISync(chan); + err |= !EXIImm(chan, revision, 4, EXI_READ, NULL); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + } + EXIUnlock(chan); + } + + if (chan != 2 && dev == 0) + { + EXIDetach(chan); + } + + if (err) + { + return FALSE; + } + + return (*revision != 0xFFFFFFFF) ? TRUE : FALSE; +} + +void __OSEnableBarnacle(s32 chan, u32 dev) +{ + u32 id; + + if (EXIGetID(chan, dev, &id)) + { + switch (id) + { + case 0xffffffff: + case EXI_MEMORY_CARD_59: + case EXI_MEMORY_CARD_123: + case EXI_MEMORY_CARD_251: + case EXI_MEMORY_CARD_507: + case EXI_USB_ADAPTER: + case EXI_NPDP_GDEV: + case EXI_MODEM: + case EXI_MARLIN: + case 0x04220000: + case 0x04020100: + case 0x04020200: + case 0x04020300: + case 0x04040404: + case 0x04060000: + case 0x04120000: + case 0x04130000: + case 0x80000000 | EXI_MEMORY_CARD_59: + case 0x80000000 | EXI_MEMORY_CARD_123: + case 0x80000000 | EXI_MEMORY_CARD_251: + case 0x80000000 | EXI_MEMORY_CARD_507: + break; + default: + if (ProbeBarnacle(chan, dev, &id)) + { + Chan = chan; + Dev = dev; + Enabled = BarnacleEnabled = EXI_MAGIC; + } + break; + } + } +} + +u32 InitializeUART(u32 baudRate) +{ + if (BarnacleEnabled == EXI_MAGIC) + { + return 0; + } + + if (!(OSGetConsoleType() & OS_CONSOLE_DEVELOPMENT)) + { + Enabled = 0; + return 2; + } + else + { + Chan = 0; + Dev = 1; + Enabled = EXI_MAGIC; + return 0; + } +} + +u32 ReadUARTN(void *bytes, unsigned long length) { return 4; } + +static int QueueLength(void) +{ + u32 cmd; + + if (!EXISelect(Chan, Dev, EXI_FREQ_8M)) + return -1; + + cmd = EXI_TX << 6; + EXIImm(Chan, &cmd, 4, EXI_WRITE, NULL); + EXISync(Chan); + + EXIImm(Chan, &cmd, 1, EXI_READ, NULL); + EXISync(Chan); + EXIDeselect(Chan); + + return 16 - (int)((cmd >> 24) & 0xff); +} + +u32 WriteUARTN(const void *buf, unsigned long len) +{ + BOOL enabled; + u32 cmd; + int qLen; + long xLen; + char *ptr; + BOOL locked; + u32 error; + + if (Enabled != EXI_MAGIC) + return 2; + + enabled = OSDisableInterrupts(); + + locked = EXILock(Chan, Dev, 0); + if (!locked) + { + OSRestoreInterrupts(enabled); + return 0; + } + + for (ptr = (char *)buf; ptr - buf < len; ptr++) + { + if (*ptr == '\n') + *ptr = '\r'; + } + + error = 0; + cmd = (EXI_TX | 0x2000000) << 6; + while (len) + { + qLen = QueueLength(); + if (qLen < 0) + { + error = 3; + break; + } + + if (qLen < 12 && qLen < len) + continue; + + if (!EXISelect(Chan, Dev, EXI_FREQ_8M)) + { + error = 3; + break; + } + + EXIImm(Chan, &cmd, 4, EXI_WRITE, NULL); + EXISync(Chan); + + while (qLen && len) + { + if (qLen < 4 && qLen < len) + break; + xLen = (len < 4) ? (long)len : 4; + EXIImm(Chan, (void *)buf, xLen, EXI_WRITE, NULL); + (u8 *)buf += xLen; + len -= xLen; + qLen -= xLen; + EXISync(Chan); + } + EXIDeselect(Chan); + } + + EXIUnlock(Chan); + OSRestoreInterrupts(enabled); + return error; +} \ No newline at end of file diff --git a/libs/dolphin/gd/GDBase.c b/libs/dolphin/gd/GDBase.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gd/GDGeometry.c b/libs/dolphin/gd/GDGeometry.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXAttr.c b/libs/dolphin/gx/GXAttr.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXBump.c b/libs/dolphin/gx/GXBump.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXDisplayList.c b/libs/dolphin/gx/GXDisplayList.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXDraw.c b/libs/dolphin/gx/GXDraw.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXFifo.c b/libs/dolphin/gx/GXFifo.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXFrameBuf.c b/libs/dolphin/gx/GXFrameBuf.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXGeometry.c b/libs/dolphin/gx/GXGeometry.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXInit.c b/libs/dolphin/gx/GXInit.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXLight.c b/libs/dolphin/gx/GXLight.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXMisc.c b/libs/dolphin/gx/GXMisc.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXPerf.c b/libs/dolphin/gx/GXPerf.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXPixel.c b/libs/dolphin/gx/GXPixel.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXTev.c b/libs/dolphin/gx/GXTev.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXTexture.c b/libs/dolphin/gx/GXTexture.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXTransform.c b/libs/dolphin/gx/GXTransform.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/hio/hio.c b/libs/dolphin/hio/hio.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IFFifo.c b/libs/dolphin/ip/IFFifo.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IFRing.c b/libs/dolphin/ip/IFRing.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IP.c b/libs/dolphin/ip/IP.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPArp.c b/libs/dolphin/ip/IPArp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPChap.c b/libs/dolphin/ip/IPChap.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPDhcp.c b/libs/dolphin/ip/IPDhcp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPDns.c b/libs/dolphin/ip/IPDns.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPEther.c b/libs/dolphin/ip/IPEther.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPFrag.c b/libs/dolphin/ip/IPFrag.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPIcmp.c b/libs/dolphin/ip/IPIcmp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPIgmp.c b/libs/dolphin/ip/IPIgmp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPIpcp.c b/libs/dolphin/ip/IPIpcp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPLcp.c b/libs/dolphin/ip/IPLcp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPOpt.c b/libs/dolphin/ip/IPOpt.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPPPP.c b/libs/dolphin/ip/IPPPP.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPPPPoE.c b/libs/dolphin/ip/IPPPPoE.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPPap.c b/libs/dolphin/ip/IPPap.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPRoute.c b/libs/dolphin/ip/IPRoute.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPSocket.c b/libs/dolphin/ip/IPSocket.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPTcp.c b/libs/dolphin/ip/IPTcp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPTcpOutput.c b/libs/dolphin/ip/IPTcpOutput.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPTcpTimeWait.c b/libs/dolphin/ip/IPTcpTimeWait.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPTcpTimer.c b/libs/dolphin/ip/IPTcpTimer.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPTcpUser.c b/libs/dolphin/ip/IPTcpUser.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPUdp.c b/libs/dolphin/ip/IPUdp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPUuid.c b/libs/dolphin/ip/IPUuid.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPZero.c b/libs/dolphin/ip/IPZero.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/lg/allsrc.c b/libs/dolphin/lg/allsrc.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/mtx/mtx.c b/libs/dolphin/mtx/mtx.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/mtx/mtx44.c b/libs/dolphin/mtx/mtx44.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/mtx/mtx44vec.c b/libs/dolphin/mtx/mtx44vec.c new file mode 100644 index 000000000..2a12fbce9 --- /dev/null +++ b/libs/dolphin/mtx/mtx44vec.c @@ -0,0 +1,39 @@ +#include "dolphin/mtx.h" + +// TODO: cleanup, documentation, check other builds +void PSMTX44MultVec(register const Mtx44 m, register const Vec *src, register Vec *dst) +{ + // clang-format off + __asm { + psq_l f0, 0(src), 0, 0 + psq_l f2, 0x30(m), 0, 0 + psq_l f1, 8(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, 0(m), 0, 0 + ps_merge00 f13, f13, f13 + psq_l f5, 8(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, 0(dst), 0, 0 + ps_mul f3, f3, f13 + psq_st f3, 8(dst), 1, 0 + } + // clang-format on +} \ No newline at end of file diff --git a/libs/dolphin/mtx/mtxvec.c b/libs/dolphin/mtx/mtxvec.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/mtx/quat.c b/libs/dolphin/mtx/quat.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/mtx/vec.c b/libs/dolphin/mtx/vec.c new file mode 100644 index 000000000..17ba7c59e --- /dev/null +++ b/libs/dolphin/mtx/vec.c @@ -0,0 +1,262 @@ +#include "types.h" +#include "dolphin/mtx.h" + +#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 + +void C_VECAdd(void) +{ + // UNUSED FUNCTION +} + +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_VECSubtract(void) +{ + // UNUSED FUNCTION +} + +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 +} + +void C_VECScale(void) +{ + // UNUSED FUNCTION +} + +void PSVECScale(register const Vec *src, register Vec *dst, register f32 scale) +{ + // clang-format off + register f32 vxy, vz, rxy, rz; + __asm { + psq_l vxy, 0(src), 0, 0 + psq_l vz, 8(src), 1, 0 + ps_muls0 rxy, vxy, scale + psq_st rxy, 0(dst), 0, 0 + ps_muls0 rz, vz, scale + psq_st rz, 8(dst), 1, 0 + } + // clang-format on +} + +void C_VECNormalize(void) +{ + // UNUSED FUNCTION +} + +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 C_VECSquareMag(void) +{ + // UNUSED FUNCTION +} + +f32 PSVECSquareMag(const Vec *v) +{ + // UNUSED FUNCTION +} + +void C_VECMag(void) +{ + // UNUSED FUNCTION +} + +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; +} + +void C_VECDotProduct(void) +{ + // UNUSED FUNCTION +} + +ASM f32 PSVECDotProduct(register const Vec *a, register const Vec *b) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc; + psq_l f2, 4(a), 0, 0; + psq_l f3, 4(b), 0, 0; + ps_mul f2, f2, f3; + psq_l f5, 0(a), 0, 0; + psq_l f4, 0(b), 0, 0; + ps_madd f3, f5, f4, f2; + ps_sum0 R_RET, f3, f2, f2; + blr +#endif // clang-format on +} + +void C_VECCrossProduct(void) +{ + // UNUSED FUNCTION +} + +ASM void PSVECCrossProduct(const register Vec *vec1, const register Vec *vec2, register Vec *ret) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc; + psq_l fp1, 0(vec2), 0, 0 + lfs fp2, 8(vec1) + psq_l fp0, 0(vec1), 0, 0 + ps_merge10 fp6, fp1, fp1 + lfs fp3, 8(vec2) + ps_mul fp4, fp1, fp2 + ps_muls0 fp7, fp1, fp0 + ps_msub fp5, fp0, fp3, fp4 + ps_msub fp8, fp0, fp6, fp7 + ps_merge11 fp9, fp5, fp5 + ps_merge01 fp10, fp5, fp8 + psq_st fp9, 0(ret), 1, 0 + ps_neg fp10, fp10 + psq_st fp10, 4(ret), 0, 0 + blr; +#endif // clang-format on +} + +void C_VECHalfAngle(void) +{ + // UNUSED FUNCTION +} + +void C_VECReflect(void) +{ + // UNUSED FUNCTION +} + +void C_VECSquareDistance(void) +{ + // UNUSED FUNCTION +} + +f32 PSVECSquareDistance(const Vec *a, const Vec *b) +{ + // UNUSED FUNCTION +} + +void C_VECDistance(void) +{ + // UNUSED FUNCTION +} + +// TODO: cleanup? +ASM f32 PSVECDistance(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; + lfs f3, 0.5f; + + ps_madd f1, f0, f0, f2; + fsubs f0, f3, f3; + ps_sum0 f1, f1, f2, f2; + fcmpu cr0, f0, f1; + beq exit; + lfs f4, 3.0f; + frsqrte f0, f1; + fmuls f2, f0, f0; + fmuls f0, f0, f3; + fnmsubs f2, f2, f1, f4; + fmuls f0, f2, f0; + fmuls R_RET, f1, f0; +exit: + blr +#endif // clang-format on +} \ No newline at end of file diff --git a/libs/dolphin/odenotstub/odenotstub.c b/libs/dolphin/odenotstub/odenotstub.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/os/OS.c b/libs/dolphin/os/OS.c new file mode 100644 index 000000000..ca58c2c5b --- /dev/null +++ b/libs/dolphin/os/OS.c @@ -0,0 +1,678 @@ +#include "dolphin/os.h" +#include "dolphin/DVDPriv.h" +#include "dolphin/db.h" +#include "dolphin/os/OSBootInfo.h" +#include "macros.h" + +extern OSTime __OSGetSystemTime(); +static const char* __OSVersion = + "<< Dolphin SDK - OS\trelease build: Jul 23 2003 11:27:16 (0x2301) >>"; +// needs to be "<< Dolphin SDK - DSP\trelease build: Apr 17 2003 12:34:16 (0x2301) >>"? +extern char _db_stack_end[]; + +#define OS_BI2_DEBUG_ADDRESS 0x800000F4 +#define DEBUGFLAG_ADDR 0x800030E8 +#define OS_DEBUG_ADDRESS_2 0x800030E9 +#define OS_CURRENTCONTEXT_PADDR 0x00C0 + +extern char* __OSResetSWInterruptHandler[]; + +vu16 __OSDeviceCode : (OS_BASE_CACHED | 0x30E6); +static DVDDriveInfo DriveInfo ALIGN(32); +static DVDCommandBlock DriveBlock; + +static OSBootInfo* BootInfo; +static u32* BI2DebugFlag; +static u32* BI2DebugFlagHolder; +DECL_WEAK BOOL __OSIsGcam = FALSE; +static f64 ZeroF; +static f32 ZeroPS[2]; +static BOOL AreWeInitialized = FALSE; +static __OSExceptionHandler* OSExceptionTable; +OSTime __OSStartTime; +BOOL __OSInIPL; + +extern u8 __ArenaHi[]; +extern u8 __ArenaLo[]; +extern u32 __DVDLongFileNameFlag; +extern u32 __PADSpec; + +#define OS_EXCEPTIONTABLE_ADDR 0x3000 +#define OS_DBJUMPPOINT_ADDR 0x60 +// memory locations for important stuff +#define OS_CACHED_REGION_PREFIX 0x8000 +#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 MSR_RI_BIT 0x1E + +void OSDefaultExceptionHandler(__OSException exception, OSContext* context); +extern BOOL __DBIsExceptionMarked(__OSException); +static void OSExceptionInit(void); + +/* clang-format off */ +asm void __OSFPRInit(void) +{ + nofralloc + + mfmsr r3 + ori r3, r3, 0x2000 + mtmsr r3 + + mfspr r3, 0x398 + rlwinm. r3, r3, 3, 31, 31 + beq SkipPairedSingles + + lis r3, ZeroPS@ha + addi r3, r3, ZeroPS@l + psq_l fp0, 0(r3), 0, 0 + ps_mr fp1, fp0 + ps_mr fp2, fp0 + ps_mr fp3, fp0 + ps_mr fp4, fp0 + ps_mr fp5, fp0 + ps_mr fp6, fp0 + ps_mr fp7, fp0 + ps_mr fp8, fp0 + ps_mr fp9, fp0 + ps_mr fp10, fp0 + ps_mr fp11, fp0 + ps_mr fp12, fp0 + ps_mr fp13, fp0 + ps_mr fp14, fp0 + ps_mr fp15, fp0 + ps_mr fp16, fp0 + ps_mr fp17, fp0 + ps_mr fp18, fp0 + ps_mr fp19, fp0 + ps_mr fp20, fp0 + ps_mr fp21, fp0 + ps_mr fp22, fp0 + ps_mr fp23, fp0 + ps_mr fp24, fp0 + ps_mr fp25, fp0 + ps_mr fp26, fp0 + ps_mr fp27, fp0 + ps_mr fp28, fp0 + ps_mr fp29, fp0 + ps_mr fp30, fp0 + ps_mr fp31, fp0 + +SkipPairedSingles: + lfd fp0, ZeroF + fmr fp1, fp0 + fmr fp2, fp0 + fmr fp3, fp0 + fmr fp4, fp0 + fmr fp5, fp0 + fmr fp6, fp0 + fmr fp7, fp0 + fmr fp8, fp0 + fmr fp9, fp0 + fmr fp10, fp0 + fmr fp11, fp0 + fmr fp12, fp0 + fmr fp13, fp0 + fmr fp14, fp0 + fmr fp15, fp0 + fmr fp16, fp0 + fmr fp17, fp0 + fmr fp18, fp0 + fmr fp19, fp0 + fmr fp20, fp0 + fmr fp21, fp0 + fmr fp22, fp0 + fmr fp23, fp0 + fmr fp24, fp0 + fmr fp25, fp0 + fmr fp26, fp0 + fmr fp27, fp0 + fmr fp28, fp0 + fmr fp29, fp0 + fmr fp30, fp0 + fmr fp31, fp0 + + mtfsf 0xFF, fp0 + + blr +} +/* clang-format on */ + +u32 OSGetConsoleType() +{ + if (BootInfo == NULL || BootInfo->consoleType == 0) + { + return OS_CONSOLE_ARTHUR; + } + return BootInfo->consoleType; +} + +void* __OSSavedRegionStart; +void* __OSSavedRegionEnd; + +extern u32 BOOT_REGION_START : 0x812FDFF0; //(*(u32 *)0x812fdff0) +extern u32 BOOT_REGION_END : 0x812FDFEC; //(*(u32 *)0x812fdfec) + +void ClearArena(void) +{ + if ((u32)(OSGetResetCode() + 0x80000000) != 0U) + { + __OSSavedRegionStart = 0U; + __OSSavedRegionEnd = 0U; + memset(OSGetArenaLo(), 0U, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); + return; + } + __OSSavedRegionStart = (void*)BOOT_REGION_START; + __OSSavedRegionEnd = (void*)BOOT_REGION_END; + if (BOOT_REGION_START == 0U) + { + memset(OSGetArenaLo(), 0U, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); + return; + } + + if ((u32)OSGetArenaLo() < (u32)__OSSavedRegionStart) + { + if ((u32)OSGetArenaHi() <= (u32)__OSSavedRegionStart) + { + memset((u32)OSGetArenaLo(), 0U, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); + return; + } + memset(OSGetArenaLo(), 0U, (u32)__OSSavedRegionStart - (u32)OSGetArenaLo()); + if ((u32)OSGetArenaHi() > (u32)__OSSavedRegionEnd) + { + memset((u32)__OSSavedRegionEnd, 0, (u32)OSGetArenaHi() - (u32)__OSSavedRegionEnd); + } + } +} + +static void InquiryCallback(s32 result, DVDCommandBlock* block) +{ + switch (block->state) + { + case 0: + __OSDeviceCode = (u16)(0x8000 | DriveInfo.deviceCode); + break; + default: + __OSDeviceCode = 1; + break; + } +} + +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 + */ + // pretty sure this is the min(/max) amount of pointers etc for the stack to match + BI2Debug* DebugInfo; + void* debugArenaLo; + u32 inputConsoleType; + u32 tdev; + + // check if we've already done all this or not + if ((BOOL)AreWeInitialized == FALSE) + { // fantastic name + AreWeInitialized = TRUE; // flag to make sure we don't have to do this again + + // SYSTEM // + __OSStartTime = __OSGetSystemTime(); + OSDisableInterrupts(); + + // set some PPC things + PPCMtmmcr0(0); + PPCMtmmcr1(0); + PPCMtpmc1(0); + PPCMtpmc2(0); + PPCMtpmc3(0); + PPCMtpmc4(0); + PPCDisableSpeculation(); + PPCSetFpNonIEEEMode(); + + // DEBUG // + // load some DVD stuff + BI2DebugFlag = 0; // debug flag from the DVD BI2 header + BootInfo = (OSBootInfo*)OS_BASE_CACHED; // set pointer to BootInfo + + __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 the debug info address exists, grab some debug info + 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->arenaHi) + { // if the top of the heap is already set + 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 + } + + __DVDLongFileNameFlag = 1; // we made it through debug! + + // HEAP // + // set up bottom of heap (ArenaLo) + // grab address from BootInfo if it exists, otherwise use default __ArenaLo + OSSetArenaLo((BootInfo->arenaLo == NULL) ? __ArenaLo : BootInfo->arenaLo); + + // 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->arenaLo == NULL) && (BI2DebugFlag != 0) && (*BI2DebugFlag < 2)) + { + debugArenaLo = (char*)(((u32)_db_stack_end + 0x1f) & ~0x1f); + OSSetArenaLo(debugArenaLo); + } + + // set up top of heap (ArenaHi) + // grab address from BootInfo if it exists, otherwise use default __ArenaHi + OSSetArenaHi((BootInfo->arenaHi == NULL) ? __ArenaHi : BootInfo->arenaHi); + + // OS INIT AND REPORT // + // initialise a whole bunch of OS stuff + OSExceptionInit(); + __OSInitSystemCall(); + OSInitAlarm(); + __OSModuleInit(); + __OSInterruptInit(); + __OSSetInterruptHandler(__OS_INTERRUPT_PI_RSW, (void*)__OSResetSWInterruptHandler); + __OSContextInit(); + __OSCacheInit(); + EXIInit(); + SIInit(); + __OSInitSram(); + __OSThreadInit(); + __OSInitAudioSystem(); + PPCMthid2(PPCMfhid2() & 0xBFFFFFFF); + if ((BOOL)__OSInIPL == FALSE) + { + __OSInitMemoryProtection(); + } + + // begin OS reporting + OSReport("\nDolphin OS\n"); + OSReport("Kernel built : %s %s\n", "Jul 23 2003", "11:27:16"); + OSReport("Console Type : "); + + // this is a function in the same file, but it doesn't seem to match + // inputConsoleType = OSGetConsoleType(); + + // inputConsoleType = (BootInfo == NULL || (inputConsoleType = BootInfo->consoleType) == 0) ? 0x10000002 : BootInfo->consoleType; + if (BootInfo == NULL || (inputConsoleType = BootInfo->consoleType) == 0) + { + inputConsoleType = OS_CONSOLE_ARTHUR; // default console type + } + else + { + inputConsoleType = BootInfo->consoleType; + } + + // work out what console type this corresponds to and report it + // consoleTypeSwitchHi = inputConsoleType & 0xF0000000; + switch (inputConsoleType & 0xF0000000) + { // check "first" byte + case OS_CONSOLE_RETAIL: + OSReport("Retail %d\n", inputConsoleType); + break; + case OS_CONSOLE_DEVELOPMENT: + case OS_CONSOLE_TDEV: + // consoleTypeSwitchLo = (inputConsoleType & 0x0FFFFFFF); + switch (inputConsoleType & 0x0FFFFFFF) + { // if "first" byte is 2, check "the rest" + case OS_CONSOLE_EMULATOR: + OSReport("Mac Emulator\n"); + break; + case OS_CONSOLE_PC_EMULATOR: + OSReport("PC Emulator\n"); + break; + case OS_CONSOLE_ARTHUR: + OSReport("EPPC Arthur\n"); + break; + case OS_CONSOLE_MINNOW: + OSReport("EPPC Minnow\n"); + break; + default: // if none of the above, just report the info we have + tdev = (u32)inputConsoleType & 0x0FFFFFFF; + OSReport("Development HW%d (%08x)\n", tdev - 3, inputConsoleType); + break; + } + break; + default: // if none of the above, just report the info we have + OSReport("%08x\n", inputConsoleType); + break; + } + + // report memory size + OSReport("Memory %d MB\n", (u32)BootInfo->memorySize >> 0x14U); + // report heap bounds + OSReport("Arena : 0x%x - 0x%x\n", OSGetArenaLo(), OSGetArenaHi()); + // report OS version + OSRegisterVersion(__OSVersion); + + // if location of debug flag exists, and flag is >= 2, enable MetroTRKInterrupts + if (BI2DebugFlag && ((*BI2DebugFlag) >= 2)) + { + EnableMetroTRKInterrupts(); + } + + // free up memory and re-enable things + ClearArena(); + OSEnableInterrupts(); + + // check if we can load OS from IPL; if not, grab it from DVD (?) + if ((BOOL)__OSInIPL == FALSE) + { + DVDInit(); + if ((BOOL)__OSIsGcam) + { + __OSDeviceCode = 0x9000; + return; + } + DCInvalidateRange(&DriveInfo, sizeof(DriveInfo)); + DVDInquiryAsync(&DriveBlock, &DriveInfo, InquiryCallback); + } + } +} + +static u32 __OSExceptionLocations[] = { + 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 __OSEVEnd(void); +void __OSEVSetNumber(void); +void __OSExceptionVector(void); + +void __DBVECTOR(void); +void __OSDBINTSTART(void); +void __OSDBINTEND(void); +void __OSDBJUMPSTART(void); +void __OSDBJUMPEND(void); + +#define NOP 0x60000000 + +__OSExceptionHandler __OSSetExceptionHandler(__OSException exception, __OSExceptionHandler handler); + +/* + * --INFO-- + * Address: 800EB654 + * Size: 000280 + */ +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; + + // 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 + { + DBPrintf("Installing OSDBIntegrator\n"); + memcpy(destAddr, (void*)__OSDBINTSTART, (u32)__OSDBINTEND - (u32)__OSDBINTSTART); + DCFlushRangeNoSync(destAddr, (u32)__OSDBINTEND - (u32)__OSDBINTSTART); + __sync(); + ICInvalidateRange(destAddr, (u32)__OSDBINTEND - (u32)__OSDBINTSTART); + } + + // Copy the right vector into the table + 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); + } + 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); + DCFlushRangeNoSync(destAddr, handlerSize); + __sync(); + ICInvalidateRange(destAddr, handlerSize); + } + + // initialize pointer to exception table + OSExceptionTable = OSPhysicalToCached(OS_EXCEPTIONTABLE_ADDR); + + // install default exception handlers + 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"); +} + +static asm void __OSDBIntegrator(void) +{ + /* clang-format off */ + nofralloc +entry __OSDBINTSTART + 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 */ +} + +static asm void __OSDBJump(void){ + /* clang-format off */ + + nofralloc +entry __OSDBJUMPSTART + bla OS_DBJUMPPOINT_ADDR +entry __OSDBJUMPEND + /* clang-format on */ + +} + +__OSExceptionHandler __OSSetExceptionHandler(__OSException exception, __OSExceptionHandler handler) +{ + __OSExceptionHandler oldHandler; + oldHandler = OSExceptionTable[exception]; + OSExceptionTable[exception] = handler; + return oldHandler; +} + +__OSExceptionHandler __OSGetExceptionHandler(__OSException exception) +{ + return OSExceptionTable[exception]; +} + +static asm void OSExceptionVector(void) +{ + /* clang-format off */ + nofralloc + +entry __OSEVStart + // Save r4 into SPRG0 + mtsprg 0, r4 + + // Load current context physical address into r4 + 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) + + 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 + +entry __DBVECTOR + nop + + // Set SRR1[IR|DR] to turn on address + // translation at the next RFI + mfmsr r3 + ori r3, r3, 0x30 + mtsrr1 r3 + + // This lets us change the exception number based on the + // exception we're installing. +entry __OSEVSetNumber + addi r3, 0, 0x0000 + + // Load current context virtual address into r4 + lwz r4, 0xD4 + + // Check non-recoverable interrupt + rlwinm. r5, r5, 0, MSR_RI_BIT, MSR_RI_BIT + 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, 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 enalbed, not yet recoverable + + rfi + // NOT REACHED HERE + // The handler will restore state + +entry __OSEVEnd + nop + /* clang-format on */ +} + +void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar); +asm void OSDefaultExceptionHandler(register __OSException exception, register OSContext* context) +{ + /* clang-format off */ + nofralloc + OS_EXCEPTION_SAVE_GPRS(context) + mfdsisr r5 + mfdar r6 + + stwu r1,-8(r1) + b __OSUnhandledException + /* clang-foramt on */ +} + +void __OSPSInit(void) +{ + PPCMthid2(PPCMfhid2() | 0xA0000000); + ICFlashInvalidate(); + __sync(); + // clang-format off + 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 + } + // clang-format on +} + +#define DI_CONFIG_IDX 0x9 +#define DI_CONFIG_CONFIG_MASK 0xFF +u32 __OSGetDIConfig(void) +{ + return (__DIRegs[DI_CONFIG_IDX] & DI_CONFIG_CONFIG_MASK); +} + +void OSRegisterVersion(const char* id) +{ + OSReport("%s\n", id); +} diff --git a/libs/dolphin/os/OSAlarm.c b/libs/dolphin/os/OSAlarm.c new file mode 100644 index 000000000..c384f40b7 --- /dev/null +++ b/libs/dolphin/os/OSAlarm.c @@ -0,0 +1,254 @@ +#include "dolphin/base/PPCArch.h" +#include "dolphin/os/OSPriv.h" +#include "dolphin/os/OSReset.h" + +static struct OSAlarmQueue +{ + OSAlarm *head; + OSAlarm *tail; +} AlarmQueue; + +static void DecrementerExceptionHandler(__OSException exception, OSContext *context); +static BOOL OnReset(BOOL final); + +static OSResetFunctionInfo ResetFunctionInfo = {OnReset, 0xFFFFFFFF}; + +static void SetTimer(OSAlarm *alarm) +{ + OSTime delta; + + delta = alarm->fire - __OSGetSystemTime(); + if (delta < 0) + { + PPCMtdec(0); + } + else if (delta < 0x80000000) + { + PPCMtdec((u32)delta); + } + else + { + PPCMtdec(0x7fffffff); + } +} + +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) + { + OSTime time = __OSGetSystemTime(); + + fire = alarm->start; + if (alarm->start < time) + { + fire += alarm->period * ((time - alarm->start) / alarm->period + 1); + } + } + + alarm->handler = handler; + 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; + if (prev) + { + prev->next = alarm; + } + else + { + AlarmQueue.head = alarm; + SetTimer(alarm); + } + return; + } + alarm->next = 0; + prev = AlarmQueue.tail; + AlarmQueue.tail = alarm; + alarm->prev = prev; + if (prev) + { + prev->next = alarm; + } + else + { + AlarmQueue.head = AlarmQueue.tail = alarm; + SetTimer(alarm); + } +} + +void OSSetAlarm(OSAlarm *alarm, OSTime tick, OSAlarmHandler handler) +{ + BOOL enabled; + enabled = OSDisableInterrupts(); + alarm->period = 0; + InsertAlarm(alarm, __OSGetSystemTime() + tick, handler); + OSRestoreInterrupts(enabled); +} + +void OSSetPeriodicAlarm(OSAlarm *alarm, OSTime start, OSTime period, OSAlarmHandler handler) +{ + BOOL enabled; + enabled = OSDisableInterrupts(); + alarm->period = period; + alarm->start = __OSTimeToSystemTime(start); + InsertAlarm(alarm, 0, handler); + OSRestoreInterrupts(enabled); +} + +void OSCancelAlarm(OSAlarm *alarm) +{ + OSAlarm *next; + BOOL enabled; + + enabled = OSDisableInterrupts(); + + if (alarm->handler == 0) + { + OSRestoreInterrupts(enabled); + return; + } + + next = alarm->next; + if (next == 0) + { + AlarmQueue.tail = alarm->prev; + } + else + { + next->prev = alarm->prev; + } + if (alarm->prev) + { + alarm->prev->next = next; + } + else + { + AlarmQueue.head = next; + if (next) + { + SetTimer(next); + } + } + alarm->handler = 0; + + OSRestoreInterrupts(enabled); +} + +static void DecrementerExceptionCallback(register __OSException exception, + register OSContext *context) +{ + OSAlarm *alarm; + OSAlarm *next; + OSAlarmHandler handler; + OSTime time; + OSContext exceptionContext; + time = __OSGetSystemTime(); + alarm = AlarmQueue.head; + if (alarm == 0) + { + OSLoadContext(context); + } + + if (time < alarm->fire) + { + SetTimer(alarm); + OSLoadContext(context); + } + + next = alarm->next; + AlarmQueue.head = next; + if (next == 0) + { + AlarmQueue.tail = 0; + } + else + { + next->prev = 0; + } + + handler = alarm->handler; + alarm->handler = 0; + if (0 < alarm->period) + { + InsertAlarm(alarm, 0, handler); + } + + if (AlarmQueue.head) + { + SetTimer(AlarmQueue.head); + } + + OSDisableScheduler(); + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + handler(alarm, context); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + OSEnableScheduler(); + __OSReschedule(); + OSLoadContext(context); +} + +static asm void DecrementerExceptionHandler(register __OSException exception, + register OSContext *context) +{ + // clang-format off + nofralloc + OS_EXCEPTION_SAVE_GPRS(context) + stwu r1, -8(r1) + b DecrementerExceptionCallback + // clang-format on +} + +static BOOL OnReset(BOOL final) +{ + OSAlarm *alarm; + OSAlarm *next; + + if (final) + { + alarm = AlarmQueue.head; + next = (alarm) ? alarm->next : NULL; + + while (alarm != NULL) + { + if (__DVDTestAlarm(alarm) == FALSE) + { + OSCancelAlarm(alarm); + } + + alarm = next; + next = (alarm) ? alarm->next : NULL; + } + } + + return TRUE; +} diff --git a/libs/dolphin/os/OSAlloc.c b/libs/dolphin/os/OSAlloc.c new file mode 100644 index 000000000..bb2898e7a --- /dev/null +++ b/libs/dolphin/os/OSAlloc.c @@ -0,0 +1,228 @@ +#include "types.h" +#include + +typedef struct HeapCell +{ + struct HeapCell *prev; + struct HeapCell *next; + u32 size; +} HeapCell; + +typedef struct Heap +{ + s32 size; + struct HeapCell *free; // linked list of free cells + struct HeapCell *allocated; // linked list of allocated cells +} Heap; + +void *ArenaEnd; +void *ArenaStart; +int NumHeaps; +struct Heap *HeapArray; +volatile OSHeapHandle __OSCurrHeap = -1; + +#define InRange(addr, start, end) ((u8 *)(start) <= (u8 *)(addr) && (u8 *)(addr) < (u8 *)(end)) +#define OFFSET(addr, align) (((u32)(addr) & ((align)-1))) + +#define ALIGNMENT 32 +#define MINOBJSIZE 64 + +static inline void *DLAddFront(struct HeapCell *neighbor, struct HeapCell *cell) +{ + cell->next = neighbor; + cell->prev = NULL; + if (neighbor != NULL) + neighbor->prev = cell; + return cell; +} + +void DLLookup(void) +{ + // UNUSED FUNCTION +} + +// removes 'cell' from 'list' and returns 'list' +static inline HeapCell *DLExtract(struct HeapCell *list, struct HeapCell *cell) +{ + if (cell->next != NULL) + cell->next->prev = cell->prev; + if (cell->prev == NULL) + list = cell->next; + else + cell->prev->next = cell->next; + return list; +} + +static HeapCell *DLInsert(HeapCell *list, HeapCell *cell, void *unused /* needed to match OSFreeToHeap */) +{ + HeapCell *before = NULL; + HeapCell *after = list; + + while (after != NULL) + { + if (cell <= after) + break; + before = after; + after = after->next; + } + cell->next = after; + cell->prev = before; + if (after != NULL) + { + after->prev = cell; + if ((u8 *)cell + cell->size == (u8 *)after) + { + cell->size += after->size; + after = after->next; + cell->next = after; + if (after != NULL) + after->prev = cell; + } + } + if (before != NULL) + { + before->next = cell; + if ((u8 *)before + before->size == (u8 *)cell) + { + before->size += cell->size; + before->next = after; + if (after != NULL) + after->prev = before; + } + return list; + } + return cell; +} + +void DLOverlap(void) +{ + // UNUSED FUNCTION +} + +void DLSize(void) +{ + // UNUSED FUNCTION +} + +void *OSAllocFromHeap(OSHeapHandle heap, u32 size) +{ + struct Heap *hd = &HeapArray[heap]; + s32 sizeAligned = OSRoundUp32B(ALIGNMENT + size); + struct HeapCell *cell; + struct HeapCell *oldTail; + u32 leftoverSpace; + + // find first cell with enough capacity + for (cell = hd->free; cell != NULL; cell = cell->next) + { + if (sizeAligned <= (s32)cell->size) + break; + } + if (cell == NULL) + return NULL; + + leftoverSpace = cell->size - sizeAligned; + if (leftoverSpace < MINOBJSIZE) + { + // remove this cell from the free list + hd->free = DLExtract(hd->free, cell); + } + else + { + // remove this cell from the free list and make a new cell out of the + // remaining space + struct HeapCell *newcell = (void *)((u8 *)cell + sizeAligned); + cell->size = sizeAligned; + newcell->size = leftoverSpace; + 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 + hd->free = newcell; + } + + // add the cell to the beginning of the allocated list + hd->allocated = DLAddFront(hd->allocated, cell); + + return (u8 *)cell + ALIGNMENT; +} + +void OSFreeToHeap(OSHeapHandle heap, void *ptr) +{ + HeapCell *cell = (void *)((u8 *)ptr - ALIGNMENT); + Heap *hd = &HeapArray[heap]; + HeapCell *list = hd->allocated; + + // remove cell from the allocated list + // hd->allocated = DLExtract(hd->allocated, cell); + if (cell->next != NULL) + cell->next->prev = cell->prev; + if (cell->prev == NULL) + list = cell->next; + else + cell->prev->next = cell->next; + hd->allocated = list; + hd->free = DLInsert(hd->free, cell, list); +} + +OSHeapHandle OSSetCurrentHeap(OSHeapHandle heap) +{ + OSHeapHandle old = __OSCurrHeap; + + __OSCurrHeap = heap; + return old; +} + +void *OSInitAlloc(void *arenaStart, void *arenaEnd, int maxHeaps) +{ + u32 totalSize = maxHeaps * sizeof(struct Heap); + int i; + + HeapArray = arenaStart; + NumHeaps = maxHeaps; + + for (i = 0; i < NumHeaps; i++) + { + Heap *heap = &HeapArray[i]; + + heap->size = -1; + heap->free = heap->allocated = NULL; + } + + __OSCurrHeap = -1; + + arenaStart = (u8 *)HeapArray + totalSize; + arenaStart = (void *)OSRoundUp32B(arenaStart); + + ArenaStart = arenaStart; + ArenaEnd = (void *)OSRoundDown32B(arenaEnd); + + return arenaStart; +} + +OSHeapHandle OSCreateHeap(void *start, void *end) +{ + int i; + HeapCell *cell = (void *)OSRoundUp32B(start); + + end = (void *)OSRoundDown32B(end); + for (i = 0; i < NumHeaps; i++) + { + Heap *hd = &HeapArray[i]; + + if (hd->size < 0) + { + hd->size = (u8 *)end - (u8 *)cell; + cell->prev = NULL; + cell->next = NULL; + cell->size = hd->size; + hd->free = cell; + hd->allocated = NULL; + return i; + } + } + return -1; +} diff --git a/libs/dolphin/os/OSArena.c b/libs/dolphin/os/OSArena.c new file mode 100644 index 000000000..97e7ede95 --- /dev/null +++ b/libs/dolphin/os/OSArena.c @@ -0,0 +1,41 @@ +#include + +#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) +#define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) + +void *__OSArenaHi; +void *__OSArenaLo = (void *)-1; + +void *OSGetArenaHi(void) { return __OSArenaHi; } + +void *OSGetArenaLo(void) { return __OSArenaLo; } + +void OSSetArenaHi(void *addr) { __OSArenaHi = addr; } + +void OSSetArenaLo(void *addr) { __OSArenaLo = addr; } + +void *OSAllocFromArenaLo(u32 size, u32 align) +{ + void *ptr; + u8 *arenaLo; + + 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; +} \ No newline at end of file diff --git a/libs/dolphin/os/OSAudioSystem.c b/libs/dolphin/os/OSAudioSystem.c new file mode 100644 index 000000000..c88cfa1c3 --- /dev/null +++ b/libs/dolphin/os/OSAudioSystem.c @@ -0,0 +1,114 @@ +#include "types.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static u8 DSPInitCode[128] = { + // clang-format off + 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, + 0x12, 0x06, 0x12, 0x03, 0x12, 0x04, 0x12, 0x05, 0x00, 0x80, 0x80, 0x00, 0x00, 0x88, 0xFF, 0xFF, + 0x00, 0x84, 0x10, 0x00, 0x00, 0x64, 0x00, 0x1D, 0x02, 0x18, 0x00, 0x00, 0x81, 0x00, 0x1C, 0x1E, + 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, + // clang-format on +}; + +#define __DSPWorkBuffer (void*)0x81000000 + +void __OSInitAudioSystem(void) { + u32 r28; + u16 r3; + + u32 padding; + + memcpy((void*)((u8*)OSGetArenaHi() - 128), __DSPWorkBuffer, 128); + memcpy(__DSPWorkBuffer, (void*)DSPInitCode, 128); + + DCFlushRange(__DSPWorkBuffer, 128); + + __DSPRegs[9] = 0x43; + __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; + + r28 = OSGetTick(); + while ((s32)(OSGetTick() - r28) < 0x892) + ; + + *(u32*)&__DSPRegs[16] = 0x1000000; + *(u32*)&__DSPRegs[18] = 0; + *(u32*)&__DSPRegs[20] = 0x20; + + r3 = __DSPRegs[5]; + while (!(r3 & 0x20)) + r3 = __DSPRegs[5]; + __DSPRegs[5] = r3; + + __DSPRegs[5] &= ~0x800; + while ((__DSPRegs[5]) & 0x400) + ; + __DSPRegs[5] &= ~4; + + r3 = __DSPRegs[2]; + + while (!(r3 & 0x8000)) + r3 = __DSPRegs[2]; + + (void)__DSPRegs[3]; + r3 != 42069; + __DSPRegs[5] |= 4; + __DSPRegs[5] = 0x8AC; + __DSPRegs[5] |= 1; + while (__DSPRegs[5] & 1) + ; + memcpy(__DSPWorkBuffer, (void*)((u8*)OSGetArenaHi() - 128), 128); +} + +void __OSStopAudioSystem(void) { + u32 r28; + +#define waitUntil(load, mask) \ + r28 = (load); \ + while (r28 & (mask)) { \ + r28 = (load); \ + } + + __DSPRegs[5] = 0x804; + r28 = __DSPRegs[27]; + __DSPRegs[27] = r28 & ~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; + waitUntil(__DSPRegs[5], 0x001); + +#undef waitUntil +} + +#ifdef __cplusplus +} +#endif diff --git a/libs/dolphin/os/OSCache.c b/libs/dolphin/os/OSCache.c new file mode 100644 index 000000000..2cec4d3dd --- /dev/null +++ b/libs/dolphin/os/OSCache.c @@ -0,0 +1,426 @@ +#include "dolphin/base/PPCArch.h" +#include "dolphin/os.h" + +// Can't use this due to weird condition register issues +//#include "asm_types.h" +#define HID2 920 + +#include "dolphin/db.h" + +/* clang-format off */ +asm void DCEnable() { + nofralloc + sync + mfspr r3, HID0 + ori r3, r3, 0x4000 + mtspr HID0, r3 + 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 + +@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, 31 + srwi nBytes, nBytes, 5 + mtctr nBytes + +@1 + dcbf r0, addr + addi addr, addr, 32 + bdnz @1 + sc + blr +} + +asm void DCStoreRange(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 + sc + + blr +} + +asm void DCFlushRangeNoSync(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 + 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 +} + +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 ICInvalidateRange(register void* addr, register u32 nBytes) { + nofralloc + nofralloc + cmplwi nBytes, 0 + blelr + clrlwi r5, addr, 27 + add nBytes, nBytes, r5 + addi nBytes, nBytes, 31 + srwi nBytes, nBytes, 5 + mtctr nBytes + +@1 + icbi r0, addr + addi addr, addr, 32 + bdnz @1 + sync + isync + + blr +} + + +asm void ICFlashInvalidate() { + nofralloc + mfspr r3, HID0 + ori r3, r3, 0x800 + mtspr HID0, r3 + blr +} + +asm void ICEnable() { + nofralloc + isync + mfspr r3, HID0 + ori r3, r3, 0x8000 + mtspr HID0, r3 + blr +} + +#define LC_LINES 512 +#define CACHE_LINES 1024 + +asm void __LCEnable() { + 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 + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + blr +} + +void LCEnable() { + BOOL enabled; + + enabled = OSDisableInterrupts(); + __LCEnable(); + OSRestoreInterrupts(enabled); +} + + +asm void LCDisable() { + nofralloc + lis r3, LC_BASE_PREFIX + li r4, LC_LINES + mtctr r4 +@1 + dcbi r0, r3 + addi r3, r3, 32 + bdnz @1 + mfspr r4, HID2 + rlwinm r4, r4, 0, 4, 2 + mtspr HID2, r4 + 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 +} + +/* clang-format on */ + +u32 LCLoadData(register void* destAddr, register void* srcAddr, register u32 nBytes) { + u32 numBlocks = (nBytes + 31) / 32; + u32 numTransactions = (numBlocks + 128 - 1) / 128; + + while (numBlocks > 0) { + if (numBlocks < 128) { + LCLoadBlocks(destAddr, srcAddr, numBlocks); + numBlocks = 0; + } else { + LCLoadBlocks(destAddr, srcAddr, 0); + numBlocks -= 128; + destAddr = (void*)((u32)destAddr + 4096); + srcAddr = (void*)((u32)srcAddr + 4096); + } + } + + return numTransactions; +} +u32 LCStoreData(void* destAddr, void* srcAddr, u32 nBytes) { + u32 numBlocks = (nBytes + 31) / 32; + u32 numTransactions = (numBlocks + 128 - 1) / 128; + + 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; +} + +/* clang-format off */ +asm u32 LCQueueLength() { + nofralloc + mfspr r4, HID2 + rlwinm r3, r4, 8, 28, 31 + blr +} + +asm void LCQueueWait(register u32 len) { + nofralloc +wait: + mfspr r4, HID2 + rlwinm r4, r4, 8, 28, 31 + cmpw r4, r3 + bgt wait + blr +} + +/* clang-format on */ +static void L2Disable(void) { + __sync(); + PPCMtl2cr(PPCMfl2cr() & ~0x80000000); + __sync(); +} + +void L2GlobalInvalidate(void) { + L2Disable(); + PPCMtl2cr(PPCMfl2cr() | 0x00200000); + while (PPCMfl2cr() & 0x00000001u) + ; + PPCMtl2cr(PPCMfl2cr() & ~0x00200000); + while (PPCMfl2cr() & 0x00000001u) { + DBPrintf(">>> L2 INVALIDATE : SHOULD NEVER HAPPEN\n"); + } +} + +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 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)) { + OSReport("Machine check was not DMA/locked cache related\n"); + OSDumpContext(context); + PPCHalt(); + } + + OSReport("DMAErrorHandler(): An error occurred while processing DMA.\n"); + OSReport("The following errors have been detected and cleared :\n"); + + if (hid2 & HID2_DCHERR) { + OSReport("\t- Requested a locked cache tag that was already in the cache\n"); + } + + if (hid2 & HID2_DNCERR) { + OSReport("\t- DMA attempted to access normal cache\n"); + } + + if (hid2 & HID2_DCMERR) { + OSReport("\t- DMA missed in data cache\n"); + } + + if (hid2 & HID2_DQOERR) { + OSReport("\t- DMA queue overflowed\n"); + } + + // write hid2 back to clear the error bits + PPCMthid2(hid2); +} + +void __OSCacheInit() { + if (!(PPCMfhid0() & HID0_ICE)) { + ICEnable(); + DBPrintf("L1 i-caches initialized\n"); + } + if (!(PPCMfhid0() & HID0_DCE)) { + DCEnable(); + DBPrintf("L1 d-caches initialized\n"); + } + + if (!(PPCMfl2cr() & L2CR_L2E)) { + L2Init(); + L2Enable(); + DBPrintf("L2 cache initialized\n"); + } + + OSSetErrorHandler(OS_ERROR_MACHINE_CHECK, DMAErrorHandler); + DBPrintf("Locked cache machine check handler installed\n"); +} diff --git a/libs/dolphin/os/OSContext.c b/libs/dolphin/os/OSContext.c new file mode 100644 index 000000000..f8aae0446 --- /dev/null +++ b/libs/dolphin/os/OSContext.c @@ -0,0 +1,637 @@ +#include +#include + +#define HID2 920 + +volatile OSContext* __OSCurrentContext : (OS_BASE_CACHED | 0x00D4); +volatile OSContext* __OSFPUContext : (OS_BASE_CACHED | 0x00D8); + +static asm void __OSLoadFPUContext(register u32, register OSContext* fpuContext) { + // clang-format off + nofralloc + lhz r5, fpuContext->state; + clrlwi. r5, r5, 31 + beq _return + + lfd fp0, OS_CONTEXT_FPSCR(fpuContext) + mtfsf 0xFF, fp0 + mfspr r5, HID2 + rlwinm. r5, r5, 3, 31, 31 + beq _regular_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 + +_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 +} + +static asm void __OSSaveFPUContext(register u32, register u32, register OSContext* fpuContext) { + // clang-format off + nofralloc + + lhz r3, fpuContext->state + ori r3, r3, 1 + sth r3, fpuContext->state + + 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 fp0 + stfd fp0, OS_CONTEXT_FPSCR(fpuContext) + + lfd fp0, fpuContext->fpr[0] + + 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 +} + +asm void OSLoadFPUContext(register OSContext* fpuContext) { + // clang-format off + nofralloc + addi r4, fpuContext, 0 + b __OSLoadFPUContext + // clang-format on +} + +asm void OSSaveFPUContext(register OSContext* fpuContext) { + // clang-format off + nofralloc + addi r5, fpuContext, 0 + b __OSSaveFPUContext + // clang-format on +} + +asm void OSSetCurrentContext(register OSContext* context){ + // clang-format off + nofralloc + + 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 + +_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 +} + +OSContext* OSGetCurrentContext(void) { + return (OSContext*)__OSCurrentContext; +} + +asm u32 OSSaveContext(register OSContext* context) { + // clang-format off + nofralloc + 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 +} + +extern void __RAS_OSDisableInterrupts_begin(); +extern void __RAS_OSDisableInterrupts_end(); + +asm void OSLoadContext(register OSContext* context) { + // clang-format off + nofralloc + + 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 +} + +asm u32 OSGetStackPointer() { + // clang-format off + nofralloc + mr r3, r1 + blr + // clang-format on +} + +asm u32 OSSwitchStack(register u32 newsp) { + // clang-format off + nofralloc + mr r5, r1 + mr r1, newsp + mr r3, r5 + blr + // clang-format on +} + +asm int OSSwitchFiber(register u32 pc, register u32 newsp) { + // clang-format off + 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 + // clang-format on +} + +void OSClearContext(register OSContext* context) { + context->mode = 0; + context->state = 0; + if (context == __OSFPUContext) + __OSFPUContext = NULL; +} + +asm void OSInitContext(register OSContext* context, register u32 pc, register u32 newsp) { + // clang-format off + 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 + // clang-format on +} + +void OSDumpContext(OSContext* context) { + u32 i; + u32* p; + + OSReport("------------------------- Context 0x%08x -------------------------\n", 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]); + } + + OSReport("LR = 0x%08x CR = 0x%08x\n", context->lr, context->cr); + OSReport("SRR0 = 0x%08x SRR1 = 0x%08x\n", context->srr0, context->srr1); + + 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]); + } + + if (context->state & OS_CONTEXT_STATE_FPSAVED) { + OSContext* currentContext; + OSContext fpuContext; + BOOL enabled; + + enabled = OSDisableInterrupts(); + 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]); + } + 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->psf[i], i + 1, + (u32)context->psf[i + 1]); + } + + OSClearContext(&fpuContext); + OSSetCurrentContext(currentContext); + OSRestoreInterrupts(enabled); + } + + OSReport("\nAddress: Back Chain LR Save\n"); + for (i = 0, p = (u32*)context->gpr[1]; p && (u32)p != 0xffffffff && i++ < 16; p = (u32*)*p) { + OSReport("0x%08x: 0x%08x 0x%08x\n", p, p[0], p[1]); + } +} + +static asm void OSSwitchFPUContext(register __OSException exception, register OSContext* context) { + // clang-format off + nofralloc + mfmsr r5 + ori r5, r5, 0x2000 + mtmsr r5 + isync + 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 +} + +void __OSContextInit(void) { + __OSSetExceptionHandler(__OS_EXCEPTION_FLOATING_POINT, OSSwitchFPUContext); + __OSFPUContext = NULL; + DBPrintf("FPU-unavailable handler installed\n"); +} + +asm void OSFillFPUContext(register OSContext *context) +{ + // clang-format off + nofralloc + mfmsr r5 + ori r5, r5, 0x2000 + mtmsr r5 + + isync + stfd f0, 0x90(r3) + stfd f1, 0x98(r3) + stfd f2, 0xA0(r3) + stfd f3, 0xA8(r3) + stfd f4, 0xB0(r3) + stfd f5, 0xB8(r3) + stfd f6, 0xC0(r3) + stfd f7, 0xC8(r3) + stfd f8, 0xD0(r3) + stfd f9, 0xD8(r3) + stfd f10, 0xE0(r3) + stfd f11, 0xE8(r3) + stfd f12, 0xF0(r3) + stfd f13, 0xF8(r3) + stfd f14, 0x100(r3) + stfd f15, 0x108(r3) + stfd f16, 0x110(r3) + stfd f17, 0x118(r3) + stfd f18, 0x120(r3) + stfd f19, 0x128(r3) + stfd f20, 0x130(r3) + stfd f21, 0x138(r3) + stfd f22, 0x140(r3) + stfd f23, 0x148(r3) + stfd f24, 0x150(r3) + stfd f25, 0x158(r3) + stfd f26, 0x160(r3) + stfd f27, 0x168(r3) + stfd f28, 0x170(r3) + stfd f29, 0x178(r3) + stfd f30, 0x180(r3) + stfd f31, 0x188(r3) + mffs f0 + stfd f0, 0x190(r3) + lfd f0, 0x90(r3) + + mfspr r5, 0x398 + rlwinm. r5,r5,3,31,31 + beq- _return + + psq_st f0,0x1C8(r3),0,0 + psq_st f1,0x1D0(r3),0,0 + psq_st f2,0x1D8(r3),0,0 + psq_st f3,0x1E0(r3),0,0 + psq_st f4,0x1E8(r3),0,0 + psq_st f5,0x1F0(r3),0,0 + psq_st f6,0x1F8(r3),0,0 + psq_st f7,0x200(r3),0,0 + psq_st f8,0x208(r3),0,0 + psq_st f9,0x210(r3),0,0 + psq_st f10,0x218(r3),0,0 + psq_st f11,0x220(r3),0,0 + psq_st f12,0x228(r3),0,0 + psq_st f13,0x230(r3),0,0 + psq_st f14,0x238(r3),0,0 + psq_st f15,0x240(r3),0,0 + psq_st f16,0x248(r3),0,0 + psq_st f17,0x250(r3),0,0 + psq_st f18,0x258(r3),0,0 + psq_st f19,0x260(r3),0,0 + psq_st f20,0x268(r3),0,0 + psq_st f21,0x270(r3),0,0 + psq_st f22,0x278(r3),0,0 + psq_st f23,0x280(r3),0,0 + psq_st f24,0x288(r3),0,0 + psq_st f25,0x290(r3),0,0 + psq_st f26,0x298(r3),0,0 + psq_st f27,0x2A0(r3),0,0 + psq_st f28,0x2A8(r3),0,0 + psq_st f29,0x2B0(r3),0,0 + psq_st f30,0x2B8(r3),0,0 + psq_st f31,0x2C0(r3),0,0 + +_return: + blr + // clang-format on +} \ No newline at end of file diff --git a/libs/dolphin/os/OSError.c b/libs/dolphin/os/OSError.c new file mode 100644 index 000000000..b7091c98f --- /dev/null +++ b/libs/dolphin/os/OSError.c @@ -0,0 +1,205 @@ +#include +#include +#include +#include + +OSThread* __OSCurrentThread : (OS_BASE_CACHED | 0x00E4); +OSThreadQueue __OSActiveThreadQueue : (OS_BASE_CACHED | 0x00DC); +volatile OSContext* __OSFPUContext : (OS_BASE_CACHED | 0x00D8); + +OSErrorHandler __OSErrorTable[OS_ERROR_MAX]; +#define FPSCR_ENABLE (FPSCR_VE | FPSCR_OE | FPSCR_UE | FPSCR_ZE | FPSCR_XE) +u32 __OSFpscrEnableBits = FPSCR_ENABLE; + +__declspec(weak) void OSReport(const char* msg, ...) { + va_list args; + va_start(args, msg); + vprintf(msg, args); + va_end(args); +} + +__declspec(weak) void OSVReport(const char* msg, va_list list) { vprintf(msg, list); } + +__declspec(weak) void OSPanic(const char* file, int line, const char* msg, ...) { + va_list marker; + u32 i; + u32* p; + + OSDisableInterrupts(); + va_start(marker, msg); + vprintf(msg, marker); + va_end(marker); + OSReport(" in \"%s\" on line %d.\n", file, line); + + OSReport("\nAddress: Back Chain LR Save\n"); + 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(); +} + +OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler) { + OSErrorHandler oldHandler; + BOOL enabled; + + enabled = OSDisableInterrupts(); + oldHandler = __OSErrorTable[error]; + __OSErrorTable[error] = handler; + + if (error == OS_ERROR_FPE) { + u32 msr; + u32 fpscr; + OSThread* thread; + + msr = PPCMfmsr(); + PPCMtmsr(msr | MSR_FP); + fpscr = PPCMffpscr(); + if (handler) { + for (thread = __OSActiveThreadQueue.head; thread; 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.psf[i] = (u64)0xffffffffffffffffLL; + } + thread->context.fpscr = FPSCR_NI; + } + thread->context.fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE; + thread->context.fpscr &= + ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | + FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | + FPSCR_OX | FPSCR_FX | FPSCR_FI); + } + fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE; + msr |= MSR_FE0 | MSR_FE1; + } else { + for (thread = __OSActiveThreadQueue.head; thread; thread = thread->linkActive.next) { + thread->context.srr1 &= ~(MSR_FE0 | MSR_FE1); + thread->context.fpscr &= ~FPSCR_ENABLE; + thread->context.fpscr &= + ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | + FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | + FPSCR_OX | FPSCR_FX | FPSCR_FI); + } + fpscr &= ~FPSCR_ENABLE; + msr &= ~(MSR_FE0 | MSR_FE1); + } + + fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | + FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | + FPSCR_OX | FPSCR_FX | FPSCR_FI); + + PPCMtfpscr(fpscr); + PPCMtmsr(msr); + } + + OSRestoreInterrupts(enabled); + return oldHandler; +} + +void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar) { + OSTime now; + + now = OSGetTime(); + + if (!(context->srr1 & MSR_RI)) { + OSReport("Non-recoverable Exception %d", exception); + } else { + if (exception == __OS_EXCEPTION_PROGRAM && (context->srr1 & (0x80000000 >> 11)) && + __OSErrorTable[OS_ERROR_FPE] != 0) { + u32 fpscr; + u32 msr; + + exception = OS_ERROR_FPE; + + msr = PPCMfmsr(); + PPCMtmsr(msr | MSR_FP); + + if (__OSFPUContext) { + OSSaveFPUContext((OSContext*)__OSFPUContext); + } + + fpscr = PPCMffpscr(); + fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | + FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | + FPSCR_OX | FPSCR_FX | FPSCR_FI); + PPCMtfpscr(fpscr); + + PPCMtmsr(msr); + + if (__OSFPUContext == context) { + OSDisableScheduler(); + __OSErrorTable[exception](exception, context, dsisr, dar); + context->srr1 &= ~MSR_FP; + __OSFPUContext = NULL; + + context->fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | + FPSCR_VXSNAN | FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | + FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI); + OSEnableScheduler(); + __OSReschedule(); + } else { + context->srr1 &= ~MSR_FP; + __OSFPUContext = NULL; + } + + OSLoadContext(context); + } + + if (__OSErrorTable[exception]) { + OSDisableScheduler(); + __OSErrorTable[exception](exception, context, dsisr, dar); + OSEnableScheduler(); + __OSReschedule(); + OSLoadContext(context); + } + + if (exception == OS_ERROR_DECREMENTER) { + OSLoadContext(context); + } + + OSReport("Unhandled Exception %d", exception); + } + + OSReport("\n"); + OSDumpContext(context); + OSReport("\nDSISR = 0x%08x DAR = 0x%08x\n", dsisr, dar); + OSReport("TB = 0x%016llx\n", now); + + 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); + break; + case __OS_EXCEPTION_ISI: + OSReport("\nAttempted to fetch instruction from invalid address 0x%x " + "(read from SRR0)\n", + context->srr0); + break; + 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); + break; + case __OS_EXCEPTION_PROGRAM: + OSReport("\nProgram exception : Possible illegal instruction/operation " + "at or around 0x%x (read from SRR0)\n", + context->srr0, dar); + break; + case OS_ERROR_PROTECTION: + OSReport("\n"); + OSReport("AI DMA Address = 0x%04x%04x\n", __DSPRegs[0x00000018], __DSPRegs[0x00000018 + 1]); + OSReport("ARAM DMA Address = 0x%04x%04x\n", __DSPRegs[0x00000010], __DSPRegs[0x00000010 + 1]); + OSReport("DI DMA Address = 0x%08x\n", __DIRegs[0x00000005]); + break; + } + + OSReport("\nLast interrupt (%d): SRR0 = 0x%08x TB = 0x%016llx\n", __OSLastInterrupt, + __OSLastInterruptSrr0, __OSLastInterruptTime); + + PPCHalt(); +} diff --git a/libs/dolphin/os/OSFont.c b/libs/dolphin/os/OSFont.c new file mode 100644 index 000000000..aa79fb6bc --- /dev/null +++ b/libs/dolphin/os/OSFont.c @@ -0,0 +1,32 @@ +#include +#include +#include + +// there shoudl be more in this file, however this is the only thing that gets used, i'm not gonna add 1000 lines of text that have no value here + +u16 OSGetFontEncode() +{ + static u16 fontEncode = OS_FONT_ENCODE_NULL; + + if (fontEncode <= 1) + { + return fontEncode; + } + + switch (__OSTVMode) + { + case VI_NTSC: + fontEncode = (__VIRegs[VI_DTV_STAT] & 2) ? OS_FONT_ENCODE_SJIS : OS_FONT_ENCODE_ANSI; + break; + + case VI_PAL: + case VI_MPAL: + case VI_DEBUG: + case VI_DEBUG_PAL: + case VI_EURGB60: + default: + fontEncode = OS_FONT_ENCODE_ANSI; + } + + return fontEncode; +} diff --git a/libs/dolphin/os/OSInterrupt.c b/libs/dolphin/os/OSInterrupt.c new file mode 100644 index 000000000..a7bed16a5 --- /dev/null +++ b/libs/dolphin/os/OSInterrupt.c @@ -0,0 +1,427 @@ +#include +#include + +static asm void ExternalInterruptHandler(register __OSException exception, + register OSContext* context); + +extern void __RAS_OSDisableInterrupts_begin(void); +extern void __RAS_OSDisableInterrupts_end(void); + +static __OSInterruptHandler* InterruptHandlerTable; + +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, +}; + +asm BOOL OSDisableInterrupts(void) { + // clang-format off + 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 + // clang-format on +} +asm BOOL OSEnableInterrupts(void) { + // clang-format off + nofralloc + + mfmsr r3 + ori r4, r3, 0x8000 + mtmsr r4 + rlwinm r3, r3, 17, 31, 31 + blr + // clang-format on +} + +asm BOOL OSRestoreInterrupts(register BOOL level){ + // clang-format off + + 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 + // clang-format on +} + +__OSInterruptHandler + __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler) { + __OSInterruptHandler oldHandler; + + oldHandler = InterruptHandlerTable[interrupt]; + InterruptHandlerTable[interrupt] = handler; + return oldHandler; +} + +__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt) { + return InterruptHandlerTable[interrupt]; +} + +void __OSInterruptInit(void) { + InterruptHandlerTable = 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); + + __OSSetExceptionHandler(4, ExternalInterruptHandler); +} + +u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current) { + u32 reg; + + switch (__cntlzw(mask)) { + 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; + if (!(current & OS_INTERRUPTMASK_MEM_1)) + reg |= 0x2; + if (!(current & OS_INTERRUPTMASK_MEM_2)) + reg |= 0x4; + if (!(current & OS_INTERRUPTMASK_MEM_3)) + reg |= 0x8; + if (!(current & OS_INTERRUPTMASK_MEM_ADDRESS)) + reg |= 0x10; + __MEMRegs[0x0000000e] = (u16)reg; + mask &= ~OS_INTERRUPTMASK_MEM; + break; + 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)) + reg |= 0x10; + if (!(current & OS_INTERRUPTMASK_DSP_ARAM)) + reg |= 0x40; + if (!(current & OS_INTERRUPTMASK_DSP_DSP)) + reg |= 0x100; + __DSPRegs[0x00000005] = (u16)reg; + mask &= ~OS_INTERRUPTMASK_DSP; + break; + case __OS_INTERRUPT_AI_AI: + reg = __AIRegs[0]; + reg &= ~0x2C; + if (!(current & OS_INTERRUPTMASK_AI_AI)) + reg |= 0x4; + __AIRegs[0] = reg; + mask &= ~OS_INTERRUPTMASK_AI; + break; + 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)) + reg |= 0x1; + if (!(current & OS_INTERRUPTMASK_EXI_0_TC)) + reg |= 0x4; + if (!(current & OS_INTERRUPTMASK_EXI_0_EXT)) + reg |= 0x400; + __EXIRegs[0] = reg; + mask &= ~OS_INTERRUPTMASK_EXI_0; + break; + case __OS_INTERRUPT_EXI_1_EXI: + case __OS_INTERRUPT_EXI_1_TC: + case __OS_INTERRUPT_EXI_1_EXT: + reg = __EXIRegs[5]; + reg &= ~0xC0F; + + if (!(current & OS_INTERRUPTMASK_EXI_1_EXI)) + reg |= 0x1; + if (!(current & OS_INTERRUPTMASK_EXI_1_TC)) + reg |= 0x4; + if (!(current & OS_INTERRUPTMASK_EXI_1_EXT)) + reg |= 0x400; + __EXIRegs[5] = reg; + mask &= ~OS_INTERRUPTMASK_EXI_1; + break; + case __OS_INTERRUPT_EXI_2_EXI: + case __OS_INTERRUPT_EXI_2_TC: + reg = __EXIRegs[10]; + reg &= ~0xF; + if (!(current & OS_INTERRUPTMASK_EXI_2_EXI)) + reg |= 0x1; + if (!(current & OS_INTERRUPTMASK_EXI_2_TC)) + reg |= 0x4; + + __EXIRegs[10] = reg; + mask &= ~OS_INTERRUPTMASK_EXI_2; + break; + 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)) { + reg |= 0x800; + } + if (!(current & OS_INTERRUPTMASK_PI_SI)) { + reg |= 0x8; + } + if (!(current & OS_INTERRUPTMASK_PI_DI)) { + reg |= 0x4; + } + if (!(current & OS_INTERRUPTMASK_PI_RSW)) { + reg |= 0x2; + } + if (!(current & OS_INTERRUPTMASK_PI_ERROR)) { + reg |= 0x1; + } + if (!(current & OS_INTERRUPTMASK_PI_VI)) { + reg |= 0x100; + } + if (!(current & OS_INTERRUPTMASK_PI_DEBUG)) { + reg |= 0x1000; + } + if (!(current & OS_INTERRUPTMASK_PI_PE_TOKEN)) { + reg |= 0x200; + } + if (!(current & OS_INTERRUPTMASK_PI_PE_FINISH)) { + reg |= 0x400; + } + if (!(current & OS_INTERRUPTMASK_PI_HSP)) { + reg |= 0x2000; + } + __PIRegs[1] = reg; + mask &= ~OS_INTERRUPTMASK_PI; + break; + default: + break; + } + return mask; +} + +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; + OSInterruptMask local; + OSInterruptMask mask; + + enabled = OSDisableInterrupts(); + prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4); + local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8); + mask = ~(prev | local) & global; + global |= prev; + *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global; + while (mask) { + mask = SetInterruptMask(mask, global | local); + } + OSRestoreInterrupts(enabled); + return prev; +} + +OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask global) { + BOOL enabled; + OSInterruptMask prev; + OSInterruptMask local; + OSInterruptMask mask; + + enabled = OSDisableInterrupts(); + prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4); + local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8); + mask = (prev | local) & global; + global = prev & ~global; + *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global; + while (mask) { + mask = SetInterruptMask(mask, global | local); + } + OSRestoreInterrupts(enabled); + return prev; +} + +volatile OSTime __OSLastInterruptTime; +volatile __OSInterrupt __OSLastInterrupt; +volatile u32 __OSLastInterruptSrr0; + +void __OSDispatchInterrupt(__OSException exception, OSContext* context) { + u32 intsr; + u32 reg; + OSInterruptMask cause; + OSInterruptMask unmasked; + OSInterruptMask* prio; + __OSInterrupt interrupt; + __OSInterruptHandler handler; + intsr = __PIRegs[0]; + intsr &= ~0x00010000; + + if (intsr == 0 || (intsr & __PIRegs[1]) == 0) { + OSLoadContext(context); + } + + cause = 0; + + if (intsr & 0x00000080) { + reg = __MEMRegs[15]; + if (reg & 0x1) + cause |= OS_INTERRUPTMASK_MEM_0; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_MEM_1; + if (reg & 0x4) + cause |= OS_INTERRUPTMASK_MEM_2; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_MEM_3; + if (reg & 0x10) + cause |= OS_INTERRUPTMASK_MEM_ADDRESS; + } + + if (intsr & 0x00000040) { + reg = __DSPRegs[5]; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_DSP_AI; + if (reg & 0x20) + cause |= OS_INTERRUPTMASK_DSP_ARAM; + if (reg & 0x80) + cause |= OS_INTERRUPTMASK_DSP_DSP; + } + + if (intsr & 0x00000020) { + reg = __AIRegs[0]; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_AI_AI; + } + + if (intsr & 0x00000010) { + reg = __EXIRegs[0]; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_EXI_0_EXI; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_EXI_0_TC; + if (reg & 0x800) + cause |= OS_INTERRUPTMASK_EXI_0_EXT; + reg = __EXIRegs[5]; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_EXI_1_EXI; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_EXI_1_TC; + if (reg & 0x800) + cause |= OS_INTERRUPTMASK_EXI_1_EXT; + reg = __EXIRegs[10]; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_EXI_2_EXI; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_EXI_2_TC; + } + + if (intsr & 0x00002000) + cause |= OS_INTERRUPTMASK_PI_HSP; + if (intsr & 0x00001000) + cause |= OS_INTERRUPTMASK_PI_DEBUG; + if (intsr & 0x00000400) + cause |= OS_INTERRUPTMASK_PI_PE_FINISH; + if (intsr & 0x00000200) + cause |= OS_INTERRUPTMASK_PI_PE_TOKEN; + if (intsr & 0x00000100) + cause |= OS_INTERRUPTMASK_PI_VI; + if (intsr & 0x00000008) + cause |= OS_INTERRUPTMASK_PI_SI; + if (intsr & 0x00000004) + cause |= OS_INTERRUPTMASK_PI_DI; + if (intsr & 0x00000002) + cause |= OS_INTERRUPTMASK_PI_RSW; + if (intsr & 0x00000800) + cause |= OS_INTERRUPTMASK_PI_CP; + if (intsr & 0x00000001) + cause |= OS_INTERRUPTMASK_PI_ERROR; + + unmasked = cause & ~(*(OSInterruptMask*)OSPhysicalToCached(0x00C4) | + *(OSInterruptMask*)OSPhysicalToCached(0x00C8)); + if (unmasked) { + for (prio = InterruptPrioTable;; ++prio) { + if (unmasked & *prio) { + interrupt = (__OSInterrupt)__cntlzw(unmasked & *prio); + break; + } + } + + handler = __OSGetInterruptHandler(interrupt); + if (handler) { + if (__OS_INTERRUPT_MEM_ADDRESS < interrupt) { + __OSLastInterrupt = interrupt; + __OSLastInterruptTime = OSGetTime(); + __OSLastInterruptSrr0 = context->srr0; + } + + OSDisableScheduler(); + handler(interrupt, context); + OSEnableScheduler(); + __OSReschedule(); + OSLoadContext(context); + } + } + + OSLoadContext(context); +} + +static asm void ExternalInterruptHandler(register __OSException exception, + register OSContext* context) { +#pragma unused(exception) + // clang-format off + nofralloc + OS_EXCEPTION_SAVE_GPRS(context) + + stwu r1, -8(r1) + b __OSDispatchInterrupt + // clang-format on +} diff --git a/libs/dolphin/os/OSLink.c b/libs/dolphin/os/OSLink.c new file mode 100644 index 000000000..d6f5a51d7 --- /dev/null +++ b/libs/dolphin/os/OSLink.c @@ -0,0 +1,556 @@ +#include + +#define SHN_UNDEF 0 +#define SHN_LORESERVE 0xff00 +#define SHN_LOPROC 0xff00 +#define SHN_HIPROC 0xff1f +#define SHN_ABS 0xfff1 +#define SHN_COMMON 0xfff2 +#define SHN_HIRESERVE 0xffff + +#define ELF32_R_SYM(i) ((i) >> 8) +#define ELF32_R_TYPE(i) ((unsigned char)(i)) +#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_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_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_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 + +OSModuleQueue __OSModuleInfoList : (OS_BASE_CACHED | 0x30C8); +const void* __OSStringTable : (OS_BASE_CACHED | 0x30D0); + +#pragma dont_inline on +__declspec(weak) void OSNotifyLink(OSModuleInfo* module) {} + +__declspec(weak) void OSNotifyUnlink(OSModuleInfo* module) {} + +#pragma dont_inline reset + +#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) + +#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) + +void OSSetStringTable(const void* stringTable) { __OSStringTable = stringTable; } + +static BOOL Relocate(OSModuleHeader* newModule, OSModuleHeader* module) { + OSModuleID idNew; + OSImportInfo* imp; + OSRel* rel; + OSSectionInfo* si; + OSSectionInfo* siFlush; + u32* p; + u32 offset; + u32 x; + + idNew = newModule ? newModule->info.id : 0; + for (imp = (OSImportInfo*)module->impOffset; + imp < (OSImportInfo*)(module->impOffset + module->impSize); imp++) { + if (imp->id == idNew) { + goto Found; + } + } + return FALSE; + +Found: + siFlush = 0; + for (rel = (OSRel*)imp->offset; rel->type != R_DOLPHIN_END; rel++) { + (u8*)p += rel->offset; + if (idNew) { + si = &OSGetSectionInfo(newModule)[rel->section]; + offset = OS_SECTIONINFO_OFFSET(si->offset); + } else { + offset = 0; + } + switch (rel->type) { + case R_PPC_NONE: + break; + case R_PPC_ADDR32: + x = offset + rel->addend; + *p = x; + break; + case R_PPC_ADDR24: + x = offset + rel->addend; + *p = (*p & ~0x03fffffc) | (x & 0x03fffffc); + break; + case R_PPC_ADDR16: + x = offset + rel->addend; + *(u16*)p = (u16)(x & 0xffff); + break; + case R_PPC_ADDR16_LO: + x = offset + rel->addend; + *(u16*)p = (u16)(x & 0xffff); + break; + case R_PPC_ADDR16_HI: + x = offset + rel->addend; + *(u16*)p = (u16)(((x >> 16) & 0xffff)); + break; + case R_PPC_ADDR16_HA: + x = offset + rel->addend; + *(u16*)p = (u16)(((x >> 16) + ((x & 0x8000) ? 1 : 0)) & 0xffff); + break; + case R_PPC_ADDR14: + case R_PPC_ADDR14_BRTAKEN: + case R_PPC_ADDR14_BRNTAKEN: + x = offset + rel->addend; + *p = (*p & ~0x0000fffc) | (x & 0x0000fffc); + break; + case R_PPC_REL24: + x = offset + rel->addend - (u32)p; + *p = (*p & ~0x03fffffc) | (x & 0x03fffffc); + break; + case R_PPC_REL14: + case R_PPC_REL14_BRTAKEN: + case R_PPC_REL14_BRNTAKEN: + x = offset + rel->addend - (u32)p; + *p = (*p & ~0x0000fffc) | (x & 0x0000fffc); + break; + case R_DOLPHIN_NOP: + break; + case R_DOLPHIN_SECTION: + si = &OSGetSectionInfo(module)[rel->section]; + p = (u32*)OS_SECTIONINFO_OFFSET(si->offset); + if (siFlush) { + offset = OS_SECTIONINFO_OFFSET(siFlush->offset); + DCFlushRange((void*)offset, siFlush->size); + ICInvalidateRange((void*)offset, siFlush->size); + } + siFlush = (si->offset & OS_SECTIONINFO_EXEC) ? si : 0; + break; + default: + OSReport("OSLink: unknown relocation type %3d\n", rel->type); + break; + } + } + + if (siFlush) { + offset = OS_SECTIONINFO_OFFSET(siFlush->offset); + DCFlushRange((void*)offset, siFlush->size); + ICInvalidateRange((void*)offset, siFlush->size); + } + + return TRUE; +} + +#if OS_MODULE_VERSION >= 3 +static BOOL Link(OSModuleInfo* newModule, void* bss, BOOL fixed) { + u32 i; + OSSectionInfo* si; + OSModuleHeader* moduleHeader; + OSModuleInfo* moduleInfo; + OSImportInfo* imp; + + moduleHeader = (OSModuleHeader*)newModule; + moduleHeader->bssSection = 0; + + if (OS_MODULE_VERSION < newModule->version || + 2 <= newModule->version && + (moduleHeader->align && (u32)newModule % moduleHeader->align != 0 || + moduleHeader->bssAlign && (u32)bss % moduleHeader->bssAlign != 0)) { + return FALSE; + } + + EnqueueTail(&__OSModuleInfoList, newModule, link); + newModule->sectionInfoOffset += (u32)moduleHeader; + moduleHeader->relOffset += (u32)moduleHeader; + moduleHeader->impOffset += (u32)moduleHeader; + if (3 <= newModule->version) { + moduleHeader->fixSize += (u32)moduleHeader; + } + for (i = 1; i < newModule->numSections; i++) { + si = &OSGetSectionInfo(newModule)[i]; + if (si->offset != 0) { + si->offset += (u32)moduleHeader; + } else if (si->size != 0) { + moduleHeader->bssSection = (u8)i; + si->offset = (u32)bss; + bss = (void*)((u32)bss + si->size); + } + } + for (imp = (OSImportInfo*)moduleHeader->impOffset; + imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) { + imp->offset += (u32)moduleHeader; + } + if (moduleHeader->prologSection != SHN_UNDEF) { + moduleHeader->prolog += + OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->prologSection].offset); + } + if (moduleHeader->epilogSection != SHN_UNDEF) { + moduleHeader->epilog += + OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->epilogSection].offset); + } + if (moduleHeader->unresolvedSection != SHN_UNDEF) { + moduleHeader->unresolved += + OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->unresolvedSection].offset); + } + if (__OSStringTable) { + newModule->nameOffset += (u32)__OSStringTable; + } + + Relocate(0, moduleHeader); + + for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) { + Relocate(moduleHeader, (OSModuleHeader*)moduleInfo); + if (moduleInfo != newModule) { + Relocate((OSModuleHeader*)moduleInfo, moduleHeader); + } + } + + if (fixed) { + for (imp = (OSImportInfo*)moduleHeader->impOffset; + imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) { + if (imp->id == 0 || imp->id == newModule->id) { + moduleHeader->impSize = (u32)((u8*)imp - (u8*)moduleHeader->impOffset); + break; + } + } + } + + memset(bss, 0, moduleHeader->bssSize); + + OSNotifyLink(newModule); + + return TRUE; +} + +BOOL OSLink(OSModuleInfo* newModule, void* bss) { return Link(newModule, bss, FALSE); } + +BOOL OSLinkFixed(OSModuleInfo* newModule, void* bss) { + if (OS_MODULE_VERSION < newModule->version || newModule->version < 3) { + return FALSE; + } + return Link(newModule, bss, TRUE); +} +#else +BOOL OSLink(OSModuleInfo* newModule, void* bss) { + u32 i; + OSSectionInfo* si; + OSModuleHeader* moduleHeader; + OSModuleInfo* moduleInfo; + OSImportInfo* imp; + + moduleHeader = (OSModuleHeader*)newModule; + moduleHeader->bssSection = 0; + + if (OS_MODULE_VERSION < newModule->version || + 2 <= newModule->version && + (moduleHeader->align && (u32)newModule % moduleHeader->align != 0 || + moduleHeader->bssAlign && (u32)bss % moduleHeader->bssAlign != 0)) { + return FALSE; + } + + EnqueueTail(&__OSModuleInfoList, newModule, link); + memset(bss, 0, moduleHeader->bssSize); + newModule->sectionInfoOffset += (u32)moduleHeader; + moduleHeader->relOffset += (u32)moduleHeader; + moduleHeader->impOffset += (u32)moduleHeader; + + for (i = 1; i < newModule->numSections; i++) { + si = &OSGetSectionInfo(newModule)[i]; + if (si->offset != 0) { + si->offset += (u32)moduleHeader; + } else if (si->size != 0) { + moduleHeader->bssSection = (u8)i; + si->offset = (u32)bss; + bss = (void*)((u32)bss + si->size); + } + } + for (imp = (OSImportInfo*)moduleHeader->impOffset; + imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) { + imp->offset += (u32)moduleHeader; + } + if (moduleHeader->prologSection != SHN_UNDEF) { + moduleHeader->prolog += + OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->prologSection].offset); + } + if (moduleHeader->epilogSection != SHN_UNDEF) { + moduleHeader->epilog += + OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->epilogSection].offset); + } + if (moduleHeader->unresolvedSection != SHN_UNDEF) { + moduleHeader->unresolved += + OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->unresolvedSection].offset); + } + if (__OSStringTable) { + newModule->nameOffset += (u32)__OSStringTable; + } + + Relocate(0, moduleHeader); + + for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) { + Relocate(moduleHeader, (OSModuleHeader*)moduleInfo); + if (moduleInfo != newModule) { + Relocate((OSModuleHeader*)moduleInfo, moduleHeader); + } + } + + OSNotifyLink(newModule); + + return TRUE; +} +#endif + +static BOOL Undo(OSModuleHeader* newModule, OSModuleHeader* module) { + OSModuleID idNew; + OSImportInfo* imp; + OSRel* rel; + OSSectionInfo* si; + OSSectionInfo* siFlush; + u32* p; + u32 offset; + u32 x; + + idNew = newModule->info.id; + for (imp = (OSImportInfo*)module->impOffset; + imp < (OSImportInfo*)(module->impOffset + module->impSize); imp++) { + if (imp->id == idNew) { + goto Found; + } + } + return FALSE; + +Found: + siFlush = 0; + for (rel = (OSRel*)imp->offset; rel->type != R_DOLPHIN_END; rel++) { + (u8*)p += rel->offset; + si = &OSGetSectionInfo(newModule)[rel->section]; + offset = OS_SECTIONINFO_OFFSET(si->offset); + x = 0; + switch (rel->type) { + case R_PPC_NONE: + break; + case R_PPC_ADDR32: + *p = x; + break; + case R_PPC_ADDR24: + *p = (*p & ~0x03fffffc) | (x & 0x03fffffc); + break; + case R_PPC_ADDR16: + *(u16*)p = (u16)(x & 0xffff); + break; + case R_PPC_ADDR16_LO: + *(u16*)p = (u16)(x & 0xffff); + break; + case R_PPC_ADDR16_HI: + *(u16*)p = (u16)(((x >> 16) & 0xffff)); + break; + case R_PPC_ADDR16_HA: + *(u16*)p = (u16)(((x >> 16) + ((x & 0x8000) ? 1 : 0)) & 0xffff); + break; + case R_PPC_ADDR14: + case R_PPC_ADDR14_BRTAKEN: + case R_PPC_ADDR14_BRNTAKEN: + *p = (*p & ~0x0000fffc) | (x & 0x0000fffc); + break; + case R_PPC_REL24: + if (module->unresolvedSection != SHN_UNDEF) { + x = (u32)module->unresolved - (u32)p; + } + *p = (*p & ~0x03fffffc) | (x & 0x03fffffc); + break; + case R_PPC_REL14: + case R_PPC_REL14_BRTAKEN: + case R_PPC_REL14_BRNTAKEN: + *p = (*p & ~0x0000fffc) | (x & 0x0000fffc); + break; + case R_DOLPHIN_NOP: + break; + case R_DOLPHIN_SECTION: + si = &OSGetSectionInfo(module)[rel->section]; + p = (u32*)OS_SECTIONINFO_OFFSET(si->offset); + if (siFlush) { + offset = OS_SECTIONINFO_OFFSET(siFlush->offset); + DCFlushRange((void*)offset, siFlush->size); + ICInvalidateRange((void*)offset, siFlush->size); + } + siFlush = (si->offset & OS_SECTIONINFO_EXEC) ? si : 0; + break; + default: + OSReport("OSUnlink: unknown relocation type %3d\n", rel->type); + break; + } + } + + if (siFlush) { + offset = OS_SECTIONINFO_OFFSET(siFlush->offset); + DCFlushRange((void*)offset, siFlush->size); + ICInvalidateRange((void*)offset, siFlush->size); + } + + return TRUE; +} + +BOOL OSUnlink(OSModuleInfo* oldModule) { + OSModuleHeader* moduleHeader; + OSModuleInfo* moduleInfo; + u32 i; + OSSectionInfo* si; + OSImportInfo* imp; + + moduleHeader = (OSModuleHeader*)oldModule; + + DequeueItem(&__OSModuleInfoList, oldModule, link); + + for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) { + Undo(moduleHeader, (OSModuleHeader*)moduleInfo); + } + + OSNotifyUnlink(oldModule); + + if (__OSStringTable) { + oldModule->nameOffset -= (u32)__OSStringTable; + } + if (moduleHeader->prologSection != SHN_UNDEF) { + moduleHeader->prolog -= + OS_SECTIONINFO_OFFSET(OSGetSectionInfo(oldModule)[moduleHeader->prologSection].offset); + } + if (moduleHeader->epilogSection != SHN_UNDEF) { + moduleHeader->epilog -= + OS_SECTIONINFO_OFFSET(OSGetSectionInfo(oldModule)[moduleHeader->epilogSection].offset); + } + if (moduleHeader->unresolvedSection != SHN_UNDEF) { + moduleHeader->unresolved -= + OS_SECTIONINFO_OFFSET(OSGetSectionInfo(oldModule)[moduleHeader->unresolvedSection].offset); + } + for (imp = (OSImportInfo*)moduleHeader->impOffset; + imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) { + imp->offset -= (u32)moduleHeader; + } + for (i = 1; i < oldModule->numSections; i++) { + si = &OSGetSectionInfo(oldModule)[i]; + if (i == moduleHeader->bssSection) { + moduleHeader->bssSection = 0; + si->offset = 0; + } else if (si->offset != 0) { + si->offset -= (u32)moduleHeader; + } + } + moduleHeader->relOffset -= (u32)moduleHeader; + moduleHeader->impOffset -= (u32)moduleHeader; + oldModule->sectionInfoOffset -= (u32)moduleHeader; + + return TRUE; +} + +void __OSModuleInit(void) { + __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; + } + + for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) { + sectionInfo = OSGetSectionInfo(moduleInfo); + for (i = 0; i < moduleInfo->numSections; ++i) { + if (sectionInfo->size) { + baseSection = OS_SECTIONINFO_OFFSET(sectionInfo->offset); + if (baseSection <= (u32)ptr && (u32)ptr < baseSection + sectionInfo->size) { + if (section) { + *section = i; + } + if (offset) { + *offset = (u32)ptr - baseSection; + } + return moduleInfo; + } + } + sectionInfo++; + } + } + + return NULL; +} diff --git a/libs/dolphin/os/OSMemory.c b/libs/dolphin/os/OSMemory.c new file mode 100644 index 000000000..71d3097af --- /dev/null +++ b/libs/dolphin/os/OSMemory.c @@ -0,0 +1,223 @@ +#include + +#define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) +#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) + +vu16 __MEMRegs[64] : 0xCC004000; + +static BOOL OnReset(BOOL final); + +static OSResetFunctionInfo ResetFunctionInfo = { + OnReset, + 127, +}; + +u32 OSGetPhysicalMemSize() { return *(u32 *)(OSPhysicalToCached(0x0028)); } + +u32 OSGetConsoleSimulatedMemSize() { return *(u32 *)(OSPhysicalToCached(0x00F0)); } + +static BOOL OnReset(BOOL final) { + if (final != FALSE) { + __MEMRegs[8] = 0xFF; + __OSMaskInterrupts(0xf0000000); + } + return TRUE; +} + +static void MEMIntrruptHandler(__OSInterrupt interrupt, OSContext* context) { + u32 addr; + u32 cause; + + cause = __MEMRegs[0xf]; + addr = (((u32)__MEMRegs[0x12] & 0x3ff) << 16) | __MEMRegs[0x11]; + __MEMRegs[0x10] = 0; + + if (__OSErrorTable[OS_ERROR_PROTECTION]) { + __OSErrorTable[OS_ERROR_PROTECTION](OS_ERROR_PROTECTION, context, cause, addr); + return; + } + + __OSUnhandledException(OS_ERROR_PROTECTION, context, cause, addr); +} + +void OSProtectRange(u32 chan, void* addr, u32 nBytes, u32 control) { + BOOL enabled; + u32 start; + u32 end; + u16 reg; + if (4 <= chan) { + return; + } + + control &= OS_PROTECT_CONTROL_RDWR; + + end = (u32)addr + nBytes; + start = TRUNC(addr, 1u << 10); + end = ROUND(end, 1u << 10); + + DCFlushRange((void*)start, end - start); + + enabled = OSDisableInterrupts(); + + __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 |= control << 2 * chan; + __MEMRegs[8] = reg; + + if (control != OS_PROTECT_CONTROL_RDWR) { + __OSUnmaskInterrupts(OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_0 + chan)); + } + + OSRestoreInterrupts(enabled); +} + +asm void Config24MB() { + // clang-format off + nofralloc + + addi r7,r0,0 + + addis r4,r0,0x00000002@ha + addi r4,r4,0x00000002@l + addis r3,r0,0x800001ff@ha + addi r3,r3,0x800001ff@l + + addis r6,r0,0x01000002@ha + addi r6,r6,0x01000002@l + addis r5,r0,0x810000ff@ha + addi r5,r5,0x810000ff@l + + isync + + mtspr dbat0u,r7 + mtspr dbat0l,r4 + mtspr dbat0u,r3 + isync + + mtspr ibat0u,r7 + mtspr ibat0l,r4 + mtspr ibat0u,r3 + isync + + mtspr dbat2u,r7 + mtspr dbat2l,r6 + mtspr dbat2u,r5 + isync + + mtspr ibat2u,r7 + mtspr ibat2l,r6 + mtspr ibat2u,r5 + isync + + mfmsr r3 + ori r3, r3, 0x30 + mtsrr1 r3 + + mflr r3 + mtsrr0 r3 + rfi + // clang-format on +} + +asm void Config48MB() { + // clang-format off + nofralloc + + addi r7,r0,0x0000 + + addis r4,r0,0x00000002@ha + addi r4,r4,0x00000002@l + addis r3,r0,0x800003ff@ha + addi r3,r3,0x800003ff@l + + addis r6,r0,0x02000002@ha + addi r6,r6,0x02000002@l + addis r5,r0,0x820001ff@ha + addi r5,r5,0x820001ff@l + + isync + + mtspr dbat0u,r7 + mtspr dbat0l,r4 + mtspr dbat0u,r3 + isync + + mtspr ibat0u,r7 + mtspr ibat0l,r4 + mtspr ibat0u,r3 + isync + + mtspr dbat2u,r7 + mtspr dbat2l,r6 + mtspr dbat2u,r5 + isync + + mtspr ibat2u,r7 + mtspr ibat2l,r6 + mtspr ibat2u,r5 + isync + + mfmsr r3 + ori r3, r3, 0x30 + mtsrr1 r3 + + mflr r3 + mtsrr0 r3 + rfi + // clang-format on +} + +asm void RealMode(register u32 addr) { + // clang-format off + nofralloc + clrlwi r3, r3, 2 + mtsrr0 r3 + mfmsr r3 + rlwinm r3, r3, 0, 28, 25 + mtsrr1 r3 + rfi + // clang-format on +} + +void __OSInitMemoryProtection() { + u32 padding[8]; + u32 simulatedSize; + BOOL enabled; + simulatedSize = OSGetConsoleSimulatedMemSize(); + enabled = OSDisableInterrupts(); + + __MEMRegs[16] = 0; + __MEMRegs[8] = 0xFF; + + __OSMaskInterrupts(OS_INTERRUPTMASK_MEM_0 | OS_INTERRUPTMASK_MEM_1 | OS_INTERRUPTMASK_MEM_2 | + OS_INTERRUPTMASK_MEM_3); + __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) { + DCInvalidateRange((void*)0x81800000, 0x1800000); + __MEMRegs[20] = 2; + } + + if (simulatedSize <= 0x1800000) + { + RealMode((u32)&Config24MB); + } + else if (simulatedSize <= 0x3000000) + { + RealMode((u32)&Config48MB); + } + + __OSUnmaskInterrupts(OS_INTERRUPTMASK_MEM_ADDRESS); + OSRestoreInterrupts(enabled); +} diff --git a/libs/dolphin/os/OSMessage.c b/libs/dolphin/os/OSMessage.c new file mode 100644 index 000000000..db4d2fdd2 --- /dev/null +++ b/libs/dolphin/os/OSMessage.c @@ -0,0 +1,86 @@ +#include + +void OSInitMessageQueue(OSMessageQueue* mq, OSMessage* msgArray, s32 msgCount) { + OSInitThreadQueue(&mq->queueSend); + OSInitThreadQueue(&mq->queueReceive); + mq->msgArray = msgArray; + mq->msgCount = msgCount; + mq->firstIndex = 0; + mq->usedCount = 0; +} + +BOOL OSSendMessage(OSMessageQueue* mq, OSMessage msg, s32 flags) { + BOOL enabled; + s32 lastIndex; + + enabled = OSDisableInterrupts(); + + while (mq->msgCount <= mq->usedCount) { + if (!(flags & OS_MESSAGE_BLOCK)) { + OSRestoreInterrupts(enabled); + return FALSE; + } else { + OSSleepThread(&mq->queueSend); + } + } + + lastIndex = (mq->firstIndex + mq->usedCount) % mq->msgCount; + mq->msgArray[lastIndex] = msg; + mq->usedCount++; + + OSWakeupThread(&mq->queueReceive); + + OSRestoreInterrupts(enabled); + return TRUE; +} + +BOOL OSReceiveMessage(OSMessageQueue* mq, OSMessage* msg, s32 flags) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + + while (mq->usedCount == 0) { + if (!(flags & OS_MESSAGE_BLOCK)) { + OSRestoreInterrupts(enabled); + return FALSE; + } else { + OSSleepThread(&mq->queueReceive); + } + } + + if (msg != NULL) { + *msg = mq->msgArray[mq->firstIndex]; + } + mq->firstIndex = (mq->firstIndex + 1) % mq->msgCount; + mq->usedCount--; + + OSWakeupThread(&mq->queueSend); + + OSRestoreInterrupts(enabled); + return TRUE; +} + +BOOL OSJamMessage(OSMessageQueue* mq, OSMessage msg, s32 flags) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + + while (mq->msgCount <= mq->usedCount) + { + if (!(flags & OS_MESSAGE_BLOCK)) { + OSRestoreInterrupts(enabled); + return FALSE; + } else { + OSSleepThread(&mq->queueSend); + } + } + + mq->firstIndex = (mq->firstIndex + mq->msgCount - 1) % mq->msgCount; + mq->msgArray[mq->firstIndex] = msg; + mq->usedCount++; + + OSWakeupThread(&mq->queueReceive); + + OSRestoreInterrupts(enabled); + return TRUE; +} diff --git a/libs/dolphin/os/OSMutex.c b/libs/dolphin/os/OSMutex.c new file mode 100644 index 000000000..f853729e0 --- /dev/null +++ b/libs/dolphin/os/OSMutex.c @@ -0,0 +1,223 @@ +#include "dolphin/os.h" + +#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) + +#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 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) + +void OSInitMutex(OSMutex* mutex) { + OSInitThreadQueue(&mutex->queue); + mutex->thread = 0; + mutex->count = 0; +} + +void OSLockMutex(OSMutex* mutex) { + BOOL enabled = OSDisableInterrupts(); + OSThread* currentThread = OSGetCurrentThread(); + OSThread* ownerThread; + + while (TRUE) { + ownerThread = ((OSMutex*)mutex)->thread; + if (ownerThread == 0) { + mutex->thread = currentThread; + mutex->count++; + PushTail(¤tThread->queueMutex, mutex, link); + break; + } else if (ownerThread == currentThread) { + mutex->count++; + break; + } else { + currentThread->mutex = mutex; + __OSPromoteThread(mutex->thread, currentThread->priority); + OSSleepThread(&mutex->queue); + currentThread->mutex = 0; + } + } + OSRestoreInterrupts(enabled); +} + +void OSUnlockMutex(OSMutex* mutex) { + BOOL enabled = OSDisableInterrupts(); + OSThread* currentThread = OSGetCurrentThread(); + + if (mutex->thread == currentThread && --mutex->count == 0) { + PopItem(¤tThread->queueMutex, mutex, link); + mutex->thread = NULL; + if (currentThread->priority < currentThread->base) { + currentThread->priority = __OSGetEffectivePriority(currentThread); + } + + OSWakeupThread(&mutex->queue); + } + OSRestoreInterrupts(enabled); +} + +void __OSUnlockAllMutex(OSThread* thread) { + OSMutex* mutex; + + while (thread->queueMutex.head) { + PopHead(&thread->queueMutex, mutex, link); + mutex->count = 0; + mutex->thread = NULL; + OSWakeupThread(&mutex->queue); + } +} + +BOOL OSTryLockMutex(OSMutex* mutex) { + BOOL enabled = OSDisableInterrupts(); + OSThread* currentThread = OSGetCurrentThread(); + BOOL locked; + if (mutex->thread == 0) { + mutex->thread = currentThread; + mutex->count++; + PushTail(¤tThread->queueMutex, mutex, link); + locked = TRUE; + } else if (mutex->thread == currentThread) { + mutex->count++; + locked = TRUE; + } else { + locked = FALSE; + } + OSRestoreInterrupts(enabled); + return locked; +} + +void OSInitCond(OSCond* cond) { OSInitThreadQueue(&cond->queue); } + +void OSWaitCond(OSCond* cond, OSMutex* mutex) { + BOOL enabled = OSDisableInterrupts(); + OSThread* currentThread = OSGetCurrentThread(); + s32 count; + + if (mutex->thread == currentThread) { + count = mutex->count; + mutex->count = 0; + PopItem(¤tThread->queueMutex, mutex, link); + mutex->thread = NULL; + + if (currentThread->priority < currentThread->base) { + currentThread->priority = __OSGetEffectivePriority(currentThread); + } + + OSDisableScheduler(); + OSWakeupThread(&mutex->queue); + OSEnableScheduler(); + OSSleepThread(&cond->queue); + OSLockMutex(mutex); + mutex->count = count; + } + + OSRestoreInterrupts(enabled); +} + +void OSSignalCond(OSCond* cond) { OSWakeupThread(&cond->queue); } + +static BOOL IsMember(OSMutexQueue* queue, OSMutex* mutex) { + OSMutex* member; + + for (member = queue->head; member; member = member->link.next) { + if (mutex == member) + return TRUE; + } + return FALSE; +} + +BOOL __OSCheckMutex(OSMutex* mutex) { + OSThread* thread; + OSThreadQueue* queue; + OSPriority 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->priority < priority) + return FALSE; + priority = thread->priority; + } + + if (mutex->thread) { + if (mutex->count <= 0) + return FALSE; + } else { + if (0 != mutex->count) + return FALSE; + } + + return TRUE; +} + +BOOL __OSCheckDeadLock(OSThread* thread) { + OSMutex* mutex; + + mutex = thread->mutex; + while (mutex && mutex->thread) { + if (mutex->thread == thread) + return TRUE; + mutex = mutex->thread->mutex; + } + return FALSE; +} + +BOOL __OSCheckMutexes(OSThread* thread) { + OSMutex* mutex; + + for (mutex = thread->queueMutex.head; mutex; mutex = mutex->link.next) { + if (mutex->thread != thread) + return FALSE; + if (!__OSCheckMutex(mutex)) + return FALSE; + } + return TRUE; +} diff --git a/libs/dolphin/os/OSReboot.c b/libs/dolphin/os/OSReboot.c new file mode 100644 index 000000000..4fd3bf22e --- /dev/null +++ b/libs/dolphin/os/OSReboot.c @@ -0,0 +1,119 @@ +#include "dolphin/dvd.h" +#include "dolphin/os.h" +#include "dolphin/os/OSBootInfo.h" +#include "dolphin/ai.h" + +// Struct for Apploader header (size 0x20). +typedef struct _ApploaderHeader { + char date[16]; // _00 + u32 entry; // _10 + u32 size; // _14 + u32 rebootSize; // _18 + u32 reserved2; // _1C +} ApploaderHeader; + +static ApploaderHeader Header ALIGN(32); + +extern void* __OSSavedRegionStart; +extern void* __OSSavedRegionEnd; + +static void* SaveStart = NULL; +static void* SaveEnd = NULL; + +extern u32 UNK_817FFFF8 AT_ADDRESS(0x817FFFF8); +extern u32 UNK_817FFFFC AT_ADDRESS(0x817FFFFC); +extern u32 BOOT_REGION_START AT_ADDRESS(0x812FDFF0); +extern u32 BOOT_REGION_END AT_ADDRESS(0x812FDFEC); +extern u32 OS_RESET_CODE AT_ADDRESS(0x800030F0); +extern u8 OS_REBOOT_BOOL AT_ADDRESS(0x800030E2); // unknown function, set to true by __OSReboot + +static BOOL Prepared = FALSE; + +void __OSDoHotReset(int); + +inline void ReadApploader(OSTime time1) { + if (DVDCheckDisk() == DVD_RESULT_GOOD || OSGetTime() - time1 > OS_TIMER_CLOCK) { + __OSDoHotReset(UNK_817FFFFC); + } +} + +ASM void Run() { +#ifdef __MWERKS__ // clang-format off + nofralloc + sync + isync + mtlr r3 + blr +#endif // clang-format on +} + +static void Callback() { Prepared = TRUE; } + +inline BOOL IsStreamEnabled(void) { + if (DVDGetCurrentDiskID()->streaming) { + return TRUE; + } + return FALSE; +} + +void __OSReboot(u32 resetCode, u32 bootDol) { + OSContext exceptionContext; + OSTime time; + DVDCommandBlock dvdCmd; + DVDCommandBlock dvdCmd2; + DVDCommandBlock dvdCmd3; + u32 numBytes; + u32 offset; + + OSDisableInterrupts(); + UNK_817FFFFC = 0; + UNK_817FFFF8 = 0; + OS_REBOOT_BOOL = TRUE; + BOOT_REGION_START = (u32)SaveStart; + BOOT_REGION_END = (u32)SaveEnd; + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + DVDInit(); + DVDSetAutoInvalidation(TRUE); + DVDResume(); + Prepared = FALSE; + __DVDPrepareResetAsync(Callback); + __OSMaskInterrupts(~0x1F); + __OSUnmaskInterrupts(0x400); + OSEnableInterrupts(); + + time = OSGetTime(); + while (Prepared != TRUE) { + ReadApploader(time); + } + + if (!__OSIsGcam && IsStreamEnabled()) { + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + DVDCancelStreamAsync(&dvdCmd, NULL); + time = OSGetTime(); + while (DVDGetCommandBlockStatus(&dvdCmd)) { + ReadApploader(time); + } + AISetStreamPlayState(0); + } + + DVDReadAbsAsyncPrio(&dvdCmd2, &Header, 32, 0x2440, NULL, 0); + time = OSGetTime(); + while (DVDGetCommandBlockStatus(&dvdCmd2)) { + ReadApploader(time); + } + + offset = Header.size + 0x20; + numBytes = OSRoundUp32B(Header.rebootSize); + DVDReadAbsAsyncPrio(&dvdCmd3, (void*)(OS_BOOTROM_ADDR), numBytes, offset + 0x2440, NULL, 0); + time = OSGetTime(); + while (DVDGetCommandBlockStatus(&dvdCmd3)) { + ReadApploader(time); + } + + ICInvalidateRange((void*)(OS_BOOTROM_ADDR), numBytes); + OSDisableInterrupts(); + ICFlashInvalidate(); + Run((void*)OS_BOOTROM_ADDR); +} \ No newline at end of file diff --git a/libs/dolphin/os/OSReset.c b/libs/dolphin/os/OSReset.c new file mode 100644 index 000000000..1194de004 --- /dev/null +++ b/libs/dolphin/os/OSReset.c @@ -0,0 +1,211 @@ +#include "dolphin/OSRtcPriv.h" +#include "dolphin/os.h" +#include "dolphin/vi.h" +#include "dolphin/hw_regs.h" + +volatile u8 DAT_800030e2 : 0x800030e2; +typedef struct Unk { + u8 pad[0x24]; + u32 resetCode; +} Unk; +volatile Unk DAT_cc003000 : 0xcc003000; + +typedef struct Unk2 { + u16 _0; + u16 _2; +} Unk2; + +volatile Unk2 DAT_cc002000 : 0xcc002000; + +typedef struct OSResetQueue { + OSResetFunctionInfo* first; + OSResetFunctionInfo* last; +} OSResetQueue; + +static OSResetQueue ResetFunctionQueue; +static u32 bootThisDol; + +void OSRegisterResetFunction(OSResetFunctionInfo* func) { + OSResetFunctionInfo* tmp; + OSResetFunctionInfo* iter; + + for (iter = ResetFunctionQueue.first; iter && iter->priority <= func->priority; iter = iter->next) + ; + + 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; + } + + func->next = iter; + tmp = iter->prev; + iter->prev = func; + func->prev = tmp; + if (tmp == NULL) { + ResetFunctionQueue.first = func; + return; + } + tmp->next = func; +} + +BOOL __OSCallResetFunctions(u32 arg0) { + OSResetFunctionInfo *info; + s32 err = 0; + + for (info = ResetFunctionQueue.first; info != NULL && err == 0; info = info->next) + { + err |= !info->func(arg0); + } + err |= !__OSSyncSram() ; + if (err) + { + return 0; + } + return 1; +} + +asm void Reset(register s32 resetCode) { + // clang-format off + nofralloc + b lbl_8038315C +lbl_80383140: + mfspr r8, HID0 + ori r8, r8, 8 + mtspr HID0, r8 + isync + sync + nop + b lbl_80383160 +lbl_8038315C: + b lbl_8038317C +lbl_80383160: + mftb r5, 268 +lbl_80383164: + mftb r6, 268 + subf r7, r5, r6 + cmplwi r7, 0x1124 + blt lbl_80383164 + nop + b lbl_80383180 +lbl_8038317C: + b lbl_8038319C +lbl_80383180: + lis r8, 0xCC003000@h + ori r8, r8, 0xCC003000@l + li r4, 3 + stw r4, 0x24(r8) + stw r3, 0x24(r8) + nop + b lbl_803831A0 +lbl_8038319C: + b lbl_803831A8 +lbl_803831A0: + nop + b lbl_803831A0 +lbl_803831A8: + b lbl_80383140 + // clang-format on +} + +OSThreadQueue __OSActiveThreadQueue : (OS_BASE_CACHED | 0x00DC); + +static void KillThreads(void) { + OSThread* thread; + OSThread* next; + + for (thread = __OSActiveThreadQueue.head; thread; thread = next) { + next = thread->linkActive.next; + switch (thread->state) { + case 1: + case 4: + OSCancelThread(thread); + break; + default: + break; + } + } +} + +void __OSDoHotReset(s32 arg0) { + OSDisableInterrupts(); + __VIRegs[1] = 0; + ICFlashInvalidate(); + Reset(arg0 * 8); +} + +void OSResetSystem(int reset, u32 resetCode, BOOL forceMenu) +{ + BOOL rc; + BOOL disableRecalibration; + u32 unk[3]; // dumb compiler + + OSDisableScheduler(); + __OSStopAudioSystem(); + + if (reset == OS_RESET_SHUTDOWN || (reset == OS_RESET_RESTART && bootThisDol != 0)) + { + disableRecalibration = __PADDisableRecalibration(TRUE); + } + + while (!__OSCallResetFunctions(FALSE)) + { + ; + } + + if (reset == OS_RESET_HOTRESET && forceMenu) + { + OSSram *sram; + + sram = __OSLockSram(); + sram->flags |= 0x40; + __OSUnlockSram(TRUE); + + while (!__OSSyncSram()) + { + ; + } + } + + OSDisableInterrupts(); + __OSCallResetFunctions(TRUE); + LCDisable(); + if (reset == OS_RESET_HOTRESET) + { + __OSDoHotReset(resetCode); + } + else if (reset == OS_RESET_RESTART) + { + if ((*(u32 *)OSPhysicalToCached(0x30EC) = bootThisDol) != 0) + { + __PADDisableRecalibration(disableRecalibration); + } + KillThreads(); + OSEnableScheduler(); + __OSReboot(resetCode, forceMenu); + } + + KillThreads(); + memset(OSPhysicalToCached(0x40), 0, 0xCC - 0x40); + memset(OSPhysicalToCached(0xD4), 0, 0xE8 - 0xD4); + memset(OSPhysicalToCached(0xF4), 0, 0xF8 - 0xF4); + memset(OSPhysicalToCached(0x3000), 0, 0xC0); + memset(OSPhysicalToCached(0x30C8), 0, 0xD4 - 0xC8); + memset(OSPhysicalToCached(0x30E2), 0, 1); + + __PADDisableRecalibration(disableRecalibration); +} + +u32 OSGetResetCode(void) { + if (DAT_800030e2 != 0) { + return 0x80000000; + } + return ((DAT_cc003000.resetCode & ~7) >> 3); +} diff --git a/libs/dolphin/os/OSResetSW.c b/libs/dolphin/os/OSResetSW.c new file mode 100644 index 000000000..24766fd35 --- /dev/null +++ b/libs/dolphin/os/OSResetSW.c @@ -0,0 +1,118 @@ +#include + +extern OSTime __OSGetSystemTime(); + +u8 GameChoice : (OS_BASE_CACHED | 0x30E3); + +vu32 __PIRegs[12] : 0xCC003000; + +extern OSTime __OSStartTime; + +static OSResetCallback ResetCallback; +static BOOL Down; +static BOOL LastState; +static OSTime HoldUp; +static OSTime HoldDown; + +void __OSResetSWInterruptHandler(__OSInterrupt interrupt, OSContext *context) +{ + OSResetCallback callback; + + HoldDown = __OSGetSystemTime(); + while (__OSGetSystemTime() - HoldDown < OSMicrosecondsToTicks(100) && + !(__PIRegs[0] & 0x00010000)) + { + ; + } + if (!(__PIRegs[0] & 0x00010000)) + { + LastState = Down = TRUE; + __OSMaskInterrupts(OS_INTERRUPTMASK_PI_RSW); + if (ResetCallback) + { + callback = ResetCallback; + ResetCallback = NULL; + callback(); + } + } + __PIRegs[0] = 2; +} + +BOOL OSGetResetButtonState(void) +{ + BOOL enabled; + BOOL state; + u32 reg; + OSTime now; + + enabled = OSDisableInterrupts(); + + now = __OSGetSystemTime(); + + reg = __PIRegs[0]; + if (!(reg & 0x00010000)) + { + if (!Down) + { + Down = TRUE; + state = HoldUp ? TRUE : FALSE; + HoldDown = now; + } + else + { + state = (HoldUp || (OSMicrosecondsToTicks(100) < now - HoldDown)) ? TRUE : FALSE; + } + } + else if (Down) + { + Down = FALSE; + state = LastState; + if (state) + { + HoldUp = now; + } + else + { + HoldUp = 0; + } + } + else if (HoldUp && (now - HoldUp < OSMillisecondsToTicks(40))) + { + state = TRUE; + } + else + { + state = FALSE; + HoldUp = 0; + } + + LastState = state; + + if (GameChoice & 0x1f) + { + OSTime fire = (GameChoice & 0x1f) * 60; + fire = __OSStartTime + OSSecondsToTicks(fire); + if (fire < now) + { + now -= fire; + now = OSTicksToSeconds(now) / 2; + if ((now & 1) == 0) + { + state = TRUE; + } + else + { + state = FALSE; + } + } + } + + OSRestoreInterrupts(enabled); + return state; +} + +#pragma dont_inline on + +BOOL OSGetResetSwitchState(void) { return OSGetResetButtonState(); } + +#pragma dont_inline reset diff --git a/libs/dolphin/os/OSRtc.c b/libs/dolphin/os/OSRtc.c new file mode 100644 index 000000000..b76bcdc21 --- /dev/null +++ b/libs/dolphin/os/OSRtc.c @@ -0,0 +1,399 @@ +#include "dolphin/OSRtcPriv.h" +#include "dolphin/os.h" + +#define RTC_CMD_READ 0x20000000 +#define RTC_CMD_WRITE 0xa0000000 + +#define RTC_SRAM_ADDR 0x00000100 +#define RTC_SRAM_SIZE 64 + +#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; + +static SramControlBlock Scb ALIGN(32); + +static BOOL GetRTC(u32* rtc) { + BOOL err; + u32 cmd; + + if (!EXILock(RTC_CHAN, RTC_DEV, 0)) { + return FALSE; + } + if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { + EXIUnlock(RTC_CHAN); + return FALSE; + } + + cmd = RTC_CMD_READ; + err = FALSE; + err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL); + err |= !EXISync(RTC_CHAN); + err |= !EXIImm(RTC_CHAN, &cmd, 4, 0, NULL); + err |= !EXISync(RTC_CHAN); + err |= !EXIDeselect(RTC_CHAN); + EXIUnlock(RTC_CHAN); + + *rtc = cmd; + + return !err; +} + +BOOL __OSGetRTC(u32* rtc) { + BOOL err; + u32 t0; + u32 t1; + int i; + + for (i = 0; i < 16; i++) { + err = FALSE; + err |= !GetRTC(&t0); + err |= !GetRTC(&t1); + if (err) { + break; + } + if (t0 == t1) { + *rtc = t0; + return TRUE; + } + } + return FALSE; +} + +BOOL __OSSetRTC(u32 rtc) { + BOOL err; + u32 cmd; + + if (!EXILock(RTC_CHAN, RTC_DEV, 0)) { + return FALSE; + } + if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { + EXIUnlock(RTC_CHAN); + return FALSE; + } + + cmd = RTC_CMD_WRITE; + err = FALSE; + err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL); + err |= !EXISync(RTC_CHAN); + err |= !EXIImm(RTC_CHAN, &rtc, 4, 1, NULL); + err |= !EXISync(RTC_CHAN); + err |= !EXIDeselect(RTC_CHAN); + EXIUnlock(RTC_CHAN); + + return !err; +} + +static BOOL ReadSram(void* buffer) { + BOOL err; + u32 cmd; + + DCInvalidateRange(buffer, RTC_SRAM_SIZE); + + if (!EXILock(RTC_CHAN, RTC_DEV, 0)) { + return FALSE; + } + if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { + EXIUnlock(RTC_CHAN); + return FALSE; + } + + 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); + + return !err; +} + +BOOL WriteSram(void* buffer, u32 offset, u32 size); +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; + } +} + +BOOL WriteSram(void* buffer, u32 offset, u32 size) { + BOOL err; + u32 cmd; + + if (!EXILock(RTC_CHAN, RTC_DEV, WriteSramCallback)) { + return FALSE; + } + if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { + EXIUnlock(RTC_CHAN); + return FALSE; + } + + 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); + + return !err; +} + +void __OSInitSram() { + Scb.locked = Scb.enabled = FALSE; + Scb.sync = ReadSram(Scb.sram); + Scb.offset = RTC_SRAM_SIZE; + + OSSetGbsMode(OSGetGbsMode()); +} + +static void* LockSram(u32 offset) { + BOOL enabled; + enabled = OSDisableInterrupts(); + + if (Scb.locked != FALSE) { + OSRestoreInterrupts(enabled); + return NULL; + } + + Scb.enabled = enabled; + Scb.locked = TRUE; + + return Scb.sram + offset; +} + +OSSram* __OSLockSram() { return LockSram(0); } + +OSSramEx* __OSLockSramEx() { return LockSram(sizeof(OSSram)); } + +static BOOL UnlockSram(BOOL commit, u32 offset) { + u16* p; + + if (commit) { + if (offset == 0) { + 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++) { + sram->checkSum += *p; + sram->checkSumInv += ~*p; + } + } + + if (offset < Scb.offset) { + Scb.offset = offset; + } + // this isn't in prime? + if (Scb.offset <= 20) + { + // this seems to work? esp. since we have GbsMode functions when prime doesn't + // wacky tho + OSSramEx *sramEx = (OSSramEx *)(&Scb.sram[20]); + if ((u32)(sramEx->gbs & 0x7C00) == 0x5000 || (u32)(sramEx->gbs & 0xC0) == 0xC0) + { + sramEx->gbs = 0; + } + } + + Scb.sync = WriteSram(Scb.sram + Scb.offset, Scb.offset, RTC_SRAM_SIZE - Scb.offset); + if (Scb.sync) { + Scb.offset = RTC_SRAM_SIZE; + } + } + Scb.locked = FALSE; + OSRestoreInterrupts(Scb.enabled); + return Scb.sync; +} + +BOOL __OSUnlockSram(BOOL commit) { return UnlockSram(commit, 0); } + +BOOL __OSUnlockSramEx(BOOL commit) { return UnlockSram(commit, sizeof(OSSram)); } + +BOOL __OSSyncSram() { return Scb.sync; } + +BOOL __OSReadROM(void* buffer, s32 length, s32 offset) { + BOOL err; + u32 cmd; + + DCInvalidateRange(buffer, (u32)length); + + if (!EXILock(RTC_CHAN, RTC_DEV, 0)) { + return FALSE; + } + if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { + EXIUnlock(RTC_CHAN); + return FALSE; + } + + cmd = (u32)(offset << 6); + err = FALSE; + err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL); + err |= !EXISync(RTC_CHAN); + err |= !EXIDma(RTC_CHAN, buffer, length, 0, NULL); + err |= !EXISync(RTC_CHAN); + err |= !EXIDeselect(RTC_CHAN); + EXIUnlock(RTC_CHAN); + + return !err; +} + +inline OSSram* __OSLockSramHACK() { return LockSram(0); } +u32 OSGetSoundMode() { + OSSram* sram; + u32 mode; + + sram = __OSLockSramHACK(); + mode = (sram->flags & 0x4) ? OS_SOUND_MODE_STEREO : OS_SOUND_MODE_MONO; + __OSUnlockSram(FALSE); + return mode; +} + +void OSSetSoundMode(u32 mode) { + OSSram* sram; + mode <<= 2; + mode &= 4; + + sram = __OSLockSramHACK(); + if (mode == (sram->flags & 4)) { + __OSUnlockSram(FALSE); + return; + } + + sram->flags &= ~4; + sram->flags |= mode; + __OSUnlockSram(TRUE); +} + +u32 OSGetProgressiveMode() { + OSSram* sram; + u32 mode; + + sram = __OSLockSramHACK(); + mode = (sram->flags & 0x80) >> 7; + __OSUnlockSram(FALSE); + return mode; +} + +void OSSetProgressiveMode(u32 mode) { + OSSram* sram; + mode <<= 7; + mode &= 0x80; + + sram = __OSLockSramHACK(); + if (mode == (sram->flags & 0x80)) { + __OSUnlockSram(FALSE); + return; + } + + sram->flags &= ~0x80; + sram->flags |= mode; + __OSUnlockSram(TRUE); +} + +u8 OSGetLanguage() { + OSSram* sram; + u8 language; + + sram = __OSLockSramHACK(); + language = sram->language; + __OSUnlockSram(FALSE); + return language; +} + +u32 OSGetEuRgb60Mode() { + OSSram *sram; + u32 on; + sram = __OSLockSramHACK(); + on = (sram->ntd >> 6) & 0x1; + __OSUnlockSram(FALSE); + return on; +} + +void OSSetEuRgb60Mode(u32 mode) +{ + OSSram *sram; + mode <<= 6; + mode &= 0x40; + + sram = __OSLockSramHACK(); + if (mode == (sram->ntd & 0x40)) + { + __OSUnlockSram(FALSE); + return; + } + + sram->ntd &= ~0x40; + sram->ntd |= mode; + __OSUnlockSram(TRUE); +} + +u16 OSGetWirelessID(s32 channel) { + OSSramEx* sram; + u16 id; + + sram = __OSLockSramEx(); + id = sram->wirelessPadID[channel]; + __OSUnlockSramEx(FALSE); + return id; +} + +void OSSetWirelessID(s32 channel, u16 id) { + OSSramEx* sram; + + sram = __OSLockSramEx(); + if (sram->wirelessPadID[channel] != id) { + sram->wirelessPadID[channel] = id; + __OSUnlockSramEx(TRUE); + return; + } + + __OSUnlockSramEx(FALSE); +} + +u16 OSGetGbsMode() +{ + OSSramEx *sram; + u16 id; + + sram = __OSLockSramEx(); + id = sram->gbs; + __OSUnlockSramEx(FALSE); + return id; +} + +void OSSetGbsMode(u16 mode) +{ + OSSramEx *sram; + + // same odd code as in UnlockSram? + if ((u32)(mode & 0x7C00) == 0x5000 || (u32)(mode & 0xC0) == 0xC0) + { + mode = 0; + } + + sram = __OSLockSramEx(); + if (mode == sram->gbs) + { + __OSUnlockSramEx(FALSE); + return; + } + + sram->gbs = mode; + __OSUnlockSramEx(TRUE); +} \ No newline at end of file diff --git a/libs/dolphin/os/OSSync.c b/libs/dolphin/os/OSSync.c new file mode 100644 index 000000000..5681518ed --- /dev/null +++ b/libs/dolphin/os/OSSync.c @@ -0,0 +1,29 @@ +#include +#include "dolphin/base/PPCArch.h" +#include "dolphin/os.h" + +void __OSSystemCallVectorStart(); +void __OSSystemCallVectorEnd(); +static asm void SystemCallVector() { + nofralloc +entry __OSSystemCallVectorStart + mfspr r9, HID0 + ori r10, r9, 8 + mtspr HID0, r10 + isync + sync + mtspr HID0, r9 + + rfi + +entry __OSSystemCallVectorEnd + nop +} + +void __OSInitSystemCall() { + void* addr = OSPhysicalToCached(0x00C00); + memcpy(addr, __OSSystemCallVectorStart, (size_t)__OSSystemCallVectorEnd - (size_t)__OSSystemCallVectorStart); + DCFlushRangeNoSync(addr, 0x100); + __sync(); + ICInvalidateRange(addr, 0x100); +} diff --git a/libs/dolphin/os/OSThread.c b/libs/dolphin/os/OSThread.c new file mode 100644 index 000000000..016bfd3bd --- /dev/null +++ b/libs/dolphin/os/OSThread.c @@ -0,0 +1,590 @@ +#include "dolphin/os/OSPriv.h" + +static vu32 RunQueueBits; +static volatile BOOL RunQueueHint; +static vs32 Reschedule; + +static OSThreadQueue RunQueue[32]; +static OSThread IdleThread; +static OSThread DefaultThread; +static OSContext IdleContext; +static void DefaultSwitchThreadCallback(OSThread* from, OSThread* to); +static OSSwitchThreadCallback SwitchThreadCallback = DefaultSwitchThreadCallback; + +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; + +static void DefaultSwitchThreadCallback(OSThread* from, OSThread* to) {} + +extern u8 _stack_addr[]; +extern u8 _stack_end[]; + +#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 AddPrio(queue, thread, link) \ + do { \ + OSThread *prev, *next; \ + \ + for (next = (queue)->head; next && next->priority <= thread->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 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 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) + +static inline void OSInitMutexQueue(OSMutexQueue* queue) { queue->head = queue->tail = NULL; } + +static inline void OSSetCurrentThread(OSThread* thread) { + SwitchThreadCallback(__OSCurrentThread, thread); + __OSCurrentThread = thread; +} + +void __OSThreadInit() { + OSThread* thread = &DefaultThread; + int prio; + + thread->state = OS_THREAD_STATE_RUNNING; + thread->attr = OS_THREAD_ATTR_DETACH; + thread->priority = thread->base = 16; + thread->suspend = 0; + thread->val = (void*)-1; + thread->mutex = NULL; + OSInitThreadQueue(&thread->queueJoin); + OSInitMutexQueue(&thread->queueMutex); + + __OSFPUContext = &thread->context; + + OSClearContext(&thread->context); + OSSetCurrentContext(&thread->context); + thread->stackBase = (void*)_stack_addr; + thread->stackEnd = (void*)_stack_end; + *(thread->stackEnd) = OS_THREAD_STACK_MAGIC; + + OSSetCurrentThread(thread); + OSClearStack(0); + + RunQueueBits = 0; + RunQueueHint = FALSE; + for (prio = OS_PRIORITY_MIN; prio <= OS_PRIORITY_MAX; ++prio) { + OSInitThreadQueue(&RunQueue[prio]); + } + + OSInitThreadQueue(&__OSActiveThreadQueue); + AddTail(&__OSActiveThreadQueue, thread, linkActive); + OSClearContext(&IdleContext); + Reschedule = 0; +} + +void OSInitThreadQueue(OSThreadQueue* queue) { queue->head = queue->tail = NULL; } + +OSThread* OSGetCurrentThread() { return __OSCurrentThread; } + +static void __OSSwitchThread(OSThread *nextThread) +{ + OSSetCurrentThread(nextThread); + OSSetCurrentContext(&nextThread->context); + OSLoadContext(&nextThread->context); +} + +BOOL OSIsThreadTerminated(OSThread *thread) +{ + return (thread->state == OS_THREAD_STATE_MORIBUND || thread->state == OS_THREAD_STATE_NULL) ? TRUE : FALSE; +} + +s32 OSDisableScheduler() { + BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + count = Reschedule++; + OSRestoreInterrupts(enabled); + return count; +} + +s32 OSEnableScheduler() { + BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + count = Reschedule--; + OSRestoreInterrupts(enabled); + return count; +} + +static void SetRun(OSThread* thread) { + thread->queue = &RunQueue[thread->priority]; + AddTail(thread->queue, thread, link); + RunQueueBits |= 1u << (OS_PRIORITY_MAX - thread->priority); + RunQueueHint = TRUE; +} +#pragma dont_inline on +static void UnsetRun(OSThread* thread) { + OSThreadQueue* queue; + queue = thread->queue; + RemoveItem(queue, thread, link); + if (queue->head == 0) + RunQueueBits &= ~(1u << (OS_PRIORITY_MAX - thread->priority)); + thread->queue = NULL; +} +#pragma dont_inline reset + +OSPriority __OSGetEffectivePriority(OSThread* thread) { + OSPriority priority; + OSMutex* mutex; + OSThread* blocked; + + priority = thread->base; + for (mutex = thread->queueMutex.head; mutex; mutex = mutex->link.next) { + blocked = mutex->queue.head; + if (blocked && blocked->priority < priority) { + priority = blocked->priority; + } + } + return priority; +} + +static OSThread* SetEffectivePriority(OSThread* thread, OSPriority priority) { + switch (thread->state) { + case OS_THREAD_STATE_READY: + UnsetRun(thread); + thread->priority = priority; + SetRun(thread); + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->priority = priority; + AddPrio(thread->queue, thread, link); + if (thread->mutex) { + return thread->mutex->thread; + } + break; + case OS_THREAD_STATE_RUNNING: + RunQueueHint = TRUE; + thread->priority = priority; + break; + } + return NULL; +} + +static void UpdatePriority(OSThread* thread) { + OSPriority priority; + + do { + if (0 < thread->suspend) { + break; + } + priority = __OSGetEffectivePriority(thread); + if (thread->priority == priority) { + break; + } + thread = SetEffectivePriority(thread, priority); + } while (thread); +} + +void __OSPromoteThread(OSThread *thread, OSPriority priority) +{ + do + { + if (thread->suspend > 0) + { + break; + } + if (thread->priority <= priority) + { + break; + } + + thread = SetEffectivePriority(thread, priority); + } while (thread); +} + +static OSThread *SelectThread(BOOL yield) +{ + OSContext *currentContext; + OSThread *currentThread; + OSThread *nextThread; + OSPriority priority; + OSThreadQueue *queue; + + if (0 < Reschedule) + { + return 0; + } + + currentContext = OSGetCurrentContext(); + currentThread = OSGetCurrentThread(); + if (currentContext != ¤tThread->context) + { + return 0; + } + + if (currentThread) + { + if (currentThread->state == OS_THREAD_STATE_RUNNING) + { + if (!yield) + { + priority = __cntlzw(RunQueueBits); + if (currentThread->priority <= priority) + { + return 0; + } + } + currentThread->state = OS_THREAD_STATE_READY; + SetRun(currentThread); + } + + if (!(currentThread->context.state & OS_CONTEXT_STATE_EXC) && OSSaveContext(¤tThread->context)) + { + return 0; + } + } + + if (RunQueueBits == 0) + { + SwitchThreadCallback(__OSCurrentThread, nullptr); + __OSCurrentThread = nullptr; + OSSetCurrentContext(&IdleContext); + do + { + OSEnableInterrupts(); + while (RunQueueBits == 0) + ; + OSDisableInterrupts(); + } while (RunQueueBits == 0); + + OSClearContext(&IdleContext); + } + + RunQueueHint = FALSE; + + priority = __cntlzw(RunQueueBits); + queue = &RunQueue[priority]; + RemoveHead(queue, nextThread, link); + if (queue->head == 0) + { + RunQueueBits &= ~(1u << (OS_PRIORITY_MAX - priority)); + } + nextThread->queue = NULL; + nextThread->state = OS_THREAD_STATE_RUNNING; + __OSSwitchThread(nextThread); + return nextThread; +} + +void __OSReschedule() { + if (!RunQueueHint) { + return; + } + + SelectThread(FALSE); +} + +void OSYieldThread(void) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + SelectThread(TRUE); + OSRestoreInterrupts(enabled); +} + +BOOL OSCreateThread(OSThread *thread, OSThreadStartFunction func, void *param, void *stack, u32 stackSize, OSPriority priority, u16 attr) +{ + BOOL enable; + u32 stackThing; + int i; + u32 tmp[2]; // DUMB compiler smfh. + + if (priority < OS_PRIORITY_MIN || priority > OS_PRIORITY_MAX) + { + return FALSE; + } + + stackThing = ((u32)stack & 0xFFFFFFF8); // ?? + thread->state = OS_THREAD_STATE_READY; + thread->attr = attr & OS_THREAD_ATTR_DETACH; + thread->base = priority; + thread->priority = priority; + thread->suspend = 1; + thread->val = (void *)-1; + thread->mutex = nullptr; + OSInitThreadQueue(&thread->queueJoin); + OSInitMutexQueue(&thread->queueMutex); + *(u32 *)(stackThing - 8) = 0; + *(u32 *)(stackThing - 4) = 0; + + OSInitContext(&thread->context, (u32)func, (u32)(stackThing - 8)); + + thread->context.lr = (u32)&OSExitThread; + thread->context.gpr[3] = (u32)param; + thread->stackBase = stack; + thread->stackEnd = (u32 *)((u32)stack - stackSize); + *(thread->stackEnd) = OS_THREAD_STACK_MAGIC; + thread->error = 0; + thread->specific[0] = nullptr; + thread->specific[1] = nullptr; + + enable = OSDisableInterrupts(); + + if (__OSErrorTable[OS_ERROR_FPE] != nullptr) + { + thread->context.srr1 |= 0x900; // ?? + thread->context.state |= OS_CONTEXT_STATE_FPSAVED; + thread->context.fpscr = (__OSFpscrEnableBits & 0xF8) | 0x4; // ?? + + for (i = 0; i < 32; i++) + { + *(u64 *)&thread->context.fpr[i] = -1; // ??????? + *(u64 *)&thread->context.psf[i] = -1; // ??????? + } + } + + AddTail(&__OSActiveThreadQueue, thread, linkActive); + OSRestoreInterrupts(enable); + return TRUE; +} + +void OSExitThread(void *val) +{ + OSThread *thread; + BOOL enable; + + enable = OSDisableInterrupts(); + thread = __OSCurrentThread; + OSClearContext(&thread->context); + + if (thread->attr & OS_THREAD_ATTR_DETACH) + { + RemoveItem(&__OSActiveThreadQueue, thread, linkActive); + thread->state = OS_THREAD_STATE_NULL; + } + else + { + thread->state = OS_THREAD_STATE_MORIBUND; + thread->val = val; + } + + __OSUnlockAllMutex(thread); + OSWakeupThread(&thread->queueJoin); + RunQueueHint = TRUE; + if (RunQueueHint != FALSE) + { + SelectThread(FALSE); + } + + OSRestoreInterrupts(enable); +} + +void OSCancelThread(OSThread* thread) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + + switch (thread->state) { + case OS_THREAD_STATE_READY: + if (!(0 < thread->suspend)) { + UnsetRun(thread); + } + break; + case OS_THREAD_STATE_RUNNING: + RunQueueHint = TRUE; + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->queue = NULL; + if (!(0 < thread->suspend) && thread->mutex) { + UpdatePriority(thread->mutex->thread); + } + break; + default: + OSRestoreInterrupts(enabled); + return; + } + + OSClearContext(&thread->context); + if (thread->attr & OS_THREAD_ATTR_DETACH) { + RemoveItem(&__OSActiveThreadQueue, thread, linkActive); + thread->state = 0; + } else { + thread->state = OS_THREAD_STATE_MORIBUND; + } + + __OSUnlockAllMutex(thread); + + OSWakeupThread(&thread->queueJoin); + + __OSReschedule(); + OSRestoreInterrupts(enabled); + + return; +} + +void OSDetachThread(OSThread *thread) +{ + BOOL enable; + + enable = OSDisableInterrupts(); + thread->attr |= OS_THREAD_ATTR_DETACH; + if (thread->state == OS_THREAD_STATE_MORIBUND) + { + RemoveItem(&__OSActiveThreadQueue, thread, linkActive); + thread->state = OS_THREAD_STATE_NULL; + } + + OSWakeupThread(&thread->queueJoin); + OSRestoreInterrupts(enable); +} + +s32 OSResumeThread(OSThread* thread) { + BOOL enabled; + s32 suspendCount; + + enabled = OSDisableInterrupts(); + suspendCount = thread->suspend--; + if (thread->suspend < 0) { + thread->suspend = 0; + } else if (thread->suspend == 0) { + switch (thread->state) { + case OS_THREAD_STATE_READY: + thread->priority = __OSGetEffectivePriority(thread); + SetRun(thread); + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->priority = __OSGetEffectivePriority(thread); + AddPrio(thread->queue, thread, link); + if (thread->mutex) { + UpdatePriority(thread->mutex->thread); + } + break; + } + __OSReschedule(); + } + OSRestoreInterrupts(enabled); + return suspendCount; +} + +s32 OSSuspendThread(OSThread* thread) { + BOOL enabled; + s32 suspendCount; + + enabled = OSDisableInterrupts(); + suspendCount = thread->suspend++; + if (suspendCount == 0) { + switch (thread->state) { + case OS_THREAD_STATE_RUNNING: + RunQueueHint = TRUE; + thread->state = OS_THREAD_STATE_READY; + break; + case OS_THREAD_STATE_READY: + UnsetRun(thread); + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->priority = 32; + AddTail(thread->queue, thread, link); + if (thread->mutex) { + UpdatePriority(thread->mutex->thread); + } + break; + } + + __OSReschedule(); + } + OSRestoreInterrupts(enabled); + return suspendCount; +} + +void OSSleepThread(OSThreadQueue* queue) { + BOOL enabled; + OSThread* currentThread; + + enabled = OSDisableInterrupts(); + currentThread = OSGetCurrentThread(); + + currentThread->state = OS_THREAD_STATE_WAITING; + currentThread->queue = queue; + AddPrio(queue, currentThread, link); + RunQueueHint = TRUE; + __OSReschedule(); + OSRestoreInterrupts(enabled); +} + +void OSWakeupThread(OSThreadQueue* queue) { + BOOL enabled; + OSThread* thread; + + enabled = OSDisableInterrupts(); + while (queue->head) { + RemoveHead(queue, thread, link); + thread->state = OS_THREAD_STATE_READY; + if (!(0 < thread->suspend)) { + SetRun(thread); + } + } + __OSReschedule(); + OSRestoreInterrupts(enabled); +} + +OSPriority OSGetThreadPriority(OSThread *thread) { return thread->base; } + +void OSClearStack(u8 val) { + register u32 sp; + register u32* p; + register u32 pattern; + + pattern = ((u32)val << 24) | ((u32)val << 16) | ((u32)val << 8) | (u32)val; + sp = OSGetStackPointer(); + for (p = __OSCurrentThread->stackEnd + 1; p < (u32*)sp; ++p) { + *p = pattern; + } +} diff --git a/libs/dolphin/os/OSTime.c b/libs/dolphin/os/OSTime.c new file mode 100644 index 000000000..803fe10bc --- /dev/null +++ b/libs/dolphin/os/OSTime.c @@ -0,0 +1,137 @@ +#include + +#define OS_TIME_MONTH_MAX 12 +#define OS_TIME_WEEK_DAY_MAX 7 +#define OS_TIME_YEAR_DAY_MAX 365 + +// End of each month in standard year +static s32 YearDays[OS_TIME_MONTH_MAX] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; +// End of each month in leap year +static s32 LeapYearDays[OS_TIME_MONTH_MAX] = {0, 31, 60, 91, 121, 152, + 182, 213, 244, 274, 305, 335}; + +asm OSTime OSGetTime(void) { + // clang-format off + nofralloc + + mftbu r3 + mftb r4 + + // Check for possible carry from TBL to TBU + mftbu r5 + cmpw r3, r5 + bne OSGetTime + + blr + // clang-format on +} + +asm OSTick OSGetTick(void){ + // clang-format off + nofralloc + + mftb r3 + blr + // clang-format on +} + +#define OS_SYSTEMTIME_BASE 0x30D8 + +OSTime __OSGetSystemTime(void) { + BOOL enabled; + OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE); + OSTime result; + + enabled = OSDisableInterrupts(); + result = *timeAdjustAddr + OSGetTime(); + OSRestoreInterrupts(enabled); + + return result; +} + +OSTime __OSTimeToSystemTime(OSTime time) { + BOOL enabled; + OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE); + OSTime result; + + enabled = OSDisableInterrupts(); + result = *timeAdjustAddr + time; + OSRestoreInterrupts(enabled); + + return result; +} + +static BOOL IsLeapYear(s32 year) { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); } + +static s32 GetYearDays(s32 year, s32 mon) { + return (IsLeapYear(year) ? LeapYearDays : YearDays)[mon]; +} + +static s32 GetLeapDays(s32 year) { + if (year < 1) { + return 0; + } + return (year + 3) / 4 - (year - 1) / 100 + (year - 1) / 400; +} + +static void GetDates(s32 days, OSCalendarTime* cal) { + s32 year; + s32 totalDays; + s32* p_days; + s32 month; + cal->wday = (days + 6) % OS_TIME_WEEK_DAY_MAX; + + for (year = days / OS_TIME_YEAR_DAY_MAX; + days < (totalDays = year * OS_TIME_YEAR_DAY_MAX + GetLeapDays(year));) { + year--; + } + + days -= totalDays; + cal->year = year; + cal->yday = days; + + p_days = IsLeapYear(year) ? LeapYearDays : YearDays; + month = OS_TIME_MONTH_MAX; + while (days < p_days[--month]) { + ; + } + cal->mon = month; + cal->mday = days - p_days[month] + 1; +} + +#define BIAS (2000 * 365 + (2000 + 3) / 4 - (2000 - 1) / 100 + (2000 - 1) / 400) + +#pragma push +#pragma dont_inline on +void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* td) { + int days; + int secs; + OSTime d; + + d = ticks % OSSecondsToTicks(1); + if (d < 0) { + d += OSSecondsToTicks(1); + } + td->usec = (int)(OSTicksToMicroseconds(d) % 1000); + td->msec = (int)(OSTicksToMilliseconds(d) % 1000); + + ticks -= d; + days = (int)(OSTicksToSeconds(ticks) / 86400 + BIAS); + secs = (int)(OSTicksToSeconds(ticks) % 86400); + if (secs < 0) { + days -= 1; + secs += 24 * 60 * 60; + } + + GetDates(days, td); + + td->hour = secs / 60 / 60; + td->min = (secs / 60) % 60; + td->sec = secs % 60; +} +#pragma dont_inline reset + +OSTime OSCalendarTimeToTicks(const OSCalendarTime* time) { + ; + ; +} diff --git a/libs/dolphin/os/init/__ppc_eabi_init.cpp b/libs/dolphin/os/init/__ppc_eabi_init.cpp new file mode 100644 index 000000000..ea0791dd2 --- /dev/null +++ b/libs/dolphin/os/init/__ppc_eabi_init.cpp @@ -0,0 +1,74 @@ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void __OSPSInit(); +void __OSFPRInit(); +void __OSCacheInit(); + +typedef void (*voidfunctionptr)(void); // pointer to function returning void +__declspec(section ".ctors") extern voidfunctionptr _ctors[]; +__declspec(section ".dtors") extern voidfunctionptr _dtors[]; + +static void __init_cpp(void); + +// clang-format off +__declspec(section ".init") asm void __init_hardware(void) { + nofralloc + mfmsr r0 + ori r0,r0,0x2000 + mtmsr r0 + mflr r31 + bl __OSPSInit + bl __OSFPRInit + bl __OSCacheInit + mtlr r31 + blr +} + +__declspec(section ".init") asm void __flush_cache(void) { + nofralloc + lis r5, 0xFFFFFFF1@h + ori r5, r5, 0xFFFFFFF1@l + and r5, r5, r3 + subf r3, r5, r3 + add r4, r4, r3 +loop: + dcbst 0, r5 + sync + icbi 0, r5 + addic r5, r5, 8 + addic. r4, r4, -8 + bge loop + isync + blr +} +// clang-format on + + +void __init_user(void) { __init_cpp(); } + +static void __init_cpp(void) +{ + voidfunctionptr* constructor; + /* + * call static initializers + */ + for (constructor = _ctors; *constructor; constructor++) { + (*constructor)(); + } +} + + +void __fini_cpp(void) +{ + // UNUSED FUNCTION +} + +void _ExitProcess(void) { PPCHalt(); } +#ifdef __cplusplus +} +#endif diff --git a/libs/dolphin/os/init/__start.c b/libs/dolphin/os/init/__start.c new file mode 100644 index 000000000..0fa8a9546 --- /dev/null +++ b/libs/dolphin/os/init/__start.c @@ -0,0 +1,223 @@ +#include "dolphin/os/init/__start.h" +#include "PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h" +#include "PowerPC_EABI_Support/MetroTRK/dolphin_trk.h" + +void __check_pad3(void) +{ + if ((Pad3Button & 0x0eef) == 0x0eef) + { + OSResetSystem(OS_RESET_RESTART, 0, FALSE); + } + return; +} + +void __set_debug_bba(void) +{ + Debug_BBA = 1; +} + +u8 __get_debug_bba(void) +{ + return Debug_BBA; +} + +__declspec(weak) asm void __start(void) +{ + // clang-format off + nofralloc + bl __init_registers + bl __init_hardware + li r0, -1 + stwu r1, -8(r1) + stw r0, 4(r1) + stw r0, 0(r1) + bl __init_data + li r0, 0 + lis r6, EXCEPTIONMASK_ADDR@ha + addi r6, r6, EXCEPTIONMASK_ADDR@l + stw r0, 0(r6) + lis r6, BOOTINFO2_ADDR@ha + addi r6, r6, BOOTINFO2_ADDR@l + lwz r6, 0(r6) + +_check_TRK: + cmplwi r6, 0 + beq _load_lomem_debug_flag + lwz r7, OS_BI2_DEBUGFLAG_OFFSET(r6) + b _check_debug_flag + +_load_lomem_debug_flag: + lis r5, ARENAHI_ADDR@ha + addi r5, r5, ARENAHI_ADDR@l + lwz r5, 0(r5) + cmplwi r5, 0 + beq _goto_main + lis r7, DEBUGFLAG_ADDR@ha + addi r7, r7, DEBUGFLAG_ADDR@l + lwz r7, 0(r7) + +_check_debug_flag: + li r5, 0 + cmplwi r7, 2 + beq _goto_inittrk + cmplwi r7, 3 + li r5, 1 + beq _goto_inittrk + cmplwi r7, 4 + bne _goto_main + li r5, 2 + bl __set_debug_bba + b _goto_main + +_goto_inittrk: + lis r6, InitMetroTRK@ha + addi r6, r6, InitMetroTRK@l + mtlr r6 + blrl + +_goto_main: + lis r6, BOOTINFO2_ADDR@ha + addi r6, r6, BOOTINFO2_ADDR@l + lwz r5, 0(r6) + cmplwi r5, 0 + beq+ _no_args + lwz r6, 8(r5) + cmplwi r6, 0 + beq+ _no_args + add r6, r5, r6 + lwz r14, 0(r6) + cmplwi r14, 0 + beq _no_args + addi r15, r6, 4 + mtctr r14 + +_loop: + addi r6, r6, 4 + lwz r7, 0(r6) + add r7, r7, r5 + stw r7, 0(r6) + bdnz _loop + lis r5, ARENAHI_ADDR@ha + addi r5, r5, ARENAHI_ADDR@l + rlwinm r7, r15, 0, 0, 0x1a + stw r7, 0(r5) + b _end_of_parseargs + +_no_args: + li r14, 0 + li r15, 0 + +_end_of_parseargs: + bl DBInit + bl OSInit + lis r4, DVD_DEVICECODE_ADDR@ha + addi r4, r4, DVD_DEVICECODE_ADDR@l + lhz r3, 0(r4) + andi. r5, r3, 0x8000 + beq _check_pad3 + andi. r3, r3, 0x7fff + cmplwi r3, 1 + bne _skip_crc + +_check_pad3: + bl __check_pad3 + +_skip_crc: + bl __get_debug_bba + cmplwi r3, 1 + bne _goto_skip_init_bba + bl InitMetroTRK_BBA + +_goto_skip_init_bba: + bl __init_user + mr r3, r14 + mr r4, r15 + bl main + b exit + // clang-format on +} + +__declspec(section ".init") static void __copy_rom_section(void* dst, const void* src, + unsigned long size) +{ + if (size && (dst != src)) + { + memcpy(dst, src, size); + __flush_cache(dst, size); + } +} + +__declspec(section ".init") static void __init_bss_section(void* dst, unsigned long size) +{ + if (size) + { + memset(dst, 0, size); + } +} + +asm static void __init_registers(void) +{ + // clang-format off + nofralloc + li r0, 0 + li r3, 0 + li r4, 0 + li r5, 0 + li r6, 0 + li r7, 0 + li r8, 0 + li r9, 0 + li r10, 0 + li r11, 0 + li r12, 0 + li r14, 0 + li r15, 0 + li r16, 0 + li r17, 0 + li r18, 0 + li r19, 0 + li r20, 0 + li r21, 0 + li r22, 0 + li r23, 0 + li r24, 0 + li r25, 0 + li r26, 0 + li r27, 0 + li r28, 0 + li r29, 0 + li r30, 0 + li r31, 0 + lis r1, _stack_addr@h + ori r1, r1, _stack_addr@l + lis r2, _SDA2_BASE_@h + ori r2, r2, _SDA2_BASE_@l + lis r13, _SDA_BASE_@h + ori r13, r13, _SDA_BASE_@l + blr + // clang-format on +} + +void __init_data(void) +{ + __rom_copy_info* dci; + __bss_init_info* bii; + + dci = _rom_copy_info; + while (TRUE) + { + if (dci->size == 0) + break; + __copy_rom_section(dci->addr, dci->rom, dci->size); + dci++; + } + + bii = _bss_init_info; + while (TRUE) + { + if (bii->size == 0) + break; + __init_bss_section(bii->addr, bii->size); + bii++; + } +} diff --git a/libs/dolphin/pad/Pad.c b/libs/dolphin/pad/Pad.c new file mode 100644 index 000000000..f648d1cb5 --- /dev/null +++ b/libs/dolphin/pad/Pad.c @@ -0,0 +1,901 @@ +#include +#include +#include + +const char* __PADVersion = "<< Dolphin SDK - PAD\trelease build: Aug 6 2003 04:30:02 (0x2301) >>"; + +u8 UnkVal : (OS_BASE_CACHED | 0x30E3); +u16 __OSWirelessPadFixMode : (OS_BASE_CACHED | 0x30E0); + +static void PADTypeAndStatusCallback(s32 chan, u32 type); +static void PADOriginCallback(s32 chan, u32 error, OSContext* context); +static void PADProbeCallback(s32 chan, u32 error, OSContext* context); +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 void PADTypeAndStatusCallback(s32 chan, u32 type); + +static void PADOriginCallback(s32 chan, u32 error, OSContext* context); +static void PADProbeCallback(s32 chan, u32 error, OSContext* context); + +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 Initialized; + +static u32 EnabledBits; +static u32 ResettingBits; +static s32 ResettingChan = 32; +static u32 RecalibrateBits; +static u32 WaitingBits; +static u32 CheckingBits; +static u32 PendingBits; +static u32 BarrelBits; + +static u32 XPatchBits = PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT; + +static u32 AnalogMode = 0x00000300u; + +u32 __PADSpec; +static u32 Spec = 5; +static void (*MakeStatus)(s32, PADStatus*, u32[2]) = SPEC2_MakeStatus; + +static u32 Type[SI_MAX_CHAN]; +static PADStatus Origin[SI_MAX_CHAN]; + +static u32 CmdReadOrigin = 0x41 << 24; +static u32 CmdCalibrate = 0x42 << 24; +static u32 CmdProbeDevice[SI_MAX_CHAN]; + +static BOOL OnReset(BOOL final); + +static OSResetFunctionInfo ResetFunctionInfo = { OnReset, 127 }; + +static void (*SamplingCallback)(void); + +static void PADEnable(s32 chan) +{ + u32 cmd; + u32 chanBit; + u32 data[2]; + + chanBit = PAD_CHAN0_BIT >> chan; + EnabledBits |= chanBit; + SIGetResponse(chan, data); + cmd = (0x40 << 16) | AnalogMode; + SISetCommand(chan, cmd); + SIEnablePolling(EnabledBits); +} + +static void PADDisable(s32 chan) +{ + BOOL enabled; + u32 chanBit; + + enabled = OSDisableInterrupts(); + + chanBit = PAD_CHAN0_BIT >> chan; + SIDisablePolling(chanBit); + EnabledBits &= ~chanBit; + WaitingBits &= ~chanBit; + CheckingBits &= ~chanBit; + PendingBits &= ~chanBit; + BarrelBits &= ~chanBit; + OSSetWirelessID(chan, 0); + + OSRestoreInterrupts(enabled); +} + +static void DoReset(void) +{ + u32 chanBit; + + ResettingChan = __cntlzw(ResettingBits); + if (ResettingChan == 32) + { + return; + } + + 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; + } + + 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) +{ + if (!(error & + (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) + { + UpdateOrigin(ResettingChan); + PADEnable(ResettingChan); + } + DoReset(); +} + +static void PADOriginUpdateCallback(s32 chan, u32 error, OSContext* context) +{ + 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); + } +} + +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))) + { + PADEnable(ResettingChan); + WaitingBits |= PAD_CHAN0_BIT >> ResettingChan; + } + DoReset(); +} + +static void PADTypeAndStatusCallback(s32 chan, u32 type) +{ + u32 chanBit; + u32 recalibrate; + BOOL rc = TRUE; + u32 error; + chanBit = PAD_CHAN0_BIT >> ResettingChan; + error = type & 0xFF; + recalibrate = RecalibrateBits & chanBit; + RecalibrateBits &= ~chanBit; + + 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)) + { + DoReset(); + return; + } + + if (Spec < PAD_SPEC_2) + { + PADEnable(ResettingChan); + DoReset(); + return; + } + + if (!(type & SI_GC_WIRELESS) || (type & SI_WIRELESS_IR)) + { + if (recalibrate) + { + rc = SITransfer(ResettingChan, &CmdCalibrate, 3, &Origin[ResettingChan], 10, + PADOriginCallback, 0); + } + else + { + rc = SITransfer(ResettingChan, &CmdReadOrigin, 1, &Origin[ResettingChan], 10, + PADOriginCallback, 0); + } + } + else if ((type & SI_WIRELESS_FIX_ID) && (type & SI_WIRELESS_CONT_MASK) == SI_WIRELESS_CONT && + !(type & SI_WIRELESS_LITE)) + { + if (type & SI_WIRELESS_RECEIVED) + { + rc = SITransfer(ResettingChan, &CmdReadOrigin, 1, &Origin[ResettingChan], 10, + PADOriginCallback, 0); + } + else + { + rc = SITransfer(ResettingChan, &CmdProbeDevice[ResettingChan], 3, + &Origin[ResettingChan], 8, PADProbeCallback, 0); + } + } + if (!rc) + { + PendingBits |= chanBit; + DoReset(); + return; + } +} + +static void PADReceiveCheckCallback(s32 chan, u32 type) +{ + u32 error; + u32 chanBit; + + chanBit = PAD_CHAN0_BIT >> chan; + if (!(EnabledBits & chanBit)) + { + return; + } + + error = type & 0xFF; + type &= ~0xFF; + + 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); + } +} + +#pragma push +#pragma auto_inline off // fakematch most likely + +BOOL PADReset(u32 mask) +{ + BOOL enabled; + u32 diableBits; + + enabled = OSDisableInterrupts(); + + mask |= PendingBits; + PendingBits = 0; + mask &= ~(WaitingBits | CheckingBits); + ResettingBits |= mask; + diableBits = ResettingBits & EnabledBits; + EnabledBits &= ~mask; + BarrelBits &= ~mask; + + if (Spec == PAD_SPEC_4) + { + RecalibrateBits |= mask; + } + + SIDisablePolling(diableBits); + + if (ResettingChan == 32) + { + DoReset(); + } + OSRestoreInterrupts(enabled); + return TRUE; +} + +BOOL PADRecalibrate(u32 mask) +{ + BOOL enabled; + u32 disableBits; + + enabled = OSDisableInterrupts(); + + mask |= PendingBits; + PendingBits = 0; + mask &= ~(WaitingBits | CheckingBits); + ResettingBits |= mask; + disableBits = ResettingBits & EnabledBits; + EnabledBits &= ~mask; + BarrelBits &= ~mask; + + if (!(UnkVal & 0x40)) + { + RecalibrateBits |= mask; + } + + SIDisablePolling(disableBits); + if (ResettingChan == 32) + { + DoReset(); + } + OSRestoreInterrupts(enabled); + return TRUE; +} + +BOOL PADInit() +{ + s32 chan; + if (Initialized) + { + return TRUE; + } + + OSRegisterVersion(__PADVersion); + + 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); + 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); + } + + SIRefreshSamplingRate(); + OSRegisterResetFunction(&ResetFunctionInfo); + + return PADReset((PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT)); +} + +#define offsetof(type, memb) ((u32) & ((type*)0)->memb) + +u32 PADRead(PADStatus* status) +{ + BOOL enabled; + s32 chan; + u32 data[2]; + u32 chanBit; + u32 sr; + int chanShift; + u32 motor; + + enabled = OSDisableInterrupts(); + + motor = 0; + for (chan = 0; chan < SI_MAX_CHAN; chan++, status++) + { + chanBit = PAD_CHAN0_BIT >> chan; + chanShift = 8 * (SI_MAX_CHAN - 1 - chan); + + if (PendingBits & chanBit) + { + PADReset(0); + status->err = PAD_ERR_NOT_READY; + memset(status, 0, offsetof(PADStatus, err)); + continue; + } + + if ((ResettingBits & chanBit) || ResettingChan == chan) + { + status->err = PAD_ERR_NOT_READY; + memset(status, 0, offsetof(PADStatus, err)); + continue; + } + + if (!(EnabledBits & chanBit)) + { + status->err = (s8)PAD_ERR_NO_CONTROLLER; + memset(status, 0, offsetof(PADStatus, err)); + continue; + } + + if (SIIsChanBusy(chan)) + { + status->err = PAD_ERR_TRANSFER; + memset(status, 0, offsetof(PADStatus, err)); + continue; + } + + sr = SIGetStatus(chan); + if (sr & SI_ERROR_NO_RESPONSE) + { + SIGetResponse(chan, data); + + if (WaitingBits & chanBit) + { + status->err = (s8)PAD_ERR_NONE; + memset(status, 0, offsetof(PADStatus, err)); + + if (!(CheckingBits & chanBit)) + { + CheckingBits |= chanBit; + SIGetTypeAsync(chan, PADReceiveCheckCallback); + } + continue; + } + + PADDisable(chan); + + status->err = (s8)PAD_ERR_NO_CONTROLLER; + memset(status, 0, offsetof(PADStatus, err)); + continue; + } + + if (!(SIGetType(chan) & SI_GC_NOMOTOR)) + { + motor |= chanBit; + } + + if (!SIGetResponse(chan, data)) + { + status->err = PAD_ERR_TRANSFER; + memset(status, 0, offsetof(PADStatus, err)); + continue; + } + + if (data[0] & 0x80000000) + { + status->err = PAD_ERR_TRANSFER; + memset(status, 0, offsetof(PADStatus, err)); + continue; + } + + 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); + continue; + } + + status->err = PAD_ERR_NONE; + + // Clear PAD_INTERFERE bit + status->button &= ~0x0080; + } + + OSRestoreInterrupts(enabled); + return motor; +} + +#pragma pop + +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) & SI_GC_NOMOTOR)) + { + command = *commandArray; + if (Spec < PAD_SPEC_2 && command == PAD_MOTOR_STOP_HARD) + { + command = PAD_MOTOR_STOP; + } + + if (UnkVal & 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; + + enabled = OSDisableInterrupts(); + chanBit = PAD_CHAN0_BIT >> chan; + if ((EnabledBits & chanBit) && !(SIGetType(chan) & SI_GC_NOMOTOR)) + { + if (Spec < PAD_SPEC_2 && command == PAD_MOTOR_STOP_HARD) + { + command = PAD_MOTOR_STOP; + } + + if (UnkVal & 0x20) + { + command = PAD_MOTOR_STOP; + } + + SISetCommand(chan, (0x40 << 16) | AnalogMode | (command & (0x00000001 | 0x00000002))); + SITransferCommands(); + } + OSRestoreInterrupts(enabled); +} + +void PADSetSpec(u32 spec) +{ + __PADSpec = 0; + switch (spec) + { + case PAD_SPEC_0: + MakeStatus = SPEC0_MakeStatus; + break; + case PAD_SPEC_1: + MakeStatus = SPEC1_MakeStatus; + break; + case PAD_SPEC_2: + case PAD_SPEC_3: + case PAD_SPEC_4: + case PAD_SPEC_5: + MakeStatus = SPEC2_MakeStatus; + break; + } + Spec = spec; +} + +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; + status->button |= ((data[0] >> 16) & 0x0020) ? PAD_BUTTON_B : 0; + 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->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->triggerRight) + { + status->button |= PAD_TRIGGER_R; + } + status->stickX -= 128; + status->stickY -= 128; + status->substickX -= 128; + status->substickY -= 128; +} + +static void SPEC1_MakeStatus(s32 chan, PADStatus* status, u32 data[2]) +{ + status->button = 0; + status->button |= ((data[0] >> 16) & 0x0080) ? PAD_BUTTON_A : 0; + status->button |= ((data[0] >> 16) & 0x0100) ? PAD_BUTTON_B : 0; + status->button |= ((data[0] >> 16) & 0x0020) ? PAD_BUTTON_X : 0; + status->button |= ((data[0] >> 16) & 0x0010) ? PAD_BUTTON_Y : 0; + status->button |= ((data[0] >> 16) & 0x0200) ? PAD_BUTTON_START : 0; + + 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->triggerRight) + { + status->button |= PAD_TRIGGER_R; + } + + status->stickX -= 128; + status->stickY -= 128; + status->substickX -= 128; + status->substickY -= 128; +} + +static s8 ClampS8(s8 var, s8 org) +{ + if (0 < org) + { + s8 min = (s8)(-128 + org); + if (var < min) + { + var = min; + } + } + else if (org < 0) + { + s8 max = (s8)(127 + org); + if (max < var) + { + var = max; + } + } + return 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) + +static void SPEC2_MakeStatus(s32 chan, PADStatus* status, u32 data[2]) +{ + PADStatus* origin; + + status->button = (u16)((data[0] >> 16) & PAD_ALL); + status->stickX = (s8)(data[0] >> 8); + status->stickY = (s8)(data[0]); + + switch (AnalogMode & 0x00000700) + { + case 0x00000000: + case 0x00000500: + case 0x00000600: + case 0x00000700: + 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->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->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->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->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->stickX -= 128; + status->stickY -= 128; + status->substickX -= 128; + status->substickY -= 128; + + if ((Type[chan] & 0xffff0000) == SI_GC_CONTROLLER && (((status->button) & 0x80) ^ 0x80)) + { + BarrelBits |= PAD_CHAN0_BIT >> chan; + status->stickX = 0; + status->stickY = 0; + status->substickX = 0; + status->substickY = 0; + } + else + { + BarrelBits &= ~(PAD_CHAN0_BIT >> chan); + origin = &Origin[chan]; + 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); + } +} + +BOOL PADGetType(s32 chan, u32* type) +{ + u32 chanBit; + + *type = SIGetType(chan); + chanBit = PAD_CHAN0_BIT >> chan; + if ((ResettingBits & chanBit) || ResettingChan == chan || !(EnabledBits & chanBit)) + { + return FALSE; + } + return TRUE; +} + +BOOL PADSync(void) +{ + return ResettingBits == 0 && ResettingChan == 32 && !SIBusy(); +} + +void PADSetAnalogMode(u32 mode) +{ + BOOL enabled; + u32 mask; + + enabled = OSDisableInterrupts(); + AnalogMode = mode << 8; + mask = EnabledBits; + + EnabledBits &= ~mask; + WaitingBits &= ~mask; + CheckingBits &= ~mask; + + SIDisablePolling(mask); + OSRestoreInterrupts(enabled); +} + +static BOOL OnReset(BOOL f) +{ + static BOOL recalibrated = FALSE; + BOOL sync; + + if (SamplingCallback) + { + PADSetSamplingCallback(NULL); + } + + if (!f) + { + sync = PADSync(); + if (!recalibrated && sync) + { + recalibrated = + PADRecalibrate(PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT); + return FALSE; + } + return sync; + } + else + { + recalibrated = FALSE; + } + + return TRUE; +} + +void __PADDisableXPatch(void) +{ + XPatchBits = 0; +} + +static void SamplingHandler(__OSInterrupt interrupt, OSContext* context) +{ + OSContext exceptionContext; + + if (SamplingCallback) + { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + SamplingCallback(); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } +} + +PADSamplingCallback PADSetSamplingCallback(PADSamplingCallback callback) +{ + PADSamplingCallback prev; + + prev = SamplingCallback; + SamplingCallback = callback; + if (callback) + { + SIRegisterPollingHandler(SamplingHandler); + } + else + { + SIUnregisterPollingHandler(SamplingHandler); + } + return prev; +} + +BOOL __PADDisableRecalibration(BOOL disable) +{ + BOOL enabled; + BOOL prev; + + enabled = OSDisableInterrupts(); + prev = (UnkVal & 0x40) ? TRUE : FALSE; + UnkVal &= ~0x40; + if (disable) + { + UnkVal |= 0x40; + } + OSRestoreInterrupts(enabled); + return prev; +} \ No newline at end of file diff --git a/libs/dolphin/pad/Padclamp.c b/libs/dolphin/pad/Padclamp.c new file mode 100644 index 000000000..89fbbfb8a --- /dev/null +++ b/libs/dolphin/pad/Padclamp.c @@ -0,0 +1,198 @@ +#include + +#include "std/math.h" + +s32 PAD_CHANMAX; + +static const PADClampRegion ClampRegion = { + // Triggers + 30, + 180, + + // Left stick + 15, + 72, + 40, + + // Right stick + 15, + 59, + 31, + + // Stick radii + 56, + 44, +}; + +static void ClampStick(s8* px, s8* py, s8 max, s8 xy, s8 min) +{ + int x = *px; + int y = *py; + int signX; + int signY; + int d; + + if (0 <= x) + { + signX = 1; + } + else + { + signX = -1; + x = -x; + } + + if (0 <= y) + { + signY = 1; + } + else + { + signY = -1; + y = -y; + } + + if (x <= min) + { + x = 0; + } + else + { + x -= min; + } + if (y <= min) + { + y = 0; + } + else + { + y -= min; + } + + if (x == 0 && y == 0) + { + *px = *py = 0; + return; + } + + if (xy * y <= xy * x) + { + d = xy * x + (max - xy) * y; + if (xy * max < d) + { + x = (s8)(xy * max * x / d); + y = (s8)(xy * max * y / d); + } + } + else + { + d = xy * y + (max - xy) * x; + if (xy * max < d) + { + x = (s8)(xy * max * x / d); + y = (s8)(xy * max * y / d); + } + } + + *px = (s8)(signX * x); + *py = (s8)(signY * y); +} + +static void ClampCircle(s8* px, s8* py, s8 radius, s8 min) +{ + int x = *px; + int y = *py; + int squared; + int length; + + if (-min < x && x < min) + { + x = 0; + } + else if (0 < x) + { + x -= min; + } + else + { + x += min; + } + + if (-min < y && y < min) + { + y = 0; + } + else if (0 < y) + { + y -= min; + } + else + { + y += min; + } + + squared = x * x + y * y; + if (radius * radius < squared) + { + length = sqrtf(squared); + x = (x * radius) / length; + y = (y * radius) / length; + } + + *px = x; + *py = y; +} + +static void ClampTrigger(u8* trigger, u8 min, u8 max) +{ + if (*trigger <= min) + { + *trigger = 0; + return; + } + else + { + if (max < *trigger) + { + *trigger = max; + } + *trigger -= min; + } +} + +void PADClamp(PADStatus* status) +{ + int i; + for (i = 0; i < PAD_CHANMAX; i++, status++) + { + if (status->err != PAD_ERR_NONE) + { + continue; + } + + 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); + } +} + +void PADClampCircle(PADStatus* status) +{ + int i; + for (i = 0; i < PAD_CHANMAX; ++i, status++) + { + if (status->err != PAD_ERR_NONE) + { + continue; + } + + 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); + } +} diff --git a/libs/dolphin/si/SIBios.c b/libs/dolphin/si/SIBios.c new file mode 100644 index 000000000..030b026e3 --- /dev/null +++ b/libs/dolphin/si/SIBios.c @@ -0,0 +1,902 @@ +#include +#include +#include +#include + +vu32 __SIRegs[64] : 0xCC006400; + +extern OSTime __OSGetSystemTime(); + +const char* __SIVersion = "<< Dolphin SDK - SI\trelease build: Apr 17 2003 12:33:19 (0x2301) >>"; + +static SIControl Si = { + -1, 0, 0, NULL, NULL, +}; + +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; + +static SIPacket Packet[SI_MAX_CHAN]; +static OSAlarm Alarm[SI_MAX_CHAN]; +static u32 Type[SI_MAX_CHAN] = { + SI_ERROR_NO_RESPONSE, + SI_ERROR_NO_RESPONSE, + SI_ERROR_NO_RESPONSE, + SI_ERROR_NO_RESPONSE, +}; + +static OSTime TypeTime[SI_MAX_CHAN]; +static OSTime XferTime[SI_MAX_CHAN]; + +static SITypeAndStatusCallback TypeCallback[SI_MAX_CHAN][4]; +static __OSInterruptHandler RDSTHandler[4]; + +u32 __PADFixBits; + +static BOOL __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, + SICallback callback); + +static BOOL InputBufferValid[SI_MAX_CHAN]; +static u32 InputBuffer[SI_MAX_CHAN][2]; +static vu32 InputBufferVcount[SI_MAX_CHAN]; + +static BOOL SIGetResponseRaw(s32 chan); +static void GetTypeCallback(s32 chan, u32 error, OSContext* context); + +BOOL SIBusy() +{ + return Si.chan != -1 ? TRUE : FALSE; +} + +BOOL SIIsChanBusy(s32 chan) +{ + return (Packet[chan].chan != -1 || Si.chan == chan); +} + +static void SIClearTCInterrupt() +{ + u32 reg; + + reg = __SIRegs[13]; + reg |= 0x80000000; + reg &= ~0x00000001; + __SIRegs[13] = reg; +} + +static u32 CompleteTransfer() +{ + u32 sr; + u32 i; + u32 rLen; + u8* input; + + sr = __SIRegs[14]; + + SIClearTCInterrupt(); + + if (Si.chan != -1) + { + XferTime[Si.chan] = __OSGetSystemTime(); + + input = Si.input; + + rLen = Si.inputBytes / 4; + for (i = 0; i < rLen; i++) + { + *(u32*)input = __SIRegs[32 + i]; + input += 4; + } + + rLen = Si.inputBytes & 3; + if (rLen) + { + u32 temp = __SIRegs[32 + i]; + for (i = 0; i < rLen; i++) + { + *input++ = (u8)((temp >> ((3 - i) * 8)) & 0xff); + } + } + + 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 (sr == 0) + { + sr = SI_ERROR_COLLISION; + } + } + else + { + TypeTime[Si.chan] = __OSGetSystemTime(); + sr = 0; + } + + Si.chan = -1; + } + return sr; +} + +static void SITransferNext(s32 chan) +{ + int i; + SIPacket* packet; + + for (i = 0; i < SI_MAX_CHAN; ++i) + { + ++chan; + chan %= SI_MAX_CHAN; + 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; + } + break; + } + } +} + +static void SIInterruptHandler(__OSInterrupt interrupt, OSContext* context) +{ + u32 reg; + + reg = __SIRegs[13]; + + if ((reg & 0xc0000000) == 0xc0000000) + { + s32 chan; + u32 sr; + SICallback callback; + + chan = Si.chan; + sr = CompleteTransfer(); + callback = Si.callback; + Si.callback = 0; + + SITransferNext(chan); + + if (callback) + { + callback(chan, sr, context); + } + + sr = __SIRegs[14]; + sr &= 0xf000000 >> (8 * chan); + __SIRegs[14] = sr; + + if (Type[chan] == SI_ERROR_BUSY && !SIIsChanBusy(chan)) + { + static u32 cmdTypeAndStatus = 0 << 24; + SITransfer(chan, &cmdTypeAndStatus, 1, &Type[chan], 3, GetTypeCallback, + OSMicrosecondsToTicks(65)); + } + } + + if ((reg & 0x18000000) == 0x18000000) + { + int i; + u32 vcount; + u32 x; + + vcount = VIGetCurrentLine() + 1; + x = (Si.poll & 0x03ff0000) >> 16; + + for (i = 0; i < SI_MAX_CHAN; ++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 < SI_MAX_CHAN; ++i) + { + InputBufferVcount[i] = 0; + } + + for (i = 0; i < 4; ++i) + { + if (RDSTHandler[i]) + { + RDSTHandler[i](interrupt, context); + } + } + } +} + +static BOOL SIEnablePollingInterrupt(BOOL enable) +{ + BOOL enabled; + BOOL rc; + u32 reg; + int i; + + enabled = OSDisableInterrupts(); + reg = __SIRegs[13]; + rc = (reg & 0x08000000) ? TRUE : FALSE; + if (enable) + { + reg |= 0x08000000; + for (i = 0; i < SI_MAX_CHAN; ++i) + { + InputBufferVcount[i] = 0; + } + } + else + { + reg &= ~0x08000000; + } + reg &= ~0x80000001; + __SIRegs[13] = reg; + OSRestoreInterrupts(enabled); + return rc; +} + +BOOL SIRegisterPollingHandler(__OSInterruptHandler handler) +{ + BOOL enabled; + int i; + + enabled = OSDisableInterrupts(); + for (i = 0; i < 4; ++i) + { + if (RDSTHandler[i] == handler) + { + OSRestoreInterrupts(enabled); + return TRUE; + } + } + for (i = 0; i < 4; ++i) + { + if (RDSTHandler[i] == 0) + { + RDSTHandler[i] = handler; + SIEnablePollingInterrupt(TRUE); + OSRestoreInterrupts(enabled); + return TRUE; + } + } + OSRestoreInterrupts(enabled); + return FALSE; +} + +BOOL SIUnregisterPollingHandler(__OSInterruptHandler handler) +{ + BOOL enabled; + int i; + + enabled = OSDisableInterrupts(); + for (i = 0; i < 4; ++i) + { + if (RDSTHandler[i] == handler) + { + RDSTHandler[i] = 0; + for (i = 0; i < 4; ++i) + { + if (RDSTHandler[i]) + { + break; + } + } + if (i == 4) + { + SIEnablePollingInterrupt(FALSE); + } + OSRestoreInterrupts(enabled); + return TRUE; + break; + } + } + OSRestoreInterrupts(enabled); + return FALSE; +} + +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) + ; + + __SIRegs[13] = 0x80000000; + + __OSSetInterruptHandler(__OS_INTERRUPT_PI_SI, SIInterruptHandler); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_SI); + + SIGetType(0); + SIGetType(1); + SIGetType(2); + SIGetType(3); +} + +#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) + +static BOOL __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, + SICallback callback) +{ + BOOL enabled; + u32 rLen; + u32 i; + u32 sr; + SIComm_u comcsr; + + enabled = OSDisableInterrupts(); + if (Si.chan != -1) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + + sr = __SIRegs[14]; + sr &= (0xf000000) >> (8 * chan); + __SIRegs[14] = sr; + + Si.chan = chan; + Si.callback = callback; + Si.inputBytes = inputBytes; + Si.input = input; + + rLen = ROUND(outputBytes, 4) / 4; + for (i = 0; i < rLen; i++) + { + __SIRegs[32 + i] = ((u32*)output)[i]; + } + + comcsr.val = __SIRegs[13]; + 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.channel = chan; + comcsr.f.tstart = 1; + __SIRegs[13] = comcsr.val; + + OSRestoreInterrupts(enabled); + + return TRUE; +} + +u32 SISync(void) +{ + BOOL enabled; + u32 sr; + + while (__SIRegs[13] & 1) + ; + + enabled = OSDisableInterrupts(); + sr = CompleteTransfer(); + + SITransferNext(SI_MAX_CHAN); + + OSRestoreInterrupts(enabled); + + return sr; +} + +u32 SIGetStatus(s32 chan) +{ + BOOL enabled; + u32 sr; + int chanShift; + + enabled = OSDisableInterrupts(); + sr = __SIRegs[14]; + chanShift = 8 * (SI_MAX_CHAN - 1 - chan); + sr >>= chanShift; + if (sr & SI_ERROR_NO_RESPONSE) + { + if (!(Type[chan] & SI_ERROR_BUSY)) + { + Type[chan] = SI_ERROR_NO_RESPONSE; + } + } + OSRestoreInterrupts(enabled); + return sr; +} + +void SISetCommand(s32 chan, u32 command) +{ + __SIRegs[3 * chan] = command; +} + +u32 SIGetCommand(s32 chan) +{ + return __SIRegs[3 * chan]; +} + +void SITransferCommands(void) +{ + __SIRegs[14] = 0x80000000; +} + +u32 SISetXY(u32 x, u32 y) +{ + u32 poll; + BOOL enabled; + + poll = x << 16; + poll |= y << 8; + + enabled = OSDisableInterrupts(); + Si.poll &= ~(0x03ff0000 | 0x0000ff00); + Si.poll |= poll; + poll = Si.poll; + __SIRegs[12] = poll; + OSRestoreInterrupts(enabled); + return poll; +} + +u32 SIEnablePolling(u32 poll) +{ + BOOL enabled; + u32 en; + + if (poll == 0) + { + return Si.poll; + } + + enabled = OSDisableInterrupts(); + + poll >>= (31 - 7); + en = poll & 0xf0; + + poll &= (en >> 4) | 0x03fffff0; + + poll &= ~0x03ffff00; + + Si.poll &= ~(en >> 4); + + Si.poll |= poll; + + poll = Si.poll; + + SITransferCommands(); + + __SIRegs[12] = poll; + + OSRestoreInterrupts(enabled); + + return poll; +} + +u32 SIDisablePolling(u32 poll) +{ + BOOL enabled; + + if (poll == 0) + { + return Si.poll; + } + + enabled = OSDisableInterrupts(); + + poll >>= (31 - 7); + poll &= 0xf0; + + poll = Si.poll & ~poll; + + __SIRegs[12] = poll; + Si.poll = poll; + + OSRestoreInterrupts(enabled); + return poll; +} + +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]; + InputBufferValid[chan] = TRUE; + return TRUE; + } + return FALSE; +} + +BOOL SIGetResponse(s32 chan, void* data) +{ + BOOL rc; + BOOL enabled; + + 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; +} + +static void AlarmHandler(OSAlarm* alarm, OSContext* context) +{ +#pragma unused(context) + s32 chan; + SIPacket* packet; + + chan = alarm - Alarm; + packet = &Packet[chan]; + if (packet->chan != -1) + { + if (__SITransfer(packet->chan, packet->output, packet->outputBytes, packet->input, + packet->inputBytes, packet->callback)) + { + packet->chan = -1; + } + } +} + +BOOL SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, + SICallback callback, OSTime delay) +{ + BOOL enabled; + SIPacket* packet = &Packet[chan]; + OSTime now; + OSTime fire; + + enabled = OSDisableInterrupts(); + if (packet->chan != -1 || Si.chan == chan) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + + now = __OSGetSystemTime(); + if (delay == 0) + { + fire = now; + } + else + { + fire = XferTime[chan] + delay; + } + if (now < fire) + { + delay = fire - now; + OSSetAlarm(&Alarm[chan], delay, AlarmHandler); + } + else if (__SITransfer(chan, output, outputBytes, input, inputBytes, callback)) + { + OSRestoreInterrupts(enabled); + return TRUE; + } + + packet->chan = chan; + packet->output = output; + packet->outputBytes = outputBytes; + packet->input = input; + packet->inputBytes = inputBytes; + packet->callback = callback; + packet->fire = fire; + + OSRestoreInterrupts(enabled); + return TRUE; +} + +static void CallTypeAndStatusCallback(s32 chan, u32 type) +{ + SITypeAndStatusCallback callback; + int i; + + for (i = 0; i < 4; ++i) + { + callback = TypeCallback[chan][i]; + if (callback) + { + TypeCallback[chan][i] = 0; + callback(chan, type); + } + } +} + +static void GetTypeCallback(s32 chan, u32 error, OSContext* context) +{ + static u32 cmdFixDevice[SI_MAX_CHAN]; + u32 type; + u32 chanBit; + BOOL fix; + u32 id; + + Type[chan] &= ~SI_ERROR_BUSY; + Type[chan] |= error; + TypeTime[chan] = __OSGetSystemTime(); + + type = Type[chan]; + + chanBit = SI_CHAN0_BIT >> chan; + fix = (BOOL)(__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)) + { + OSSetWirelessID(chan, 0); + CallTypeAndStatusCallback(chan, Type[chan]); + return; + } + + 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; + Type[chan] = SI_ERROR_BUSY; + 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)); + + 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); + } + + CallTypeAndStatusCallback(chan, Type[chan]); +} + +u32 SIGetType(s32 chan) +{ + static u32 cmdTypeAndStatus; + BOOL enabled; + u32 type; + OSTime diff; + + enabled = OSDisableInterrupts(); + + type = Type[chan]; + diff = __OSGetSystemTime() - TypeTime[chan]; + if (Si.poll & (0x80 >> chan)) + { + if (type != SI_ERROR_NO_RESPONSE) + { + TypeTime[chan] = __OSGetSystemTime(); + OSRestoreInterrupts(enabled); + return type; + } + 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)); + + OSRestoreInterrupts(enabled); + return type; +} + +u32 SIGetTypeAsync(s32 chan, SITypeAndStatusCallback callback) +{ + BOOL enabled; + u32 type; + + enabled = OSDisableInterrupts(); + type = SIGetType(chan); + if (Type[chan] & SI_ERROR_BUSY) + { + int i; + + for (i = 0; i < 4; ++i) + { + if (TypeCallback[chan][i] == callback) + { + break; + } + if (TypeCallback[chan][i] == 0) + { + TypeCallback[chan][i] = callback; + break; + } + } + } + else + { + 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_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_COLLISION | SI_ERROR_UNKNOWN)) + { + return SI_ERROR_UNKNOWN; + } + if (error) + { + return SI_ERROR_BUSY; + } + + if ((type & SI_TYPE_MASK) == SI_TYPE_N64) + { + switch (type & 0xffff0000) + { + case SI_N64_CONTROLLER: + case SI_N64_MIC: + case SI_N64_KEYBOARD: + case SI_N64_MOUSE: + case SI_GBA: + return type & 0xffff0000; + break; + } + return SI_ERROR_UNKNOWN; + } + + if ((type & SI_TYPE_MASK) != SI_TYPE_GC) + { + return SI_ERROR_UNKNOWN; + } + switch (type & 0xffff0000) + { + case SI_GC_CONTROLLER: + case SI_GC_STEERING: + return type & 0xffff0000; + break; + } + + if ((type & 0xffe00000) == SI_GC_KEYBOARD) + { + return SI_GC_KEYBOARD; + } + + if ((type & SI_GC_WIRELESS) && !(type & SI_WIRELESS_IR)) + { + if ((type & SI_GC_WAVEBIRD) == SI_GC_WAVEBIRD) + { + return SI_GC_WAVEBIRD; + } + else if (!(type & SI_WIRELESS_STATE)) + { + 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_N64_CONTROLLER: + return "N64 controller"; + case SI_N64_MIC: + return "N64 microphone"; + case SI_N64_KEYBOARD: + return "N64 keyboard"; + case SI_N64_MOUSE: + return "N64 mouse"; + case SI_GBA: + return "GameBoy Advance"; + case SI_GC_CONTROLLER: + return "Standard controller"; + case SI_GC_RECEIVER: + return "Wireless receiver"; + case SI_GC_WAVEBIRD: + return "WaveBird controller"; + case SI_GC_KEYBOARD: + return "Keyboard"; + case SI_GC_STEERING: + return "Steering"; + } +} \ No newline at end of file diff --git a/libs/dolphin/si/SISamplingRate.c b/libs/dolphin/si/SISamplingRate.c new file mode 100644 index 000000000..742759fe0 --- /dev/null +++ b/libs/dolphin/si/SISamplingRate.c @@ -0,0 +1,80 @@ +#include "dolphin/sipriv.h" +#include "dolphin/vi.h" +#include "dolphin/hw_regs.h" + +#pragma dont_inline on +static u32 SamplingRate; + +typedef struct XY +{ + u16 line; + u8 count; +} XY; + +static XY XYNTSC[12] = { + {263 - 17, 2}, + {15, 18}, + {30, 9}, + {44, 6}, + {52, 5}, + {65, 4}, + {87, 3}, + {87, 3}, + {87, 3}, + {131, 2}, + {131, 2}, + {131, 2}, +}; + +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}, +}; + +void SISetSamplingRate(u32 msec) +{ + XY *xy; + BOOL enabled; + + if (msec > 11) + { + msec = 11; + } + + enabled = OSDisableInterrupts(); + + SamplingRate = msec; + + switch (VIGetTvFormat()) + { + case VI_NTSC: + case VI_MPAL: + case VI_EURGB60: + xy = XYNTSC; + break; + case VI_PAL: + xy = XYPAL; + break; + default: + OSReport("SISetSamplingRate: unknown TV format. Use default."); + msec = 0; + xy = XYNTSC; + break; + } + + SISetXY((__VIRegs[54] & 1 ? 2u : 1u) * xy[msec].line, xy[msec].count); + OSRestoreInterrupts(enabled); +} + +void SIRefreshSamplingRate() { SISetSamplingRate(SamplingRate); } +#pragma dont_inline reset \ No newline at end of file diff --git a/libs/dolphin/si/SISteering.c b/libs/dolphin/si/SISteering.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/si/SISteeringAuto.c b/libs/dolphin/si/SISteeringAuto.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/si/SISteeringXfer.c b/libs/dolphin/si/SISteeringXfer.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/thp/THPAudio.c b/libs/dolphin/thp/THPAudio.c new file mode 100644 index 000000000..147d62180 --- /dev/null +++ b/libs/dolphin/thp/THPAudio.c @@ -0,0 +1,202 @@ +#include + +u32 THPAudioDecode(s16 *audioBuffer, u8 *audioFrame, s32 flag) +{ + THPAudioRecordHeader *header; + THPAudioDecodeInfo decInfo; + u8 *left, *right; + s16 *decLeftPtr, *decRightPtr; + s16 yn1, yn2; + s32 i; + s32 step; + s32 sample; + s64 yn; + + if (audioBuffer == NULL || audioFrame == NULL) + { + return 0; + } + + header = (THPAudioRecordHeader *)audioFrame; + left = audioFrame + sizeof(THPAudioRecordHeader); + right = left + header->offsetNextChannel; + + if (flag == 1) + { + decRightPtr = audioBuffer; + decLeftPtr = audioBuffer + header->sampleSize; + step = 1; + } + else + { + decRightPtr = audioBuffer; + decLeftPtr = audioBuffer + 1; + step = 2; + } + + if (header->offsetNextChannel == 0) + { + __THPAudioInitialize(&decInfo, left); + + yn1 = header->lYn1; + yn2 = header->lYn2; + + for (i = 0; i < header->sampleSize; i++) + { + sample = __THPAudioGetNewSample(&decInfo); + yn = header->lCoef[decInfo.predictor][1] * yn2; + yn += header->lCoef[decInfo.predictor][0] * yn1; + yn += (sample << decInfo.scale) << 11; + yn <<= 5; + + if ((u16)(yn & 0xffff) > 0x8000) + { + yn += 0x10000; + } + else if ((u16)(yn & 0xffff) == 0x8000) + { + if ((yn & 0x10000)) + yn += 0x10000; + } + + if (yn > 2147483647LL) + { + yn = 2147483647LL; + } + + if (yn < -2147483648LL) + { + yn = -2147483648LL; + } + + *decLeftPtr = (s16)(yn >> 16); + decLeftPtr += step; + *decRightPtr = (s16)(yn >> 16); + decRightPtr += step; + yn2 = yn1; + yn1 = (s16)(yn >> 16); + } + } + else + { + __THPAudioInitialize(&decInfo, left); + + yn1 = header->lYn1; + yn2 = header->lYn2; + + for (i = 0; i < header->sampleSize; i++) + { + sample = __THPAudioGetNewSample(&decInfo); + yn = header->lCoef[decInfo.predictor][1] * yn2; + yn += header->lCoef[decInfo.predictor][0] * yn1; + yn += (sample << decInfo.scale) << 11; + yn <<= 5; + if ((u16)(yn & 0xffff) > 0x8000) + { + yn += 0x10000; + } + else + { + if ((u16)(yn & 0xffff) == 0x8000) + { + if ((yn & 0x10000)) + yn += 0x10000; + } + } + + if (yn > 2147483647LL) + { + yn = 2147483647LL; + } + + if (yn < -2147483648LL) + { + yn = -2147483648LL; + } + + *decLeftPtr = (s16)(yn >> 16); + decLeftPtr += step; + yn2 = yn1; + yn1 = (s16)(yn >> 16); + } + + __THPAudioInitialize(&decInfo, right); + + yn1 = header->rYn1; + yn2 = header->rYn2; + + for (i = 0; i < header->sampleSize; i++) + { + sample = __THPAudioGetNewSample(&decInfo); + yn = header->rCoef[decInfo.predictor][1] * yn2; + yn += header->rCoef[decInfo.predictor][0] * yn1; + yn += (sample << decInfo.scale) << 11; + yn <<= 5; + + if ((u16)(yn & 0xffff) > 0x8000) + { + yn += 0x10000; + } + else + { + if ((u16)(yn & 0xffff) == 0x8000) + { + if ((yn & 0x10000)) + yn += 0x10000; + } + } + + if (yn > 2147483647LL) + { + yn = 2147483647LL; + } + + if (yn < -2147483648LL) + { + yn = -2147483648LL; + } + + *decRightPtr = (s16)(yn >> 16); + decRightPtr += step; + yn2 = yn1; + yn1 = (s16)(yn >> 16); + } + } + + return header->sampleSize; +} + +static s32 __THPAudioGetNewSample(THPAudioDecodeInfo *info) +{ + s32 sample; + + if (!(info->offsetNibbles & 0x0f)) + { + info->predictor = (u8)((*(info->encodeData) & 0x70) >> 4); + info->scale = (u8)((*(info->encodeData) & 0xF)); + info->encodeData++; + info->offsetNibbles += 2; + } + + if (info->offsetNibbles & 0x1) + { + sample = (s32)((*(info->encodeData) & 0xF) << 28) >> 28; + info->encodeData++; + } + else + { + sample = (s32)((*(info->encodeData) & 0xF0) << 24) >> 28; + } + + info->offsetNibbles++; + return sample; +} + +static void __THPAudioInitialize(THPAudioDecodeInfo *info, u8 *ptr) +{ + info->encodeData = ptr; + info->offsetNibbles = 2; + info->predictor = (u8)((*(info->encodeData) & 0x70) >> 4); + info->scale = (u8)((*(info->encodeData) & 0xF)); + info->encodeData++; +} \ No newline at end of file diff --git a/libs/dolphin/thp/THPDec.c b/libs/dolphin/thp/THPDec.c new file mode 100644 index 000000000..10ceb6189 --- /dev/null +++ b/libs/dolphin/thp/THPDec.c @@ -0,0 +1,2316 @@ +#include +#include + +const char *__THPVersion = "<< Dolphin SDK - THP\trelease build: Aug 27 2002 20:42:01 >>"; + +static THPHuffmanTab *Ydchuff __attribute__((aligned(32))); +static THPHuffmanTab *Udchuff __attribute__((aligned(32))); +static THPHuffmanTab *Vdchuff __attribute__((aligned(32))); +static THPHuffmanTab *Yachuff __attribute__((aligned(32))); +static THPHuffmanTab *Uachuff __attribute__((aligned(32))); +static THPHuffmanTab *Vachuff __attribute__((aligned(32))); +static f32 __THPIDCTWorkspace[64] __attribute__((aligned(32))); +static u8 *__THPHuffmanBits; +static u8 *__THPHuffmanSizeTab; +static u16 *__THPHuffmanCodeTab; +static THPSample *Gbase __attribute__((aligned(32))); +static u32 Gwid __attribute__((aligned(32))); +static f32 *Gq __attribute__((aligned(32))); +static u8 *__THPLCWork512[3]; +static u8 *__THPLCWork672[3]; +static u32 __THPOldGQR5; +static u32 __THPOldGQR6; +static u8 *__THPWorkArea; +static THPCoeff *__THPMCUBuffer[6]; +static THPFileInfo *__THPInfo; +static BOOL __THPInitFlag = FALSE; + +#define ROUNDUP(a, b) ((((s32)(a)) + ((s32)(b)-1L)) / ((s32)(b))) + +void __THPInverseDCTY8(register THPCoeff *, register u32); + +s32 THPVideoDecode(void *file, void *tileY, void *tileU, void *tileV, void *work) +{ + u8 all_done, status; + s32 errorCode; + + if (!file) + { + goto _err_no_input; + } + + if (tileY == NULL || tileU == NULL || tileV == NULL) + { + goto _err_no_output; + } + + if (!work) + { + goto _err_no_work; + } + + if (!(PPCMfhid2() & 0x10000000)) + { + goto _err_lc_not_enabled; + } + + if (__THPInitFlag == FALSE) + { + goto _err_not_initialized; + } + + __THPWorkArea = (u8 *)work; + __THPInfo = (THPFileInfo *)OSRoundUp32B(__THPWorkArea); + __THPWorkArea = (u8 *)OSRoundUp32B(__THPWorkArea) + sizeof(THPFileInfo); + DCZeroRange(__THPInfo, sizeof(THPFileInfo)); + __THPInfo->cnt = 33; + __THPInfo->decompressedY = 0; + __THPInfo->c = (u8 *)file; + all_done = FALSE; + + for (;;) + { + if ((*(__THPInfo->c)++) != 255) + { + goto _err_bad_syntax; + } + + while (*__THPInfo->c == 255) + { + ((__THPInfo->c)++); + } + + status = (*(__THPInfo->c)++); + + if (status <= 0xD7) + { + if (status == 196) + { + status = __THPReadHuffmanTableSpecification(); + if (status != 0) + { + goto _err_bad_status; + } + } + + else if (status == 192) + { + status = __THPReadFrameHeader(); + if (status != 0) + { + goto _err_bad_status; + } + } + + else + { + goto _err_unsupported_marker; + } + } + + else if (0xD8 <= status && status <= 0xDF) + { + if (status == 221) + { + __THPRestartDefinition(); + } + + else if (status == 219) + { + status = __THPReadQuantizationTable(); + if (status != 0) + { + goto _err_bad_status; + } + } + + else if (status == 218) + { + status = __THPReadScaneHeader(); + if (status != 0) + { + goto _err_bad_status; + } + + all_done = TRUE; + } + else if (status == 216) + { + // empty but required for match + } + else + { + goto _err_unsupported_marker; + } + } + + else if (0xE0 <= status) + { + if ((224 <= status && status <= 239) || status == 254) + { + __THPInfo->c += (__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]; + } + else + { + goto _err_unsupported_marker; + } + } + + if (all_done) + { + break; + } + } + + __THPSetupBuffers(); + __THPDecompressYUV(tileY, tileU, tileV); + return 0; + +_err_no_input: + errorCode = 25; + goto _err_exit; + +_err_no_output: + errorCode = 27; + goto _err_exit; + +_err_no_work: + errorCode = 26; + goto _err_exit; + +_err_unsupported_marker: + errorCode = 11; + goto _err_exit; + +_err_bad_resource: + errorCode = 1; + goto _err_exit; + +_err_no_mem: + errorCode = 6; + goto _err_exit; + +_err_bad_syntax: + errorCode = 3; + goto _err_exit; + +_err_bad_status: + errorCode = status; + goto _err_exit; + +_err_lc_not_enabled: + errorCode = 28; + goto _err_exit; + +_err_not_initialized: + errorCode = 29; + goto _err_exit; + +_err_exit: + return errorCode; +} + +static void __THPSetupBuffers(void) +{ + u8 i; + THPCoeff *buffer; + + buffer = (THPCoeff *)OSRoundUp32B(__THPWorkArea); + + for (i = 0; i < 6; i++) + { + __THPMCUBuffer[i] = &buffer[i * 64]; + } +} + +u8 __THPReadFrameHeader(void) +{ + u8 i, utmp8; + + __THPInfo->c += 2; + + utmp8 = (*(__THPInfo->c)++); + + if (utmp8 != 8) + { + return 10; + } + + __THPInfo->yPixelSize = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); + __THPInfo->c += 2; + __THPInfo->xPixelSize = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); + __THPInfo->c += 2; + + utmp8 = (*(__THPInfo->c)++); + if (utmp8 != 3) + { + return 12; + } + + for (i = 0; i < 3; i++) + { + utmp8 = (*(__THPInfo->c)++); + utmp8 = (*(__THPInfo->c)++); + if ((i == 0 && utmp8 != 0x22) || (i > 0 && utmp8 != 0x11)) + { + return 19; + } + + __THPInfo->components[i].quantizationTableSelector = (*(__THPInfo->c)++); + } + + return 0; +} + +/* there is an EXTREMELY tiny schedule swap but otherwise matching */ +u8 __THPReadScaneHeader(void) +{ + u8 i, utmp8; + __THPInfo->c += 2; + + utmp8 = (*(__THPInfo->c)++); + + if (utmp8 != 3) + { + return 12; + } + + for (i = 0; i < 3; i++) + { + utmp8 = (*(__THPInfo->c)++); + + utmp8 = (*(__THPInfo->c)++); + __THPInfo->components[i].DCTableSelector = (u8)(utmp8 >> 4); + __THPInfo->components[i].ACTableSelector = (u8)(utmp8 & 15); + + if ((__THPInfo->validHuffmanTabs & (1 << ((utmp8 >> 4)))) == 0) + { + return 15; + } + + if ((__THPInfo->validHuffmanTabs & (1 << ((utmp8 & 15) + 1))) == 0) + { + return 15; + } + } + + __THPInfo->c += 3; + __THPInfo->MCUsPerRow = (u16)ROUNDUP(__THPInfo->xPixelSize, 16); + __THPInfo->components[0].predDC = 0; + __THPInfo->components[1].predDC = 0; + __THPInfo->components[2].predDC = 0; + return 0; +} + +u8 __THPReadQuantizationTable(void) +{ + u16 length, id, i, row, col; + f32 q_temp[64]; + + length = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); + __THPInfo->c += 2; + length -= 2; + + for (;;) + { + id = (*(__THPInfo->c)++); + + for (i = 0; i < 64; i++) + { + q_temp[__THPJpegNaturalOrder[i]] = (f32)(*(__THPInfo->c)++); + } + + i = 0; + for (row = 0; row < 8; row++) + { + for (col = 0; col < 8; col++) + { + __THPInfo->quantTabs[id][i] = (f32)((f64)q_temp[i] * __THPAANScaleFactor[row] * __THPAANScaleFactor[col]); + i++; + } + } + + length -= 65; + if (!length) + { + break; + } + } + + return 0; +} + +u8 __THPReadHuffmanTableSpecification(void) +{ + u8 t_class, id, i, tab_index; + u16 length, num_Vij; + + __THPHuffmanSizeTab = __THPWorkArea; + __THPHuffmanCodeTab = (u16 *)((u32)__THPWorkArea + 256 + 1); + length = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); + __THPInfo->c += 2; + length -= 2; + + for (;;) + { + i = (*(__THPInfo->c)++); + id = (u8)(i & 15); + t_class = (u8)(i >> 4); + __THPHuffmanBits = __THPInfo->c; + tab_index = (u8)((id << 1) + t_class); + num_Vij = 0; + + for (i = 0; i < 16; i++) + { + num_Vij += (*(__THPInfo->c)++); + } + + __THPInfo->huffmanTabs[tab_index].Vij = __THPInfo->c; + __THPInfo->c += num_Vij; + __THPHuffGenerateSizeTable(); + __THPHuffGenerateCodeTable(); + __THPHuffGenerateDecoderTables(tab_index); + __THPInfo->validHuffmanTabs |= 1 << tab_index; + length -= 17 + num_Vij; + + if (length == 0) + { + break; + } + } + + return 0; +} + +static void __THPHuffGenerateSizeTable(void) +{ + s32 p, l, i; + p = 0; + + for (l = 1; l <= 16; l++) + { + i = (s32)__THPHuffmanBits[l - 1]; + while (i--) + { + __THPHuffmanSizeTab[p++] = (u8)l; + } + } + + __THPHuffmanSizeTab[p] = 0; +} + +static void __THPHuffGenerateCodeTable(void) +{ + u8 si; + u16 p, code; + + p = 0; + code = 0; + si = __THPHuffmanSizeTab[0]; + + while (__THPHuffmanSizeTab[p]) + { + while (__THPHuffmanSizeTab[p] == si) + { + __THPHuffmanCodeTab[p++] = code; + code++; + } + + code <<= 1; + si++; + } +} + +static void __THPHuffGenerateDecoderTables(u8 tabIndex) +{ + s32 p, l; + THPHuffmanTab *h; + + p = 0; + h = &__THPInfo->huffmanTabs[tabIndex]; + for (l = 1; l <= 16; l++) + { + if (__THPHuffmanBits[l - 1]) + { + h->valPtr[l] = p - __THPHuffmanCodeTab[p]; + p += __THPHuffmanBits[l - 1]; + h->maxCode[l] = __THPHuffmanCodeTab[p - 1]; + } + else + { + h->maxCode[l] = -1; + h->valPtr[l] = -1; + } + } + + h->maxCode[17] = 0xfffffL; +} + +static void __THPRestartDefinition(void) +{ + __THPInfo->RST = TRUE; + __THPInfo->c += 2; + __THPInfo->nMCU = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); + __THPInfo->c += 2; + __THPInfo->currMCU = __THPInfo->nMCU; +} + +static inline void __THPGQRSetup(void) +{ + register u32 tmp1, tmp2; + + asm { + mfspr tmp1, GQR5; + mfspr tmp2, GQR6; + } + + __THPOldGQR5 = tmp1; + __THPOldGQR6 = tmp2; + + asm { + li r3, 0x0007 + oris r3, r3, 0x0007 + mtspr GQR5, r3 + li r3, 0x3D04 + oris r3, r3, 0x3D04 + mtspr GQR6, r3 + } +} + +static inline void __THPGQRRestore(void) +{ + register u32 tmp1, tmp2; + tmp1 = __THPOldGQR5; + tmp2 = __THPOldGQR6; + + asm { + mtspr GQR5, tmp1; + mtspr GQR6, tmp2; + } +} + +void __THPPrepBitStream(void) +{ + u32 *ptr; + u32 offset, i, j, k; + + ptr = (u32 *)((u32)__THPInfo->c & 0xFFFFFFFC); + offset = (u32)__THPInfo->c & 3; + + if (__THPInfo->cnt != 33) + { + __THPInfo->cnt -= (3 - offset) * 8; + } + else + { + __THPInfo->cnt = (offset * 8) + 1; + } + + __THPInfo->c = (u8 *)ptr; + __THPInfo->currByte = *ptr; + + for (i = 0; i < 4; i++) + { + if (__THPInfo->validHuffmanTabs & (1 << i)) + { + for (j = 0; j < 32; j++) + { + __THPInfo->huffmanTabs[i].quick[j] = 0xFF; + + for (k = 0; k < 5; k++) + { + s32 code = (s32)(j >> (5 - k - 1)); + + if (code <= __THPInfo->huffmanTabs[i].maxCode[k + 1]) + { + __THPInfo->huffmanTabs[i].quick[j] = __THPInfo->huffmanTabs[i].Vij[(s32)(code + __THPInfo->huffmanTabs[i].valPtr[k + 1])]; + __THPInfo->huffmanTabs[i].increment[j] = (u8)(k + 1); + k = 99; + } + else + { + } + } + } + } + } + + { + s32 YdcTab, UdcTab, VdcTab, YacTab, UacTab, VacTab; + + YdcTab = (__THPInfo->components[0].DCTableSelector << 1); + UdcTab = (__THPInfo->components[1].DCTableSelector << 1); + VdcTab = (__THPInfo->components[2].DCTableSelector << 1); + + YacTab = (__THPInfo->components[0].ACTableSelector << 1) + 1; + UacTab = (__THPInfo->components[1].ACTableSelector << 1) + 1; + VacTab = (__THPInfo->components[2].ACTableSelector << 1) + 1; + + Ydchuff = &__THPInfo->huffmanTabs[YdcTab]; + Udchuff = &__THPInfo->huffmanTabs[UdcTab]; + Vdchuff = &__THPInfo->huffmanTabs[VdcTab]; + + Yachuff = &__THPInfo->huffmanTabs[YacTab]; + Uachuff = &__THPInfo->huffmanTabs[UacTab]; + Vachuff = &__THPInfo->huffmanTabs[VacTab]; + } +} + +void __THPDecompressYUV(void *tileY, void *tileU, void *tileV) +{ + u16 currentY, targetY; + __THPInfo->dLC[0] = tileY; + __THPInfo->dLC[1] = tileU; + __THPInfo->dLC[2] = tileV; + + currentY = __THPInfo->decompressedY; + targetY = __THPInfo->yPixelSize; + + __THPGQRSetup(); + __THPPrepBitStream(); + + if (__THPInfo->xPixelSize == 512 && targetY == 448) + { + while (currentY < targetY) + { + __THPDecompressiMCURow512x448(); + currentY += 16; + } + } + else if (__THPInfo->xPixelSize == 640 && targetY == 480) + { + while (currentY < targetY) + { + __THPDecompressiMCURow640x480(); + currentY += 16; + } + } + else + { + while (currentY < targetY) + { + __THPDecompressiMCURowNxN(); + currentY += 16; + } + } + + __THPGQRRestore(); +} + +inline void __THPInverseDCTNoYPos(register THPCoeff *in, register u32 xPos) +{ + register f32 *q, *ws; + register f32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; + register f32 tmp10, tmp11, tmp12, tmp13; + register f32 tmp20, tmp21, tmp22, tmp23; + register f32 cc4 = 1.414213562F; + register f32 cc2 = 1.847759065F; + register f32 cc2c6s = 1.082392200F; + register f32 cc2c6a = -2.613125930F; + register f32 bias = 1024.0F; + q = Gq; + ws = &__THPIDCTWorkspace[0] - 2; + + { + register u32 itmp0, itmp1, itmp2, itmp3; + asm { + li itmp2, 8 + mtctr itmp2 + + _loopHead0: + psq_l tmp10, 0(in), 0, 5 + psq_l tmp11, 0(q), 0, 0 + lwz itmp0, 12(in) + lwz itmp3, 8(in) + ps_mul tmp10, tmp10, tmp11 + lwz itmp1, 4(in) + lhz itmp2, 2(in) + or. itmp0, itmp0, itmp3 + + _loopHead1: + cmpwi itmp0, 0 + bne _regularIDCT + ps_merge00 tmp0, tmp10, tmp10 + cmpwi itmp1, 0 + psq_st tmp0, 8(ws), 0, 0 + bne _halfIDCT + psq_st tmp0, 16(ws), 0, 0 + cmpwi itmp2, 0 + psq_st tmp0, 24(ws), 0, 0 + bne _quarterIDCT + addi q, q, 8*sizeof(f32) + psq_stu tmp0, 32(ws), 0, 0 + addi in, in, 8*sizeof(THPCoeff) + bdnz _loopHead0 + b _loopEnd + + _quarterIDCT: + addi in, in, 8*sizeof(THPCoeff) + ps_msub tmp2, tmp10, cc2, tmp10 + addi q, q, 8*sizeof(f32) + ps_merge00 tmp9, tmp10, tmp10 + lwz itmp1, 4(in) + ps_sub tmp1, cc2, cc2c6s + ps_msub tmp3, tmp10, cc4, tmp2 + lhz itmp2, 2(in) + ps_merge11 tmp5, tmp10, tmp2 + psq_l tmp11, 0(q), 0, 0 + ps_nmsub tmp4, tmp10, tmp1, tmp3 + ps_add tmp7, tmp9, tmp5 + psq_l tmp10, 0(in), 0, 5 + ps_merge11 tmp6, tmp3, tmp4 + ps_sub tmp5, tmp9, tmp5 + lwz itmp0, 12(in) + ps_add tmp8, tmp9, tmp6 + lwz itmp3, 8(in) + ps_sub tmp6, tmp9, tmp6 + psq_stu tmp7, 8(ws), 0, 0 + ps_merge10 tmp6, tmp6, tmp6 + psq_stu tmp8, 8(ws), 0, 0 + ps_merge10 tmp5, tmp5, tmp5 + or itmp0, itmp0, itmp3 + psq_stu tmp6, 8(ws), 0, 0 + ps_mul tmp10, tmp10, tmp11 + psq_stu tmp5, 8(ws), 0, 0 + bdnz _loopHead1 + b _loopEnd + + _halfIDCT: + psq_l tmp1, 4(in), 0, 5 + psq_l tmp9, 8(q), 0, 0 + addi in, in, 8*sizeof(THPCoeff) + ps_mul tmp1, tmp1, tmp9 + addi q, q, 8*sizeof(f32) + ps_sub tmp3, tmp10, tmp1 + ps_add tmp2, tmp10, tmp1 + lwz itmp0, 12(in) + ps_madd tmp4, tmp1, cc4, tmp3 + ps_nmsub tmp5, tmp1, cc4, tmp2 + ps_mul tmp8, tmp3, cc2 + ps_merge00 tmp4, tmp2, tmp4 + lwz itmp3, 8(in) + ps_nmsub tmp6, tmp1, cc2c6a, tmp8 + ps_merge00 tmp5, tmp5, tmp3 + lwz itmp1, 4(in) + ps_sub tmp6, tmp6, tmp2 + ps_nmsub tmp7, tmp10, cc2c6s, tmp8 + lhz itmp2, 2(in) + ps_merge11 tmp2, tmp2, tmp6 + ps_msub tmp8, tmp3, cc4, tmp6 + psq_l tmp10, 0(in), 0, 5 + ps_add tmp9, tmp4, tmp2 + ps_sub tmp7, tmp7, tmp8 + psq_l tmp11, 0(q), 0, 0 + ps_merge11 tmp3, tmp8, tmp7 + ps_sub tmp4, tmp4, tmp2 + psq_stu tmp9, 8(ws), 0, 0 + ps_add tmp0, tmp5, tmp3 + ps_sub tmp1, tmp5, tmp3 + or itmp0, itmp0, itmp3 + psq_stu tmp0, 8(ws), 0, 0 + ps_merge10 tmp1, tmp1, tmp1 + ps_merge10 tmp4, tmp4, tmp4 + psq_stu tmp1, 8(ws), 0, 0 + ps_mul tmp10, tmp10, tmp11 + psq_stu tmp4, 8(ws), 0, 0 + bdnz _loopHead1 + b _loopEnd + + _regularIDCT: + psq_l tmp9, 4(in), 0, 5 + psq_l tmp5, 8(q), 0, 0 + ps_mul tmp9, tmp9, tmp5 + psq_l tmp2, 8(in), 0, 5 + psq_l tmp6, 16(q), 0, 0 + ps_merge01 tmp0, tmp10, tmp9 + psq_l tmp3, 12(in), 0, 5 + ps_merge01 tmp1, tmp9, tmp10 + psq_l tmp7, 24(q), 0, 0 + addi in, in, 8*sizeof(THPCoeff) + ps_madd tmp4, tmp2, tmp6, tmp0 + ps_nmsub tmp5, tmp2, tmp6, tmp0 + ps_madd tmp6, tmp3, tmp7, tmp1 + ps_nmsub tmp7, tmp3, tmp7, tmp1 + addi q, q, 8*sizeof(f32) + ps_add tmp0, tmp4, tmp6 + ps_sub tmp3, tmp4, tmp6 + ps_msub tmp2, tmp7, cc4, tmp6 + lwz itmp0, 12(in) + ps_sub tmp8, tmp7, tmp5 + ps_add tmp1, tmp5, tmp2 + ps_sub tmp2, tmp5, tmp2 + ps_mul tmp8, tmp8, cc2 + lwz itmp3, 8(in) + ps_merge00 tmp1, tmp0, tmp1 + ps_nmsub tmp6, tmp5, cc2c6a, tmp8 + ps_msub tmp4, tmp7, cc2c6s, tmp8 + lwz itmp1, 4(in) + ps_sub tmp6, tmp6, tmp0 + ps_merge00 tmp2, tmp2, tmp3 + lhz itmp2, 2(in) + ps_madd tmp5, tmp3, cc4, tmp6 + ps_merge11 tmp7, tmp0, tmp6 + psq_l tmp10, 0(in), 0, 5 + ps_sub tmp4, tmp4, tmp5 + ps_add tmp3, tmp1, tmp7 + psq_l tmp11, 0(q), 0, 0 + ps_merge11 tmp4, tmp5, tmp4 + ps_sub tmp0, tmp1, tmp7 + ps_mul tmp10, tmp10, tmp11 + ps_add tmp5, tmp2, tmp4 + ps_sub tmp6, tmp2, tmp4 + ps_merge10 tmp5, tmp5, tmp5 + psq_stu tmp3, 8(ws), 0, 0 + ps_merge10 tmp0, tmp0, tmp0 + psq_stu tmp6, 8(ws), 0, 0 + psq_stu tmp5, 8(ws), 0, 0 + or itmp0, itmp0, itmp3 + psq_stu tmp0, 8(ws), 0, 0 + bdnz _loopHead1 + + _loopEnd: + + } + } + + ws = &__THPIDCTWorkspace[0]; + + { + register THPSample *obase = Gbase; + register u32 wid = Gwid; + + register u32 itmp0, off0, off1; + register THPSample *out0, *out1; + + asm { + psq_l tmp10, 8*0*sizeof(f32)(ws), 0, 0 + slwi xPos, xPos, 2 + psq_l tmp11, 8*4*sizeof(f32)(ws), 0, 0 + slwi off1, wid, 2 + psq_l tmp12, 8*2*sizeof(f32)(ws), 0, 0 + mr off0, xPos + ps_add tmp6, tmp10, tmp11 + psq_l tmp13, 8*6*sizeof(f32)(ws), 0, 0 + ps_sub tmp8, tmp10, tmp11 + add off1, off0, off1 + ps_add tmp6, tmp6, bias + li itmp0, 3 + ps_add tmp7, tmp12, tmp13 + add out0, obase, off0 + ps_sub tmp9, tmp12, tmp13 + ps_add tmp0, tmp6, tmp7 + add out1, obase, off1 + ps_add tmp8, tmp8, bias + mtctr itmp0 + + _loopHead10: + psq_l tmp4, 8*1*sizeof(f32)(ws), 0, 0 + ps_msub tmp9, tmp9, cc4, tmp7 + psq_l tmp5, 8*3*sizeof(f32)(ws), 0, 0 + ps_sub tmp3, tmp6, tmp7 + ps_add tmp1, tmp8, tmp9 + psq_l tmp6, 8*5*sizeof(f32)(ws), 0, 0 + ps_sub tmp2, tmp8, tmp9 + psq_l tmp7, 8*7*sizeof(f32)(ws), 0, 0 + ps_add tmp8, tmp6, tmp5 + ps_sub tmp6, tmp6, tmp5 + addi ws, ws, 2*sizeof(f32) + ps_add tmp9, tmp4, tmp7 + ps_sub tmp4, tmp4, tmp7 + psq_l tmp10, 8*0*sizeof(f32)(ws), 0, 0 + ps_add tmp7, tmp9, tmp8 + ps_sub tmp5, tmp9, tmp8 + ps_add tmp8, tmp6, tmp4 + psq_l tmp11, 8*4*sizeof(f32)(ws), 0, 0 + ps_add tmp9, tmp0, tmp7 + ps_mul tmp8, tmp8, cc2 + psq_l tmp12, 8*2*sizeof(f32)(ws), 0, 0 + ps_sub tmp23, tmp0, tmp7 + ps_madd tmp6, tmp6, cc2c6a, tmp8 + psq_l tmp13, 8*6*sizeof(f32)(ws), 0, 0 + ps_sub tmp6, tmp6, tmp7 + addi off0, off0, 2*sizeof(THPSample) + psq_st tmp9, 0(out0), 0, 6 + ps_msub tmp4, tmp4, cc2c6s, tmp8 + ps_add tmp9, tmp1, tmp6 + ps_msub tmp5, tmp5, cc4, tmp6 + ps_sub tmp22, tmp1, tmp6 + psq_st tmp9, 8(out0), 0, 6 + ps_add tmp8, tmp2, tmp5 + ps_add tmp4, tmp4, tmp5 + psq_st tmp8, 16(out0), 0, 6 + addi off1, off1, 2*sizeof(THPSample) + ps_sub tmp9, tmp3, tmp4 + ps_add tmp20, tmp3, tmp4 + psq_st tmp9, 24(out0), 0, 6 + ps_sub tmp21, tmp2, tmp5 + ps_add tmp6, tmp10, tmp11 + psq_st tmp20, 0(out1), 0, 6 + ps_sub tmp8, tmp10, tmp11 + ps_add tmp6, tmp6, bias + psq_st tmp21, 8(out1), 0, 6 + ps_add tmp7, tmp12, tmp13 + ps_sub tmp9, tmp12, tmp13 + psq_st tmp22, 16(out1), 0, 6 + add out0, obase, off0 + ps_add tmp0, tmp6, tmp7 + psq_st tmp23, 24(out1), 0, 6 + ps_add tmp8, tmp8, bias + add out1, obase, off1 + bdnz _loopHead10 + psq_l tmp4, 8*1*sizeof(f32)(ws), 0, 0 + ps_msub tmp9, tmp9, cc4, tmp7 + psq_l tmp5, 8*3*sizeof(f32)(ws), 0, 0 + ps_sub tmp3, tmp6, tmp7 + ps_add tmp1, tmp8, tmp9 + psq_l tmp6, 8*5*sizeof(f32)(ws), 0, 0 + ps_sub tmp2, tmp8, tmp9 + psq_l tmp7, 8*7*sizeof(f32)(ws), 0, 0 + ps_add tmp8, tmp6, tmp5 + ps_sub tmp6, tmp6, tmp5 + ps_add tmp9, tmp4, tmp7 + ps_sub tmp4, tmp4, tmp7 + ps_add tmp7, tmp9, tmp8 + ps_sub tmp5, tmp9, tmp8 + ps_add tmp8, tmp6, tmp4 + ps_add tmp9, tmp0, tmp7 + ps_mul tmp8, tmp8, cc2 + ps_sub tmp23, tmp0, tmp7 + ps_madd tmp6, tmp6, cc2c6a, tmp8 + psq_st tmp9, 0(out0), 0, 6 + ps_sub tmp6, tmp6, tmp7 + ps_msub tmp4, tmp4, cc2c6s, tmp8 + psq_st tmp23, 24(out1), 0, 6 + ps_add tmp9, tmp1, tmp6 + ps_msub tmp5, tmp5, cc4, tmp6 + ps_sub tmp22, tmp1, tmp6 + psq_st tmp9, 8(out0), 0, 6 + ps_add tmp8, tmp2, tmp5 + ps_add tmp4, tmp4, tmp5 + psq_st tmp22, 16(out1), 0, 6 + psq_st tmp8, 16(out0), 0, 6 + ps_sub tmp9, tmp3, tmp4 + ps_add tmp20, tmp3, tmp4 + psq_st tmp9, 24(out0), 0, 6 + ps_sub tmp21, tmp2, tmp5 + psq_st tmp20, 0(out1), 0, 6 + psq_st tmp21, 8(out1), 0, 6 + } + } +} + +inline void __THPInverseDCTY8(register THPCoeff *in, register u32 xPos) +{ + register f32 *q, *ws; + register f32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; + register f32 tmp10, tmp11, tmp12, tmp13; + register f32 tmp20, tmp21, tmp22, tmp23; + register f32 cc4 = 1.414213562F; + register f32 cc2 = 1.847759065F; + register f32 cc2c6s = 1.082392200F; + register f32 cc2c6a = -2.613125930F; + register f32 bias = 1024.0F; + + q = Gq; + ws = &__THPIDCTWorkspace[0] - 2; + + { + register u32 itmp0, itmp1, itmp2, itmp3; + + asm { + li itmp2, 8 + mtctr itmp2 + + _loopHead0: + psq_l tmp10, 0(in), 0, 5 + psq_l tmp11, 0(q), 0, 0 + lwz itmp0, 12(in) + lwz itmp3, 8(in) + ps_mul tmp10, tmp10, tmp11 + lwz itmp1, 4(in) + lhz itmp2, 2(in) + or itmp0, itmp0, itmp3 + + _loopHead1: + cmpwi itmp0, 0 + bne _regularIDCT + ps_merge00 tmp0, tmp10, tmp10 + cmpwi itmp1, 0 + psq_st tmp0, 8(ws), 0, 0 + bne _halfIDCT + psq_st tmp0, 16(ws), 0, 0 + cmpwi itmp2, 0 + psq_st tmp0, 24(ws), 0, 0 + bne _quarterIDCT + addi q, q, 8*sizeof(f32) + psq_stu tmp0, 32(ws), 0, 0 + addi in, in, 8*sizeof(THPCoeff) + bdnz _loopHead0 + b _loopEnd + + _quarterIDCT: + ps_msub tmp2, tmp10, cc2, tmp10 + addi in, in, 8*sizeof(THPCoeff) + ps_merge00 tmp9, tmp10, tmp10 + addi q, q, 8*sizeof(f32) + ps_sub tmp1, cc2, cc2c6s + lwz itmp1, 4(in) + ps_msub tmp3, tmp10, cc4, tmp2 + lhz itmp2, 2(in) + ps_merge11 tmp5, tmp10, tmp2 + psq_l tmp11, 0(q), 0, 0 + ps_nmsub tmp4, tmp10, tmp1, tmp3 + ps_add tmp7, tmp9, tmp5 + psq_l tmp10, 0(in), 0, 5 + ps_merge11 tmp6, tmp3, tmp4 + ps_sub tmp5, tmp9, tmp5 + lwz itmp0, 12(in) + ps_add tmp8, tmp9, tmp6 + lwz itmp3, 8(in) + ps_sub tmp6, tmp9, tmp6 + psq_stu tmp7, 8(ws), 0, 0 + ps_merge10 tmp6, tmp6, tmp6 + psq_stu tmp8, 8(ws), 0, 0 + ps_merge10 tmp5, tmp5, tmp5 + or itmp0, itmp0, itmp3 + psq_stu tmp6, 8(ws), 0, 0 + ps_mul tmp10, tmp10, tmp11 + psq_stu tmp5, 8(ws), 0, 0 + bdnz _loopHead1 + b _loopEnd + + _halfIDCT: + psq_l tmp1, 4(in), 0, 5 + psq_l tmp9, 8(q), 0, 0 + addi in, in, 8*sizeof(THPCoeff) + ps_mul tmp1, tmp1, tmp9 + addi q, q, 8*sizeof(f32) + ps_sub tmp3, tmp10, tmp1 + ps_add tmp2, tmp10, tmp1 + lwz itmp0, 12(in) + ps_madd tmp4, tmp1, cc4, tmp3 + ps_nmsub tmp5, tmp1, cc4, tmp2 + ps_mul tmp8, tmp3, cc2 + ps_merge00 tmp4, tmp2, tmp4 + lwz itmp3, 8(in) + ps_nmsub tmp6, tmp1, cc2c6a, tmp8 + ps_merge00 tmp5, tmp5, tmp3 + lwz itmp1, 4(in) + ps_sub tmp6, tmp6, tmp2 + ps_nmsub tmp7, tmp10, cc2c6s, tmp8 + lhz itmp2, 2(in) + ps_merge11 tmp2, tmp2, tmp6 + ps_msub tmp8, tmp3, cc4, tmp6 + psq_l tmp10, 0(in), 0, 5 + ps_add tmp9, tmp4, tmp2 + ps_sub tmp7, tmp7, tmp8 + psq_l tmp11, 0(q), 0, 0 + ps_merge11 tmp3, tmp8, tmp7 + ps_sub tmp4, tmp4, tmp2 + psq_stu tmp9, 8(ws), 0, 0 + ps_add tmp0, tmp5, tmp3 + ps_sub tmp1, tmp5, tmp3 + or itmp0, itmp0, itmp3 + psq_stu tmp0, 8(ws), 0, 0 + ps_merge10 tmp1, tmp1, tmp1 + ps_merge10 tmp4, tmp4, tmp4 + psq_stu tmp1, 8(ws), 0, 0 + ps_mul tmp10, tmp10, tmp11 + psq_stu tmp4, 8(ws), 0, 0 + bdnz _loopHead1 + b _loopEnd + + _regularIDCT: + psq_l tmp9, 4(in), 0, 5 + psq_l tmp5, 8(q), 0, 0 + ps_mul tmp9, tmp9, tmp5 + psq_l tmp2, 8(in), 0, 5 + psq_l tmp6, 16(q), 0, 0 + ps_merge01 tmp0, tmp10, tmp9 + psq_l tmp3, 12(in), 0, 5 + ps_merge01 tmp1, tmp9, tmp10 + psq_l tmp7, 24(q), 0, 0 + addi in, in, 8*sizeof(THPCoeff) + ps_madd tmp4, tmp2, tmp6, tmp0 + ps_nmsub tmp5, tmp2, tmp6, tmp0 + ps_madd tmp6, tmp3, tmp7, tmp1 + ps_nmsub tmp7, tmp3, tmp7, tmp1 + addi q, q, 8*sizeof(f32) + ps_add tmp0, tmp4, tmp6 + ps_sub tmp3, tmp4, tmp6 + ps_msub tmp2, tmp7, cc4, tmp6 + lwz itmp0, 12(in) + ps_sub tmp8, tmp7, tmp5 + ps_add tmp1, tmp5, tmp2 + ps_sub tmp2, tmp5, tmp2 + ps_mul tmp8, tmp8, cc2 + lwz itmp3, 8(in) + ps_merge00 tmp1, tmp0, tmp1 + ps_nmsub tmp6, tmp5, cc2c6a, tmp8 + ps_msub tmp4, tmp7, cc2c6s, tmp8 + lwz itmp1, 4(in) + ps_sub tmp6, tmp6, tmp0 + ps_merge00 tmp2, tmp2, tmp3 + lhz itmp2, 2(in) + ps_madd tmp5, tmp3, cc4, tmp6 + ps_merge11 tmp7, tmp0, tmp6 + psq_l tmp10, 0(in), 0, 5 + ps_sub tmp4, tmp4, tmp5 + ps_add tmp3, tmp1, tmp7 + psq_l tmp11, 0(q), 0, 0 + ps_merge11 tmp4, tmp5, tmp4 + ps_sub tmp0, tmp1, tmp7 + ps_mul tmp10, tmp10, tmp11 + ps_add tmp5, tmp2, tmp4 + ps_sub tmp6, tmp2, tmp4 + ps_merge10 tmp5, tmp5, tmp5 + psq_stu tmp3, 8(ws), 0, 0 + ps_merge10 tmp0, tmp0, tmp0 + psq_stu tmp6, 8(ws), 0, 0 + psq_stu tmp5, 8(ws), 0, 0 + or itmp0, itmp0, itmp3 + psq_stu tmp0, 8(ws), 0, 0 + bdnz _loopHead1 + + _loopEnd: + + } + } + + ws = &__THPIDCTWorkspace[0]; + + { + register THPSample *obase = Gbase; + register u32 wid = Gwid; + + register u32 itmp0, off0, off1; + register THPSample *out0, *out1; + + asm { + psq_l tmp10, 8*0*sizeof(f32)(ws), 0, 0 + slwi off0, wid, 3; + psq_l tmp11, 8*4*sizeof(f32)(ws), 0, 0 + slwi xPos, xPos, 2 + psq_l tmp12, 8*2*sizeof(f32)(ws), 0, 0 + slwi off1, wid, 2 + ps_add tmp6, tmp10, tmp11 + add off0, off0, xPos + psq_l tmp13, 8*6*sizeof(f32)(ws), 0, 0 + ps_sub tmp8, tmp10, tmp11 + add off1, off0, off1 + ps_add tmp6, tmp6, bias + li itmp0, 3 + ps_add tmp7, tmp12, tmp13 + add out0, obase, off0 + ps_sub tmp9, tmp12, tmp13 + ps_add tmp0, tmp6, tmp7 + add out1, obase, off1 + ps_add tmp8, tmp8, bias + mtctr itmp0 + + _loopHead10: + psq_l tmp4, 8*1*sizeof(f32)(ws), 0, 0 + ps_msub tmp9, tmp9, cc4, tmp7 + psq_l tmp5, 8*3*sizeof(f32)(ws), 0, 0 + ps_sub tmp3, tmp6, tmp7 + ps_add tmp1, tmp8, tmp9 + psq_l tmp6, 8*5*sizeof(f32)(ws), 0, 0 + ps_sub tmp2, tmp8, tmp9 + psq_l tmp7, 8*7*sizeof(f32)(ws), 0, 0 + ps_add tmp8, tmp6, tmp5 + ps_sub tmp6, tmp6, tmp5 + addi ws, ws, 2*sizeof(f32) + ps_add tmp9, tmp4, tmp7 + ps_sub tmp4, tmp4, tmp7 + psq_l tmp10, 8*0*sizeof(f32)(ws), 0, 0 + ps_add tmp7, tmp9, tmp8 + ps_sub tmp5, tmp9, tmp8 + ps_add tmp8, tmp6, tmp4 + psq_l tmp11, 8*4*sizeof(f32)(ws), 0, 0 + ps_add tmp9, tmp0, tmp7 + ps_mul tmp8, tmp8, cc2 + psq_l tmp12, 8*2*sizeof(f32)(ws), 0, 0 + ps_sub tmp23, tmp0, tmp7 + ps_madd tmp6, tmp6, cc2c6a, tmp8 + psq_l tmp13, 8*6*sizeof(f32)(ws), 0, 0 + ps_sub tmp6, tmp6, tmp7 + addi off0, off0, 2*sizeof(THPSample) + psq_st tmp9, 0(out0), 0, 6 + ps_msub tmp4, tmp4, cc2c6s, tmp8 + ps_add tmp9, tmp1, tmp6 + ps_msub tmp5, tmp5, cc4, tmp6 + ps_sub tmp22, tmp1, tmp6 + psq_st tmp9, 8(out0), 0, 6 + ps_add tmp8, tmp2, tmp5 + ps_add tmp4, tmp4, tmp5 + psq_st tmp8, 16(out0), 0, 6 + addi off1, off1, 2*sizeof(THPSample) + ps_sub tmp9, tmp3, tmp4 + ps_add tmp20, tmp3, tmp4 + psq_st tmp9, 24(out0), 0, 6 + ps_sub tmp21, tmp2, tmp5 + ps_add tmp6, tmp10, tmp11 + psq_st tmp20, 0(out1), 0, 6 + ps_sub tmp8, tmp10, tmp11 + ps_add tmp6, tmp6, bias + psq_st tmp21, 8(out1), 0, 6 + ps_add tmp7, tmp12, tmp13 + ps_sub tmp9, tmp12, tmp13 + psq_st tmp22, 16(out1), 0, 6 + add out0, obase, off0 + ps_add tmp0, tmp6, tmp7 + psq_st tmp23, 24(out1), 0, 6 + ps_add tmp8, tmp8, bias + add out1, obase, off1 + + bdnz _loopHead10 + psq_l tmp4, 8*1*sizeof(f32)(ws), 0, 0 + ps_msub tmp9, tmp9, cc4, tmp7 + psq_l tmp5, 8*3*sizeof(f32)(ws), 0, 0 + ps_sub tmp3, tmp6, tmp7 + ps_add tmp1, tmp8, tmp9 + psq_l tmp6, 8*5*sizeof(f32)(ws), 0, 0 + ps_sub tmp2, tmp8, tmp9 + psq_l tmp7, 8*7*sizeof(f32)(ws), 0, 0 + ps_add tmp8, tmp6, tmp5 + ps_sub tmp6, tmp6, tmp5 + ps_add tmp9, tmp4, tmp7 + ps_sub tmp4, tmp4, tmp7 + ps_add tmp7, tmp9, tmp8 + ps_sub tmp5, tmp9, tmp8 + ps_add tmp8, tmp6, tmp4 + ps_add tmp9, tmp0, tmp7 + ps_mul tmp8, tmp8, cc2 + ps_sub tmp23, tmp0, tmp7 + ps_madd tmp6, tmp6, cc2c6a, tmp8 + psq_st tmp9, 0(out0), 0, 6 + ps_sub tmp6, tmp6, tmp7 + ps_msub tmp4, tmp4, cc2c6s, tmp8 + psq_st tmp23, 24(out1), 0, 6 + ps_add tmp9, tmp1, tmp6 + ps_msub tmp5, tmp5, cc4, tmp6 + ps_sub tmp22, tmp1, tmp6 + psq_st tmp9, 8(out0), 0, 6 + ps_add tmp8, tmp2, tmp5 + ps_add tmp4, tmp4, tmp5 + psq_st tmp8, 16(out0), 0, 6 + ps_sub tmp9, tmp3, tmp4 + psq_st tmp22, 16(out1), 0, 6 + ps_add tmp20, tmp3, tmp4 + psq_st tmp9, 24(out0), 0, 6 + ps_sub tmp21, tmp2, tmp5 + psq_st tmp20, 0(out1), 0, 6 + psq_st tmp21, 8(out1), 0, 6 + + } + } +} + +void __THPDecompressiMCURow512x448(void) +{ + u8 cl_num; + u32 x_pos; + THPComponent *comp; + + LCQueueWait(3); + + for (cl_num = 0; cl_num < __THPInfo->MCUsPerRow; cl_num++) + { + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[0]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[1]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[2]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[3]); + __THPHuffDecodeDCTCompU(__THPInfo, __THPMCUBuffer[4]); + __THPHuffDecodeDCTCompV(__THPInfo, __THPMCUBuffer[5]); + + comp = &__THPInfo->components[0]; + Gbase = __THPLCWork512[0]; + Gwid = 512; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + x_pos = (u32)(cl_num * 16); + __THPInverseDCTNoYPos(__THPMCUBuffer[0], x_pos); + __THPInverseDCTNoYPos(__THPMCUBuffer[1], x_pos + 8); + __THPInverseDCTY8(__THPMCUBuffer[2], x_pos); + __THPInverseDCTY8(__THPMCUBuffer[3], x_pos + 8); + + comp = &__THPInfo->components[1]; + Gbase = __THPLCWork512[1]; + Gwid = 256; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + x_pos /= 2; + __THPInverseDCTNoYPos(__THPMCUBuffer[4], x_pos); + comp = &__THPInfo->components[2]; + Gbase = __THPLCWork512[2]; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + __THPInverseDCTNoYPos(__THPMCUBuffer[5], x_pos); + + if (__THPInfo->RST != 0) + { + if ((--__THPInfo->currMCU) == 0) + { + __THPInfo->currMCU = __THPInfo->nMCU; + __THPInfo->cnt = 1 + ((__THPInfo->cnt + 6) & 0xFFFFFFF8); + + if (__THPInfo->cnt > 33) + { + __THPInfo->cnt = 33; + } + + __THPInfo->components[0].predDC = 0; + __THPInfo->components[1].predDC = 0; + __THPInfo->components[2].predDC = 0; + } + } + } + + LCStoreData(__THPInfo->dLC[0], __THPLCWork512[0], 0x2000); + LCStoreData(__THPInfo->dLC[1], __THPLCWork512[1], 0x800); + LCStoreData(__THPInfo->dLC[2], __THPLCWork512[2], 0x800); + + __THPInfo->dLC[0] += 0x2000; + __THPInfo->dLC[1] += 0x800; + __THPInfo->dLC[2] += 0x800; +} + +inline s32 __THPHuffDecodeTab(register THPFileInfo *info, register THPHuffmanTab *h) +{ + register s32 code; + register u32 cnt; + register s32 cb; + register u32 increment; + register s32 tmp; + +#define cnt4 code + asm + { + lwz cnt, info->cnt; + addi increment, h, 32; + lwz cb, info->currByte; + addi cnt4, cnt, 4; + cmpwi cnt, 28; + rlwnm tmp, cb, cnt4, 27, 31; + bgt _notEnoughBits; + lbzx code, h, tmp; + lbzx increment, increment, tmp; + cmpwi code, 0xFF; + beq _FailedCheckEnoughBits; + add cnt, cnt, increment; + stw cnt, info->cnt; + } +_done: + return code; + + { + register u32 maxcodebase; + register u32 tmp2; + + _FailedCheckEnoughBits: + maxcodebase = (u32) & (h->maxCode); + cnt += 5; + + asm { + li tmp2, sizeof(s32)*(5); + li code, 5; + add maxcodebase, maxcodebase, tmp2; + __WHILE_START: + cmpwi cnt, 33; + slwi tmp, tmp, 1 + + beq _FCEB_faster; + rlwnm increment, cb, cnt, 31, 31; + lwzu tmp2, 4(maxcodebase); + or tmp, tmp, increment + addi cnt, cnt, 1; + b __WHILE_CHECK; + + _FCEB_faster: + lwz increment, info->c; + li cnt, 1; + lwzu cb, 4(increment); + lwzu tmp2, 4(maxcodebase); + + stw increment, info->c; + rlwimi tmp, cb, 1,31,31; + stw cb, info->currByte; + b __FL_WHILE_CHECK; + + __FL_WHILE_START: + slwi tmp, tmp, 1; + rlwnm increment, cb, cnt, 31, 31; + lwzu tmp2, 4(maxcodebase); + or tmp, tmp, increment; + + __FL_WHILE_CHECK: + cmpw tmp,tmp2 + addi cnt, cnt, 1; + addi code, code, 1 + bgt __FL_WHILE_START; + b _FCEB_Done; + + __WHILE_CHECK: + cmpw tmp,tmp2 + addi code, code, 1 + bgt __WHILE_START; + } + } +_FCEB_Done: + info->cnt = cnt; + return (h->Vij[(s32)(tmp + h->valPtr[code])]); + + asm + { // 6684 + _notEnoughBits: + cmpwi cnt, 33; + lwz tmp, info->c; + beq _getfullword; + + cmpwi cnt, 32; + rlwnm code, cb, cnt4, 27, 31 + beq _1bitleft; + + lbzx tmp, h, code; + lbzx increment, increment, code; + cmpwi tmp, 0xFF; + add code, cnt, increment; + beq _FailedCheckNoBits0; + + cmpwi code, 33; + stw code, info->cnt; + bgt _FailedCheckNoBits1; + } + return tmp; + + asm + { + _1bitleft: + lwzu cb, 4(tmp); + + stw tmp, info->c; + rlwimi code, cb, 4, 28, 31; + lbzx tmp, h, code; + lbzx increment, increment, code + stw cb, info->currByte; + cmpwi tmp, 0xFF + stw increment, info->cnt; + beq _DammitRead4; + + } + return tmp; + +_DammitRead4: +{ + register u32 maxcodebase = (u32) & (h->maxCode); + register u32 tmp2; + + asm + { + li cnt, sizeof(s32)*5; + add maxcodebase, maxcodebase, cnt; + + slwi tmp, code, 32-5; + li cnt,5; + rlwimi tmp, cb, 32-1, 1,31; + + __DR4_WHILE_START: + + subfic cb, cnt, 31; + lwzu tmp2, 4(maxcodebase); + srw code, tmp, cb; + __DR4_WHILE_CHECK: + cmpw code, tmp2 + addi cnt, cnt, 1 + bgt __DR4_WHILE_START; + + } +} + + info->cnt = cnt; +__CODE_PLUS_VP_CNT: + return (h->Vij[(s32)(code + h->valPtr[cnt])]); + +_getfullword: + asm + { + lwzu cb, 4(tmp); + + rlwinm code, cb, 5, 27, 31 + stw tmp, info->c; + lbzx cnt, h, code; + lbzx increment, increment, code; + cmpwi cnt, 0xFF + stw cb, info->currByte; + addi increment, increment, 1 + beq _FailedCheckEnoughbits_Updated; + + stw increment, info->cnt; + } + return (s32)cnt; + +_FailedCheckEnoughbits_Updated: + + cnt = 5; + do + { + asm + { + subfic tmp, cnt, 31; + addi cnt, cnt, 1; + srw code, cb, tmp; + } + } while (code > h->maxCode[cnt]); + + info->cnt = cnt + 1; + goto __CODE_PLUS_VP_CNT; + +#undef cnt4 + +_FailedCheckNoBits0: +_FailedCheckNoBits1: + +{ + register u32 mask = 0xFFFFFFFF << (33 - cnt); + register u32 tmp2; + + code = (s32)(cb & (~mask)); + mask = (u32) & (h->maxCode); + + asm + { + lwz tmp, info->c; + subfic tmp2, cnt, 33; + addi cnt, tmp2, 1; + slwi tmp2, tmp2, 2; + lwzu cb, 4(tmp); + add mask,mask, tmp2; + stw tmp, info->c; + slwi code, code, 1; + stw cb, info->currByte; + rlwimi code, cb, 1, 31, 31; + lwzu tmp2, 4(mask); + li tmp, 2; + b __FCNB1_WHILE_CHECK; + + __FCNB1_WHILE_START: + slwi code, code, 1; + + addi cnt, cnt, 1; + lwzu tmp2, 4(mask); + add code, code, increment; + addi tmp, tmp, 1; + + __FCNB1_WHILE_CHECK: + cmpw code, tmp2; + rlwnm increment, cb, tmp, 31, 31; + bgt __FCNB1_WHILE_START; + + } +} + + info->cnt = (u32)tmp; + return (h->Vij[(s32)(code + h->valPtr[cnt])]); +} + +void __THPDecompressiMCURow640x480(void) +{ + u8 cl_num; + u32 x_pos; + THPComponent *comp; + + LCQueueWait(3); + + { + for (cl_num = 0; cl_num < __THPInfo->MCUsPerRow; cl_num++) + { + THPFileInfo *um = __THPInfo; + __THPHuffDecodeDCTCompY(um, __THPMCUBuffer[0]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[1]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[2]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[3]); + __THPHuffDecodeDCTCompU(__THPInfo, __THPMCUBuffer[4]); + __THPHuffDecodeDCTCompV(__THPInfo, __THPMCUBuffer[5]); + + comp = &__THPInfo->components[0]; + Gbase = __THPLCWork672[0]; + Gwid = 640; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + x_pos = (u32)(cl_num * 16); + __THPInverseDCTNoYPos(__THPMCUBuffer[0], x_pos); + __THPInverseDCTNoYPos(__THPMCUBuffer[1], x_pos + 8); + __THPInverseDCTY8(__THPMCUBuffer[2], x_pos); + __THPInverseDCTY8(__THPMCUBuffer[3], x_pos + 8); + + comp = &__THPInfo->components[1]; + Gbase = __THPLCWork672[1]; + Gwid = 320; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + x_pos /= 2; + __THPInverseDCTNoYPos(__THPMCUBuffer[4], x_pos); + + comp = &__THPInfo->components[2]; + Gbase = __THPLCWork672[2]; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + __THPInverseDCTNoYPos(__THPMCUBuffer[5], x_pos); + + if (__THPInfo->RST != 0) + { + __THPInfo->currMCU--; + if (__THPInfo->currMCU == 0) + { + __THPInfo->currMCU = __THPInfo->nMCU; + + __THPInfo->cnt = 1 + ((__THPInfo->cnt + 6) & 0xFFFFFFF8); + + if (__THPInfo->cnt > 32) + { + __THPInfo->cnt = 33; + } + + __THPInfo->components[0].predDC = 0; + __THPInfo->components[1].predDC = 0; + __THPInfo->components[2].predDC = 0; + } + } + } + } + + LCStoreData(__THPInfo->dLC[0], __THPLCWork672[0], 0x2800); + LCStoreData(__THPInfo->dLC[1], __THPLCWork672[1], 0xA00); + LCStoreData(__THPInfo->dLC[2], __THPLCWork672[2], 0xA00); + + __THPInfo->dLC[0] += 0x2800; + __THPInfo->dLC[1] += 0xA00; + __THPInfo->dLC[2] += 0xA00; +} + +void __THPDecompressiMCURowNxN(void) +{ + u8 cl_num; + u32 x_pos, x; + THPComponent *comp; + + x = __THPInfo->xPixelSize; + + LCQueueWait(3); + + for (cl_num = 0; cl_num < __THPInfo->MCUsPerRow; cl_num++) + { + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[0]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[1]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[2]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[3]); + __THPHuffDecodeDCTCompU(__THPInfo, __THPMCUBuffer[4]); + __THPHuffDecodeDCTCompV(__THPInfo, __THPMCUBuffer[5]); + + comp = &__THPInfo->components[0]; + Gbase = __THPLCWork672[0]; + Gwid = x; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + x_pos = (u32)(cl_num * 16); + __THPInverseDCTNoYPos(__THPMCUBuffer[0], x_pos); + __THPInverseDCTNoYPos(__THPMCUBuffer[1], x_pos + 8); + __THPInverseDCTY8(__THPMCUBuffer[2], x_pos); + __THPInverseDCTY8(__THPMCUBuffer[3], x_pos + 8); + + comp = &__THPInfo->components[1]; + Gbase = __THPLCWork672[1]; + Gwid = x / 2; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + x_pos /= 2; + __THPInverseDCTNoYPos(__THPMCUBuffer[4], x_pos); + + comp = &__THPInfo->components[2]; + Gbase = __THPLCWork672[2]; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + __THPInverseDCTNoYPos(__THPMCUBuffer[5], x_pos); + + if (__THPInfo->RST != 0) + { + __THPInfo->currMCU--; + if (__THPInfo->currMCU == 0) + { + __THPInfo->currMCU = __THPInfo->nMCU; + __THPInfo->cnt = 1 + ((__THPInfo->cnt + 6) & 0xFFFFFFF8); + + if (__THPInfo->cnt > 32) + { + __THPInfo->cnt = 33; + } + + __THPInfo->components[0].predDC = 0; + __THPInfo->components[1].predDC = 0; + __THPInfo->components[2].predDC = 0; + } + } + } + + LCStoreData(__THPInfo->dLC[0], __THPLCWork672[0], ((4 * sizeof(u8) * 64) * (x / 16))); + LCStoreData(__THPInfo->dLC[1], __THPLCWork672[1], ((sizeof(u8) * 64) * (x / 16))); + LCStoreData(__THPInfo->dLC[2], __THPLCWork672[2], ((sizeof(u8) * 64) * (x / 16))); + __THPInfo->dLC[0] += ((4 * sizeof(u8) * 64) * (x / 16)); + __THPInfo->dLC[1] += ((sizeof(u8) * 64) * (x / 16)); + __THPInfo->dLC[2] += ((sizeof(u8) * 64) * (x / 16)); +} + +void __THPHuffDecodeDCTCompY(register THPFileInfo *info, THPCoeff *block) +{ + { + register s32 t; + THPCoeff dc; + register THPCoeff diff; + + __dcbz((void *)block, 0); + t = __THPHuffDecodeTab(info, Ydchuff); + __dcbz((void *)block, 32); + diff = 0; + __dcbz((void *)block, 64); + + if (t) + { + { + register s32 v; + register u32 cb; + register u32 cnt; + register u32 cnt33; + register u32 tmp; + register u32 cnt1; + register u32 tmp1; + asm { + lwz cnt,info->cnt; + subfic cnt33,cnt,33; + lwz cb,info->currByte; + + subfc. tmp, cnt33, t; + subi cnt1,cnt,1; + + bgt _notEnoughBitsDIFF; + add v,cnt,t; + + slw cnt,cb,cnt1; + stw v,info->cnt; + subfic v,t,32; + srw diff,cnt,v; + } + + asm + { + b _DoneDIFF; + _notEnoughBitsDIFF: + lwz tmp1, info->c; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, cnt33; + stw tmp1, info->c; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, t, 32; + srw diff, v, tmp; + _DoneDIFF: + } + } + + if (__cntlzw((u32)diff) > 32 - t) + { + diff += ((0xFFFFFFFF << t) + 1); + } + }; + + __dcbz((void *)block, 96); + dc = (s16)(info->components[0].predDC + diff); + block[0] = info->components[0].predDC = dc; + } + + { + register s32 k; + register s32 code; + register u32 cnt; + register u32 cb; + register u32 increment; + register s32 tmp; + register THPHuffmanTab *h = Yachuff; + +#define cnt4 code + asm + { + lwz cnt, info->cnt; + addi increment, h, 32; + lwz cb, info->currByte; + } + + for (k = 1; k < 64; k++) + { + register s32 ssss; + register s32 rrrr; + + asm { + addi cnt4, cnt, 4; + cmpwi cnt, 28; + rlwnm tmp, cb, cnt4, 27, 31; + bgt _notEnoughBits; + + lbzx ssss, h, tmp; + lbzx code, increment, tmp; + cmpwi ssss, 0xFF; + + beq _FailedCheckEnoughBits; + add cnt, cnt, code; + b _DoneDecodeTab; + } + + { + register u32 maxcodebase; + register u32 tmp2; + + _FailedCheckEnoughBits: + cnt += 5; + maxcodebase = (u32) & (h->maxCode); + asm { + li tmp2, sizeof(s32)*(5); + li code, 5; + add maxcodebase, maxcodebase, tmp2; + __WHILE_START: + cmpwi cnt, 33; + slwi tmp, tmp, 1 + + beq _FCEB_faster; + rlwnm ssss, cb, cnt, 31, 31; + lwzu tmp2, 4(maxcodebase); + or tmp, tmp, ssss + addi cnt, cnt, 1; + b __WHILE_CHECK; + + _FCEB_faster: + lwz ssss, info->c; + li cnt, 1; + lwzu cb, 4(ssss); + + lwzu tmp2, 4(maxcodebase); + + stw ssss, info->c; + rlwimi tmp, cb, 1,31,31; + b __FL_WHILE_CHECK; + + __FL_WHILE_START: + slwi tmp, tmp, 1; + + rlwnm ssss, cb, cnt, 31, 31; + lwzu tmp2, 4(maxcodebase); + or tmp, tmp, ssss; + + __FL_WHILE_CHECK: + cmpw tmp,tmp2 + addi cnt, cnt, 1; + addi code, code, 1 + bgt __FL_WHILE_START; + b _FCEB_Done; + + __WHILE_CHECK: + cmpw tmp,tmp2 + addi code, code, 1 + bgt __WHILE_START; + } + } + _FCEB_Done: + ssss = (h->Vij[(s32)(tmp + h->valPtr[code])]); + goto _DoneDecodeTab; + + _notEnoughBits: + asm + { + cmpwi cnt, 33; + lwz tmp, info->c; + beq _getfullword; + + cmpwi cnt, 32; + rlwnm code, cb, cnt4, 27, 31 + beq _1bitleft; + + lbzx ssss, h, code; + lbzx rrrr, increment, code; + cmpwi ssss, 0xFF; + add code, cnt, rrrr; + beq _FailedCheckNoBits0; + + cmpwi code, 33; + bgt _FailedCheckNoBits1; + } + cnt = (u32)code; + goto _DoneDecodeTab; + + _getfullword: + { + asm + { + lwzu cb, 4(tmp); + rlwinm code, cb, 5, 27, 31 + stw tmp, info->c; + lbzx ssss, h, code; + lbzx tmp, increment, code; + cmpwi ssss, 0xFF + addi cnt, tmp, 1 + beq _FailedCheckEnoughbits_Updated; + } + } + goto _DoneDecodeTab; + + _FailedCheckEnoughbits_Updated: + ssss = 5; + do + { + asm + { + subfic tmp, ssss, 31; + addi ssss, ssss, 1; + srw code, cb, tmp; + } + } while (code > h->maxCode[ssss]); + + cnt = (u32)(ssss + 1); + ssss = (h->Vij[(s32)(code + h->valPtr[ssss])]); + + goto _DoneDecodeTab; + + _1bitleft: + asm { + lwzu cb, 4(tmp); + + stw tmp, info->c; + rlwimi code, cb, 4, 28, 31; + lbzx ssss, h, code; + lbzx cnt, increment, code + cmpwi ssss, 0xFF + beq _DammitRead4; + + } + + goto _DoneDecodeTab; + + _DammitRead4: + { + register u32 maxcodebase = (u32) & (h->maxCode); + register u32 tmp2; + + asm { + li cnt, sizeof(s32)*5; + add maxcodebase, maxcodebase, cnt; + + slwi tmp, code, 32-5; + li cnt,5; + rlwimi tmp, cb, 32-1, 1,31; + + __DR4_WHILE_START: + + subfic ssss, cnt, 31; + lwzu tmp2, 4(maxcodebase); + srw code, tmp, ssss; + __DR4_WHILE_CHECK: + cmpw code, tmp2 + addi cnt, cnt, 1 + bgt __DR4_WHILE_START; + + } + } + ssss = (h->Vij[(s32)(code + h->valPtr[cnt])]); + goto _DoneDecodeTab; + + _FailedCheckNoBits0: + _FailedCheckNoBits1: + _REALFAILEDCHECKNOBITS: + { + register u32 mask = 0xFFFFFFFF << (33 - cnt); + register u32 tmp2; + register u32 tmp3; + code = (s32)(cb & (~mask)); + mask = (u32) & (h->maxCode); + + asm { + lwz tmp, info->c; + subfic tmp2, cnt, 33; + addi tmp3, tmp2, 1; + slwi tmp2, tmp2, 2; + lwzu cb, 4(tmp); + add mask,mask, tmp2; + stw tmp, info->c; + slwi code, code, 1; + rlwimi code, cb, 1, 31, 31; + lwzu tmp2, 4(mask); + li cnt, 2; + b __FCNB1_WHILE_CHECK; + + __FCNB1_WHILE_START: + slwi code, code, 1; + + addi tmp3, tmp3, 1; + lwzu tmp2, 4(mask); + add code, code, rrrr; + addi cnt, cnt, 1; + + __FCNB1_WHILE_CHECK: + cmpw code, tmp2; + rlwnm rrrr, cb, cnt, 31, 31; + bgt __FCNB1_WHILE_START; + + } + ssss = (h->Vij[(s32)(code + h->valPtr[tmp3])]); + } + + goto _DoneDecodeTab; + + _DoneDecodeTab: + asm { + andi. rrrr, ssss, 15; + srawi ssss, ssss, 4; + beq _RECV_SSSS_ZERO; + } + + { + k += ssss; + { + register s32 v; +#define cnt33 code + register u32 cnt1; + register u32 tmp1; + asm + { + subfic cnt33,cnt,33; + subfc. tmp, cnt33, rrrr; + subi cnt1,cnt,1; + bgt _RECVnotEnoughBits; + add cnt,cnt,rrrr; + slw tmp1,cb,cnt1; + subfic v,rrrr,32; + srw ssss,tmp1,v; + } + asm + { + b _RECVDone; + _RECVnotEnoughBits: + lwz tmp1, info->c; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi cnt, tmp, 1; + stw tmp1, info->c; + srw tmp1, cb, cnt33; + + add v, tmp1, v; + subfic tmp, rrrr, 32; + srw ssss, v, tmp; + _RECVDone: + } + } + +#undef cnt33 + + if (__cntlzw((u32)ssss) > 32 - rrrr) + { + ssss += ((0xFFFFFFFF << rrrr) + 1); + } + + block[__THPJpegNaturalOrder[k]] = (s16)ssss; + goto _RECV_END; + } + + { + _RECV_SSSS_ZERO: + if (ssss != 15) + { + break; + } + + k += 15; + }; + + asm + { + _RECV_END: + } + } + info->cnt = cnt; + info->currByte = cb; + } +#undef cnt4 +} + +void __THPHuffDecodeDCTCompU(register THPFileInfo *info, THPCoeff *block) +{ + register s32 t; + register THPCoeff diff; + THPCoeff dc; + register s32 v; + register u32 cb; + register u32 cnt; + register u32 cnt33; + register u32 tmp; + register u32 cnt1; + register u32 tmp1; + register s32 k; + register s32 ssss; + register s32 rrrr; + + __dcbz((void *)block, 0); + t = __THPHuffDecodeTab(info, Udchuff); + __dcbz((void *)block, 32); + diff = 0; + __dcbz((void *)block, 64); + + if (t) + { + asm + { + lwz cnt,info->cnt; + subfic cnt33,cnt,33; + lwz cb,info->currByte; + subfc. tmp, cnt33, t; + subi cnt1,cnt,1; + bgt _notEnoughBitsDIFF; + add v,cnt,t; + slw cnt,cb,cnt1; + stw v,info->cnt; + subfic v,t,32; + srw diff,cnt,v; + } + + asm + { + b _DoneDIFF; + _notEnoughBitsDIFF: + lwz tmp1, info->c; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, cnt33; + stw tmp1, info->c; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, t, 32; + srw diff, v, tmp; + _DoneDIFF: + } + + if (__cntlzw((u32)diff) > 32 - t) + { + diff += ((0xFFFFFFFF << t) + 1); + } + } + + __dcbz((void *)block, 96); + dc = (s16)(info->components[1].predDC + diff); + block[0] = info->components[1].predDC = dc; + + for (k = 1; k < 64; k++) + { + ssss = __THPHuffDecodeTab(info, Uachuff); + rrrr = ssss >> 4; + ssss &= 15; + + if (ssss) + { + k += rrrr; + asm + { + lwz cnt,info->cnt; + subfic cnt33,cnt,33; + lwz cb,info->currByte; + subf. tmp, cnt33, ssss; + subi cnt1,cnt,1; + bgt _notEnoughBits; + add v,cnt,ssss; + slw cnt,cb,cnt1; + stw v,info->cnt; + subfic v,ssss,32; + srw rrrr,cnt,v; + } + + asm + { + b _Done; + _notEnoughBits: + lwz tmp1, info->c; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, cnt33; + stw tmp1, info->c; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, ssss, 32; + srw rrrr, v, tmp; + _Done: + } + + if (__cntlzw((u32)rrrr) > 32 - ssss) + { + rrrr += ((0xFFFFFFFF << ssss) + 1); + } + + block[__THPJpegNaturalOrder[k]] = (s16)rrrr; + } + + else + { + if (rrrr != 15) + break; + k += 15; + } + } +} + +void __THPHuffDecodeDCTCompV(register THPFileInfo *info, THPCoeff *block) +{ + register s32 t; + register THPCoeff diff; + THPCoeff dc; + register s32 v; + register u32 cb; + register u32 cnt; + register u32 cnt33; + register u32 tmp; + register u32 cnt1; + register u32 tmp1; + register s32 k; + register s32 ssss; + register s32 rrrr; + + __dcbz((void *)block, 0); + t = __THPHuffDecodeTab(info, Vdchuff); + __dcbz((void *)block, 32); + diff = 0; + __dcbz((void *)block, 64); + + if (t) + { + asm + { + lwz cnt,info->cnt; + subfic cnt33,cnt,33; + lwz cb,info->currByte; + subf. tmp, cnt33, t; + subi cnt1,cnt,1; + bgt _notEnoughBitsDIFF; + add v,cnt,t; + slw cnt,cb,cnt1; + stw v,info->cnt; + subfic v,t,32; + srw diff,cnt,v; + } + + asm + { + b _DoneDIFF; + _notEnoughBitsDIFF: + lwz tmp1, info->c; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, cnt33; + stw tmp1, info->c; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, t, 32; + srw diff, v, tmp; + _DoneDIFF: + } + + if (__cntlzw((u32)diff) > 32 - t) + { + diff += ((0xFFFFFFFF << t) + 1); + } + } + + __dcbz((void *)block, 96); + + dc = (s16)(info->components[2].predDC + diff); + block[0] = info->components[2].predDC = dc; + + for (k = 1; k < 64; k++) + { + ssss = __THPHuffDecodeTab(info, Vachuff); + rrrr = ssss >> 4; + ssss &= 15; + + if (ssss) + { + k += rrrr; + + asm + { + lwz cnt,info->cnt; + subfic cnt33,cnt,33; + lwz cb,info->currByte; + + subf. tmp, cnt33, ssss; + subi cnt1,cnt,1; + + bgt _notEnoughBits; + add v,cnt,ssss; + + slw cnt,cb,cnt1; + stw v,info->cnt; + subfic v,ssss,32; + srw rrrr,cnt,v; + } + + asm + { + b _Done; + _notEnoughBits: + lwz tmp1, info->c; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, cnt33; + stw tmp1, info->c; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, ssss, 32; + srw rrrr, v, tmp; + _Done: + } + + if (__cntlzw((u32)rrrr) > 32 - ssss) + { + rrrr += ((0xFFFFFFFF << ssss) + 1); + } + + block[__THPJpegNaturalOrder[k]] = (s16)rrrr; + } + else + { + if (rrrr != 15) + break; + k += 15; + } + } +} + +BOOL THPInit(void) +{ + u8 *base; + OSRegisterVersion(__THPVersion); + base = (u8 *)(0xE000 << 16); // lc base + + __THPLCWork512[0] = base; + base += 0x2000; + __THPLCWork512[1] = base; + base += 0x800; + __THPLCWork512[2] = base; + base += 0x200; + + base = (u8 *)(0xE000 << 16); // lc base + __THPLCWork672[0] = base; + base += 0x2800; + __THPLCWork672[1] = base; + base += 0xA00; + __THPLCWork672[2] = base; + base += 0xA80; + + OSInitFastCast(); + + __THPInitFlag = TRUE; + return TRUE; +} \ No newline at end of file diff --git a/libs/dolphin/upnp/UPnP.c b/libs/dolphin/upnp/UPnP.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/upnp/UPnPHttp.c b/libs/dolphin/upnp/UPnPHttp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/upnp/UPnPHttpd.c b/libs/dolphin/upnp/UPnPHttpd.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/upnp/UPnPHttpdResponse.c b/libs/dolphin/upnp/UPnPHttpdResponse.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/upnp/UPnPSsdp.c b/libs/dolphin/upnp/UPnPSsdp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/upnp/UPnPUri.c b/libs/dolphin/upnp/UPnPUri.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/upnp/UPnPUuid.c b/libs/dolphin/upnp/UPnPUuid.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/vi/vi.c b/libs/dolphin/vi/vi.c new file mode 100644 index 000000000..61ed43d58 --- /dev/null +++ b/libs/dolphin/vi/vi.c @@ -0,0 +1,1037 @@ +#include +#include +#include +#include + +#include + +// Useful macros. +#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))) + +const char* __VIVersion = "<< Dolphin SDK - VI\trelease build: Apr 17 2003 12:33:22 (0x2301) >>"; + +static BOOL IsInitialized; +static vu32 retraceCount; +static u32 flushFlag; +static OSThreadQueue retraceQueue; +static VIRetraceCallback PreCB; +static VIRetraceCallback PostCB; +static VIPositionCallback PositionCallback; +static u32 encoderType; + +static s16 displayOffsetH; +static s16 displayOffsetV; + +static vu32 changeMode; +static vu64 changed; + +static vu32 shdwChangeMode; +static vu64 shdwChanged; + +static VITimingInfo* CurrTiming; +static u32 CurrTvMode; + +static u32 NextBufAddr; +static u32 CurrBufAddr; + +static u32 FBSet; + +static vu16 regs[59]; +static vu16 shdwRegs[59]; + +static VIPositionInfo HorVer; +// clang-format off +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, + }, +}; +// clang-format on + +static u16 taps[25] = { 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 }; + +// forward declaring statics +static u32 getCurrentFieldEvenOdd(); + +static void getEncoderType(void) +{ + // UNUSED FUNCTION +} + +static int cntlzd(u64 bit) +{ + u32 hi, lo; + int value; + + hi = (u32)(bit >> 32); + lo = (u32)(bit & 0xFFFFFFFF); + value = __cntlzw(hi); + + if (value < 32) { + return value; + } + + return (32 + __cntlzw(lo)); +} + +static BOOL VISetRegs(void) +{ + int regIndex; + + if (!((shdwChangeMode == 1) && (getCurrentFieldEvenOdd() == 0))) { + while (shdwChanged) { + regIndex = cntlzd(shdwChanged); + __VIRegs[regIndex] = shdwRegs[regIndex]; + shdwChanged &= ~(VI_BITMASK(regIndex)); + } + + shdwChangeMode = 0; + CurrTiming = HorVer.timing; + CurrTvMode = HorVer.tv; + CurrBufAddr = NextBufAddr; + + return TRUE; + } + return FALSE; +} + +static void __VIRetraceHandler(__OSInterrupt interrupt, OSContext* context) +{ + OSContext exceptionContext; + u16 viReg; + u32 inter = 0; + + viReg = __VIRegs[VI_DISP_INT_0]; + if (viReg & 0x8000) { + __VIRegs[VI_DISP_INT_0] = (u16)(viReg & ~0x8000); + inter |= 1; + } + + viReg = __VIRegs[VI_DISP_INT_1]; + if (viReg & 0x8000) { + __VIRegs[VI_DISP_INT_1] = (u16)(viReg & ~0x8000); + inter |= 2; + } + + viReg = __VIRegs[VI_DISP_INT_2]; + if (viReg & 0x8000) { + __VIRegs[VI_DISP_INT_2] = (u16)(viReg & ~0x8000); + inter |= 4; + } + + viReg = __VIRegs[VI_DISP_INT_3]; + if (viReg & 0x8000) { + __VIRegs[VI_DISP_INT_3] = (u16)(viReg & ~0x8000); + inter |= 8; + } + + if ((inter & 4) || (inter & 8)) { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + if (PositionCallback) { + s16 x, y; + __VIGetCurrentPosition(&x, &y); + (*PositionCallback)(x, y); + } + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + return; + } + + retraceCount++; + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + if (PreCB) { + (*PreCB)(retraceCount); + } + + if (flushFlag) { + if (VISetRegs()) { + flushFlag = 0; + SIRefreshSamplingRate(); + } + } + + if (PostCB) { + OSClearContext(&exceptionContext); + (*PostCB)(retraceCount); + } + + OSWakeupThread(&retraceQueue); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback callback) +{ + int interrupt; + VIRetraceCallback oldCallback; + + oldCallback = PreCB; + + interrupt = OSDisableInterrupts(); + PreCB = callback; + OSRestoreInterrupts(interrupt); + + return oldCallback; +} + +VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback callback) +{ + int interrupt; + VIRetraceCallback oldCallback; + + oldCallback = PostCB; + + interrupt = OSDisableInterrupts(); + PostCB = callback; + OSRestoreInterrupts(interrupt); + + return oldCallback; +} + +static VITimingInfo* 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]; + } + + return nullptr; +} + +void __VIInit(VITVMode mode) +{ + VITimingInfo* tm; + u32 nonInter; + vu32 a; + u32 tv, tvForReg; + + u16 hct, vct; + + nonInter = mode & 2; + tv = (u32)mode >> 2; + + *(u32*)OSPhysicalToCached(0xCC) = tv; + + tm = getTiming(mode); + + __VIRegs[VI_DISP_CONFIG] = 2; + for (a = 0; a < 1000; a++) { + ; + } + + __VIRegs[VI_DISP_CONFIG] = 0; + + __VIRegs[VI_HORIZ_TIMING_0U] = tm->hlw << 0; + __VIRegs[VI_HORIZ_TIMING_0L] = (tm->hce << 0) | (tm->hcs << 8); + + __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[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; + + if (mode != VI_TVMODE_NTSC_PROG && mode != VI_TVMODE_NTSC_3D && mode != VI_TVMODE_GCA_PROG) { + __VIRegs[VI_DISP_CONFIG] = (1 << 0) | (0 << 1) | (nonInter << 2) | (0 << 3) | (0 << 4) | (0 << 6) | (tv << 8); + __VIRegs[VI_CLOCK_SEL] = 0; + + } else { + __VIRegs[VI_DISP_CONFIG] = (1 << 0) | (0 << 1) | (1 << 2) | (0 << 3) | (0 << 4) | (0 << 6) | (tv << 8); + __VIRegs[VI_CLOCK_SEL] = 1; + } +} + +static void AdjustPosition(u16 acv) +{ + s32 coeff, frac; + + HorVer.adjDispPosX = (u16)CLAMP(0, 720 - HorVer.dispSizeX, (s16)HorVer.dispPosX + displayOffsetH); + + 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); +} + +static void ImportAdjustingValues(void) +{ + displayOffsetH = __OSLockSram()->displayOffsetH; + displayOffsetV = 0; + __OSUnlockSram(FALSE); +} + +void VIInit(void) +{ + u16 dspCfg; + u32 value, tv, tvInBootrom; + + if (IsInitialized) { + return; + } + + OSRegisterVersion(__VIVersion); + IsInitialized = TRUE; + encoderType = 1; + + if (!(__VIRegs[VI_DISP_CONFIG] & 1)) { + __VIInit(VI_TVMODE_NTSC_INT); + } + + retraceCount = 0; + changed = 0; + shdwChanged = 0; + changeMode = 0; + 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; + ImportAdjustingValues(); + tvInBootrom = *(u32*)OSPhysicalToCached(0xCC); + dspCfg = __VIRegs[VI_DISP_CONFIG]; + + HorVer.nonInter = ((((u32)(dspCfg)) >> 2 & 0x00000001)); + HorVer.tv = ((((u32)(dspCfg)) & 0x00000300) >> 8); + + 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; + + 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; + + AdjustPosition(CurrTiming->acv); + + 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; + + 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; + + PreCB = nullptr; + PostCB = nullptr; + + __OSSetInterruptHandler(24, __VIRetraceHandler); + __OSUnmaskInterrupts((0x80000000u >> (24))); +} + +void VIWaitForRetrace(void) +{ + int interrupt; + u32 startCount; + + interrupt = OSDisableInterrupts(); + startCount = retraceCount; + do { + OSSleepThread(&retraceQueue); + } while (startCount == retraceCount); + OSRestoreInterrupts(interrupt); +} + +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); + + vct++; + hct++; + + 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); +} + +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 setBBIntervalRegs(VITimingInfo* 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 = (u16)((((u32)(tm->bs3))) | (((u32)(tm->be3)) << 5)); + regs[VI_BBI_ODD] = val; + changed |= VI_BITMASK(VI_BBI_ODD); + + val = (u16)((((u32)(tm->bs2))) | (((u32)(tm->be2)) << 5)); + regs[VI_BBI_EVEN_U] = val; + changed |= VI_BITMASK(VI_BBI_EVEN_U); + + val = (u16)((((u32)(tm->bs4))) | (((u32)(tm->be4)) << 5)); + regs[VI_BBI_EVEN] = val; + changed |= VI_BITMASK(VI_BBI_EVEN); +} + +static void setScalingRegs(u16 panSizeX, u16 dispSizeX, BOOL is3D) +{ + u32 scale; + + panSizeX = (u16)(is3D ? panSizeX * 2 : 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); + } else { + regs[VI_HSR] = (u16)((((u32)(256))) | (((u32)(0)) << 12)); + changed |= VI_BITMASK(VI_HSR); + } +} + +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); + + if (dispPosY % 2 == 1) { + u32 tmp = *tfbb; + *tfbb = *bfbb; + *bfbb = tmp; + } + + *tfbb = ToPhysical(*tfbb); + *bfbb = ToPhysical(*bfbb); +} + +static void setFbbRegs(VIPositionInfo* hv, 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); + } + + if (IS_LOWER_16MB(*tfbb) && IS_LOWER_16MB(*bfbb) && IS_LOWER_16MB(*rtfbb) && IS_LOWER_16MB(*rbfbb)) { + shifted = 0; + } else { + shifted = 1; + } + + if (shifted) { + *tfbb >>= 5; + *bfbb >>= 5; + *rtfbb >>= 5; + *rbfbb >>= 5; + } + + regs[VI_TOP_FIELD_BASE_LEFT_U] = (u16)(*tfbb & 0xFFFF); + changed |= VI_BITMASK(VI_TOP_FIELD_BASE_LEFT_U); + + 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); + } +} + +static void setHorizontalRegs(VITimingInfo* tm, u16 dispPosX, u16 dispSizeX) +{ + u32 hbe, hbs, hbeLo, 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); + 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); +} + +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; + + if (regs[VI_CLOCK_SEL] & 1) { + c = 1; + d = 2; + } else { + c = 2; + 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)); + } 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)); + } + + actualAcv = (u16)(dispSizeY / c); + + if (black) { + actualPrbOdd += 2 * actualAcv - 2; + actualPsbOdd += 2; + actualPrbEven += 2 * actualAcv - 2; + actualPsbEven += 2; + 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); +} + +static void PrintDebugPalCaution(void) +{ + static u32 message = 0; + + if (message == 0) { + message = 1; + OSReport("***************************************\n"); + OSReport(" ! ! ! C A U T I O N ! ! ! \n"); + OSReport("This TV format \"DEBUG_PAL\" is only for \n"); + OSReport("temporary solution until PAL DAC board \n"); + OSReport("is available. Please do NOT use this \n"); + OSReport("mode in real games!!! \n"); + OSReport("***************************************\n"); + } +} + +void VIConfigure(const GXRenderModeObj* obj) +{ + VITimingInfo* tm; + u32 regDspCfg; + BOOL enabled; + u32 newNonInter, tvInBootrom, tvInGame; + + enabled = OSDisableInterrupts(); + newNonInter = (u32)obj->viTVmode & 3; + + if (HorVer.nonInter != newNonInter) { + changeMode = 1; + HorVer.nonInter = newNonInter; + } + + tvInGame = (u32)obj->viTVmode >> 2; + tvInBootrom = *(u32*)OSPhysicalToCached(0xCC); + + if (tvInGame == VI_DEBUG_PAL) { + PrintDebugPalCaution(); + } + + switch (tvInBootrom) { + case VI_MPAL: + case VI_NTSC: + case VI_GCA: + if (tvInGame == VI_NTSC || tvInGame == VI_MPAL || tvInGame == VI_GCA) { + break; + } + goto panic; + case VI_PAL: + case VI_EURGB60: + if (tvInGame == VI_PAL || tvInGame == VI_EURGB60) { + break; + } + default: + panic: + OSErrorLine(1908, "VIConfigure(): Tried to change mode from (%d) to (%d), which is forbidden\n", tvInBootrom, tvInGame); + } + // if (((tvInBootrom != VI_PAL && tvInBootrom != VI_EURGB60) && (tvInGame == VI_PAL || tvInGame == VI_EURGB60)) + // || ((tvInBootrom == VI_PAL || tvInBootrom == VI_EURGB60) && (tvInGame != VI_PAL && tvInGame != VI_EURGB60))) { + + // OSErrorLine(1908, "VIConfigure(): Tried to change mode from (%d) to (%d), which is forbidden\n", tvInBootrom, tvInGame); + // } + + if ((tvInGame == VI_NTSC) || (tvInGame == VI_MPAL)) { + HorVer.tv = tvInBootrom; + } else { + HorVer.tv = tvInGame; + } + + HorVer.dispPosX = obj->viXOrigin; + HorVer.dispPosY = (u16)((HorVer.nonInter == VI_NON_INTERLACE) ? (u16)(obj->viYOrigin * 2) : obj->viYOrigin); + HorVer.dispSizeX = obj->viWidth; + HorVer.fbSizeX = obj->fbWidth; + HorVer.fbSizeY = obj->xfbHeight; + HorVer.xfbMode = obj->xFBmode; + HorVer.panSizeX = HorVer.fbSizeX; + HorVer.panSizeY = HorVer.fbSizeY; + HorVer.panPosX = 0; + HorVer.panPosY = 0; + + 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)); + HorVer.timing = tm; + + AdjustPosition(tm->acv); + if (encoderType == 0) { + HorVer.tv = VI_DEBUG; + } + setInterruptRegs(tm); + + regDspCfg = regs[VI_DISP_CONFIG]; + // TODO: USE BIT MACROS OR SOMETHING + if ((HorVer.nonInter == VI_PROGRESSIVE) || (HorVer.nonInter == VI_3D)) { + regDspCfg = (((u32)(regDspCfg)) & ~0x00000004) | (((u32)(1)) << 2); + } else { + regDspCfg = (((u32)(regDspCfg)) & ~0x00000004) | (((u32)(HorVer.nonInter & 1)) << 2); + } + + regDspCfg = (((u32)(regDspCfg)) & ~0x00000008) | (((u32)(HorVer.is3D)) << 3); + + if ((HorVer.tv == VI_DEBUG_PAL) || (HorVer.tv == VI_EURGB60) || (HorVer.tv == VI_GCA)) { + regDspCfg = (((u32)(regDspCfg)) & ~0x00000300); + } else { + regDspCfg = (((u32)(regDspCfg)) & ~0x00000300) | (((u32)(HorVer.tv)) << 8); + } + + regs[VI_DISP_CONFIG] = (u16)regDspCfg; + changed |= VI_BITMASK(0x01); + + regDspCfg = regs[VI_CLOCK_SEL]; + if (obj->viTVmode == VI_TVMODE_NTSC_PROG || obj->viTVmode == VI_TVMODE_NTSC_3D || obj->viTVmode == VI_TVMODE_GCA_PROG) { + regDspCfg = (u32)(regDspCfg & ~0x1) | 1; + } else { + regDspCfg = (u32)(regDspCfg & ~0x1); + } + + regs[VI_CLOCK_SEL] = (u16)regDspCfg; + + changed |= 0x200; + + setScalingRegs(HorVer.panSizeX, HorVer.dispSizeX, HorVer.is3D); + setHorizontalRegs(tm, HorVer.adjDispPosX, HorVer.dispSizeX); + setBBIntervalRegs(tm); + setPicConfig(HorVer.fbSizeX, HorVer.xfbMode, HorVer.panPosX, HorVer.panSizeX, &HorVer.wordPerLine, &HorVer.std, &HorVer.wpl, + &HorVer.xof); + + if (FBSet) { + 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); + OSRestoreInterrupts(enabled); +} + +void VIConfigurePan(u16 panPosX, u16 panPosY, u16 panSizeX, u16 panSizeY) +{ + // UNUSED FUNCTION +} + +void VIFlush(void) +{ + BOOL enabled; + s32 regIndex; + u32 val; // for stack. + + enabled = OSDisableInterrupts(); + shdwChangeMode |= changeMode; + changeMode = 0; + shdwChanged |= changed; + + while (changed) { + regIndex = cntlzd(changed); + shdwRegs[regIndex] = regs[regIndex]; + changed &= ~VI_BITMASK(regIndex); + } + + flushFlag = 1; + NextBufAddr = HorVer.bufAddr; + OSRestoreInterrupts(enabled); +} + +void VISetNextFrameBuffer(void* fb) +{ + BOOL enabled = OSDisableInterrupts(); + HorVer.bufAddr = (u32)fb; + FBSet = 1; + setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); + OSRestoreInterrupts(enabled); +} + +void* VIGetNextFrameBuffer(void) { return (void*)NextBufAddr; } + +void* VIGetCurrentFrameBuffer(void) { return (void*)CurrBufAddr; } + +void VISetNextRightFrameBuffer(void* fb) +{ + // UNUSED FUNCTION +} + +void VISetBlack(BOOL isBlack) +{ + int interrupt; + VITimingInfo* tm; + + 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); +} + +void VISet3D(void) +{ + // UNUSED FUNCTION +} + +u32 VIGetRetraceCount(void) { return retraceCount; } + +static void GetCurrentDisplayPosition(u32* hct, u32* vct) +{ + u32 hcount, vcount0, vcount; + vcount = __VIRegs[VI_VERT_COUNT] & 0x7FF; + + do { + vcount0 = vcount; + hcount = __VIRegs[VI_HORIZ_COUNT] & 0x7FF; + vcount = __VIRegs[VI_VERT_COUNT] & 0x7FF; + } while (vcount0 != vcount); + + *hct = hcount; + *vct = vcount; +} + +static u32 getCurrentHalfLine(void) +{ + u32 hcount, vcount; + GetCurrentDisplayPosition(&hcount, &vcount); + + return ((vcount - 1) << 1) + ((hcount - 1) / CurrTiming->hlw); +} + +static u32 getCurrentFieldEvenOdd() { return (getCurrentHalfLine() < CurrTiming->numHalfLines) ? 1 : 0; } + +u32 VIGetNextField(void) +{ + u32 nextField; + int interrupt; + + interrupt = OSDisableInterrupts(); + nextField = getCurrentFieldEvenOdd() ^ 1; + OSRestoreInterrupts(interrupt); + return nextField ^ (HorVer.adjDispPosY & 1); +} + +u32 VIGetCurrentLine(void) +{ + u32 line; + VITimingInfo* tm; + int interrupt; + + tm = CurrTiming; + interrupt = OSDisableInterrupts(); + line = getCurrentHalfLine(); + OSRestoreInterrupts(interrupt); + + if (line >= tm->numHalfLines) { + line -= tm->numHalfLines; + } + + return (line >> 1); +} + +u32 VIGetTvFormat(void) +{ + u32 fmt; + int interrupt; + + interrupt = OSDisableInterrupts(); + + switch (CurrTvMode) { + case VI_NTSC: + case VI_DEBUG: + case VI_GCA: + fmt = VI_NTSC; + break; + case VI_PAL: + case VI_DEBUG_PAL: + fmt = VI_PAL; + break; + case VI_EURGB60: + case VI_MPAL: + fmt = CurrTvMode; + break; + } + + OSRestoreInterrupts(interrupt); + return fmt; +} + +u32 VIGetDTVStatus(void) +{ + u32 stat; + int interrupt; + + interrupt = OSDisableInterrupts(); + stat = (__VIRegs[VI_DTV_STAT] & 3); + OSRestoreInterrupts(interrupt); + return (stat & 1); +} + +void __VIDisplayPositionToXY(u32 hcount, u32 vcount, s16* x, s16* y) +{ + u32 halfLine = ((vcount - 1) << 1) + ((hcount - 1) / CurrTiming->hlw); + + if (HorVer.nonInter == VI_INTERLACE) { + if (halfLine < CurrTiming->numHalfLines) { + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) { + *y = -1; + } else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbOdd) { + *y = -1; + } else { + *y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd) & ~1); + } + } else { + halfLine -= CurrTiming->numHalfLines; + + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbEven) { + *y = -1; + } else if (halfLine >= CurrTiming->numHalfLines - 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->equ * 3 + CurrTiming->prbOdd) { + *y = -1; + } else if (halfLine >= CurrTiming->numHalfLines - 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->equ * 3 + CurrTiming->prbOdd) { + *y = -1; + } else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbOdd) { + *y = -1; + } else { + *y = (s16)(halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd); + } + } else { + halfLine -= CurrTiming->numHalfLines; + + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbEven) { + *y = -1; + } else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbEven) { + *y = -1; + } else + *y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbEven) & ~1); + } + } + + *x = (s16)(hcount - 1); +} + +void __VIGetCurrentPosition(s16* x, s16* y) +{ + u32 h, v; + GetCurrentDisplayPosition(&h, &v); + __VIDisplayPositionToXY(h, v, x, y); +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Export/mslsupp.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Export/mslsupp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/UDP_Stubs.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/UDP_Stubs.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/targcont.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/targcont.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/target_options.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/target_options.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/usr_put.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/usr_put.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/dispatch.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/dispatch.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/main_TRK.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/main_TRK.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mainloop.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mainloop.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mem_TRK.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mem_TRK.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msg.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msg.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mutex_TRK.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mutex_TRK.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/notify.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/notify.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubevent.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubevent.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubinit.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubinit.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/serpoll.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/serpoll.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/gamedev/cust_connection/cc/exi2/GCN/EXI2_DDH_GCN/main.c b/libs/runtime_libs/gamedev/cust_connection/cc/exi2/GCN/EXI2_DDH_GCN/main.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/gamedev/cust_connection/cc/exi2/GCN/EXI2_GDEV_GCN/main.c b/libs/runtime_libs/gamedev/cust_connection/cc/exi2/GCN/EXI2_GDEV_GCN/main.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/gamedev/cust_connection/utils/common/CircleBuffer.c b/libs/runtime_libs/gamedev/cust_connection/utils/common/CircleBuffer.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/gamedev/cust_connection/utils/common/MWTrace.c b/libs/runtime_libs/gamedev/cust_connection/utils/common/MWTrace.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/gamedev/cust_connection/utils/gc/MWCriticalSection_gc.cpp b/libs/runtime_libs/gamedev/cust_connection/utils/gc/MWCriticalSection_gc.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/SB/Core/gc/iFMV.cpp b/src/SB/Core/gc/iFMV.cpp index 2d348521f..8fd0a89e1 100644 --- a/src/SB/Core/gc/iFMV.cpp +++ b/src/SB/Core/gc/iFMV.cpp @@ -8,6 +8,7 @@ #include "xFile.h" #include "xPar.h" +#include "gx.h" #include "zGlobals.h" diff --git a/src/SB/Core/gc/iFMV.h b/src/SB/Core/gc/iFMV.h index 3c49fed20..57b28f7f3 100644 --- a/src/SB/Core/gc/iFMV.h +++ b/src/SB/Core/gc/iFMV.h @@ -3,7 +3,7 @@ #include #include -#include +#include #ifdef __cplusplus diff --git a/src/SB/Core/gc/iMath.cpp b/src/SB/Core/gc/iMath.cpp index 35f6ff623..286d856ec 100644 --- a/src/SB/Core/gc/iMath.cpp +++ b/src/SB/Core/gc/iMath.cpp @@ -1,6 +1,6 @@ #include "iMath.h" -#include +#include F32 isin(F32 x) { diff --git a/src/SB/Core/gc/iMemMgr.cpp b/src/SB/Core/gc/iMemMgr.cpp index ec7aaf201..7772094ba 100644 --- a/src/SB/Core/gc/iMemMgr.cpp +++ b/src/SB/Core/gc/iMemMgr.cpp @@ -3,7 +3,7 @@ #include "xMemMgr.h" #include -#include +#include #include U32 mem_top_alloc; diff --git a/src/SB/Core/gc/iMix.c b/src/SB/Core/gc/iMix.c index e1fba9861..a08f0f46e 100644 --- a/src/SB/Core/gc/iMix.c +++ b/src/SB/Core/gc/iMix.c @@ -6,358 +6,135 @@ static unsigned int __MIXSoundMode; static int __MIXDvdStreamAttenUser; static int __MIXDvdStreamAttenCurrent; -unsigned short __MIXVolumeTable[] = -{ - 0x0, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, - 0x2, 0x3, 0x3, 0x3, - 0x3, 0x3, 0x3, 0x3, - 0x3, 0x3, 0x3, 0x3, - 0x3, 0x3, 0x3, 0x3, - 0x3, 0x3, 0x3, 0x3, - 0x3, 0x3, 0x3, 0x3, - 0x3, 0x3, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, - 0x4, 0x5, 0x5, 0x5, - 0x5, 0x5, 0x5, 0x5, - 0x5, 0x5, 0x5, 0x5, - 0x5, 0x5, 0x5, 0x5, - 0x5, 0x6, 0x6, 0x6, - 0x6, 0x6, 0x6, 0x6, - 0x6, 0x6, 0x6, 0x6, - 0x6, 0x6, 0x7, 0x7, - 0x7, 0x7, 0x7, 0x7, - 0x7, 0x7, 0x7, 0x7, - 0x7, 0x7, 0x8, 0x8, - 0x8, 0x8, 0x8, 0x8, - 0x8, 0x8, 0x8, 0x8, - 0x9, 0x9, 0x9, 0x9, - 0x9, 0x9, 0x9, 0x9, - 0x9, 0xA, 0xA, 0xA, - 0xA, 0xA, 0xA, 0xA, - 0xA, 0xA, 0xB, 0xB, - 0xB, 0xB, 0xB, 0xB, - 0xB, 0xC, 0xC, 0xC, - 0xC, 0xC, 0xC, 0xC, - 0xD, 0xD, 0xD, 0xD, - 0xD, 0xD, 0xD, 0xE, - 0xE, 0xE, 0xE, 0xE, - 0xE, 0xF, 0xF, 0xF, - 0xF, 0xF, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x11, - 0x11, 0x11, 0x11, 0x11, - 0x12, 0x12, 0x12, 0x12, - 0x12, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x14, 0x14, - 0x14, 0x14, 0x15, 0x15, - 0x15, 0x15, 0x16, 0x16, - 0x16, 0x16, 0x17, 0x17, - 0x17, 0x18, 0x18, 0x18, - 0x18, 0x19, 0x19, 0x19, - 0x1A, 0x1A, 0x1A, 0x1A, - 0x1B, 0x1B, 0x1B, 0x1C, - 0x1C, 0x1C, 0x1D, 0x1D, - 0x1D, 0x1E, 0x1E, 0x1E, - 0x1F, 0x1F, 0x20, 0x20, - 0x20, 0x21, 0x21, 0x21, - 0x22, 0x22, 0x23, 0x23, - 0x23, 0x24, 0x24, 0x25, - 0x25, 0x26, 0x26, 0x26, - 0x27, 0x27, 0x28, 0x28, - 0x29, 0x29, 0x2A, 0x2A, - 0x2B, 0x2B, 0x2C, 0x2C, - 0x2D, 0x2D, 0x2E, 0x2E, - 0x2F, 0x2F, 0x30, 0x31, - 0x31, 0x32, 0x32, 0x33, - 0x33, 0x34, 0x35, 0x35, - 0x36, 0x37, 0x37, 0x38, - 0x38, 0x39, 0x3A, 0x3A, - 0x3B, 0x3C, 0x3D, 0x3D, - 0x3E, 0x3F, 0x3F, 0x40, - 0x41, 0x42, 0x42, 0x43, - 0x44, 0x45, 0x46, 0x46, - 0x47, 0x48, 0x49, 0x4A, - 0x4B, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, - 0x52, 0x53, 0x54, 0x55, - 0x56, 0x57, 0x58, 0x59, - 0x5A, 0x5B, 0x5C, 0x5D, - 0x5E, 0x5F, 0x60, 0x61, - 0x62, 0x64, 0x65, 0x66, - 0x67, 0x68, 0x6A, 0x6B, - 0x6C, 0x6D, 0x6F, 0x70, - 0x71, 0x72, 0x74, 0x75, - 0x76, 0x78, 0x79, 0x7B, - 0x7C, 0x7E, 0x7F, 0x80, - 0x82, 0x83, 0x85, 0x87, - 0x88, 0x8A, 0x8B, 0x8D, - 0x8F, 0x90, 0x92, 0x94, - 0x95, 0x97, 0x99, 0x9B, - 0x9C, 0x9E, 0xA0, 0xA2, - 0xA4, 0xA6, 0xA8, 0xAA, - 0xAB, 0xAD, 0xAF, 0xB2, - 0xB4, 0xB6, 0xB8, 0xBA, - 0xBC, 0xBE, 0xC0, 0xC3, - 0xC5, 0xC7, 0xCA, 0xCC, - 0xCE, 0xD1, 0xD3, 0xD6, - 0xD8, 0xDB, 0xDD, 0xE0, - 0xE2, 0xE5, 0xE7, 0xEA, - 0xED, 0xF0, 0xF2, 0xF5, - 0xF8, 0xFB, 0xFE, 0x101, - 0x104, 0x107, 0x10A, 0x10D, - 0x110, 0x113, 0x116, 0x11A, - 0x11D, 0x120, 0x124, 0x127, - 0x12A, 0x12E, 0x131, 0x135, - 0x138, 0x13C, 0x140, 0x143, - 0x147, 0x14B, 0x14F, 0x153, - 0x157, 0x15B, 0x15F, 0x163, - 0x167, 0x16B, 0x16F, 0x173, - 0x178, 0x17C, 0x180, 0x185, - 0x189, 0x18E, 0x193, 0x197, - 0x19C, 0x1A1, 0x1A6, 0x1AB, - 0x1AF, 0x1B4, 0x1BA, 0x1BF, - 0x1C4, 0x1C9, 0x1CE, 0x1D4, - 0x1D9, 0x1DF, 0x1E4, 0x1EA, - 0x1EF, 0x1F5, 0x1FB, 0x201, - 0x207, 0x20D, 0x213, 0x219, - 0x21F, 0x226, 0x22C, 0x232, - 0x239, 0x240, 0x246, 0x24D, - 0x254, 0x25B, 0x262, 0x269, - 0x270, 0x277, 0x27E, 0x286, - 0x28D, 0x295, 0x29D, 0x2A4, - 0x2AC, 0x2B4, 0x2BC, 0x2C4, - 0x2CC, 0x2D5, 0x2DD, 0x2E6, - 0x2EE, 0x2F7, 0x300, 0x309, - 0x312, 0x31B, 0x324, 0x32D, - 0x337, 0x340, 0x34A, 0x354, - 0x35D, 0x367, 0x371, 0x37C, - 0x386, 0x390, 0x39B, 0x3A6, - 0x3B1, 0x3BB, 0x3C7, 0x3D2, - 0x3DD, 0x3E9, 0x3F4, 0x400, - 0x40C, 0x418, 0x424, 0x430, - 0x43D, 0x449, 0x456, 0x463, - 0x470, 0x47D, 0x48A, 0x498, - 0x4A5, 0x4B3, 0x4C1, 0x4CF, - 0x4DD, 0x4EC, 0x4FA, 0x509, - 0x518, 0x527, 0x536, 0x546, - 0x555, 0x565, 0x575, 0x586, - 0x596, 0x5A6, 0x5B7, 0x5C8, - 0x5D9, 0x5EB, 0x5FC, 0x60E, - 0x620, 0x632, 0x644, 0x657, - 0x66A, 0x67D, 0x690, 0x6A4, - 0x6B7, 0x6CB, 0x6DF, 0x6F4, - 0x708, 0x71D, 0x732, 0x748, - 0x75D, 0x773, 0x789, 0x79F, - 0x7B6, 0x7CD, 0x7E4, 0x7FB, - 0x813, 0x82B, 0x843, 0x85C, - 0x874, 0x88E, 0x8A7, 0x8C1, - 0x8DA, 0x8F5, 0x90F, 0x92A, - 0x945, 0x961, 0x97D, 0x999, - 0x9B5, 0x9D2, 0x9EF, 0xA0D, - 0xA2A, 0xA48, 0xA67, 0xA86, - 0xAA5, 0xAC5, 0xAE5, 0xB05, - 0xB25, 0xB47, 0xB68, 0xB8A, - 0xBAC, 0xBCF, 0xBF2, 0xC15, - 0xC39, 0xC5D, 0xC82, 0xCA7, - 0xCCC, 0xCF2, 0xD19, 0xD3F, - 0xD67, 0xD8E, 0xDB7, 0xDDF, - 0xE08, 0xE32, 0xE5C, 0xE87, - 0xEB2, 0xEDD, 0xF09, 0xF36, - 0xF63, 0xF91, 0xFBF, 0xFEE, - 0x101D, 0x104D, 0x107D, 0x10AE, - 0x10DF, 0x1111, 0x1144, 0x1177, - 0x11AB, 0x11DF, 0x1214, 0x124A, - 0x1280, 0x12B7, 0x12EE, 0x1326, - 0x135F, 0x1399, 0x13D3, 0x140D, - 0x1449, 0x1485, 0x14C2, 0x14FF, - 0x153E, 0x157D, 0x15BC, 0x15FD, - 0x163E, 0x1680, 0x16C3, 0x1706, - 0x174A, 0x178F, 0x17D5, 0x181C, - 0x1863, 0x18AC, 0x18F5, 0x193F, - 0x198A, 0x19D5, 0x1A22, 0x1A6F, - 0x1ABE, 0x1B0D, 0x1B5D, 0x1BAE, - 0x1C00, 0x1C53, 0x1CA7, 0x1CFC, - 0x1D52, 0x1DA9, 0x1E01, 0x1E5A, - 0x1EB4, 0x1F0F, 0x1F6B, 0x1FC8, - 0x2026, 0x2086, 0x20E6, 0x2148, - 0x21AA, 0x220E, 0x2273, 0x22D9, - 0x2341, 0x23A9, 0x2413, 0x247E, - 0x24EA, 0x2557, 0x25C6, 0x2636, - 0x26A7, 0x271A, 0x278E, 0x2803, - 0x287A, 0x28F2, 0x296B, 0x29E6, - 0x2A62, 0x2AE0, 0x2B5F, 0x2BDF, - 0x2C61, 0x2CE5, 0x2D6A, 0x2DF1, - 0x2E79, 0x2F03, 0x2F8E, 0x301B, - 0x30AA, 0x313A, 0x31CC, 0x325F, - 0x32F5, 0x338C, 0x3425, 0x34BF, - 0x355B, 0x35FA, 0x369A, 0x373C, - 0x37DF, 0x3885, 0x392C, 0x39D6, - 0x3A81, 0x3B2F, 0x3BDE, 0x3C90, - 0x3D43, 0x3DF9, 0x3EB1, 0x3F6A, - 0x4026, 0x40E5, 0x41A5, 0x4268, - 0x432C, 0x43F4, 0x44BD, 0x4589, - 0x4657, 0x4727, 0x47FA, 0x48D0, - 0x49A8, 0x4A82, 0x4B5F, 0x4C3E, - 0x4D20, 0x4E05, 0x4EEC, 0x4FD6, - 0x50C3, 0x51B2, 0x52A4, 0x5399, - 0x5491, 0x558C, 0x5689, 0x578A, - 0x588D, 0x5994, 0x5A9D, 0x5BAA, - 0x5CBA, 0x5DCD, 0x5EE3, 0x5FFC, - 0x6119, 0x6238, 0x635C, 0x6482, - 0x65AC, 0x66D9, 0x680A, 0x693F, - 0x6A77, 0x6BB2, 0x6CF2, 0x6E35, - 0x6F7B, 0x70C6, 0x7214, 0x7366, - 0x74BC, 0x7616, 0x7774, 0x78D6, - 0x7A3D, 0x7BA7, 0x7D16, 0x7E88, - 0x7FFF, 0x817B, 0x82FB, 0x847F, - 0x8608, 0x8795, 0x8927, 0x8ABE, - 0x8C59, 0x8DF9, 0x8F9E, 0x9148, - 0x92F6, 0x94AA, 0x9663, 0x9820, - 0x99E3, 0x9BAB, 0x9D79, 0x9F4C, - 0xA124, 0xA302, 0xA4E5, 0xA6CE, - 0xA8BC, 0xAAB0, 0xACAA, 0xAEAA, - 0xB0B0, 0xB2BC, 0xB4CE, 0xB6E5, - 0xB904, 0xBB28, 0xBD53, 0xBF84, - 0xC1BC, 0xC3FA, 0xC63F, 0xC88B, - 0xCADD, 0xCD37, 0xCF97, 0xD1FE, - 0xD46D, 0xD6E3, 0xD960, 0xDBE4, - 0xDE70, 0xE103, 0xE39E, 0xE641, - 0xE8EB, 0xEB9E, 0xEE58, 0xF11B, - 0xF3E6, 0xF6B9, 0xF994, 0xFC78, - 0xFF64 +unsigned short __MIXVolumeTable[] = { + 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, + 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, + 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, + 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, + 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, + 0x5, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, + 0x6, 0x6, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, + 0x7, 0x7, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0xA, 0xA, 0xA, + 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, + 0xB, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xD, 0xD, 0xD, 0xD, + 0xD, 0xD, 0xD, 0xE, 0xE, 0xE, 0xE, 0xE, 0xE, 0xF, 0xF, 0xF, + 0xF, 0xF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, + 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, + 0x17, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1B, 0x1B, 0x1B, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1D, 0x1E, 0x1E, 0x1E, + 0x1F, 0x1F, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, + 0x23, 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, + 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B, 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, + 0x2F, 0x2F, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x35, 0x35, + 0x36, 0x37, 0x37, 0x38, 0x38, 0x39, 0x3A, 0x3A, 0x3B, 0x3C, 0x3D, 0x3D, + 0x3E, 0x3F, 0x3F, 0x40, 0x41, 0x42, 0x42, 0x43, 0x44, 0x45, 0x46, 0x46, + 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, + 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, + 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x64, 0x65, 0x66, 0x67, 0x68, 0x6A, 0x6B, + 0x6C, 0x6D, 0x6F, 0x70, 0x71, 0x72, 0x74, 0x75, 0x76, 0x78, 0x79, 0x7B, + 0x7C, 0x7E, 0x7F, 0x80, 0x82, 0x83, 0x85, 0x87, 0x88, 0x8A, 0x8B, 0x8D, + 0x8F, 0x90, 0x92, 0x94, 0x95, 0x97, 0x99, 0x9B, 0x9C, 0x9E, 0xA0, 0xA2, + 0xA4, 0xA6, 0xA8, 0xAA, 0xAB, 0xAD, 0xAF, 0xB2, 0xB4, 0xB6, 0xB8, 0xBA, + 0xBC, 0xBE, 0xC0, 0xC3, 0xC5, 0xC7, 0xCA, 0xCC, 0xCE, 0xD1, 0xD3, 0xD6, + 0xD8, 0xDB, 0xDD, 0xE0, 0xE2, 0xE5, 0xE7, 0xEA, 0xED, 0xF0, 0xF2, 0xF5, + 0xF8, 0xFB, 0xFE, 0x101, 0x104, 0x107, 0x10A, 0x10D, 0x110, 0x113, 0x116, 0x11A, + 0x11D, 0x120, 0x124, 0x127, 0x12A, 0x12E, 0x131, 0x135, 0x138, 0x13C, 0x140, 0x143, + 0x147, 0x14B, 0x14F, 0x153, 0x157, 0x15B, 0x15F, 0x163, 0x167, 0x16B, 0x16F, 0x173, + 0x178, 0x17C, 0x180, 0x185, 0x189, 0x18E, 0x193, 0x197, 0x19C, 0x1A1, 0x1A6, 0x1AB, + 0x1AF, 0x1B4, 0x1BA, 0x1BF, 0x1C4, 0x1C9, 0x1CE, 0x1D4, 0x1D9, 0x1DF, 0x1E4, 0x1EA, + 0x1EF, 0x1F5, 0x1FB, 0x201, 0x207, 0x20D, 0x213, 0x219, 0x21F, 0x226, 0x22C, 0x232, + 0x239, 0x240, 0x246, 0x24D, 0x254, 0x25B, 0x262, 0x269, 0x270, 0x277, 0x27E, 0x286, + 0x28D, 0x295, 0x29D, 0x2A4, 0x2AC, 0x2B4, 0x2BC, 0x2C4, 0x2CC, 0x2D5, 0x2DD, 0x2E6, + 0x2EE, 0x2F7, 0x300, 0x309, 0x312, 0x31B, 0x324, 0x32D, 0x337, 0x340, 0x34A, 0x354, + 0x35D, 0x367, 0x371, 0x37C, 0x386, 0x390, 0x39B, 0x3A6, 0x3B1, 0x3BB, 0x3C7, 0x3D2, + 0x3DD, 0x3E9, 0x3F4, 0x400, 0x40C, 0x418, 0x424, 0x430, 0x43D, 0x449, 0x456, 0x463, + 0x470, 0x47D, 0x48A, 0x498, 0x4A5, 0x4B3, 0x4C1, 0x4CF, 0x4DD, 0x4EC, 0x4FA, 0x509, + 0x518, 0x527, 0x536, 0x546, 0x555, 0x565, 0x575, 0x586, 0x596, 0x5A6, 0x5B7, 0x5C8, + 0x5D9, 0x5EB, 0x5FC, 0x60E, 0x620, 0x632, 0x644, 0x657, 0x66A, 0x67D, 0x690, 0x6A4, + 0x6B7, 0x6CB, 0x6DF, 0x6F4, 0x708, 0x71D, 0x732, 0x748, 0x75D, 0x773, 0x789, 0x79F, + 0x7B6, 0x7CD, 0x7E4, 0x7FB, 0x813, 0x82B, 0x843, 0x85C, 0x874, 0x88E, 0x8A7, 0x8C1, + 0x8DA, 0x8F5, 0x90F, 0x92A, 0x945, 0x961, 0x97D, 0x999, 0x9B5, 0x9D2, 0x9EF, 0xA0D, + 0xA2A, 0xA48, 0xA67, 0xA86, 0xAA5, 0xAC5, 0xAE5, 0xB05, 0xB25, 0xB47, 0xB68, 0xB8A, + 0xBAC, 0xBCF, 0xBF2, 0xC15, 0xC39, 0xC5D, 0xC82, 0xCA7, 0xCCC, 0xCF2, 0xD19, 0xD3F, + 0xD67, 0xD8E, 0xDB7, 0xDDF, 0xE08, 0xE32, 0xE5C, 0xE87, 0xEB2, 0xEDD, 0xF09, 0xF36, + 0xF63, 0xF91, 0xFBF, 0xFEE, 0x101D, 0x104D, 0x107D, 0x10AE, 0x10DF, 0x1111, 0x1144, 0x1177, + 0x11AB, 0x11DF, 0x1214, 0x124A, 0x1280, 0x12B7, 0x12EE, 0x1326, 0x135F, 0x1399, 0x13D3, 0x140D, + 0x1449, 0x1485, 0x14C2, 0x14FF, 0x153E, 0x157D, 0x15BC, 0x15FD, 0x163E, 0x1680, 0x16C3, 0x1706, + 0x174A, 0x178F, 0x17D5, 0x181C, 0x1863, 0x18AC, 0x18F5, 0x193F, 0x198A, 0x19D5, 0x1A22, 0x1A6F, + 0x1ABE, 0x1B0D, 0x1B5D, 0x1BAE, 0x1C00, 0x1C53, 0x1CA7, 0x1CFC, 0x1D52, 0x1DA9, 0x1E01, 0x1E5A, + 0x1EB4, 0x1F0F, 0x1F6B, 0x1FC8, 0x2026, 0x2086, 0x20E6, 0x2148, 0x21AA, 0x220E, 0x2273, 0x22D9, + 0x2341, 0x23A9, 0x2413, 0x247E, 0x24EA, 0x2557, 0x25C6, 0x2636, 0x26A7, 0x271A, 0x278E, 0x2803, + 0x287A, 0x28F2, 0x296B, 0x29E6, 0x2A62, 0x2AE0, 0x2B5F, 0x2BDF, 0x2C61, 0x2CE5, 0x2D6A, 0x2DF1, + 0x2E79, 0x2F03, 0x2F8E, 0x301B, 0x30AA, 0x313A, 0x31CC, 0x325F, 0x32F5, 0x338C, 0x3425, 0x34BF, + 0x355B, 0x35FA, 0x369A, 0x373C, 0x37DF, 0x3885, 0x392C, 0x39D6, 0x3A81, 0x3B2F, 0x3BDE, 0x3C90, + 0x3D43, 0x3DF9, 0x3EB1, 0x3F6A, 0x4026, 0x40E5, 0x41A5, 0x4268, 0x432C, 0x43F4, 0x44BD, 0x4589, + 0x4657, 0x4727, 0x47FA, 0x48D0, 0x49A8, 0x4A82, 0x4B5F, 0x4C3E, 0x4D20, 0x4E05, 0x4EEC, 0x4FD6, + 0x50C3, 0x51B2, 0x52A4, 0x5399, 0x5491, 0x558C, 0x5689, 0x578A, 0x588D, 0x5994, 0x5A9D, 0x5BAA, + 0x5CBA, 0x5DCD, 0x5EE3, 0x5FFC, 0x6119, 0x6238, 0x635C, 0x6482, 0x65AC, 0x66D9, 0x680A, 0x693F, + 0x6A77, 0x6BB2, 0x6CF2, 0x6E35, 0x6F7B, 0x70C6, 0x7214, 0x7366, 0x74BC, 0x7616, 0x7774, 0x78D6, + 0x7A3D, 0x7BA7, 0x7D16, 0x7E88, 0x7FFF, 0x817B, 0x82FB, 0x847F, 0x8608, 0x8795, 0x8927, 0x8ABE, + 0x8C59, 0x8DF9, 0x8F9E, 0x9148, 0x92F6, 0x94AA, 0x9663, 0x9820, 0x99E3, 0x9BAB, 0x9D79, 0x9F4C, + 0xA124, 0xA302, 0xA4E5, 0xA6CE, 0xA8BC, 0xAAB0, 0xACAA, 0xAEAA, 0xB0B0, 0xB2BC, 0xB4CE, 0xB6E5, + 0xB904, 0xBB28, 0xBD53, 0xBF84, 0xC1BC, 0xC3FA, 0xC63F, 0xC88B, 0xCADD, 0xCD37, 0xCF97, 0xD1FE, + 0xD46D, 0xD6E3, 0xD960, 0xDBE4, 0xDE70, 0xE103, 0xE39E, 0xE641, 0xE8EB, 0xEB9E, 0xEE58, 0xF11B, + 0xF3E6, 0xF6B9, 0xF994, 0xFC78, 0xFF64 }; -int __MIXPanTable[] = -{ - 0x0, 0x0, 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 +int __MIXPanTable[] = { + 0x0, 0x0, 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 }; -short __MIX_DPL2_front[] = -{ - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 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 +short __MIX_DPL2_front[] = { + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 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 }; -short __MIX_DPL2_rear[] = -{ - 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 +short __MIX_DPL2_rear[] = { + 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 }; static int __MIXGetVolume(int param_1) @@ -373,18 +150,18 @@ static int __MIXGetVolume(int param_1) return __MIXVolumeTable[param_1 + 0x388]; } -static int __MIXSetPan(struct MIXChannel *param_1) +static int __MIXSetPan(struct MIXChannel* param_1) { - int iVar1 = *(int *)((int)param_1 + 0x14); - int iVar3 = *(int *)((int)param_1 + 0x18); + int iVar1 = *(int*)((int)param_1 + 0x14); + int iVar3 = *(int*)((int)param_1 + 0x18); int iVar2 = 0x7f - iVar1; int iVar4 = 0x7f - iVar3; if (__MIXSoundMode == 3) { - param_1->data[8] = __MIX_DPL2_front[iVar1]; - param_1->data[9] = __MIX_DPL2_front[iVar2]; + param_1->data[8] = __MIX_DPL2_front[iVar1]; + param_1->data[9] = __MIX_DPL2_front[iVar2]; param_1->data[10] = __MIX_DPL2_front[iVar4]; param_1->data[11] = __MIX_DPL2_front[iVar3]; param_1->data[12] = __MIX_DPL2_rear[iVar2]; @@ -392,14 +169,15 @@ static int __MIXSetPan(struct MIXChannel *param_1) } else { - param_1->data[8] = __MIXPanTable[iVar1]; - param_1->data[9] = __MIXPanTable[iVar2]; + param_1->data[8] = __MIXPanTable[iVar1]; + param_1->data[9] = __MIXPanTable[iVar2]; param_1->data[10] = __MIXPanTable[iVar4]; param_1->data[11] = __MIXPanTable[iVar3]; } + return 0; } -static void __MIXResetChannel(struct MIXChannel *param_1) +static void __MIXResetChannel(struct MIXChannel* param_1) { param_1->data[1] = 0x50000000; param_1->data[2] = 0; @@ -443,17 +221,18 @@ void MIXInit() int iVar1 = 0; do { - __MIXResetChannel((struct MIXChannel *)&__MIXChannel[iVar1]); + __MIXResetChannel((struct MIXChannel*)&__MIXChannel[iVar1]); iVar1++; } while (iVar1 < 0x40); __MIXDvdStreamAttenCurrent = 0; __MIXDvdStreamAttenUser = 0; - __MIXSoundMode = OSGetSoundMode(); + //__MIXSoundMode = OSGetSoundMode(); } -void MIXInitChannel(int param_1, unsigned int param_2, int param_3, int param_4, int param_5, int param_6, int param_7, int param_8) +void MIXInitChannel(int param_1, unsigned int param_2, int param_3, int param_4, int param_5, + int param_6, int param_7, int param_8) { - struct MIXChannel* chan = &__MIXChannel[*(int *)((int)param_1 + 0x18)]; + struct MIXChannel* chan = &__MIXChannel[*(int*)((int)param_1 + 0x18)]; short sVar1; unsigned short uVar2; @@ -468,173 +247,201 @@ void MIXInitChannel(int param_1, unsigned int param_2, int param_3, int param_4, chan->data[6] = param_7; chan->data[7] = param_8; - __MIXSetPan( chan); + __MIXSetPan(chan); - if ( (chan->data[1] & 4)) + if ((chan->data[1] & 4)) { - *(unsigned short *)( &chan->data[0xe]) = 0; + *(unsigned short*)(&chan->data[0xe]) = 0; } else { - *(unsigned short *)( &chan->data[0xe]) = __MIXGetVolume(param_3); + *(unsigned short*)(&chan->data[0xe]) = __MIXGetVolume(param_3); } - uVar4 = 0; switch ((int)__MIXSoundMode) { - case 0: - *(unsigned short *)(&chan->data[0xf]) = __MIXGetVolume(chan->data[7]+ chan->data[10]); - *(unsigned short *)(&chan->data[0x10]) = __MIXGetVolume(chan->data[7] + chan->data[10]); - *(unsigned short *)(&chan->data[0x11]) = __MIXGetVolume(chan->data[7] + chan->data[11]); + case 0: + *(unsigned short*)(&chan->data[0xf]) = __MIXGetVolume(chan->data[7] + chan->data[10]); + *(unsigned short*)(&chan->data[0x10]) = __MIXGetVolume(chan->data[7] + chan->data[10]); + *(unsigned short*)(&chan->data[0x11]) = __MIXGetVolume(chan->data[7] + chan->data[11]); if ((chan->data[1] & 1U) != 0) { - *(unsigned short *)(&chan->data[0x12]) = __MIXGetVolume(chan->data[3] + chan->data[10] ); - *(unsigned short *)(&chan->data[0x13]) = __MIXGetVolume(chan->data[3] + chan->data[10] ); - *(unsigned short *)(&chan->data[0x14]) = __MIXGetVolume(chan->data[3] + chan->data[11] - 0x3c); + *(unsigned short*)(&chan->data[0x12]) = __MIXGetVolume(chan->data[3] + chan->data[10]); + *(unsigned short*)(&chan->data[0x13]) = __MIXGetVolume(chan->data[3] + chan->data[10]); + *(unsigned short*)(&chan->data[0x14]) = + __MIXGetVolume(chan->data[3] + chan->data[11] - 0x3c); } else { - *(unsigned short *)(&chan->data[0x12]) = __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[10]); - *(unsigned short *)(&chan->data[0x13]) = __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[10] ); - *(unsigned short *)(&chan->data[0x14]) = __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[11] - 0x3c); - + *(unsigned short*)(&chan->data[0x12]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[10]); + *(unsigned short*)(&chan->data[0x13]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[10]); + *(unsigned short*)(&chan->data[0x14]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[11] - 0x3c); } if (chan->data[1] & 2) { - - *(unsigned short *)(&chan->data[0x15]) = __MIXGetVolume(chan->data[4] + chan->data[10]); - *(unsigned short *)(&chan->data[0x16]) = __MIXGetVolume(chan->data[4] + chan->data[10]); - *(unsigned short *)(&chan->data[0x17]) = __MIXGetVolume(chan->data[4] + chan->data[11] - 0x3c); + *(unsigned short*)(&chan->data[0x15]) = __MIXGetVolume(chan->data[4] + chan->data[10]); + *(unsigned short*)(&chan->data[0x16]) = __MIXGetVolume(chan->data[4] + chan->data[10]); + *(unsigned short*)(&chan->data[0x17]) = + __MIXGetVolume(chan->data[4] + chan->data[11] - 0x3c); } else { - *(unsigned short *)(&chan->data[0x15]) = __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[10]); - *(unsigned short *)(&chan->data[0x16]) = __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[10]); - *(unsigned short *)(&chan->data[0x17]) = __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[11] - 0x3c); + *(unsigned short*)(&chan->data[0x15]) = + __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[10]); + *(unsigned short*)(&chan->data[0x16]) = + __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[10]); + *(unsigned short*)(&chan->data[0x17]) = + __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[11] - 0x3c); } - - break; - case 1: - case 2: - *(unsigned short *)(&chan->data[0xf]) = __MIXGetVolume(chan->data[7] + chan->data[8] + chan->data[10]); - *(unsigned short *)(&chan->data[0x10]) = __MIXGetVolume(chan->data[7] + chan->data[9] + chan->data[10]); - *(unsigned short *)(&chan->data[0x11]) = __MIXGetVolume(chan->data[7] + chan->data[11]); - - if ( (chan->data[1] & 1) != 0) - { - *(unsigned short *)(&chan->data[0x12]) = __MIXGetVolume(chan->data[3] + chan->data[8] + chan->data[10]); - *(unsigned short *)(&chan->data[0x13]) = __MIXGetVolume(chan->data[3] + chan->data[9] + chan->data[10]); - *(unsigned short *)(&chan->data[0x14]) = __MIXGetVolume(chan->data[3] + chan->data[11] + -0x3c); - } - else - { - *(unsigned short *)(&chan->data[0x12]) = __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[8] + chan->data[10]); - *(unsigned short *)(&chan->data[0x13]) = __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[9] + chan->data[10]); - *(unsigned short *)(&chan->data[0x14]) = __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[11] + -0x3c); - } - if (chan->data[1] & 2U) - { - *(unsigned short *)(&chan->data[0x15]) = __MIXGetVolume(chan->data[4] + chan->data[8] + chan->data[10]); - *(unsigned short *)(&chan->data[0x16]) = __MIXGetVolume(chan->data[4] + chan->data[9] + chan->data[10]); - *(unsigned short *)(&chan->data[0x17]) = __MIXGetVolume(chan->data[4] + chan->data[11] + -0x3c); - } - else - { - *(unsigned short *)(&chan->data[0x15]) = __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[8] + chan->data[10]); - *(unsigned short *)(&chan->data[0x16]) = __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[9] + chan->data[10]); - *(unsigned short *)(&chan->data[0x17]) = __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[11] + -0x3c); - } + case 1: + case 2: + *(unsigned short*)(&chan->data[0xf]) = + __MIXGetVolume(chan->data[7] + chan->data[8] + chan->data[10]); + *(unsigned short*)(&chan->data[0x10]) = + __MIXGetVolume(chan->data[7] + chan->data[9] + chan->data[10]); + *(unsigned short*)(&chan->data[0x11]) = __MIXGetVolume(chan->data[7] + chan->data[11]); + + if ((chan->data[1] & 1) != 0) + { + *(unsigned short*)(&chan->data[0x12]) = + __MIXGetVolume(chan->data[3] + chan->data[8] + chan->data[10]); + *(unsigned short*)(&chan->data[0x13]) = + __MIXGetVolume(chan->data[3] + chan->data[9] + chan->data[10]); + *(unsigned short*)(&chan->data[0x14]) = + __MIXGetVolume(chan->data[3] + chan->data[11] + -0x3c); + } + else + { + *(unsigned short*)(&chan->data[0x12]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[8] + chan->data[10]); + *(unsigned short*)(&chan->data[0x13]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[9] + chan->data[10]); + *(unsigned short*)(&chan->data[0x14]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[11] + -0x3c); + } + if (chan->data[1] & 2U) + { + *(unsigned short*)(&chan->data[0x15]) = + __MIXGetVolume(chan->data[4] + chan->data[8] + chan->data[10]); + *(unsigned short*)(&chan->data[0x16]) = + __MIXGetVolume(chan->data[4] + chan->data[9] + chan->data[10]); + *(unsigned short*)(&chan->data[0x17]) = + __MIXGetVolume(chan->data[4] + chan->data[11] + -0x3c); + } + else + { + *(unsigned short*)(&chan->data[0x15]) = + __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[8] + chan->data[10]); + *(unsigned short*)(&chan->data[0x16]) = + __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[9] + chan->data[10]); + *(unsigned short*)(&chan->data[0x17]) = + __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[11] + -0x3c); + } break; - case 3: - *(unsigned short *)(&chan->data[15]) = __MIXGetVolume(chan->data[7] + chan->data[8] + chan->data[10]); - *(unsigned short *)(&chan->data[16]) = __MIXGetVolume(chan->data[7] + chan->data[9] + chan->data[10]); - *(unsigned short *)(&chan->data[21]) = __MIXGetVolume(chan->data[7] + chan->data[12] + chan->data[11]); - *(unsigned short *)(&chan->data[22]) = __MIXGetVolume(chan->data[7] + chan->data[13] + chan->data[11]); - - if ((chan->data[1] & 1) != 0) - { - *(unsigned short *)(&chan->data[0x12]) = __MIXGetVolume(chan->data[3] + chan->data[8] + chan->data[10] ); - *(unsigned short *)(&chan->data[0x13]) = __MIXGetVolume(chan->data[3] + chan->data[9] + chan->data[10] ); - *(unsigned short *)(&chan->data[0x14]) = __MIXGetVolume(chan->data[3] + chan->data[12] + chan->data[11]); - *(unsigned short *)(&chan->data[0x17]) = __MIXGetVolume(chan->data[3] + chan->data[13] + chan->data[11]); - } - else - { - *(unsigned short *)(&chan->data[0x12]) = __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[8] + chan->data[10]); - *(unsigned short *)(&chan->data[0x13]) = __MIXGetVolume(chan->data[7] + chan->data[3]+ chan->data[9]+ chan->data[10] ); - *(unsigned short *)(&chan->data[0x14]) = __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[12] + chan->data[11]); - *(unsigned short *)(&chan->data[0x17]) = __MIXGetVolume(chan->data[7] + chan->data[3]+ chan->data[13] + chan->data[11]); - } - - uVar4 |= 0x4000; - break; + case 3: + *(unsigned short*)(&chan->data[15]) = + __MIXGetVolume(chan->data[7] + chan->data[8] + chan->data[10]); + *(unsigned short*)(&chan->data[16]) = + __MIXGetVolume(chan->data[7] + chan->data[9] + chan->data[10]); + *(unsigned short*)(&chan->data[21]) = + __MIXGetVolume(chan->data[7] + chan->data[12] + chan->data[11]); + *(unsigned short*)(&chan->data[22]) = + __MIXGetVolume(chan->data[7] + chan->data[13] + chan->data[11]); + + if ((chan->data[1] & 1) != 0) + { + *(unsigned short*)(&chan->data[0x12]) = + __MIXGetVolume(chan->data[3] + chan->data[8] + chan->data[10]); + *(unsigned short*)(&chan->data[0x13]) = + __MIXGetVolume(chan->data[3] + chan->data[9] + chan->data[10]); + *(unsigned short*)(&chan->data[0x14]) = + __MIXGetVolume(chan->data[3] + chan->data[12] + chan->data[11]); + *(unsigned short*)(&chan->data[0x17]) = + __MIXGetVolume(chan->data[3] + chan->data[13] + chan->data[11]); + } + else + { + *(unsigned short*)(&chan->data[0x12]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[8] + chan->data[10]); + *(unsigned short*)(&chan->data[0x13]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[9] + chan->data[10]); + *(unsigned short*)(&chan->data[0x14]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[12] + chan->data[11]); + *(unsigned short*)(&chan->data[0x17]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[13] + chan->data[11]); + } + uVar4 |= 0x4000; + break; } - OSDisableInterrupts(); + //OSDisableInterrupts(); - *(unsigned short *)((int)param_1 + 0x19c) = *(unsigned short *)(&chan->data[0xe]); // Target sets to r4 instead of r3. - *(unsigned short *)((int)param_1 + 0x19e) = 0; - if ( (*(unsigned short *)((int)param_1 + 0x14a) = *(unsigned short *)(&chan->data[0xf])) ) + *(unsigned short*)((int)param_1 + 0x19c) = + *(unsigned short*)(&chan->data[0xe]); // Target sets to r4 instead of r3. + *(unsigned short*)((int)param_1 + 0x19e) = 0; + if ((*(unsigned short*)((int)param_1 + 0x14a) = *(unsigned short*)(&chan->data[0xf]))) { uVar4 |= 1; } - *(unsigned short *)((int)param_1 + 0x14c) = 0; + *(unsigned short*)((int)param_1 + 0x14c) = 0; - if (*(unsigned short *)(param_1 + 0x14e) = *(unsigned short *)(&chan->data[0x10])) + if (*(unsigned short*)(param_1 + 0x14e) = *(unsigned short*)(&chan->data[0x10])) { uVar4 = uVar4 | 2; } - *(unsigned short *)(param_1 + 0x150) = 0; + *(unsigned short*)(param_1 + 0x150) = 0; - if (*(unsigned short *)(param_1 + 0x152) = *(unsigned short *)(&chan->data[0x12])) + if (*(unsigned short*)(param_1 + 0x152) = *(unsigned short*)(&chan->data[0x12])) { uVar4 = uVar4 | 0x10; } - *(unsigned short *)((int)param_1 + 0x154) = 0; - if (*(unsigned short *)((int)param_1 + 0x156) = *(unsigned short *)(&chan->data[0x13])) + *(unsigned short*)((int)param_1 + 0x154) = 0; + if (*(unsigned short*)((int)param_1 + 0x156) = *(unsigned short*)(&chan->data[0x13])) { uVar4 = uVar4 | 0x20; } - *(unsigned short *)(param_1 + 0x158) = 0; - if (*(unsigned short *)(param_1 + 0x15a) = *(unsigned short *)(&chan->data[0x15])) + *(unsigned short*)(param_1 + 0x158) = 0; + if (*(unsigned short*)(param_1 + 0x15a) = *(unsigned short*)(&chan->data[0x15])) { uVar4 = uVar4 | 0x200; } - *(unsigned short *)(param_1 + 0x15c) = 0; - if (*(unsigned short *)(param_1 + 0x15e) = *(unsigned short *)(&chan->data[0x16])) + *(unsigned short*)(param_1 + 0x15c) = 0; + if (*(unsigned short*)(param_1 + 0x15e) = *(unsigned short*)(&chan->data[0x16])) { uVar4 = uVar4 | 0x400; } - *(unsigned short *)(param_1 + 0x160) = 0; + *(unsigned short*)(param_1 + 0x160) = 0; ; - if (*(unsigned short *)(param_1 + 0x162) = *(unsigned short *)(&chan->data[0x17])) + if (*(unsigned short*)(param_1 + 0x162) = *(unsigned short*)(&chan->data[0x17])) { uVar4 = uVar4 | 0x1000; } - *(unsigned short *)(param_1 + 0x164) = 0; - if (*(unsigned short *)((int)param_1 + 0x166) = *(unsigned short *)(&chan->data[0x11])) + *(unsigned short*)(param_1 + 0x164) = 0; + if (*(unsigned short*)((int)param_1 + 0x166) = *(unsigned short*)(&chan->data[0x11])) { uVar4 = uVar4 | 4; } - *(unsigned short *)((int)param_1 + 0x168) = 0; - if (*(unsigned short *)(param_1 + 0x16a) = *(unsigned short *)(&chan->data[0x14])) + *(unsigned short*)((int)param_1 + 0x168) = 0; + if (*(unsigned short*)(param_1 + 0x16a) = *(unsigned short*)(&chan->data[0x14])) { uVar4 = uVar4 | 0x80; } - *(unsigned short *)((int)param_1 + 0x16c) = 0; - *(unsigned short *)((int)param_1 + 0x144) = uVar4; - *(unsigned int *)(param_1 + 0x1c) = *(unsigned int *)(param_1 + 0x1c) | 0x212; - OSRestoreInterrupts(); - + *(unsigned short*)((int)param_1 + 0x16c) = 0; + *(unsigned short*)((int)param_1 + 0x144) = uVar4; + *(unsigned int*)(param_1 + 0x1c) = *(unsigned int*)(param_1 + 0x1c) | 0x212; + //OSRestoreInterrupts(); } void MIXReleaseChannel(int* param_1) diff --git a/src/SB/Core/gc/iPad.cpp b/src/SB/Core/gc/iPad.cpp index 6a04b9cc2..39b66ff5f 100644 --- a/src/SB/Core/gc/iPad.cpp +++ b/src/SB/Core/gc/iPad.cpp @@ -4,6 +4,8 @@ #include "xTRC.h" #include "zGlobals.h" +#include + extern xGlobals* xglobals; extern zGlobals globals; diff --git a/src/SB/Core/gc/iTRC.cpp b/src/SB/Core/gc/iTRC.cpp index c4e17697b..56d02dbfd 100644 --- a/src/SB/Core/gc/iTRC.cpp +++ b/src/SB/Core/gc/iTRC.cpp @@ -1,5 +1,6 @@ #include "iTRC.h" +#include #include #include #include @@ -12,6 +13,7 @@ #include #include #include +#include #define FONT_MATRIX_ID 0x1E #define TEXTBOX_MAX_TEXT_LENGTH 256 @@ -192,10 +194,10 @@ void ROMFont::DrawCell(S32 param_1, S32 param_2, S32 param_3, S32 param_4) { U16 uVar1; U16 uVar2; - S16 sVar3; - S32 iVar4; - S32 iVar5; - S32 iVar6; + S16 sVar3 = 0; + S32 iVar4 = 0; + S32 iVar5 = 0; + S16 iVar6 = 0; uVar1 = mFontData->cellWidth; uVar2 = mFontData->cellHeight; @@ -211,14 +213,14 @@ void ROMFont::DrawCell(S32 param_1, S32 param_2, S32 param_3, S32 param_4) iVar6 = (int)(short)(param_3 + uVar1); - GXTexCoord2s16(iVar6, param_4); + GXTexCoord2s16(iVar6, sVar3); GXPosition3s16(iVar5, iVar4, 0); sVar3 = param_4 + uVar2; GXTexCoord2s16(iVar6, sVar3); GXPosition3s16((int)param_1, iVar4, 0); - GXTexCoord2s16((int)param_3, sVar3); + GXTexCoord2s16(iVar6, sVar3); GXEnd(); } diff --git a/src/SB/Core/gc/ngcrad3d.c b/src/SB/Core/gc/ngcrad3d.c index 163d52dba..8742bc781 100644 --- a/src/SB/Core/gc/ngcrad3d.c +++ b/src/SB/Core/gc/ngcrad3d.c @@ -1,5 +1,6 @@ #include "ngcrad3d.h" +#include #include "iFMV.h" static int D3D_surface_type[5]; @@ -29,37 +30,39 @@ static void Setup_surface_array() Built_tables = 1; } -HRAD3DIMAGE Open_RAD_3D_image(HBINK param_1, unsigned int param_2, unsigned int param_3, unsigned int param_4) -{ - HRAD3DIMAGE imgDat; - int pi_p4; - - Setup_surface_array(); +// HRAD3DIMAGE Open_RAD_3D_image(HBINK param_1, unsigned int param_2, unsigned int param_3, +// unsigned int param_4) +// { +// HRAD3DIMAGE imgDat; +// int pi_p4; - pi_p4 = Pixel_info[param_4] & 0xff; - imgDat = (HRAD3DIMAGE)iFMVmalloc(0x3c); +// Setup_surface_array(); - if (imgDat == 0) - { - return 0; - } +// pi_p4 = Pixel_info[param_4] & 0xff; +// imgDat = (HRAD3DIMAGE)iFMVmalloc(0x3c); - imgDat->a = param_2; - imgDat->b = param_3; - imgDat->c = Pixel_info[param_4] >> 31; - imgDat->d = pi_p4; - imgDat->e = param_4; +// if (imgDat == 0) +// { +// return 0; +// } - imgDat->g = GXGetTexBufferSize((unsigned short)param_2, (unsigned short)param_3, D3D_surface_type[param_4], 0, 0); - imgDat->f = (void*)iFMVmalloc(imgDat->g); +// imgDat->a = param_2; +// imgDat->b = param_3; +// imgDat->c = Pixel_info[param_4] >> 31; +// imgDat->d = pi_p4; +// imgDat->e = param_4; - GXInitTexObj((volatile int)imgDat + 0x1c, imgDat->f, param_2 & 0xffff, param_3 & 0xffff, D3D_surface_type[param_4], 0, 0, 0); +// imgDat->g = GXGetTexBufferSize((unsigned short)param_2, (unsigned short)param_3, +// D3D_surface_type[param_4], 0, 0); +// imgDat->f = (void*)iFMVmalloc(imgDat->g); - GXInitTexObjLOD(0.0f, 0.0f, 0.0f, (volatile int)imgDat + 0x1c, 1, 0, 0, 0, 0); +// GXInitTexObj((volatile int)imgDat + 0x1c, imgDat->f, param_2 & 0xffff, param_3 & 0xffff, +// D3D_surface_type[param_4], 0, 0, 0); - return imgDat; +// GXInitTexObjLOD(imgDat, 0.0f, 0.0f, (volatile int)imgDat + 0x1c, 1, 0, 0, 0, 0); -} +// return imgDat; +// } void Close_RAD_3D_image(struct RAD3DIMAGE* image) { @@ -74,7 +77,8 @@ void Close_RAD_3D_image(struct RAD3DIMAGE* image) } } -int Lock_RAD_3D_image(HRAD3DIMAGE rad_image, void* out_pixel_buffer, unsigned int* out_buffer_pitch, unsigned int* arg3) +int Lock_RAD_3D_image(HRAD3DIMAGE rad_image, void* out_pixel_buffer, unsigned int* out_buffer_pitch, + unsigned int* arg3) { if (rad_image == 0) { @@ -99,75 +103,74 @@ int Lock_RAD_3D_image(HRAD3DIMAGE rad_image, void* out_pixel_buffer, unsigned in return 1; } -void Unlock_RAD_3D_image(struct RAD3DIMAGE* image) -{ - if (image) - { - DCStoreRange(image->f, image->g); - } -} - -void GXEnd() { } - -static void GXTexCoord2f32(float f1, float f2) -{ - int ptr = 0xcc010000; - *(float*)((char*)(ptr) - 0x8000) = f1; - *(float*)((char*)(ptr) - 0x8000) = f2; -} +// void Unlock_RAD_3D_image(struct RAD3DIMAGE* image) +// { +// if (image) +// { +// DCStoreRange(image->f, image->g); +// } +// } + +// static void GXTexCoord2f32(float f1, float f2) +// { +// int ptr = 0xcc010000; +// *(float*)((char*)(ptr)-0x8000) = f1; +// *(float*)((char*)(ptr)-0x8000) = f2; +// } static void GXColor4u8(int r3, int r4, int r5, int r6) { int ptr = 0xcc010000; - *((char*)(ptr) - 0x8000) = r3; - *((char*)(ptr) - 0x8000) = r4; - *((char*)(ptr) - 0x8000) = r5; - *((char*)(ptr) - 0x8000) = r6; + *((char*)(ptr)-0x8000) = r3; + *((char*)(ptr)-0x8000) = r4; + *((char*)(ptr)-0x8000) = r5; + *((char*)(ptr)-0x8000) = r6; } static void GXPosition3s16(int r3, int r4, int r5) { int ptr = 0xcc010000; - *(short*)((char*)(ptr) - 0x8000) = r3; - *(short*)((char*)(ptr) - 0x8000) = r4; - *(short*)((char*)(ptr) - 0x8000) = r5; + *(short*)((char*)(ptr)-0x8000) = r3; + *(short*)((char*)(ptr)-0x8000) = r4; + *(short*)((char*)(ptr)-0x8000) = r5; } -static void GXSetTextCoordGen(int a, int b, int c, int d) -{ - GXSetTexCoordGen2(a, b, c, d, 0, 0x7d); -} - -static void Submit_vertices(float param_1, float param_2, float param_3, float param_4, long param_5, long param_6, float param_7) -{ - short uVar1 = (short)(param_7 * 255.0f) & 0xff; - short iVar3; - short iVar2; - short blah = (unsigned short)param_2; - - GXSetCullMode(0); - GXSetZMode(1, 7, 1); - GXSetColorUpdate(1); - GXBegin(0x80, 0, 4); - iVar3 = param_1; - iVar2 = param_6 * param_4 + param_2; - - GXPosition3s16(iVar3, iVar2, 0); - GXColor4u8(0xff, 0xff, 0xff, uVar1); - GXTexCoord2f32(0, 1.0f); - - GXPosition3s16(iVar3, blah, 0); - GXColor4u8(0xff, 0xff, 0xff, uVar1); - GXTexCoord2f32(0, 0); - iVar3 = param_5 * param_3 + param_1; - - GXPosition3s16(iVar3, blah, 0); - GXColor4u8(0xff, 0xff, 0xff, uVar1); - GXTexCoord2f32(4503601774854144.0, 0); - - GXPosition3s16(iVar3, iVar2, 0); - GXColor4u8(0xff, 0xff, 0xff, uVar1); - GXTexCoord2f32(1.0f, 1.0f); - - GXEnd(); -} \ No newline at end of file +// static void GXSetTextCoordGen(int a, int b, int c, int d) +// { +// GXSetTexCoordGen2(a, b, c, d, 0, 0x7d); +// } + +// static void Submit_vertices(float param_1, float param_2, float param_3, float param_4, +// long param_5, long param_6, float param_7) +// { +// short uVar1 = (short)(param_7 * 255.0f) & 0xff; +// short iVar3; +// short iVar2; +// short blah = (unsigned short)param_2; + +// GXSetCullMode(0); +// GXSetZMode(1, 7, 1); +// GXSetColorUpdate(1); +// GXBegin(0x80, 0, 4); +// iVar3 = param_1; +// iVar2 = param_6 * param_4 + param_2; + +// GXPosition3s16(iVar3, iVar2, 0); +// GXColor4u8(0xff, 0xff, 0xff, uVar1); +// GXTexCoord2f32(0, 1.0f); + +// GXPosition3s16(iVar3, blah, 0); +// GXColor4u8(0xff, 0xff, 0xff, uVar1); +// GXTexCoord2f32(0, 0); +// iVar3 = param_5 * param_3 + param_1; + +// GXPosition3s16(iVar3, blah, 0); +// GXColor4u8(0xff, 0xff, 0xff, uVar1); +// GXTexCoord2f32(4503601774854144.0, 0); + +// GXPosition3s16(iVar3, iVar2, 0); +// GXColor4u8(0xff, 0xff, 0xff, uVar1); +// GXTexCoord2f32(1.0f, 1.0f); + +// GXEnd(); +// } \ No newline at end of file diff --git a/src/SB/Core/x/xAnim.cpp b/src/SB/Core/x/xAnim.cpp index f08f07bf1..198549529 100644 --- a/src/SB/Core/x/xAnim.cpp +++ b/src/SB/Core/x/xAnim.cpp @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include @@ -360,19 +360,19 @@ void xAnimTempTransitionInit(U32 count) sizeof(xAnimTransition), count, count / 2); } -// TODO: move to xMathInlines.h -F32 xatan2(F32 y, F32 x) -{ - return xAngleClampFast(std::atan2f(y, x)); -} - #ifndef INLINE -float std::atan2f(float y, float x) +float atan2f(float y, float x) { return (float)atan2((double)y, (double)x); } #endif +// TODO: move to xMathInlines.h +F32 xatan2(F32 y, F32 x) +{ + return xAngleClampFast(std::atan2f(y, x)); +} + float CalcRecipBlendMax(U16* arg0) { float max = 0.0f; @@ -684,7 +684,7 @@ void xAnimFileEval(xAnimFile* data, F32 time, F32* bilinear, U32 flags, xVec3* t } #ifndef INLINE -float std::floorf(float x) +float floorf(float x) { return (float)floor((double)x); } @@ -2093,7 +2093,7 @@ void xAnimPoolCB(xMemPool* pool, void* data) clone->Pool = pool; } -#define ADD_4_BITS(x) (((x) & 1) + (((x) >> 1) & 1) + (((x) >> 2) & 1) + (((x) >> 3) & 1)) +#define ADD_4_BITS(x) (((x)&1) + (((x) >> 1) & 1) + (((x) >> 2) & 1) + (((x) >> 3) & 1)) void xAnimPoolInit(xMemPool* pool, U32 count, U32 singles, U32 blendFlags, U32 effectMax) { effectMax += effectMax & 1; diff --git a/src/SB/Core/x/xCamera.cpp b/src/SB/Core/x/xCamera.cpp index b3e6ca00b..791c0ba10 100644 --- a/src/SB/Core/x/xCamera.cpp +++ b/src/SB/Core/x/xCamera.cpp @@ -9,22 +9,16 @@ #include "iMath.h" -#include -#include - - +#include +#include #define CAMERAFX_ZOOM_MODE_0 0 #define CAMERAFX_ZOOM_MODE_1 1 #define CAMERAFX_ZOOM_MODE_2 2 #define CAMERAFX_ZOOM_MODE_3 3 - - #define CAMERAFX_TYPE_SHAKE 2 - - S32 sCamCollis; volatile S32 xcam_collis_owner_disable; S32 xcam_do_collis = 1; @@ -687,8 +681,8 @@ void xCameraFXShakeUpdate(cameraFX* f, F32 dt, const xMat4x3*, xMat4x3* m) xMat3x3GetEuler(m, &e); - e.z += - f->shake.cycleTime / f->shake.cycleMax * 0.63661975f * 0.1f * scale * f->shake.rotate_magnitude; + e.z += f->shake.cycleTime / f->shake.cycleMax * 0.63661975f * 0.1f * scale * + f->shake.rotate_magnitude; xMat3x3Euler(m, &e); } @@ -800,7 +794,8 @@ void xCameraMove(xCamera* cam, U32 flags, F32 dgoal, F32 hgoal, F32 pgoal, F32 t xCam_cyltoworld(&cam->mat.pos, cam->tgt_mat, dgoal, hgoal, pgoal, cam->flags); cam->omat.pos = cam->mat.pos; - cam->yaw_cur = cam->yaw_goal = cam->pcur + ((cam->pcur >= 3.1415927f) ? -3.1415927f : 3.1415927f); + cam->yaw_cur = cam->yaw_goal = + cam->pcur + ((cam->pcur >= 3.1415927f) ? -3.1415927f : 3.1415927f); } } else diff --git a/src/SB/Core/x/xCutscene.cpp b/src/SB/Core/x/xCutscene.cpp index 45e0e63c0..544c35097 100644 --- a/src/SB/Core/x/xCutscene.cpp +++ b/src/SB/Core/x/xCutscene.cpp @@ -10,6 +10,7 @@ #include #include +#include xCutscene sActiveCutscene; U32 sCutTocCount; @@ -143,7 +144,7 @@ S32 xCutscene_LoadStart(xCutscene* csn) return 1; } -S32 xCutscene_Update(xCutscene *csn, F32 dt) +S32 xCutscene_Update(xCutscene* csn, F32 dt) { if ((csn->SndStarted == FALSE) && (csn->SndNumChannel != 0)) { @@ -183,7 +184,8 @@ S32 xCutscene_Update(xCutscene *csn, F32 dt) if (csn->Waiting) { csn->Time = csn->Play->EndTime; - csn->CamTime = xCutsceneConvertBreak(csn->Time, csn->BreakList, csn->Info->BreakCount, -1); + csn->CamTime = + xCutsceneConvertBreak(csn->Time, csn->BreakList, csn->Info->BreakCount, -1); if (csn->BadReadPause == FALSE) { @@ -202,7 +204,9 @@ S32 xCutscene_Update(xCutscene *csn, F32 dt) if (csn->PlayIndex + 1 < csn->Info->NumTime) { - iCSFileAsyncRead(csn, csn->Stream, csn->TimeChunkOffs[csn->PlayIndex + 2] - csn->TimeChunkOffs[csn->PlayIndex + 1]); + iCSFileAsyncRead(csn, csn->Stream, + csn->TimeChunkOffs[csn->PlayIndex + 2] - + csn->TimeChunkOffs[csn->PlayIndex + 1]); } } @@ -244,7 +248,7 @@ void xCutscene_SetSpeed(xCutscene* csn, F32 speed) F32 xlog(F32 x) { - return std::logf(x); + return std::logf(x); } float std::logf(float x) diff --git a/src/SB/Core/x/xFont.cpp b/src/SB/Core/x/xFont.cpp index 594658a89..c6ecb8eec 100644 --- a/src/SB/Core/x/xFont.cpp +++ b/src/SB/Core/x/xFont.cpp @@ -13,6 +13,7 @@ #include #include +#include /* xtextbox flags */ diff --git a/src/SB/Core/x/xHud.cpp b/src/SB/Core/x/xHud.cpp index c17501952..eb7d9236c 100644 --- a/src/SB/Core/x/xHud.cpp +++ b/src/SB/Core/x/xHud.cpp @@ -9,7 +9,7 @@ #include "zEnt.h" -#include +#include #include #define lengthof(x) (sizeof(x) / sizeof((x)[0])) @@ -339,10 +339,10 @@ namespace xhud U32 widget_size; } known_types[] = { // TODO: The second value should probably be sizeof(...) - {0x3a, 0x9c}, - {0x3c, 0x19c}, - {0x3b, 0x15c}, - {0x47, 0x17c}, + { 0x3a, 0x9c }, + { 0x3c, 0x19c }, + { 0x3b, 0x15c }, + { 0x47, 0x17c }, }; struct functor_disable @@ -380,8 +380,7 @@ namespace xhud F32 delta_time; }; - template - void for_each(U8 widget_type, U32 type_size, F f) + template void for_each(U8 widget_type, U32 type_size, F f) { U32 count = globals.sceneCur->baseCount[widget_type]; U8* list = (U8*)globals.sceneCur->baseList[widget_type]; @@ -391,7 +390,8 @@ namespace xhud } } - void render_one_model(xModelInstance& model, F32 alpha, const basic_rect& rect, const xVec3& from, const xVec3& to, const xMat4x3& frame) + void render_one_model(xModelInstance& model, F32 alpha, const basic_rect& rect, + const xVec3& from, const xVec3& to, const xMat4x3& frame) { xModelSetMaterialAlpha(&model, 255.0f * alpha + 0.5f); xModelSetFrame(&model, &frame); @@ -402,7 +402,6 @@ namespace xhud void widget::debug_render() { - } void widget::setup_all() @@ -555,7 +554,7 @@ namespace xhud bool shake_motive_update(widget& w, motive& m, F32 dt) { - static const float mult[4] = {-1.0f, -1.0f, 1.0f, 1.0f}; + static const float mult[4] = { -1.0f, -1.0f, 1.0f, 1.0f }; *((U32*)&m.context) += 1; U32 context = *((U32*)&m.context); @@ -592,15 +591,14 @@ namespace xhud void xhud::render_model(xModelInstance& model, const xhud::render_context& rc) { - basic_rect rect = { 0 }; rect.x = rc.loc.x; rect.y = rc.loc.y; rect.w = rc.size.x; rect.h = rc.size.y; - xVec3 vecA = {0, 0, 1}; - xVec3 vecB = {0, 0, -rc.loc.z}; + xVec3 vecA = { 0, 0, 1 }; + xVec3 vecB = { 0, 0, -rc.loc.z }; xMat4x3 matrix; xMat3x3Euler(&matrix, rc.rot.x, rc.rot.y, rc.rot.z); diff --git a/src/SB/Core/x/xHudMeter.cpp b/src/SB/Core/x/xHudMeter.cpp index 31af911b3..9fa21340a 100644 --- a/src/SB/Core/x/xHudMeter.cpp +++ b/src/SB/Core/x/xHudMeter.cpp @@ -4,6 +4,7 @@ #include "xString.h" #include "xMathInlines.h" +#include "PowerPC_EABI_Support\MSL_C\MSL_Common\printf.h" namespace xhud { diff --git a/src/SB/Core/x/xHudModel.cpp b/src/SB/Core/x/xHudModel.cpp index 3b61a73f1..041d72cbb 100644 --- a/src/SB/Core/x/xHudModel.cpp +++ b/src/SB/Core/x/xHudModel.cpp @@ -2,7 +2,7 @@ #include "xHud.h" #include "xString.h" -#include +#include #include xAnimTable* XHUD_AnimTable_Idle() diff --git a/src/SB/Core/x/xHudText.cpp b/src/SB/Core/x/xHudText.cpp index 5c9597a56..49202adcb 100644 --- a/src/SB/Core/x/xHudText.cpp +++ b/src/SB/Core/x/xHudText.cpp @@ -4,8 +4,8 @@ #include "zScene.h" #include "zTextBox.h" -#include -#include +#include +#include #include void xhud::text_widget::load(xBase& data, xDynAsset& asset, size_t) diff --git a/src/SB/Core/x/xIni.cpp b/src/SB/Core/x/xIni.cpp index d1a270bc3..90c0e45a2 100644 --- a/src/SB/Core/x/xIni.cpp +++ b/src/SB/Core/x/xIni.cpp @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include char* TrimWhitespace(char* string) { diff --git a/src/SB/Core/x/xJaw.cpp b/src/SB/Core/x/xJaw.cpp index f94519f97..4c04d9545 100644 --- a/src/SB/Core/x/xJaw.cpp +++ b/src/SB/Core/x/xJaw.cpp @@ -2,7 +2,7 @@ #include "xstransvc.h" -#include +#include struct xJawDataTable { @@ -45,13 +45,13 @@ void* xJaw_FindData(U32 soundID) #define swap(data) \ { \ - U8 c; \ - c = ((U8*)(data))[3]; \ - ((U8*)(data))[3] = ((U8*)(data))[0]; \ - ((U8*)(data))[0] = c; \ - c = ((U8*)(data))[2]; \ - ((U8*)(data))[2] = ((U8*)(data))[1]; \ - ((U8*)(data))[1] = c; \ + U8 c; \ + c = ((U8*)(data))[3]; \ + ((U8*)(data))[3] = ((U8*)(data))[0]; \ + ((U8*)(data))[0] = c; \ + c = ((U8*)(data))[2]; \ + ((U8*)(data))[2] = ((U8*)(data))[1]; \ + ((U8*)(data))[1] = c; \ } F32 xJaw_EvalData(void* data, F32 time) diff --git a/src/SB/Core/x/xMath.cpp b/src/SB/Core/x/xMath.cpp index ed37d17c2..a1c64c580 100644 --- a/src/SB/Core/x/xMath.cpp +++ b/src/SB/Core/x/xMath.cpp @@ -1,7 +1,7 @@ #include "xMath.h" #include -#include +#include #include "xMathInlines.h" @@ -98,7 +98,8 @@ U32 xMathSolveQuadratic(F32 a, F32 b, F32 c, F32* x1, F32* x2) return 2; } -U32 xMathSolveCubic(F32 a, F32 b, F32 c, F32 d, F32* x1, F32* x2, F32* x3) { +U32 xMathSolveCubic(F32 a, F32 b, F32 c, F32 d, F32* x1, F32* x2, F32* x3) +{ F32 arecip; // F32 fA; // p F32 fB; // q @@ -118,10 +119,12 @@ U32 xMathSolveCubic(F32 a, F32 b, F32 c, F32 d, F32* x1, F32* x2, F32* x3) { F32 temp_f29; F32 var_f1; - if (a == 0.0f) { + if (a == 0.0f) + { return xMathSolveQuadratic(b, c, d, x1, x2); } - if (a != 1.0f) { + if (a != 1.0f) + { arecip = 1.0f / a; b *= arecip; c *= arecip; @@ -132,27 +135,36 @@ U32 xMathSolveCubic(F32 a, F32 b, F32 c, F32 d, F32* x1, F32* x2, F32* x3) { fOffset = 0.33333334f * b; fDiscr = (0.25f * (fB * fB)) + (0.037037037f * (fA * (fA * fA))); fHalfB = 0.5f * fB; - if ((F32) __fabs(fDiscr) < 0.000001f) { + if ((F32)__fabs(fDiscr) < 0.000001f) + { fDiscr = 0.0f; } - if (fDiscr > 0.0f) { + if (fDiscr > 0.0f) + { temp_f1 = xsqrt(fDiscr); temp_f1_2 = -fHalfB + temp_f1; - if (temp_f1_2 >= 0.0f) { + if (temp_f1_2 >= 0.0f) + { *x1 = xpow(temp_f1_2, 0.33333334f); - } else { + } + else + { *x1 = -xpow(-temp_f1_2, 0.33333334f); } temp_f1_3 = -fHalfB - temp_f1; - if (temp_f1_3 >= 0.0f) { + if (temp_f1_3 >= 0.0f) + { *x1 += xpow(temp_f1_3, 0.33333334f); - } else { + } + else + { *x1 -= xpow(-temp_f1_3, 0.33333334f); } *x1 -= fOffset; return 1; } - if (fDiscr < 0.0f) { + if (fDiscr < 0.0f) + { temp_f29 = xsqrt(-0.33333334f * fA); temp_f28_2 = 0.33333334f * xatan2(xsqrt(-fDiscr), -fHalfB); fCos = icos(temp_f28_2); @@ -162,9 +174,12 @@ U32 xMathSolveCubic(F32 a, F32 b, F32 c, F32 d, F32* x1, F32* x2, F32* x3) { *x3 = (-temp_f29 * (fCos - 1.7320508f * fSin)) - fOffset; return 3; } - if (fHalfB >= 0.0f) { + if (fHalfB >= 0.0f) + { var_f1 = -xpow(fHalfB, 0.33333334f); - } else { + } + else + { var_f1 = xpow(-fHalfB, 0.33333334f); } *x1 = (2.0f * var_f1) - fOffset; @@ -220,7 +235,8 @@ F32 xDangleClamp(F32 a) return rem; } -void xAccelMove(F32& x, F32& v, F32 a, F32 dt, F32 endx, F32 maxv) { +void xAccelMove(F32& x, F32& v, F32 a, F32 dt, F32 endx, F32 maxv) +{ F32 offset; F32 t1; F32 t2; @@ -249,97 +265,144 @@ void xAccelMove(F32& x, F32& v, F32 a, F32 dt, F32 endx, F32 maxv) { temp_f29 = endx - x; var_r3 = 1; - if (!((F32) __fabs(v) < 0.001f)) { - if (v < 0.0f) { + if (!((F32)__fabs(v) < 0.001f)) + { + if (v < 0.0f) + { var_r4 = 1; - } else { + } + else + { var_r4 = 0; } - if (temp_f29 < 0.0f) { + if (temp_f29 < 0.0f) + { var_r0 = 1; - } else { + } + else + { var_r0 = 0; } - if (var_r0 == var_r4) { + if (var_r0 == var_r4) + { var_r3 = 0; } } - if (var_r3 != 0) { + if (var_r3 != 0) + { var_f31 = 1e38f; - } else { + } + else + { var_f31 = temp_f29 / v; } - temp_f28 = (F32) __fabs(v / a); - if (var_f31 < temp_f28) { + temp_f28 = (F32)__fabs(v / a); + if (var_f31 < temp_f28) + { a *= -1.0f; } - if (temp_f29 < 0.0f) { + if (temp_f29 < 0.0f) + { a *= -1.0f; } dv = a * dt; oldv = v; newv = oldv + dv; - if ((F32) __fabs(newv) == maxv) { + if ((F32)__fabs(newv) == maxv) + { v = newv; var_f0 = 0.5f * dv * dt; - } else { - - if ((F32) __fabs(oldv) == maxv) { + } + else + { + if ((F32)__fabs(oldv) == maxv) + { v = range_limit(newv, -maxv, maxv); - if (oldv != v) { + if (oldv != v) + { temp_f1_2 = v - oldv; var_f0 = (0.5f * temp_f1_2 * temp_f1_2) / a; - } else { + } + else + { var_f0 = 0.0f; } - } else { - if (dv < 0.0f) { + } + else + { + if (dv < 0.0f) + { var_r3_2 = 1; - } else { + } + else + { var_r3_2 = 0; } - if (newv < 0.0f) { + if (newv < 0.0f) + { var_r0_2 = 1; - } else { + } + else + { var_r0_2 = 0; } - if (var_r0_2 != var_r3_2) { + if (var_r0_2 != var_r3_2) + { v = newv; var_f0 = 0.5f * dv * dt; - } else { + } + else + { var_f0 = 0.0f; } } } var_f2 = (oldv * dt) + var_f0; - if (var_f31 > temp_f28) { - if (temp_f29 < 0.0f) { + if (var_f31 > temp_f28) + { + if (temp_f29 < 0.0f) + { var_r3_3 = 1; - } else { + } + else + { var_r3_3 = 0; } - if (var_f2 < 0.0f) { + if (var_f2 < 0.0f) + { var_r0_3 = 1; - } else { + } + else + { var_r0_3 = 0; } - if ((var_r0_3 == var_r3_3) && ((F32) __fabs(var_f2) > (F32) __fabs(temp_f29))) { + if ((var_r0_3 == var_r3_3) && ((F32)__fabs(var_f2) > (F32)__fabs(temp_f29))) + { var_f2 = temp_f29; v = 0.0f; } - } else { - if (temp_f29 < 0.0f) { + } + else + { + if (temp_f29 < 0.0f) + { var_r3_4 = 1; - } else { + } + else + { var_r3_4 = 0; } - if (var_f2 < 0.0f) { + if (var_f2 < 0.0f) + { var_r0_4 = 1; - } else { + } + else + { var_r0_4 = 0; } - if (var_r0_4 != var_r3_4) { + if (var_r0_4 != var_r3_4) + { var_f2 = temp_f29; v = 0.0f; } @@ -359,33 +422,44 @@ F32 xAccelMoveTime(F32 dx, F32 a, F32, F32 maxv) return 2.0f * dx; } -void xAccelMove(F32& x, F32& v, F32 a, F32 dt, F32 maxv) { +void xAccelMove(F32& x, F32& v, F32 a, F32 dt, F32 maxv) +{ U32 bn; // r10 U32 bp; // r7 U32 aa; // r29+0xC F32 diff; F32 dv; - if ((F32) __fabs(v) > (F32) __fabs(maxv)) { - if (v < 0.0f) { - if (a > 0.0f) { + if ((F32)__fabs(v) > (F32)__fabs(maxv)) + { + if (v < 0.0f) + { + if (a > 0.0f) + { a = -a; } - } else if (a < 0.0f) { + } + else if (a < 0.0f) + { a = -a; } a = -a; } - if (a < 0.0f) { - if (maxv > 0.0f) { + if (a < 0.0f) + { + if (maxv > 0.0f) + { maxv = -maxv; } - } else if (maxv < 0.0f) { + } + else if (maxv < 0.0f) + { maxv = -maxv; } diff = maxv - v; dv = a * dt; - if ((F32) __fabs(diff) < (F32) __fabs(dv)) { + if ((F32)__fabs(diff) < (F32)__fabs(dv)) + { x += (v * dt) + ((0.5f * diff * diff) / a); v = maxv; return; @@ -394,7 +468,8 @@ void xAccelMove(F32& x, F32& v, F32 a, F32 dt, F32 maxv) { v += dv; } -void xAccelStop(F32& x, F32& v, F32 a, F32 dt) { +void xAccelStop(F32& x, F32& v, F32 a, F32 dt) +{ S32 aa; // From DWARF, currently unused. F32 oldv; @@ -402,47 +477,61 @@ void xAccelStop(F32& x, F32& v, F32 a, F32 dt) { S32 var_r5; oldv = v; - if (!(oldv >= -0.00001f) || !(oldv <= 0.00001f)) { - if (oldv < 0.0f) { - if (a > 0.0f) { + if (!(oldv >= -0.00001f) || !(oldv <= 0.00001f)) + { + if (oldv < 0.0f) + { + if (a > 0.0f) + { a = -a; } - } else if (a < 0.0f) { + } + else if (a < 0.0f) + { a = -a; } v += -a * dt; - if (v < 0.0f) { + if (v < 0.0f) + { var_r5 = 1; - } else { + } + else + { var_r5 = 0; } - if (oldv < 0.0f) { + if (oldv < 0.0f) + { var_r0 = 1; - } else { + } + else + { var_r0 = 0; } - if (var_r0 == var_r5) { + if (var_r0 == var_r5) + { x += (-a * (0.5f * dt * dt)) + (oldv * dt); return; } - if (!(-a >= -0.00001f) || !(-a <= 0.00001f)) { + if (!(-a >= -0.00001f) || !(-a <= 0.00001f)) + { x -= (0.5f * oldv * oldv) / -a; } v = 0.0f; } } -void xFuncPiece_EndPoints(xFuncPiece* func, F32 pi, F32 pf, F32 fi, F32 ff) { +void xFuncPiece_EndPoints(xFuncPiece* func, F32 pi, F32 pf, F32 fi, F32 ff) +{ F32 xfinv; // from DWARF data func->end = pf - pi; func->order = 1; - func->coef[0]= fi; + func->coef[0] = fi; func->coef[1] = (ff - fi) * (1.0f / func->end); xFuncPiece_ShiftPiece(func, func, -pi); } diff --git a/src/SB/Core/x/xModelBucket.cpp b/src/SB/Core/x/xModelBucket.cpp index 790ebfdca..b95b13618 100644 --- a/src/SB/Core/x/xModelBucket.cpp +++ b/src/SB/Core/x/xModelBucket.cpp @@ -3,7 +3,7 @@ #include "iCamera.h" #include -#include +#include extern RpWorld* sBucketDummyWorld; extern RwCamera* sBucketDummyCamera; diff --git a/src/SB/Core/x/xPtankPool.cpp b/src/SB/Core/x/xPtankPool.cpp index c65b0b7a5..c2ea08778 100644 --- a/src/SB/Core/x/xPtankPool.cpp +++ b/src/SB/Core/x/xPtankPool.cpp @@ -3,7 +3,7 @@ #include "xMemMgr.h" #include -#include +#include #include #include diff --git a/src/SB/Core/x/xRMemData.h b/src/SB/Core/x/xRMemData.h index 9d0a94be2..4a94d448f 100644 --- a/src/SB/Core/x/xRMemData.h +++ b/src/SB/Core/x/xRMemData.h @@ -3,7 +3,7 @@ #include "xBase.h" -#include +#include struct RyzMemGrow { diff --git a/src/SB/Core/x/xString.h b/src/SB/Core/x/xString.h index 8ceaf9250..27c809232 100644 --- a/src/SB/Core/x/xString.h +++ b/src/SB/Core/x/xString.h @@ -2,7 +2,7 @@ #define XSTRING_H #include -#include +//#include struct substr { diff --git a/src/SB/Core/x/xpkrsvc.h b/src/SB/Core/x/xpkrsvc.h index 7b25e75e0..d07914095 100644 --- a/src/SB/Core/x/xpkrsvc.h +++ b/src/SB/Core/x/xpkrsvc.h @@ -2,7 +2,8 @@ #define XPKRSVC_H #include -#include +#include +#include "PowerPC_EABI_Support\MSL_C\MSL_Common\time.h" #include "xhipio.h" #include "xordarray.h" diff --git a/src/SB/Core/x/xutil.cpp b/src/SB/Core/x/xutil.cpp index 9a518ff66..77537c9fd 100644 --- a/src/SB/Core/x/xutil.cpp +++ b/src/SB/Core/x/xutil.cpp @@ -3,6 +3,8 @@ #include "xMath.h" #include +#include +#include static volatile S32 g_xutilinit; // volatile so xUtilShutdown matches static S32 g_crc_needinit = 1; diff --git a/src/SB/Game/zAssetTypes.cpp b/src/SB/Game/zAssetTypes.cpp index 5733cb4b1..c4ff20f4e 100644 --- a/src/SB/Game/zAssetTypes.cpp +++ b/src/SB/Game/zAssetTypes.cpp @@ -6,6 +6,7 @@ #include "xJSP.h" #include +#include #include #include #include diff --git a/src/SB/Game/zCamera.h b/src/SB/Game/zCamera.h index 5318d6685..791f6686e 100644 --- a/src/SB/Game/zCamera.h +++ b/src/SB/Game/zCamera.h @@ -3,6 +3,8 @@ #include "xCamera.h" +#include + enum WallJumpViewState { WJVS_DISABLED, diff --git a/src/SB/Game/zDiscoFloor.cpp b/src/SB/Game/zDiscoFloor.cpp index 78303e9bf..09fa33956 100644 --- a/src/SB/Game/zDiscoFloor.cpp +++ b/src/SB/Game/zDiscoFloor.cpp @@ -16,6 +16,7 @@ #include #include +#include extern U32 current_disco_floor; diff --git a/src/SB/Game/zEnt.cpp b/src/SB/Game/zEnt.cpp index 1355560a2..0254af9f0 100644 --- a/src/SB/Game/zEnt.cpp +++ b/src/SB/Game/zEnt.cpp @@ -14,8 +14,9 @@ #include "xSnd.h" #include "xCollide.h" #include "zNPCTypes.h" -#include +#include #include +#include void zEntInit(zEnt* ent, xEntAsset* asset, U32 type) { diff --git a/src/SB/Game/zEntCruiseBubble.cpp b/src/SB/Game/zEntCruiseBubble.cpp index 2e68af6fb..c40a995a1 100644 --- a/src/SB/Game/zEntCruiseBubble.cpp +++ b/src/SB/Game/zEntCruiseBubble.cpp @@ -1,5 +1,5 @@ #include "zNPCHazard.h" -#include +#include #include #include "stdio.h" diff --git a/src/SB/Game/zEntPlayerBungeeState.cpp b/src/SB/Game/zEntPlayerBungeeState.cpp index 2353d7dd8..9968048f8 100644 --- a/src/SB/Game/zEntPlayerBungeeState.cpp +++ b/src/SB/Game/zEntPlayerBungeeState.cpp @@ -26,7 +26,7 @@ #include "zLightning.h" #include "zScene.h" -#include +#include #include // FIXME: remove this when no longer needed for float data order diff --git a/src/SB/Game/zFX.cpp b/src/SB/Game/zFX.cpp index 9263fafce..d6b0d4c8a 100644 --- a/src/SB/Game/zFX.cpp +++ b/src/SB/Game/zFX.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include extern xFXRing sPatrickStunRing[3]; extern xFXRing sPorterRing[2]; diff --git a/src/SB/Game/zMain.cpp b/src/SB/Game/zMain.cpp index 5d9efb3ca..598bb930d 100644 --- a/src/SB/Game/zMain.cpp +++ b/src/SB/Game/zMain.cpp @@ -2,7 +2,7 @@ #include "zGlobals.h" #include "zMain.h" -#include +#include #include #include "iSystem.h" diff --git a/src/SB/Game/zParPTank.cpp b/src/SB/Game/zParPTank.cpp index dc537a55f..9a131a508 100644 --- a/src/SB/Game/zParPTank.cpp +++ b/src/SB/Game/zParPTank.cpp @@ -1,6 +1,6 @@ #include "zParPTank.h" -#include +#include #include #include @@ -65,8 +65,7 @@ static float sSteamAnimTime; const RwV2d sparkle_size = { 0.3f, 0.3f }; -static void zParPTankSparkleCreate(zParPTank* zp, U32 max_particles, - zParPTankUpdateCallback update) +static void zParPTankSparkleCreate(zParPTank* zp, U32 max_particles, zParPTankUpdateCallback update) { zp->num_particles = 0; zp->max_particles = max_particles; @@ -228,8 +227,7 @@ void zParPTankSpawnSparkles(xVec3* pos, U32 count) const RwRGBA bubble_color = { 0x80, 0x80, 0x80, 0xFF }; // Equivalent, float scheduling -static void zParPTankBubbleCreate(zParPTank* zp, U32 max_particles, - zParPTankUpdateCallback update) +static void zParPTankBubbleCreate(zParPTank* zp, U32 max_particles, zParPTankUpdateCallback update) { zp->num_particles = 0; zp->max_particles = max_particles; @@ -616,8 +614,7 @@ void zParPTankSpawnSnow(xVec3* pos, xVec3* vel, U32 count) const RwV2d steam_size = { 0.4f, 0.4f }; -static void zParPTankSteamCreate(zParPTank* zp, U32 max_particles, - zParPTankUpdateCallback update) +static void zParPTankSteamCreate(zParPTank* zp, U32 max_particles, zParPTankUpdateCallback update) { zp->num_particles = 0; zp->max_particles = max_particles; diff --git a/src/SB/Game/zUI.cpp b/src/SB/Game/zUI.cpp index 35178ac91..934195a30 100644 --- a/src/SB/Game/zUI.cpp +++ b/src/SB/Game/zUI.cpp @@ -20,7 +20,7 @@ #include "iMath.h" -#include +#include #include #include @@ -1358,8 +1358,7 @@ static zUIFont* findUIFont(zScene* zsc, U32 id) return ui; } -S32 zUIPortalEventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, - xBase* toParamWidget) +S32 zUIPortalEventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, xBase* toParamWidget) { S32 result; diff --git a/src/SB/Game/zVar.cpp b/src/SB/Game/zVar.cpp index 68a7a5619..2de635362 100644 --- a/src/SB/Game/zVar.cpp +++ b/src/SB/Game/zVar.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "iTime.h" From 510456afd9cb37029f1490329a8a799e0cf4bc22 Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Sat, 24 May 2025 20:24:59 -0400 Subject: [PATCH 05/19] Finished adding in the last files for the SDK. All files are added. --- config/GQPE78/symbols.txt | 2 +- configure.py | 125 +- include/dolphin/dvd.h | 22 +- include/dolphin/gx/GXEnum.h | 1557 ++++++++++++---------- include/dolphin/gx/GXFrameBuffer.h | 4 +- include/dolphin/gx/GXGeometry.h | 9 +- include/dolphin/gx/GXManage.h | 1 + include/dolphin/gx/GXTexture.h | 6 +- include/dolphin/os/OSFont.h | 8 + include/dolphin/os/OSRtc.h | 25 +- include/fake_tgmath.h | 66 + libs/dolphin/OdemuExi2/DebuggerDriver.c | 448 +++++++ libs/dolphin/amcstubs/AmcExi2Stubs.c | 29 + libs/dolphin/ax/AXCL.c | 2 +- libs/dolphin/ax/AXOut.c | 4 - libs/dolphin/ax/AXVPB.c | 20 +- libs/dolphin/base/PPCArch.c | 191 +-- libs/dolphin/dvd/dvd.c | 45 +- libs/dolphin/dvd/dvdFatal.c | 95 -- libs/dolphin/dvd/dvderror.c | 23 +- libs/dolphin/dvd/dvdfs.c | 200 +-- libs/dolphin/dvd/dvdlow.c | 40 +- libs/dolphin/dvd/dvdqueue.c | 124 +- libs/dolphin/exi/EXIBios.c | 179 +-- libs/dolphin/exi/EXIUart.c | 14 +- libs/dolphin/gx/GXAttr.c | 622 +++++++++ libs/dolphin/gx/GXBump.c | 207 +++ libs/dolphin/gx/GXDisplayList.c | 29 + libs/dolphin/gx/GXDraw.c | 571 ++++++++ libs/dolphin/gx/GXFifo.c | 426 ++++++ libs/dolphin/gx/GXFrameBuf.c | 591 ++++++++ libs/dolphin/gx/GXGeometry.c | 192 +++ libs/dolphin/gx/GXInit.c | 562 ++++++++ libs/dolphin/gx/GXLight.c | 457 +++++++ libs/dolphin/gx/GXMisc.c | 346 +++++ libs/dolphin/gx/GXPerf.c | 364 +++++ libs/dolphin/gx/GXPixel.c | 321 +++++ libs/dolphin/gx/GXSave.c | 601 +++++++++ libs/dolphin/gx/GXStubs.c | 7 + libs/dolphin/gx/GXTev.c | 486 +++++++ libs/dolphin/gx/GXTexture.c | 856 ++++++++++++ libs/dolphin/gx/GXTransform.c | 495 +++++++ libs/dolphin/gx/GXVerifRAS.c | 943 +++++++++++++ libs/dolphin/gx/GXVerifXF.c | 1291 ++++++++++++++++++ libs/dolphin/gx/GXVerify.c | 399 ++++++ libs/dolphin/gx/GXVert.c | 110 ++ libs/dolphin/gx/__gx.h | 632 +++++++++ libs/dolphin/mtx/mtx.c | 96 ++ libs/dolphin/mtx/mtx44.c | 30 + libs/dolphin/mtx/mtx44vec.c | 284 +++- libs/dolphin/mtx/mtxstack.c | 108 ++ libs/dolphin/mtx/mtxvec.c | 204 +++ libs/dolphin/mtx/psmtx.c | 336 +++++ libs/dolphin/mtx/quat.c | 486 +++++++ libs/dolphin/mtx/vec.c | 506 ++++--- libs/dolphin/odenotstub/odenotstub.c | 9 + libs/dolphin/os/OSAlarm.c | 60 +- libs/dolphin/os/OSAlloc.c | 86 +- libs/dolphin/os/OSArena.c | 42 +- libs/dolphin/os/OSCache.c | 344 ++--- libs/dolphin/os/OSContext.c | 353 ++--- libs/dolphin/os/OSError.c | 372 +++--- libs/dolphin/os/OSFont.c | 752 ++++++++++- libs/dolphin/os/OSInterrupt.c | 670 +++++----- libs/dolphin/os/OSLink.c | 554 +------- libs/dolphin/os/OSMemory.c | 184 ++- libs/dolphin/os/OSMutex.c | 258 +--- libs/dolphin/os/OSReset.c | 262 ++-- libs/dolphin/os/OSResetSW.c | 14 +- libs/dolphin/os/OSRtc.c | 578 ++++---- libs/dolphin/os/OSThread.c | 872 ++++++------ libs/dolphin/os/OSTime.c | 177 +-- libs/dolphin/os/__os.h | 133 ++ libs/dolphin/os/init/__ppc_eabi_init.cpp | 24 +- libs/dolphin/pad/Padclamp.c | 67 +- libs/dolphin/upnp/UPnP.c | 0 libs/dolphin/upnp/UPnPHttp.c | 0 libs/dolphin/upnp/UPnPHttpd.c | 0 libs/dolphin/upnp/UPnPHttpdResponse.c | 0 libs/dolphin/upnp/UPnPSsdp.c | 0 libs/dolphin/upnp/UPnPUri.c | 0 libs/dolphin/upnp/UPnPUuid.c | 0 82 files changed, 16851 insertions(+), 4757 deletions(-) create mode 100644 include/fake_tgmath.h create mode 100644 libs/dolphin/amcstubs/AmcExi2Stubs.c create mode 100644 libs/dolphin/gx/GXSave.c create mode 100644 libs/dolphin/gx/GXStubs.c create mode 100644 libs/dolphin/gx/GXVerifRAS.c create mode 100644 libs/dolphin/gx/GXVerifXF.c create mode 100644 libs/dolphin/gx/GXVerify.c create mode 100644 libs/dolphin/gx/GXVert.c create mode 100644 libs/dolphin/gx/__gx.h create mode 100644 libs/dolphin/mtx/mtxstack.c create mode 100644 libs/dolphin/mtx/psmtx.c create mode 100644 libs/dolphin/os/__os.h delete mode 100644 libs/dolphin/upnp/UPnP.c delete mode 100644 libs/dolphin/upnp/UPnPHttp.c delete mode 100644 libs/dolphin/upnp/UPnPHttpd.c delete mode 100644 libs/dolphin/upnp/UPnPHttpdResponse.c delete mode 100644 libs/dolphin/upnp/UPnPSsdp.c delete mode 100644 libs/dolphin/upnp/UPnPUri.c delete mode 100644 libs/dolphin/upnp/UPnPUuid.c diff --git a/config/GQPE78/symbols.txt b/config/GQPE78/symbols.txt index 4dcb07112..e039ef79f 100644 --- a/config/GQPE78/symbols.txt +++ b/config/GQPE78/symbols.txt @@ -11990,7 +11990,7 @@ axDspSlave = .data:0x802B2000; // type:object size:0x1EC0 scope:global ...data.0 = .data:0x802B3EC0; // type:label scope:local @1 = .data:0x802B3EC0; // type:object size:0x46 scope:local data:string ResetFunctionInfo = .data:0x802B3F08; // type:object size:0x10 scope:local -CardData = .data:0x802B3F20; // type:object size:0x160 scope:local +CardData = .data:0x802B3F20; // type:object size:0x160 scope:local align:32 SectorSizeTable = .data:0x802B4080; // type:object size:0x20 scope:local LatencyTable = .data:0x802B40A0; // type:object size:0x20 scope:local @9 = .data:0x802B40C0; // type:object size:0x18 scope:local data:string diff --git a/configure.py b/configure.py index 9350e48da..442cb5405 100644 --- a/configure.py +++ b/configure.py @@ -630,14 +630,13 @@ def MatchingFor(*versions): DolphinLib( "base", [ - # Needs a lot of Extended ASM work - # Object(NonMatching, "dolphin/base/PPCArch.c") + Object(Matching, "dolphin/base/PPCArch.c") ] ), DolphinLib( "card", [ - Object(NonMatching, "dolphin/card/CARDBios.c"), + Object(Matching, "dolphin/card/CARDBios.c"), Object(NonMatching, "dolphin/card/CARDUnlock.c"), Object(Matching, "dolphin/card/CARDRdwr.c"), Object(Matching, "dolphin/card/CARDBlock.c"), @@ -675,22 +674,13 @@ def MatchingFor(*versions): Object(NonMatching, "dolphin/dvd/dvdlow.c"), Object(NonMatching, "dolphin/dvd/dvdfs.c"), Object(NonMatching, "dolphin/dvd/dvd.c"), - Object(NonMatching, "dolphin/dvd/dvdqueue.c"), + Object(Matching, "dolphin/dvd/dvdqueue.c"), Object(NonMatching, "dolphin/dvd/dvderror.c"), Object(Matching, "dolphin/dvd/dvdidutils.c"), - Object(NonMatching, "dolphin/dvd/dvdFatal.c"), - Object(NonMatching, "dolphin/dvd/emu_level2/fstload.c"), + Object(Matching, "dolphin/dvd/dvdFatal.c"), + Object(Matching, "dolphin/dvd/emu_level2/fstload.c"), ], ), - DolphinLib( - "eth", - [ - Object(Matching, "dolphin/eth/eth.c"), - Object(Matching, "dolphin/eth/ethsec.c"), - Object(Matching, "dolphin/eth/md5.c"), - Object(Matching, "dolphin/eth/base64.c") - ] - ), DolphinLib( "exi", [ @@ -698,13 +688,6 @@ def MatchingFor(*versions): Object(NonMatching, "dolphin/exi/EXIUart.c") ] ), - DolphinLib( - "gd", - [ - Object(NonMatching, "dolphin/gd/GDBase.c"), - Object(NonMatching, "dolphin/gd/GDGeometry.c") - ] - ), DolphinLib( "gx", [ @@ -720,64 +703,22 @@ def MatchingFor(*versions): Object(NonMatching, "dolphin/gx/GXTev.c"), Object(NonMatching, "dolphin/gx/GXPixel.c"), Object(NonMatching, "dolphin/gx/GXDraw.c"), - Object(NonMatching, "dolphin/gx/GXDisplayList.c"), + Object(Matching, "dolphin/gx/GXDisplayList.c"), Object(NonMatching, "dolphin/gx/GXTransform.c"), - Object(NonMatching, "dolphin/gx/GXPerf.c") - ] - ), - DolphinLib( - "hio", - [ - Object(NonMatching, "dolphin/hio/hio.c") - ] - ), - DolphinLib( - "ip", - [ - Object(NonMatching, "dolphin/ip/IP.c"), - Object(NonMatching, "dolphin/ip/IPArp.c"), - Object(NonMatching, "dolphin/ip/IPIcmp.c"), - Object(NonMatching, "dolphin/ip/IPRoute.c"), - Object(NonMatching, "dolphin/ip/IPUdp.c"), - Object(NonMatching, "dolphin/ip/IPFrag.c"), - Object(NonMatching, "dolphin/ip/IPEther.c"), - Object(NonMatching, "dolphin/ip/IFFifo.c"), - Object(NonMatching, "dolphin/ip/IFRing.c"), - Object(NonMatching, "dolphin/ip/IPTcp.c"), - Object(NonMatching, "dolphin/ip/IPTcpOutput.c"), - Object(NonMatching, "dolphin/ip/IPTcpTimer.c"), - Object(NonMatching, "dolphin/ip/IPTcpUser.c"), - Object(NonMatching, "dolphin/ip/IPTcpTimeWait.c"), - Object(NonMatching, "dolphin/ip/IPDns.c"), - Object(NonMatching, "dolphin/ip/IPDhcp.c"), - Object(NonMatching, "dolphin/ip/IPZero.c"), - Object(NonMatching, "dolphin/ip/IPOpt.c"), - Object(NonMatching, "dolphin/ip/IPSocket.c"), - Object(NonMatching, "dolphin/ip/IPPPP.c"), - Object(NonMatching, "dolphin/ip/IPPPPoE.c"), - Object(NonMatching, "dolphin/ip/IPLcp.c"), - Object(NonMatching, "dolphin/ip/IPIpcp.c"), - Object(NonMatching, "dolphin/ip/IPPap.c"), - Object(NonMatching, "dolphin/ip/IPChap.c"), - Object(NonMatching, "dolphin/ip/IPIgmp.c"), - Object(NonMatching, "dolphin/ip/IPUuid.c") - ] - ), - DolphinLib( - "lg", # unofficial name - [ - Object(NonMatching, "dolphin/lg/allsrc.c") + Object(Matching, "dolphin/gx/GXPerf.c") ] ), + # DolphinLib( + # "lg", # unofficial name + # [ + # Object(NonMatching, "dolphin/lg/allsrc.c") + # ] + # ), DolphinLib( "mtx", [ Object(NonMatching, "dolphin/mtx/mtx.c"), - Object(NonMatching, "dolphin/mtx/mtxvec.c"), Object(NonMatching, "dolphin/mtx/mtx44.c"), - Object(Matching, "dolphin/mtx/mtx44vec.c"), - Object(Matching, "dolphin/mtx/vec.c"), - Object(NonMatching, "dolphin/mtx/quat.c"), ] ), DolphinLib( @@ -789,7 +730,7 @@ def MatchingFor(*versions): DolphinLib( "odenotstub", [ - Object(NonMatching, "dolphin/odenotstub/odenotstub.c") + Object(Matching, "dolphin/odenotstub/odenotstub.c") ] ), DolphinLib( @@ -797,25 +738,24 @@ def MatchingFor(*versions): [ Object(NonMatching, "dolphin/os/OS.c"), Object(NonMatching, "dolphin/os/OSAlarm.c"), - Object(NonMatching, "dolphin/os/OSAlloc.c"), - Object(NonMatching, "dolphin/os/OSArena.c"), + Object(Matching, "dolphin/os/OSAlloc.c"), + Object(Matching, "dolphin/os/OSArena.c"), Object(Matching, "dolphin/os/OSAudioSystem.c"), Object(NonMatching, "dolphin/os/OSCache.c"), - Object(NonMatching, "dolphin/os/OSContext.c"), + Object(Matching, "dolphin/os/OSContext.c"), Object(NonMatching, "dolphin/os/OSError.c"), Object(NonMatching, "dolphin/os/OSFont.c"), - Object(NonMatching, "dolphin/os/OSInterrupt.c"), - Object(NonMatching, "dolphin/os/OSLink.c"), - Object(NonMatching, "dolphin/os/OSMessage.c"), - Object(NonMatching, "dolphin/os/OSMemory.c"), - Object(NonMatching, "dolphin/os/OSMutex.c"), + Object(Matching, "dolphin/os/OSInterrupt.c"), + Object(Matching, "dolphin/os/OSLink.c"), + Object(Matching, "dolphin/os/OSMemory.c"), + Object(Matching, "dolphin/os/OSMutex.c"), Object(Matching, "dolphin/os/OSReboot.c"), Object(NonMatching, "dolphin/os/OSReset.c"), - Object(NonMatching, "dolphin/os/OSResetSW.c"), + Object(Matching, "dolphin/os/OSResetSW.c"), Object(NonMatching, "dolphin/os/OSRtc.c"), Object(NonMatching, "dolphin/os/OSThread.c"), Object(NonMatching, "dolphin/os/OSTime.c"), - Object(NonMatching, "dolphin/os/OSSync.c"), + Object(Matching, "dolphin/os/OSSync.c"), Object(NonMatching, "dolphin/os/init/__start.c"), Object(NonMatching, "dolphin/os/init/__ppc_eabi_init.cpp") ] @@ -834,31 +774,12 @@ def MatchingFor(*versions): Object(Matching, "dolphin/si/SISamplingRate.c"), ] ), - DolphinLib( - "upnp", - [ - Object(NonMatching, "dolphin/upnp/UPnP.c"), - Object(NonMatching, "dolphin/upnp/UPnPHttp.c"), - Object(NonMatching, "dolphin/upnp/UPnPSsdp.c"), - Object(NonMatching, "dolphin/upnp/UPnPUuid.c"), - Object(NonMatching, "dolphin/upnp/UPnPUri.c"), - Object(NonMatching, "dolphin/upnp/UPnPHttpd.c"), - Object(NonMatching, "dolphin/upnp/UPnPHttpdResponse.c") - ] - ), DolphinLib( "vi", [ Object(NonMatching, "dolphin/vi/vi.c"), ], ), - DolphinLib( - "thp", - [ - Object(Matching, "dolphin/thp/THPDec.c"), - Object(Matching, "dolphin/thp/THPAudio.c") - ] - ), mslLib( "Runtime.PPCEABI.H", [], diff --git a/include/dolphin/dvd.h b/include/dolphin/dvd.h index 0774f0459..b750eb142 100644 --- a/include/dolphin/dvd.h +++ b/include/dolphin/dvd.h @@ -2,8 +2,7 @@ #define _DOLPHIN_PUBLIC_DVD_H #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif #include @@ -11,6 +10,25 @@ extern "C" #include #include +// 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 + #ifdef __cplusplus } #endif diff --git a/include/dolphin/gx/GXEnum.h b/include/dolphin/gx/GXEnum.h index e69c621b7..f8d731ba1 100644 --- a/include/dolphin/gx/GXEnum.h +++ b/include/dolphin/gx/GXEnum.h @@ -15,886 +15,969 @@ typedef u8 GXBool; #define GX_ENABLE ((GXBool)1) #define GX_DISABLE ((GXBool)0) -typedef enum _GXProjectionType { - GX_PERSPECTIVE, - GX_ORTHOGRAPHIC, +typedef enum _GXCopyMode +{ + GX_COPY_PROGRESSIVE = 0, + GX_COPY_INTLC_EVEN = 2, + GX_COPY_INTLC_ODD = 3, +} GXCopyMode; + +typedef enum _GXAlphaReadMode +{ + GX_READ_00, + GX_READ_FF, + GX_READ_NONE, +} GXAlphaReadMode; + +typedef enum _GXProjectionType +{ + GX_PERSPECTIVE, + GX_ORTHOGRAPHIC, } GXProjectionType; -typedef enum _GXCompare { - GX_NEVER, - GX_LESS, - GX_EQUAL, - GX_LEQUAL, - GX_GREATER, - GX_NEQUAL, - GX_GEQUAL, - GX_ALWAYS, +typedef enum _GXCompare +{ + GX_NEVER, + GX_LESS, + GX_EQUAL, + GX_LEQUAL, + GX_GREATER, + GX_NEQUAL, + GX_GEQUAL, + GX_ALWAYS, } GXCompare; -typedef enum _GXAlphaOp { - GX_AOP_AND, - GX_AOP_OR, - GX_AOP_XOR, - GX_AOP_XNOR, - GX_MAX_ALPHAOP, +typedef enum _GXAlphaOp +{ + GX_AOP_AND, + GX_AOP_OR, + GX_AOP_XOR, + GX_AOP_XNOR, + GX_MAX_ALPHAOP, } GXAlphaOp; -typedef enum _GXFBClamp { - GX_CLAMP_NONE, - GX_CLAMP_TOP, - GX_CLAMP_BOTTOM, +typedef enum _GXFBClamp +{ + GX_CLAMP_NONE, + GX_CLAMP_TOP, + GX_CLAMP_BOTTOM, } GXFBClamp; -typedef enum _GXZFmt16 { - GX_ZC_LINEAR, - GX_ZC_NEAR, - GX_ZC_MID, - GX_ZC_FAR, +typedef enum _GXZFmt16 +{ + GX_ZC_LINEAR, + GX_ZC_NEAR, + GX_ZC_MID, + GX_ZC_FAR, } GXZFmt16; -typedef enum _GXGamma { - GX_GM_1_0, - GX_GM_1_7, - GX_GM_2_2, +typedef enum _GXGamma +{ + GX_GM_1_0, + GX_GM_1_7, + GX_GM_2_2, } GXGamma; -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, +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; -typedef enum _GXPrimitive { - GX_QUADS = 0x80, - GX_TRIANGLES = 0x90, - GX_TRIANGLESTRIP = 0x98, - GX_TRIANGLEFAN = 0xA0, - GX_LINES = 0xA8, - GX_LINESTRIP = 0xB0, - GX_POINTS = 0xB8, +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 _GXVtxFmt { - GX_VTXFMT0, - GX_VTXFMT1, - GX_VTXFMT2, - GX_VTXFMT3, - GX_VTXFMT4, - GX_VTXFMT5, - GX_VTXFMT6, - GX_VTXFMT7, - GX_MAX_VTXFMT, +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 _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, +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; #define GX_MAX_VTXDESCLIST_SZ (GX_VA_MAX_ATTR + 1) -typedef enum _GXAttrType { - GX_NONE, - GX_DIRECT, - GX_INDEX8, - GX_INDEX16, +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, +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, +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, +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, +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, +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, +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, +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, +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, +typedef enum _GXTevMode +{ + GX_MODULATE, + GX_DECAL, + GX_BLEND, + GX_REPLACE, + GX_PASSCLR, } GXTevMode; -typedef enum _GXTexMtxType { - GX_MTX3x4, - GX_MTX2x4, +typedef enum _GXTexMtxType +{ + GX_MTX3x4, + GX_MTX2x4, } GXTexMtxType; -typedef enum _GXTexGenType { - 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, +typedef enum _GXTexGenType +{ + 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 _GXPosNrmMtx { - 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, +typedef enum _GXPosNrmMtx +{ + 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, - 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, +typedef enum _GXTexMtx +{ + 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, +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, - GX_MAX_TEXGENSRC, +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, + GX_MAX_TEXGENSRC, } GXTexGenSrc; -typedef enum _GXBlendMode { - GX_BM_NONE, - GX_BM_BLEND, - GX_BM_LOGIC, - GX_BM_SUBTRACT, - GX_MAX_BLENDMODE, +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, +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, +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, +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, +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, - 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, +typedef enum _GXPTTexMtx +{ + 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 _GXTevRegID { - GX_TEVPREV, - GX_TEVREG0, - GX_TEVREG1, - GX_TEVREG2, - GX_MAX_TEVREG, +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, +typedef enum _GXDiffuseFn +{ + GX_DF_NONE, + GX_DF_SIGN, + GX_DF_CLAMP, } GXDiffuseFn; -typedef enum _GXColorSrc { - GX_SRC_REG, - GX_SRC_VTX, +typedef enum _GXColorSrc +{ + GX_SRC_REG, + GX_SRC_VTX, } GXColorSrc; -typedef enum _GXAttnFn { - GX_AF_SPEC, - GX_AF_SPOT, - GX_AF_NONE, +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, +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, +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, +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, +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, +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, +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, +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 = GX_FOG_PERSP_LIN, - GX_FOG_EXP = GX_FOG_PERSP_EXP, - GX_FOG_EXP2 = GX_FOG_PERSP_EXP2, - GX_FOG_REVEXP = GX_FOG_PERSP_REVEXP, - GX_FOG_REVEXP2 = GX_FOG_PERSP_REVEXP2, +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 = GX_FOG_PERSP_LIN, + GX_FOG_EXP = GX_FOG_PERSP_EXP, + GX_FOG_EXP2 = GX_FOG_PERSP_EXP2, + GX_FOG_REVEXP = GX_FOG_PERSP_REVEXP, + GX_FOG_REVEXP2 = GX_FOG_PERSP_REVEXP2, } GXFogType; -typedef enum _GXTevColorArg { - GX_CC_CPREV, - GX_CC_APREV, - GX_CC_C0, - GX_CC_A0, - GX_CC_C1, - GX_CC_A1, - GX_CC_C2, - GX_CC_A2, - GX_CC_TEXC, - GX_CC_TEXA, - GX_CC_RASC, - GX_CC_RASA, - GX_CC_ONE, - GX_CC_HALF, - GX_CC_KONST, - GX_CC_ZERO, +typedef enum _GXTevColorArg +{ + GX_CC_CPREV, + GX_CC_APREV, + GX_CC_C0, + GX_CC_A0, + GX_CC_C1, + GX_CC_A1, + GX_CC_C2, + GX_CC_A2, + GX_CC_TEXC, + GX_CC_TEXA, + GX_CC_RASC, + GX_CC_RASA, + GX_CC_ONE, + GX_CC_HALF, + GX_CC_KONST, + GX_CC_ZERO, } GXTevColorArg; -typedef enum _GXTevAlphaArg { - GX_CA_APREV, - GX_CA_A0, - GX_CA_A1, - GX_CA_A2, - GX_CA_TEXA, - GX_CA_RASA, - GX_CA_KONST, - GX_CA_ZERO, +typedef enum _GXTevAlphaArg +{ + GX_CA_APREV, + GX_CA_A0, + GX_CA_A1, + GX_CA_A2, + GX_CA_TEXA, + GX_CA_RASA, + GX_CA_KONST, + GX_CA_ZERO, } 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, +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, +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, +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_8_8 = 0x00, - GX_TEV_KCSEL_7_8 = 0x01, - GX_TEV_KCSEL_6_8 = 0x02, - GX_TEV_KCSEL_5_8 = 0x03, - GX_TEV_KCSEL_4_8 = 0x04, - GX_TEV_KCSEL_3_8 = 0x05, - GX_TEV_KCSEL_2_8 = 0x06, - GX_TEV_KCSEL_1_8 = 0x07, - GX_TEV_KCSEL_1 = GX_TEV_KCSEL_8_8, - GX_TEV_KCSEL_3_4 = GX_TEV_KCSEL_6_8, - GX_TEV_KCSEL_1_2 = GX_TEV_KCSEL_4_8, - GX_TEV_KCSEL_1_4 = GX_TEV_KCSEL_2_8, - 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, +typedef enum _GXTevKColorSel +{ + GX_TEV_KCSEL_8_8 = 0x00, + GX_TEV_KCSEL_7_8 = 0x01, + GX_TEV_KCSEL_6_8 = 0x02, + GX_TEV_KCSEL_5_8 = 0x03, + GX_TEV_KCSEL_4_8 = 0x04, + GX_TEV_KCSEL_3_8 = 0x05, + GX_TEV_KCSEL_2_8 = 0x06, + GX_TEV_KCSEL_1_8 = 0x07, + GX_TEV_KCSEL_1 = GX_TEV_KCSEL_8_8, + GX_TEV_KCSEL_3_4 = GX_TEV_KCSEL_6_8, + GX_TEV_KCSEL_1_2 = GX_TEV_KCSEL_4_8, + GX_TEV_KCSEL_1_4 = GX_TEV_KCSEL_2_8, + 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_8_8 = 0x00, - GX_TEV_KASEL_7_8 = 0x01, - GX_TEV_KASEL_6_8 = 0x02, - GX_TEV_KASEL_5_8 = 0x03, - GX_TEV_KASEL_4_8 = 0x04, - GX_TEV_KASEL_3_8 = 0x05, - GX_TEV_KASEL_2_8 = 0x06, - GX_TEV_KASEL_1_8 = 0x07, - GX_TEV_KASEL_1 = GX_TEV_KASEL_8_8, - GX_TEV_KASEL_3_4 = GX_TEV_KASEL_6_8, - GX_TEV_KASEL_1_2 = GX_TEV_KASEL_4_8, - GX_TEV_KASEL_1_4 = GX_TEV_KASEL_2_8, - 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, +typedef enum _GXTevKAlphaSel +{ + GX_TEV_KASEL_8_8 = 0x00, + GX_TEV_KASEL_7_8 = 0x01, + GX_TEV_KASEL_6_8 = 0x02, + GX_TEV_KASEL_5_8 = 0x03, + GX_TEV_KASEL_4_8 = 0x04, + GX_TEV_KASEL_3_8 = 0x05, + GX_TEV_KASEL_2_8 = 0x06, + GX_TEV_KASEL_1_8 = 0x07, + GX_TEV_KASEL_1 = GX_TEV_KASEL_8_8, + GX_TEV_KASEL_3_4 = GX_TEV_KASEL_6_8, + GX_TEV_KASEL_1_2 = GX_TEV_KASEL_4_8, + GX_TEV_KASEL_1_4 = GX_TEV_KASEL_2_8, + 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, +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, +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, +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, +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, +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, +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, +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, +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, +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 _GXClipMode { - GX_CLIP_ENABLE = 0, - GX_CLIP_DISABLE = 1, +typedef enum _GXClipMode +{ + GX_CLIP_ENABLE = 0, + GX_CLIP_DISABLE = 1, } GXClipMode; -typedef enum _GXTlut { - GX_TLUT0 = 0, - GX_TLUT1 = 1, - GX_TLUT2 = 2, - GX_TLUT3 = 3, - GX_TLUT4 = 4, - GX_TLUT5 = 5, - GX_TLUT6 = 6, - GX_TLUT7 = 7, - GX_TLUT8 = 8, - GX_TLUT9 = 9, - GX_TLUT10 = 10, - GX_TLUT11 = 11, - GX_TLUT12 = 12, - GX_TLUT13 = 13, - GX_TLUT14 = 14, - GX_TLUT15 = 15, - GX_BIGTLUT0 = 16, - GX_BIGTLUT1 = 17, - GX_BIGTLUT2 = 18, - GX_BIGTLUT3 = 19, +typedef enum _GXTlut +{ + GX_TLUT0 = 0, + GX_TLUT1 = 1, + GX_TLUT2 = 2, + GX_TLUT3 = 3, + GX_TLUT4 = 4, + GX_TLUT5 = 5, + GX_TLUT6 = 6, + GX_TLUT7 = 7, + GX_TLUT8 = 8, + GX_TLUT9 = 9, + GX_TLUT10 = 10, + GX_TLUT11 = 11, + GX_TLUT12 = 12, + GX_TLUT13 = 13, + GX_TLUT14 = 14, + GX_TLUT15 = 15, + GX_BIGTLUT0 = 16, + GX_BIGTLUT1 = 17, + GX_BIGTLUT2 = 18, + GX_BIGTLUT3 = 19, } GXTlut; -typedef enum _GXTlutFmt { - GX_TL_IA8, - GX_TL_RGB565, - GX_TL_RGB5A3, - GX_MAX_TLUTFMT, +typedef enum _GXTlutFmt +{ + GX_TL_IA8, + GX_TL_RGB565, + GX_TL_RGB5A3, + GX_MAX_TLUTFMT, } GXTlutFmt; -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, +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; -typedef enum _GXMiscToken { - GX_MT_NULL = 0, - GX_MT_XF_FLUSH = 1, - GX_MT_DL_SAVE_CONTEXT = 2, - GX_MT_ABORT_WAIT_COPYOUT = 3, +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; -typedef enum _GXTexCacheSize { - GX_TEXCACHE_32K, - GX_TEXCACHE_128K, - GX_TEXCACHE_512K, - GX_TEXCACHE_NONE +typedef enum _GXTexCacheSize +{ + GX_TEXCACHE_32K, + GX_TEXCACHE_128K, + GX_TEXCACHE_512K, + GX_TEXCACHE_NONE } GXTexCacheSize; -typedef enum _GXPerf0 { - 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, - 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, - 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, - GX_PERF0_NONE +typedef enum _GXPerf0 +{ + 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, + 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, + 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, + GX_PERF0_NONE } GXPerf0; -typedef enum _GXPerf1 { - 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, - 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, - GX_PERF1_CALL_REQ, - GX_PERF1_VC_MISS_REQ, - GX_PERF1_CP_ALL_REQ, - - GX_PERF1_CLOCKS, - GX_PERF1_NONE +typedef enum _GXPerf1 +{ + 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, + 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, + GX_PERF1_CALL_REQ, + GX_PERF1_VC_MISS_REQ, + GX_PERF1_CP_ALL_REQ, + + GX_PERF1_CLOCKS, + GX_PERF1_NONE } GXPerf1; -typedef enum _GXVCachePerf { - GX_VC_POS, - GX_VC_NRM, - GX_VC_CLR0, - GX_VC_CLR1, - GX_VC_TEX0, - GX_VC_TEX1, - GX_VC_TEX2, - GX_VC_TEX3, - GX_VC_TEX4, - GX_VC_TEX5, - GX_VC_TEX6, - GX_VC_TEX7, - GX_VC_ALL = 0xf +typedef enum _GXVCachePerf +{ + GX_VC_POS, + GX_VC_NRM, + GX_VC_CLR0, + GX_VC_CLR1, + GX_VC_TEX0, + GX_VC_TEX1, + GX_VC_TEX2, + GX_VC_TEX3, + GX_VC_TEX4, + GX_VC_TEX5, + GX_VC_TEX6, + GX_VC_TEX7, + GX_VC_ALL = 0xf } GXVCachePerf; diff --git a/include/dolphin/gx/GXFrameBuffer.h b/include/dolphin/gx/GXFrameBuffer.h index 2579fc00f..91c9f7921 100644 --- a/include/dolphin/gx/GXFrameBuffer.h +++ b/include/dolphin/gx/GXFrameBuffer.h @@ -43,7 +43,7 @@ extern GXRenderModeObj GXEurgb60Hz480IntAa; #define GX_MAX_Z24 0x00FFFFFF void GXSetCopyClear(GXColor clear_clr, u32 clear_z); -void GXAdjustForOverscan(GXRenderModeObj* rmin, GXRenderModeObj* rmout, u16 hor, u16 ver); +void GXAdjustForOverscan(const GXRenderModeObj* rmin, GXRenderModeObj* rmout, u16 hor, u16 ver); void GXCopyDisp(void* dest, GXBool clear); void GXSetDispCopyGamma(GXGamma gamma); void GXSetDispCopySrc(u16 left, u16 top, u16 wd, u16 ht); @@ -51,7 +51,7 @@ void GXSetDispCopyDst(u16 wd, u16 ht); f32 GXGetYScaleFactor(u16 efbHeight, u16 xfbHeight); u32 GXSetDispCopyYScale(f32 vscale); u16 GXGetNumXfbLines(u16 efbHeight, f32 yScale); -void GXSetCopyFilter(GXBool aa, u8 sample_pattern[12][2], GXBool vf, u8 vfilter[7]); +void GXSetCopyFilter(GXBool aa, const u8 sample_pattern[12][2], GXBool vf, const u8 vfilter[7]); void GXSetPixelFmt(GXPixelFmt pix_fmt, GXZFmt16 z_fmt); void GXSetTexCopySrc(u16 left, u16 top, u16 wd, u16 ht); void GXSetTexCopyDst(u16 wd, u16 ht, GXTexFmt fmt, GXBool mipmap); diff --git a/include/dolphin/gx/GXGeometry.h b/include/dolphin/gx/GXGeometry.h index 870e7d2e9..bfafcdc03 100644 --- a/include/dolphin/gx/GXGeometry.h +++ b/include/dolphin/gx/GXGeometry.h @@ -8,7 +8,7 @@ extern "C" { #endif void GXSetVtxDesc(GXAttr attr, GXAttrType type); -void GXSetVtxDescv(GXVtxDescList* list); +void GXSetVtxDescv(const GXVtxDescList* list); void GXClearVtxDesc(void); void GXSetVtxAttrFmt(GXVtxFmt vtxfmt, GXAttr attr, GXCompCnt cnt, GXCompType type, u8 frac); void GXSetNumTexGens(u8 nTexGens); @@ -18,12 +18,13 @@ void GXSetTexCoordGen2(GXTexCoordID dst_coord, GXTexGenType func, GXTexGenSrc sr void GXSetLineWidth(u8 width, GXTexOffset texOffsets); void GXSetPointSize(u8 pointSize, GXTexOffset texOffsets); void GXEnableTexOffsets(GXTexCoordID coord, GXBool line_enable, GXBool point_enable); -void GXSetArray(GXAttr attr, const void* data, u8 stride); +void GXSetArray(GXAttr attr, void* data, u8 stride); void GXInvalidateVtxCache(void); 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); + GXTexGenSrc src_param, u32 mtx) +{ + GXSetTexCoordGen2(dst_coord, func, src_param, mtx, GX_FALSE, GX_PTIDENTITY); } #ifdef __cplusplus diff --git a/include/dolphin/gx/GXManage.h b/include/dolphin/gx/GXManage.h index ab3a72c84..019647578 100644 --- a/include/dolphin/gx/GXManage.h +++ b/include/dolphin/gx/GXManage.h @@ -7,6 +7,7 @@ extern "C" { #endif +typedef void (*GXDrawSyncCallback)(u16 token); typedef void (*GXDrawDoneCallback)(void); GXFifoObj* GXInit(void* base, u32 size); diff --git a/include/dolphin/gx/GXTexture.h b/include/dolphin/gx/GXTexture.h index 76bae19c1..a91670306 100644 --- a/include/dolphin/gx/GXTexture.h +++ b/include/dolphin/gx/GXTexture.h @@ -8,9 +8,10 @@ extern "C" { #endif -typedef GXTexRegion* (*GXTexRegionCallback)(const GXTexObj* obj, GXTexMapID id); +typedef GXTexRegion* (*GXTexRegionCallback)(GXTexObj* obj, GXTexMapID id); +typedef GXTlutRegion* (*GXTlutRegionCallback)(u32 idx); -void GXInitTexObj(GXTexObj* obj, void* image_ptr, u16 width, u16 height, GXTexFmt format, +void GXInitTexObj(GXTexObj* obj, const void* image_ptr, u16 width, u16 height, GXTexFmt format, GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, GXBool mipmap); void GXInitTexObjCI(GXTexObj* obj, const void* data, u16 width, u16 height, GXCITexFmt format, GXTexWrapMode wrapS, GXTexWrapMode wrapT, GXBool mipmap, u32 tlut); @@ -28,6 +29,7 @@ void GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 ss, u16 t void GXInitTexCacheRegion(GXTexRegion* region, GXBool is_32b_mipmap, u32 tmem_even, GXTexCacheSize size_even, u32 tmem_odd, GXTexCacheSize size_odd); GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback callback); +GXTlutRegionCallback GXSetTlutRegionCallback(GXTlutRegionCallback f); void GXInvalidateTexRegion(const GXTexRegion* region); #ifdef __cplusplus diff --git a/include/dolphin/os/OSFont.h b/include/dolphin/os/OSFont.h index ba312bde0..1c9d7d9b2 100644 --- a/include/dolphin/os/OSFont.h +++ b/include/dolphin/os/OSFont.h @@ -7,6 +7,14 @@ extern "C" { #endif +#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 { u16 fontType; // _00 diff --git a/include/dolphin/os/OSRtc.h b/include/dolphin/os/OSRtc.h index ed3c3dd81..0ae3f40d2 100644 --- a/include/dolphin/os/OSRtc.h +++ b/include/dolphin/os/OSRtc.h @@ -8,20 +8,21 @@ extern "C" { #endif // make the assert happy -#define OS_SOUND_MODE_MONO 0 -#define OS_SOUND_MODE_STEREO 1 +//#define OS_SOUND_MODE_MONO 0 +//#define OS_SOUND_MODE_STEREO 1 // make the asserts happy #define OS_VIDEO_MODE_NTSC 0 #define OS_VIDEO_MODE_MPAL 2 -#define OS_PROGRESSIVE_MODE_OFF 0 -#define OS_PROGRESSIVE_MODE_ON 1 +// #define OS_PROGRESSIVE_MODE_OFF 0 +// #define OS_PROGRESSIVE_MODE_ON 1 -#define OS_EURGB60_OFF 0 -#define OS_EURGB60_ON 1 +// #define OS_EURGB60_OFF 0 +// #define OS_EURGB60_ON 1 -typedef struct OSSram { +typedef struct OSSram +{ u16 checkSum; u16 checkSumInv; u32 ead0; @@ -33,7 +34,8 @@ typedef struct OSSram { u8 flags; } OSSram; -typedef struct OSSramEx { +typedef struct OSSramEx +{ u8 flashID[2][12]; u32 wirelessKeyboardID; u16 wirelessPadID[4]; @@ -46,8 +48,9 @@ typedef struct OSSramEx { #define SRAM_SIZE (sizeof(OSSram) + sizeof(OSSramEx)) -typedef struct SramControl { - u8 sram[SRAM_SIZE]; // dummy for OSSram + OSSramEx +typedef struct SramControl +{ + u8 sram[SRAM_SIZE]; // dummy for OSSram + OSSramEx u32 offset; BOOL enabled; BOOL locked; @@ -57,7 +60,7 @@ typedef struct SramControl { u32 OSGetSoundMode(void); void OSSetSoundMode(u32 mode); -u32 OSGetVideoMode(void); +u32 OSGetVideoMode(); void OSSetVideoMode(u32 mode); u8 OSGetLanguage(void); void OSSetLanguage(u8 language); diff --git a/include/fake_tgmath.h b/include/fake_tgmath.h new file mode 100644 index 000000000..41a982106 --- /dev/null +++ b/include/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/libs/dolphin/OdemuExi2/DebuggerDriver.c b/libs/dolphin/OdemuExi2/DebuggerDriver.c index e69de29bb..c2c5e7c3d 100644 --- a/libs/dolphin/OdemuExi2/DebuggerDriver.c +++ b/libs/dolphin/OdemuExi2/DebuggerDriver.c @@ -0,0 +1,448 @@ +#include "types.h" +#include "Dolphin/os.h" +#include "Dolphin/hw_regs.h" + +typedef void (*MTRCallbackType)(int); + +static MTRCallbackType MTRCallback; +static void (*DBGCallback)(u32, OSContext*); + +static u32 SendMailData; +static s32 RecvDataLeng; + +static u8* pEXIInputFlag; +static u8 EXIInputFlag; + +static u8 SendCount = 0x80; + +#define IS_TRUE(x) ((x) != FALSE) +#define IS_FALSE(x) !IS_TRUE(x) +#define ROUND_UP(x, align) (((x) + (align)-1) & (-(align))) + +void DBGEXIInit() +{ + __OSMaskInterrupts(0x18000); + __EXIRegs[10] = 0; +} + +/* + * --INFO-- + * Address: ........ + * Size: 000028 + */ + +static u32 DBGEXISelect(u32 v) +{ + u32 regs = __EXIRegs[10]; + regs &= 0x405; + regs |= 0x80 | (v << 4); + __EXIRegs[10] = regs; + return TRUE; +} + +/* + * --INFO-- + * Address: ........ + * Size: 00001C + */ +BOOL DBGEXIDeselect(void) +{ + __EXIRegs[10] &= 0x405; + return TRUE; +} + +/* + * --INFO-- + * Address: ........ + * Size: 00001C + */ +static BOOL DBGEXISync() +{ + while (__EXIRegs[13] & 1) + ; + + return TRUE; +} + +/* + * --INFO-- + * Address: 802214D8 + * Size: 000298 + */ +static BOOL DBGEXIImm(void* buffer, s32 bytecounter, u32 write) +{ + u8* tempPointer; + u32 writeOutValue; + int i; + + if (write) + { + tempPointer = buffer; + writeOutValue = 0; + for (i = 0; i < bytecounter; i++) + { + u8* temp = ((u8*)buffer) + i; + writeOutValue |= *temp << ((3 - i) << 3); + } + __EXIRegs[14] = writeOutValue; + } + + __EXIRegs[13] = 1 | write << 2 | (bytecounter - 1) << 4; + DBGEXISync(); + + if (!write) + { + writeOutValue = __EXIRegs[14]; + tempPointer = buffer; + for (i = 0; i < bytecounter; i++) + { + *tempPointer++ = writeOutValue >> ((3 - i) << 3); + } + } + + return TRUE; +} + +/* + * --INFO-- + * Address: ........ + * Size: 00008C + */ +static BOOL DBGWriteMailbox(u32 p1) +{ + BOOL total = FALSE; + u32 v; + + if (!DBGEXISelect(4)) + { + return FALSE; + } + + v = (p1 & 0x1fffffff) | (0xC0000000); + total |= IS_FALSE(DBGEXIImm(&v, sizeof(v), 1)); + total |= IS_FALSE(DBGEXISync()); + total |= IS_FALSE(DBGEXIDeselect()); + + return IS_FALSE(total); +} + +/* + * --INFO-- + * Address: 80221770 + * Size: 0000AC + */ +static BOOL DBGReadMailbox(u32* p1) +{ + BOOL total = FALSE; + u32 v; + + if (!DBGEXISelect(4)) + { + return FALSE; + } + + v = 0x60000000; + total |= IS_FALSE(DBGEXIImm(&v, 2, 1)); + total |= IS_FALSE(DBGEXISync()); + + total |= IS_FALSE(DBGEXIImm(p1, 4, 0)); + total |= IS_FALSE(DBGEXISync()); + + total |= IS_FALSE(DBGEXIDeselect()); + + return IS_FALSE(total); +} + +/* + * --INFO-- + * Address: 8022181C + * Size: 0000DC + */ +static BOOL DBGRead(u32 count, u32* buffer, s32 param3) +{ + BOOL total = FALSE; + u32* buf_p = (u32*)buffer; + u32 v1; + u32 v; + + if (!DBGEXISelect(4)) + { + return FALSE; + } + + v1 = (count & 0x1fffc) << 8 | 0x20000000; + total |= IS_FALSE(DBGEXIImm(&v1, sizeof(v1), 1)); + total |= IS_FALSE(DBGEXISync()); + + while (param3) + { + total |= IS_FALSE(DBGEXIImm(&v, sizeof(v), 0)); + total |= IS_FALSE(DBGEXISync()); + + *buf_p++ = v; + + param3 -= 4; + if (param3 < 0) + { + param3 = 0; + } + } + + total |= IS_FALSE(DBGEXIDeselect()); + return IS_FALSE(total); +} + +/* + * --INFO-- + * Address: 802218F8 + * Size: 0000DC + */ +static BOOL DBGWrite(u32 count, void* buffer, s32 param3) +{ + BOOL total = FALSE; + u32* buf_p = (u32*)buffer; + u32 v1; + u32 v; + + if (!DBGEXISelect(4)) + { + return FALSE; + } + + v1 = (count & 0x1fffc) << 8 | 0xa0000000; + total |= IS_FALSE(DBGEXIImm(&v1, sizeof(v1), 1)); + total |= IS_FALSE(DBGEXISync()); + + while (param3 != 0) + { + v = *buf_p++; + + total |= IS_FALSE(DBGEXIImm(&v, sizeof(v), 1)); + total |= IS_FALSE(DBGEXISync()); + + param3 -= 4; + if (param3 < 0) + { + param3 = 0; + } + } + + total |= IS_FALSE(DBGEXIDeselect()); + return IS_FALSE(total); +} + +/* + * --INFO-- + * Address: 802219D4 + * Size: 0000AC + */ +static BOOL DBGReadStatus(u32* p1) +{ + BOOL total = FALSE; + u32 v; + + if (!DBGEXISelect(4)) + { + return FALSE; + } + + v = 1 << 30; + total |= IS_FALSE(DBGEXIImm((u8*)&v, 2, 1)); + total |= IS_FALSE(DBGEXISync()); + + total |= IS_FALSE(DBGEXIImm(p1, 4, 0)); + total |= IS_FALSE(DBGEXISync()); + + total |= IS_FALSE(DBGEXIDeselect()); + + return IS_FALSE(total); +} + +/* + * --INFO-- + * Address: 80221A80 + * Size: 00003C + */ +static void MWCallback(u32 a, OSContext* b) +{ + EXIInputFlag = TRUE; + if (MTRCallback) + { + MTRCallback(0); + } +} + +/* + * --INFO-- + * Address: 80221ABC + * Size: 000040 + */ +static void DBGHandler(s16 a, OSContext* b) +{ + *__PIRegs = 0x1000; + if (DBGCallback) + { + DBGCallback(a, b); + } +} + +/* + * --INFO-- + * Address: 80221AFC + * Size: 000078 + */ +void DBInitComm(u8** a, MTRCallbackType b) +{ + BOOL interrupts = OSDisableInterrupts(); + { + pEXIInputFlag = (u8*)EXIInputFlag; + pEXIInputFlag = &EXIInputFlag; + + *a = pEXIInputFlag; + + MTRCallback = b; + + DBGEXIInit(); + } + OSRestoreInterrupts(interrupts); +} + +/* + * --INFO-- + * Address: 80221B74 + * Size: 000054 + */ +void DBInitInterrupts(void) +{ + __OSMaskInterrupts(0x18000); + __OSMaskInterrupts(0x40); + DBGCallback = &MWCallback; + __OSSetInterruptHandler(0x19, DBGHandler); + __OSUnmaskInterrupts(0x40); +} + +/* + * --INFO-- + * Address: ........ + * Size: 000150 + */ +static void CheckMailBox(void) +{ + u32 v; + DBGReadStatus(&v); + if (v & 1) + { + DBGReadMailbox(&v); + v &= 0x1fffffff; + + if ((v & 0x1f000000) == 0x1f000000) + { + SendMailData = v; + RecvDataLeng = v & 0x7fff; + EXIInputFlag = 1; + } + } +} + +/* + * --INFO-- + * Address: 80221BC8 + * Size: 00009C + */ +u32 DBQueryData(void) +{ + BOOL interrupts; + + EXIInputFlag = 0; + if (!RecvDataLeng) + { + interrupts = OSDisableInterrupts(); + CheckMailBox(); + } + OSRestoreInterrupts(interrupts); + return RecvDataLeng; +} + +/* + * --INFO-- + * Address: 80221C64 + * Size: 00008C + */ +BOOL DBRead(u32* buffer, s32 count) +{ + u32 interrupts = OSDisableInterrupts(); + u32 v = SendMailData & 0x10000 ? 0x1000 : 0; + + DBGRead(v + 0x1e000, buffer, ROUND_UP(count, 4)); + + RecvDataLeng = 0; + EXIInputFlag = 0; + + OSRestoreInterrupts(interrupts); + + return 0; +} + +/* + * --INFO-- + * Address: 80221CF0 + * Size: 000260 + */ +BOOL DBWrite(const void* src, u32 size) +{ + u32 v; + u32 busyFlag; + BOOL interrupts; + + interrupts = OSDisableInterrupts(); + + do + { + DBGReadStatus(&busyFlag); + } while (busyFlag & 2); + + SendCount++; + v = ((SendCount & 1) ? 0x1000 : 0); + + while (!DBGWrite(v | 0x1c000, (u32*)src, ROUND_UP(size, 4))) + ; + + do + { + DBGReadStatus(&busyFlag); + } while (busyFlag & 2); + + v = (SendCount << 0x10) | 0x1F000000 | size; + while (!DBGWriteMailbox(v)) + ; + + do + { + while (!DBGReadStatus(&busyFlag)) + ; + } while (busyFlag & 2); + + OSRestoreInterrupts(interrupts); + + return 0; +} + +/* + * --INFO-- + * Address: 80221F50 + * Size: 000004 + */ +void DBOpen(void) +{ + return; +} + +/* + * * --INFO-- + * Address: 80221F54 + * Size: 000004 + */ +void DBClose(void) +{ + return; +} \ No newline at end of file diff --git a/libs/dolphin/amcstubs/AmcExi2Stubs.c b/libs/dolphin/amcstubs/AmcExi2Stubs.c new file mode 100644 index 000000000..99073a34c --- /dev/null +++ b/libs/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/libs/dolphin/ax/AXCL.c b/libs/dolphin/ax/AXCL.c index 4487e3cb8..7653eff26 100644 --- a/libs/dolphin/ax/AXCL.c +++ b/libs/dolphin/ax/AXCL.c @@ -72,7 +72,7 @@ void __AXNextFrame(void* sbuffer, void* buffer) case 2: break; default: - ASSERTMSGLINE(193, 0, "Unknown AX mode!"); + return; } data = (u32)__AXGetPBs(); diff --git a/libs/dolphin/ax/AXOut.c b/libs/dolphin/ax/AXOut.c index 7ead2b859..885c40f54 100644 --- a/libs/dolphin/ax/AXOut.c +++ b/libs/dolphin/ax/AXOut.c @@ -178,10 +178,6 @@ 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; diff --git a/libs/dolphin/ax/AXVPB.c b/libs/dolphin/ax/AXVPB.c index b91ad2e30..6fa4269c9 100644 --- a/libs/dolphin/ax/AXVPB.c +++ b/libs/dolphin/ax/AXVPB.c @@ -33,7 +33,6 @@ void __AXServiceVPB(AXVPB* pvpb) AXPB* ppbUser; u32 sync; - ASSERTLINE(0xA1, (pvpb->index >= 0) && (pvpb->index < AX_MAX_VOICES)); __AXNumVoices += 1; ppbDsp = &__AXPB[pvpb->index]; ppbUser = &pvpb->pb; @@ -662,8 +661,8 @@ void __AXSetPBDefault(AXVPB* p) p->sync = 0xA4; 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.update.updNum[59] = 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; } void __AXVPBInit(void) @@ -688,9 +687,6 @@ void __AXVPBInit(void) ppbi = &__AXITD[i]; ppbu = &__AXUpdates[i]; pvpb = &__AXVPB[i]; - ASSERTLINE(0x2F6, (u32)ppb ^ 0x1F); - ASSERTLINE(0x2F7, (u32)ppbi ^ 0x1F); - ASSERTLINE(0x2F8, (u32)ppbu ^ 0x1F); pvpb->index = i; pvpb->updateWrite = pvpb->updateData; pvpb->itdBuffer = ppbi; @@ -735,8 +731,6 @@ void AXSetVoiceSrcType(AXVPB* p, u32 type) int old; AXPB* ppb; - ASSERTLINE(0x35E, p); - ASSERTLINE(0x35F, type <= AX_SRC_TYPE_4TAP_16K); old = OSDisableInterrupts(); ppb = &p->pb; switch (type) @@ -931,7 +925,6 @@ void AXSetVoiceUpdateIncrement(AXVPB* p) old = OSDisableInterrupts(); p->updateMS++; p->sync |= AX_SYNC_FLAG_COPYUPDATE; - ASSERTMSGLINE(0x431, p->updateMS <= 4, "PB updates cannot exceed 5ms\n"); OSRestoreInterrupts(old); } @@ -941,7 +934,7 @@ void AXSetVoiceUpdateWrite(AXVPB* p, u16 param, u16 data) old = OSDisableInterrupts(); p->updateCounter += 2; - ASSERTMSGLINE(0x43F, p->updateCounter <= 128, "PB update block exceeded 128 words\n"); + *(p->updateWrite) = param; p->updateWrite += 1; *(p->updateWrite) = data; @@ -1051,12 +1044,6 @@ void AXSetVoiceAddr(AXVPB* p, AXPBADDR* addr) switch (addr->format) { case 0: - ASSERTMSGLINE(0x4BA, (addr->loopAddressLo & 0xF) > 1, - "*** loop address on ADPCM frame header! ***\n"); - ASSERTMSGLINE(0x4BF, (addr->endAddressLo & 0xF) > 1, - "*** end address on ADPCM frame header! ***\n"); - ASSERTMSGLINE(0x4C4, (addr->currentAddressLo & 0xF) > 1, - "*** current address on ADPCM frame header! ***\n"); break; case 10: dst += 1; @@ -1105,7 +1092,6 @@ void AXSetVoiceAddr(AXVPB* p, AXPBADDR* addr) dst += 1; break; default: - ASSERTMSGLINE(0x4F0, 0, "unknown addr->formaqt in PB\n"); break; } p->sync &= ~(AX_SYNC_FLAG_COPYLOOP | AX_SYNC_FLAG_COPYLOOPADDR | AX_SYNC_FLAG_COPYENDADDR | diff --git a/libs/dolphin/base/PPCArch.c b/libs/dolphin/base/PPCArch.c index 33dc03e67..1b0ca3bee 100644 --- a/libs/dolphin/base/PPCArch.c +++ b/libs/dolphin/base/PPCArch.c @@ -16,78 +16,58 @@ void PPCMthid0(u32 newHID0); asm u32 PPCMfmsr(void) { - nofralloc mfmsr r3 blr + nofralloc; + mfmsr r3; + blr } asm void PPCMtmsr(register u32 newMSR) { - nofralloc mtmsr newMSR blr -} - -void PPCOrMsr(void) -{ - // UNUSED FUNCTION -} - -void PPCAndMsr(void) -{ - // UNUSED FUNCTION -} - -void PPCAndCMsr(void) -{ - // UNUSED FUNCTION + nofralloc; + mtmsr newMSR; + blr } asm u32 PPCMfhid0(void) { - nofralloc mfspr r3, HID0 blr + nofralloc; + mfspr r3, HID0; + blr } asm void PPCMthid0(register u32 newHID0) { - nofralloc mtspr HID0, newHID0 blr -} - -void PPCMfhid1(void) -{ - // UNUSED FUNCTION + nofralloc; + mtspr HID0, newHID0; + blr } asm u32 PPCMfl2cr(void) { - nofralloc mfspr r3, L2CR blr + nofralloc; + mfspr r3, L2CR; + blr } asm void PPCMtl2cr(register u32 newL2cr) { - nofralloc mtspr L2CR, newL2cr blr + nofralloc; + mtspr L2CR, newL2cr; + blr } __declspec(weak) asm void PPCMtdec(register u32 newDec) { - nofralloc mtdec newDec blr -} - -void PPCMfdec(void) -{ - // UNUSED FUNCTION + nofralloc; + mtdec newDec; + blr } asm void PPCSync(void) { - nofralloc sc blr -} - -asm void PPCEieio(void) -{ - nofralloc mfmsr r5 rlwinm r6, r5, 0, 0x11, 0xf mtmsr r6 mfspr r3, hid0 ori r4, r3, 8 mtspr hid0, - r4 isync eieio isync - - mtspr hid0, - r3 mtmsr r5 isync - - blr + nofralloc; + sc; + blr } __declspec(weak) asm void PPCHalt(void) //spins infinitely @@ -96,79 +76,56 @@ __declspec(weak) asm void PPCHalt(void) //spins infinitely sync - _spin : nop li r3, - 0 nop b _spin + _spin : nop; + li r3, 0; + nop; + b _spin // NEVER REACHED } -asm void PPCMfmmcr0(void) -{ - nofralloc mfspr r3, MMCR0 blr -} - asm void PPCMtmmcr0(register u32 newMmcr0) { - nofralloc mtspr MMCR0, newMmcr0 blr -} - -asm void PPCMfmmcr1(void) -{ - nofralloc mfspr r3, MMCR1 blr + nofralloc; + mtspr MMCR0, newMmcr0; + blr } asm void PPCMtmmcr1(register u32 newMmcr1) { - nofralloc mtspr MMCR1, newMmcr1 blr -} - -asm void PPCMfpmc1(void) -{ - nofralloc mfspr r3, PMC1 blr + nofralloc; + mtspr MMCR1, newMmcr1; + blr } asm void PPCMtpmc1(register u32 newPmc1) { - nofralloc mtspr PMC1, newPmc1 blr -} - -asm void PPCMfpmc2(void) -{ - nofralloc mfspr r3, PMC2 blr + nofralloc; + mtspr PMC1, newPmc1; + blr } asm void PPCMtpmc2(register u32 newPmc2) { - nofralloc mtspr PMC2, newPmc2 blr -} - -asm void PPCMfpmc3(void) -{ - nofralloc mfspr r3, PMC2 blr + nofralloc; + mtspr PMC2, newPmc2; + blr } asm void PPCMtpmc3(register u32 newPmc3) { - nofralloc mtspr PMC3, newPmc3 blr -} - -asm void PPCMfpmc4(void) -{ - nofralloc mfspr r3, PMC4 blr + nofralloc; + mtspr PMC3, newPmc3; + blr } asm void PPCMtpmc4(register u32 newPmc4) { - nofralloc mtspr PMC4, newPmc4 blr + nofralloc; + mtspr PMC4, newPmc4; + blr } -asm void PPCMfsia(void) -{ - nofralloc mfspr r3, SIA blr -} - -asm void PPCMtsia(register u32 newSia){ nofralloc mtspr SIA, newSia blr } - u32 PPCMffpscr(void) { union FpscrUnion m; @@ -198,52 +155,23 @@ void PPCMtfpscr(register u32 newFPSCR) asm u32 PPCMfhid2(void) { - nofralloc mfspr r3, 0x398 blr + nofralloc; + mfspr r3, 0x398; + blr } asm void PPCMthid2(register u32 newhid2) { - nofralloc mtspr 0x398, newhid2 blr -} - -asm u32 PPCMfwpar(void) -{ - nofralloc sync mfspr r3, WPAR blr + nofralloc; + mtspr 0x398, newhid2; + blr } asm void PPCMtwpar(register u32 newwpar) { - nofralloc mtspr WPAR, newwpar blr -} - -asm void PPCMfdmaU(void) -{ - nofralloc mfspr r3, DMA_U blr -} - -asm void PPCMfdmaL(void) -{ - nofralloc mfspr r3, DMA_L blr -} - -void PPCMtdmaU(void) -{ - // UNUSED FUNCTION -} - -void PPCMtdmaL(void) -{ - // UNUSED FUNCTION -} - -void PPCMfpvr(void) -{ - // UNUSED FUNCTION -} - -void PPCEnableSpeculation(void) -{ - // UNUSED FUNCTION + nofralloc; + mtspr WPAR, newwpar; + blr } void PPCDisableSpeculation(void) @@ -251,13 +179,10 @@ void PPCDisableSpeculation(void) PPCMthid0(PPCMfhid0() | HID0_SPD); } -asm void PPCSetFpIEEEMode(void) -{ - nofralloc mtfsb0 4 * 7 + 1 blr -} - asm void PPCSetFpNonIEEEMode(void) { - nofralloc mtfsb1 29 blr + nofralloc; + mtfsb1 29; + blr } // clang-format on \ No newline at end of file diff --git a/libs/dolphin/dvd/dvd.c b/libs/dolphin/dvd/dvd.c index 30b70e61e..de5304885 100644 --- a/libs/dolphin/dvd/dvd.c +++ b/libs/dolphin/dvd/dvd.c @@ -4,7 +4,7 @@ #include #include -const char* __DVDVersion = "<< Dolphin SDK - DVD\trelease build: Jul 23 2003 11:27:57 (0x2301) >>"; +const char* __DVDVersion = "<< Dolphin SDK - DVD\trelease build: Apr 22 2003 15:49:00 (0x2301) >>"; // need to be "<< Dolphin SDK - DSP\trelease build: Apr 17 2003 12:34:16 (0x2301) >>" typedef void (*stateFunc)(DVDCommandBlock* block); @@ -114,7 +114,7 @@ static void stateReadingFST() if (bootInfo->FSTMaxLength < BB2.FSTLength) { -#line 650 +#line 644 OSHalt("DVDChangeDisk(): FST in the new disc is too big. "); } @@ -1093,6 +1093,18 @@ BOOL DVDReadAbsAsyncPrio(DVDCommandBlock* block, void* addr, s32 length, s32 off return idle; } +int DVDSeekAbsAsyncPrio(DVDCommandBlock* block, s32 offset, DVDCBCallback callback, s32 prio) +{ + int idle; + + block->command = DVD_COMMAND_SEEK; + block->offset = offset; + block->callback = callback; + + idle = issueCommand(prio, block); + return idle; +} + BOOL DVDReadAbsAsyncForBS(DVDCommandBlock* block, void* addr, s32 length, s32 offset, DVDCBCallback callback) { @@ -1483,27 +1495,30 @@ static void cbForCancelSync(s32 result, DVDCommandBlock* block) OSWakeupThread(&__DVDThreadQueue); } -inline 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) + { retVal = DVDCancelAsync(executing, callback); + } else { - retVal = TRUE; + retVal = 1; if (callback) - (*callback)(0, NULL); + { + callback(0, NULL); + } } DVDResume(); @@ -1648,17 +1663,3 @@ void __DVDPrepareResetAsync(DVDCBCallback callback) OSRestoreInterrupts(enabled); } - -BOOL __DVDTestAlarm(OSAlarm* alarm) -{ - BOOL ret; - if (alarm == &ResetAlarm) - { - ret = TRUE; - } - else - { - ret = __DVDLowTestAlarm(alarm); - } - return ret; -} \ No newline at end of file diff --git a/libs/dolphin/dvd/dvdFatal.c b/libs/dolphin/dvd/dvdFatal.c index 43359a1a4..2d27647db 100644 --- a/libs/dolphin/dvd/dvdFatal.c +++ b/libs/dolphin/dvd/dvdFatal.c @@ -7,101 +7,6 @@ void __DVDPrintFatalMessage(void); static void (*FatalFunc)(void) = NULL; -const char *Japanese = "\n\n\nエラーが発生しました。" - "\n\n本体のパワーボタンを押して電源をOFFにし、" - "\n本体の取扱説明書の指示に従ってください。"; - -const char *English = "\n\n\nAn error has occurred." - "\nTurn the power off and refer to the" - "\nNintendo GameCube Instruction Booklet" - "\nfor further instructions."; - -const char *const Europe[] = { - // English - "\n\n\nAn error has occurred." - "\nTurn the power off and refer to the" - "\nNintendo GameCube" - "\x99" - " Instruction Booklet" - "\nfor further instructions.", - - // German - "\n\n\nEin Fehler ist aufgetreten." - "\nBitte schalten Sie den NINTENDO GAMECUBE" - "\naus und lesen Sie die Bedienungsanleitung," - "\num weitere Informationen zu erhalten.", - - // French - "\n\n\nUne erreur est survenue." - "\nEteignez la console et r" - "\xe9" - "f" - "\xe9" - "rez-vous au" - "\nmanuel d'instructions NINTENDO GAMECUBE" - "\npour de plus amples informations.", - - // Spanish - "\n\n\nSe ha producido un error." - "\nApaga la consola y consulta el manual" - "\nde instrucciones de NINTENDO GAMECUBE" - "\npara obtener m" - "\xe1" - "s informaci" - "\xf3" - "n.", - - // Italian - "\n\n\nSi \xe8 verificato un errore." - "\nSpegni (OFF) e controlla il manuale" - "\nd'istruzioni del NINTENDO GAMECUBE" - "\nper ulteriori indicazioni.", - - // Dutch - "\n\n\nEr is een fout opgetreden." - "\nZet de NINTENDO GAMECUBE uit en" - "\nraadpleeg de handleiding van de" - "\nNintendo GameCube voor nadere" - "\ninstructies.", -}; - -static void ShowMessage(void) -{ - const char *message; - GXColor bg = {0, 0, 0, 0}; - GXColor fg = {255, 255, 255, 0}; - - if (VIGetTvFormat() == VI_NTSC) - { - if (OSGetFontEncode() == OS_FONT_ENCODE_SJIS) - { - message = Japanese; - } - else - { - message = English; - } - } - else - { - message = Europe[OSGetLanguage()]; - } - - OSFatal(fg, bg, message); -} - -BOOL DVDSetAutoFatalMessaging(BOOL enable) -{ - BOOL enabled; - BOOL prev; - - enabled = OSDisableInterrupts(); - prev = FatalFunc ? TRUE : FALSE; - FatalFunc = enable ? ShowMessage : NULL; - OSRestoreInterrupts(enabled); - return prev; -} - void __DVDPrintFatalMessage(void) { if (!FatalFunc) diff --git a/libs/dolphin/dvd/dvderror.c b/libs/dolphin/dvd/dvderror.c index a2f294393..259e8a5bf 100644 --- a/libs/dolphin/dvd/dvderror.c +++ b/libs/dolphin/dvd/dvderror.c @@ -2,24 +2,9 @@ #include "dolphin/OSRtcPriv.h" static u32 ErrorTable[] = { - 0, - 0x00023A00, - 0x00062800, - 0x00030200, - 0x00031100, - 0x00052000, - 0x00052001, - 0x00052100, - 0x00052400, - 0x00052401, - 0x00052402, - 0x000B5A01, - 0x00056300, - 0x00020401, - 0x00020400, - 0x00040800, - 0x00100007, - 0, + 0, 0x00023A00, 0x00062800, 0x00030200, 0x00031100, 0x00052000, + 0x00052001, 0x00052100, 0x00052400, 0x00052401, 0x00052402, 0x000B5A01, + 0x00056300, 0x00020401, 0x00020400, 0x00040800, 0x00100007, 0, }; static u8 ErrorCode2Num(u32 errorCode) @@ -66,7 +51,7 @@ static u8 Convert(u32 error) void __DVDStoreErrorCode(u32 error) { - OSSramEx *sram; + OSSramEx* sram; u8 num; num = Convert(error); diff --git a/libs/dolphin/dvd/dvdfs.c b/libs/dolphin/dvd/dvdfs.c index 7b688f415..27e75e9df 100644 --- a/libs/dolphin/dvd/dvdfs.c +++ b/libs/dolphin/dvd/dvdfs.c @@ -11,30 +11,30 @@ struct FSTEntry unsigned int nextEntryOrLength; }; -static OSBootInfo *BootInfo; -static FSTEntry *FstStart; -static char *FstStringStart; +static OSBootInfo* BootInfo; +static FSTEntry* FstStart; +static char* FstStringStart; static u32 MaxEntryNum; static u32 currentDirectory = 0; OSThreadQueue __DVDThreadQueue; u32 __DVDLongFileNameFlag = 0; -static void cbForReadAsync(s32 result, DVDCommandBlock *block); -static void cbForReadSync(s32 result, DVDCommandBlock *block); -static void cbForSeekAsync(s32 result, DVDCommandBlock *block); -static void cbForSeekSync(s32 result, DVDCommandBlock *block); -static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock *block); -static void cbForPrepareStreamSync(s32 result, DVDCommandBlock *block); +static void cbForReadAsync(s32 result, DVDCommandBlock* block); +static void cbForReadSync(s32 result, DVDCommandBlock* block); +static void cbForSeekAsync(s32 result, DVDCommandBlock* block); +static void cbForSeekSync(s32 result, DVDCommandBlock* block); +static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock* block); +static void cbForPrepareStreamSync(s32 result, DVDCommandBlock* block); void __DVDFSInit() { - BootInfo = (OSBootInfo *)OSPhysicalToCached(0); - FstStart = (FSTEntry *)BootInfo->FSTLocation; + BootInfo = (OSBootInfo*)OSPhysicalToCached(0); + FstStart = (FSTEntry*)BootInfo->FSTLocation; if (FstStart) { MaxEntryNum = FstStart[0].nextEntryOrLength; - FstStringStart = (char *)&(FstStart[MaxEntryNum]); + FstStringStart = (char*)&(FstStart[MaxEntryNum]); } } @@ -46,7 +46,7 @@ void __DVDFSInit() #define filePosition(i) (FstStart[i].parentOrPosition) #define fileLength(i) (FstStart[i].nextEntryOrLength) -static BOOL isSame(const char *path, const char *string) +static BOOL isSame(const char* path, const char* string) { while (*string != '\0') { @@ -64,16 +64,16 @@ static BOOL isSame(const char *path, const char *string) return FALSE; } -s32 DVDConvertPathToEntrynum(const char *pathPtr) +s32 DVDConvertPathToEntrynum(const char* pathPtr) { - const char *ptr; - char *stringPtr; + const char* ptr; + char* stringPtr; BOOL isDir; u32 length; u32 dirLookAt; u32 i; - const char *origPathPtr = pathPtr; - const char *extentionStart; + const char* origPathPtr = pathPtr; + const char* extentionStart; BOOL illegal; BOOL extention; @@ -81,7 +81,6 @@ s32 DVDConvertPathToEntrynum(const char *pathPtr) while (1) { - if (*pathPtr == '\0') { return (s32)dirLookAt; @@ -142,14 +141,16 @@ s32 DVDConvertPathToEntrynum(const char *pathPtr) if ((extention == TRUE) && (ptr - extentionStart > 3)) illegal = TRUE; - if (illegal) { - OSPanic(__FILE__, 383, - "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); - } + if (illegal) + { + OSPanic( + __FILE__, 383, + "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 { @@ -190,7 +191,7 @@ s32 DVDConvertPathToEntrynum(const char *pathPtr) } } -BOOL DVDFastOpen(s32 entrynum, DVDFileInfo *fileInfo) +BOOL DVDFastOpen(s32 entrynum, DVDFileInfo* fileInfo) { if ((entrynum < 0) || (entrynum >= MaxEntryNum) || entryIsDir(entrynum)) { @@ -205,7 +206,7 @@ BOOL DVDFastOpen(s32 entrynum, DVDFileInfo *fileInfo) return TRUE; } -BOOL DVDOpen(const char *fileName, DVDFileInfo *fileInfo) +BOOL DVDOpen(const char* fileName, DVDFileInfo* fileInfo) { s32 entry; char currentDir[128]; @@ -232,13 +233,13 @@ BOOL DVDOpen(const char *fileName, DVDFileInfo *fileInfo) return TRUE; } -BOOL DVDClose(DVDFileInfo *fileInfo) +BOOL DVDClose(DVDFileInfo* fileInfo) { DVDCancel(&(fileInfo->cb)); return TRUE; } -static u32 myStrncpy(char *dest, char *src, u32 maxlen) +static u32 myStrncpy(char* dest, char* src, u32 maxlen) { u32 i = maxlen; @@ -251,9 +252,9 @@ static u32 myStrncpy(char *dest, char *src, u32 maxlen) return (maxlen - i); } -static u32 entryToPath(u32 entry, char *path, u32 maxlen) +static u32 entryToPath(u32 entry, char* path, u32 maxlen) { - char *name; + char* name; u32 loc; if (entry == 0) @@ -277,7 +278,7 @@ static u32 entryToPath(u32 entry, char *path, u32 maxlen) return loc; } -static BOOL DVDConvertEntrynumToPath(s32 entrynum, char *path, u32 maxlen) +static BOOL DVDConvertEntrynumToPath(s32 entrynum, char* path, u32 maxlen) { u32 loc; @@ -304,12 +305,12 @@ static BOOL DVDConvertEntrynumToPath(s32 entrynum, char *path, u32 maxlen) return TRUE; } -BOOL DVDGetCurrentDir(char *path, u32 maxlen) +BOOL DVDGetCurrentDir(char* path, u32 maxlen) { return DVDConvertEntrynumToPath((s32)currentDirectory, path, maxlen); } -BOOL DVDChangeDir(char *dirName) +BOOL DVDChangeDir(char* dirName) { s32 entry; entry = DVDConvertPathToEntrynum(dirName); @@ -323,10 +324,9 @@ BOOL DVDChangeDir(char *dirName) return TRUE; } -BOOL DVDReadAsyncPrio(DVDFileInfo *fileInfo, void *addr, s32 length, s32 offset, +BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, DVDCallback callback, s32 prio) { - if (!((0 <= offset) && (offset < fileInfo->length))) { #line 746 @@ -346,24 +346,24 @@ BOOL DVDReadAsyncPrio(DVDFileInfo *fileInfo, void *addr, s32 length, s32 offset, return TRUE; } #ifndef offsetof -#define offsetof(type, memb) ((u32) & ((type *)0)->memb) +#define offsetof(type, memb) ((u32) & ((type*)0)->memb) #endif -static void cbForReadAsync(s32 result, DVDCommandBlock *block) +static void cbForReadAsync(s32 result, DVDCommandBlock* block) { - DVDFileInfo *fileInfo; + DVDFileInfo* fileInfo; - fileInfo = (DVDFileInfo *)((char *)block - offsetof(DVDFileInfo, cb)); + fileInfo = (DVDFileInfo*)((char*)block - offsetof(DVDFileInfo, cb)); if (fileInfo->callback) { (fileInfo->callback)(result, fileInfo); } } -s32 DVDReadPrio(DVDFileInfo *fileInfo, void *addr, s32 length, s32 offset, s32 prio) +s32 DVDReadPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, s32 prio) { BOOL result; - DVDCommandBlock *block; + DVDCommandBlock* block; s32 state; BOOL enabled; s32 retVal; @@ -394,7 +394,7 @@ s32 DVDReadPrio(DVDFileInfo *fileInfo, void *addr, s32 length, s32 offset, s32 p while (1) { - state = ((volatile DVDCommandBlock *)block)->state; + state = ((volatile DVDCommandBlock*)block)->state; if (state == DVD_STATE_END) { @@ -420,27 +420,29 @@ s32 DVDReadPrio(DVDFileInfo *fileInfo, void *addr, s32 length, s32 offset, s32 p } /* This is based on the revolution SDK, these may not match in all cases */ -static void cbForReadSync(s32 result, DVDCommandBlock *block) { OSWakeupThread(&__DVDThreadQueue); } +static void cbForReadSync(s32 result, DVDCommandBlock* block) +{ + OSWakeupThread(&__DVDThreadQueue); +} /* This is based on the revolution SDK, these may not match in all cases */ -BOOL DVDSeekAsyncPrio(DVDFileInfo *fileInfo, s32 offset, DVDCallback callback, s32 prio) +BOOL DVDSeekAsyncPrio(DVDFileInfo* fileInfo, s32 offset, DVDCallback callback, s32 prio) { - if (!((0 <= offset) && (offset <= fileInfo->length))) + if (!((0 <= offset) && (offset < fileInfo->length))) { - OSPanic(__FILE__, 0, "DVDSeek(): offset is out of the file "); + OSPanic(__FILE__, 0x387, "DVDSeek(): offset is out of the file "); } fileInfo->callback = callback; - DVDSeekAbsAsyncPrio(&(fileInfo->cb), (s32)(fileInfo->startAddr + offset), cbForSeekAsync, - prio); + DVDSeekAbsAsyncPrio(&(fileInfo->cb), (s32)(fileInfo->startAddr + offset), cbForSeekAsync, prio); return TRUE; } /* This is based on the revolution SDK, these may not match in all cases */ -static void cbForSeekAsync(s32 result, DVDCommandBlock *block) +static void cbForSeekAsync(s32 result, DVDCommandBlock* block) { - DVDFileInfo *fileInfo; + DVDFileInfo* fileInfo; - fileInfo = (DVDFileInfo *)((char *)block - offsetof(DVDFileInfo, cb)); + fileInfo = (DVDFileInfo*)((char*)block - offsetof(DVDFileInfo, cb)); if (fileInfo->callback) { @@ -448,18 +450,17 @@ static void cbForSeekAsync(s32 result, DVDCommandBlock *block) } } /* This is based on the revolution SDK, these may not match in all cases */ -s32 DVDSeekPrio(DVDFileInfo *fileInfo, s32 offset, s32 prio) +s32 DVDSeekPrio(DVDFileInfo* fileInfo, s32 offset, s32 prio) { BOOL result; - DVDCommandBlock *block; + DVDCommandBlock* block; s32 state; BOOL enabled; s32 retVal; block = &(fileInfo->cb); - result = - DVDSeekAbsAsyncPrio(block, (s32)(fileInfo->startAddr + offset), cbForSeekSync, prio); + result = DVDSeekAbsAsyncPrio(block, (s32)(fileInfo->startAddr + offset), cbForSeekSync, prio); if (result == FALSE) { @@ -470,7 +471,7 @@ s32 DVDSeekPrio(DVDFileInfo *fileInfo, s32 offset, s32 prio) while (1) { - state = ((volatile DVDCommandBlock *)block)->state; + state = ((volatile DVDCommandBlock*)block)->state; if (state == DVD_STATE_END) { @@ -495,18 +496,20 @@ s32 DVDSeekPrio(DVDFileInfo *fileInfo, s32 offset, s32 prio) return retVal; } /* This is based on the revolution SDK, these may not match in all cases */ -static void cbForSeekSync(s32 result, DVDCommandBlock *block) { OSWakeupThread(&__DVDThreadQueue); } +static void cbForSeekSync(s32 result, DVDCommandBlock* block) +{ + OSWakeupThread(&__DVDThreadQueue); +} /* This is based on the revolution SDK, these may not match in all cases */ -s32 DVDGetFileInfoStatus(DVDFileInfo *fileInfo) +s32 DVDGetFileInfoStatus(DVDFileInfo* fileInfo) { return DVDGetCommandBlockStatus(&fileInfo->cb); } /* This is based on the revolution SDK, these may not match in all cases */ -BOOL DVDFastOpenDir(s32 entrynum, DVDDir *dir) +BOOL DVDFastOpenDir(s32 entrynum, DVDDir* dir) { - if ((entrynum < 0) || (entrynum >= MaxEntryNum) || !entryIsDir(entrynum)) { return FALSE; @@ -520,7 +523,7 @@ BOOL DVDFastOpenDir(s32 entrynum, DVDDir *dir) } /* This is based on the revolution SDK, these may not match in all cases */ -BOOL DVDOpenDir(char *dirName, DVDDir *dir) +BOOL DVDOpenDir(char* dirName, DVDDir* dir) { s32 entry; char currentDir[128]; @@ -545,7 +548,7 @@ BOOL DVDOpenDir(char *dirName, DVDDir *dir) return TRUE; } -BOOL DVDReadDir(DVDDir *dir, DVDDirEntry *dirent) +BOOL DVDReadDir(DVDDir* dir, DVDDirEntry* dirent) { u32 loc = dir->location; if ((loc <= dir->entryNum) || (dir->next <= loc)) @@ -561,18 +564,27 @@ BOOL DVDReadDir(DVDDir *dir, DVDDirEntry *dirent) } /* This is based on the revolution SDK, these may not match in all cases */ -BOOL DVDCloseDir(DVDDir *dir) { return TRUE; } +BOOL DVDCloseDir(DVDDir* dir) +{ + return TRUE; +} /* This is based on the revolution SDK, these may not match in all cases */ -void DVDRewindDir(DVDDir *dir) { dir->location = dir->entryNum + 1; } +void DVDRewindDir(DVDDir* dir) +{ + dir->location = dir->entryNum + 1; +} /* This is based on the revolution SDK, these may not match in all cases */ -void *DVDGetFSTLocation(void) { return BootInfo->FSTLocation; } +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) +BOOL DVDPrepareStreamAsync(DVDFileInfo* fileInfo, u32 length, u32 offset, DVDCallback callback) { u32 start; @@ -580,10 +592,11 @@ BOOL DVDPrepareStreamAsync(DVDFileInfo *fileInfo, u32 length, u32 offset, DVDCal if (!Is32KBAligned(start)) { - OSPanic(__FILE__, 1189, - "DVDPrepareStreamAsync(): Specified start address (filestart(0x%x) + offset(0x%x)) is " - "not 32KB aligned", - fileInfo->startAddr, offset); + OSPanic( + __FILE__, 1189, + "DVDPrepareStreamAsync(): Specified start address (filestart(0x%x) + offset(0x%x)) is " + "not 32KB aligned", + fileInfo->startAddr, offset); } if (length == 0) @@ -591,17 +604,19 @@ BOOL DVDPrepareStreamAsync(DVDFileInfo *fileInfo, u32 length, u32 offset, DVDCal if (!Is32KBAligned(length)) { - OSPanic(__FILE__, 1199, - "DVDPrepareStreamAsync(): Specified length (0x%x) is not a multiple of 32768(32*1024)", - length); + OSPanic( + __FILE__, 1199, + "DVDPrepareStreamAsync(): Specified length (0x%x) is not a multiple of 32768(32*1024)", + length); } if (!((offset < fileInfo->length) && (offset + length <= fileInfo->length))) { - OSPanic(__FILE__, 1207, - "DVDPrepareStreamAsync(): The area specified (offset(0x%x), length(0x%x)) is out of " - "the file", - offset, length); + OSPanic( + __FILE__, 1207, + "DVDPrepareStreamAsync(): The area specified (offset(0x%x), length(0x%x)) is out of " + "the file", + offset, length); } fileInfo->callback = callback; @@ -609,11 +624,11 @@ BOOL DVDPrepareStreamAsync(DVDFileInfo *fileInfo, u32 length, u32 offset, DVDCal cbForPrepareStreamAsync); } -static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock *block) +static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock* block) { - DVDFileInfo *fileInfo; + DVDFileInfo* fileInfo; - fileInfo = (DVDFileInfo *)((char *)block - offsetof(DVDFileInfo, cb)); + fileInfo = (DVDFileInfo*)((char*)block - offsetof(DVDFileInfo, cb)); if (fileInfo->callback) { @@ -622,10 +637,10 @@ static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock *block) } /* This is based on the revolution SDK, these may not match in all cases */ -s32 DVDPrepareStream(DVDFileInfo *fileInfo, u32 length, u32 offset) +s32 DVDPrepareStream(DVDFileInfo* fileInfo, u32 length, u32 offset) { BOOL result; - DVDCommandBlock *block; + DVDCommandBlock* block; s32 state; BOOL enabled; s32 retVal; @@ -634,10 +649,11 @@ s32 DVDPrepareStream(DVDFileInfo *fileInfo, u32 length, u32 offset) if (!Is32KBAligned(start)) { - OSPanic(__FILE__, 0, - "DVDPrepareStream(): Specified start address (filestart(0x%x) + offset(0x%x)) is not " - "32KB aligned", - fileInfo->startAddr, offset); + OSPanic( + __FILE__, 0, + "DVDPrepareStream(): Specified start address (filestart(0x%x) + offset(0x%x)) is not " + "32KB aligned", + fileInfo->startAddr, offset); } if (length == 0) @@ -670,7 +686,7 @@ s32 DVDPrepareStream(DVDFileInfo *fileInfo, u32 length, u32 offset) while (1) { - state = ((volatile DVDCommandBlock *)block)->state; + state = ((volatile DVDCommandBlock*)block)->state; if (state == DVD_STATE_END) { @@ -696,16 +712,16 @@ s32 DVDPrepareStream(DVDFileInfo *fileInfo, u32 length, u32 offset) } /* This is based on the revolution SDK, these may not match in all cases */ -static void cbForPrepareStreamSync(s32 result, DVDCommandBlock *block) +static void cbForPrepareStreamSync(s32 result, DVDCommandBlock* block) { OSWakeupThread(&__DVDThreadQueue); } /* This is based on the revolution SDK, these may not match in all cases */ -s32 DVDGetTransferredSize(DVDFileInfo *fileinfo) +s32 DVDGetTransferredSize(DVDFileInfo* fileinfo) { s32 bytes; - DVDCommandBlock *cb; + DVDCommandBlock* cb; cb = &(fileinfo->cb); diff --git a/libs/dolphin/dvd/dvdlow.c b/libs/dolphin/dvd/dvdlow.c index c09c54eb9..3c2aab44b 100644 --- a/libs/dolphin/dvd/dvdlow.c +++ b/libs/dolphin/dvd/dvdlow.c @@ -19,7 +19,7 @@ static vu32 NextCommandNumber = 0; typedef struct DVDBuffer { - void *addr; + void* addr; u32 length; u32 offset; } DVDBuffer; @@ -27,7 +27,7 @@ typedef struct DVDBuffer typedef struct DVDCommand { s32 cmd; - void *addr; + void* addr; u32 length; u32 offset; DVDLowCallback callback; @@ -48,7 +48,7 @@ void __DVDInitWA() OSInitAlarm(); } -static void Read(void *addr, u32 length, u32 offset, DVDLowCallback callback); +static void Read(void* addr, u32 length, u32 offset, DVDLowCallback callback); static BOOL ProcessNextCommand() { @@ -72,7 +72,7 @@ static BOOL ProcessNextCommand() return FALSE; } -void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext *context) +void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext* context) { DVDLowCallback cb; OSContext exceptionContext; @@ -195,13 +195,13 @@ void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext *context) OSSetCurrentContext(context); } -static void AlarmHandler(OSAlarm *alarm, OSContext *context) +static void AlarmHandler(OSAlarm* alarm, OSContext* context) { BOOL error = ProcessNextCommand(); ASSERTMSG(error != FALSE, "Failed assertion processed"); } -static void AlarmHandlerForTimeout(OSAlarm *alarm, OSContext *context) +static void AlarmHandlerForTimeout(OSAlarm* alarm, OSContext* context) { OSContext tmpContext; DVDLowCallback callback; @@ -224,7 +224,7 @@ static void SetTimeoutAlarm(OSTime timeout) OSSetAlarm(&AlarmForTimeout, timeout, AlarmHandlerForTimeout); } -static void Read(void *addr, u32 length, u32 offset, DVDLowCallback callback) +static void Read(void* addr, u32 length, u32 offset, DVDLowCallback callback) { StopAtNextInt = FALSE; LastCommandWasRead = TRUE; @@ -249,7 +249,7 @@ static void Read(void *addr, u32 length, u32 offset, DVDLowCallback callback) } } -BOOL HitCache(DVDBuffer *cur, DVDBuffer *prev) +BOOL HitCache(DVDBuffer* cur, DVDBuffer* prev) { u32 uVar1 = (prev->offset + prev->length - 1) >> 15; u32 uVar2 = (cur->offset >> 15); @@ -262,14 +262,14 @@ BOOL HitCache(DVDBuffer *cur, DVDBuffer *prev) return FALSE; } -static void DoJustRead(void *addr, u32 length, u32 offset, DVDLowCallback callback) +static void DoJustRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { CommandList[0].cmd = -1; NextCommandNumber = 0; Read(addr, length, offset, callback); } -static void SeekTwiceBeforeRead(void *addr, u32 length, u32 offset, DVDLowCallback callback) +static void SeekTwiceBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { u32 newOffset = offset & ~0x7FFF; if (!newOffset) @@ -293,7 +293,7 @@ static void SeekTwiceBeforeRead(void *addr, u32 length, u32 offset, DVDLowCallba DVDLowSeek(newOffset, callback); } -static void WaitBeforeRead(void *addr, u32 length, u32 offset, DVDLowCallback callback, +static void WaitBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback, OSTime timeout) { CommandList[0].cmd = 1; @@ -307,7 +307,7 @@ static void WaitBeforeRead(void *addr, u32 length, u32 offset, DVDLowCallback ca OSSetAlarm(&AlarmForWA, timeout, AlarmHandler); } -BOOL DVDLowRead(void *addr, u32 length, u32 offset, DVDLowCallback callback) +BOOL DVDLowRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { OSTime diff; u32 prev; @@ -346,7 +346,8 @@ BOOL DVDLowRead(void *addr, u32 length, u32 offset, DVDLowCallback callback) else { WaitBeforeRead(addr, length, offset, callback, - OSMillisecondsToTicks(5) - diff + OSMicrosecondsToTicks(500)); + OSMillisecondsToTicks(5) - diff + + OSMicrosecondsToTicks(500)); } } else @@ -380,7 +381,7 @@ BOOL DVDLowWaitCoverClose(DVDLowCallback callback) return TRUE; } -BOOL DVDLowReadDiskID(DVDDiskID *diskID, DVDLowCallback callback) +BOOL DVDLowReadDiskID(DVDDiskID* diskID, DVDLowCallback callback) { StopAtNextInt = FALSE; Callback = callback; @@ -414,7 +415,7 @@ BOOL DVDLowRequestError(DVDLowCallback callback) return TRUE; } -BOOL DVDLowInquiry(DVDDriveInfo *info, DVDLowCallback callback) +BOOL DVDLowInquiry(DVDDriveInfo* info, DVDLowCallback callback) { StopAtNextInt = FALSE; Callback = callback; @@ -503,11 +504,14 @@ void __DVDLowSetWAType(u32 type, u32 location) OSRestoreInterrupts(enabled); } -BOOL __DVDLowTestAlarm(OSAlarm *alarm) { - if(alarm == &AlarmForBreak) { +BOOL __DVDLowTestAlarm(OSAlarm* alarm) +{ + if (alarm == &AlarmForBreak) + { return TRUE; } - if(alarm == &AlarmForTimeout) { + if (alarm == &AlarmForTimeout) + { return TRUE; } diff --git a/libs/dolphin/dvd/dvdqueue.c b/libs/dolphin/dvd/dvdqueue.c index 54851a3c3..62f6a1c5c 100644 --- a/libs/dolphin/dvd/dvdqueue.c +++ b/libs/dolphin/dvd/dvdqueue.c @@ -3,8 +3,8 @@ #define MAX_QUEUES 4 typedef struct { - DVDCommandBlock *next; - DVDCommandBlock *prev; + DVDCommandBlock* next; + DVDCommandBlock* prev; } DVDQueue; static DVDQueue WaitingQueue[MAX_QUEUES]; @@ -15,22 +15,22 @@ void __DVDClearWaitingQueue(void) for (i = 0; i < MAX_QUEUES; i++) { - DVDCommandBlock *q; + DVDCommandBlock* q; - q = (DVDCommandBlock *)&(WaitingQueue[i]); + q = (DVDCommandBlock*)&(WaitingQueue[i]); q->next = q; q->prev = q; } } -BOOL __DVDPushWaitingQueue(s32 prio, DVDCommandBlock *block) +BOOL __DVDPushWaitingQueue(s32 prio, DVDCommandBlock* block) { BOOL enabled; - DVDCommandBlock *q; + DVDCommandBlock* q; enabled = OSDisableInterrupts(); - q = (DVDCommandBlock *)&(WaitingQueue[prio]); + q = (DVDCommandBlock*)&(WaitingQueue[prio]); q->prev->next = block; block->prev = q->prev; @@ -42,62 +42,76 @@ BOOL __DVDPushWaitingQueue(s32 prio, DVDCommandBlock *block) return TRUE; } -static DVDCommandBlock *PopWaitingQueuePrio(s32 prio) -{ - DVDCommandBlock *tmp; - BOOL enabled; - DVDCommandBlock *q; +// static DVDCommandBlock* PopWaitingQueuePrio(s32 prio) +// { +// DVDCommandBlock* tmp; +// BOOL enabled; +// DVDCommandBlock* q; - enabled = OSDisableInterrupts(); +// enabled = OSDisableInterrupts(); - q = (DVDCommandBlock *)&(WaitingQueue[prio]); +// q = (DVDCommandBlock*)&(WaitingQueue[prio]); - tmp = q->next; - q->next = tmp->next; - tmp->next->prev = q; +// tmp = q->next; +// q->next = tmp->next; +// tmp->next->prev = q; - OSRestoreInterrupts(enabled); +// OSRestoreInterrupts(enabled); - tmp->next = (DVDCommandBlock *)NULL; - tmp->prev = (DVDCommandBlock *)NULL; +// tmp->next = (DVDCommandBlock*)NULL; +// tmp->prev = (DVDCommandBlock*)NULL; - return tmp; -} +// return tmp; +// } -DVDCommandBlock *__DVDPopWaitingQueue(void) +DVDCommandBlock* __DVDPopWaitingQueue(void) { u32 i; BOOL enabled; - DVDCommandBlock *q; + DVDCommandBlock* q; + DVDCommandBlock* tmp; enabled = OSDisableInterrupts(); for (i = 0; i < MAX_QUEUES; i++) { - q = (DVDCommandBlock *)&(WaitingQueue[i]); + q = (DVDCommandBlock*)&(WaitingQueue[i]); if (q->next != q) { OSRestoreInterrupts(enabled); - return PopWaitingQueuePrio((s32)i); + enabled = OSDisableInterrupts(); + + q = (DVDCommandBlock*)&(WaitingQueue[i]); + + tmp = q->next; + q->next = tmp->next; + tmp->next->prev = q; + + OSRestoreInterrupts(enabled); + + tmp->next = (DVDCommandBlock*)NULL; + tmp->prev = (DVDCommandBlock*)NULL; + + return tmp; } } OSRestoreInterrupts(enabled); - return (DVDCommandBlock *)NULL; + return (DVDCommandBlock*)NULL; } BOOL __DVDCheckWaitingQueue(void) { u32 i; BOOL enabled; - DVDCommandBlock *q; + DVDCommandBlock* q; enabled = OSDisableInterrupts(); for (i = 0; i < MAX_QUEUES; i++) { - q = (DVDCommandBlock *)&(WaitingQueue[i]); + q = (DVDCommandBlock*)&(WaitingQueue[i]); if (q->next != q) { OSRestoreInterrupts(enabled); @@ -110,18 +124,18 @@ BOOL __DVDCheckWaitingQueue(void) return FALSE; } -BOOL __DVDDequeueWaitingQueue(DVDCommandBlock *block) +BOOL __DVDDequeueWaitingQueue(DVDCommandBlock* block) { BOOL enabled; - DVDCommandBlock *prev; - DVDCommandBlock *next; + DVDCommandBlock* prev; + DVDCommandBlock* next; enabled = OSDisableInterrupts(); prev = block->prev; next = block->next; - if ((prev == (DVDCommandBlock *)NULL) || (next == (DVDCommandBlock *)NULL)) + if ((prev == (DVDCommandBlock*)NULL) || (next == (DVDCommandBlock*)NULL)) { OSRestoreInterrupts(enabled); return FALSE; @@ -135,25 +149,25 @@ BOOL __DVDDequeueWaitingQueue(DVDCommandBlock *block) return TRUE; } -BOOL __DVDIsBlockInWaitingQueue(DVDCommandBlock *block) -{ - u32 i; - DVDCommandBlock *start; - DVDCommandBlock *q; - - for (i = 0; i < MAX_QUEUES; i++) - { - start = (DVDCommandBlock *)&(WaitingQueue[i]); - - if (start->next != start) - { - for (q = start->next; q != start; q = q->next) - { - if (q == block) - return TRUE; - } - } - } - - return FALSE; -} \ No newline at end of file +// BOOL __DVDIsBlockInWaitingQueue(DVDCommandBlock *block) +// { +// u32 i; +// DVDCommandBlock *start; +// DVDCommandBlock *q; + +// for (i = 0; i < MAX_QUEUES; i++) +// { +// start = (DVDCommandBlock *)&(WaitingQueue[i]); + +// if (start->next != start) +// { +// for (q = start->next; q != start; q = q->next) +// { +// if (q == block) +// return TRUE; +// } +// } +// } + +// return FALSE; +// } \ No newline at end of file diff --git a/libs/dolphin/exi/EXIBios.c b/libs/dolphin/exi/EXIBios.c index 66653a0a9..3b50ca02d 100644 --- a/libs/dolphin/exi/EXIBios.c +++ b/libs/dolphin/exi/EXIBios.c @@ -1,7 +1,7 @@ #include "dolphin/os.h" #include "dolphin/hw_regs.h" -static const char *__EXIVersion = +static const char* __EXIVersion = "<< Dolphin SDK - EXI\trelease build: Apr 17 2003 12:33:17 (0x2301) >>"; #define MAX_DEV 3 @@ -18,7 +18,7 @@ static const char *__EXIVersion = #define STATE_ATTACHED 0x08 #define STATE_LOCKED 0x10 -#define EXI_0CR(tstart, dma, rw, tlen) \ +#define EXI_0CR(tstart, dma, rw, tlen) \ ((((u32)(tstart)) << 0) | (((u32)(dma)) << 1) | (((u32)(rw)) << 2) | (((u32)(tlen)) << 4)) #define CPR_CS(x) ((1u << (x)) << 7) @@ -31,7 +31,7 @@ typedef struct EXIControl EXICallback extCallback; vu32 state; int immLen; - u8 *immBuf; + u8* immBuf; u32 dev; u32 id; s32 idTime; @@ -49,9 +49,9 @@ s32 __EXIProbeStartTime[2] : (OS_BASE_CACHED | 0x30C0); #pragma scheduling off -static void SetExiInterruptMask(s32 chan, EXIControl *exi) +static void SetExiInterruptMask(s32 chan, EXIControl* exi) { - EXIControl *exi2; + EXIControl* exi2; exi2 = &Ecb[2]; switch (chan) @@ -91,8 +91,8 @@ static void SetExiInterruptMask(s32 chan, EXIControl *exi) static void CompleteTransfer(s32 chan) { - EXIControl *exi = &Ecb[chan]; - u8 *buf; + EXIControl* exi = &Ecb[chan]; + u8* buf; u32 data; int i; int len; @@ -112,9 +112,9 @@ static void CompleteTransfer(s32 chan) } } -BOOL EXIImm(s32 chan, void *buf, s32 len, u32 type, EXICallback callback) +BOOL EXIImm(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL enabled; enabled = OSDisableInterrupts(); @@ -141,7 +141,7 @@ BOOL EXIImm(s32 chan, void *buf, s32 len, u32 type, EXICallback callback) data = 0; for (i = 0; i < len; i++) { - data |= ((u8 *)buf)[i] << ((3 - i) * 8); + data |= ((u8*)buf)[i] << ((3 - i) * 8); } REG(chan, 4) = data; } @@ -156,7 +156,7 @@ BOOL EXIImm(s32 chan, void *buf, s32 len, u32 type, EXICallback callback) return TRUE; } -BOOL EXIImmEx(s32 chan, void *buf, s32 len, u32 mode) +BOOL EXIImmEx(s32 chan, void* buf, s32 len, u32 mode) { s32 xLen; @@ -173,15 +173,15 @@ BOOL EXIImmEx(s32 chan, void *buf, s32 len, u32 mode) return FALSE; } - (u8 *)buf += xLen; + (u8*)buf += xLen; len -= xLen; } return TRUE; } -BOOL EXIDma(s32 chan, void *buf, s32 len, u32 type, EXICallback callback) +BOOL EXIDma(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL enabled; enabled = OSDisableInterrupts(); @@ -215,7 +215,7 @@ vu16 __OSDeviceCode : (OS_BASE_CACHED | 0x30E6); BOOL EXISync(s32 chan) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL rc = FALSE; BOOL enabled; @@ -227,8 +227,9 @@ BOOL EXISync(s32 chan) if (exi->state & STATE_SELECTED) { CompleteTransfer(chan); - if (__OSGetDIConfig() != 0xff || ((OSGetConsoleType() & OS_CONSOLE_MASK) == OS_CONSOLE_TDEV) || exi->immLen != 4 || - (REG(chan, 0) & 0x00000070) != (EXI_FREQ_1M << 4) || + if (__OSGetDIConfig() != 0xff || + ((OSGetConsoleType() & OS_CONSOLE_MASK) == OS_CONSOLE_TDEV) || + 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) @@ -262,7 +263,7 @@ u32 EXIClearInterrupts(s32 chan, BOOL exi, BOOL tc, BOOL ext) EXICallback EXISetExiCallback(s32 chan, EXICallback exiCallback) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; EXICallback prev; BOOL enabled; @@ -283,17 +284,9 @@ EXICallback EXISetExiCallback(s32 chan, EXICallback exiCallback) return prev; } -void EXIProbeReset(void) -{ - __EXIProbeStartTime[0] = __EXIProbeStartTime[1] = 0; - Ecb[0].idTime = Ecb[1].idTime = 0; - __EXIProbe(0); - __EXIProbe(1); -} - static BOOL __EXIProbe(s32 chan) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL enabled; BOOL rc; u32 cpr; @@ -345,7 +338,7 @@ static BOOL __EXIProbe(s32 chan) BOOL EXIProbe(s32 chan) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL rc; u32 id; @@ -375,7 +368,7 @@ s32 EXIProbeEx(s32 chan) static BOOL __EXIAttach(s32 chan, EXICallback extCallback) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL enabled; enabled = OSDisableInterrupts(); @@ -397,7 +390,7 @@ static BOOL __EXIAttach(s32 chan, EXICallback extCallback) BOOL EXIAttach(s32 chan, EXICallback extCallback) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL enabled; BOOL rc; @@ -416,7 +409,7 @@ BOOL EXIAttach(s32 chan, EXICallback extCallback) BOOL EXIDetach(s32 chan) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL enabled; enabled = OSDisableInterrupts(); @@ -439,7 +432,7 @@ BOOL EXIDetach(s32 chan) BOOL EXISelect(s32 chan, u32 dev, u32 freq) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; u32 cpr; BOOL enabled; @@ -477,7 +470,7 @@ BOOL EXISelect(s32 chan, u32 dev, u32 freq) BOOL EXIDeselect(s32 chan) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; u32 cpr; BOOL enabled; @@ -514,10 +507,10 @@ BOOL EXIDeselect(s32 chan) return TRUE; } -static void EXIIntrruptHandler(__OSInterrupt interrupt, OSContext *context) +static void EXIIntrruptHandler(__OSInterrupt interrupt, OSContext* context) { s32 chan; - EXIControl *exi; + EXIControl* exi; EXICallback callback; chan = (interrupt - __OS_INTERRUPT_EXI_0_EXI) / 3; @@ -538,11 +531,11 @@ static void EXIIntrruptHandler(__OSInterrupt interrupt, OSContext *context) } } -static void TCIntrruptHandler(__OSInterrupt interrupt, OSContext *context) +static void TCIntrruptHandler(__OSInterrupt interrupt, OSContext* context) { OSContext exceptionContext; s32 chan; - EXIControl *exi; + EXIControl* exi; EXICallback callback; chan = (interrupt - __OS_INTERRUPT_EXI_0_TC) / 3; @@ -565,10 +558,10 @@ static void TCIntrruptHandler(__OSInterrupt interrupt, OSContext *context) } } -static void EXTIntrruptHandler(__OSInterrupt interrupt, OSContext *context) +static void EXTIntrruptHandler(__OSInterrupt interrupt, OSContext* context) { s32 chan; - EXIControl *exi; + EXIControl* exi; EXICallback callback; chan = (interrupt - __OS_INTERRUPT_EXI_0_EXT) / 3; @@ -594,12 +587,15 @@ static void EXTIntrruptHandler(__OSInterrupt interrupt, OSContext *context) void EXIInit(void) { u32 id; - while (((REG(0, 3) & 0x1) == 1) || ((REG(1, 3) & 0x1) == 1) || ((REG(2, 3) & 0x1) == 1)) { + while (((REG(0, 3) & 0x1) == 1) || ((REG(1, 3) & 0x1) == 1) || ((REG(2, 3) & 0x1) == 1)) + { continue; } - __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); + __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_0_TC | + OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_1_EXI | + OS_INTERRUPTMASK_EXI_1_TC | OS_INTERRUPTMASK_EXI_1_EXT | + OS_INTERRUPTMASK_EXI_2_EXI | OS_INTERRUPTMASK_EXI_2_TC); REG(0, 0) = 0; REG(1, 0) = 0; @@ -618,14 +614,19 @@ void EXIInit(void) EXIGetID(0, 2, &IDSerialPort1); - if (__OSInIPL) { + if (__OSInIPL) + { __EXIProbeStartTime[0] = __EXIProbeStartTime[1] = 0; Ecb[0].idTime = Ecb[1].idTime = 0; __EXIProbe(0); __EXIProbe(1); - } else if (EXIGetID(0, 0, &id) && id == 0x07010000) { + } + else if (EXIGetID(0, 0, &id) && id == 0x07010000) + { __OSEnableBarnacle(1, 0); - } else if (EXIGetID(1, 0, &id) && id == 0x07010000) { + } + else if (EXIGetID(1, 0, &id) && id == 0x07010000) + { __OSEnableBarnacle(0, 2); } @@ -634,7 +635,7 @@ void EXIInit(void) BOOL EXILock(s32 chan, u32 dev, EXICallback unlockedCallback) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL enabled; int i; @@ -669,7 +670,7 @@ BOOL EXILock(s32 chan, u32 dev, EXICallback unlockedCallback) BOOL EXIUnlock(s32 chan) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL enabled; EXICallback unlockedCallback; @@ -698,12 +699,12 @@ BOOL EXIUnlock(s32 chan) u32 EXIGetState(s32 chan) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; return (u32)exi->state; } -static void UnlockedHandler(s32 chan, OSContext *context) +static void UnlockedHandler(s32 chan, OSContext* context) { u32 id; @@ -719,32 +720,39 @@ s32 EXIGetID(s32 chan, u32 dev, u32* id) BOOL enabled; BOOL interrupt; - if (chan == 0 && dev == 2 && IDSerialPort1) { + if (chan == 0 && dev == 2 && IDSerialPort1) + { *id = IDSerialPort1; return 1; } - if (chan < 2 && dev == 0) { - if (!__EXIProbe(chan)) { + if (chan < 2 && dev == 0) + { + if (!__EXIProbe(chan)) + { return 0; } - if (exi->idTime == __EXIProbeStartTime[chan]) { + if (exi->idTime == __EXIProbeStartTime[chan]) + { *id = exi->id; return exi->idTime; } - if (!__EXIAttach(chan, NULL)) { + if (!__EXIAttach(chan, NULL)) + { return 0; } startTime = __EXIProbeStartTime[chan]; } interrupt = OSDisableInterrupts(); - err = !EXILock(chan, dev, (chan < 2 && dev == 0) ? UnlockedHandler : NULL); - if (!err) { + err = !EXILock(chan, dev, (chan < 2 && dev == 0) ? UnlockedHandler : NULL); + if (!err) + { err = !EXISelect(chan, dev, EXI_FREQ_1M); - if (!err) { + if (!err) + { cmd = 0; err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, NULL); err |= !EXISync(chan); @@ -756,12 +764,14 @@ s32 EXIGetID(s32 chan, u32 dev, u32* id) } OSRestoreInterrupts(interrupt); - if (chan < 2 && dev == 0) { + if (chan < 2 && dev == 0) + { EXIDetach(chan); enabled = OSDisableInterrupts(); err |= (startTime != __EXIProbeStartTime[chan]); - if (!err) { - exi->id = *id; + if (!err) + { + exi->id = *id; exi->idTime = startTime; } OSRestoreInterrupts(enabled); @@ -772,55 +782,10 @@ s32 EXIGetID(s32 chan, u32 dev, u32* id) return err ? 0 : !0; } -s32 EXIGetType(s32 chan, u32 dev, u32 *type) { - u32 _type; - s32 probe; - - probe = EXIGetID(chan, dev, &_type); - if(probe == 0) - return probe; - - switch(_type & 0xffffff00) - { - case 0x4020100: - case 0x4020200: - case 0x4020300: - case 0x4060000: - *type = _type & 0xffffff00; - return probe; - } - - switch(_type & 0xffff0000) - { - case 0: - { - if ((_type & 0x3803)) - break; - - switch (_type & 0xfc) - { - case 4: - case 8: - case 16: - case 32: - case 64: - case 128: - *type = _type & 0xfc; - return probe; - } - break; - } - case 0x5070000: - *type = 0x5070000; - return probe; - } - *type = _type; - return probe; -} - char* EXIGetTypeString(u32 type) { - switch (type) { + switch (type) + { case EXI_MEMORY_CARD_59: return "Memory Card 59"; case EXI_MEMORY_CARD_123: diff --git a/libs/dolphin/exi/EXIUart.c b/libs/dolphin/exi/EXIUart.c index 8e8734a1a..73efc2cef 100644 --- a/libs/dolphin/exi/EXIUart.c +++ b/libs/dolphin/exi/EXIUart.c @@ -8,7 +8,7 @@ static u32 Dev; static u32 Enabled = 0; static u32 BarnacleEnabled = 0; -static BOOL ProbeBarnacle(s32 chan, u32 dev, u32 *revision) +static BOOL ProbeBarnacle(s32 chan, u32 dev, u32* revision) { BOOL err; u32 cmd; @@ -111,8 +111,6 @@ u32 InitializeUART(u32 baudRate) } } -u32 ReadUARTN(void *bytes, unsigned long length) { return 4; } - static int QueueLength(void) { u32 cmd; @@ -131,13 +129,13 @@ static int QueueLength(void) return 16 - (int)((cmd >> 24) & 0xff); } -u32 WriteUARTN(const void *buf, unsigned long len) +u32 WriteUARTN(const void* buf, unsigned long len) { BOOL enabled; u32 cmd; int qLen; long xLen; - char *ptr; + char* ptr; BOOL locked; u32 error; @@ -153,7 +151,7 @@ u32 WriteUARTN(const void *buf, unsigned long len) return 0; } - for (ptr = (char *)buf; ptr - buf < len; ptr++) + for (ptr = (char*)buf; ptr - buf < len; ptr++) { if (*ptr == '\n') *ptr = '\r'; @@ -187,8 +185,8 @@ u32 WriteUARTN(const void *buf, unsigned long len) if (qLen < 4 && qLen < len) break; xLen = (len < 4) ? (long)len : 4; - EXIImm(Chan, (void *)buf, xLen, EXI_WRITE, NULL); - (u8 *)buf += xLen; + EXIImm(Chan, (void*)buf, xLen, EXI_WRITE, NULL); + (u8*)buf += xLen; len -= xLen; qLen -= xLen; EXISync(Chan); diff --git a/libs/dolphin/gx/GXAttr.c b/libs/dolphin/gx/GXAttr.c index e69de29bb..6af279ddd 100644 --- a/libs/dolphin/gx/GXAttr.c +++ b/libs/dolphin/gx/GXAttr.c @@ -0,0 +1,622 @@ +#include +#include + +#include + +#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 = 1; + __GXData->hasBiNrms = 0; + __GXData->nrmType = Type; + } + else + { + __GXData->hasNrms = 0; + } + break; + case GX_VA_NBT: + if (Type != GX_NONE) + { + __GXData->hasBiNrms = 1; + __GXData->hasNrms = 0; + __GXData->nrmType = Type; + } + else + { + __GXData->hasBiNrms = 0; + } + 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 attr, GXAttrType type) +{ + SETVCDATTR(attr, type); + if (__GXData->hasNrms || __GXData->hasBiNrms) + { + SET_REG_FIELD(280, __GXData->vcdLo, 2, 11, __GXData->nrmType); + } + else + { + SET_REG_FIELD(0, __GXData->vcdLo, 2, 11, 0); + } + __GXData->dirtyState |= 8; +} + +void __GXSetVCD(void) +{ + GX_WRITE_SOME_REG4(8, 0x50, __GXData->vcdLo, -12); + GX_WRITE_SOME_REG4(8, 0x60, __GXData->vcdHi, -12); + __GXXfVtxSpecs(); +} + +void __GXCalculateVLim(void) +{ + static u8 tbl1[] = { 0, 4, 1, 2 }; + static u8 tbl2[] = { 0, 8, 1, 2 }; + static u8 tbl3[] = { 0, 12, 1, 2 }; + + GXCompCnt nc = 0; + u32 vlm; + u32 b; + u32 vl; + u32 vh; + u32 va; + + if (__GXData->vNum != 0) + { + vl = __GXData->vcdLo; + vh = __GXData->vcdHi; + va = __GXData->vatA[0]; + nc = GET_REG_FIELD(va, 1, 9); + + 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 + { + b = 1; + } + + 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 GXClearVtxDesc(void) +{ + CHECK_GXBEGIN(543, "GXClearVtxDesc"); + __GXData->vcdLo = 0; + SET_REG_FIELD(0, __GXData->vcdLo, 2, 9, 1); + __GXData->vcdHi = 0; + __GXData->hasNrms = 0; + __GXData->hasBiNrms = 0; + __GXData->dirtyState |= 8; +} + +static inline void SETVAT(u32* va, u32* vb, u32* vc, GXAttr attr, GXCompCnt cnt, GXCompType type, + u8 shft) +{ + switch (attr) + { + case GX_VA_POS: + 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: + 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 + { + SET_REG_FIELD(599, *va, 1, 9, cnt); + SET_REG_FIELD(599, *va, 1, 31, 0); + } + break; + case GX_VA_CLR0: + SET_REG_FIELD(605, *va, 1, 13, cnt); + SET_REG_FIELD(606, *va, 3, 14, type); + break; + case GX_VA_CLR1: + SET_REG_FIELD(609, *va, 1, 0x11, cnt); + SET_REG_FIELD(610, *va, 3, 18, type); + break; + case GX_VA_TEX0: + 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: + 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: + 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: + 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: + 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: + 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: + 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: + 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; + } +} + +void GXSetVtxAttrFmt(GXVtxFmt vtxfmt, GXAttr attr, GXCompCnt cnt, GXCompType type, u8 frac) +{ + u32* va; + u32* vb; + u32* vc; + + //CHECK_GXBEGIN(666, "GXSetVtxAttrFmt"); + //CHECK_VTXFMT(667, vtxfmt); + //CHECK_ATTRNAME4(671, attr); + //CHECK_FRAC(672, frac); + + 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); +} + +void GXSetVtxAttrFmtv(GXVtxFmt vtxfmt, const GXVtxAttrFmtList* list) +{ + u32* va; + u32* vb; + u32* vc; + + va = &__GXData->vatA[vtxfmt]; + vb = &__GXData->vatB[vtxfmt]; + vc = &__GXData->vatC[vtxfmt]; + + while (list->attr != GX_VA_NULL) + { + 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 |= 0x10; + __GXData->dirtyVAT |= (u8)(1 << (u8)vtxfmt); +} + +void __GXSetVAT(void) +{ + s32 i; + u32 dirty = __GXData->dirtyVAT; + + i = 0; + do + { + 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); + } + + dirty >>= 1; + i++; + } while (dirty != 0); + + __GXData->dirtyVAT = 0; +} + +static inline u8 GetFracForNrm(GXCompType type) +{ + u8 frac; + + switch (type) + { + case GX_S8: + frac = 6; + break; + case GX_S16: + frac = 14; + break; + default: + case GX_U16: + frac = 0; + break; + } + + return frac; +} + +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: + 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(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: + 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 + { + SET_REG_FIELD(0, reg, 3, 4, 3); + } + SET_REG_FIELD(0, reg, 5, 7, 2); + break; + default: + //ASSERTMSGLINE(1113, 0, "GXSetTexCoordGen: Invalid function"); + break; + } + + GX_WRITE_XF_REG(dst_coord + 0x40, reg); + reg = 0; + 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); + + 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; + } + + mtxIdAttr = dst_coord + 1; + __GXSetMatrixIndex(mtxIdAttr); +} + +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/libs/dolphin/gx/GXBump.c b/libs/dolphin/gx/GXBump.c index e69de29bb..bf02bbbba 100644 --- a/libs/dolphin/gx/GXBump.c +++ b/libs/dolphin/gx/GXBump.c @@ -0,0 +1,207 @@ +#include +#include + +#include + +#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 + +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; +} + +void GXSetIndTexMtx(GXIndTexMtxID mtx_id, const f32 offset[2][3], s8 scale_exp) +{ + s32 mtx[6]; + u32 reg; + u32 id; + + CHECK_GXBEGIN(186, "GXSetIndTexMtx"); + + switch (mtx_id) + { + case GX_ITM_0: + case GX_ITM_1: + case GX_ITM_2: + id = mtx_id - 1; + break; + case GX_ITM_S0: + case GX_ITM_S1: + case GX_ITM_S2: + id = mtx_id - 5; + break; + case GX_ITM_T0: + case GX_ITM_T1: + case GX_ITM_T2: + id = mtx_id - 9; + break; + default: + id = 0; + break; + } + + 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); + + 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); + + 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; +} + +void GXSetIndTexCoordScale(GXIndTexStageID ind_state, GXIndTexScale scale_s, GXIndTexScale scale_t) +{ + CHECK_GXBEGIN(249, "GXSetIndTexScale"); + + switch (ind_state) + { + case GX_INDTEXSTAGE0: + 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: + 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: + 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: + 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: + + break; + } + __GXData->bpSentNot = 0; +} + +void GXSetIndTexOrder(GXIndTexStageID ind_stage, GXTexCoordID tex_coord, GXTexMapID tex_map) +{ + CHECK_GXBEGIN(302, "GXSetIndTexOrder"); + + if (tex_map == GX_TEXMAP_NULL) + { + tex_map = GX_TEXMAP0; + } + + if (tex_coord == GX_TEXCOORD_NULL) + { + tex_coord = GX_TEXCOORD0; + } + + switch (ind_stage) + { + case GX_INDTEXSTAGE0: + SET_REG_FIELD(319, __GXData->iref, 3, 0, tex_map); + SET_REG_FIELD(320, __GXData->iref, 3, 3, tex_coord); + break; + case GX_INDTEXSTAGE1: + SET_REG_FIELD(323, __GXData->iref, 3, 6, tex_map); + SET_REG_FIELD(324, __GXData->iref, 3, 9, tex_coord); + break; + case GX_INDTEXSTAGE2: + SET_REG_FIELD(327, __GXData->iref, 3, 12, tex_map); + SET_REG_FIELD(328, __GXData->iref, 3, 15, tex_coord); + break; + case GX_INDTEXSTAGE3: + SET_REG_FIELD(331, __GXData->iref, 3, 18, tex_map); + SET_REG_FIELD(332, __GXData->iref, 3, 21, tex_coord); + break; + default: + 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"); + + 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 __GXUpdateBPMask(void) +{ +} + +void __GXFlushTextureState(void) +{ + GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->bpMask); + __GXData->bpSentNot = 0; +} diff --git a/libs/dolphin/gx/GXDisplayList.c b/libs/dolphin/gx/GXDisplayList.c index e69de29bb..061f9e670 100644 --- a/libs/dolphin/gx/GXDisplayList.c +++ b/libs/dolphin/gx/GXDisplayList.c @@ -0,0 +1,29 @@ +#include + +#include +#include + +#include + +void GXCallDisplayList(const void* list, u32 nbytes) +{ + CHECK_GXBEGIN(254, "GXCallDisplayList"); + + if (__GXData->dirtyState != 0) + { + __GXSetDirtyState(); + } + +#if DEBUG + __GXShadowDispList(list, nbytes); +#endif + + if (*(u32*)&__GXData->vNumNot == 0) + { // checks both vNum and bpSent + __GXSendFlushPrim(); + } + + GX_WRITE_U8(GX_CMD_CALL_DL); + GX_WRITE_U32(list); + GX_WRITE_U32(nbytes); +} diff --git a/libs/dolphin/gx/GXDraw.c b/libs/dolphin/gx/GXDraw.c index e69de29bb..c457eb712 100644 --- a/libs/dolphin/gx/GXDraw.c +++ b/libs/dolphin/gx/GXDraw.c @@ -0,0 +1,571 @@ +#include + +#include +#include + +#include + +static GXVtxDescList vcd[27]; +static GXVtxAttrFmtList vat[27]; + +static void GetVertState(void) +{ + GXGetVtxDescv(vcd); + GXGetVtxAttrFmtv(GX_VTXFMT3, vat); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_NRM, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0); +} + +static void RestoreVertState(void) +{ + GXSetVtxDescv(vcd); + GXSetVtxAttrFmtv(GX_VTXFMT3, vat); +} + +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) +{ + s32 i; + f32 top; + f32 bottom; + f32 x[100]; + f32 y[100]; + f32 angle; + + top = 1.0f; + bottom = -top; + ASSERTMSGLINE(216, numEdges <= 99, "GXDrawCylinder: too many edges"); + + GetVertState(); + + for (i = 0; i <= numEdges; i++) + { + 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(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, top); + GXNormal3f32(0.0f, 0.0f, 1.0f); + for (i = 0; i <= numEdges; i++) + { + 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, bottom); + GXNormal3f32(0.0f, 0.0f, -1.0f); + for (i = 0; i <= numEdges; i++) + { + GXPosition3f32(x[i], y[i], bottom); + GXNormal3f32(0.0f, 0.0f, -1.0f); + } + GXEnd(); + + RestoreVertState(); +} + +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/libs/dolphin/gx/GXFifo.c b/libs/dolphin/gx/GXFifo.c index e69de29bb..940304938 100644 --- a/libs/dolphin/gx/GXFifo.c +++ b/libs/dolphin/gx/GXFifo.c @@ -0,0 +1,426 @@ +#include +#include +#include +#include + +#include + +static OSThread* __GXCurrentThread; +static GXBool CPGPLinked; +static BOOL GXOverflowSuspendInProgress; +static GXBreakPtCallback BreakPointCB; +static u32 __GXOverflowCount; + +#if DEBUG +static BOOL IsWGPipeRedirected; +#endif + +__GXFifoObj* CPUFifo; +__GXFifoObj* GPFifo; +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(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); +} + +#define SOME_SET_REG_MACRO(reg, size, shift, val) \ + do \ + { \ + (reg) = \ + (u32)__rlwimi((u32)(reg), (val), (shift), (32 - (shift) - (size)), (31 - (shift))); \ + } while (0); + +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 != NULL) + { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + BreakPointCB(); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } +} + +static void GXCPInterruptHandler(__OSInterrupt interrupt, OSContext* context) +{ + __GXData->cpStatus = GX_GET_CP_REG(0); + if (GET_REG_FIELD(__GXData->cpEnable, 1, 3) && GET_REG_FIELD(__GXData->cpStatus, 1, 1)) + { + GXUnderflowHandler(interrupt, context); + } + if (GET_REG_FIELD(__GXData->cpEnable, 1, 2) && GET_REG_FIELD(__GXData->cpStatus, 1, 0)) + { + GXOverflowHandler(interrupt, context); + } + if (GET_REG_FIELD(__GXData->cpEnable, 1, 5) && GET_REG_FIELD(__GXData->cpStatus, 1, 4)) + { + GXBreakPointHandler(interrupt, context); + } +} + +void GXInitFifoBase(GXFifoObj* fifo, void* base, u32 size) +{ + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + + 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); +} + +void GXInitFifoPtrs(GXFifoObj* fifo, void* readPtr, void* writePtr) +{ + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + BOOL enabled; + + enabled = OSDisableInterrupts(); + realFifo->rdPtr = readPtr; + realFifo->wrPtr = writePtr; + realFifo->count = (u8*)writePtr - (u8*)readPtr; + if (realFifo->count < 0) + { + realFifo->count += realFifo->size; + } + OSRestoreInterrupts(enabled); +} + +void GXInitFifoLimits(GXFifoObj* fifo, u32 hiWatermark, u32 loWatermark) +{ + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + + realFifo->hiWatermark = hiWatermark; + realFifo->loWatermark = loWatermark; +} + +#define GX_SET_PI_REG(offset, val) (*(volatile u32*)((volatile u32*)(__piReg) + (offset)) = val) + +// NONMATCHING DEBUG +void GXSetCPUFifo(GXFifoObj* fifo) +{ + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + BOOL enabled = OSDisableInterrupts(); + + CPUFifo = realFifo; + if (CPUFifo == GPFifo) + { + u32 reg = 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); + + CPGPLinked = GX_TRUE; + + __GXWriteFifoIntReset(1, 1); + __GXWriteFifoIntEnable(1, 0); + __GXFifoLink(1); + } + else + { + u32 reg; + + if (CPGPLinked) + { + __GXFifoLink(0); + CPGPLinked = GX_FALSE; + } + + __GXWriteFifoIntEnable(0, 0); + reg = 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(enabled); +} + +void GXSetGPFifo(GXFifoObj* fifo) +{ + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + BOOL enabled = OSDisableInterrupts(); +#if SDK_REVISION >= 2 + u32 stbtmp; +#endif + + __GXFifoReadDisable(); + __GXWriteFifoIntEnable(0, 0); + GPFifo = realFifo; + + 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) + { + CPGPLinked = GX_TRUE; + __GXWriteFifoIntEnable(1, 0); + __GXFifoLink(1); + } + else + { + CPGPLinked = GX_FALSE; + __GXWriteFifoIntEnable(0, 0); + __GXFifoLink(0); + } + +#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(enabled); +} + +#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 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; + } + } + + *readPtr = realFifo->rdPtr; + *writePtr = realFifo->wrPtr; +} + +GXBreakPtCallback GXSetBreakPtCallback(GXBreakPtCallback cb) +{ + GXBreakPtCallback oldcb = BreakPointCB; + BOOL enabled = OSDisableInterrupts(); + + BreakPointCB = cb; + 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); +} + +void __GXFifoInit(void) +{ + __OSSetInterruptHandler(0x11, GXCPInterruptHandler); + __OSUnmaskInterrupts(0x4000); + __GXCurrentThread = OSGetCurrentThread(); + GXOverflowSuspendInProgress = FALSE; + CPUFifo = NULL; + GPFifo = NULL; +} + +static void __GXFifoReadEnable(void) +{ + SET_REG_FIELD(0, __GXData->cpEnable, 1, 0, 1); + GX_SET_CP_REG(1, __GXData->cpEnable); +} + +static void __GXFifoReadDisable(void) +{ + SET_REG_FIELD(0, __GXData->cpEnable, 1, 0, 0); + GX_SET_CP_REG(1, __GXData->cpEnable); +} + +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); +} + +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); +} + +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); +} + +OSThread* GXSetCurrentGXThread(void) +{ + BOOL enabled; + OSThread* prev; + + enabled = OSDisableInterrupts(); + prev = __GXCurrentThread; + __GXCurrentThread = OSGetCurrentThread(); + OSRestoreInterrupts(enabled); + return prev; +} + +GXFifoObj* GXGetCPUFifo(void) +{ + return (GXFifoObj*)CPUFifo; +} + +GXFifoObj* GXGetGPFifo(void) +{ + return (GXFifoObj*)GPFifo; +} \ No newline at end of file diff --git a/libs/dolphin/gx/GXFrameBuf.c b/libs/dolphin/gx/GXFrameBuf.c index e69de29bb..b6a32d569 100644 --- a/libs/dolphin/gx/GXFrameBuf.c +++ b/libs/dolphin/gx/GXFrameBuf.c @@ -0,0 +1,591 @@ +#include +#include + +#include +#include + +GXRenderModeObj GXNtsc480IntDf = { 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 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 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 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 } }; + +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; + + 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; + + 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_YUVA8: + SET_REG_FIELD(0, __GXData->cpTex, 2, 15, 3); + break; + default: + SET_REG_FIELD(0, __GXData->cpTex, 2, 15, 2); + break; + } + + __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); + + __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); +} + +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); +} + +void GXSetCopyClamp(GXFBClamp clamp) +{ + 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 efbHt, u32 iScale) +{ + u32 count; + u32 realHt; + u32 iScaleD; + + count = (efbHt - 1) * 0x100; + realHt = (count / iScale) + 1; + + iScaleD = iScale; + + if (iScaleD > 0x80 && iScaleD < 0x100) + { + while (iScaleD % 2 == 0) + { + iScaleD /= 2; + } + + if (efbHt % iScaleD == 0) + { + realHt++; + } + } + + if (realHt > 0x400) + { + realHt = 0x400; + } + + return realHt; +} + +f32 GXGetYScaleFactor(u16 efbHeight, u16 xfbHeight) +{ + f32 fScale; + f32 yScale; + u32 iScale; + u32 tgtHt; + u32 realHt; + + 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); + } + + fScale = yScale; + while (realHt < xfbHeight) + { + fScale = yScale; + tgtHt++; + yScale = (f32)tgtHt / (f32)efbHeight; + iScale = (u32)(256.0f / yScale) & 0x1FF; + realHt = __GXGetNumXfbLines(efbHeight, iScale); + } + + return fScale; +} + +u32 GXSetDispCopyYScale(f32 vscale) +{ + u8 enable; + u32 iScale; + u32 ht; + u32 reg; + + 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; + 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); +} + +void GXSetCopyClear(GXColor clear_clr, u32 clear_z) +{ + u32 reg; + + CHECK_GXBEGIN(1596, "GXSetCopyClear"); + //ASSERTMSGLINE(1598, clear_z <= 0xFFFFFF, "GXSetCopyClear: Z clear value is out of range"); + + 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; +} + +void GXCopyTex(void* dest, GXBool clear) +{ + u32 reg; + u32 tempPeCtrl; + u32 phyAddr; + u8 changePeCtrl; + + CHECK_GXBEGIN(1916, "GXCopyTex"); + +#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 = 0; + tempPeCtrl = __GXData->peCtrl; + + if (__GXData->cpTexZ && ((tempPeCtrl & 7) != 3)) + { + changePeCtrl = 1; + SET_REG_FIELD(0, tempPeCtrl, 3, 0, 3); + } + + if ((clear || ((u32)(tempPeCtrl & 7) == 3)) && ((u32)((tempPeCtrl >> 6) & 1) == 1)) + { + changePeCtrl = 1; + SET_REG_FIELD(0, tempPeCtrl, 1, 6, 0); + } + + 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; + SET_REG_FIELD(1965, reg, 21, 0, phyAddr >> 5); + SET_REG_FIELD(1965, reg, 8, 24, 0x4B); + GX_WRITE_RAS_REG(reg); + + 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 (clear) + { + GX_WRITE_RAS_REG(__GXData->zmode); + GX_WRITE_RAS_REG(__GXData->cmode0); + } + + if (changePeCtrl) + { + GX_WRITE_RAS_REG(__GXData->peCtrl); + } + + __GXData->bpSentNot = 0; +} + +void GXClearBoundingBox(void) +{ + u32 reg; + + CHECK_GXBEGIN(2003, "GXClearBoundingBox"); + reg = 0x550003FF; + GX_WRITE_RAS_REG(reg); + reg = 0x560003FF; + GX_WRITE_RAS_REG(reg); + __GXData->bpSentNot = 0; +} \ No newline at end of file diff --git a/libs/dolphin/gx/GXGeometry.c b/libs/dolphin/gx/GXGeometry.c index e69de29bb..a6b7d661c 100644 --- a/libs/dolphin/gx/GXGeometry.c +++ b/libs/dolphin/gx/GXGeometry.c @@ -0,0 +1,192 @@ +#include +#include +#include + +#include + +void __GXSetDirtyState(void) +{ + u32 dState = __GXData->dirtyState; + + if (dState & 1) + { + __GXSetSUTexRegs(); + } + if (dState & 2) + { + __GXUpdateBPMask(); + } + if (dState & 4) + { + __GXSetGenMode(); + } + if (dState & 8) + { + __GXSetVCD(); + } + if (dState & 0x10) + { + __GXSetVAT(); + } + if (dState & 0x18) + { + __GXCalculateVLim(); + } + + __GXData->dirtyState = 0; +} + +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 (__GXData->dirtyState != 0) + { + __GXSetDirtyState(); + } + +#if DEBUG + if (!__GXData->inDispList) + { + __GXVerifyState(vtxfmt); + } + __GXinBegin = 1; +#endif + + if (*(u32*)&__GXData->vNumNot == 0) + { // checks both vNum and bpSentNot + __GXSendFlushPrim(); + } + GX_WRITE_U8(vtxfmt | type); + GX_WRITE_U16(nverts); +} + +void __GXSendFlushPrim(void) +{ + u32 i; + u32 numD = __GXData->vNum * __GXData->vLim; + + GX_WRITE_U8(0x98); + GX_WRITE_U16(__GXData->vNum); + for (i = 0; i < numD; i += 4) + { + GX_WRITE_U32(0); + } + __GXData->bpSentNot = 1; +} + +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; +} + +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/libs/dolphin/gx/GXInit.c b/libs/dolphin/gx/GXInit.c index e69de29bb..86f823eba 100644 --- a/libs/dolphin/gx/GXInit.c +++ b/libs/dolphin/gx/GXInit.c @@ -0,0 +1,562 @@ +#include + +#include +#include +#include +#include + +#include +#include + +#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 + +static GXFifoObj FifoObj; + +static GXData gxData; +GXData* const __GXData = &gxData; + +// these are supposed to be in-function static, but it messed up sbss order +u32 resetFuncRegistered; +u32 calledOnce; +OSTime time; +u32 peCount; + +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 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 (fmt) + { + case GX_TF_RGBA8: + 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 (mm) + { + return &__GXData->TexRegions1[id]; + } + return &__GXData->TexRegions0[id]; + } +} + +static GXTlutRegion* __GXDefaultTlutRegionCallback(u32 idx) +{ + if (idx >= 20) + { + return NULL; + } + return &__GXData->TlutRegions[idx]; +} + +#if DEBUG +static void __GXDefaultVerifyCallback(GXWarningLevel level, u32 id, const char* msg) +{ + OSReport("Level %1d, Warning %3d: %s\n", level, id, msg); +} +#endif + +static int __GXShutdown(BOOL final) +{ + u32 reg; + u32 peCountNew; + OSTime timeNew; + + if (!final) + { + if (!calledOnce) + { + peCount = __GXReadMEMCounterU32(0x28, 0x27); + time = OSGetTime(); + calledOnce = 1; + return 0; + } + + timeNew = OSGetTime(); + peCountNew = __GXReadMEMCounterU32(0x28, 0x27); + + if (timeNew - time < 10) + { + return 0; + } + + if (peCountNew != peCount) + { + peCount = peCountNew; + time = timeNew; + return 0; + } + } + else + { + GXSetBreakPtCallback(NULL); + GXSetDrawSyncCallback(NULL); + GXSetDrawDoneCallback(NULL); + + 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(); + + reg = 0; + GX_SET_CP_REG(1, reg); + + reg = 3; + GX_SET_CP_REG(2, reg); + + __GXData->abtWaitPECopy = 1; + + __GXAbort(); + } + + return 1; +} + +#define SOME_SET_REG_MACRO(reg, size, shift, val) \ + do \ + { \ + (reg) = \ + (u32)__rlwimi((u32)(reg), (val), (shift), (32 - (shift) - (size)), (31 - (shift))); \ + } while (0); + +GXFifoObj* GXInit(void* base, u32 size) +{ + u32 i; + u32 reg; + u32 freqBase; + + OSRegisterVersion(__GXVersion); + + __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 = OSPhysicalToUncached(0xC003000); + __cpReg = OSPhysicalToUncached(0xC000000); + __peReg = OSPhysicalToUncached(0xC001000); + __memReg = OSPhysicalToUncached(0xC004000); + __GXFifoInit(); + GXInitFifoBase(&FifoObj, base, size); + GXSetCPUFifo(&FifoObj); + GXSetGPFifo(&FifoObj); + + if (!resetFuncRegistered) + { + OSRegisterResetFunction(&GXResetFuncInfo); + resetFuncRegistered = 1; + } + + __GXPEInit(); + EnableWriteGatherPipe(); + + __GXData->genMode = 0; + SET_REG_FIELD(0, __GXData->genMode, 8, 24, 0); + __GXData->bpMask = 255; + SET_REG_FIELD(0, __GXData->bpMask, 8, 24, 0x0F); + __GXData->lpSize = 0; + SET_REG_FIELD(0, __GXData->lpSize, 8, 24, 0x22); + + 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; + 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; + SET_REG_FIELD(0, __GXData->iref, 8, 24, 0x27); + + for (i = 0; i < 8; ++i) + { + __GXData->suTs0[i] = 0; + __GXData->suTs1[i] = 0; + SET_REG_FIELD(1144, __GXData->suTs0[i], 8, 24, 0x30 + i * 2); + SET_REG_FIELD(1145, __GXData->suTs1[i], 8, 24, 0x31 + i * 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 = FALSE; + +#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 < 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], + GX_TEXCACHE_32K, GXTexRegionAddrTable[i + 24], GX_TEXCACHE_32K); + GXInitTexCacheRegion(&__GXData->TexRegions2[i], GX_TRUE, GXTexRegionAddrTable[i + 32], + GX_TEXCACHE_32K, GXTexRegionAddrTable[i + 40], GX_TEXCACHE_32K); + } + + for (i = 0; i < 16; i++) + { + GXInitTlutRegion(&__GXData->TlutRegions[i], 0xC0000 + 0x2000 * i, GX_TLUT_256); + } + + for (i = 0; i < 4; i++) + { + GXInitTlutRegion(&__GXData->TlutRegions[i + 16], 0xE0000 + 0x8000 * i, GX_TLUT_1K); + } + + { + u32 reg = 0; +#if DEBUG + s32 regAddr; +#endif + GX_SET_CP_REG(3, reg); + + 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); + + reg = 0x24000000; + GX_WRITE_RAS_REG(reg); + + reg = 0x67000000; + GX_WRITE_RAS_REG(reg); + } + + __GXSetIndirectMask(0); + __GXSetTmemConfig(2); + __GXInitGX(); + + return &FifoObj; +} + +void __GXInitGX(void) +{ + 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: + rmode = &GXNtsc480IntDf; + break; + case VI_PAL: + rmode = &GXPal528IntDf; + break; + case VI_EURGB60: + rmode = &GXEurgb60Hz480IntDf; + break; + case VI_MPAL: + rmode = &GXMpal480IntDf; + break; + default: + //ASSERTMSGLINE(1342, 0, "GXInit: invalid TV format"); + rmode = &GXNtsc480IntDf; + break; + } + + 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(i, __GXData, 0); + } + + 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, 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(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_DISABLE); + GXSetCullMode(GX_CULL_BACK); + GXSetClipMode(GX_CLIP_ENABLE); + GXSetScissor(0, 0, rmode->fbWidth, rmode->efbHeight); + GXSetScissorBoxOffset(0, 0); + GXSetNumChans(0); + 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((GXTexRegionCallback)__GXDefaultTexRegionCallback); + GXSetTlutRegionCallback(__GXDefaultTlutRegionCallback); + + 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); + GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD2, GX_TEXMAP2, GX_COLOR0A0); + GXSetTevOrder(GX_TEVSTAGE3, GX_TEXCOORD3, GX_TEXMAP3, GX_COLOR0A0); + GXSetTevOrder(GX_TEVSTAGE4, GX_TEXCOORD4, GX_TEXMAP4, GX_COLOR0A0); + 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); + GXSetTevOrder(GX_TEVSTAGE11, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE12, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE13, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE14, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE15, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + + 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 = 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); + } + + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_RED, GX_CH_RED, GX_CH_ALPHA); + 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 = GX_TEVSTAGE0; i < GX_MAX_TEVSTAGE; i++) + GXSetTevDirect((GXTevStageID)i); + + GXSetNumIndStages(0); + GXSetIndTexCoordScale(GX_INDTEXSTAGE0, GX_ITS_1, GX_ITS_1); + 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); + + 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_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 : 0)); + + 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(); + + GXPokeColorUpdate(GX_TRUE); + GXPokeAlphaUpdate(GX_TRUE); + GXPokeDither(GX_FALSE); + GXPokeBlendMode(GX_BM_NONE, GX_BL_ZERO, GX_BL_ONE, GX_LO_SET); + GXPokeAlphaMode(GX_ALWAYS, 0); + GXPokeAlphaRead(GX_READ_FF); + GXPokeDstAlpha(GX_DISABLE, 0); + GXPokeZMode(GX_TRUE, GX_ALWAYS, GX_TRUE); + + GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE); + GXClearGPMetric(); +} diff --git a/libs/dolphin/gx/GXLight.c b/libs/dolphin/gx/GXLight.c index e69de29bb..8bc3fb616 100644 --- a/libs/dolphin/gx/GXLight.c +++ b/libs/dolphin/gx/GXLight.c @@ -0,0 +1,457 @@ +#include +#include +#include + +#include + +// 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; + + 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; +} + +void GXInitLightAttnA(GXLightObj* lt_obj, f32 a0, f32 a1, f32 a2) +{ + __GXLightObjInt_struct* obj; + + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(144, "GXInitLightAttnA"); + obj->a[0] = a0; + obj->a[1] = a1; + obj->a[2] = a2; +} + +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: + a0 = -1000.0f * cr; + a1 = 1000.0f; + a2 = 0.0f; + break; + case GX_SP_COS: + a1 = 1.0f / (1.0f - cr); + a0 = -cr * a1; + a2 = 0.0f; + break; + case GX_SP_COS2: + a2 = 1.0f / (1.0f - cr); + a0 = 0.0f; + a1 = -cr * a2; + break; + case GX_SP_SHARP: + 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 - 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 - 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; + } + obj->a[0] = a0; + obj->a[1] = a1; + obj->a[2] = a2; +} + +void GXInitLightDistAttn(GXLightObj* lt_obj, f32 ref_dist, f32 ref_br, GXDistAttnFn dist_func) +{ + f32 k0, k1, k2; + __GXLightObjInt_struct* obj; + + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(275, "GXInitLightDistAttn"); + + 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_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_br * ref_dist * ref_dist); + break; + case GX_DA_STEEP: + k0 = 1.0f; + k1 = 0.0f; + k2 = (1.0f - ref_br) / (ref_br * ref_dist * ref_dist); + break; + case GX_DA_OFF: + default: + k0 = 1.0f; + k1 = 0.0f; + k2 = 0.0f; + break; + } + + obj->k[0] = k0; + obj->k[1] = k1; + obj->k[2] = k2; +} + +void GXInitLightPos(GXLightObj* lt_obj, f32 x, f32 y, f32 z) +{ + __GXLightObjInt_struct* obj; + + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(330, "GXInitLightPos"); + + obj->lpos[0] = x; + obj->lpos[1] = y; + obj->lpos[2] = z; +} + +void GXInitLightDir(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz) +{ + __GXLightObjInt_struct* obj; + + obj = (__GXLightObjInt_struct*)lt_obj; + + obj->ldir[0] = -nx; + obj->ldir[1] = -ny; + obj->ldir[2] = -nz; +} + +void GXInitLightColor(GXLightObj* lt_obj, GXColor color) +{ + __GXLightObjInt_struct* obj; + + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(463, "GXInitLightColor"); + + *(u32*)&obj->Color = *(u32*)&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) +{ + register u32 zero, color; + register f32 a0_a1, a2_k0, k1_k2; + register f32 px_py, pz_dx, dy_dz; +#ifdef __MWERKS__ // clang-format off + asm { + lwz color, 12(lt_obj) + xor zero, zero, zero + psq_l a0_a1, 16(lt_obj), 0, 0 + psq_l a2_k0, 24(lt_obj), 0, 0 + psq_l k1_k2, 32(lt_obj), 0, 0 + psq_l px_py, 40(lt_obj), 0, 0 + psq_l pz_dx, 48(lt_obj), 0, 0 + psq_l dy_dz, 56(lt_obj), 0, 0 + + stw zero, 0(dest) + stw zero, 0(dest) + stw zero, 0(dest) + stw color, 0(dest) + psq_st a0_a1, 0(dest), 0, 0 + psq_st a2_k0, 0(dest), 0, 0 + psq_st k1_k2, 0(dest), 0, 0 + psq_st px_py, 0(dest), 0, 0 + psq_st pz_dx, 0(dest), 0, 0 + psq_st dy_dz, 0(dest), 0, 0 + } +#endif // clang-format on +} + +void GXLoadLightObjImm(GXLightObj* lt_obj, GXLightID light) +{ + u32 addr; + u32 idx; + __GXLightObjInt_struct* obj; + + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(569, "GXLoadLightObjImm"); + +#if DEBUG + idx = ConvLightID2Num(light); +#else + idx = 31 - __cntlzw(light); +#endif + + idx &= 7; + + addr = idx * 0x10 + 0x600; + GX_WRITE_U8(0x10); + GX_WRITE_U32(addr | 0xF0000); + +#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 + + __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]; + 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]; + 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]; + SET_REG_FIELD(696, reg, 8, 0, amb_color.a); + colIdx = 0; + break; + case GX_ALPHA1: + reg = __GXData->ambColor[GX_COLOR1]; + SET_REG_FIELD(702, reg, 8, 0, amb_color.a); + colIdx = 1; + break; + case GX_COLOR0A0: + reg = GXCOLOR_AS_U32(amb_color); + colIdx = 0; + break; + case GX_COLOR1A1: + reg = GXCOLOR_AS_U32(amb_color); + colIdx = 1; + break; + default: + return; + } + + GX_WRITE_XF_REG(colIdx + 10, reg); + __GXData->bpSentNot = 1; + __GXData->ambColor[colIdx] = reg; +} + +void GXSetChanMatColor(GXChannelID chan, GXColor mat_color) +{ + u32 reg; + u32 rgb; + u32 colIdx; + + CHECK_GXBEGIN(762, "GXSetChanMatColor"); + + switch (chan) + { + case GX_COLOR0: + reg = __GXData->matColor[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]; + 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]; + SET_REG_FIELD(797, reg, 8, 0, mat_color.a); + colIdx = 0; + break; + case GX_ALPHA1: + reg = __GXData->matColor[GX_COLOR1]; + SET_REG_FIELD(803, reg, 8, 0, mat_color.a); + colIdx = 1; + break; + case GX_COLOR0A0: + reg = GXCOLOR_AS_U32(mat_color); + colIdx = 0; + break; + case GX_COLOR1A1: + reg = GXCOLOR_AS_U32(mat_color); + colIdx = 1; + break; + default: + return; + } + + GX_WRITE_XF_REG(colIdx + 12, reg); + __GXData->bpSentNot = 1; + __GXData->matColor[colIdx] = reg; +} + +void GXSetNumChans(u8 nChans) +{ + CHECK_GXBEGIN(857, "GXSetNumChans"); + + SET_REG_FIELD(860, __GXData->genMode, 3, 4, nChans); + GX_WRITE_XF_REG(9, nChans); + __GXData->dirtyState |= 4; +} + +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; + + CHECK_GXBEGIN(892, "GXSetChanCtrl"); + +#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 = 1; +} diff --git a/libs/dolphin/gx/GXMisc.c b/libs/dolphin/gx/GXMisc.c index e69de29bb..e3c11f1c5 100644 --- a/libs/dolphin/gx/GXMisc.c +++ b/libs/dolphin/gx/GXMisc.c @@ -0,0 +1,346 @@ +#include +#include +#include +#include +#include + +#include +#include + +static GXDrawSyncCallback TokenCB; +static GXDrawDoneCallback DrawDoneCB; +static u8 DrawDone; +static OSThreadQueue FinishQueue; + +void GXSetMisc(GXMiscToken token, u32 val) +{ + switch (token) + { + case GX_MT_XF_FLUSH: + __GXData->vNum = val; + __GXData->vNumNot = !__GXData->vNum; + __GXData->bpSentNot = 1; + + if (__GXData->vNum != 0) + { + __GXData->dirtyState |= 8; + } + break; + case GX_MT_DL_SAVE_CONTEXT: + __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; + } +} + +void GXFlush(void) +{ + CHECK_GXBEGIN(270, "GXFlush"); + if (__GXData->dirtyState) + { + __GXSetDirtyState(); + } + + 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; + OSTime time1; + + time0 = OSGetTime(); + do + { + time1 = OSGetTime(); + } while (time1 - time0 <= (clocks / 4)); +} + +static void __GXAbortWaitPECopyDone(void) +{ + u32 peCnt0; + u32 peCnt1; + + peCnt0 = __GXReadMEMCounterU32(0x28, 0x27); + do + { + peCnt1 = peCnt0; + __GXAbortWait(32); + + peCnt0 = __GXReadMEMCounterU32(0x28, 0x27); + } while (peCnt0 != peCnt1); +} + +void __GXAbort(void) +{ + if (__GXData->abtWaitPECopy && GXGetGPFifo() != (GXFifoObj*)NULL) + { + __GXAbortWaitPECopyDone(); + } + + __PIRegs[0x18 / 4] = 1; + __GXAbortWait(200); + __PIRegs[0x18 / 4] = 0; + __GXAbortWait(20); +} + +void GXSetDrawSync(u16 token) +{ + BOOL enabled; + u32 reg; + + CHECK_GXBEGIN(430, "GXSetDrawSync"); + + 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; +} + +void GXSetDrawDone(void) +{ + u32 reg; + BOOL enabled; + + CHECK_GXBEGIN(488, "GXSetDrawDone"); + enabled = OSDisableInterrupts(); + reg = 0x45000002; + GX_WRITE_RAS_REG(reg); + GXFlush(); + DrawDone = 0; + OSRestoreInterrupts(enabled); +} + +void GXWaitDrawDone(void) +{ + BOOL enabled; + + CHECK_GXBEGIN(534, "GXWaitDrawDone"); + + enabled = OSDisableInterrupts(); + while (!DrawDone) + { + OSSleepThread(&FinishQueue); + } + OSRestoreInterrupts(enabled); +} + +void GXDrawDone(void) +{ + // GXSetDrawDone uses GXFlush() + // This functions requires less lines in GXFlush + // but then GXFlush doesnt match + CHECK_GXBEGIN(566, "GXDrawDone"); + GXSetDrawDone(); + GXWaitDrawDone(); +} + +void GXPixModeSync(void) +{ + CHECK_GXBEGIN(601, "GXPixModeSync"); + GX_WRITE_RAS_REG(__GXData->peCtrl); + __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); +} + +void GXPokeAlphaRead(GXAlphaReadMode mode) +{ + 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); +} + +void GXPokeAlphaUpdate(GXBool update_enable) +{ + u32 reg; + + reg = GX_GET_PE_REG(1); + SET_REG_FIELD(704, reg, 1, 4, update_enable); + GX_SET_PE_REG(1, reg); +} + +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); +} + +void GXPokeDstAlpha(GXBool enable, u8 alpha) +{ + 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); +} + +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); +} + +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); +} + +GXDrawSyncCallback GXSetDrawSyncCallback(GXDrawSyncCallback cb) +{ + GXDrawSyncCallback oldcb; + BOOL enabled; + + oldcb = TokenCB; + enabled = OSDisableInterrupts(); + TokenCB = cb; + OSRestoreInterrupts(enabled); + return oldcb; +} + +static void GXTokenInterruptHandler(__OSInterrupt interrupt, OSContext* context) +{ + u16 token; + OSContext exceptionContext; + u32 reg; + + token = GX_GET_PE_REG(7); + if (TokenCB != NULL) + { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + TokenCB(token); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } + reg = GX_GET_PE_REG(5); + SET_REG_FIELD(0, reg, 1, 2, 1); + GX_SET_PE_REG(5, reg); +} + +GXDrawDoneCallback GXSetDrawDoneCallback(GXDrawDoneCallback cb) +{ + GXDrawDoneCallback oldcb; + BOOL enabled; + + oldcb = DrawDoneCB; + enabled = OSDisableInterrupts(); + DrawDoneCB = cb; + OSRestoreInterrupts(enabled); + return oldcb; +} + +static void GXFinishInterruptHandler(__OSInterrupt interrupt, OSContext* context) +{ + OSContext exceptionContext; + u32 reg; + + reg = GX_GET_PE_REG(5); + SET_REG_FIELD(0, reg, 1, 3, 1); + GX_SET_PE_REG(5, reg); + DrawDone = 1; + if (DrawDoneCB != NULL) + { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + DrawDoneCB(); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } + OSWakeupThread(&FinishQueue); +} + +void __GXPEInit(void) +{ + u32 reg; + __OSSetInterruptHandler(0x12, GXTokenInterruptHandler); + __OSSetInterruptHandler(0x13, GXFinishInterruptHandler); + OSInitThreadQueue(&FinishQueue); + __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); +} diff --git a/libs/dolphin/gx/GXPerf.c b/libs/dolphin/gx/GXPerf.c index e69de29bb..662872553 100644 --- a/libs/dolphin/gx/GXPerf.c +++ b/libs/dolphin/gx/GXPerf.c @@ -0,0 +1,364 @@ +#include +#include +#include + +#include + +void GXSetGPMetric(GXPerf0 perf0, GXPerf1 perf1) +{ + u32 reg; + + CHECK_GXBEGIN(134, "GXSetGPMetric"); + + switch (__GXData->perf0) + { + 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_CLIP_RATIO: + case GX_PERF0_CLOCKS: + reg = 0; + GX_WRITE_XF_REG(6, reg); + break; + 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: + reg = 0x23000000; + GX_WRITE_RAS_REG(reg); + break; + 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: + reg = 0x24000000; + GX_WRITE_RAS_REG(reg); + break; + case GX_PERF0_NONE: + break; + default: + + break; + } + + switch (__GXData->perf1) + { + case GX_PERF1_TEXELS: + case GX_PERF1_TX_IDLE: + case GX_PERF1_TX_REGS: + case GX_PERF1_TX_MEMSTALL: + case GX_PERF1_TC_CHECK1_2: + case GX_PERF1_TC_CHECK3_4: + case GX_PERF1_TC_CHECK5_6: + case GX_PERF1_TC_CHECK7_8: + case GX_PERF1_TC_MISS: + case GX_PERF1_CLOCKS: + 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: + 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: + 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: + reg = 0; + GX_SET_CP_REG(3, reg); + break; + case GX_PERF1_NONE: + break; + default: + + break; + } + + __GXData->perf0 = perf0; + switch (__GXData->perf0) + { + case GX_PERF0_VERTICES: + + reg = 0x273; + GX_WRITE_XF_REG(6, reg); + break; + 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: + + break; + } + + __GXData->perf1 = perf1; + switch (__GXData->perf1) + { + 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: + + break; + } + + __GXData->bpSentNot = 0; +} + +void GXClearGPMetric(void) +{ + u32 reg; + + reg = 4; + GX_SET_CP_REG(2, reg); +} diff --git a/libs/dolphin/gx/GXPixel.c b/libs/dolphin/gx/GXPixel.c index e69de29bb..47bb5ebd3 100644 --- a/libs/dolphin/gx/GXPixel.c +++ b/libs/dolphin/gx/GXPixel.c @@ -0,0 +1,321 @@ +#include +#include +#include +#include +#include + +#include + +void GXSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color) +{ + 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; + + fogclr = 0; + fog0 = 0; + fog1 = 0; + fog2 = 0; + fog3 = 0; + + CHECK_GXBEGIN(138, "GXSetFog"); + + 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)); + a = A * (farz - nearz); + c = A * (startz - nearz); + } + } + 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 = 0; + while (B_mant > 1.0) + { + B_mant /= 2.0f; + B_expn++; + } + while (B_mant > 0.0f && B_mant < 0.5) + { + B_mant *= 2.0f; + B_expn--; + } + + a = A / (f32)(1 << (B_expn + 1)); + b_m = 8.388638e6f * B_mant; + b_s = B_expn + 1; + c = C; + + SET_REG_FIELD(198, fog1, 24, 0, b_m); + SET_REG_FIELD(198, fog1, 8, 24, 0xEF); + + SET_REG_FIELD(201, fog2, 5, 0, b_s); + SET_REG_FIELD(201, fog2, 8, 24, 0xF0); + } + + a_hex = *(u32*)&a; + c_hex = *(u32*)&c; + + 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); + + 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)); + + SET_REG_FIELD(217, fog3, 1, 20, proj); + SET_REG_FIELD(218, fog3, 3, 21, fsel); + SET_REG_FIELD(218, fog3, 8, 24, 0xF1); + + rgba = *(u32*)&color; + SET_REG_FIELD(222, fogclr, 24, 0, rgba >> 8); + SET_REG_FIELD(222, fogclr, 8, 24, 0xF2); + + 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; +} + +void GXSetFogRangeAdj(GXBool enable, u16 center, GXFogAdjTable* table) +{ + u32 i; + u32 range_adj; + u32 range_c; + + CHECK_GXBEGIN(331, "GXSetFogRangeAdj"); + + if (enable) + { + for (i = 0; i < 10; i += 2) + { + range_adj = 0; + // complains about r + // 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); + } + } + 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; +} + +void GXSetBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor, + GXLogicOp op) +{ + u32 reg; + u32 blend_en; + + CHECK_GXBEGIN(375, "GXSetBlendMode"); + + 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; +} + +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; +} + +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; +} + +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; +} + +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; +} + +void GXSetPixelFmt(GXPixelFmt pix_fmt, GXZFmt16 z_fmt) +{ + u32 oldPeCtrl; + u8 aa; + static u32 p2f[8] = { 0, 1, 2, 3, 4, 4, 4, 5 }; + + CHECK_GXBEGIN(511, "GXSetPixelFmt"); + oldPeCtrl = __GXData->peCtrl; + + SET_REG_FIELD(517, __GXData->peCtrl, 3, 0, p2f[pix_fmt]); + SET_REG_FIELD(518, __GXData->peCtrl, 3, 3, z_fmt); + + 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[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 = 0; +} + +void GXSetDither(GXBool dither) +{ + 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; +} + +void GXSetDstAlpha(GXBool enable, u8 alpha) +{ + 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; +} + +void GXSetFieldMask(GXBool odd_mask, GXBool even_mask) +{ + u32 reg; + + 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; +} + +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(); + reg = field_mode | 0x68000000; + GX_WRITE_RAS_REG(reg); + __GXFlushTextureState(); +} diff --git a/libs/dolphin/gx/GXSave.c b/libs/dolphin/gx/GXSave.c new file mode 100644 index 000000000..42cb0b664 --- /dev/null +++ b/libs/dolphin/gx/GXSave.c @@ -0,0 +1,601 @@ +#if DEBUG + +#include +#include + +#include + +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/libs/dolphin/gx/GXStubs.c b/libs/dolphin/gx/GXStubs.c new file mode 100644 index 000000000..438c03104 --- /dev/null +++ b/libs/dolphin/gx/GXStubs.c @@ -0,0 +1,7 @@ +#include + +#include + +void __GXSetRange(f32 nearz, f32 fgSideX) +{ +} diff --git a/libs/dolphin/gx/GXTev.c b/libs/dolphin/gx/GXTev.c index e69de29bb..7dc8ae2d9 100644 --- a/libs/dolphin/gx/GXTev.c +++ b/libs/dolphin/gx/GXTev.c @@ -0,0 +1,486 @@ +#include +#include + +#include + +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 +}; + +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 +}; + +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 +}; + +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 +}; + +#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; + + CHECK_GXBEGIN(420, "GXSetTevOp"); + + if (id == GX_TEVSTAGE0) + { + ctmp = (u32*)TEVCOpTableST0 + mode; + atmp = (u32*)TEVAOpTableST0 + mode; + } + else + { + 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"); + + tevReg = __GXData->tevc[stage]; + 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"); + + tevReg = __GXData->teva[stage]; + 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 = 0; +} + +void GXSetTevColorOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, + GXTevRegID out_reg) +{ + u32 tevReg; + + CHECK_GXBEGIN(653, "GXSetTevColorOp"); + + tevReg = __GXData->tevc[stage]; + SET_REG_FIELD(663, tevReg, 1, 18, op & 1); + if (op <= 1) + { + SET_REG_FIELD(665, tevReg, 2, 20, scale); + SET_REG_FIELD(666, tevReg, 2, 16, bias); + } + else + { + 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); + + GX_WRITE_RAS_REG(tevReg); + __GXData->tevc[stage] = tevReg; + __GXData->bpSentNot = 0; +} + +void GXSetTevAlphaOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, + GXTevRegID out_reg) +{ + u32 tevReg; + + CHECK_GXBEGIN(699, "GXSetTevAlphaOp"); + + tevReg = __GXData->teva[stage]; + SET_REG_FIELD(708, tevReg, 1, 18, op & 1); + if (op <= 1) + { + SET_REG_FIELD(710, tevReg, 2, 20, scale); + SET_REG_FIELD(711, tevReg, 2, 16, bias); + } + else + { + 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); + + GX_WRITE_RAS_REG(tevReg); + __GXData->teva[stage] = tevReg; + __GXData->bpSentNot = 0; +} + +void GXSetTevColor(GXTevRegID id, GXColor color) +{ + u32 rgba; + u32 regRA; + u32 regBG; + + CHECK_GXBEGIN(740, "GXSetTevColor"); + rgba = *(u32*)&color; + + regRA = (0xE0 + id * 2) << 24; + SET_REG_FIELD(745, regRA, 8, 0, rgba >> 24); + SET_REG_FIELD(746, regRA, 8, 12, rgba & 0xFF); + + 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; +} + +void GXSetTevColorS10(GXTevRegID id, GXColorS10 color) +{ + u32 sRG; + u32 sBA; + u32 regRA; + u32 regBG; + + CHECK_GXBEGIN(782, "GXSetTevColorS10"); + sRG = *(u32*)&color; + sBA = *((u32*)&color + 1); + + 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; +} + +void GXSetTevKColor(GXTevKColorID id, GXColor color) +{ + u32 rgba; + u32 regRA; + u32 regBG; + + CHECK_GXBEGIN(833, "GXSetTevKColor"); + rgba = *(u32*)&color; + + 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); + + 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); + + GX_WRITE_RAS_REG(regRA); + GX_WRITE_RAS_REG(regBG); + + __GXData->bpSentNot = 0; +} + +void GXSetTevKColorSel(GXTevStageID stage, GXTevKColorSel sel) +{ + u32* Kreg; + + CHECK_GXBEGIN(872, "GXSetTevKColorSel"); + + Kreg = &__GXData->tevKsel[stage >> 1]; + if (stage & 1) + { + SET_REG_FIELD(0x36E, *Kreg, 5, 14, sel); + } + else + { + SET_REG_FIELD(0x370, *Kreg, 5, 4, sel); + } + + GX_WRITE_RAS_REG(*Kreg); + __GXData->bpSentNot = 0; +} + +void GXSetTevKAlphaSel(GXTevStageID stage, GXTevKAlphaSel sel) +{ + u32* Kreg; + + CHECK_GXBEGIN(905, "GXSetTevKAlphaSel"); + + Kreg = &__GXData->tevKsel[stage >> 1]; + if (stage & 1) + { + SET_REG_FIELD(911, *Kreg, 5, 19, sel); + } + else + { + SET_REG_FIELD(913, *Kreg, 5, 9, sel); + } + + GX_WRITE_RAS_REG(*Kreg); + __GXData->bpSentNot = 0; +} + +void GXSetTevSwapMode(GXTevStageID stage, GXTevSwapSel ras_sel, GXTevSwapSel tex_sel) +{ + u32* pTevReg; + + CHECK_GXBEGIN(942, "GXSetTevSwapMode"); + + 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; +} + +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 + + CHECK_GXBEGIN(978, "GXSetTevSwapModeTable"); + +#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); + + GX_WRITE_RAS_REG(*Kreg); + + Kreg = &__GXData->tevKsel[table * 2 + 1]; + SET_REG_FIELD(987, *Kreg, 2, 0, blue); + SET_REG_FIELD(988, *Kreg, 2, 2, alpha); + + GX_WRITE_RAS_REG(*Kreg); + __GXData->bpSentNot = 0; +} + +void GXSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1) +{ + u32 reg; + + CHECK_GXBEGIN(1046, "GXSetAlphaCompare"); + reg = 0xF3000000; + + 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); + + GX_WRITE_RAS_REG(reg); + __GXData->bpSentNot = 0; +} + +void GXSetZTexture(GXZTexOp op, GXTexFmt fmt, u32 bias) +{ + u32 zenv0; + u32 zenv1; + u32 type; + + CHECK_GXBEGIN(1077, "GXSetZTexture"); + + 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: + type = 0; + break; + case GX_TF_Z16: + type = 1; + break; + case GX_TF_Z24X8: + type = 2; + break; + default: + type = 2; + break; + } + + 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_WRITE_RAS_REG(zenv0); + GX_WRITE_RAS_REG(zenv1); + __GXData->bpSentNot = 0; +} + +void GXSetTevOrder(GXTevStageID stage, GXTexCoordID coord, GXTexMapID map, GXChannelID color) +{ + u32* ptref; + u32 tmap; + u32 tcoord; + static int c2r[] = { 0, 1, 0, 1, 0, 1, 7, 5, 6 }; + + CHECK_GXBEGIN(1131, "GXSetTevOrder"); + + ptref = &__GXData->tref[stage / 2]; + __GXData->texmapId[stage] = map; + + tmap = map & ~GX_TEX_DISABLE; + tmap = (tmap >= GX_MAX_TEXMAP) ? GX_TEXMAP0 : tmap; + + if (coord >= GX_MAX_TEXCOORD) + { + tcoord = GX_TEXCOORD0; + __GXData->tevTcEnab = __GXData->tevTcEnab & ~(1 << stage); + } + else + { + tcoord = coord; + __GXData->tevTcEnab = __GXData->tevTcEnab | (1 << stage); + } + + if (stage & 1) + { + 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 + { + 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_WRITE_RAS_REG(*ptref); + __GXData->bpSentNot = 0; + __GXData->dirtyState |= 1; +} + +void GXSetNumTevStages(u8 nStages) +{ + CHECK_GXBEGIN(1187, "GXSetNumTevStages"); + + SET_REG_FIELD(1190, __GXData->genMode, 4, 10, nStages - 1); + __GXData->dirtyState |= 4; +} diff --git a/libs/dolphin/gx/GXTexture.c b/libs/dolphin/gx/GXTexture.c index e69de29bb..3e1493494 100644 --- a/libs/dolphin/gx/GXTexture.c +++ b/libs/dolphin/gx/GXTexture.c @@ -0,0 +1,856 @@ +#include +#include + +#include + +// 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 0x8: + case GX_TF_CMPR: + case GX_CTF_R4: + case GX_CTF_Z4: + *rowTileS = 3; + *colTileS = 3; + break; + case GX_TF_I8: + case GX_TF_IA4: + 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_Z8M: + case GX_CTF_Z8L: + *rowTileS = 3; + *colTileS = 2; + break; + case GX_TF_IA8: + case GX_TF_RGB565: + case GX_TF_RGB5A3: + case GX_TF_RGBA8: + case 0xA: + case GX_TF_Z16: + case GX_TF_Z24X8: + case GX_CTF_RA8: + case GX_CTF_RG8: + case GX_CTF_GB8: + case GX_CTF_Z16L: + *rowTileS = 2; + *colTileS = 2; + break; + default: + *rowTileS = *colTileS = 0; + //ASSERTMSGLINEV(444, 0, "%s: invalid texture format", "GX"); + break; + } +} + +u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, GXBool mipmap, u8 max_lod) +{ + u32 tileShiftX; + u32 tileShiftY; + u32 tileBytes; + u32 bufferSize; + u32 nx; + u32 ny; + u32 level; + + __GXGetTexTileShift(format, &tileShiftX, &tileShiftY); + if (format == GX_TF_RGBA8 || format == GX_TF_Z24X8) + { + tileBytes = 64; + } + else + { + tileBytes = 32; + } + + if (mipmap == GX_TRUE) + { + nx = 1 << (31 - __cntlzw(width)); + ny = 1 << (31 - __cntlzw(height)); + + bufferSize = 0; + 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; + } + } + else + { + nx = (width + (1 << tileShiftX) - 1) >> tileShiftX; + ny = (height + (1 << tileShiftY) - 1) >> tileShiftY; + bufferSize = nx * ny * tileBytes; + } + + return bufferSize; +} + +void __GetImageTileCount(GXTexFmt fmt, u16 wd, u16 ht, u32* rowTiles, u32* colTiles, u32* cmpTiles) +{ + u32 texRowShift; + u32 texColShift; + + __GXGetTexTileShift(fmt, &texRowShift, &texColShift); + if (wd == 0) + { + wd = 1; + } + if (ht == 0) + { + ht = 1; + } + *rowTiles = (wd + (1 << texRowShift) - 1) >> texRowShift; + *colTiles = (ht + (1 << texColShift) - 1) >> texColShift; + *cmpTiles = (fmt == GX_TF_RGBA8 || fmt == GX_TF_Z24X8) ? 2 : 1; +} + +#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, const void* image_ptr, u16 width, u16 height, GXTexFmt format, + GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, GXBool mipmap) +{ + u32 imageBase; + u32 maxLOD; + u16 rowT; + u16 colT; + u32 rowC; + u32 colC; + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + CHECK_GXBEGIN(567, "GXInitTexObj"); + +#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 (format == 8 || format == 9 || format == 10) + { + SOME_SET_REG_MACRO(t->mode0, 3, 5, 5); + } + else + { + SOME_SET_REG_MACRO(t->mode0, 3, 5, 6); + } + + 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 + { + SOME_SET_REG_MACRO(t->mode0, 3, 5, 4); + } + + 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); + + imageBase = (u32)((u32)image_ptr >> 5) & 0x01FFFFFF; + SET_REG_FIELD(656, t->image3, 21, 0, imageBase); + + switch (format & 0xF) + { + case GX_TF_I4: + case 8: + t->loadFmt = 1; + rowT = 3; + colT = 3; + break; + case GX_TF_I8: + case GX_TF_IA4: + case 9: + t->loadFmt = 2; + rowT = 3; + colT = 2; + break; + case GX_TF_IA8: + case GX_TF_RGB565: + case GX_TF_RGB5A3: + case 10: + t->loadFmt = 2; + rowT = 2; + colT = 2; + break; + case GX_TF_RGBA8: + t->loadFmt = 3; + rowT = 2; + colT = 2; + break; + case GX_TF_CMPR: + t->loadFmt = 0; + rowT = 3; + colT = 3; + break; + default: + + t->loadFmt = 2; + rowT = 2; + colT = 2; + break; + } + + rowC = (width + (1 << rowT) - 1) >> rowT; + colC = (height + (1 << colT) - 1) >> colT; + t->loadCnt = (rowC * colC) & 0x7FFF; + t->flags |= 2; +} + +void GXInitTexObjCI(GXTexObj* obj, const void* image_ptr, u16 width, u16 height, GXCITexFmt format, + GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, GXBool mipmap, u32 tlut_name) +{ + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + CHECK_GXBEGIN(739, "GXInitTexObjCI"); + GXInitTexObj(obj, image_ptr, width, height, format, wrap_s, wrap_t, mipmap); + t->flags &= 0xFFFFFFFD; + t->tlutName = tlut_name; +} + +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; + + CHECK_GXBEGIN(778, "GXInitTexObjLOD"); + + 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(788, t->mode0, 8, 9, lbias); + + SET_REG_FIELD(792, t->mode0, 1, 4, (mag_filt == GX_LINEAR) ? 1 : 0); + + 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 (min_lod < 0.0f) + { + min_lod = 0.0f; + } + else if (min_lod > 10.0f) + { + min_lod = 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; + } + lmax = 16.0f * max_lod; + SET_REG_FIELD(816, t->mode1, 8, 0, lmin); + SET_REG_FIELD(817, t->mode1, 8, 8, lmax); +} + +GXTexFmt GXGetTexObjFmt(const GXTexObj* to) +{ + const __GXTexObjInt* t = (const __GXTexObjInt*)to; + + return t->fmt; +} + +GXBool GXGetTexObjMipMap(const GXTexObj* to) +{ + const __GXTexObjInt* t = (const __GXTexObjInt*)to; + + return (t->flags & 1) == 1; +} + +f32 GXGetTexObjLODBias(const GXTexObj* tex_obj) +{ + s16 tmp; + const __GXTexObjInt* t = (const __GXTexObjInt*)tex_obj; + + 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; + + return (u32)GET_REG_FIELD(t->mode0, 1, 21); +} + +GXBool GXGetTexObjEdgeLOD(const GXTexObj* tex_obj) +{ + const __GXTexObjInt* t = (const __GXTexObjInt*)tex_obj; + + return !GET_REG_FIELD(t->mode0, 1, 8); +} + +GXAnisotropy GXGetTexObjMaxAniso(const GXTexObj* tex_obj) +{ + const __GXTexObjInt* t = (const __GXTexObjInt*)tex_obj; + + return GET_REG_FIELD(t->mode0, 2, 19); +} + +u32 GXGetTexObjTlut(const GXTexObj* tex_obj) +{ + const __GXTexObjInt* t = (const __GXTexObjInt*)tex_obj; + + 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; + + CHECK_GXBEGIN(1259, "GXLoadTexObjPreLoaded"); + + 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)) + { + tlr = (__GXTlutRegionInt*)__GXData->tlutRegionCallback(t->tlutName); + + SET_REG_FIELD(1291, tlr->tlutObj.tlut, 8, 24, GXTexTlutIds[id]); + GX_WRITE_RAS_REG(tlr->tlutObj.tlut); + } + + __GXData->tImage0[id] = t->image0; + __GXData->tMode0[id] = t->mode0; + __GXData->dirtyState |= 1; + __GXData->bpSentNot = 0; +} + +void GXLoadTexObj(GXTexObj* obj, GXTexMapID id) +{ + GXTexRegion* r; + + CHECK_GXBEGIN(1318, "GXLoadTexObj"); + + r = __GXData->texRegionCallback(obj, id); + + GXLoadTexObjPreLoaded(obj, r, id); +} + +void GXInitTlutObj(GXTlutObj* tlut_obj, const void* lut, GXTlutFmt fmt, u16 n_entries) +{ + __GXTlutObjInt* t = (__GXTlutObjInt*)tlut_obj; + + CHECK_GXBEGIN(1351, "GXInitTlutObj"); + + 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 GXLoadTlut(const GXTlutObj* tlut_obj, u32 tlut_name) +{ + __GXTlutRegionInt* r; + u32 tlut_offset; + __GXTlutObjInt* t = (__GXTlutObjInt*)tlut_obj; + + CHECK_GXBEGIN(1434, "GXLoadTlut"); + + r = (__GXTlutRegionInt*)__GXData->tlutRegionCallback(tlut_name); + + __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; + + CHECK_GXBEGIN(1486, "GXInitTexCacheRegion"); + + 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: + + 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: + 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 GXInitTlutRegion(GXTlutRegion* region, u32 tmem_addr, GXTlutSize tlut_size) +{ + __GXTlutRegionInt* t = (__GXTlutRegionInt*)region; + + CHECK_GXBEGIN(1654, "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 GXInvalidateTexRegion(const GXTexRegion* region) +{ + s32 wle; + s32 hle; + s32 wlo; + s32 hlo; + s32 count; + u32 reg0; + u32 reg1; + __GXTexRegionInt* r = (__GXTexRegionInt*)region; + + 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 GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 ss, u16 ts) +{ + CHECK_GXBEGIN(1989, "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; + } +} + +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: + tmap = GET_REG_FIELD(__GXData->iref, 3, 0); + coord = GET_REG_FIELD(__GXData->iref, 3, 3); + break; + case 1: + tmap = GET_REG_FIELD(__GXData->iref, 3, 6); + coord = GET_REG_FIELD(__GXData->iref, 3, 9); + break; + case 2: + tmap = GET_REG_FIELD(__GXData->iref, 3, 12); + coord = GET_REG_FIELD(__GXData->iref, 3, 15); + break; + case 3: + tmap = GET_REG_FIELD(__GXData->iref, 3, 18); + coord = GET_REG_FIELD(__GXData->iref, 3, 21); + break; + } + if (!(__GXData->tcsManEnab & (1 << coord))) + { + __SetSURegs(tmap, coord); + } + } + + i = 0; + for (i = 0; i < nStages; i++) + { + ptref = &__GXData->tref[i / 2]; + map = __GXData->texmapId[i]; + tmap = map & 0xFFFFFEFF; + if (i & 1) + { + coord = GET_REG_FIELD(*ptref, 3, 15); + } + else + { + coord = GET_REG_FIELD(*ptref, 3, 3); + } + if ((tmap != 0xFF) && !(__GXData->tcsManEnab & (1 << coord)) && + (__GXData->tevTcEnab & (1 << i))) + { + __SetSURegs(tmap, coord); + } + } + } +} + +void __GXSetTmemConfig(u32 config) +{ + switch (config) + { + case 2: + GX_WRITE_RAS_REG(0x8c0d8000); + GX_WRITE_RAS_REG(0x900dc000); + + GX_WRITE_RAS_REG(0x8d0d8800); + GX_WRITE_RAS_REG(0x910dc800); + + GX_WRITE_RAS_REG(0x8e0d9000); + GX_WRITE_RAS_REG(0x920dd000); + + GX_WRITE_RAS_REG(0x8f0d9800); + GX_WRITE_RAS_REG(0x930dd800); + + GX_WRITE_RAS_REG(0xac0da000); + GX_WRITE_RAS_REG(0xb00dc400); + + GX_WRITE_RAS_REG(0xad0da800); + GX_WRITE_RAS_REG(0xb10dcc00); + + GX_WRITE_RAS_REG(0xae0db000); + GX_WRITE_RAS_REG(0xb20dd400); + + GX_WRITE_RAS_REG(0xaf0db800); + GX_WRITE_RAS_REG(0xb30ddc00); + break; + case 1: + GX_WRITE_RAS_REG(0x8c0d8000); + GX_WRITE_RAS_REG(0x900dc000); + + GX_WRITE_RAS_REG(0x8d0d8800); + GX_WRITE_RAS_REG(0x910dc800); + + GX_WRITE_RAS_REG(0x8e0d9000); + GX_WRITE_RAS_REG(0x920dd000); + + GX_WRITE_RAS_REG(0x8f0d9800); + GX_WRITE_RAS_REG(0x930dd800); + + GX_WRITE_RAS_REG(0xac0da000); + GX_WRITE_RAS_REG(0xb00de000); + + GX_WRITE_RAS_REG(0xad0da800); + GX_WRITE_RAS_REG(0xb10de800); + + GX_WRITE_RAS_REG(0xae0db000); + GX_WRITE_RAS_REG(0xb20df000); + + GX_WRITE_RAS_REG(0xaf0db800); + GX_WRITE_RAS_REG(0xb30df800); + + break; + case 0: + default: + GX_WRITE_RAS_REG(0x8c0d8000); + GX_WRITE_RAS_REG(0x900dc000); + + GX_WRITE_RAS_REG(0x8d0d8400); + GX_WRITE_RAS_REG(0x910dc400); + + GX_WRITE_RAS_REG(0x8e0d8800); + GX_WRITE_RAS_REG(0x920dc800); + + GX_WRITE_RAS_REG(0x8f0d8c00); + GX_WRITE_RAS_REG(0x930dcc00); + + GX_WRITE_RAS_REG(0xac0d9000); + GX_WRITE_RAS_REG(0xb00dd000); + + GX_WRITE_RAS_REG(0xad0d9400); + GX_WRITE_RAS_REG(0xb10dd400); + + GX_WRITE_RAS_REG(0xae0d9800); + GX_WRITE_RAS_REG(0xb20dd800); + + GX_WRITE_RAS_REG(0xaf0d9c00); + GX_WRITE_RAS_REG(0xb30ddc00); + + break; + } +} diff --git a/libs/dolphin/gx/GXTransform.c b/libs/dolphin/gx/GXTransform.c index e69de29bb..0c19f70e1 100644 --- a/libs/dolphin/gx/GXTransform.c +++ b/libs/dolphin/gx/GXTransform.c @@ -0,0 +1,495 @@ +#include +#include +#include + +#include + +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; + + ASSERTMSGLINE(168, pm && vp && sx && sy && sz, "GXGet*: invalid null pointer"); + + 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 + { + 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]))); +} + +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) +{ + 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 +} + +void GXSetProjection(Mtx44 mtx, GXProjectionType type) +{ + CHECK_GXBEGIN(295, "GXSetProjection"); + + __GXData->projType = type; + __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] = mtx[0][3]; + __GXData->projMtx[3] = mtx[1][3]; + } + else + { + __GXData->projMtx[1] = mtx[0][2]; + __GXData->projMtx[3] = mtx[1][2]; + } + + __GXSetProjection(); + __GXData->bpSentNot = 1; +} + +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 = 1; +} + +#define qr0 0 + +void GXGetProjectionv(f32* ptr) +{ + 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(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; + + 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_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 + } +} + +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; + + asm { + 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) + } +} + +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(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 GXLoadNrmMtxImm(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 GXSetCurrentMtx(u32 id) +{ + CHECK_GXBEGIN(708, "GXSetCurrentMtx"); + SET_REG_FIELD(712, __GXData->matIdxA, 6, 0, id); + __GXSetMatrixIndex(GX_VA_PNMTXIDX); +} + +void GXLoadTexMtxImm(f32 mtx[][4], u32 id, GXTexMtxType type) +{ + u32 reg; + u32 addr; + u32 count; + + CHECK_GXBEGIN(741, "GXLoadTexMtxImm"); + + if (id >= GX_PTTEXMTX0) + { + addr = (id - GX_PTTEXMTX0) * 4 + 0x500; + } + else + { + addr = id * 4; + } + 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 +} + +void __GXSetViewport(void) +{ + f32 sx; + f32 sy; + f32 sz; + f32 ox; + f32 oy; + f32 oz; + f32 zmin; + f32 zmax; + u32 reg; + + 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)); + + zmin = __GXData->vpNearz * __GXData->zScale; + zmax = __GXData->vpFarz * __GXData->zScale; + + sz = zmax - zmin; + oz = zmax + __GXData->zOffset; + + 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); +} + +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; + } + + __GXData->vpLeft = left; + __GXData->vpTop = top; + __GXData->vpWd = wd; + __GXData->vpHt = ht; + __GXData->vpNearz = nearz; + __GXData->vpFarz = farz; + + __GXSetViewport(); + __GXData->bpSentNot = 1; +} + +void GXSetViewport(f32 left, f32 top, f32 wd, f32 ht, f32 nearz, f32 farz) +{ + GXSetViewportJitter(left, top, wd, ht, nearz, farz, 1); +} + +#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) + +void GXSetScissor(u32 left, u32 top, u32 wd, u32 ht) +{ + u32 tp; + u32 lf; + u32 bm; + u32 rt; + + CHECK_GXBEGIN(1048, "GXSetScissor"); + + tp = top + 342; + lf = left + 342; + bm = tp + ht - 1; + rt = lf + wd - 1; + + 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 GXSetScissorBoxOffset(s32 x_off, s32 y_off) +{ + u32 reg = 0; + u32 hx; + u32 hy; + + CHECK_GXBEGIN(1119, "GXSetScissorBoxOffset"); + + 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; +} + +void GXSetClipMode(GXClipMode mode) +{ + CHECK_GXBEGIN(1151, "GXSetClipMode"); + GX_WRITE_XF_REG(5, mode); + __GXData->bpSentNot = 1; +} + +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_WRITE_SOME_REG4(8, 0x40, __GXData->matIdxB, -12); + GX_WRITE_XF_REG(25, __GXData->matIdxB); + } + __GXData->bpSentNot = 1; +} diff --git a/libs/dolphin/gx/GXVerifRAS.c b/libs/dolphin/gx/GXVerifRAS.c new file mode 100644 index 000000000..eb69a0dcb --- /dev/null +++ b/libs/dolphin/gx/GXVerifRAS.c @@ -0,0 +1,943 @@ +#if DEBUG + +#include + +#include + +#include + +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/libs/dolphin/gx/GXVerifXF.c b/libs/dolphin/gx/GXVerifXF.c new file mode 100644 index 000000000..8a1715839 --- /dev/null +++ b/libs/dolphin/gx/GXVerifXF.c @@ -0,0 +1,1291 @@ +#if DEBUG + +#include + +#include + +#include + +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/libs/dolphin/gx/GXVerify.c b/libs/dolphin/gx/GXVerify.c new file mode 100644 index 000000000..12e6b984d --- /dev/null +++ b/libs/dolphin/gx/GXVerify.c @@ -0,0 +1,399 @@ +#if DEBUG + +#include + +#include + +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/libs/dolphin/gx/GXVert.c b/libs/dolphin/gx/GXVert.c new file mode 100644 index 000000000..a1f9a9686 --- /dev/null +++ b/libs/dolphin/gx/GXVert.c @@ -0,0 +1,110 @@ +#if DEBUG +#include + +#include + +#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/libs/dolphin/gx/__gx.h b/libs/dolphin/gx/__gx.h new file mode 100644 index 000000000..fe60c8852 --- /dev/null +++ b/libs/dolphin/gx/__gx.h @@ -0,0 +1,632 @@ +#ifndef _DOLPHIN_GX_INTERNAL_H_ +#define _DOLPHIN_GX_INTERNAL_H_ + +#include +#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 \ + { \ + (reg) = ((u32)__rlwimi((u32)(reg), (val), (shift), 32 - (shift) - (size), 31 - (shift))); \ + } while (0) + +#define CHECK_GXBEGIN(line, name) +// Commented out because it seems useless and lowers match% \ + 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/libs/dolphin/mtx/mtx.c b/libs/dolphin/mtx/mtx.c index e69de29bb..1ec3dd5d3 100644 --- a/libs/dolphin/mtx/mtx.c +++ b/libs/dolphin/mtx/mtx.c @@ -0,0 +1,96 @@ +#include +#include +#include "fake_tgmath.h" + +static f32 Unit01[2] = { 0.0f, 1.0f }; + +void PSMTXIdentity(register Mtx m) +{ + register f32 c_zero = 0.0f; + register f32 c_one = 1.0f; + register f32 c_01; + register f32 c_10; + + 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 + } +} + +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 PSMTXScale(register Mtx m, register f32 xS, register f32 yS, register f32 zS) +{ + register f32 c0 = 0.0f; + + 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) + } +} diff --git a/libs/dolphin/mtx/mtx44.c b/libs/dolphin/mtx/mtx44.c index e69de29bb..89615c9ae 100644 --- a/libs/dolphin/mtx/mtx44.c +++ b/libs/dolphin/mtx/mtx44.c @@ -0,0 +1,30 @@ +#include +#include +#include "fake_tgmath.h" + +static f32 mtxUnit[] = { 0.0f, 1.0f, 0.5f, 3.0f }; + +void C_MTXOrtho(Mtx44 m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f) +{ + f32 tmp; + + 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; +} diff --git a/libs/dolphin/mtx/mtx44vec.c b/libs/dolphin/mtx/mtx44vec.c index 2a12fbce9..478c49fc9 100644 --- a/libs/dolphin/mtx/mtx44vec.c +++ b/libs/dolphin/mtx/mtx44vec.c @@ -1,39 +1,247 @@ -#include "dolphin/mtx.h" - -// TODO: cleanup, documentation, check other builds -void PSMTX44MultVec(register const Mtx44 m, register const Vec *src, register Vec *dst) -{ - // clang-format off - __asm { - psq_l f0, 0(src), 0, 0 - psq_l f2, 0x30(m), 0, 0 - psq_l f1, 8(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, 0(m), 0, 0 - ps_merge00 f13, f13, f13 - psq_l f5, 8(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, 0(dst), 0, 0 - ps_mul f3, f3, f13 - psq_st f3, 8(dst), 1, 0 +#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++; } - // clang-format on -} \ No newline at end of file +} + +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/libs/dolphin/mtx/mtxstack.c b/libs/dolphin/mtx/mtxstack.c new file mode 100644 index 000000000..475175c2c --- /dev/null +++ b/libs/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/libs/dolphin/mtx/mtxvec.c b/libs/dolphin/mtx/mtxvec.c index e69de29bb..47146ee8b 100644 --- a/libs/dolphin/mtx/mtxvec.c +++ b/libs/dolphin/mtx/mtxvec.c @@ -0,0 +1,204 @@ +#include +#include +#include "fake_tgmath.h" + +void C_MTXMultVec(const Mtx m, const Vec* src, Vec* dst) { + Vec vTmp; + + 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; +} + +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 +} + +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 + subi dstBase, dstBase, 0x4 + psq_l f10, 0x18(m), 0, 0 + ps_merge11 f1, f13, f12 + mtctr count + psq_l f4, 0x20(m), 0, 0 + ps_merge00 f2, f11, f10 + psq_l f5, 0x28(m), 0, 0 + ps_merge11 f3, f11, f10 + 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 +L_000003C4: + psq_lu f6, 0x4(srcBase), 0, 0 + ps_madds0 f12, f2, f7, f8 + 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, 0x4(dstBase), 0, 0 + ps_madds1 f8, f1, f6, f8 + psq_stu f13, 0x8(dstBase), 1, 0 + ps_madd f10, f5, f7, f9 + bdnz L_000003C4 + ps_madds0 f12, f2, f7, f8 + ps_sum0 f13, f10, f9, f10 + psq_stu f12, 0x4(dstBase), 0, 0 + psq_stu f13, 0x8(dstBase), 1, 0 + blr +} + +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; +} + +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 +} + +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 + subi dstBase, dstBase, 0x4 + psq_l f10, 0x18(m), 1, 0 + ps_merge11 f1, f13, f12 + mtctr count + psq_l f3, 0x20(m), 0, 0 + ps_merge00 f2, f11, f10 + 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 +L_000007D0: + psq_lu f6, 0x4(srcBase), 0, 0 + ps_madds0 f12, f2, f7, f8 + 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, 0x4(dstBase), 0, 0 + ps_madds1 f8, f1, f6, f8 + psq_stu f13, 0x8(dstBase), 1, 0 + ps_madd f10, f4, f7, f9 + bdnz L_000007D0 + ps_madds0 f12, f2, f7, f8 + ps_sum0 f13, f10, f9, f9 + psq_stu f12, 0x4(dstBase), 0, 0 + psq_stu f13, 0x8(dstBase), 1, 0 + blr +} diff --git a/libs/dolphin/mtx/psmtx.c b/libs/dolphin/mtx/psmtx.c new file mode 100644 index 000000000..6ec6c2955 --- /dev/null +++ b/libs/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/libs/dolphin/mtx/quat.c b/libs/dolphin/mtx/quat.c index e69de29bb..79687f05a 100644 --- a/libs/dolphin/mtx/quat.c +++ b/libs/dolphin/mtx/quat.c @@ -0,0 +1,486 @@ +#include +#include +#include "fake_tgmath.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; + + asm { + 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 + } +} + +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; +} + +void PSQUATSubtract(const register Quaternion* p, const register Quaternion* q, register Quaternion* r) { + register f32 pxy, qxy, rxy, pzw, qzw, rzw; + + 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 + } +} + +void C_QUATMultiply(const Quaternion* p, const Quaternion* q, Quaternion* pq) { + Quaternion* r; + Quaternion pqTmp; + + 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 { + r = pq; + } + + 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/libs/dolphin/mtx/vec.c b/libs/dolphin/mtx/vec.c index 17ba7c59e..994ee18d8 100644 --- a/libs/dolphin/mtx/vec.c +++ b/libs/dolphin/mtx/vec.c @@ -1,262 +1,344 @@ -#include "types.h" -#include "dolphin/mtx.h" - -#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 - -void C_VECAdd(void) -{ - // UNUSED FUNCTION +#include +#include +#include "fake_tgmath.h" + +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; } -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 +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 } -void C_VECSubtract(void) -{ - // UNUSED FUNCTION +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 *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 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(void) -{ - // UNUSED FUNCTION +void C_VECScale(const Vec* src, Vec* dst, f32 scale) { + 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); } -void PSVECScale(register const Vec *src, register Vec *dst, register f32 scale) -{ - // clang-format off +void PSVECScale(const register Vec* src, register Vec* dst, register f32 scale) { register f32 vxy, vz, rxy, rz; - __asm { - psq_l vxy, 0(src), 0, 0 - psq_l vz, 8(src), 1, 0 - ps_muls0 rxy, vxy, scale - psq_st rxy, 0(dst), 0, 0 - ps_muls0 rz, vz, scale - psq_st rz, 8(dst), 1, 0 + + 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 } - // clang-format on } -void C_VECNormalize(void) -{ - // UNUSED FUNCTION +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 *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; +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 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; + 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 } -#endif // clang-format on } -void C_VECSquareMag(void) -{ - // UNUSED FUNCTION +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 Vec *v) -{ - // UNUSED FUNCTION +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; } -void C_VECMag(void) -{ - // UNUSED FUNCTION +f32 C_VECMag(const Vec* v) { + return sqrtf(C_VECSquareMag(v)); } -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 +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 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 + 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 } - #endif // clang-format on - three = 3.0f; - #ifdef __MWERKS__ // clang-format off + + c_three = 3.0f; + 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: + 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: } - #endif // clang-format on - return square_mag; + + return sqmag; } -void C_VECDotProduct(void) -{ - // UNUSED FUNCTION +f32 C_VECDotProduct(const Vec* a, const Vec* b) { + f32 dot; + + 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; } -ASM f32 PSVECDotProduct(register const Vec *a, register const Vec *b) -{ -#ifdef __MWERKS__ // clang-format off - nofralloc; - psq_l f2, 4(a), 0, 0; - psq_l f3, 4(b), 0, 0; - ps_mul f2, f2, f3; - psq_l f5, 0(a), 0, 0; - psq_l f4, 0(b), 0, 0; - ps_madd f3, f5, f4, f2; - ps_sum0 R_RET, f3, f2, f2; - blr -#endif // clang-format on +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 } -void C_VECCrossProduct(void) -{ - // UNUSED FUNCTION +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 *vec1, const register Vec *vec2, register Vec *ret) -{ -#ifdef __MWERKS__ // clang-format off - nofralloc; - psq_l fp1, 0(vec2), 0, 0 - lfs fp2, 8(vec1) - psq_l fp0, 0(vec1), 0, 0 - ps_merge10 fp6, fp1, fp1 - lfs fp3, 8(vec2) - ps_mul fp4, fp1, fp2 - ps_muls0 fp7, fp1, fp0 - ps_msub fp5, fp0, fp3, fp4 - ps_msub fp8, fp0, fp6, fp7 - ps_merge11 fp9, fp5, fp5 - ps_merge01 fp10, fp5, fp8 - psq_st fp9, 0(ret), 1, 0 - ps_neg fp10, fp10 - psq_st fp10, 4(ret), 0, 0 - blr; -#endif // clang-format on +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(void) -{ - // UNUSED FUNCTION +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(void) -{ - // UNUSED FUNCTION +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); } -void C_VECSquareDistance(void) -{ - // UNUSED FUNCTION +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)); } -f32 PSVECSquareDistance(const Vec *a, const Vec *b) -{ - // UNUSED FUNCTION +f32 PSVECSquareDistance(const register Vec* a, const register Vec* b) { + register f32 v0yz, v1yz, v0xy, v1xy, dyz, dxy; + register f32 sqdist; + + asm { + 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 + } + + return sqdist; } -void C_VECDistance(void) -{ - // UNUSED FUNCTION +f32 C_VECDistance(const Vec* a, const Vec* b) { + return sqrtf(C_VECSquareDistance(a, b)); } -// TODO: cleanup? -ASM f32 PSVECDistance(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; - lfs f3, 0.5f; - - ps_madd f1, f0, f0, f2; - fsubs f0, f3, f3; - ps_sum0 f1, f1, f2, f2; - fcmpu cr0, f0, f1; - beq exit; - lfs f4, 3.0f; - frsqrte f0, f1; - fmuls f2, f0, f0; - fmuls f0, f0, f3; - fnmsubs f2, f2, f1, f4; - fmuls f0, f2, f0; - fmuls R_RET, f1, f0; -exit: - blr -#endif // clang-format on -} \ No newline at end of file +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 { + 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 + } + + 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/libs/dolphin/odenotstub/odenotstub.c b/libs/dolphin/odenotstub/odenotstub.c index e69de29bb..094dc1b71 100644 --- a/libs/dolphin/odenotstub/odenotstub.c +++ b/libs/dolphin/odenotstub/odenotstub.c @@ -0,0 +1,9 @@ +#include + +// prototypes +__declspec(weak) int Hu_IsStub(); + +__declspec(weak) int Hu_IsStub() +{ + return 0; +} diff --git a/libs/dolphin/os/OSAlarm.c b/libs/dolphin/os/OSAlarm.c index c384f40b7..46eeff622 100644 --- a/libs/dolphin/os/OSAlarm.c +++ b/libs/dolphin/os/OSAlarm.c @@ -4,16 +4,14 @@ static struct OSAlarmQueue { - OSAlarm *head; - OSAlarm *tail; + OSAlarm* head; + OSAlarm* tail; } AlarmQueue; -static void DecrementerExceptionHandler(__OSException exception, OSContext *context); +static void DecrementerExceptionHandler(__OSException exception, OSContext* context); static BOOL OnReset(BOOL final); -static OSResetFunctionInfo ResetFunctionInfo = {OnReset, 0xFFFFFFFF}; - -static void SetTimer(OSAlarm *alarm) +static void SetTimer(OSAlarm* alarm) { OSTime delta; @@ -38,20 +36,19 @@ void OSInitAlarm(void) { AlarmQueue.head = AlarmQueue.tail = NULL; __OSSetExceptionHandler(8, DecrementerExceptionHandler); - OSRegisterResetFunction(&ResetFunctionInfo); } } -void OSCreateAlarm(OSAlarm *alarm) +void OSCreateAlarm(OSAlarm* alarm) { alarm->handler = 0; alarm->tag = 0; } -static void InsertAlarm(OSAlarm *alarm, OSTime fire, OSAlarmHandler handler) +static void InsertAlarm(OSAlarm* alarm, OSTime fire, OSAlarmHandler handler) { - OSAlarm *next; - OSAlarm *prev; + OSAlarm* next; + OSAlarm* prev; if (0 < alarm->period) { @@ -104,7 +101,7 @@ static void InsertAlarm(OSAlarm *alarm, OSTime fire, OSAlarmHandler handler) } } -void OSSetAlarm(OSAlarm *alarm, OSTime tick, OSAlarmHandler handler) +void OSSetAlarm(OSAlarm* alarm, OSTime tick, OSAlarmHandler handler) { BOOL enabled; enabled = OSDisableInterrupts(); @@ -113,7 +110,7 @@ void OSSetAlarm(OSAlarm *alarm, OSTime tick, OSAlarmHandler handler) OSRestoreInterrupts(enabled); } -void OSSetPeriodicAlarm(OSAlarm *alarm, OSTime start, OSTime period, OSAlarmHandler handler) +void OSSetPeriodicAlarm(OSAlarm* alarm, OSTime start, OSTime period, OSAlarmHandler handler) { BOOL enabled; enabled = OSDisableInterrupts(); @@ -123,9 +120,9 @@ void OSSetPeriodicAlarm(OSAlarm *alarm, OSTime start, OSTime period, OSAlarmHand OSRestoreInterrupts(enabled); } -void OSCancelAlarm(OSAlarm *alarm) +void OSCancelAlarm(OSAlarm* alarm) { - OSAlarm *next; + OSAlarm* next; BOOL enabled; enabled = OSDisableInterrupts(); @@ -163,10 +160,10 @@ void OSCancelAlarm(OSAlarm *alarm) } static void DecrementerExceptionCallback(register __OSException exception, - register OSContext *context) + register OSContext* context) { - OSAlarm *alarm; - OSAlarm *next; + OSAlarm* alarm; + OSAlarm* next; OSAlarmHandler handler; OSTime time; OSContext exceptionContext; @@ -218,7 +215,7 @@ static void DecrementerExceptionCallback(register __OSException exception, } static asm void DecrementerExceptionHandler(register __OSException exception, - register OSContext *context) + register OSContext* context) { // clang-format off nofralloc @@ -227,28 +224,3 @@ static asm void DecrementerExceptionHandler(register __OSException exception, b DecrementerExceptionCallback // clang-format on } - -static BOOL OnReset(BOOL final) -{ - OSAlarm *alarm; - OSAlarm *next; - - if (final) - { - alarm = AlarmQueue.head; - next = (alarm) ? alarm->next : NULL; - - while (alarm != NULL) - { - if (__DVDTestAlarm(alarm) == FALSE) - { - OSCancelAlarm(alarm); - } - - alarm = next; - next = (alarm) ? alarm->next : NULL; - } - } - - return TRUE; -} diff --git a/libs/dolphin/os/OSAlloc.c b/libs/dolphin/os/OSAlloc.c index bb2898e7a..fd9b8c0fe 100644 --- a/libs/dolphin/os/OSAlloc.c +++ b/libs/dolphin/os/OSAlloc.c @@ -3,31 +3,31 @@ typedef struct HeapCell { - struct HeapCell *prev; - struct HeapCell *next; + struct HeapCell* prev; + struct HeapCell* next; u32 size; } HeapCell; typedef struct Heap { s32 size; - struct HeapCell *free; // linked list of free cells - struct HeapCell *allocated; // linked list of allocated cells + struct HeapCell* free; // linked list of free cells + struct HeapCell* allocated; // linked list of allocated cells } Heap; -void *ArenaEnd; -void *ArenaStart; +void* ArenaEnd; +void* ArenaStart; int NumHeaps; -struct Heap *HeapArray; +struct Heap* HeapArray; volatile OSHeapHandle __OSCurrHeap = -1; -#define InRange(addr, start, end) ((u8 *)(start) <= (u8 *)(addr) && (u8 *)(addr) < (u8 *)(end)) +#define InRange(addr, start, end) ((u8*)(start) <= (u8*)(addr) && (u8*)(addr) < (u8*)(end)) #define OFFSET(addr, align) (((u32)(addr) & ((align)-1))) #define ALIGNMENT 32 #define MINOBJSIZE 64 -static inline void *DLAddFront(struct HeapCell *neighbor, struct HeapCell *cell) +static inline void* DLAddFront(struct HeapCell* neighbor, struct HeapCell* cell) { cell->next = neighbor; cell->prev = NULL; @@ -36,13 +36,8 @@ static inline void *DLAddFront(struct HeapCell *neighbor, struct HeapCell *cell) return cell; } -void DLLookup(void) -{ - // UNUSED FUNCTION -} - // removes 'cell' from 'list' and returns 'list' -static inline HeapCell *DLExtract(struct HeapCell *list, struct HeapCell *cell) +static inline HeapCell* DLExtract(struct HeapCell* list, struct HeapCell* cell) { if (cell->next != NULL) cell->next->prev = cell->prev; @@ -53,10 +48,11 @@ static inline HeapCell *DLExtract(struct HeapCell *list, struct HeapCell *cell) return list; } -static HeapCell *DLInsert(HeapCell *list, HeapCell *cell, void *unused /* needed to match OSFreeToHeap */) +static HeapCell* DLInsert(HeapCell* list, HeapCell* cell, + void* unused /* needed to match OSFreeToHeap */) { - HeapCell *before = NULL; - HeapCell *after = list; + HeapCell* before = NULL; + HeapCell* after = list; while (after != NULL) { @@ -70,7 +66,7 @@ static HeapCell *DLInsert(HeapCell *list, HeapCell *cell, void *unused /* needed if (after != NULL) { after->prev = cell; - if ((u8 *)cell + cell->size == (u8 *)after) + if ((u8*)cell + cell->size == (u8*)after) { cell->size += after->size; after = after->next; @@ -82,7 +78,7 @@ static HeapCell *DLInsert(HeapCell *list, HeapCell *cell, void *unused /* needed if (before != NULL) { before->next = cell; - if ((u8 *)before + before->size == (u8 *)cell) + if ((u8*)before + before->size == (u8*)cell) { before->size += cell->size; before->next = after; @@ -94,22 +90,12 @@ static HeapCell *DLInsert(HeapCell *list, HeapCell *cell, void *unused /* needed return cell; } -void DLOverlap(void) -{ - // UNUSED FUNCTION -} - -void DLSize(void) -{ - // UNUSED FUNCTION -} - -void *OSAllocFromHeap(OSHeapHandle heap, u32 size) +void* OSAllocFromHeap(OSHeapHandle heap, u32 size) { - struct Heap *hd = &HeapArray[heap]; + struct Heap* hd = &HeapArray[heap]; s32 sizeAligned = OSRoundUp32B(ALIGNMENT + size); - struct HeapCell *cell; - struct HeapCell *oldTail; + struct HeapCell* cell; + struct HeapCell* oldTail; u32 leftoverSpace; // find first cell with enough capacity @@ -131,7 +117,7 @@ void *OSAllocFromHeap(OSHeapHandle heap, u32 size) { // remove this cell from the free list and make a new cell out of the // remaining space - struct HeapCell *newcell = (void *)((u8 *)cell + sizeAligned); + struct HeapCell* newcell = (void*)((u8*)cell + sizeAligned); cell->size = sizeAligned; newcell->size = leftoverSpace; newcell->prev = cell->prev; @@ -147,14 +133,14 @@ void *OSAllocFromHeap(OSHeapHandle heap, u32 size) // add the cell to the beginning of the allocated list hd->allocated = DLAddFront(hd->allocated, cell); - return (u8 *)cell + ALIGNMENT; + return (u8*)cell + ALIGNMENT; } -void OSFreeToHeap(OSHeapHandle heap, void *ptr) +void OSFreeToHeap(OSHeapHandle heap, void* ptr) { - HeapCell *cell = (void *)((u8 *)ptr - ALIGNMENT); - Heap *hd = &HeapArray[heap]; - HeapCell *list = hd->allocated; + HeapCell* cell = (void*)((u8*)ptr - ALIGNMENT); + Heap* hd = &HeapArray[heap]; + HeapCell* list = hd->allocated; // remove cell from the allocated list // hd->allocated = DLExtract(hd->allocated, cell); @@ -176,7 +162,7 @@ OSHeapHandle OSSetCurrentHeap(OSHeapHandle heap) return old; } -void *OSInitAlloc(void *arenaStart, void *arenaEnd, int maxHeaps) +void* OSInitAlloc(void* arenaStart, void* arenaEnd, int maxHeaps) { u32 totalSize = maxHeaps * sizeof(struct Heap); int i; @@ -186,7 +172,7 @@ void *OSInitAlloc(void *arenaStart, void *arenaEnd, int maxHeaps) for (i = 0; i < NumHeaps; i++) { - Heap *heap = &HeapArray[i]; + Heap* heap = &HeapArray[i]; heap->size = -1; heap->free = heap->allocated = NULL; @@ -194,28 +180,28 @@ void *OSInitAlloc(void *arenaStart, void *arenaEnd, int maxHeaps) __OSCurrHeap = -1; - arenaStart = (u8 *)HeapArray + totalSize; - arenaStart = (void *)OSRoundUp32B(arenaStart); + arenaStart = (u8*)HeapArray + totalSize; + arenaStart = (void*)OSRoundUp32B(arenaStart); ArenaStart = arenaStart; - ArenaEnd = (void *)OSRoundDown32B(arenaEnd); + ArenaEnd = (void*)OSRoundDown32B(arenaEnd); return arenaStart; } -OSHeapHandle OSCreateHeap(void *start, void *end) +OSHeapHandle OSCreateHeap(void* start, void* end) { int i; - HeapCell *cell = (void *)OSRoundUp32B(start); + HeapCell* cell = (void*)OSRoundUp32B(start); - end = (void *)OSRoundDown32B(end); + end = (void*)OSRoundDown32B(end); for (i = 0; i < NumHeaps; i++) { - Heap *hd = &HeapArray[i]; + Heap* hd = &HeapArray[i]; if (hd->size < 0) { - hd->size = (u8 *)end - (u8 *)cell; + hd->size = (u8*)end - (u8*)cell; cell->prev = NULL; cell->next = NULL; cell->size = hd->size; diff --git a/libs/dolphin/os/OSArena.c b/libs/dolphin/os/OSArena.c index 97e7ede95..79b71e639 100644 --- a/libs/dolphin/os/OSArena.c +++ b/libs/dolphin/os/OSArena.c @@ -3,39 +3,25 @@ #define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) #define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) -void *__OSArenaHi; -void *__OSArenaLo = (void *)-1; +void* __OSArenaHi; +void* __OSArenaLo = (void*)-1; -void *OSGetArenaHi(void) { return __OSArenaHi; } - -void *OSGetArenaLo(void) { return __OSArenaLo; } - -void OSSetArenaHi(void *addr) { __OSArenaHi = addr; } - -void OSSetArenaLo(void *addr) { __OSArenaLo = addr; } - -void *OSAllocFromArenaLo(u32 size, u32 align) +void* OSGetArenaHi(void) { - void *ptr; - u8 *arenaLo; + return __OSArenaHi; +} - ptr = OSGetArenaLo(); - arenaLo = ptr = (void *)ROUND(ptr, align); - arenaLo += size; - arenaLo = (u8 *)ROUND(arenaLo, align); - OSSetArenaLo(arenaLo); - return ptr; +void* OSGetArenaLo(void) +{ + return __OSArenaLo; } -void *OSAllocFromArenaHi(u32 size, u32 align) +void OSSetArenaHi(void* addr) { - void *ptr; - u8 *arenaHi; + __OSArenaHi = addr; +} - arenaHi = OSGetArenaHi(); - arenaHi = (u8 *)TRUNC(arenaHi, align); - arenaHi -= size; - arenaHi = ptr = (void *)TRUNC(arenaHi, align); - OSSetArenaHi(arenaHi); - return ptr; +void OSSetArenaLo(void* addr) +{ + __OSArenaLo = addr; } \ No newline at end of file diff --git a/libs/dolphin/os/OSCache.c b/libs/dolphin/os/OSCache.c index 2cec4d3dd..11ba9094f 100644 --- a/libs/dolphin/os/OSCache.c +++ b/libs/dolphin/os/OSCache.c @@ -89,44 +89,6 @@ asm void DCFlushRangeNoSync(register void* addr, register u32 nBytes) { 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 -} - -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 ICInvalidateRange(register void* addr, register u32 nBytes) { nofralloc nofralloc @@ -169,76 +131,6 @@ asm void ICEnable() { #define LC_LINES 512 #define CACHE_LINES 1024 -asm void __LCEnable() { - 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 - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - - blr -} - -void LCEnable() { - BOOL enabled; - - enabled = OSDisableInterrupts(); - __LCEnable(); - OSRestoreInterrupts(enabled); -} - asm void LCDisable() { nofralloc @@ -255,172 +147,104 @@ asm void LCDisable() { 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 -} - /* clang-format on */ -u32 LCLoadData(register void* destAddr, register void* srcAddr, register u32 nBytes) { - u32 numBlocks = (nBytes + 31) / 32; - u32 numTransactions = (numBlocks + 128 - 1) / 128; - - while (numBlocks > 0) { - if (numBlocks < 128) { - LCLoadBlocks(destAddr, srcAddr, numBlocks); - numBlocks = 0; - } else { - LCLoadBlocks(destAddr, srcAddr, 0); - numBlocks -= 128; - destAddr = (void*)((u32)destAddr + 4096); - srcAddr = (void*)((u32)srcAddr + 4096); - } - } - - return numTransactions; -} -u32 LCStoreData(void* destAddr, void* srcAddr, u32 nBytes) { - u32 numBlocks = (nBytes + 31) / 32; - u32 numTransactions = (numBlocks + 128 - 1) / 128; - - 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; -} - /* clang-format off */ -asm u32 LCQueueLength() { - nofralloc - mfspr r4, HID2 - rlwinm r3, r4, 8, 28, 31 - blr -} - -asm void LCQueueWait(register u32 len) { - nofralloc -wait: - mfspr r4, HID2 - rlwinm r4, r4, 8, 28, 31 - cmpw r4, r3 - bgt wait - blr -} /* clang-format on */ -static void L2Disable(void) { - __sync(); - PPCMtl2cr(PPCMfl2cr() & ~0x80000000); - __sync(); -} - -void L2GlobalInvalidate(void) { - L2Disable(); - PPCMtl2cr(PPCMfl2cr() | 0x00200000); - while (PPCMfl2cr() & 0x00000001u) - ; - PPCMtl2cr(PPCMfl2cr() & ~0x00200000); - while (PPCMfl2cr() & 0x00000001u) { - DBPrintf(">>> L2 INVALIDATE : SHOULD NEVER HAPPEN\n"); - } -} - -static void L2Init(void) { - u32 oldMSR; - oldMSR = PPCMfmsr(); - __sync(); - PPCMtmsr(MSR_IR | MSR_DR); - __sync(); - L2Disable(); - L2GlobalInvalidate(); - PPCMtmsr(oldMSR); +static void L2Disable(void) +{ + __sync(); + PPCMtl2cr(PPCMfl2cr() & ~0x80000000); + __sync(); +} + +void L2GlobalInvalidate(void) +{ + L2Disable(); + PPCMtl2cr(PPCMfl2cr() | 0x00200000); + while (PPCMfl2cr() & 0x00000001u) + ; + PPCMtl2cr(PPCMfl2cr() & ~0x00200000); + while (PPCMfl2cr() & 0x00000001u) + { + DBPrintf(">>> L2 INVALIDATE : SHOULD NEVER HAPPEN\n"); + } } -void L2Enable(void) { PPCMtl2cr((PPCMfl2cr() | L2CR_L2E) & ~L2CR_L2I); } +static void L2Init(void) +{ + u32 oldMSR; + oldMSR = PPCMfmsr(); + __sync(); + PPCMtmsr(MSR_IR | MSR_DR); + __sync(); + L2Disable(); + L2GlobalInvalidate(); + PPCMtmsr(oldMSR); +} + +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)) + { + OSReport("Machine check was not DMA/locked cache related\n"); + OSDumpContext(context); + PPCHalt(); + } -void DMAErrorHandler(OSError error, OSContext* context, ...) { - u32 hid2 = PPCMfhid2(); + OSReport("DMAErrorHandler(): An error occurred while processing DMA.\n"); + OSReport("The following errors have been detected and cleared :\n"); - 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)) { - OSReport("Machine check was not DMA/locked cache related\n"); - OSDumpContext(context); - PPCHalt(); - } + if (hid2 & HID2_DCHERR) + { + OSReport("\t- Requested a locked cache tag that was already in the cache\n"); + } - OSReport("DMAErrorHandler(): An error occurred while processing DMA.\n"); - OSReport("The following errors have been detected and cleared :\n"); + if (hid2 & HID2_DNCERR) + { + OSReport("\t- DMA attempted to access normal cache\n"); + } - if (hid2 & HID2_DCHERR) { - OSReport("\t- Requested a locked cache tag that was already in the cache\n"); - } + if (hid2 & HID2_DCMERR) + { + OSReport("\t- DMA missed in data cache\n"); + } - if (hid2 & HID2_DNCERR) { - OSReport("\t- DMA attempted to access normal cache\n"); - } + if (hid2 & HID2_DQOERR) + { + OSReport("\t- DMA queue overflowed\n"); + } - if (hid2 & HID2_DCMERR) { - OSReport("\t- DMA missed in data cache\n"); - } + // write hid2 back to clear the error bits + PPCMthid2(hid2); +} - if (hid2 & HID2_DQOERR) { - OSReport("\t- DMA queue overflowed\n"); - } +void __OSCacheInit() +{ + if (!(PPCMfhid0() & HID0_ICE)) + { + ICEnable(); + DBPrintf("L1 i-caches initialized\n"); + } + if (!(PPCMfhid0() & HID0_DCE)) + { + DCEnable(); + DBPrintf("L1 d-caches initialized\n"); + } - // write hid2 back to clear the error bits - PPCMthid2(hid2); -} + if (!(PPCMfl2cr() & L2CR_L2E)) + { + L2Init(); + PPCMtl2cr((PPCMfl2cr() | L2CR_L2E) & ~L2CR_L2I); + DBPrintf("L2 cache initialized\n"); + } -void __OSCacheInit() { - if (!(PPCMfhid0() & HID0_ICE)) { - ICEnable(); - DBPrintf("L1 i-caches initialized\n"); - } - if (!(PPCMfhid0() & HID0_DCE)) { - DCEnable(); - DBPrintf("L1 d-caches initialized\n"); - } - - if (!(PPCMfl2cr() & L2CR_L2E)) { - L2Init(); - L2Enable(); - DBPrintf("L2 cache initialized\n"); - } - - OSSetErrorHandler(OS_ERROR_MACHINE_CHECK, DMAErrorHandler); - DBPrintf("Locked cache machine check handler installed\n"); + OSSetErrorHandler(OS_ERROR_MACHINE_CHECK, DMAErrorHandler); + DBPrintf("Locked cache machine check handler installed\n"); } diff --git a/libs/dolphin/os/OSContext.c b/libs/dolphin/os/OSContext.c index f8aae0446..35542bcfc 100644 --- a/libs/dolphin/os/OSContext.c +++ b/libs/dolphin/os/OSContext.c @@ -6,8 +6,9 @@ volatile OSContext* __OSCurrentContext : (OS_BASE_CACHED | 0x00D4); volatile OSContext* __OSFPUContext : (OS_BASE_CACHED | 0x00D8); -static asm void __OSLoadFPUContext(register u32, register OSContext* fpuContext) { - // clang-format off +static asm void __OSLoadFPUContext(register u32, register OSContext* fpuContext) +{ + // clang-format off nofralloc lhz r5, fpuContext->state; clrlwi. r5, r5, 31 @@ -87,11 +88,12 @@ static asm void __OSLoadFPUContext(register u32, register OSContext* fpuContext) lfd fp31, fpuContext->fpr[31] _return: blr - // clang-format on + // clang-format on } -static asm void __OSSaveFPUContext(register u32, register u32, register OSContext* fpuContext) { - // clang-format off +static asm void __OSSaveFPUContext(register u32, register u32, register OSContext* fpuContext) +{ + // clang-format off nofralloc lhz r3, fpuContext->state @@ -175,27 +177,20 @@ static asm void __OSSaveFPUContext(register u32, register u32, register OSContex _return: blr - // clang-format on -} - -asm void OSLoadFPUContext(register OSContext* fpuContext) { - // clang-format off - nofralloc - addi r4, fpuContext, 0 - b __OSLoadFPUContext - // clang-format on + // clang-format on } -asm void OSSaveFPUContext(register OSContext* fpuContext) { - // clang-format off +asm void OSSaveFPUContext(register OSContext* fpuContext) +{ + // clang-format off nofralloc addi r5, fpuContext, 0 b __OSSaveFPUContext - // clang-format on + // clang-format on } asm void OSSetCurrentContext(register OSContext* context){ - // clang-format off + // clang-format off nofralloc addis r4, r0, OS_CACHED_REGION_PREFIX @@ -227,15 +222,17 @@ asm void OSSetCurrentContext(register OSContext* context){ mtmsr r6 isync blr - // clang-format on + // clang-format on } -OSContext* OSGetCurrentContext(void) { - return (OSContext*)__OSCurrentContext; +OSContext* OSGetCurrentContext(void) +{ + return (OSContext*)__OSCurrentContext; } -asm u32 OSSaveContext(register OSContext* context) { - // clang-format off +asm u32 OSSaveContext(register OSContext* context) +{ + // clang-format off nofralloc stmw r13, context->gpr[13] mfspr r0, GQR1 @@ -269,14 +266,15 @@ asm u32 OSSaveContext(register OSContext* context) { stw r0, context->gpr[3] li r3, 0 blr - // clang-format on + // clang-format on } extern void __RAS_OSDisableInterrupts_begin(); extern void __RAS_OSDisableInterrupts_end(); -asm void OSLoadContext(register OSContext* context) { - // clang-format off +asm void OSLoadContext(register OSContext* context) +{ + // clang-format off nofralloc lis r4,__RAS_OSDisableInterrupts_begin@ha @@ -345,165 +343,88 @@ asm void OSLoadContext(register OSContext* context) { lwz r3, context->gpr[3] rfi - // clang-format on + // clang-format on } -asm u32 OSGetStackPointer() { - // clang-format off +asm u32 OSGetStackPointer() +{ + // clang-format off nofralloc mr r3, r1 blr - // clang-format on -} - -asm u32 OSSwitchStack(register u32 newsp) { - // clang-format off - nofralloc - mr r5, r1 - mr r1, newsp - mr r3, r5 - blr - // clang-format on -} - -asm int OSSwitchFiber(register u32 pc, register u32 newsp) { - // clang-format off - 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 - // clang-format on + // clang-format on } -void OSClearContext(register OSContext* context) { - context->mode = 0; - context->state = 0; - if (context == __OSFPUContext) - __OSFPUContext = NULL; -} - -asm void OSInitContext(register OSContext* context, register u32 pc, register u32 newsp) { - // clang-format off - 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 - // clang-format on +void OSClearContext(register OSContext* context) +{ + context->mode = 0; + context->state = 0; + if (context == __OSFPUContext) + __OSFPUContext = NULL; } -void OSDumpContext(OSContext* context) { - u32 i; - u32* p; - - OSReport("------------------------- Context 0x%08x -------------------------\n", 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]); - } - - OSReport("LR = 0x%08x CR = 0x%08x\n", context->lr, context->cr); - OSReport("SRR0 = 0x%08x SRR1 = 0x%08x\n", context->srr0, context->srr1); +void OSDumpContext(OSContext* context) +{ + u32 i; + u32* p; - 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("------------------------- Context 0x%08x -------------------------\n", context); - if (context->state & OS_CONTEXT_STATE_FPSAVED) { - OSContext* currentContext; - OSContext fpuContext; - BOOL enabled; + 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]); + } - enabled = OSDisableInterrupts(); - currentContext = OSGetCurrentContext(); - OSClearContext(&fpuContext); - OSSetCurrentContext(&fpuContext); + OSReport("LR = 0x%08x CR = 0x%08x\n", context->lr, context->cr); + OSReport("SRR0 = 0x%08x SRR1 = 0x%08x\n", context->srr0, context->srr1); - 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]); - } - 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->psf[i], i + 1, - (u32)context->psf[i + 1]); + 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]); } - OSClearContext(&fpuContext); - OSSetCurrentContext(currentContext); - OSRestoreInterrupts(enabled); - } + if (context->state & OS_CONTEXT_STATE_FPSAVED) + { + OSContext* currentContext; + OSContext fpuContext; + BOOL enabled; + + enabled = OSDisableInterrupts(); + 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]); + } + 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->psf[i], i + 1, + (u32)context->psf[i + 1]); + } + + OSClearContext(&fpuContext); + OSSetCurrentContext(currentContext); + OSRestoreInterrupts(enabled); + } - OSReport("\nAddress: Back Chain LR Save\n"); - for (i = 0, p = (u32*)context->gpr[1]; p && (u32)p != 0xffffffff && i++ < 16; p = (u32*)*p) { - OSReport("0x%08x: 0x%08x 0x%08x\n", p, p[0], p[1]); - } + OSReport("\nAddress: Back Chain LR Save\n"); + for (i = 0, p = (u32*)context->gpr[1]; p && (u32)p != 0xffffffff && i++ < 16; p = (u32*)*p) + { + OSReport("0x%08x: 0x%08x 0x%08x\n", p, p[0], p[1]); + } } -static asm void OSSwitchFPUContext(register __OSException exception, register OSContext* context) { - // clang-format off +static asm void OSSwitchFPUContext(register __OSException exception, register OSContext* context) +{ + // clang-format off nofralloc mfmsr r5 ori r5, r5, 0x2000 @@ -540,98 +461,12 @@ static asm void OSSwitchFPUContext(register __OSException exception, register OS lwz r3, OS_CONTEXT_R3(context) lwz r4, OS_CONTEXT_R4(context) rfi - // clang-format on -} - -void __OSContextInit(void) { - __OSSetExceptionHandler(__OS_EXCEPTION_FLOATING_POINT, OSSwitchFPUContext); - __OSFPUContext = NULL; - DBPrintf("FPU-unavailable handler installed\n"); + // clang-format on } -asm void OSFillFPUContext(register OSContext *context) +void __OSContextInit(void) { - // clang-format off - nofralloc - mfmsr r5 - ori r5, r5, 0x2000 - mtmsr r5 - - isync - stfd f0, 0x90(r3) - stfd f1, 0x98(r3) - stfd f2, 0xA0(r3) - stfd f3, 0xA8(r3) - stfd f4, 0xB0(r3) - stfd f5, 0xB8(r3) - stfd f6, 0xC0(r3) - stfd f7, 0xC8(r3) - stfd f8, 0xD0(r3) - stfd f9, 0xD8(r3) - stfd f10, 0xE0(r3) - stfd f11, 0xE8(r3) - stfd f12, 0xF0(r3) - stfd f13, 0xF8(r3) - stfd f14, 0x100(r3) - stfd f15, 0x108(r3) - stfd f16, 0x110(r3) - stfd f17, 0x118(r3) - stfd f18, 0x120(r3) - stfd f19, 0x128(r3) - stfd f20, 0x130(r3) - stfd f21, 0x138(r3) - stfd f22, 0x140(r3) - stfd f23, 0x148(r3) - stfd f24, 0x150(r3) - stfd f25, 0x158(r3) - stfd f26, 0x160(r3) - stfd f27, 0x168(r3) - stfd f28, 0x170(r3) - stfd f29, 0x178(r3) - stfd f30, 0x180(r3) - stfd f31, 0x188(r3) - mffs f0 - stfd f0, 0x190(r3) - lfd f0, 0x90(r3) - - mfspr r5, 0x398 - rlwinm. r5,r5,3,31,31 - beq- _return - - psq_st f0,0x1C8(r3),0,0 - psq_st f1,0x1D0(r3),0,0 - psq_st f2,0x1D8(r3),0,0 - psq_st f3,0x1E0(r3),0,0 - psq_st f4,0x1E8(r3),0,0 - psq_st f5,0x1F0(r3),0,0 - psq_st f6,0x1F8(r3),0,0 - psq_st f7,0x200(r3),0,0 - psq_st f8,0x208(r3),0,0 - psq_st f9,0x210(r3),0,0 - psq_st f10,0x218(r3),0,0 - psq_st f11,0x220(r3),0,0 - psq_st f12,0x228(r3),0,0 - psq_st f13,0x230(r3),0,0 - psq_st f14,0x238(r3),0,0 - psq_st f15,0x240(r3),0,0 - psq_st f16,0x248(r3),0,0 - psq_st f17,0x250(r3),0,0 - psq_st f18,0x258(r3),0,0 - psq_st f19,0x260(r3),0,0 - psq_st f20,0x268(r3),0,0 - psq_st f21,0x270(r3),0,0 - psq_st f22,0x278(r3),0,0 - psq_st f23,0x280(r3),0,0 - psq_st f24,0x288(r3),0,0 - psq_st f25,0x290(r3),0,0 - psq_st f26,0x298(r3),0,0 - psq_st f27,0x2A0(r3),0,0 - psq_st f28,0x2A8(r3),0,0 - psq_st f29,0x2B0(r3),0,0 - psq_st f30,0x2B8(r3),0,0 - psq_st f31,0x2C0(r3),0,0 - -_return: - blr - // clang-format on -} \ No newline at end of file + __OSSetExceptionHandler(__OS_EXCEPTION_FLOATING_POINT, OSSwitchFPUContext); + __OSFPUContext = NULL; + DBPrintf("FPU-unavailable handler installed\n"); +} diff --git a/libs/dolphin/os/OSError.c b/libs/dolphin/os/OSError.c index b7091c98f..ec942ba48 100644 --- a/libs/dolphin/os/OSError.c +++ b/libs/dolphin/os/OSError.c @@ -11,195 +11,225 @@ OSErrorHandler __OSErrorTable[OS_ERROR_MAX]; #define FPSCR_ENABLE (FPSCR_VE | FPSCR_OE | FPSCR_UE | FPSCR_ZE | FPSCR_XE) u32 __OSFpscrEnableBits = FPSCR_ENABLE; -__declspec(weak) void OSReport(const char* msg, ...) { - va_list args; - va_start(args, msg); - vprintf(msg, args); - va_end(args); +__declspec(weak) void OSReport(const char* msg, ...) +{ + va_list args; + va_start(args, msg); + vprintf(msg, args); + va_end(args); } -__declspec(weak) void OSVReport(const char* msg, va_list list) { vprintf(msg, list); } - -__declspec(weak) void OSPanic(const char* file, int line, const char* msg, ...) { - va_list marker; - u32 i; - u32* p; - - OSDisableInterrupts(); - va_start(marker, msg); - vprintf(msg, marker); - va_end(marker); - OSReport(" in \"%s\" on line %d.\n", file, line); +__declspec(weak) void OSVReport(const char* msg, va_list list) +{ + vprintf(msg, list); +} - OSReport("\nAddress: Back Chain LR Save\n"); - 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]); - } +__declspec(weak) void OSPanic(const char* file, int line, const char* msg, ...) +{ + va_list marker; + u32 i; + u32* p; + + OSDisableInterrupts(); + va_start(marker, msg); + vprintf(msg, marker); + va_end(marker); + OSReport(" in \"%s\" on line %d.\n", file, line); + + OSReport("\nAddress: Back Chain LR Save\n"); + 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(); + PPCHalt(); } -OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler) { - OSErrorHandler oldHandler; - BOOL enabled; - - enabled = OSDisableInterrupts(); - oldHandler = __OSErrorTable[error]; - __OSErrorTable[error] = handler; - - if (error == OS_ERROR_FPE) { - u32 msr; - u32 fpscr; - OSThread* thread; - - msr = PPCMfmsr(); - PPCMtmsr(msr | MSR_FP); - fpscr = PPCMffpscr(); - if (handler) { - for (thread = __OSActiveThreadQueue.head; thread; 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.psf[i] = (u64)0xffffffffffffffffLL; - } - thread->context.fpscr = FPSCR_NI; +OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler) +{ + OSErrorHandler oldHandler; + BOOL enabled; + + enabled = OSDisableInterrupts(); + oldHandler = __OSErrorTable[error]; + __OSErrorTable[error] = handler; + + if (error == OS_ERROR_FPE) + { + u32 msr; + u32 fpscr; + OSThread* thread; + + msr = PPCMfmsr(); + PPCMtmsr(msr | MSR_FP); + fpscr = PPCMffpscr(); + if (handler) + { + for (thread = __OSActiveThreadQueue.head; thread; 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.psf[i] = (u64)0xffffffffffffffffLL; + } + thread->context.fpscr = FPSCR_NI; + } + thread->context.fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE; + thread->context.fpscr &= + ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | + FPSCR_VXSNAN | FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | + FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI); + } + fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE; + msr |= MSR_FE0 | MSR_FE1; + } + else + { + for (thread = __OSActiveThreadQueue.head; thread; thread = thread->linkActive.next) + { + thread->context.srr1 &= ~(MSR_FE0 | MSR_FE1); + thread->context.fpscr &= ~FPSCR_ENABLE; + thread->context.fpscr &= + ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | + FPSCR_VXSNAN | FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | + FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI); + } + fpscr &= ~FPSCR_ENABLE; + msr &= ~(MSR_FE0 | MSR_FE1); } - thread->context.fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE; - thread->context.fpscr &= - ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | - FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | - FPSCR_OX | FPSCR_FX | FPSCR_FI); - } - fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE; - msr |= MSR_FE0 | MSR_FE1; - } else { - for (thread = __OSActiveThreadQueue.head; thread; thread = thread->linkActive.next) { - thread->context.srr1 &= ~(MSR_FE0 | MSR_FE1); - thread->context.fpscr &= ~FPSCR_ENABLE; - thread->context.fpscr &= - ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | - FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | - FPSCR_OX | FPSCR_FX | FPSCR_FI); - } - fpscr &= ~FPSCR_ENABLE; - msr &= ~(MSR_FE0 | MSR_FE1); - } - fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | - FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | - FPSCR_OX | FPSCR_FX | FPSCR_FI); + fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | + FPSCR_VXSNAN | FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | + FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI); - PPCMtfpscr(fpscr); - PPCMtmsr(msr); - } + PPCMtfpscr(fpscr); + PPCMtmsr(msr); + } - OSRestoreInterrupts(enabled); - return oldHandler; + OSRestoreInterrupts(enabled); + return oldHandler; } -void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar) { - OSTime now; - - now = OSGetTime(); - - if (!(context->srr1 & MSR_RI)) { - OSReport("Non-recoverable Exception %d", exception); - } else { - if (exception == __OS_EXCEPTION_PROGRAM && (context->srr1 & (0x80000000 >> 11)) && - __OSErrorTable[OS_ERROR_FPE] != 0) { - u32 fpscr; - u32 msr; - - exception = OS_ERROR_FPE; - - msr = PPCMfmsr(); - PPCMtmsr(msr | MSR_FP); - - if (__OSFPUContext) { - OSSaveFPUContext((OSContext*)__OSFPUContext); - } - - fpscr = PPCMffpscr(); - fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | - FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | - FPSCR_OX | FPSCR_FX | FPSCR_FI); - PPCMtfpscr(fpscr); - - PPCMtmsr(msr); - - if (__OSFPUContext == context) { - OSDisableScheduler(); - __OSErrorTable[exception](exception, context, dsisr, dar); - context->srr1 &= ~MSR_FP; - __OSFPUContext = NULL; - - context->fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | - FPSCR_VXSNAN | FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | - FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI); - OSEnableScheduler(); - __OSReschedule(); - } else { - context->srr1 &= ~MSR_FP; - __OSFPUContext = NULL; - } - - OSLoadContext(context); - } +void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar) +{ + OSTime now; - if (__OSErrorTable[exception]) { - OSDisableScheduler(); - __OSErrorTable[exception](exception, context, dsisr, dar); - OSEnableScheduler(); - __OSReschedule(); - OSLoadContext(context); + now = OSGetTime(); + + if (!(context->srr1 & MSR_RI)) + { + OSReport("Non-recoverable Exception %d", exception); } + else + { + if (exception == __OS_EXCEPTION_PROGRAM && (context->srr1 & (0x80000000 >> 11)) && + __OSErrorTable[OS_ERROR_FPE] != 0) + { + u32 fpscr; + u32 msr; + + exception = OS_ERROR_FPE; + + msr = PPCMfmsr(); + PPCMtmsr(msr | MSR_FP); + + if (__OSFPUContext) + { + OSSaveFPUContext((OSContext*)__OSFPUContext); + } + + fpscr = PPCMffpscr(); + fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | + FPSCR_VXSNAN | FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | + FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI); + PPCMtfpscr(fpscr); + + PPCMtmsr(msr); + + if (__OSFPUContext == context) + { + OSDisableScheduler(); + __OSErrorTable[exception](exception, context, dsisr, dar); + context->srr1 &= ~MSR_FP; + __OSFPUContext = NULL; + + context->fpscr &= + ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | + FPSCR_VXSNAN | FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | + FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI); + OSEnableScheduler(); + __OSReschedule(); + } + else + { + context->srr1 &= ~MSR_FP; + __OSFPUContext = NULL; + } + + OSLoadContext(context); + } + + if (__OSErrorTable[exception]) + { + OSDisableScheduler(); + __OSErrorTable[exception](exception, context, dsisr, dar); + OSEnableScheduler(); + __OSReschedule(); + OSLoadContext(context); + } - if (exception == OS_ERROR_DECREMENTER) { - OSLoadContext(context); + if (exception == OS_ERROR_DECREMENTER) + { + OSLoadContext(context); + } + + OSReport("Unhandled Exception %d", exception); } - OSReport("Unhandled Exception %d", exception); - } - - OSReport("\n"); - OSDumpContext(context); - OSReport("\nDSISR = 0x%08x DAR = 0x%08x\n", dsisr, dar); - OSReport("TB = 0x%016llx\n", now); - - 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); - break; - case __OS_EXCEPTION_ISI: - OSReport("\nAttempted to fetch instruction from invalid address 0x%x " - "(read from SRR0)\n", - context->srr0); - break; - 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); - break; - case __OS_EXCEPTION_PROGRAM: - OSReport("\nProgram exception : Possible illegal instruction/operation " - "at or around 0x%x (read from SRR0)\n", - context->srr0, dar); - break; - case OS_ERROR_PROTECTION: OSReport("\n"); - OSReport("AI DMA Address = 0x%04x%04x\n", __DSPRegs[0x00000018], __DSPRegs[0x00000018 + 1]); - OSReport("ARAM DMA Address = 0x%04x%04x\n", __DSPRegs[0x00000010], __DSPRegs[0x00000010 + 1]); - OSReport("DI DMA Address = 0x%08x\n", __DIRegs[0x00000005]); - break; - } + OSDumpContext(context); + OSReport("\nDSISR = 0x%08x DAR = 0x%08x\n", dsisr, dar); + OSReport("TB = 0x%016llx\n", now); + + 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); + break; + case __OS_EXCEPTION_ISI: + OSReport("\nAttempted to fetch instruction from invalid address 0x%x " + "(read from SRR0)\n", + context->srr0); + break; + 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); + break; + case __OS_EXCEPTION_PROGRAM: + OSReport("\nProgram exception : Possible illegal instruction/operation " + "at or around 0x%x (read from SRR0)\n", + context->srr0, dar); + break; + case OS_ERROR_PROTECTION: + OSReport("\n"); + OSReport("AI DMA Address = 0x%04x%04x\n", __DSPRegs[0x00000018], + __DSPRegs[0x00000018 + 1]); + OSReport("ARAM DMA Address = 0x%04x%04x\n", __DSPRegs[0x00000010], + __DSPRegs[0x00000010 + 1]); + OSReport("DI DMA Address = 0x%08x\n", __DIRegs[0x00000005]); + break; + } - OSReport("\nLast interrupt (%d): SRR0 = 0x%08x TB = 0x%016llx\n", __OSLastInterrupt, - __OSLastInterruptSrr0, __OSLastInterruptTime); + OSReport("\nLast interrupt (%d): SRR0 = 0x%08x TB = 0x%016llx\n", __OSLastInterrupt, + __OSLastInterruptSrr0, __OSLastInterruptTime); - PPCHalt(); + PPCHalt(); } diff --git a/libs/dolphin/os/OSFont.c b/libs/dolphin/os/OSFont.c index aa79fb6bc..aaf0a51a6 100644 --- a/libs/dolphin/os/OSFont.c +++ b/libs/dolphin/os/OSFont.c @@ -1,32 +1,760 @@ +#include #include -#include -#include -// there shoudl be more in this file, however this is the only thing that gets used, i'm not gonna add 1000 lines of text that have no value here +#include +#include -u16 OSGetFontEncode() +typedef char* (*ParseStringCallback)(u16, char*, OSFontHeader**, int*); + +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 c) +{ + return (0x40 <= c && c <= 0xFC) && (c != 0x7F); +} + +static int GetFontCode(u16 encode, u16 code) +{ + if (encode == OS_FONT_ENCODE_SJIS) + { + if (code >= 0x20 && code <= 0xDF) + { + return HankakuToCode[code - 0x20]; + } + + if (code > 0x889E && code <= 0x9872) + { + int i = ((code >> 8) - 0x88) * 188; + int j = (code & 0xFF); + + if (!IsSjisTrailByte(j)) + { + return 0; + } + + j -= 0x40; + if (j >= 0x40) + { + j--; + } + + return (i + j + 0x2BE); + } + + if (code >= 0x8140 && code < 0x879E) + { + int i = ((code >> 8) - 0x81) * 188; + int j = (code & 0xFF); + + if (!IsSjisTrailByte(j)) + { + return 0; + } + + j -= 0x40; + if (j >= 0x40) + { + j--; + } + + return Zenkaku2Code[i + j]; + } + } + else if (code > 0x20 && code <= 0xFF) + { + return code - 0x20; + } + + return 0; +} + +static void Decode(u8* s, u8* d) { - static u16 fontEncode = OS_FONT_ENCODE_NULL; + 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; + + os = *(int*)(s + 0x4); + r7 = *(int*)(s + 0x8); + r25 = *(int*)(s + 0xC); + + q = 0; + flag = 0; + p = 16; - if (fontEncode <= 1) + do { - return fontEncode; + // 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); } - switch (__OSTVMode) + return 0; +} + +u16 OSGetFontEncode(void) +{ + if (FontEncode != 0xFFFF) + { + return FontEncode; + } + + switch (*(int*)OSPhysicalToCached(0xCC)) { case VI_NTSC: - fontEncode = (__VIRegs[VI_DTV_STAT] & 2) ? 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: case VI_DEBUG: case VI_DEBUG_PAL: case VI_EURGB60: default: - fontEncode = OS_FONT_ENCODE_ANSI; + FontEncode = OS_FONT_ENCODE_ANSI; + } + + ParseString = (ParseStringCallback)ParseStringS; + return FontEncode; +} + +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 = *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; + } + + *pfont = font; + *pfontCode = GetFontCode(encode, code); + + 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); - return fontEncode; + 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/libs/dolphin/os/OSInterrupt.c b/libs/dolphin/os/OSInterrupt.c index a7bed16a5..12cedc3fa 100644 --- a/libs/dolphin/os/OSInterrupt.c +++ b/libs/dolphin/os/OSInterrupt.c @@ -24,8 +24,9 @@ static OSInterruptMask InterruptPrioTable[] = { 0xFFFFFFFF, }; -asm BOOL OSDisableInterrupts(void) { - // clang-format off +asm BOOL OSDisableInterrupts(void) +{ + // clang-format off nofralloc entry __RAS_OSDisableInterrupts_begin mfmsr r3 @@ -34,10 +35,11 @@ entry __RAS_OSDisableInterrupts_begin entry __RAS_OSDisableInterrupts_end rlwinm r3, r3, 17, 31, 31 blr - // clang-format on + // clang-format on } -asm BOOL OSEnableInterrupts(void) { - // clang-format off +asm BOOL OSEnableInterrupts(void) +{ + // clang-format off nofralloc mfmsr r3 @@ -45,11 +47,11 @@ asm BOOL OSEnableInterrupts(void) { mtmsr r4 rlwinm r3, r3, 17, 31, 31 blr - // clang-format on + // clang-format on } asm BOOL OSRestoreInterrupts(register BOOL level){ - // clang-format off + // clang-format off nofralloc @@ -64,364 +66,374 @@ asm BOOL OSRestoreInterrupts(register BOOL level){ mtmsr r5 rlwinm r3, r4, 17, 31, 31 blr - // clang-format on + // clang-format on } -__OSInterruptHandler - __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler) { - __OSInterruptHandler oldHandler; +__OSInterruptHandler __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler) +{ + __OSInterruptHandler oldHandler; - oldHandler = InterruptHandlerTable[interrupt]; - InterruptHandlerTable[interrupt] = handler; - return oldHandler; + oldHandler = InterruptHandlerTable[interrupt]; + InterruptHandlerTable[interrupt] = handler; + return oldHandler; } -__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt) { - return InterruptHandlerTable[interrupt]; +__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt) +{ + return InterruptHandlerTable[interrupt]; } -void __OSInterruptInit(void) { - InterruptHandlerTable = OSPhysicalToCached(0x3040); - memset(InterruptHandlerTable, 0, __OS_INTERRUPT_MAX * sizeof(__OSInterruptHandler)); +void __OSInterruptInit(void) +{ + InterruptHandlerTable = OSPhysicalToCached(0x3040); + memset(InterruptHandlerTable, 0, __OS_INTERRUPT_MAX * sizeof(__OSInterruptHandler)); - *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = 0; + *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = 0; - *(OSInterruptMask*)OSPhysicalToCached(0x00C8) = 0; + *(OSInterruptMask*)OSPhysicalToCached(0x00C8) = 0; - __PIRegs[1] = 0xf0; + __PIRegs[1] = 0xf0; - __OSMaskInterrupts(OS_INTERRUPTMASK_MEM | OS_INTERRUPTMASK_DSP | OS_INTERRUPTMASK_AI | - OS_INTERRUPTMASK_EXI | OS_INTERRUPTMASK_PI); + __OSMaskInterrupts(OS_INTERRUPTMASK_MEM | OS_INTERRUPTMASK_DSP | OS_INTERRUPTMASK_AI | + OS_INTERRUPTMASK_EXI | OS_INTERRUPTMASK_PI); - __OSSetExceptionHandler(4, ExternalInterruptHandler); + __OSSetExceptionHandler(4, ExternalInterruptHandler); } -u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current) { - u32 reg; - - switch (__cntlzw(mask)) { - 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; - if (!(current & OS_INTERRUPTMASK_MEM_1)) - reg |= 0x2; - if (!(current & OS_INTERRUPTMASK_MEM_2)) - reg |= 0x4; - if (!(current & OS_INTERRUPTMASK_MEM_3)) - reg |= 0x8; - if (!(current & OS_INTERRUPTMASK_MEM_ADDRESS)) - reg |= 0x10; - __MEMRegs[0x0000000e] = (u16)reg; - mask &= ~OS_INTERRUPTMASK_MEM; - break; - 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)) - reg |= 0x10; - if (!(current & OS_INTERRUPTMASK_DSP_ARAM)) - reg |= 0x40; - if (!(current & OS_INTERRUPTMASK_DSP_DSP)) - reg |= 0x100; - __DSPRegs[0x00000005] = (u16)reg; - mask &= ~OS_INTERRUPTMASK_DSP; - break; - case __OS_INTERRUPT_AI_AI: - reg = __AIRegs[0]; - reg &= ~0x2C; - if (!(current & OS_INTERRUPTMASK_AI_AI)) - reg |= 0x4; - __AIRegs[0] = reg; - mask &= ~OS_INTERRUPTMASK_AI; - break; - 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)) - reg |= 0x1; - if (!(current & OS_INTERRUPTMASK_EXI_0_TC)) - reg |= 0x4; - if (!(current & OS_INTERRUPTMASK_EXI_0_EXT)) - reg |= 0x400; - __EXIRegs[0] = reg; - mask &= ~OS_INTERRUPTMASK_EXI_0; - break; - case __OS_INTERRUPT_EXI_1_EXI: - case __OS_INTERRUPT_EXI_1_TC: - case __OS_INTERRUPT_EXI_1_EXT: - reg = __EXIRegs[5]; - reg &= ~0xC0F; - - if (!(current & OS_INTERRUPTMASK_EXI_1_EXI)) - reg |= 0x1; - if (!(current & OS_INTERRUPTMASK_EXI_1_TC)) - reg |= 0x4; - if (!(current & OS_INTERRUPTMASK_EXI_1_EXT)) - reg |= 0x400; - __EXIRegs[5] = reg; - mask &= ~OS_INTERRUPTMASK_EXI_1; - break; - case __OS_INTERRUPT_EXI_2_EXI: - case __OS_INTERRUPT_EXI_2_TC: - reg = __EXIRegs[10]; - reg &= ~0xF; - if (!(current & OS_INTERRUPTMASK_EXI_2_EXI)) - reg |= 0x1; - if (!(current & OS_INTERRUPTMASK_EXI_2_TC)) - reg |= 0x4; - - __EXIRegs[10] = reg; - mask &= ~OS_INTERRUPTMASK_EXI_2; - break; - 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)) { - reg |= 0x800; - } - if (!(current & OS_INTERRUPTMASK_PI_SI)) { - reg |= 0x8; - } - if (!(current & OS_INTERRUPTMASK_PI_DI)) { - reg |= 0x4; - } - if (!(current & OS_INTERRUPTMASK_PI_RSW)) { - reg |= 0x2; - } - if (!(current & OS_INTERRUPTMASK_PI_ERROR)) { - reg |= 0x1; - } - if (!(current & OS_INTERRUPTMASK_PI_VI)) { - reg |= 0x100; - } - if (!(current & OS_INTERRUPTMASK_PI_DEBUG)) { - reg |= 0x1000; - } - if (!(current & OS_INTERRUPTMASK_PI_PE_TOKEN)) { - reg |= 0x200; - } - if (!(current & OS_INTERRUPTMASK_PI_PE_FINISH)) { - reg |= 0x400; - } - if (!(current & OS_INTERRUPTMASK_PI_HSP)) { - reg |= 0x2000; +u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current) +{ + u32 reg; + + switch (__cntlzw(mask)) + { + 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; + if (!(current & OS_INTERRUPTMASK_MEM_1)) + reg |= 0x2; + if (!(current & OS_INTERRUPTMASK_MEM_2)) + reg |= 0x4; + if (!(current & OS_INTERRUPTMASK_MEM_3)) + reg |= 0x8; + if (!(current & OS_INTERRUPTMASK_MEM_ADDRESS)) + reg |= 0x10; + __MEMRegs[0x0000000e] = (u16)reg; + mask &= ~OS_INTERRUPTMASK_MEM; + break; + 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)) + reg |= 0x10; + if (!(current & OS_INTERRUPTMASK_DSP_ARAM)) + reg |= 0x40; + if (!(current & OS_INTERRUPTMASK_DSP_DSP)) + reg |= 0x100; + __DSPRegs[0x00000005] = (u16)reg; + mask &= ~OS_INTERRUPTMASK_DSP; + break; + case __OS_INTERRUPT_AI_AI: + reg = __AIRegs[0]; + reg &= ~0x2C; + if (!(current & OS_INTERRUPTMASK_AI_AI)) + reg |= 0x4; + __AIRegs[0] = reg; + mask &= ~OS_INTERRUPTMASK_AI; + break; + 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)) + reg |= 0x1; + if (!(current & OS_INTERRUPTMASK_EXI_0_TC)) + reg |= 0x4; + if (!(current & OS_INTERRUPTMASK_EXI_0_EXT)) + reg |= 0x400; + __EXIRegs[0] = reg; + mask &= ~OS_INTERRUPTMASK_EXI_0; + break; + case __OS_INTERRUPT_EXI_1_EXI: + case __OS_INTERRUPT_EXI_1_TC: + case __OS_INTERRUPT_EXI_1_EXT: + reg = __EXIRegs[5]; + reg &= ~0xC0F; + + if (!(current & OS_INTERRUPTMASK_EXI_1_EXI)) + reg |= 0x1; + if (!(current & OS_INTERRUPTMASK_EXI_1_TC)) + reg |= 0x4; + if (!(current & OS_INTERRUPTMASK_EXI_1_EXT)) + reg |= 0x400; + __EXIRegs[5] = reg; + mask &= ~OS_INTERRUPTMASK_EXI_1; + break; + case __OS_INTERRUPT_EXI_2_EXI: + case __OS_INTERRUPT_EXI_2_TC: + reg = __EXIRegs[10]; + reg &= ~0xF; + if (!(current & OS_INTERRUPTMASK_EXI_2_EXI)) + reg |= 0x1; + if (!(current & OS_INTERRUPTMASK_EXI_2_TC)) + reg |= 0x4; + + __EXIRegs[10] = reg; + mask &= ~OS_INTERRUPTMASK_EXI_2; + break; + 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)) + { + reg |= 0x800; + } + if (!(current & OS_INTERRUPTMASK_PI_SI)) + { + reg |= 0x8; + } + if (!(current & OS_INTERRUPTMASK_PI_DI)) + { + reg |= 0x4; + } + if (!(current & OS_INTERRUPTMASK_PI_RSW)) + { + reg |= 0x2; + } + if (!(current & OS_INTERRUPTMASK_PI_ERROR)) + { + reg |= 0x1; + } + if (!(current & OS_INTERRUPTMASK_PI_VI)) + { + reg |= 0x100; + } + if (!(current & OS_INTERRUPTMASK_PI_DEBUG)) + { + reg |= 0x1000; + } + if (!(current & OS_INTERRUPTMASK_PI_PE_TOKEN)) + { + reg |= 0x200; + } + if (!(current & OS_INTERRUPTMASK_PI_PE_FINISH)) + { + reg |= 0x400; + } + if (!(current & OS_INTERRUPTMASK_PI_HSP)) + { + reg |= 0x2000; + } + __PIRegs[1] = reg; + mask &= ~OS_INTERRUPTMASK_PI; + break; + default: + break; } - __PIRegs[1] = reg; - mask &= ~OS_INTERRUPTMASK_PI; - break; - default: - break; - } - return mask; -} - -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; + return mask; } -OSInterruptMask __OSMaskInterrupts(OSInterruptMask global) { - BOOL enabled; - OSInterruptMask prev; - OSInterruptMask local; - OSInterruptMask mask; - - enabled = OSDisableInterrupts(); - prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4); - local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8); - mask = ~(prev | local) & global; - global |= prev; - *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global; - while (mask) { - mask = SetInterruptMask(mask, global | local); - } - OSRestoreInterrupts(enabled); - return prev; +OSInterruptMask __OSMaskInterrupts(OSInterruptMask global) +{ + BOOL enabled; + OSInterruptMask prev; + OSInterruptMask local; + OSInterruptMask mask; + + enabled = OSDisableInterrupts(); + prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4); + local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8); + mask = ~(prev | local) & global; + global |= prev; + *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global; + while (mask) + { + mask = SetInterruptMask(mask, global | local); + } + OSRestoreInterrupts(enabled); + return prev; } -OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask global) { - BOOL enabled; - OSInterruptMask prev; - OSInterruptMask local; - OSInterruptMask mask; - - enabled = OSDisableInterrupts(); - prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4); - local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8); - mask = (prev | local) & global; - global = prev & ~global; - *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global; - while (mask) { - mask = SetInterruptMask(mask, global | local); - } - OSRestoreInterrupts(enabled); - return prev; +OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask global) +{ + BOOL enabled; + OSInterruptMask prev; + OSInterruptMask local; + OSInterruptMask mask; + + enabled = OSDisableInterrupts(); + prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4); + local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8); + mask = (prev | local) & global; + global = prev & ~global; + *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global; + while (mask) + { + mask = SetInterruptMask(mask, global | local); + } + OSRestoreInterrupts(enabled); + return prev; } volatile OSTime __OSLastInterruptTime; volatile __OSInterrupt __OSLastInterrupt; volatile u32 __OSLastInterruptSrr0; -void __OSDispatchInterrupt(__OSException exception, OSContext* context) { - u32 intsr; - u32 reg; - OSInterruptMask cause; - OSInterruptMask unmasked; - OSInterruptMask* prio; - __OSInterrupt interrupt; - __OSInterruptHandler handler; - intsr = __PIRegs[0]; - intsr &= ~0x00010000; - - if (intsr == 0 || (intsr & __PIRegs[1]) == 0) { - OSLoadContext(context); - } - - cause = 0; - - if (intsr & 0x00000080) { - reg = __MEMRegs[15]; - if (reg & 0x1) - cause |= OS_INTERRUPTMASK_MEM_0; - if (reg & 0x2) - cause |= OS_INTERRUPTMASK_MEM_1; - if (reg & 0x4) - cause |= OS_INTERRUPTMASK_MEM_2; - if (reg & 0x8) - cause |= OS_INTERRUPTMASK_MEM_3; - if (reg & 0x10) - cause |= OS_INTERRUPTMASK_MEM_ADDRESS; - } - - if (intsr & 0x00000040) { - reg = __DSPRegs[5]; - if (reg & 0x8) - cause |= OS_INTERRUPTMASK_DSP_AI; - if (reg & 0x20) - cause |= OS_INTERRUPTMASK_DSP_ARAM; - if (reg & 0x80) - cause |= OS_INTERRUPTMASK_DSP_DSP; - } - - if (intsr & 0x00000020) { - reg = __AIRegs[0]; - if (reg & 0x8) - cause |= OS_INTERRUPTMASK_AI_AI; - } - - if (intsr & 0x00000010) { - reg = __EXIRegs[0]; - if (reg & 0x2) - cause |= OS_INTERRUPTMASK_EXI_0_EXI; - if (reg & 0x8) - cause |= OS_INTERRUPTMASK_EXI_0_TC; - if (reg & 0x800) - cause |= OS_INTERRUPTMASK_EXI_0_EXT; - reg = __EXIRegs[5]; - if (reg & 0x2) - cause |= OS_INTERRUPTMASK_EXI_1_EXI; - if (reg & 0x8) - cause |= OS_INTERRUPTMASK_EXI_1_TC; - if (reg & 0x800) - cause |= OS_INTERRUPTMASK_EXI_1_EXT; - reg = __EXIRegs[10]; - if (reg & 0x2) - cause |= OS_INTERRUPTMASK_EXI_2_EXI; - if (reg & 0x8) - cause |= OS_INTERRUPTMASK_EXI_2_TC; - } - - if (intsr & 0x00002000) - cause |= OS_INTERRUPTMASK_PI_HSP; - if (intsr & 0x00001000) - cause |= OS_INTERRUPTMASK_PI_DEBUG; - if (intsr & 0x00000400) - cause |= OS_INTERRUPTMASK_PI_PE_FINISH; - if (intsr & 0x00000200) - cause |= OS_INTERRUPTMASK_PI_PE_TOKEN; - if (intsr & 0x00000100) - cause |= OS_INTERRUPTMASK_PI_VI; - if (intsr & 0x00000008) - cause |= OS_INTERRUPTMASK_PI_SI; - if (intsr & 0x00000004) - cause |= OS_INTERRUPTMASK_PI_DI; - if (intsr & 0x00000002) - cause |= OS_INTERRUPTMASK_PI_RSW; - if (intsr & 0x00000800) - cause |= OS_INTERRUPTMASK_PI_CP; - if (intsr & 0x00000001) - cause |= OS_INTERRUPTMASK_PI_ERROR; - - unmasked = cause & ~(*(OSInterruptMask*)OSPhysicalToCached(0x00C4) | - *(OSInterruptMask*)OSPhysicalToCached(0x00C8)); - if (unmasked) { - for (prio = InterruptPrioTable;; ++prio) { - if (unmasked & *prio) { - interrupt = (__OSInterrupt)__cntlzw(unmasked & *prio); - break; - } +void __OSDispatchInterrupt(__OSException exception, OSContext* context) +{ + u32 intsr; + u32 reg; + OSInterruptMask cause; + OSInterruptMask unmasked; + OSInterruptMask* prio; + __OSInterrupt interrupt; + __OSInterruptHandler handler; + intsr = __PIRegs[0]; + intsr &= ~0x00010000; + + if (intsr == 0 || (intsr & __PIRegs[1]) == 0) + { + OSLoadContext(context); + } + + cause = 0; + + if (intsr & 0x00000080) + { + reg = __MEMRegs[15]; + if (reg & 0x1) + cause |= OS_INTERRUPTMASK_MEM_0; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_MEM_1; + if (reg & 0x4) + cause |= OS_INTERRUPTMASK_MEM_2; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_MEM_3; + if (reg & 0x10) + cause |= OS_INTERRUPTMASK_MEM_ADDRESS; + } + + if (intsr & 0x00000040) + { + reg = __DSPRegs[5]; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_DSP_AI; + if (reg & 0x20) + cause |= OS_INTERRUPTMASK_DSP_ARAM; + if (reg & 0x80) + cause |= OS_INTERRUPTMASK_DSP_DSP; + } + + if (intsr & 0x00000020) + { + reg = __AIRegs[0]; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_AI_AI; + } + + if (intsr & 0x00000010) + { + reg = __EXIRegs[0]; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_EXI_0_EXI; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_EXI_0_TC; + if (reg & 0x800) + cause |= OS_INTERRUPTMASK_EXI_0_EXT; + reg = __EXIRegs[5]; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_EXI_1_EXI; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_EXI_1_TC; + if (reg & 0x800) + cause |= OS_INTERRUPTMASK_EXI_1_EXT; + reg = __EXIRegs[10]; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_EXI_2_EXI; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_EXI_2_TC; } - handler = __OSGetInterruptHandler(interrupt); - if (handler) { - if (__OS_INTERRUPT_MEM_ADDRESS < interrupt) { - __OSLastInterrupt = interrupt; - __OSLastInterruptTime = OSGetTime(); - __OSLastInterruptSrr0 = context->srr0; - } - - OSDisableScheduler(); - handler(interrupt, context); - OSEnableScheduler(); - __OSReschedule(); - OSLoadContext(context); + if (intsr & 0x00002000) + cause |= OS_INTERRUPTMASK_PI_HSP; + if (intsr & 0x00001000) + cause |= OS_INTERRUPTMASK_PI_DEBUG; + if (intsr & 0x00000400) + cause |= OS_INTERRUPTMASK_PI_PE_FINISH; + if (intsr & 0x00000200) + cause |= OS_INTERRUPTMASK_PI_PE_TOKEN; + if (intsr & 0x00000100) + cause |= OS_INTERRUPTMASK_PI_VI; + if (intsr & 0x00000008) + cause |= OS_INTERRUPTMASK_PI_SI; + if (intsr & 0x00000004) + cause |= OS_INTERRUPTMASK_PI_DI; + if (intsr & 0x00000002) + cause |= OS_INTERRUPTMASK_PI_RSW; + if (intsr & 0x00000800) + cause |= OS_INTERRUPTMASK_PI_CP; + if (intsr & 0x00000001) + cause |= OS_INTERRUPTMASK_PI_ERROR; + + unmasked = cause & ~(*(OSInterruptMask*)OSPhysicalToCached(0x00C4) | + *(OSInterruptMask*)OSPhysicalToCached(0x00C8)); + if (unmasked) + { + for (prio = InterruptPrioTable;; ++prio) + { + if (unmasked & *prio) + { + interrupt = (__OSInterrupt)__cntlzw(unmasked & *prio); + break; + } + } + + handler = __OSGetInterruptHandler(interrupt); + if (handler) + { + if (__OS_INTERRUPT_MEM_ADDRESS < interrupt) + { + __OSLastInterrupt = interrupt; + __OSLastInterruptTime = OSGetTime(); + __OSLastInterruptSrr0 = context->srr0; + } + + OSDisableScheduler(); + handler(interrupt, context); + OSEnableScheduler(); + __OSReschedule(); + OSLoadContext(context); + } } - } - OSLoadContext(context); + OSLoadContext(context); } static asm void ExternalInterruptHandler(register __OSException exception, - register OSContext* context) { + register OSContext* context) +{ #pragma unused(exception) - // clang-format off + // clang-format off nofralloc OS_EXCEPTION_SAVE_GPRS(context) stwu r1, -8(r1) b __OSDispatchInterrupt - // clang-format on + // clang-format on } diff --git a/libs/dolphin/os/OSLink.c b/libs/dolphin/os/OSLink.c index d6f5a51d7..c035ef60e 100644 --- a/libs/dolphin/os/OSLink.c +++ b/libs/dolphin/os/OSLink.c @@ -1,556 +1,10 @@ #include -#define SHN_UNDEF 0 -#define SHN_LORESERVE 0xff00 -#define SHN_LOPROC 0xff00 -#define SHN_HIPROC 0xff1f -#define SHN_ABS 0xfff1 -#define SHN_COMMON 0xfff2 -#define SHN_HIRESERVE 0xffff - -#define ELF32_R_SYM(i) ((i) >> 8) -#define ELF32_R_TYPE(i) ((unsigned char)(i)) -#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_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_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_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 - OSModuleQueue __OSModuleInfoList : (OS_BASE_CACHED | 0x30C8); const void* __OSStringTable : (OS_BASE_CACHED | 0x30D0); -#pragma dont_inline on -__declspec(weak) void OSNotifyLink(OSModuleInfo* module) {} - -__declspec(weak) void OSNotifyUnlink(OSModuleInfo* module) {} - -#pragma dont_inline reset - -#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) - -#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) - -void OSSetStringTable(const void* stringTable) { __OSStringTable = stringTable; } - -static BOOL Relocate(OSModuleHeader* newModule, OSModuleHeader* module) { - OSModuleID idNew; - OSImportInfo* imp; - OSRel* rel; - OSSectionInfo* si; - OSSectionInfo* siFlush; - u32* p; - u32 offset; - u32 x; - - idNew = newModule ? newModule->info.id : 0; - for (imp = (OSImportInfo*)module->impOffset; - imp < (OSImportInfo*)(module->impOffset + module->impSize); imp++) { - if (imp->id == idNew) { - goto Found; - } - } - return FALSE; - -Found: - siFlush = 0; - for (rel = (OSRel*)imp->offset; rel->type != R_DOLPHIN_END; rel++) { - (u8*)p += rel->offset; - if (idNew) { - si = &OSGetSectionInfo(newModule)[rel->section]; - offset = OS_SECTIONINFO_OFFSET(si->offset); - } else { - offset = 0; - } - switch (rel->type) { - case R_PPC_NONE: - break; - case R_PPC_ADDR32: - x = offset + rel->addend; - *p = x; - break; - case R_PPC_ADDR24: - x = offset + rel->addend; - *p = (*p & ~0x03fffffc) | (x & 0x03fffffc); - break; - case R_PPC_ADDR16: - x = offset + rel->addend; - *(u16*)p = (u16)(x & 0xffff); - break; - case R_PPC_ADDR16_LO: - x = offset + rel->addend; - *(u16*)p = (u16)(x & 0xffff); - break; - case R_PPC_ADDR16_HI: - x = offset + rel->addend; - *(u16*)p = (u16)(((x >> 16) & 0xffff)); - break; - case R_PPC_ADDR16_HA: - x = offset + rel->addend; - *(u16*)p = (u16)(((x >> 16) + ((x & 0x8000) ? 1 : 0)) & 0xffff); - break; - case R_PPC_ADDR14: - case R_PPC_ADDR14_BRTAKEN: - case R_PPC_ADDR14_BRNTAKEN: - x = offset + rel->addend; - *p = (*p & ~0x0000fffc) | (x & 0x0000fffc); - break; - case R_PPC_REL24: - x = offset + rel->addend - (u32)p; - *p = (*p & ~0x03fffffc) | (x & 0x03fffffc); - break; - case R_PPC_REL14: - case R_PPC_REL14_BRTAKEN: - case R_PPC_REL14_BRNTAKEN: - x = offset + rel->addend - (u32)p; - *p = (*p & ~0x0000fffc) | (x & 0x0000fffc); - break; - case R_DOLPHIN_NOP: - break; - case R_DOLPHIN_SECTION: - si = &OSGetSectionInfo(module)[rel->section]; - p = (u32*)OS_SECTIONINFO_OFFSET(si->offset); - if (siFlush) { - offset = OS_SECTIONINFO_OFFSET(siFlush->offset); - DCFlushRange((void*)offset, siFlush->size); - ICInvalidateRange((void*)offset, siFlush->size); - } - siFlush = (si->offset & OS_SECTIONINFO_EXEC) ? si : 0; - break; - default: - OSReport("OSLink: unknown relocation type %3d\n", rel->type); - break; - } - } - - if (siFlush) { - offset = OS_SECTIONINFO_OFFSET(siFlush->offset); - DCFlushRange((void*)offset, siFlush->size); - ICInvalidateRange((void*)offset, siFlush->size); - } - - return TRUE; -} - -#if OS_MODULE_VERSION >= 3 -static BOOL Link(OSModuleInfo* newModule, void* bss, BOOL fixed) { - u32 i; - OSSectionInfo* si; - OSModuleHeader* moduleHeader; - OSModuleInfo* moduleInfo; - OSImportInfo* imp; - - moduleHeader = (OSModuleHeader*)newModule; - moduleHeader->bssSection = 0; - - if (OS_MODULE_VERSION < newModule->version || - 2 <= newModule->version && - (moduleHeader->align && (u32)newModule % moduleHeader->align != 0 || - moduleHeader->bssAlign && (u32)bss % moduleHeader->bssAlign != 0)) { - return FALSE; - } - - EnqueueTail(&__OSModuleInfoList, newModule, link); - newModule->sectionInfoOffset += (u32)moduleHeader; - moduleHeader->relOffset += (u32)moduleHeader; - moduleHeader->impOffset += (u32)moduleHeader; - if (3 <= newModule->version) { - moduleHeader->fixSize += (u32)moduleHeader; - } - for (i = 1; i < newModule->numSections; i++) { - si = &OSGetSectionInfo(newModule)[i]; - if (si->offset != 0) { - si->offset += (u32)moduleHeader; - } else if (si->size != 0) { - moduleHeader->bssSection = (u8)i; - si->offset = (u32)bss; - bss = (void*)((u32)bss + si->size); - } - } - for (imp = (OSImportInfo*)moduleHeader->impOffset; - imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) { - imp->offset += (u32)moduleHeader; - } - if (moduleHeader->prologSection != SHN_UNDEF) { - moduleHeader->prolog += - OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->prologSection].offset); - } - if (moduleHeader->epilogSection != SHN_UNDEF) { - moduleHeader->epilog += - OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->epilogSection].offset); - } - if (moduleHeader->unresolvedSection != SHN_UNDEF) { - moduleHeader->unresolved += - OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->unresolvedSection].offset); - } - if (__OSStringTable) { - newModule->nameOffset += (u32)__OSStringTable; - } - - Relocate(0, moduleHeader); - - for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) { - Relocate(moduleHeader, (OSModuleHeader*)moduleInfo); - if (moduleInfo != newModule) { - Relocate((OSModuleHeader*)moduleInfo, moduleHeader); - } - } - - if (fixed) { - for (imp = (OSImportInfo*)moduleHeader->impOffset; - imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) { - if (imp->id == 0 || imp->id == newModule->id) { - moduleHeader->impSize = (u32)((u8*)imp - (u8*)moduleHeader->impOffset); - break; - } - } - } - - memset(bss, 0, moduleHeader->bssSize); - - OSNotifyLink(newModule); - - return TRUE; -} - -BOOL OSLink(OSModuleInfo* newModule, void* bss) { return Link(newModule, bss, FALSE); } - -BOOL OSLinkFixed(OSModuleInfo* newModule, void* bss) { - if (OS_MODULE_VERSION < newModule->version || newModule->version < 3) { - return FALSE; - } - return Link(newModule, bss, TRUE); -} -#else -BOOL OSLink(OSModuleInfo* newModule, void* bss) { - u32 i; - OSSectionInfo* si; - OSModuleHeader* moduleHeader; - OSModuleInfo* moduleInfo; - OSImportInfo* imp; - - moduleHeader = (OSModuleHeader*)newModule; - moduleHeader->bssSection = 0; - - if (OS_MODULE_VERSION < newModule->version || - 2 <= newModule->version && - (moduleHeader->align && (u32)newModule % moduleHeader->align != 0 || - moduleHeader->bssAlign && (u32)bss % moduleHeader->bssAlign != 0)) { - return FALSE; - } - - EnqueueTail(&__OSModuleInfoList, newModule, link); - memset(bss, 0, moduleHeader->bssSize); - newModule->sectionInfoOffset += (u32)moduleHeader; - moduleHeader->relOffset += (u32)moduleHeader; - moduleHeader->impOffset += (u32)moduleHeader; - - for (i = 1; i < newModule->numSections; i++) { - si = &OSGetSectionInfo(newModule)[i]; - if (si->offset != 0) { - si->offset += (u32)moduleHeader; - } else if (si->size != 0) { - moduleHeader->bssSection = (u8)i; - si->offset = (u32)bss; - bss = (void*)((u32)bss + si->size); - } - } - for (imp = (OSImportInfo*)moduleHeader->impOffset; - imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) { - imp->offset += (u32)moduleHeader; - } - if (moduleHeader->prologSection != SHN_UNDEF) { - moduleHeader->prolog += - OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->prologSection].offset); - } - if (moduleHeader->epilogSection != SHN_UNDEF) { - moduleHeader->epilog += - OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->epilogSection].offset); - } - if (moduleHeader->unresolvedSection != SHN_UNDEF) { - moduleHeader->unresolved += - OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->unresolvedSection].offset); - } - if (__OSStringTable) { - newModule->nameOffset += (u32)__OSStringTable; - } - - Relocate(0, moduleHeader); - - for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) { - Relocate(moduleHeader, (OSModuleHeader*)moduleInfo); - if (moduleInfo != newModule) { - Relocate((OSModuleHeader*)moduleInfo, moduleHeader); - } - } - - OSNotifyLink(newModule); - - return TRUE; -} -#endif - -static BOOL Undo(OSModuleHeader* newModule, OSModuleHeader* module) { - OSModuleID idNew; - OSImportInfo* imp; - OSRel* rel; - OSSectionInfo* si; - OSSectionInfo* siFlush; - u32* p; - u32 offset; - u32 x; - - idNew = newModule->info.id; - for (imp = (OSImportInfo*)module->impOffset; - imp < (OSImportInfo*)(module->impOffset + module->impSize); imp++) { - if (imp->id == idNew) { - goto Found; - } - } - return FALSE; - -Found: - siFlush = 0; - for (rel = (OSRel*)imp->offset; rel->type != R_DOLPHIN_END; rel++) { - (u8*)p += rel->offset; - si = &OSGetSectionInfo(newModule)[rel->section]; - offset = OS_SECTIONINFO_OFFSET(si->offset); - x = 0; - switch (rel->type) { - case R_PPC_NONE: - break; - case R_PPC_ADDR32: - *p = x; - break; - case R_PPC_ADDR24: - *p = (*p & ~0x03fffffc) | (x & 0x03fffffc); - break; - case R_PPC_ADDR16: - *(u16*)p = (u16)(x & 0xffff); - break; - case R_PPC_ADDR16_LO: - *(u16*)p = (u16)(x & 0xffff); - break; - case R_PPC_ADDR16_HI: - *(u16*)p = (u16)(((x >> 16) & 0xffff)); - break; - case R_PPC_ADDR16_HA: - *(u16*)p = (u16)(((x >> 16) + ((x & 0x8000) ? 1 : 0)) & 0xffff); - break; - case R_PPC_ADDR14: - case R_PPC_ADDR14_BRTAKEN: - case R_PPC_ADDR14_BRNTAKEN: - *p = (*p & ~0x0000fffc) | (x & 0x0000fffc); - break; - case R_PPC_REL24: - if (module->unresolvedSection != SHN_UNDEF) { - x = (u32)module->unresolved - (u32)p; - } - *p = (*p & ~0x03fffffc) | (x & 0x03fffffc); - break; - case R_PPC_REL14: - case R_PPC_REL14_BRTAKEN: - case R_PPC_REL14_BRNTAKEN: - *p = (*p & ~0x0000fffc) | (x & 0x0000fffc); - break; - case R_DOLPHIN_NOP: - break; - case R_DOLPHIN_SECTION: - si = &OSGetSectionInfo(module)[rel->section]; - p = (u32*)OS_SECTIONINFO_OFFSET(si->offset); - if (siFlush) { - offset = OS_SECTIONINFO_OFFSET(siFlush->offset); - DCFlushRange((void*)offset, siFlush->size); - ICInvalidateRange((void*)offset, siFlush->size); - } - siFlush = (si->offset & OS_SECTIONINFO_EXEC) ? si : 0; - break; - default: - OSReport("OSUnlink: unknown relocation type %3d\n", rel->type); - break; - } - } - - if (siFlush) { - offset = OS_SECTIONINFO_OFFSET(siFlush->offset); - DCFlushRange((void*)offset, siFlush->size); - ICInvalidateRange((void*)offset, siFlush->size); - } - - return TRUE; -} - -BOOL OSUnlink(OSModuleInfo* oldModule) { - OSModuleHeader* moduleHeader; - OSModuleInfo* moduleInfo; - u32 i; - OSSectionInfo* si; - OSImportInfo* imp; - - moduleHeader = (OSModuleHeader*)oldModule; - - DequeueItem(&__OSModuleInfoList, oldModule, link); - - for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) { - Undo(moduleHeader, (OSModuleHeader*)moduleInfo); - } - - OSNotifyUnlink(oldModule); - - if (__OSStringTable) { - oldModule->nameOffset -= (u32)__OSStringTable; - } - if (moduleHeader->prologSection != SHN_UNDEF) { - moduleHeader->prolog -= - OS_SECTIONINFO_OFFSET(OSGetSectionInfo(oldModule)[moduleHeader->prologSection].offset); - } - if (moduleHeader->epilogSection != SHN_UNDEF) { - moduleHeader->epilog -= - OS_SECTIONINFO_OFFSET(OSGetSectionInfo(oldModule)[moduleHeader->epilogSection].offset); - } - if (moduleHeader->unresolvedSection != SHN_UNDEF) { - moduleHeader->unresolved -= - OS_SECTIONINFO_OFFSET(OSGetSectionInfo(oldModule)[moduleHeader->unresolvedSection].offset); - } - for (imp = (OSImportInfo*)moduleHeader->impOffset; - imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) { - imp->offset -= (u32)moduleHeader; - } - for (i = 1; i < oldModule->numSections; i++) { - si = &OSGetSectionInfo(oldModule)[i]; - if (i == moduleHeader->bssSection) { - moduleHeader->bssSection = 0; - si->offset = 0; - } else if (si->offset != 0) { - si->offset -= (u32)moduleHeader; - } - } - moduleHeader->relOffset -= (u32)moduleHeader; - moduleHeader->impOffset -= (u32)moduleHeader; - oldModule->sectionInfoOffset -= (u32)moduleHeader; - - return TRUE; -} - -void __OSModuleInit(void) { - __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; - } - - for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) { - sectionInfo = OSGetSectionInfo(moduleInfo); - for (i = 0; i < moduleInfo->numSections; ++i) { - if (sectionInfo->size) { - baseSection = OS_SECTIONINFO_OFFSET(sectionInfo->offset); - if (baseSection <= (u32)ptr && (u32)ptr < baseSection + sectionInfo->size) { - if (section) { - *section = i; - } - if (offset) { - *offset = (u32)ptr - baseSection; - } - return moduleInfo; - } - } - sectionInfo++; - } - } - - return NULL; +void __OSModuleInit(void) +{ + __OSModuleInfoList.head = __OSModuleInfoList.tail = 0; + __OSStringTable = 0; } diff --git a/libs/dolphin/os/OSMemory.c b/libs/dolphin/os/OSMemory.c index 71d3097af..9fed89b6d 100644 --- a/libs/dolphin/os/OSMemory.c +++ b/libs/dolphin/os/OSMemory.c @@ -1,4 +1,5 @@ #include +#include #define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) #define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) @@ -12,72 +13,47 @@ static OSResetFunctionInfo ResetFunctionInfo = { 127, }; -u32 OSGetPhysicalMemSize() { return *(u32 *)(OSPhysicalToCached(0x0028)); } - -u32 OSGetConsoleSimulatedMemSize() { return *(u32 *)(OSPhysicalToCached(0x00F0)); } - -static BOOL OnReset(BOOL final) { - if (final != FALSE) { - __MEMRegs[8] = 0xFF; - __OSMaskInterrupts(0xf0000000); - } - return TRUE; +// u32 OSGetPhysicalMemSize() +// { +// return *(u32*)(OSPhysicalToCached(0x0028)); +// } + +// u32 OSGetConsoleSimulatedMemSize() +// { +// return *(u32*)(OSPhysicalToCached(0x00F0)); +// } + +static BOOL OnReset(BOOL final) +{ + if (final != FALSE) + { + __MEMRegs[8] = 0xFF; + __OSMaskInterrupts(0xf0000000); + } + return TRUE; } -static void MEMIntrruptHandler(__OSInterrupt interrupt, OSContext* context) { - u32 addr; - u32 cause; +static void MEMIntrruptHandler(__OSInterrupt interrupt, OSContext* context) +{ + u32 addr; + u32 cause; - cause = __MEMRegs[0xf]; - addr = (((u32)__MEMRegs[0x12] & 0x3ff) << 16) | __MEMRegs[0x11]; - __MEMRegs[0x10] = 0; + cause = __MEMRegs[0xf]; + addr = (((u32)__MEMRegs[0x12] & 0x3ff) << 16) | __MEMRegs[0x11]; + __MEMRegs[0x10] = 0; - if (__OSErrorTable[OS_ERROR_PROTECTION]) { - __OSErrorTable[OS_ERROR_PROTECTION](OS_ERROR_PROTECTION, context, cause, addr); - return; - } + if (__OSErrorTable[OS_ERROR_PROTECTION]) + { + __OSErrorTable[OS_ERROR_PROTECTION](OS_ERROR_PROTECTION, context, cause, addr); + return; + } - __OSUnhandledException(OS_ERROR_PROTECTION, context, cause, addr); + __OSUnhandledException(OS_ERROR_PROTECTION, context, cause, addr); } -void OSProtectRange(u32 chan, void* addr, u32 nBytes, u32 control) { - BOOL enabled; - u32 start; - u32 end; - u16 reg; - if (4 <= chan) { - return; - } - - control &= OS_PROTECT_CONTROL_RDWR; - - end = (u32)addr + nBytes; - start = TRUNC(addr, 1u << 10); - end = ROUND(end, 1u << 10); - - DCFlushRange((void*)start, end - start); - - enabled = OSDisableInterrupts(); - - __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 |= control << 2 * chan; - __MEMRegs[8] = reg; - - if (control != OS_PROTECT_CONTROL_RDWR) { - __OSUnmaskInterrupts(OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_0 + chan)); - } - - OSRestoreInterrupts(enabled); -} - -asm void Config24MB() { - // clang-format off +asm void Config24MB() +{ + // clang-format off nofralloc addi r7,r0,0 @@ -121,11 +97,12 @@ asm void Config24MB() { mflr r3 mtsrr0 r3 rfi - // clang-format on + // clang-format on } -asm void Config48MB() { - // clang-format off +asm void Config48MB() +{ + // clang-format off nofralloc addi r7,r0,0x0000 @@ -169,11 +146,12 @@ asm void Config48MB() { mflr r3 mtsrr0 r3 rfi - // clang-format on + // clang-format on } -asm void RealMode(register u32 addr) { - // clang-format off +asm void RealMode(register u32 addr) +{ + // clang-format off nofralloc clrlwi r3, r3, 2 mtsrr0 r3 @@ -181,43 +159,45 @@ asm void RealMode(register u32 addr) { rlwinm r3, r3, 0, 28, 25 mtsrr1 r3 rfi - // clang-format on + // clang-format on } -void __OSInitMemoryProtection() { - u32 padding[8]; - u32 simulatedSize; - BOOL enabled; - simulatedSize = OSGetConsoleSimulatedMemSize(); - enabled = OSDisableInterrupts(); - - __MEMRegs[16] = 0; - __MEMRegs[8] = 0xFF; - - __OSMaskInterrupts(OS_INTERRUPTMASK_MEM_0 | OS_INTERRUPTMASK_MEM_1 | OS_INTERRUPTMASK_MEM_2 | - OS_INTERRUPTMASK_MEM_3); - __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) { - DCInvalidateRange((void*)0x81800000, 0x1800000); - __MEMRegs[20] = 2; - } - - if (simulatedSize <= 0x1800000) - { - RealMode((u32)&Config24MB); - } - else if (simulatedSize <= 0x3000000) - { - RealMode((u32)&Config48MB); - } - - __OSUnmaskInterrupts(OS_INTERRUPTMASK_MEM_ADDRESS); - OSRestoreInterrupts(enabled); +void __OSInitMemoryProtection() +{ + u32 padding[12]; + u32 simulatedSize; + BOOL enabled; + simulatedSize = *(u32*)(OSPhysicalToCached(0x00F0)); + enabled = OSDisableInterrupts(); + + __MEMRegs[16] = 0; + __MEMRegs[8] = 0xFF; + + __OSMaskInterrupts(OS_INTERRUPTMASK_MEM_0 | OS_INTERRUPTMASK_MEM_1 | OS_INTERRUPTMASK_MEM_2 | + OS_INTERRUPTMASK_MEM_3); + __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 (*(u32*)(OSPhysicalToCached(0x00F0)) < *(u32*)(OSPhysicalToCached(0x0028)) && + *(u32*)(OSPhysicalToCached(0x00F0)) == 0x1800000) + { + DCInvalidateRange((void*)0x81800000, 0x1800000); + __MEMRegs[20] = 2; + } + + if (simulatedSize <= 0x1800000) + { + RealMode((u32)&Config24MB); + } + else if (simulatedSize <= 0x3000000) + { + RealMode((u32)&Config48MB); + } + + __OSUnmaskInterrupts(OS_INTERRUPTMASK_MEM_ADDRESS); + OSRestoreInterrupts(enabled); } diff --git a/libs/dolphin/os/OSMutex.c b/libs/dolphin/os/OSMutex.c index f853729e0..adfa396ab 100644 --- a/libs/dolphin/os/OSMutex.c +++ b/libs/dolphin/os/OSMutex.c @@ -1,223 +1,63 @@ #include "dolphin/os.h" #define PushTail(queue, mutex, link) \ - do { \ - OSMutex* __prev; \ + 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) + __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) #define PopHead(queue, mutex, link) \ - do { \ - OSMutex* __next; \ + 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) + (mutex) = (queue)->head; \ + __next = (mutex)->link.next; \ + if (__next == NULL) \ + (queue)->tail = NULL; \ + else \ + __next->link.prev = NULL; \ + (queue)->head = __next; \ + } while (0) #define PopItem(queue, mutex, link) \ - do { \ - OSMutex* __next; \ - OSMutex* __prev; \ + do \ + { \ + OSMutex* __next; \ + OSMutex* __prev; \ \ - __next = (mutex)->link.next; \ - __prev = (mutex)->link.prev; \ + __next = (mutex)->link.next; \ + __prev = (mutex)->link.prev; \ \ - if (__next == NULL) \ - (queue)->tail = __prev; \ - else \ - __next->link.prev = __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) - -void OSInitMutex(OSMutex* mutex) { - OSInitThreadQueue(&mutex->queue); - mutex->thread = 0; - mutex->count = 0; -} - -void OSLockMutex(OSMutex* mutex) { - BOOL enabled = OSDisableInterrupts(); - OSThread* currentThread = OSGetCurrentThread(); - OSThread* ownerThread; - - while (TRUE) { - ownerThread = ((OSMutex*)mutex)->thread; - if (ownerThread == 0) { - mutex->thread = currentThread; - mutex->count++; - PushTail(¤tThread->queueMutex, mutex, link); - break; - } else if (ownerThread == currentThread) { - mutex->count++; - break; - } else { - currentThread->mutex = mutex; - __OSPromoteThread(mutex->thread, currentThread->priority); - OSSleepThread(&mutex->queue); - currentThread->mutex = 0; - } - } - OSRestoreInterrupts(enabled); -} - -void OSUnlockMutex(OSMutex* mutex) { - BOOL enabled = OSDisableInterrupts(); - OSThread* currentThread = OSGetCurrentThread(); - - if (mutex->thread == currentThread && --mutex->count == 0) { - PopItem(¤tThread->queueMutex, mutex, link); - mutex->thread = NULL; - if (currentThread->priority < currentThread->base) { - currentThread->priority = __OSGetEffectivePriority(currentThread); - } - - OSWakeupThread(&mutex->queue); - } - OSRestoreInterrupts(enabled); -} - -void __OSUnlockAllMutex(OSThread* thread) { - OSMutex* mutex; - - while (thread->queueMutex.head) { - PopHead(&thread->queueMutex, mutex, link); - mutex->count = 0; - mutex->thread = NULL; - OSWakeupThread(&mutex->queue); - } -} - -BOOL OSTryLockMutex(OSMutex* mutex) { - BOOL enabled = OSDisableInterrupts(); - OSThread* currentThread = OSGetCurrentThread(); - BOOL locked; - if (mutex->thread == 0) { - mutex->thread = currentThread; - mutex->count++; - PushTail(¤tThread->queueMutex, mutex, link); - locked = TRUE; - } else if (mutex->thread == currentThread) { - mutex->count++; - locked = TRUE; - } else { - locked = FALSE; - } - OSRestoreInterrupts(enabled); - return locked; -} - -void OSInitCond(OSCond* cond) { OSInitThreadQueue(&cond->queue); } - -void OSWaitCond(OSCond* cond, OSMutex* mutex) { - BOOL enabled = OSDisableInterrupts(); - OSThread* currentThread = OSGetCurrentThread(); - s32 count; - - if (mutex->thread == currentThread) { - count = mutex->count; - mutex->count = 0; - PopItem(¤tThread->queueMutex, mutex, link); - mutex->thread = NULL; - - if (currentThread->priority < currentThread->base) { - currentThread->priority = __OSGetEffectivePriority(currentThread); + if (__prev == NULL) \ + (queue)->head = __next; \ + else \ + __prev->link.next = __next; \ + } while (0) + +void __OSUnlockAllMutex(OSThread* thread) +{ + OSMutex* mutex; + + while (thread->queueMutex.head) + { + PopHead(&thread->queueMutex, mutex, link); + mutex->count = 0; + mutex->thread = NULL; + OSWakeupThread(&mutex->queue); } - - OSDisableScheduler(); - OSWakeupThread(&mutex->queue); - OSEnableScheduler(); - OSSleepThread(&cond->queue); - OSLockMutex(mutex); - mutex->count = count; - } - - OSRestoreInterrupts(enabled); -} - -void OSSignalCond(OSCond* cond) { OSWakeupThread(&cond->queue); } - -static BOOL IsMember(OSMutexQueue* queue, OSMutex* mutex) { - OSMutex* member; - - for (member = queue->head; member; member = member->link.next) { - if (mutex == member) - return TRUE; - } - return FALSE; -} - -BOOL __OSCheckMutex(OSMutex* mutex) { - OSThread* thread; - OSThreadQueue* queue; - OSPriority 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->priority < priority) - return FALSE; - priority = thread->priority; - } - - if (mutex->thread) { - if (mutex->count <= 0) - return FALSE; - } else { - if (0 != mutex->count) - return FALSE; - } - - return TRUE; -} - -BOOL __OSCheckDeadLock(OSThread* thread) { - OSMutex* mutex; - - mutex = thread->mutex; - while (mutex && mutex->thread) { - if (mutex->thread == thread) - return TRUE; - mutex = mutex->thread->mutex; - } - return FALSE; -} - -BOOL __OSCheckMutexes(OSThread* thread) { - OSMutex* mutex; - - for (mutex = thread->queueMutex.head; mutex; mutex = mutex->link.next) { - if (mutex->thread != thread) - return FALSE; - if (!__OSCheckMutex(mutex)) - return FALSE; - } - return TRUE; } diff --git a/libs/dolphin/os/OSReset.c b/libs/dolphin/os/OSReset.c index 1194de004..8a9a2bd34 100644 --- a/libs/dolphin/os/OSReset.c +++ b/libs/dolphin/os/OSReset.c @@ -4,76 +4,88 @@ #include "dolphin/hw_regs.h" volatile u8 DAT_800030e2 : 0x800030e2; -typedef struct Unk { - u8 pad[0x24]; - u32 resetCode; +typedef struct Unk +{ + u8 pad[0x24]; + u32 resetCode; } Unk; volatile Unk DAT_cc003000 : 0xcc003000; -typedef struct Unk2 { - u16 _0; - u16 _2; +typedef struct Unk2 +{ + u16 _0; + u16 _2; } Unk2; volatile Unk2 DAT_cc002000 : 0xcc002000; -typedef struct OSResetQueue { - OSResetFunctionInfo* first; - OSResetFunctionInfo* last; +typedef struct OSResetQueue +{ + OSResetFunctionInfo* first; + OSResetFunctionInfo* last; } OSResetQueue; static OSResetQueue ResetFunctionQueue; static u32 bootThisDol; -void OSRegisterResetFunction(OSResetFunctionInfo* func) { - OSResetFunctionInfo* tmp; - OSResetFunctionInfo* iter; +void OSRegisterResetFunction(OSResetFunctionInfo* func) +{ + OSResetFunctionInfo* tmp; + OSResetFunctionInfo* iter; - for (iter = ResetFunctionQueue.first; iter && iter->priority <= func->priority; iter = iter->next) - ; + for (iter = ResetFunctionQueue.first; iter && iter->priority <= func->priority; + iter = iter->next) + ; - if (iter == NULL) { - tmp = ResetFunctionQueue.last; - if (tmp == NULL) { - ResetFunctionQueue.first = func; - } else { - tmp->next = func; + 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; } + + func->next = iter; + tmp = iter->prev; + iter->prev = func; func->prev = tmp; - func->next = NULL; - ResetFunctionQueue.last = func; - return; - } - - func->next = iter; - tmp = iter->prev; - iter->prev = func; - func->prev = tmp; - if (tmp == NULL) { - ResetFunctionQueue.first = func; - return; - } - tmp->next = func; + if (tmp == NULL) + { + ResetFunctionQueue.first = func; + return; + } + tmp->next = func; } -BOOL __OSCallResetFunctions(u32 arg0) { - OSResetFunctionInfo *info; - s32 err = 0; - - for (info = ResetFunctionQueue.first; info != NULL && err == 0; info = info->next) - { - err |= !info->func(arg0); - } - err |= !__OSSyncSram() ; - if (err) - { - return 0; - } - return 1; +BOOL __OSCallResetFunctions(u32 arg0) +{ + OSResetFunctionInfo* info; + s32 err = 0; + + for (info = ResetFunctionQueue.first; info != NULL && err == 0; info = info->next) + { + err |= !info->func(arg0); + } + err |= !__OSSyncSram(); + if (err) + { + return 0; + } + return 1; } -asm void Reset(register s32 resetCode) { - // clang-format off +asm void Reset(register s32 resetCode) +{ + // clang-format off nofralloc b lbl_8038315C lbl_80383140: @@ -112,100 +124,106 @@ asm void Reset(register s32 resetCode) { b lbl_803831A0 lbl_803831A8: b lbl_80383140 - // clang-format on + // clang-format on } OSThreadQueue __OSActiveThreadQueue : (OS_BASE_CACHED | 0x00DC); -static void KillThreads(void) { - OSThread* thread; - OSThread* next; - - for (thread = __OSActiveThreadQueue.head; thread; thread = next) { - next = thread->linkActive.next; - switch (thread->state) { - case 1: - case 4: - OSCancelThread(thread); - break; - default: - break; +static void KillThreads(void) +{ + OSThread* thread; + OSThread* next; + + for (thread = __OSActiveThreadQueue.head; thread; thread = next) + { + next = thread->linkActive.next; + switch (thread->state) + { + case 1: + case 4: + OSCancelThread(thread); + break; + default: + break; + } } - } } -void __OSDoHotReset(s32 arg0) { - OSDisableInterrupts(); - __VIRegs[1] = 0; - ICFlashInvalidate(); - Reset(arg0 * 8); +void __OSDoHotReset(s32 arg0) +{ + OSDisableInterrupts(); + __VIRegs[1] = 0; + ICFlashInvalidate(); + Reset(arg0 * 8); } void OSResetSystem(int reset, u32 resetCode, BOOL forceMenu) { - BOOL rc; - BOOL disableRecalibration; - u32 unk[3]; // dumb compiler + BOOL rc; + BOOL disableRecalibration; + u32 unk[3]; // dumb compiler - OSDisableScheduler(); - __OSStopAudioSystem(); + OSDisableScheduler(); + __OSStopAudioSystem(); - if (reset == OS_RESET_SHUTDOWN || (reset == OS_RESET_RESTART && bootThisDol != 0)) - { - disableRecalibration = __PADDisableRecalibration(TRUE); - } + if (reset == OS_RESET_SHUTDOWN || (reset == OS_RESET_RESTART && bootThisDol != 0)) + { + disableRecalibration = __PADDisableRecalibration(TRUE); + } - while (!__OSCallResetFunctions(FALSE)) - { - ; - } + while (!__OSCallResetFunctions(FALSE)) + { + ; + } - if (reset == OS_RESET_HOTRESET && forceMenu) - { - OSSram *sram; + if (reset == OS_RESET_HOTRESET && forceMenu) + { + OSSram* sram; + + sram = __OSLockSram(); + sram->flags |= 0x40; + __OSUnlockSram(TRUE); - sram = __OSLockSram(); - sram->flags |= 0x40; - __OSUnlockSram(TRUE); + while (!__OSSyncSram()) + { + ; + } + } - while (!__OSSyncSram()) + OSDisableInterrupts(); + __OSCallResetFunctions(TRUE); + LCDisable(); + if (reset == OS_RESET_HOTRESET) { - ; + __OSDoHotReset(resetCode); } - } - - OSDisableInterrupts(); - __OSCallResetFunctions(TRUE); - LCDisable(); - if (reset == OS_RESET_HOTRESET) - { - __OSDoHotReset(resetCode); - } - else if (reset == OS_RESET_RESTART) - { - if ((*(u32 *)OSPhysicalToCached(0x30EC) = bootThisDol) != 0) + else if (reset == OS_RESET_RESTART) { - __PADDisableRecalibration(disableRecalibration); + if ((*(u32*)OSPhysicalToCached(0x30EC) = bootThisDol) != 0) + { + __PADDisableRecalibration(disableRecalibration); + } + KillThreads(); + OSEnableScheduler(); + __OSReboot(resetCode, forceMenu); } + KillThreads(); - OSEnableScheduler(); - __OSReboot(resetCode, forceMenu); - } - - KillThreads(); - memset(OSPhysicalToCached(0x40), 0, 0xCC - 0x40); - memset(OSPhysicalToCached(0xD4), 0, 0xE8 - 0xD4); - memset(OSPhysicalToCached(0xF4), 0, 0xF8 - 0xF4); - memset(OSPhysicalToCached(0x3000), 0, 0xC0); - memset(OSPhysicalToCached(0x30C8), 0, 0xD4 - 0xC8); - memset(OSPhysicalToCached(0x30E2), 0, 1); - - __PADDisableRecalibration(disableRecalibration); + memset(OSPhysicalToCached(0x40), 0, 0xCC - 0x40); + memset(OSPhysicalToCached(0xD4), 0, 0xE8 - 0xD4); + memset(OSPhysicalToCached(0xF4), 0, 0xF8 - 0xF4); + memset(OSPhysicalToCached(0x3000), 0, 0xC0); + memset(OSPhysicalToCached(0x30C8), 0, 0xD4 - 0xC8); + memset(OSPhysicalToCached(0x30E2), 0, 1); + + __PADDisableRecalibration(disableRecalibration); } -u32 OSGetResetCode(void) { - if (DAT_800030e2 != 0) { - return 0x80000000; - } - return ((DAT_cc003000.resetCode & ~7) >> 3); +u32 OSGetResetCode(void) +{ + if (DAT_800030e2 != 0) + { + return 0x80000000; + } + return ((DAT_cc003000.resetCode & ~7) >> 3); } diff --git a/libs/dolphin/os/OSResetSW.c b/libs/dolphin/os/OSResetSW.c index 24766fd35..62897d2b8 100644 --- a/libs/dolphin/os/OSResetSW.c +++ b/libs/dolphin/os/OSResetSW.c @@ -14,7 +14,7 @@ static BOOL LastState; static OSTime HoldUp; static OSTime HoldDown; -void __OSResetSWInterruptHandler(__OSInterrupt interrupt, OSContext *context) +void __OSResetSWInterruptHandler(__OSInterrupt interrupt, OSContext* context) { OSResetCallback callback; @@ -88,9 +88,9 @@ BOOL OSGetResetButtonState(void) LastState = state; - if (GameChoice & 0x1f) + if (GameChoice & 0x3f) { - OSTime fire = (GameChoice & 0x1f) * 60; + OSTime fire = (GameChoice & 0x3f) * 60; fire = __OSStartTime + OSSecondsToTicks(fire); if (fire < now) { @@ -109,10 +109,4 @@ BOOL OSGetResetButtonState(void) OSRestoreInterrupts(enabled); return state; -} - -#pragma dont_inline on - -BOOL OSGetResetSwitchState(void) { return OSGetResetButtonState(); } - -#pragma dont_inline reset +} \ No newline at end of file diff --git a/libs/dolphin/os/OSRtc.c b/libs/dolphin/os/OSRtc.c index b76bcdc21..eab1d5301 100644 --- a/libs/dolphin/os/OSRtc.c +++ b/libs/dolphin/os/OSRtc.c @@ -11,389 +11,369 @@ #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); +typedef struct SramControlBlock +{ + u8 sram[RTC_SRAM_SIZE]; + u32 offset; + BOOL enabled; + BOOL locked; + BOOL sync; + void (*callback)(void); } SramControlBlock; static SramControlBlock Scb ALIGN(32); -static BOOL GetRTC(u32* rtc) { - BOOL err; - u32 cmd; - - if (!EXILock(RTC_CHAN, RTC_DEV, 0)) { - return FALSE; - } - if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { - EXIUnlock(RTC_CHAN); - return FALSE; - } - - cmd = RTC_CMD_READ; - err = FALSE; - err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL); - err |= !EXISync(RTC_CHAN); - err |= !EXIImm(RTC_CHAN, &cmd, 4, 0, NULL); - err |= !EXISync(RTC_CHAN); - err |= !EXIDeselect(RTC_CHAN); - EXIUnlock(RTC_CHAN); - - *rtc = cmd; - - return !err; -} +static BOOL ReadSram(void* buffer) +{ + BOOL err; + u32 cmd; -BOOL __OSGetRTC(u32* rtc) { - BOOL err; - u32 t0; - u32 t1; - int i; + DCInvalidateRange(buffer, RTC_SRAM_SIZE); - for (i = 0; i < 16; i++) { - err = FALSE; - err |= !GetRTC(&t0); - err |= !GetRTC(&t1); - if (err) { - break; + if (!EXILock(RTC_CHAN, RTC_DEV, 0)) + { + return FALSE; } - if (t0 == t1) { - *rtc = t0; - return TRUE; + if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) + { + EXIUnlock(RTC_CHAN); + return FALSE; } - } - return FALSE; -} -BOOL __OSSetRTC(u32 rtc) { - BOOL err; - u32 cmd; - - if (!EXILock(RTC_CHAN, RTC_DEV, 0)) { - return FALSE; - } - if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { + 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); - return FALSE; - } - - cmd = RTC_CMD_WRITE; - err = FALSE; - err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL); - err |= !EXISync(RTC_CHAN); - err |= !EXIImm(RTC_CHAN, &rtc, 4, 1, NULL); - err |= !EXISync(RTC_CHAN); - err |= !EXIDeselect(RTC_CHAN); - EXIUnlock(RTC_CHAN); - - return !err; -} -static BOOL ReadSram(void* buffer) { - BOOL err; - u32 cmd; - - DCInvalidateRange(buffer, RTC_SRAM_SIZE); - - if (!EXILock(RTC_CHAN, RTC_DEV, 0)) { - return FALSE; - } - if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { - EXIUnlock(RTC_CHAN); - return FALSE; - } - - 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); - - return !err; + return !err; } BOOL WriteSram(void* buffer, u32 offset, u32 size); -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; - } +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; + } } -BOOL WriteSram(void* buffer, u32 offset, u32 size) { - BOOL err; - u32 cmd; +BOOL WriteSram(void* buffer, u32 offset, u32 size) +{ + BOOL err; + u32 cmd; + + if (!EXILock(RTC_CHAN, RTC_DEV, WriteSramCallback)) + { + return FALSE; + } + if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) + { + EXIUnlock(RTC_CHAN); + return FALSE; + } - if (!EXILock(RTC_CHAN, RTC_DEV, WriteSramCallback)) { - return FALSE; - } - if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { + 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); - return FALSE; - } - - 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); - - return !err; + + return !err; } -void __OSInitSram() { - Scb.locked = Scb.enabled = FALSE; - Scb.sync = ReadSram(Scb.sram); - Scb.offset = RTC_SRAM_SIZE; +void __OSInitSram() +{ + Scb.locked = Scb.enabled = FALSE; + Scb.sync = ReadSram(Scb.sram); + Scb.offset = RTC_SRAM_SIZE; - OSSetGbsMode(OSGetGbsMode()); + OSSetGbsMode(OSGetGbsMode()); } -static void* LockSram(u32 offset) { - BOOL enabled; - enabled = OSDisableInterrupts(); +static void* LockSram(u32 offset) +{ + BOOL enabled; + enabled = OSDisableInterrupts(); - if (Scb.locked != FALSE) { - OSRestoreInterrupts(enabled); - return NULL; - } + if (Scb.locked != FALSE) + { + OSRestoreInterrupts(enabled); + return NULL; + } - Scb.enabled = enabled; - Scb.locked = TRUE; + Scb.enabled = enabled; + Scb.locked = TRUE; - return Scb.sram + offset; + return Scb.sram + offset; } -OSSram* __OSLockSram() { return LockSram(0); } - -OSSramEx* __OSLockSramEx() { return LockSram(sizeof(OSSram)); } - -static BOOL UnlockSram(BOOL commit, u32 offset) { - u16* p; - - if (commit) { - if (offset == 0) { - OSSram* sram = (OSSram*)Scb.sram; +OSSram* __OSLockSram() +{ + return LockSram(0); +} - if (2u < (sram->flags & 3)) { - sram->flags &= ~3; - } +OSSramEx* __OSLockSramEx() +{ + return LockSram(sizeof(OSSram)); +} - sram->checkSum = sram->checkSumInv = 0; - for (p = (u16*)&sram->counterBias; p < (u16*)(Scb.sram + sizeof(OSSram)); p++) { - sram->checkSum += *p; - sram->checkSumInv += ~*p; - } - } +static BOOL UnlockSram(BOOL commit, u32 offset) +{ + u16* p; - if (offset < Scb.offset) { - Scb.offset = offset; - } - // this isn't in prime? - if (Scb.offset <= 20) + if (commit) { - // this seems to work? esp. since we have GbsMode functions when prime doesn't - // wacky tho - OSSramEx *sramEx = (OSSramEx *)(&Scb.sram[20]); - if ((u32)(sramEx->gbs & 0x7C00) == 0x5000 || (u32)(sramEx->gbs & 0xC0) == 0xC0) - { - sramEx->gbs = 0; - } + if (offset == 0) + { + 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++) + { + sram->checkSum += *p; + sram->checkSumInv += ~*p; + } + } + + if (offset < Scb.offset) + { + Scb.offset = offset; + } + // this isn't in prime? + if (Scb.offset <= 20) + { + // this seems to work? esp. since we have GbsMode functions when prime doesn't + // wacky tho + OSSramEx* sramEx = (OSSramEx*)(&Scb.sram[20]); + if ((u32)(sramEx->gbs & 0x7C00) == 0x5000 || (u32)(sramEx->gbs & 0xC0) == 0xC0) + { + sramEx->gbs = 0; + } + } + + Scb.sync = WriteSram(Scb.sram + Scb.offset, Scb.offset, RTC_SRAM_SIZE - Scb.offset); + if (Scb.sync) + { + Scb.offset = RTC_SRAM_SIZE; + } } + Scb.locked = FALSE; + OSRestoreInterrupts(Scb.enabled); + return Scb.sync; +} - Scb.sync = WriteSram(Scb.sram + Scb.offset, Scb.offset, RTC_SRAM_SIZE - Scb.offset); - if (Scb.sync) { - Scb.offset = RTC_SRAM_SIZE; - } - } - Scb.locked = FALSE; - OSRestoreInterrupts(Scb.enabled); - return Scb.sync; +BOOL __OSUnlockSram(BOOL commit) +{ + return UnlockSram(commit, 0); } -BOOL __OSUnlockSram(BOOL commit) { return UnlockSram(commit, 0); } +BOOL __OSUnlockSramEx(BOOL commit) +{ + return UnlockSram(commit, sizeof(OSSram)); +} -BOOL __OSUnlockSramEx(BOOL commit) { return UnlockSram(commit, sizeof(OSSram)); } +BOOL __OSSyncSram() +{ + return Scb.sync; +} -BOOL __OSSyncSram() { return Scb.sync; } +BOOL __OSReadROM(void* buffer, s32 length, s32 offset) +{ + BOOL err; + u32 cmd; -BOOL __OSReadROM(void* buffer, s32 length, s32 offset) { - BOOL err; - u32 cmd; + DCInvalidateRange(buffer, (u32)length); - DCInvalidateRange(buffer, (u32)length); + if (!EXILock(RTC_CHAN, RTC_DEV, 0)) + { + return FALSE; + } + if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) + { + EXIUnlock(RTC_CHAN); + return FALSE; + } - if (!EXILock(RTC_CHAN, RTC_DEV, 0)) { - return FALSE; - } - if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { + cmd = (u32)(offset << 6); + err = FALSE; + err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL); + err |= !EXISync(RTC_CHAN); + err |= !EXIDma(RTC_CHAN, buffer, length, 0, NULL); + err |= !EXISync(RTC_CHAN); + err |= !EXIDeselect(RTC_CHAN); EXIUnlock(RTC_CHAN); - return FALSE; - } - - cmd = (u32)(offset << 6); - err = FALSE; - err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL); - err |= !EXISync(RTC_CHAN); - err |= !EXIDma(RTC_CHAN, buffer, length, 0, NULL); - err |= !EXISync(RTC_CHAN); - err |= !EXIDeselect(RTC_CHAN); - EXIUnlock(RTC_CHAN); - - return !err; + + return !err; } -inline OSSram* __OSLockSramHACK() { return LockSram(0); } -u32 OSGetSoundMode() { - OSSram* sram; - u32 mode; +inline OSSram* __OSLockSramHACK() +{ + return LockSram(0); +} +u32 OSGetSoundMode() +{ + OSSram* sram; + u32 mode; - sram = __OSLockSramHACK(); - mode = (sram->flags & 0x4) ? OS_SOUND_MODE_STEREO : OS_SOUND_MODE_MONO; - __OSUnlockSram(FALSE); - return mode; + sram = __OSLockSramHACK(); + mode = (sram->flags & 0x4) ? OS_SOUND_MODE_STEREO : OS_SOUND_MODE_MONO; + __OSUnlockSram(FALSE); + return mode; } -void OSSetSoundMode(u32 mode) { - OSSram* sram; - mode <<= 2; - mode &= 4; +void OSSetSoundMode(u32 mode) +{ + OSSram* sram; + mode <<= 2; + mode &= 4; - sram = __OSLockSramHACK(); - if (mode == (sram->flags & 4)) { - __OSUnlockSram(FALSE); - return; - } + sram = __OSLockSramHACK(); + if (mode == (sram->flags & 4)) + { + __OSUnlockSram(FALSE); + return; + } - sram->flags &= ~4; - sram->flags |= mode; - __OSUnlockSram(TRUE); + sram->flags &= ~4; + sram->flags |= mode; + __OSUnlockSram(TRUE); } -u32 OSGetProgressiveMode() { - OSSram* sram; - u32 mode; +u32 OSGetProgressiveMode() +{ + OSSram* sram; + u32 mode; - sram = __OSLockSramHACK(); - mode = (sram->flags & 0x80) >> 7; - __OSUnlockSram(FALSE); - return mode; + sram = __OSLockSramHACK(); + mode = (sram->flags & 0x80) >> 7; + __OSUnlockSram(FALSE); + return mode; } -void OSSetProgressiveMode(u32 mode) { - OSSram* sram; - mode <<= 7; - mode &= 0x80; +void OSSetProgressiveMode(u32 mode) +{ + OSSram* sram; + mode <<= 7; + mode &= 0x80; - sram = __OSLockSramHACK(); - if (mode == (sram->flags & 0x80)) { - __OSUnlockSram(FALSE); - return; - } + sram = __OSLockSramHACK(); + if (mode == (sram->flags & 0x80)) + { + __OSUnlockSram(FALSE); + return; + } - sram->flags &= ~0x80; - sram->flags |= mode; - __OSUnlockSram(TRUE); + sram->flags &= ~0x80; + sram->flags |= mode; + __OSUnlockSram(TRUE); } -u8 OSGetLanguage() { - OSSram* sram; - u8 language; +u8 OSGetLanguage() +{ + OSSram* sram; + u8 language; - sram = __OSLockSramHACK(); - language = sram->language; - __OSUnlockSram(FALSE); - return language; + sram = __OSLockSramHACK(); + language = sram->language; + __OSUnlockSram(FALSE); + return language; } -u32 OSGetEuRgb60Mode() { - OSSram *sram; - u32 on; - sram = __OSLockSramHACK(); - on = (sram->ntd >> 6) & 0x1; - __OSUnlockSram(FALSE); - return on; +u32 OSGetEuRgb60Mode() +{ + OSSram* sram; + u32 on; + sram = __OSLockSramHACK(); + on = (sram->ntd >> 6) & 0x1; + __OSUnlockSram(FALSE); + return on; } void OSSetEuRgb60Mode(u32 mode) { - OSSram *sram; - mode <<= 6; - mode &= 0x40; + OSSram* sram; + mode <<= 6; + mode &= 0x40; - sram = __OSLockSramHACK(); - if (mode == (sram->ntd & 0x40)) - { - __OSUnlockSram(FALSE); - return; - } + sram = __OSLockSramHACK(); + if (mode == (sram->ntd & 0x40)) + { + __OSUnlockSram(FALSE); + return; + } - sram->ntd &= ~0x40; - sram->ntd |= mode; - __OSUnlockSram(TRUE); + sram->ntd &= ~0x40; + sram->ntd |= mode; + __OSUnlockSram(TRUE); } -u16 OSGetWirelessID(s32 channel) { - OSSramEx* sram; - u16 id; +u16 OSGetWirelessID(s32 channel) +{ + OSSramEx* sram; + u16 id; - sram = __OSLockSramEx(); - id = sram->wirelessPadID[channel]; - __OSUnlockSramEx(FALSE); - return id; + sram = __OSLockSramEx(); + id = sram->wirelessPadID[channel]; + __OSUnlockSramEx(FALSE); + return id; } -void OSSetWirelessID(s32 channel, u16 id) { - OSSramEx* sram; +void OSSetWirelessID(s32 channel, u16 id) +{ + OSSramEx* sram; - sram = __OSLockSramEx(); - if (sram->wirelessPadID[channel] != id) { - sram->wirelessPadID[channel] = id; - __OSUnlockSramEx(TRUE); - return; - } + sram = __OSLockSramEx(); + if (sram->wirelessPadID[channel] != id) + { + sram->wirelessPadID[channel] = id; + __OSUnlockSramEx(TRUE); + return; + } - __OSUnlockSramEx(FALSE); + __OSUnlockSramEx(FALSE); } u16 OSGetGbsMode() { - OSSramEx *sram; - u16 id; + OSSramEx* sram; + u16 id; - sram = __OSLockSramEx(); - id = sram->gbs; - __OSUnlockSramEx(FALSE); - return id; + sram = __OSLockSramEx(); + id = sram->gbs; + __OSUnlockSramEx(FALSE); + return id; } void OSSetGbsMode(u16 mode) { - OSSramEx *sram; + OSSramEx* sram; - // same odd code as in UnlockSram? - if ((u32)(mode & 0x7C00) == 0x5000 || (u32)(mode & 0xC0) == 0xC0) - { - mode = 0; - } + // same odd code as in UnlockSram? + if ((u32)(mode & 0x7C00) == 0x5000 || (u32)(mode & 0xC0) == 0xC0) + { + mode = 0; + } - sram = __OSLockSramEx(); - if (mode == sram->gbs) - { - __OSUnlockSramEx(FALSE); - return; - } + sram = __OSLockSramEx(); + if (mode == sram->gbs) + { + __OSUnlockSramEx(FALSE); + return; + } - sram->gbs = mode; - __OSUnlockSramEx(TRUE); + sram->gbs = mode; + __OSUnlockSramEx(TRUE); } \ No newline at end of file diff --git a/libs/dolphin/os/OSThread.c b/libs/dolphin/os/OSThread.c index 016bfd3bd..e0a46b506 100644 --- a/libs/dolphin/os/OSThread.c +++ b/libs/dolphin/os/OSThread.c @@ -16,575 +16,509 @@ OSThreadQueue __OSActiveThreadQueue : OS_BASE_CACHED + 0x00DC; volatile OSContext __OSCurrentContext : OS_BASE_CACHED + 0x00D4; volatile OSContext* __OSFPUContext : OS_BASE_CACHED + 0x00D8; -static void DefaultSwitchThreadCallback(OSThread* from, OSThread* to) {} +static void DefaultSwitchThreadCallback(OSThread* from, OSThread* to) +{ +} extern u8 _stack_addr[]; extern u8 _stack_end[]; #define AddTail(queue, thread, link) \ - do { \ - OSThread* prev; \ + 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) + 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 AddPrio(queue, thread, link) \ - do { \ - OSThread *prev, *next; \ + do \ + { \ + OSThread *prev, *next; \ \ - for (next = (queue)->head; next && next->priority <= thread->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) + for (next = (queue)->head; next && next->priority <= thread->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 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) + 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 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) - -static inline void OSInitMutexQueue(OSMutexQueue* queue) { queue->head = queue->tail = NULL; } - -static inline void OSSetCurrentThread(OSThread* thread) { - SwitchThreadCallback(__OSCurrentThread, thread); - __OSCurrentThread = thread; + 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) + +static inline void OSInitMutexQueue(OSMutexQueue* queue) +{ + queue->head = queue->tail = NULL; } -void __OSThreadInit() { - OSThread* thread = &DefaultThread; - int prio; - - thread->state = OS_THREAD_STATE_RUNNING; - thread->attr = OS_THREAD_ATTR_DETACH; - thread->priority = thread->base = 16; - thread->suspend = 0; - thread->val = (void*)-1; - thread->mutex = NULL; - OSInitThreadQueue(&thread->queueJoin); - OSInitMutexQueue(&thread->queueMutex); - - __OSFPUContext = &thread->context; - - OSClearContext(&thread->context); - OSSetCurrentContext(&thread->context); - thread->stackBase = (void*)_stack_addr; - thread->stackEnd = (void*)_stack_end; - *(thread->stackEnd) = OS_THREAD_STACK_MAGIC; - - OSSetCurrentThread(thread); - OSClearStack(0); - - RunQueueBits = 0; - RunQueueHint = FALSE; - for (prio = OS_PRIORITY_MIN; prio <= OS_PRIORITY_MAX; ++prio) { - OSInitThreadQueue(&RunQueue[prio]); - } - - OSInitThreadQueue(&__OSActiveThreadQueue); - AddTail(&__OSActiveThreadQueue, thread, linkActive); - OSClearContext(&IdleContext); - Reschedule = 0; +static inline void OSSetCurrentThread(OSThread* thread) +{ + SwitchThreadCallback(__OSCurrentThread, thread); + __OSCurrentThread = thread; } -void OSInitThreadQueue(OSThreadQueue* queue) { queue->head = queue->tail = NULL; } +void __OSThreadInit() +{ + OSThread* thread = &DefaultThread; + int prio; + + thread->state = OS_THREAD_STATE_RUNNING; + thread->attr = OS_THREAD_ATTR_DETACH; + thread->priority = thread->base = 16; + thread->suspend = 0; + thread->val = (void*)-1; + thread->mutex = NULL; + OSInitThreadQueue(&thread->queueJoin); + OSInitMutexQueue(&thread->queueMutex); + + __OSFPUContext = &thread->context; + + OSClearContext(&thread->context); + OSSetCurrentContext(&thread->context); + thread->stackBase = (void*)_stack_addr; + thread->stackEnd = (void*)_stack_end; + *(thread->stackEnd) = OS_THREAD_STACK_MAGIC; + + OSSetCurrentThread(thread); + OSClearStack(0); + + RunQueueBits = 0; + RunQueueHint = FALSE; + for (prio = OS_PRIORITY_MIN; prio <= OS_PRIORITY_MAX; ++prio) + { + OSInitThreadQueue(&RunQueue[prio]); + } + + OSInitThreadQueue(&__OSActiveThreadQueue); + AddTail(&__OSActiveThreadQueue, thread, linkActive); + OSClearContext(&IdleContext); + Reschedule = 0; +} -OSThread* OSGetCurrentThread() { return __OSCurrentThread; } +void OSInitThreadQueue(OSThreadQueue* queue) +{ + queue->head = queue->tail = NULL; +} -static void __OSSwitchThread(OSThread *nextThread) +OSThread* OSGetCurrentThread() { - OSSetCurrentThread(nextThread); - OSSetCurrentContext(&nextThread->context); - OSLoadContext(&nextThread->context); + return __OSCurrentThread; } -BOOL OSIsThreadTerminated(OSThread *thread) +static void __OSSwitchThread(OSThread* nextThread) { - return (thread->state == OS_THREAD_STATE_MORIBUND || thread->state == OS_THREAD_STATE_NULL) ? TRUE : FALSE; + OSSetCurrentThread(nextThread); + OSSetCurrentContext(&nextThread->context); + OSLoadContext(&nextThread->context); } -s32 OSDisableScheduler() { - BOOL enabled; - s32 count; +s32 OSDisableScheduler() +{ + BOOL enabled; + s32 count; - enabled = OSDisableInterrupts(); - count = Reschedule++; - OSRestoreInterrupts(enabled); - return count; + enabled = OSDisableInterrupts(); + count = Reschedule++; + OSRestoreInterrupts(enabled); + return count; } -s32 OSEnableScheduler() { - BOOL enabled; - s32 count; +s32 OSEnableScheduler() +{ + BOOL enabled; + s32 count; - enabled = OSDisableInterrupts(); - count = Reschedule--; - OSRestoreInterrupts(enabled); - return count; + enabled = OSDisableInterrupts(); + count = Reschedule--; + OSRestoreInterrupts(enabled); + return count; } -static void SetRun(OSThread* thread) { - thread->queue = &RunQueue[thread->priority]; - AddTail(thread->queue, thread, link); - RunQueueBits |= 1u << (OS_PRIORITY_MAX - thread->priority); - RunQueueHint = TRUE; +static void SetRun(OSThread* thread) +{ + thread->queue = &RunQueue[thread->priority]; + AddTail(thread->queue, thread, link); + RunQueueBits |= 1u << (OS_PRIORITY_MAX - thread->priority); + RunQueueHint = TRUE; } #pragma dont_inline on -static void UnsetRun(OSThread* thread) { - OSThreadQueue* queue; - queue = thread->queue; - RemoveItem(queue, thread, link); - if (queue->head == 0) - RunQueueBits &= ~(1u << (OS_PRIORITY_MAX - thread->priority)); - thread->queue = NULL; +static void UnsetRun(OSThread* thread) +{ + OSThreadQueue* queue; + queue = thread->queue; + RemoveItem(queue, thread, link); + if (queue->head == 0) + RunQueueBits &= ~(1u << (OS_PRIORITY_MAX - thread->priority)); + thread->queue = NULL; } #pragma dont_inline reset -OSPriority __OSGetEffectivePriority(OSThread* thread) { - OSPriority priority; - OSMutex* mutex; - OSThread* blocked; +OSPriority __OSGetEffectivePriority(OSThread* thread) +{ + OSPriority priority; + OSMutex* mutex; + OSThread* blocked; - priority = thread->base; - for (mutex = thread->queueMutex.head; mutex; mutex = mutex->link.next) { - blocked = mutex->queue.head; - if (blocked && blocked->priority < priority) { - priority = blocked->priority; + priority = thread->base; + for (mutex = thread->queueMutex.head; mutex; mutex = mutex->link.next) + { + blocked = mutex->queue.head; + if (blocked && blocked->priority < priority) + { + priority = blocked->priority; + } } - } - return priority; + return priority; } -static OSThread* SetEffectivePriority(OSThread* thread, OSPriority priority) { - switch (thread->state) { - case OS_THREAD_STATE_READY: - UnsetRun(thread); - thread->priority = priority; - SetRun(thread); - break; - case OS_THREAD_STATE_WAITING: - RemoveItem(thread->queue, thread, link); - thread->priority = priority; - AddPrio(thread->queue, thread, link); - if (thread->mutex) { - return thread->mutex->thread; +static OSThread* SetEffectivePriority(OSThread* thread, OSPriority priority) +{ + switch (thread->state) + { + case OS_THREAD_STATE_READY: + UnsetRun(thread); + thread->priority = priority; + SetRun(thread); + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->priority = priority; + AddPrio(thread->queue, thread, link); + if (thread->mutex) + { + return thread->mutex->thread; + } + break; + case OS_THREAD_STATE_RUNNING: + RunQueueHint = TRUE; + thread->priority = priority; + break; } - break; - case OS_THREAD_STATE_RUNNING: - RunQueueHint = TRUE; - thread->priority = priority; - break; - } - return NULL; + return NULL; } -static void UpdatePriority(OSThread* thread) { - OSPriority priority; +static void UpdatePriority(OSThread* thread) +{ + OSPriority priority; - do { - if (0 < thread->suspend) { - break; - } - priority = __OSGetEffectivePriority(thread); - if (thread->priority == priority) { - break; - } - thread = SetEffectivePriority(thread, priority); - } while (thread); + do + { + if (0 < thread->suspend) + { + break; + } + priority = __OSGetEffectivePriority(thread); + if (thread->priority == priority) + { + break; + } + thread = SetEffectivePriority(thread, priority); + } while (thread); } -void __OSPromoteThread(OSThread *thread, OSPriority priority) +static OSThread* SelectThread(BOOL yield) { - do - { - if (thread->suspend > 0) + OSContext* currentContext; + OSThread* currentThread; + OSThread* nextThread; + OSPriority priority; + OSThreadQueue* queue; + + if (0 < Reschedule) { - break; + return 0; } - if (thread->priority <= priority) + + currentContext = OSGetCurrentContext(); + currentThread = OSGetCurrentThread(); + if (currentContext != ¤tThread->context) { - break; + return 0; } - thread = SetEffectivePriority(thread, priority); - } while (thread); -} - -static OSThread *SelectThread(BOOL yield) -{ - OSContext *currentContext; - OSThread *currentThread; - OSThread *nextThread; - OSPriority priority; - OSThreadQueue *queue; - - if (0 < Reschedule) - { - return 0; - } - - currentContext = OSGetCurrentContext(); - currentThread = OSGetCurrentThread(); - if (currentContext != ¤tThread->context) - { - return 0; - } - - if (currentThread) - { - if (currentThread->state == OS_THREAD_STATE_RUNNING) + if (currentThread) { - if (!yield) - { - priority = __cntlzw(RunQueueBits); - if (currentThread->priority <= priority) + if (currentThread->state == OS_THREAD_STATE_RUNNING) { - return 0; + if (!yield) + { + priority = __cntlzw(RunQueueBits); + if (currentThread->priority <= priority) + { + return 0; + } + } + currentThread->state = OS_THREAD_STATE_READY; + SetRun(currentThread); } - } - 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 & OS_CONTEXT_STATE_EXC) && + OSSaveContext(¤tThread->context)) + { + return 0; + } } - } - if (RunQueueBits == 0) - { - SwitchThreadCallback(__OSCurrentThread, nullptr); - __OSCurrentThread = nullptr; - OSSetCurrentContext(&IdleContext); - do + if (RunQueueBits == 0) { - OSEnableInterrupts(); - while (RunQueueBits == 0) - ; - OSDisableInterrupts(); - } while (RunQueueBits == 0); - - OSClearContext(&IdleContext); - } - - RunQueueHint = FALSE; - - priority = __cntlzw(RunQueueBits); - queue = &RunQueue[priority]; - RemoveHead(queue, nextThread, link); - if (queue->head == 0) - { - RunQueueBits &= ~(1u << (OS_PRIORITY_MAX - priority)); - } - nextThread->queue = NULL; - nextThread->state = OS_THREAD_STATE_RUNNING; - __OSSwitchThread(nextThread); - return nextThread; -} - -void __OSReschedule() { - if (!RunQueueHint) { - return; - } + SwitchThreadCallback(__OSCurrentThread, nullptr); + __OSCurrentThread = nullptr; + OSSetCurrentContext(&IdleContext); + do + { + OSEnableInterrupts(); + while (RunQueueBits == 0) + ; + OSDisableInterrupts(); + } while (RunQueueBits == 0); - SelectThread(FALSE); -} + OSClearContext(&IdleContext); + } -void OSYieldThread(void) { - BOOL enabled; + RunQueueHint = FALSE; - enabled = OSDisableInterrupts(); - SelectThread(TRUE); - OSRestoreInterrupts(enabled); + priority = __cntlzw(RunQueueBits); + queue = &RunQueue[priority]; + RemoveHead(queue, nextThread, link); + if (queue->head == 0) + { + RunQueueBits &= ~(1u << (OS_PRIORITY_MAX - priority)); + } + nextThread->queue = NULL; + nextThread->state = OS_THREAD_STATE_RUNNING; + __OSSwitchThread(nextThread); + return nextThread; } -BOOL OSCreateThread(OSThread *thread, OSThreadStartFunction func, void *param, void *stack, u32 stackSize, OSPriority priority, u16 attr) +void __OSReschedule() { - BOOL enable; - u32 stackThing; - int i; - u32 tmp[2]; // DUMB compiler smfh. - - if (priority < OS_PRIORITY_MIN || priority > OS_PRIORITY_MAX) - { - return FALSE; - } - - stackThing = ((u32)stack & 0xFFFFFFF8); // ?? - thread->state = OS_THREAD_STATE_READY; - thread->attr = attr & OS_THREAD_ATTR_DETACH; - thread->base = priority; - thread->priority = priority; - thread->suspend = 1; - thread->val = (void *)-1; - thread->mutex = nullptr; - OSInitThreadQueue(&thread->queueJoin); - OSInitMutexQueue(&thread->queueMutex); - *(u32 *)(stackThing - 8) = 0; - *(u32 *)(stackThing - 4) = 0; - - OSInitContext(&thread->context, (u32)func, (u32)(stackThing - 8)); - - thread->context.lr = (u32)&OSExitThread; - thread->context.gpr[3] = (u32)param; - thread->stackBase = stack; - thread->stackEnd = (u32 *)((u32)stack - stackSize); - *(thread->stackEnd) = OS_THREAD_STACK_MAGIC; - thread->error = 0; - thread->specific[0] = nullptr; - thread->specific[1] = nullptr; - - enable = OSDisableInterrupts(); - - if (__OSErrorTable[OS_ERROR_FPE] != nullptr) - { - thread->context.srr1 |= 0x900; // ?? - thread->context.state |= OS_CONTEXT_STATE_FPSAVED; - thread->context.fpscr = (__OSFpscrEnableBits & 0xF8) | 0x4; // ?? - - for (i = 0; i < 32; i++) + if (!RunQueueHint) { - *(u64 *)&thread->context.fpr[i] = -1; // ??????? - *(u64 *)&thread->context.psf[i] = -1; // ??????? + return; } - } - AddTail(&__OSActiveThreadQueue, thread, linkActive); - OSRestoreInterrupts(enable); - return TRUE; + SelectThread(FALSE); } -void OSExitThread(void *val) +void OSYieldThread(void) { - OSThread *thread; - BOOL enable; - - enable = OSDisableInterrupts(); - thread = __OSCurrentThread; - OSClearContext(&thread->context); - - if (thread->attr & OS_THREAD_ATTR_DETACH) - { - RemoveItem(&__OSActiveThreadQueue, thread, linkActive); - thread->state = OS_THREAD_STATE_NULL; - } - else - { - thread->state = OS_THREAD_STATE_MORIBUND; - thread->val = val; - } - - __OSUnlockAllMutex(thread); - OSWakeupThread(&thread->queueJoin); - RunQueueHint = TRUE; - if (RunQueueHint != FALSE) - { - SelectThread(FALSE); - } + BOOL enabled; - OSRestoreInterrupts(enable); + enabled = OSDisableInterrupts(); + SelectThread(TRUE); + OSRestoreInterrupts(enabled); } -void OSCancelThread(OSThread* thread) { - BOOL enabled; +void OSCancelThread(OSThread* thread) +{ + BOOL enabled; - enabled = OSDisableInterrupts(); + enabled = OSDisableInterrupts(); - switch (thread->state) { - case OS_THREAD_STATE_READY: - if (!(0 < thread->suspend)) { - UnsetRun(thread); - } - break; - case OS_THREAD_STATE_RUNNING: - RunQueueHint = TRUE; - break; - case OS_THREAD_STATE_WAITING: - RemoveItem(thread->queue, thread, link); - thread->queue = NULL; - if (!(0 < thread->suspend) && thread->mutex) { - UpdatePriority(thread->mutex->thread); + switch (thread->state) + { + case OS_THREAD_STATE_READY: + if (!(0 < thread->suspend)) + { + UnsetRun(thread); + } + break; + case OS_THREAD_STATE_RUNNING: + RunQueueHint = TRUE; + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->queue = NULL; + if (!(0 < thread->suspend) && thread->mutex) + { + UpdatePriority(thread->mutex->thread); + } + break; + default: + OSRestoreInterrupts(enabled); + return; } - break; - default: - OSRestoreInterrupts(enabled); - return; - } - OSClearContext(&thread->context); - if (thread->attr & OS_THREAD_ATTR_DETACH) { - RemoveItem(&__OSActiveThreadQueue, thread, linkActive); - thread->state = 0; - } else { - thread->state = OS_THREAD_STATE_MORIBUND; - } + OSClearContext(&thread->context); + if (thread->attr & OS_THREAD_ATTR_DETACH) + { + RemoveItem(&__OSActiveThreadQueue, thread, linkActive); + thread->state = 0; + } + else + { + thread->state = OS_THREAD_STATE_MORIBUND; + } - __OSUnlockAllMutex(thread); + __OSUnlockAllMutex(thread); - OSWakeupThread(&thread->queueJoin); + OSWakeupThread(&thread->queueJoin); - __OSReschedule(); - OSRestoreInterrupts(enabled); + __OSReschedule(); + OSRestoreInterrupts(enabled); - return; + return; } -void OSDetachThread(OSThread *thread) +s32 OSResumeThread(OSThread* thread) { - BOOL enable; - - enable = OSDisableInterrupts(); - thread->attr |= OS_THREAD_ATTR_DETACH; - if (thread->state == OS_THREAD_STATE_MORIBUND) - { - RemoveItem(&__OSActiveThreadQueue, thread, linkActive); - thread->state = OS_THREAD_STATE_NULL; - } - - OSWakeupThread(&thread->queueJoin); - OSRestoreInterrupts(enable); -} + BOOL enabled; + s32 suspendCount; -s32 OSResumeThread(OSThread* thread) { - BOOL enabled; - s32 suspendCount; - - enabled = OSDisableInterrupts(); - suspendCount = thread->suspend--; - if (thread->suspend < 0) { - thread->suspend = 0; - } else if (thread->suspend == 0) { - switch (thread->state) { - case OS_THREAD_STATE_READY: - thread->priority = __OSGetEffectivePriority(thread); - SetRun(thread); - break; - case OS_THREAD_STATE_WAITING: - RemoveItem(thread->queue, thread, link); - thread->priority = __OSGetEffectivePriority(thread); - AddPrio(thread->queue, thread, link); - if (thread->mutex) { - UpdatePriority(thread->mutex->thread); - } - break; + enabled = OSDisableInterrupts(); + suspendCount = thread->suspend--; + if (thread->suspend < 0) + { + thread->suspend = 0; } - __OSReschedule(); - } - OSRestoreInterrupts(enabled); - return suspendCount; + else if (thread->suspend == 0) + { + switch (thread->state) + { + case OS_THREAD_STATE_READY: + thread->priority = __OSGetEffectivePriority(thread); + SetRun(thread); + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->priority = __OSGetEffectivePriority(thread); + AddPrio(thread->queue, thread, link); + if (thread->mutex) + { + UpdatePriority(thread->mutex->thread); + } + break; + } + __OSReschedule(); + } + OSRestoreInterrupts(enabled); + return suspendCount; } -s32 OSSuspendThread(OSThread* thread) { - BOOL enabled; - s32 suspendCount; +s32 OSSuspendThread(OSThread* thread) +{ + BOOL enabled; + s32 suspendCount; - enabled = OSDisableInterrupts(); - suspendCount = thread->suspend++; - if (suspendCount == 0) { - switch (thread->state) { - case OS_THREAD_STATE_RUNNING: - RunQueueHint = TRUE; - thread->state = OS_THREAD_STATE_READY; - break; - case OS_THREAD_STATE_READY: - UnsetRun(thread); - break; - case OS_THREAD_STATE_WAITING: - RemoveItem(thread->queue, thread, link); - thread->priority = 32; - AddTail(thread->queue, thread, link); - if (thread->mutex) { - UpdatePriority(thread->mutex->thread); - } - break; - } + enabled = OSDisableInterrupts(); + suspendCount = thread->suspend++; + if (suspendCount == 0) + { + switch (thread->state) + { + case OS_THREAD_STATE_RUNNING: + RunQueueHint = TRUE; + thread->state = OS_THREAD_STATE_READY; + break; + case OS_THREAD_STATE_READY: + UnsetRun(thread); + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->priority = 32; + AddTail(thread->queue, thread, link); + if (thread->mutex) + { + UpdatePriority(thread->mutex->thread); + } + break; + } - __OSReschedule(); - } - OSRestoreInterrupts(enabled); - return suspendCount; + __OSReschedule(); + } + OSRestoreInterrupts(enabled); + return suspendCount; } -void OSSleepThread(OSThreadQueue* queue) { - BOOL enabled; - OSThread* currentThread; +void OSSleepThread(OSThreadQueue* queue) +{ + BOOL enabled; + OSThread* currentThread; - enabled = OSDisableInterrupts(); - currentThread = OSGetCurrentThread(); + enabled = OSDisableInterrupts(); + currentThread = OSGetCurrentThread(); - currentThread->state = OS_THREAD_STATE_WAITING; - currentThread->queue = queue; - AddPrio(queue, currentThread, link); - RunQueueHint = TRUE; - __OSReschedule(); - OSRestoreInterrupts(enabled); + currentThread->state = OS_THREAD_STATE_WAITING; + currentThread->queue = queue; + AddPrio(queue, currentThread, link); + RunQueueHint = TRUE; + __OSReschedule(); + OSRestoreInterrupts(enabled); } -void OSWakeupThread(OSThreadQueue* queue) { - BOOL enabled; - OSThread* thread; +void OSWakeupThread(OSThreadQueue* queue) +{ + BOOL enabled; + OSThread* thread; - enabled = OSDisableInterrupts(); - while (queue->head) { - RemoveHead(queue, thread, link); - thread->state = OS_THREAD_STATE_READY; - if (!(0 < thread->suspend)) { - SetRun(thread); + enabled = OSDisableInterrupts(); + while (queue->head) + { + RemoveHead(queue, thread, link); + thread->state = OS_THREAD_STATE_READY; + if (!(0 < thread->suspend)) + { + SetRun(thread); + } } - } - __OSReschedule(); - OSRestoreInterrupts(enabled); + __OSReschedule(); + OSRestoreInterrupts(enabled); } -OSPriority OSGetThreadPriority(OSThread *thread) { return thread->base; } - -void OSClearStack(u8 val) { - register u32 sp; - register u32* p; - register u32 pattern; +void OSClearStack(u8 val) +{ + register u32 sp; + register u32* p; + register u32 pattern; - pattern = ((u32)val << 24) | ((u32)val << 16) | ((u32)val << 8) | (u32)val; - sp = OSGetStackPointer(); - for (p = __OSCurrentThread->stackEnd + 1; p < (u32*)sp; ++p) { - *p = pattern; - } + pattern = ((u32)val << 24) | ((u32)val << 16) | ((u32)val << 8) | (u32)val; + sp = OSGetStackPointer(); + for (p = __OSCurrentThread->stackEnd + 1; p < (u32*)sp; ++p) + { + *p = pattern; + } } diff --git a/libs/dolphin/os/OSTime.c b/libs/dolphin/os/OSTime.c index 803fe10bc..7f893c0a5 100644 --- a/libs/dolphin/os/OSTime.c +++ b/libs/dolphin/os/OSTime.c @@ -5,13 +5,15 @@ #define OS_TIME_YEAR_DAY_MAX 365 // End of each month in standard year -static s32 YearDays[OS_TIME_MONTH_MAX] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; +static s32 YearDays[OS_TIME_MONTH_MAX] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; // End of each month in leap year -static s32 LeapYearDays[OS_TIME_MONTH_MAX] = {0, 31, 60, 91, 121, 152, - 182, 213, 244, 274, 305, 335}; +static s32 LeapYearDays[OS_TIME_MONTH_MAX] = { + 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 +}; -asm OSTime OSGetTime(void) { - // clang-format off +asm OSTime OSGetTime(void) +{ + // clang-format off nofralloc mftbu r3 @@ -23,7 +25,7 @@ asm OSTime OSGetTime(void) { bne OSGetTime blr - // clang-format on + // clang-format on } asm OSTick OSGetTick(void){ @@ -37,101 +39,110 @@ asm OSTick OSGetTick(void){ #define OS_SYSTEMTIME_BASE 0x30D8 -OSTime __OSGetSystemTime(void) { - BOOL enabled; - OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE); - OSTime result; +OSTime __OSGetSystemTime(void) +{ + BOOL enabled; + OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE); + OSTime result; - enabled = OSDisableInterrupts(); - result = *timeAdjustAddr + OSGetTime(); - OSRestoreInterrupts(enabled); + enabled = OSDisableInterrupts(); + result = *timeAdjustAddr + OSGetTime(); + OSRestoreInterrupts(enabled); - return result; + return result; } -OSTime __OSTimeToSystemTime(OSTime time) { - BOOL enabled; - OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE); - OSTime result; +OSTime __OSTimeToSystemTime(OSTime time) +{ + BOOL enabled; + OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE); + OSTime result; - enabled = OSDisableInterrupts(); - result = *timeAdjustAddr + time; - OSRestoreInterrupts(enabled); + enabled = OSDisableInterrupts(); + result = *timeAdjustAddr + time; + OSRestoreInterrupts(enabled); - return result; + return result; } -static BOOL IsLeapYear(s32 year) { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); } +static BOOL IsLeapYear(s32 year) +{ + return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); +} -static s32 GetYearDays(s32 year, s32 mon) { - return (IsLeapYear(year) ? LeapYearDays : YearDays)[mon]; +static s32 GetYearDays(s32 year, s32 mon) +{ + return (IsLeapYear(year) ? LeapYearDays : YearDays)[mon]; } -static s32 GetLeapDays(s32 year) { - if (year < 1) { - return 0; - } - return (year + 3) / 4 - (year - 1) / 100 + (year - 1) / 400; +static s32 GetLeapDays(s32 year) +{ + if (year < 1) + { + return 0; + } + return (year + 3) / 4 - (year - 1) / 100 + (year - 1) / 400; } -static void GetDates(s32 days, OSCalendarTime* cal) { - s32 year; - s32 totalDays; - s32* p_days; - s32 month; - cal->wday = (days + 6) % OS_TIME_WEEK_DAY_MAX; - - for (year = days / OS_TIME_YEAR_DAY_MAX; - days < (totalDays = year * OS_TIME_YEAR_DAY_MAX + GetLeapDays(year));) { - year--; - } - - days -= totalDays; - cal->year = year; - cal->yday = days; - - p_days = IsLeapYear(year) ? LeapYearDays : YearDays; - month = OS_TIME_MONTH_MAX; - while (days < p_days[--month]) { - ; - } - cal->mon = month; - cal->mday = days - p_days[month] + 1; +static void GetDates(s32 days, OSCalendarTime* cal) +{ + s32 year; + s32 totalDays; + s32* p_days; + s32 month; + cal->wday = (days + 6) % OS_TIME_WEEK_DAY_MAX; + + for (year = days / OS_TIME_YEAR_DAY_MAX; + days < (totalDays = year * OS_TIME_YEAR_DAY_MAX + GetLeapDays(year));) + { + year--; + } + + days -= totalDays; + cal->year = year; + cal->yday = days; + + p_days = IsLeapYear(year) ? LeapYearDays : YearDays; + month = OS_TIME_MONTH_MAX; + while (days < p_days[--month]) + { + ; + } + cal->mon = month; + cal->mday = days - p_days[month] + 1; } #define BIAS (2000 * 365 + (2000 + 3) / 4 - (2000 - 1) / 100 + (2000 - 1) / 400) #pragma push #pragma dont_inline on -void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* td) { - int days; - int secs; - OSTime d; - - d = ticks % OSSecondsToTicks(1); - if (d < 0) { - d += OSSecondsToTicks(1); - } - td->usec = (int)(OSTicksToMicroseconds(d) % 1000); - td->msec = (int)(OSTicksToMilliseconds(d) % 1000); - - ticks -= d; - days = (int)(OSTicksToSeconds(ticks) / 86400 + BIAS); - secs = (int)(OSTicksToSeconds(ticks) % 86400); - if (secs < 0) { - days -= 1; - secs += 24 * 60 * 60; - } - - GetDates(days, td); - - td->hour = secs / 60 / 60; - td->min = (secs / 60) % 60; - td->sec = secs % 60; +void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* td) +{ + int days; + int secs; + OSTime d; + + d = ticks % OSSecondsToTicks(1); + if (d < 0) + { + d += OSSecondsToTicks(1); + } + td->usec = (int)(OSTicksToMicroseconds(d) % 1000); + td->msec = (int)(OSTicksToMilliseconds(d) % 1000); + + ticks -= d; + days = (int)(OSTicksToSeconds(ticks) / 86400 + BIAS); + secs = (int)(OSTicksToSeconds(ticks) % 86400); + if (secs < 0) + { + days -= 1; + secs += 24 * 60 * 60; + } + + GetDates(days, td); + + td->hour = secs / 60 / 60; + td->min = (secs / 60) % 60; + td->sec = secs % 60; } #pragma dont_inline reset - -OSTime OSCalendarTimeToTicks(const OSCalendarTime* time) { - ; - ; -} diff --git a/libs/dolphin/os/__os.h b/libs/dolphin/os/__os.h new file mode 100644 index 000000000..9808a40da --- /dev/null +++ b/libs/dolphin/os/__os.h @@ -0,0 +1,133 @@ +#ifndef _DOLPHIN_OS_INTERNAL_H_ +#define _DOLPHIN_OS_INTERNAL_H_ + +#include +#include +#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/libs/dolphin/os/init/__ppc_eabi_init.cpp b/libs/dolphin/os/init/__ppc_eabi_init.cpp index ea0791dd2..e276d4a6b 100644 --- a/libs/dolphin/os/init/__ppc_eabi_init.cpp +++ b/libs/dolphin/os/init/__ppc_eabi_init.cpp @@ -48,27 +48,27 @@ __declspec(section ".init") asm void __flush_cache(void) { } // clang-format on - -void __init_user(void) { __init_cpp(); } +void __init_user(void) +{ + __init_cpp(); +} static void __init_cpp(void) { - voidfunctionptr* constructor; - /* + voidfunctionptr* constructor; + /* * call static initializers */ - for (constructor = _ctors; *constructor; constructor++) { - (*constructor)(); - } + for (constructor = _ctors; *constructor; constructor++) + { + (*constructor)(); + } } - -void __fini_cpp(void) +void _ExitProcess(void) { - // UNUSED FUNCTION + PPCHalt(); } - -void _ExitProcess(void) { PPCHalt(); } #ifdef __cplusplus } #endif diff --git a/libs/dolphin/pad/Padclamp.c b/libs/dolphin/pad/Padclamp.c index 89fbbfb8a..e6165d56a 100644 --- a/libs/dolphin/pad/Padclamp.c +++ b/libs/dolphin/pad/Padclamp.c @@ -2,8 +2,6 @@ #include "std/math.h" -s32 PAD_CHANMAX; - static const PADClampRegion ClampRegion = { // Triggers 30, @@ -98,51 +96,6 @@ static void ClampStick(s8* px, s8* py, s8 max, s8 xy, s8 min) *py = (s8)(signY * y); } -static void ClampCircle(s8* px, s8* py, s8 radius, s8 min) -{ - int x = *px; - int y = *py; - int squared; - int length; - - if (-min < x && x < min) - { - x = 0; - } - else if (0 < x) - { - x -= min; - } - else - { - x += min; - } - - if (-min < y && y < min) - { - y = 0; - } - else if (0 < y) - { - y -= min; - } - else - { - y += min; - } - - squared = x * x + y * y; - if (radius * radius < squared) - { - length = sqrtf(squared); - x = (x * radius) / length; - y = (y * radius) / length; - } - - *px = x; - *py = y; -} - static void ClampTrigger(u8* trigger, u8 min, u8 max) { if (*trigger <= min) @@ -163,7 +116,7 @@ static void ClampTrigger(u8* trigger, u8 min, u8 max) void PADClamp(PADStatus* status) { int i; - for (i = 0; i < PAD_CHANMAX; i++, status++) + for (i = 0; i < 4; i++, status++) { if (status->err != PAD_ERR_NONE) { @@ -178,21 +131,3 @@ void PADClamp(PADStatus* status) ClampTrigger(&status->triggerRight, ClampRegion.minTrigger, ClampRegion.maxTrigger); } } - -void PADClampCircle(PADStatus* status) -{ - int i; - for (i = 0; i < PAD_CHANMAX; ++i, status++) - { - if (status->err != PAD_ERR_NONE) - { - continue; - } - - 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); - } -} diff --git a/libs/dolphin/upnp/UPnP.c b/libs/dolphin/upnp/UPnP.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/upnp/UPnPHttp.c b/libs/dolphin/upnp/UPnPHttp.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/upnp/UPnPHttpd.c b/libs/dolphin/upnp/UPnPHttpd.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/upnp/UPnPHttpdResponse.c b/libs/dolphin/upnp/UPnPHttpdResponse.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/upnp/UPnPSsdp.c b/libs/dolphin/upnp/UPnPSsdp.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/upnp/UPnPUri.c b/libs/dolphin/upnp/UPnPUri.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/upnp/UPnPUuid.c b/libs/dolphin/upnp/UPnPUuid.c deleted file mode 100644 index e69de29bb..000000000 From 9a30094673ecc03d501c78b4c6fbd55b6ad9aeef Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Sat, 24 May 2025 01:20:38 -0400 Subject: [PATCH 06/19] Day 1 SDK link --- config/GQPE78/splits.txt | 366 +-- configure.py | 599 +++-- .../MSL/MSL_C/MSL_Common/Include/cctype | 6 - .../MSL/MSL_C/MSL_Common/Include/climits | 6 - .../MSL/MSL_C/MSL_Common/Include/cstdarg | 8 - .../MSL/MSL_C/MSL_Common/Include/cstddef | 6 - .../MSL/MSL_C/MSL_Common/Include/ctime | 6 - .../MSL/MSL_C/MSL_Common/Include/ctype.h | 14 - .../MSL/MSL_C/MSL_Common/Include/limits.h | 6 - .../MSL/MSL_C/MSL_Common/Include/math.h | 41 - .../MSL/MSL_C/MSL_Common/Include/stdarg.h | 6 - .../MSL/MSL_C/MSL_Common/Include/stddef.h | 6 - .../MSL/MSL_C/MSL_Common/Include/stdio.h | 27 - .../MSL/MSL_C/MSL_Common/Include/string.h | 28 - .../MSL/MSL_C/MSL_Common/Include/va_list.h | 6 - include/bink/bink.h | 3 +- include/dolphin/CARDPriv.h | 139 + include/dolphin/DVDPriv.h | 35 + include/dolphin/OSRtcPriv.h | 38 + include/dolphin/ai.h | 48 +- include/dolphin/ar/ar.h | 45 + include/dolphin/ar/arq.h | 51 + include/dolphin/base.h | 13 + include/dolphin/base/PPCArch.h | 846 +++--- include/dolphin/card.h | 378 +-- include/dolphin/db.h | 28 +- include/dolphin/dolphin/ar.h | 69 - include/dolphin/dolphin/gx.h | 40 - include/dolphin/dolphin/gx/GXBump.h | 29 - include/dolphin/dolphin/gx/GXCommandList.h | 35 - include/dolphin/dolphin/gx/GXCpu2Efb.h | 29 - include/dolphin/dolphin/gx/GXCull.h | 18 - include/dolphin/dolphin/gx/GXDispList.h | 16 - include/dolphin/dolphin/gx/GXDraw.h | 22 - include/dolphin/dolphin/gx/GXEnum.h | 898 ------- include/dolphin/dolphin/gx/GXFifo.h | 50 - include/dolphin/dolphin/gx/GXFrameBuffer.h | 66 - include/dolphin/dolphin/gx/GXGeometry.h | 47 - include/dolphin/dolphin/gx/GXGet.h | 64 - include/dolphin/dolphin/gx/GXLighting.h | 32 - include/dolphin/dolphin/gx/GXManage.h | 36 - include/dolphin/dolphin/gx/GXPerf.h | 30 - include/dolphin/dolphin/gx/GXPixel.h | 30 - include/dolphin/dolphin/gx/GXStruct.h | 75 - include/dolphin/dolphin/gx/GXTev.h | 33 - include/dolphin/dolphin/gx/GXTexture.h | 52 - include/dolphin/dolphin/gx/GXTransform.h | 34 - include/dolphin/dolphin/gx/GXVerify.h | 29 - include/dolphin/dolphin/gx/GXVert.h | 162 -- include/dolphin/dolphin/mtx.h | 373 --- include/dolphin/dolphin/vi.h | 7 - include/dolphin/dolphin/vi/vifuncs.h | 35 - include/dolphin/dolphin/vi/vitypes.h | 39 - include/dolphin/dsp.h | 85 +- include/dolphin/dvd.h | 237 +- include/dolphin/dvd/dvd.h | 169 ++ include/dolphin/dvd/dvdfs.h | 49 + include/dolphin/dvd/dvdlow.h | 41 + include/dolphin/dvd/dvdqueue.h | 28 + include/dolphin/eth/eth.h | 72 + include/dolphin/eth/hashfunc.c | 20 + include/dolphin/exi.h | 86 +- include/dolphin/gd.h | 102 +- include/dolphin/gx.h | 50 +- include/dolphin/gx/GXBump.h | 29 +- include/dolphin/gx/GXCommandList.h | 56 +- include/dolphin/gx/GXCull.h | 9 +- include/dolphin/gx/GXDispList.h | 8 +- include/dolphin/gx/GXDraw.h | 16 +- include/dolphin/gx/GXEnum.h | 1391 +++++----- include/dolphin/gx/GXFifo.h | 35 +- include/dolphin/gx/GXFrameBuffer.h | 40 +- include/dolphin/gx/GXGeometry.h | 58 +- include/dolphin/gx/GXGet.h | 61 +- include/dolphin/gx/GXLighting.h | 30 +- include/dolphin/gx/GXManage.h | 26 +- include/dolphin/gx/GXMisc.h | 21 + include/dolphin/gx/GXPerf.h | 22 +- include/dolphin/gx/GXPixel.h | 19 +- include/dolphin/gx/GXPriv.h | 38 + include/dolphin/gx/GXStruct.h | 93 +- include/dolphin/gx/GXTev.h | 22 +- include/dolphin/gx/GXTexture.h | 59 +- include/dolphin/gx/GXTransform.h | 28 +- include/dolphin/gx/GXVert.h | 191 +- include/dolphin/hio.h | 44 +- include/dolphin/hw_regs.h | 166 +- include/dolphin/ip/ip.h | 26 + include/dolphin/lg.h | 29 + include/dolphin/md5.h | 52 + include/dolphin/mtx.h | 474 +--- include/dolphin/os.h | 421 ++- include/dolphin/os/OSAlarm.h | 34 +- include/dolphin/os/OSAlloc.h | 36 +- include/dolphin/os/OSArena.h | 13 + include/dolphin/os/OSBootInfo.h | 41 + include/dolphin/os/OSCache.h | 11 +- include/dolphin/os/OSContext.h | 57 +- include/dolphin/os/OSError.h | 53 +- include/dolphin/os/OSException.h | 45 +- include/dolphin/os/OSExpansion.h | 79 + include/dolphin/os/OSFastCast.h | 86 + include/dolphin/os/OSFont.h | 80 +- include/dolphin/os/OSFst.h | 19 + include/dolphin/os/OSInterrupt.h | 71 +- include/dolphin/os/OSMemory.h | 10 +- include/dolphin/os/OSMessage.h | 40 +- include/dolphin/os/OSModule.h | 92 +- include/dolphin/os/OSMutex.h | 24 +- include/dolphin/os/OSPriv.h | 18 + include/dolphin/os/OSReset.h | 52 +- include/dolphin/os/OSResetSW.h | 11 +- include/dolphin/os/OSSerial.h | 71 +- include/dolphin/os/OSThread.h | 155 +- include/dolphin/os/OSTime.h | 57 +- include/dolphin/os/init/__start.h | 46 + include/dolphin/pad.h | 48 +- include/dolphin/sipriv.h | 42 + include/dolphin/tcp/tcp.h | 29 + include/dolphin/thp.h | 129 + include/dolphin/types.h | 61 +- include/dolphin/vi.h | 175 +- include/dolphin/vi/vitypes.h | 60 +- include/inline/fastmath.h | 2 +- include/macros.h | 80 + include/mathHelper.h | 14 + include/rwsdk/rwplcore.h | 2 +- include/std/bitset.h | 116 + include/std/math.h | 79 + include/types.h | 51 + .../MSL_C++/MSL_Common/Include/exception | 0 .../MSL_C++/MSL_Common/Include/exception.h | 0 .../MSL_C++/MSL_Common/Include/new | 0 .../MSL_C++/MSL_Common/Include/new.h | 2 +- .../MSL_C/MSL_Common/FILE_POS.h | 20 + .../MSL_C/MSL_Common/abort_exit.h | 17 + .../MSL_C/MSL_Common/alloc.h | 8 + .../MSL_C/MSL_Common/ansi_files.h | 90 + .../MSL_C/MSL_Common/ansi_fp.h | 40 + .../MSL_C/MSL_Common/ansi_params.h | 14 + .../MSL_C/MSL_Common/arith.h | 24 + .../MSL_C/MSL_Common/bsearch.h | 18 + .../MSL_C/MSL_Common}/cmath | 0 .../MSL_C/MSL_Common/critical_regions.h | 32 + .../MSL_C/MSL_Common}/cstdlib | 0 .../MSL_C/MSL_Common}/cstring | 0 .../MSL_C/MSL_Common/ctype_api.h | 36 + .../MSL_C/MSL_Common/direct_io.h | 10 + .../MSL_C/MSL_Common/file_io.h | 10 + .../MSL_C/MSL_Common/file_struc.h | 10 + .../MSL_C/MSL_Common/locale_api.h | 9 + .../MSL_C/MSL_Common/math_api.h | 93 + .../MSL_C/MSL_Common/mbstring.h | 21 + .../MSL_C/MSL_Common/mem_funcs.h | 11 + .../MSL_C/MSL_Common/misc_io.h | 8 + .../MSL_C/MSL_Common/printf.h | 25 + .../MSL_C/MSL_Common/rand.h | 17 + .../MSL_C/MSL_Common/scanf.h | 18 + .../MSL_C/MSL_Common/secure_error.h | 10 + .../MSL_C/MSL_Common/signal.h | 17 + .../MSL_C/MSL_Common}/size_t.h | 0 .../MSL_C/MSL_Common/stdio_api.h | 38 + .../MSL_C/MSL_Common}/stdlib.h | 4 +- .../MSL_C/MSL_Common/strtold.h | 6 + .../MSL_C/MSL_Common/strtoul.h | 20 + .../MSL_C/MSL_Common}/time.h | 0 .../MSL_C/MSL_Common/wchar_io.h | 9 + .../MSL_C/PPC_EABI/math_ppc.h | 18 + .../MetroTRK/custconn/CircleBuffer.h | 24 + .../MetroTRK/custconn/cc_gdev.h | 23 + .../PowerPC_EABI_Support/MetroTRK/dispatch.h | 25 + .../MetroTRK/dolphin_trk.h | 16 + .../MetroTRK/target_options.h | 9 + .../PowerPC_EABI_Support/MetroTRK/trk.h | 219 ++ .../Runtime/Gecko_ExceptionPPC.h | 231 ++ .../Runtime/MWCPlusPlusLib.h | 46 + .../Runtime/NMWException.h | 34 + .../Runtime/__init_cpp_exceptions.h | 14 + .../PowerPC_EABI_Support/Runtime/__mem.h | 16 + .../Runtime/__ppc_eabi_linker.h | 74 + .../PowerPC_EABI_Support/Runtime/__va_arg.h | 13 + .../Runtime/global_destructor_chain.h | 26 + .../PowerPC_EABI_Support/Runtime/runtime.h | 19 + libs/PowerPC_EABI_Support/include/algorithm | 51 + libs/PowerPC_EABI_Support/include/ctype.h | 54 + libs/PowerPC_EABI_Support/include/errno.h | 59 + libs/PowerPC_EABI_Support/include/exception | 20 + libs/PowerPC_EABI_Support/include/extras.h | 14 + libs/PowerPC_EABI_Support/include/fdlibm.h | 230 ++ libs/PowerPC_EABI_Support/include/float.h | 59 + libs/PowerPC_EABI_Support/include/functional | 20 + libs/PowerPC_EABI_Support/include/iterator | 41 + libs/PowerPC_EABI_Support/include/limits | 70 + libs/PowerPC_EABI_Support/include/limits.h | 36 + libs/PowerPC_EABI_Support/include/locale.h | 129 + libs/PowerPC_EABI_Support/include/math.h | 99 + libs/PowerPC_EABI_Support/include/mem.h | 20 + libs/PowerPC_EABI_Support/include/signal.h | 18 + libs/PowerPC_EABI_Support/include/stdarg.h | 40 + libs/PowerPC_EABI_Support/include/stddef.h | 6 + libs/PowerPC_EABI_Support/include/stdio.h | 19 + libs/PowerPC_EABI_Support/include/stdlib.h | 20 + libs/PowerPC_EABI_Support/include/string.h | 31 + libs/PowerPC_EABI_Support/include/utility | 21 + libs/PowerPC_EABI_Support/include/wchar.h | 16 + .../src/MSL_C/MSL_Common/FILE_POS.C | 130 + .../src/MSL_C/MSL_Common/alloc.c | 452 ++++ .../src/MSL_C/MSL_Common/ansi_files.c | 154 ++ .../src/MSL_C/MSL_Common/arith.c | 120 + .../src/MSL_C/MSL_Common/bsearch.c | 40 + .../src/MSL_C/MSL_Common/buffer_io.c | 53 + .../src/MSL_C/MSL_Common/ctype.c | 137 + .../src/MSL_C/MSL_Common/direct_io.c | 143 + .../src/MSL_C/MSL_Common/errno.c | 3 + .../src/MSL_C/MSL_Common/extras.c | 401 +++ .../src/MSL_C/MSL_Common/file_io.c | 93 + .../src/MSL_C/MSL_Common/float.c | 8 + .../src/MSL_C/MSL_Common/locale.c | 33 + .../src/MSL_C/MSL_Common/mbstring.c | 260 ++ .../src/MSL_C/MSL_Common/mem.c | 105 + .../src/MSL_C/MSL_Common/mem_funcs.c | 217 ++ .../src/MSL_C/MSL_Common/misc_io.c | 25 + .../src/MSL_C/MSL_Common/printf.c | 1250 +++++++++ .../src/MSL_C/MSL_Common/rand.c | 14 + .../src/MSL_C/MSL_Common/scanf.c | 670 +++++ .../src/MSL_C/MSL_Common/signal.c | 39 + .../src/MSL_C/MSL_Common/string.c | 306 +++ .../src/MSL_C/MSL_Common/strtold.c | 703 +++++ .../src/MSL_C/MSL_Common/strtoul.c | 353 +++ .../src/MSL_C/MSL_Common/wchar_io.c | 82 + .../Math/Double_precision/e_asin.c | 117 + .../Math/Double_precision/e_atan2.c | 143 + .../Math/Double_precision/e_exp.c | 162 ++ .../Math/Double_precision/e_fmod.c | 167 ++ .../Math/Double_precision/e_log.c | 157 ++ .../Math/Double_precision/e_log10.c | 99 + .../Math/Double_precision/e_pow.c | 408 +++ .../Math/Double_precision/e_rem_pio2.c | 181 ++ .../Math/Double_precision/e_sqrt.c | 462 ++++ .../Math/Double_precision/k_cos.c | 93 + .../Math/Double_precision/k_rem_pio2.c | 355 +++ .../Math/Double_precision/k_sin.c | 80 + .../Math/Double_precision/k_tan.c | 181 ++ .../Math/Double_precision/s_atan.c | 143 + .../Math/Double_precision/s_ceil.c | 90 + .../Math/Double_precision/s_copysign.c | 30 + .../Math/Double_precision/s_cos.c | 82 + .../Math/Double_precision/s_floor.c | 89 + .../Math/Double_precision/s_frexp.c | 58 + .../Math/Double_precision/s_ldexp.c | 63 + .../Math/Double_precision/s_modf.c | 79 + .../Math/Double_precision/s_sin.c | 82 + .../Math/Double_precision/s_tan.c | 73 + .../Math/Double_precision/w_asin.c | 15 + .../Math/Double_precision/w_atan2.c | 15 + .../Math/Double_precision/w_exp.c | 15 + .../Math/Double_precision/w_fmod.c | 15 + .../Math/Double_precision/w_log10.c | 15 + .../Math/Double_precision/w_pow.c | 15 + .../Math/Double_precision/w_sqrt.c | 15 + .../src/MSL_C/MSL_Common_Embedded/ansi_fp.c | 779 ++++++ .../MSL_Common_Embedded/uart_console_io_gcn.c | 57 + .../src/MSL_C/PPC_EABI/abort_exit.c | 70 + .../PPC_EABI/critical_regions.gamecube.c | 10 + .../src/MSL_C/PPC_EABI/math_ppc.c | 520 ++++ .../src/Runtime/CPlusLibPPC.cp | 41 + .../src/Runtime/GCN_mem_alloc.c | 36 + .../src/Runtime/Gecko_ExceptionPPC.cp | 891 +++++++ .../src/Runtime/NMWException.cp | 91 + .../src/Runtime/__init_cpp_exceptions.cpp | 37 + libs/PowerPC_EABI_Support/src/Runtime/__mem.c | 102 + .../src/Runtime/__va_arg.c | 44 + .../src/Runtime/global_destructor_chain.c | 32 + libs/PowerPC_EABI_Support/src/Runtime/ptmf.c | 104 + .../src/Runtime/runtime.c | 920 +++++++ .../src/runtime3/READ_ME.txt | 6 + .../src/runtime3/runtime.c | 920 +++++++ libs/dolphin/OdemuExi2/DebuggerDriver.c | 0 libs/dolphin/ai/ai.c | 354 +++ libs/dolphin/ar/ar.c | 383 +++ libs/dolphin/ar/arq.c | 271 ++ libs/dolphin/ax/AX.c | 43 + libs/dolphin/ax/AXAlloc.c | 256 ++ libs/dolphin/ax/AXAux.c | 184 ++ libs/dolphin/ax/AXCL.c | 226 ++ libs/dolphin/ax/AXComp.c | 287 ++ libs/dolphin/ax/AXOut.c | 243 ++ libs/dolphin/ax/AXProf.c | 24 + libs/dolphin/ax/AXSPB.c | 94 + libs/dolphin/ax/AXVPB.c | 1299 +++++++++ libs/dolphin/ax/DSPCode.c | 211 ++ libs/dolphin/ax/__ax.h | 67 + libs/dolphin/base/PPCArch.c | 263 ++ libs/dolphin/card/CARDBios.c | 722 +++++ libs/dolphin/card/CARDBlock.c | 159 ++ libs/dolphin/card/CARDCheck.c | 406 +++ libs/dolphin/card/CARDCreate.c | 141 + libs/dolphin/card/CARDDelete.c | 85 + libs/dolphin/card/CARDDir.c | 92 + libs/dolphin/card/CARDFormat.c | 138 + libs/dolphin/card/CARDMount.c | 366 +++ libs/dolphin/card/CARDNet.c | 55 + libs/dolphin/card/CARDOpen.c | 209 ++ libs/dolphin/card/CARDRdwr.c | 125 + libs/dolphin/card/CARDRead.c | 151 ++ libs/dolphin/card/CARDRename.c | 83 + libs/dolphin/card/CARDStat.c | 152 ++ libs/dolphin/card/CARDStatEx.c | 125 + libs/dolphin/card/CARDUnlock.c | 419 +++ libs/dolphin/card/CARDWrite.c | 128 + libs/dolphin/card/__card.h | 104 + libs/dolphin/db/db.c | 46 + libs/dolphin/dsp/dsp.c | 115 + libs/dolphin/dsp/dsp_debug.c | 6 + libs/dolphin/dsp/dsp_task.c | 426 +++ libs/dolphin/dvd/dvd.c | 1664 ++++++++++++ libs/dolphin/dvd/dvdFatal.c | 112 + libs/dolphin/dvd/dvderror.c | 77 + libs/dolphin/dvd/dvdfs.c | 739 ++++++ libs/dolphin/dvd/dvdidutils.c | 31 + libs/dolphin/dvd/dvdlow.c | 515 ++++ libs/dolphin/dvd/dvdqueue.c | 159 ++ libs/dolphin/dvd/emu_level2/fstload.c | 75 + libs/dolphin/eth/base64.c | 70 + libs/dolphin/eth/eth.c | 1031 ++++++++ libs/dolphin/eth/ethsec.c | 344 +++ libs/dolphin/eth/md5.c | 285 ++ libs/dolphin/exi/EXIBios.c | 854 ++++++ libs/dolphin/exi/EXIUart.c | 202 ++ libs/dolphin/gd/GDBase.c | 0 libs/dolphin/gd/GDGeometry.c | 0 libs/dolphin/gx/GXAttr.c | 0 libs/dolphin/gx/GXBump.c | 0 libs/dolphin/gx/GXDisplayList.c | 0 libs/dolphin/gx/GXDraw.c | 0 libs/dolphin/gx/GXFifo.c | 0 libs/dolphin/gx/GXFrameBuf.c | 0 libs/dolphin/gx/GXGeometry.c | 0 libs/dolphin/gx/GXInit.c | 0 libs/dolphin/gx/GXLight.c | 0 libs/dolphin/gx/GXMisc.c | 0 libs/dolphin/gx/GXPerf.c | 0 libs/dolphin/gx/GXPixel.c | 0 libs/dolphin/gx/GXTev.c | 0 libs/dolphin/gx/GXTexture.c | 0 libs/dolphin/gx/GXTransform.c | 0 libs/dolphin/hio/hio.c | 0 libs/dolphin/ip/IFFifo.c | 0 libs/dolphin/ip/IFRing.c | 0 libs/dolphin/ip/IP.c | 0 libs/dolphin/ip/IPArp.c | 0 libs/dolphin/ip/IPChap.c | 0 libs/dolphin/ip/IPDhcp.c | 0 libs/dolphin/ip/IPDns.c | 0 libs/dolphin/ip/IPEther.c | 0 libs/dolphin/ip/IPFrag.c | 0 libs/dolphin/ip/IPIcmp.c | 0 libs/dolphin/ip/IPIgmp.c | 0 libs/dolphin/ip/IPIpcp.c | 0 libs/dolphin/ip/IPLcp.c | 0 libs/dolphin/ip/IPOpt.c | 0 libs/dolphin/ip/IPPPP.c | 0 libs/dolphin/ip/IPPPPoE.c | 0 libs/dolphin/ip/IPPap.c | 0 libs/dolphin/ip/IPRoute.c | 0 libs/dolphin/ip/IPSocket.c | 0 libs/dolphin/ip/IPTcp.c | 0 libs/dolphin/ip/IPTcpOutput.c | 0 libs/dolphin/ip/IPTcpTimeWait.c | 0 libs/dolphin/ip/IPTcpTimer.c | 0 libs/dolphin/ip/IPTcpUser.c | 0 libs/dolphin/ip/IPUdp.c | 0 libs/dolphin/ip/IPUuid.c | 0 libs/dolphin/ip/IPZero.c | 0 libs/dolphin/lg/allsrc.c | 0 libs/dolphin/mtx/mtx.c | 0 libs/dolphin/mtx/mtx44.c | 0 libs/dolphin/mtx/mtx44vec.c | 39 + libs/dolphin/mtx/mtxvec.c | 0 libs/dolphin/mtx/quat.c | 0 libs/dolphin/mtx/vec.c | 262 ++ libs/dolphin/odenotstub/odenotstub.c | 0 libs/dolphin/os/OS.c | 678 +++++ libs/dolphin/os/OSAlarm.c | 254 ++ libs/dolphin/os/OSAlloc.c | 228 ++ libs/dolphin/os/OSArena.c | 41 + libs/dolphin/os/OSAudioSystem.c | 114 + libs/dolphin/os/OSCache.c | 426 +++ libs/dolphin/os/OSContext.c | 637 +++++ libs/dolphin/os/OSError.c | 205 ++ libs/dolphin/os/OSFont.c | 32 + libs/dolphin/os/OSInterrupt.c | 427 +++ libs/dolphin/os/OSLink.c | 556 ++++ libs/dolphin/os/OSMemory.c | 223 ++ libs/dolphin/os/OSMessage.c | 86 + libs/dolphin/os/OSMutex.c | 223 ++ libs/dolphin/os/OSReboot.c | 119 + libs/dolphin/os/OSReset.c | 211 ++ libs/dolphin/os/OSResetSW.c | 118 + libs/dolphin/os/OSRtc.c | 399 +++ libs/dolphin/os/OSSync.c | 29 + libs/dolphin/os/OSThread.c | 590 +++++ libs/dolphin/os/OSTime.c | 137 + libs/dolphin/os/init/__ppc_eabi_init.cpp | 74 + libs/dolphin/os/init/__start.c | 223 ++ libs/dolphin/pad/Pad.c | 901 +++++++ libs/dolphin/pad/Padclamp.c | 198 ++ libs/dolphin/si/SIBios.c | 902 +++++++ libs/dolphin/si/SISamplingRate.c | 80 + libs/dolphin/si/SISteering.c | 0 libs/dolphin/si/SISteeringAuto.c | 0 libs/dolphin/si/SISteeringXfer.c | 0 libs/dolphin/thp/THPAudio.c | 202 ++ libs/dolphin/thp/THPDec.c | 2316 +++++++++++++++++ libs/dolphin/upnp/UPnP.c | 0 libs/dolphin/upnp/UPnPHttp.c | 0 libs/dolphin/upnp/UPnPHttpd.c | 0 libs/dolphin/upnp/UPnPHttpdResponse.c | 0 libs/dolphin/upnp/UPnPSsdp.c | 0 libs/dolphin/upnp/UPnPUri.c | 0 libs/dolphin/upnp/UPnPUuid.c | 0 libs/dolphin/vi/vi.c | 1037 ++++++++ .../embedded/MetroTRK/Export/mslsupp.c | 0 .../embedded/MetroTRK/Os/dolphin/UDP_Stubs.c | 0 .../MetroTRK/Os/dolphin/dolphin_trk.c | 0 .../MetroTRK/Os/dolphin/dolphin_trk_glue.c | 0 .../embedded/MetroTRK/Os/dolphin/targcont.c | 0 .../MetroTRK/Os/dolphin/target_options.c | 0 .../embedded/MetroTRK/Os/dolphin/usr_put.c | 0 .../embedded/MetroTRK/Portable/dispatch.c | 0 .../embedded/MetroTRK/Portable/main_TRK.c | 0 .../embedded/MetroTRK/Portable/mainloop.c | 0 .../embedded/MetroTRK/Portable/mem_TRK.c | 0 .../debugger/embedded/MetroTRK/Portable/msg.c | 0 .../embedded/MetroTRK/Portable/msgbuf.c | 0 .../embedded/MetroTRK/Portable/msghndlr.c | 0 .../embedded/MetroTRK/Portable/mutex_TRK.c | 0 .../embedded/MetroTRK/Portable/notify.c | 0 .../embedded/MetroTRK/Portable/nubevent.c | 0 .../embedded/MetroTRK/Portable/nubinit.c | 0 .../embedded/MetroTRK/Portable/serpoll.c | 0 .../embedded/MetroTRK/Portable/support.c | 0 .../MetroTRK/Processor/ppc/Export/targsupp.s | 0 .../Processor/ppc/Generic/__exception.s | 0 .../Processor/ppc/Generic/flush_cache.c | 0 .../Processor/ppc/Generic/mpc_7xx_603e.c | 0 .../MetroTRK/Processor/ppc/Generic/targimpl.c | 0 .../cc/exi2/GCN/EXI2_DDH_GCN/main.c | 0 .../cc/exi2/GCN/EXI2_GDEV_GCN/main.c | 0 .../utils/common/CircleBuffer.c | 0 .../cust_connection/utils/common/MWTrace.c | 0 .../utils/gc/MWCriticalSection_gc.cpp | 0 src/SB/Core/gc/iFMV.cpp | 1 + src/SB/Core/gc/iFMV.h | 2 +- src/SB/Core/gc/iMath.cpp | 2 +- src/SB/Core/gc/iMemMgr.cpp | 2 +- src/SB/Core/gc/iMix.c | 729 ++---- src/SB/Core/gc/iPad.cpp | 2 + src/SB/Core/gc/iTRC.cpp | 14 +- src/SB/Core/gc/ngcrad3d.c | 173 +- src/SB/Core/x/xAnim.cpp | 20 +- src/SB/Core/x/xCamera.cpp | 17 +- src/SB/Core/x/xCutscene.cpp | 12 +- src/SB/Core/x/xFont.cpp | 1 + src/SB/Core/x/xHud.cpp | 24 +- src/SB/Core/x/xHudMeter.cpp | 1 + src/SB/Core/x/xHudModel.cpp | 2 +- src/SB/Core/x/xHudText.cpp | 4 +- src/SB/Core/x/xIni.cpp | 4 +- src/SB/Core/x/xJaw.cpp | 16 +- src/SB/Core/x/xMath.cpp | 233 +- src/SB/Core/x/xModelBucket.cpp | 2 +- src/SB/Core/x/xPtankPool.cpp | 2 +- src/SB/Core/x/xRMemData.h | 2 +- src/SB/Core/x/xString.h | 2 +- src/SB/Core/x/xpkrsvc.h | 3 +- src/SB/Core/x/xutil.cpp | 2 + src/SB/Game/zAssetTypes.cpp | 1 + src/SB/Game/zCamera.h | 2 + src/SB/Game/zDiscoFloor.cpp | 1 + src/SB/Game/zEnt.cpp | 3 +- src/SB/Game/zEntCruiseBubble.cpp | 2 +- src/SB/Game/zEntPlayerBungeeState.cpp | 3 +- src/SB/Game/zFX.cpp | 2 +- src/SB/Game/zMain.cpp | 2 +- src/SB/Game/zParPTank.cpp | 11 +- src/SB/Game/zUI.cpp | 5 +- src/SB/Game/zVar.cpp | 1 + 488 files changed, 48837 insertions(+), 7115 deletions(-) delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cctype delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/climits delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdarg delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstddef delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctime delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctype.h delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/limits.h delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/math.h delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdarg.h delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stddef.h delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdio.h delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h delete mode 100644 include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/va_list.h create mode 100644 include/dolphin/CARDPriv.h create mode 100644 include/dolphin/DVDPriv.h create mode 100644 include/dolphin/OSRtcPriv.h create mode 100644 include/dolphin/ar/ar.h create mode 100644 include/dolphin/ar/arq.h create mode 100644 include/dolphin/base.h delete mode 100644 include/dolphin/dolphin/ar.h delete mode 100644 include/dolphin/dolphin/gx.h delete mode 100644 include/dolphin/dolphin/gx/GXBump.h delete mode 100644 include/dolphin/dolphin/gx/GXCommandList.h delete mode 100644 include/dolphin/dolphin/gx/GXCpu2Efb.h delete mode 100644 include/dolphin/dolphin/gx/GXCull.h delete mode 100644 include/dolphin/dolphin/gx/GXDispList.h delete mode 100644 include/dolphin/dolphin/gx/GXDraw.h delete mode 100644 include/dolphin/dolphin/gx/GXEnum.h delete mode 100644 include/dolphin/dolphin/gx/GXFifo.h delete mode 100644 include/dolphin/dolphin/gx/GXFrameBuffer.h delete mode 100644 include/dolphin/dolphin/gx/GXGeometry.h delete mode 100644 include/dolphin/dolphin/gx/GXGet.h delete mode 100644 include/dolphin/dolphin/gx/GXLighting.h delete mode 100644 include/dolphin/dolphin/gx/GXManage.h delete mode 100644 include/dolphin/dolphin/gx/GXPerf.h delete mode 100644 include/dolphin/dolphin/gx/GXPixel.h delete mode 100644 include/dolphin/dolphin/gx/GXStruct.h delete mode 100644 include/dolphin/dolphin/gx/GXTev.h delete mode 100644 include/dolphin/dolphin/gx/GXTexture.h delete mode 100644 include/dolphin/dolphin/gx/GXTransform.h delete mode 100644 include/dolphin/dolphin/gx/GXVerify.h delete mode 100644 include/dolphin/dolphin/gx/GXVert.h delete mode 100644 include/dolphin/dolphin/mtx.h delete mode 100644 include/dolphin/dolphin/vi.h delete mode 100644 include/dolphin/dolphin/vi/vifuncs.h delete mode 100644 include/dolphin/dolphin/vi/vitypes.h create mode 100644 include/dolphin/dvd/dvd.h create mode 100644 include/dolphin/dvd/dvdfs.h create mode 100644 include/dolphin/dvd/dvdlow.h create mode 100644 include/dolphin/dvd/dvdqueue.h create mode 100644 include/dolphin/eth/eth.h create mode 100644 include/dolphin/eth/hashfunc.c create mode 100644 include/dolphin/gx/GXMisc.h create mode 100644 include/dolphin/gx/GXPriv.h create mode 100644 include/dolphin/ip/ip.h create mode 100644 include/dolphin/lg.h create mode 100644 include/dolphin/md5.h create mode 100644 include/dolphin/os/OSArena.h create mode 100644 include/dolphin/os/OSBootInfo.h create mode 100644 include/dolphin/os/OSExpansion.h create mode 100644 include/dolphin/os/OSFastCast.h create mode 100644 include/dolphin/os/OSFst.h create mode 100644 include/dolphin/os/OSPriv.h create mode 100644 include/dolphin/os/init/__start.h create mode 100644 include/dolphin/sipriv.h create mode 100644 include/dolphin/tcp/tcp.h create mode 100644 include/dolphin/thp.h create mode 100644 include/macros.h create mode 100644 include/mathHelper.h create mode 100644 include/std/bitset.h create mode 100644 include/std/math.h rename {include/PowerPC_EABI_Support/MSL => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support}/MSL_C++/MSL_Common/Include/exception (100%) rename {include/PowerPC_EABI_Support/MSL => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support}/MSL_C++/MSL_Common/Include/exception.h (100%) rename {include/PowerPC_EABI_Support/MSL => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support}/MSL_C++/MSL_Common/Include/new (100%) rename {include/PowerPC_EABI_Support/MSL => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support}/MSL_C++/MSL_Common/Include/new.h (94%) create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/abort_exit.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/alloc.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_fp.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_params.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/arith.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/bsearch.h rename {include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common}/cmath (100%) create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h rename {include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common}/cstdlib (100%) rename {include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common}/cstring (100%) create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ctype_api.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/direct_io.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_io.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_struc.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/locale_api.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mbstring.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mem_funcs.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/printf.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/rand.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/scanf.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/secure_error.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/signal.h rename {include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common}/size_t.h (100%) create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h rename {include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common}/stdlib.h (71%) create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtold.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtoul.h rename {include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include => libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common}/time.h (100%) create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/wchar_io.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/PPC_EABI/math_ppc.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/custconn/CircleBuffer.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/custconn/cc_gdev.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dispatch.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dolphin_trk.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/target_options.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trk.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/Gecko_ExceptionPPC.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/MWCPlusPlusLib.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/NMWException.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__init_cpp_exceptions.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__mem.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__va_arg.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/global_destructor_chain.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/runtime.h create mode 100644 libs/PowerPC_EABI_Support/include/algorithm create mode 100644 libs/PowerPC_EABI_Support/include/ctype.h create mode 100644 libs/PowerPC_EABI_Support/include/errno.h create mode 100644 libs/PowerPC_EABI_Support/include/exception create mode 100644 libs/PowerPC_EABI_Support/include/extras.h create mode 100644 libs/PowerPC_EABI_Support/include/fdlibm.h create mode 100644 libs/PowerPC_EABI_Support/include/float.h create mode 100644 libs/PowerPC_EABI_Support/include/functional create mode 100644 libs/PowerPC_EABI_Support/include/iterator create mode 100644 libs/PowerPC_EABI_Support/include/limits create mode 100644 libs/PowerPC_EABI_Support/include/limits.h create mode 100644 libs/PowerPC_EABI_Support/include/locale.h create mode 100644 libs/PowerPC_EABI_Support/include/math.h create mode 100644 libs/PowerPC_EABI_Support/include/mem.h create mode 100644 libs/PowerPC_EABI_Support/include/signal.h create mode 100644 libs/PowerPC_EABI_Support/include/stdarg.h create mode 100644 libs/PowerPC_EABI_Support/include/stddef.h create mode 100644 libs/PowerPC_EABI_Support/include/stdio.h create mode 100644 libs/PowerPC_EABI_Support/include/stdlib.h create mode 100644 libs/PowerPC_EABI_Support/include/string.h create mode 100644 libs/PowerPC_EABI_Support/include/utility create mode 100644 libs/PowerPC_EABI_Support/include/wchar.h create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/FILE_POS.C create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/alloc.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ansi_files.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/arith.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/bsearch.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/buffer_io.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ctype.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/direct_io.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/errno.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/extras.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/file_io.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/float.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/locale.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mbstring.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem_funcs.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/misc_io.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/printf.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/rand.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/scanf.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/signal.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/string.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtold.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtoul.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/wchar_io.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log10.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_sqrt.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log10.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_sqrt.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/ansi_fp.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/abort_exit.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/critical_regions.gamecube.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/math_ppc.c create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/CPlusLibPPC.cp create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/GCN_mem_alloc.c create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/Gecko_ExceptionPPC.cp create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/NMWException.cp create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/__init_cpp_exceptions.cpp create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/__mem.c create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/__va_arg.c create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/global_destructor_chain.c create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/ptmf.c create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/runtime.c create mode 100644 libs/PowerPC_EABI_Support/src/runtime3/READ_ME.txt create mode 100644 libs/PowerPC_EABI_Support/src/runtime3/runtime.c create mode 100644 libs/dolphin/OdemuExi2/DebuggerDriver.c create mode 100644 libs/dolphin/ai/ai.c create mode 100644 libs/dolphin/ar/ar.c create mode 100644 libs/dolphin/ar/arq.c create mode 100644 libs/dolphin/ax/AX.c create mode 100644 libs/dolphin/ax/AXAlloc.c create mode 100644 libs/dolphin/ax/AXAux.c create mode 100644 libs/dolphin/ax/AXCL.c create mode 100644 libs/dolphin/ax/AXComp.c create mode 100644 libs/dolphin/ax/AXOut.c create mode 100644 libs/dolphin/ax/AXProf.c create mode 100644 libs/dolphin/ax/AXSPB.c create mode 100644 libs/dolphin/ax/AXVPB.c create mode 100644 libs/dolphin/ax/DSPCode.c create mode 100644 libs/dolphin/ax/__ax.h create mode 100644 libs/dolphin/base/PPCArch.c create mode 100644 libs/dolphin/card/CARDBios.c create mode 100644 libs/dolphin/card/CARDBlock.c create mode 100644 libs/dolphin/card/CARDCheck.c create mode 100644 libs/dolphin/card/CARDCreate.c create mode 100644 libs/dolphin/card/CARDDelete.c create mode 100644 libs/dolphin/card/CARDDir.c create mode 100644 libs/dolphin/card/CARDFormat.c create mode 100644 libs/dolphin/card/CARDMount.c create mode 100644 libs/dolphin/card/CARDNet.c create mode 100644 libs/dolphin/card/CARDOpen.c create mode 100644 libs/dolphin/card/CARDRdwr.c create mode 100644 libs/dolphin/card/CARDRead.c create mode 100644 libs/dolphin/card/CARDRename.c create mode 100644 libs/dolphin/card/CARDStat.c create mode 100644 libs/dolphin/card/CARDStatEx.c create mode 100644 libs/dolphin/card/CARDUnlock.c create mode 100644 libs/dolphin/card/CARDWrite.c create mode 100644 libs/dolphin/card/__card.h create mode 100644 libs/dolphin/db/db.c create mode 100644 libs/dolphin/dsp/dsp.c create mode 100644 libs/dolphin/dsp/dsp_debug.c create mode 100644 libs/dolphin/dsp/dsp_task.c create mode 100644 libs/dolphin/dvd/dvd.c create mode 100644 libs/dolphin/dvd/dvdFatal.c create mode 100644 libs/dolphin/dvd/dvderror.c create mode 100644 libs/dolphin/dvd/dvdfs.c create mode 100644 libs/dolphin/dvd/dvdidutils.c create mode 100644 libs/dolphin/dvd/dvdlow.c create mode 100644 libs/dolphin/dvd/dvdqueue.c create mode 100644 libs/dolphin/dvd/emu_level2/fstload.c create mode 100644 libs/dolphin/eth/base64.c create mode 100644 libs/dolphin/eth/eth.c create mode 100644 libs/dolphin/eth/ethsec.c create mode 100644 libs/dolphin/eth/md5.c create mode 100644 libs/dolphin/exi/EXIBios.c create mode 100644 libs/dolphin/exi/EXIUart.c create mode 100644 libs/dolphin/gd/GDBase.c create mode 100644 libs/dolphin/gd/GDGeometry.c create mode 100644 libs/dolphin/gx/GXAttr.c create mode 100644 libs/dolphin/gx/GXBump.c create mode 100644 libs/dolphin/gx/GXDisplayList.c create mode 100644 libs/dolphin/gx/GXDraw.c create mode 100644 libs/dolphin/gx/GXFifo.c create mode 100644 libs/dolphin/gx/GXFrameBuf.c create mode 100644 libs/dolphin/gx/GXGeometry.c create mode 100644 libs/dolphin/gx/GXInit.c create mode 100644 libs/dolphin/gx/GXLight.c create mode 100644 libs/dolphin/gx/GXMisc.c create mode 100644 libs/dolphin/gx/GXPerf.c create mode 100644 libs/dolphin/gx/GXPixel.c create mode 100644 libs/dolphin/gx/GXTev.c create mode 100644 libs/dolphin/gx/GXTexture.c create mode 100644 libs/dolphin/gx/GXTransform.c create mode 100644 libs/dolphin/hio/hio.c create mode 100644 libs/dolphin/ip/IFFifo.c create mode 100644 libs/dolphin/ip/IFRing.c create mode 100644 libs/dolphin/ip/IP.c create mode 100644 libs/dolphin/ip/IPArp.c create mode 100644 libs/dolphin/ip/IPChap.c create mode 100644 libs/dolphin/ip/IPDhcp.c create mode 100644 libs/dolphin/ip/IPDns.c create mode 100644 libs/dolphin/ip/IPEther.c create mode 100644 libs/dolphin/ip/IPFrag.c create mode 100644 libs/dolphin/ip/IPIcmp.c create mode 100644 libs/dolphin/ip/IPIgmp.c create mode 100644 libs/dolphin/ip/IPIpcp.c create mode 100644 libs/dolphin/ip/IPLcp.c create mode 100644 libs/dolphin/ip/IPOpt.c create mode 100644 libs/dolphin/ip/IPPPP.c create mode 100644 libs/dolphin/ip/IPPPPoE.c create mode 100644 libs/dolphin/ip/IPPap.c create mode 100644 libs/dolphin/ip/IPRoute.c create mode 100644 libs/dolphin/ip/IPSocket.c create mode 100644 libs/dolphin/ip/IPTcp.c create mode 100644 libs/dolphin/ip/IPTcpOutput.c create mode 100644 libs/dolphin/ip/IPTcpTimeWait.c create mode 100644 libs/dolphin/ip/IPTcpTimer.c create mode 100644 libs/dolphin/ip/IPTcpUser.c create mode 100644 libs/dolphin/ip/IPUdp.c create mode 100644 libs/dolphin/ip/IPUuid.c create mode 100644 libs/dolphin/ip/IPZero.c create mode 100644 libs/dolphin/lg/allsrc.c create mode 100644 libs/dolphin/mtx/mtx.c create mode 100644 libs/dolphin/mtx/mtx44.c create mode 100644 libs/dolphin/mtx/mtx44vec.c create mode 100644 libs/dolphin/mtx/mtxvec.c create mode 100644 libs/dolphin/mtx/quat.c create mode 100644 libs/dolphin/mtx/vec.c create mode 100644 libs/dolphin/odenotstub/odenotstub.c create mode 100644 libs/dolphin/os/OS.c create mode 100644 libs/dolphin/os/OSAlarm.c create mode 100644 libs/dolphin/os/OSAlloc.c create mode 100644 libs/dolphin/os/OSArena.c create mode 100644 libs/dolphin/os/OSAudioSystem.c create mode 100644 libs/dolphin/os/OSCache.c create mode 100644 libs/dolphin/os/OSContext.c create mode 100644 libs/dolphin/os/OSError.c create mode 100644 libs/dolphin/os/OSFont.c create mode 100644 libs/dolphin/os/OSInterrupt.c create mode 100644 libs/dolphin/os/OSLink.c create mode 100644 libs/dolphin/os/OSMemory.c create mode 100644 libs/dolphin/os/OSMessage.c create mode 100644 libs/dolphin/os/OSMutex.c create mode 100644 libs/dolphin/os/OSReboot.c create mode 100644 libs/dolphin/os/OSReset.c create mode 100644 libs/dolphin/os/OSResetSW.c create mode 100644 libs/dolphin/os/OSRtc.c create mode 100644 libs/dolphin/os/OSSync.c create mode 100644 libs/dolphin/os/OSThread.c create mode 100644 libs/dolphin/os/OSTime.c create mode 100644 libs/dolphin/os/init/__ppc_eabi_init.cpp create mode 100644 libs/dolphin/os/init/__start.c create mode 100644 libs/dolphin/pad/Pad.c create mode 100644 libs/dolphin/pad/Padclamp.c create mode 100644 libs/dolphin/si/SIBios.c create mode 100644 libs/dolphin/si/SISamplingRate.c create mode 100644 libs/dolphin/si/SISteering.c create mode 100644 libs/dolphin/si/SISteeringAuto.c create mode 100644 libs/dolphin/si/SISteeringXfer.c create mode 100644 libs/dolphin/thp/THPAudio.c create mode 100644 libs/dolphin/thp/THPDec.c create mode 100644 libs/dolphin/upnp/UPnP.c create mode 100644 libs/dolphin/upnp/UPnPHttp.c create mode 100644 libs/dolphin/upnp/UPnPHttpd.c create mode 100644 libs/dolphin/upnp/UPnPHttpdResponse.c create mode 100644 libs/dolphin/upnp/UPnPSsdp.c create mode 100644 libs/dolphin/upnp/UPnPUri.c create mode 100644 libs/dolphin/upnp/UPnPUuid.c create mode 100644 libs/dolphin/vi/vi.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Export/mslsupp.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/UDP_Stubs.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/targcont.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/target_options.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/usr_put.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/dispatch.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/main_TRK.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mainloop.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mem_TRK.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msg.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mutex_TRK.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/notify.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubevent.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubinit.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/serpoll.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c create mode 100644 libs/runtime_libs/gamedev/cust_connection/cc/exi2/GCN/EXI2_DDH_GCN/main.c create mode 100644 libs/runtime_libs/gamedev/cust_connection/cc/exi2/GCN/EXI2_GDEV_GCN/main.c create mode 100644 libs/runtime_libs/gamedev/cust_connection/utils/common/CircleBuffer.c create mode 100644 libs/runtime_libs/gamedev/cust_connection/utils/common/MWTrace.c create mode 100644 libs/runtime_libs/gamedev/cust_connection/utils/gc/MWCriticalSection_gc.cpp diff --git a/config/GQPE78/splits.txt b/config/GQPE78/splits.txt index dfd29e29f..4f8b6fd67 100644 --- a/config/GQPE78/splits.txt +++ b/config/GQPE78/splits.txt @@ -2468,206 +2468,206 @@ bink/src/sdk/dct.c: bink/src/sdk/bitplane.c: .text start:0x801B1F24 end:0x801B5350 -dolphin/ai/src/ai.c: +dolphin/ai/ai.c: .text start:0x801B5350 end:0x801B5C34 .data start:0x802B03C0 end:0x802B0408 .sdata start:0x803CAE48 end:0x803CAE50 .sbss start:0x803CC220 end:0x803CC260 -dolphin/amcstubs/src/AmcExi2Stubs.c: +dolphin/amcstubs/AmcExi2Stubs.c: .text start:0x801B5C34 end:0x801B5C64 -dolphin/ar/src/ar.c: +dolphin/ar/ar.c: .text start:0x801B5C64 end:0x801B77A4 .data start:0x802B0408 end:0x802B0450 .sdata start:0x803CAE50 end:0x803CAE58 .sbss start:0x803CC260 end:0x803CC280 -dolphin/ar/src/arq.c: +dolphin/ar/arq.c: .text start:0x801B77A4 end:0x801B7C60 .data start:0x802B0450 end:0x802B0498 .sdata start:0x803CAE58 end:0x803CAE60 .sbss start:0x803CC280 end:0x803CC2B0 -dolphin/ax/src/AX.c: +dolphin/ax/AX.c: .text start:0x801B7C60 end:0x801B7D04 .data start:0x802B0498 end:0x802B04E0 .sdata start:0x803CAE60 end:0x803CAE68 -dolphin/ax/src/AXAlloc.c: +dolphin/ax/AXAlloc.c: .text start:0x801B7D04 end:0x801B81CC .bss start:0x80363D88 end:0x80363EA0 .sbss start:0x803CC2B0 end:0x803CC2B8 -dolphin/ax/src/AXAux.c: +dolphin/ax/AXAux.c: .text start:0x801B81CC end:0x801B8654 .bss start:0x80363EA0 end:0x80366BA0 .sbss start:0x803CC2B8 end:0x803CC2F0 -dolphin/ax/src/AXCL.c: +dolphin/ax/AXCL.c: .text start:0x801B8654 end:0x801B8D70 .bss start:0x80366BA0 end:0x803671A0 .sbss start:0x803CC2F0 end:0x803CC308 -dolphin/ax/src/AXOut.c: +dolphin/ax/AXOut.c: .text start:0x801B8D70 end:0x801B9540 .bss start:0x803671A0 end:0x8036BC40 .sbss start:0x803CC308 end:0x803CC340 -dolphin/ax/src/AXSPB.c: +dolphin/ax/AXSPB.c: .text start:0x801B9540 end:0x801B9A08 .bss start:0x8036BC40 end:0x8036BC80 .sbss start:0x803CC340 end:0x803CC368 -dolphin/ax/src/AXVPB.c: +dolphin/ax/AXVPB.c: .text start:0x801B9A08 end:0x801BAC28 .data start:0x802B04E0 end:0x802B05C0 .bss start:0x8036BC80 end:0x8037D480 .sbss start:0x803CC368 end:0x803CC378 .sdata2 start:0x803CFC70 end:0x803CFC78 -dolphin/ax/src/AXComp.c: +dolphin/ax/AXComp.c: .data start:0x802B05C0 end:0x802B2000 -dolphin/ax/src/DSPCode.c: +dolphin/ax/DSPCode.c: .data start:0x802B2000 end:0x802B3EC0 .sdata start:0x803CAE68 end:0x803CAE70 -dolphin/ax/src/AXProf.c: +dolphin/ax/AXProf.c: .text start:0x801BAC28 end:0x801BAC70 .sbss start:0x803CC378 end:0x803CC388 -dolphin/base/src/PPCArch.c: +dolphin/base/PPCArch.c: .text start:0x801BAC70 end:0x801BAD84 -dolphin/card/src/CARDBios.c: +dolphin/card/CARDBios.c: .text start:0x801BAD84 end:0x801BC174 .data start:0x802B3EC0 end:0x802B3F20 .bss start:0x8037D480 end:0x8037D6C0 .sdata start:0x803CAE70 end:0x803CAE78 .sbss start:0x803CC388 end:0x803CC390 -dolphin/card/src/CARDUnlock.c: +dolphin/card/CARDUnlock.c: .text start:0x801BC174 end:0x801BD3D4 .data start:0x802B3F20 end:0x802B4080 .sdata start:0x803CAE78 end:0x803CAE80 -dolphin/card/src/CARDRdwr.c: +dolphin/card/CARDRdwr.c: .text start:0x801BD3D4 end:0x801BD66C -dolphin/card/src/CARDBlock.c: +dolphin/card/CARDBlock.c: .text start:0x801BD66C end:0x801BDA70 -dolphin/card/src/CARDDir.c: +dolphin/card/CARDDir.c: .text start:0x801BDA70 end:0x801BDCD4 -dolphin/card/src/CARDCheck.c: +dolphin/card/CARDCheck.c: .text start:0x801BDCD4 end:0x801BEC98 -dolphin/card/src/CARDMount.c: +dolphin/card/CARDMount.c: .text start:0x801BEC98 end:0x801BF758 .data start:0x802B4080 end:0x802B40C0 -dolphin/card/src/CARDFormat.c: +dolphin/card/CARDFormat.c: .text start:0x801BF758 end:0x801BFF90 -dolphin/card/src/CARDOpen.c: +dolphin/card/CARDOpen.c: .text start:0x801BFF90 end:0x801C0680 -dolphin/card/src/CARDCreate.c: +dolphin/card/CARDCreate.c: .text start:0x801C0680 end:0x801C0A18 -dolphin/card/src/CARDRead.c: +dolphin/card/CARDRead.c: .text start:0x801C0A18 end:0x801C0E8C -dolphin/card/src/CARDWrite.c: +dolphin/card/CARDWrite.c: .text start:0x801C0E8C end:0x801C11C0 -dolphin/card/src/CARDDelete.c: +dolphin/card/CARDDelete.c: .text start:0x801C11C0 end:0x801C13BC -dolphin/card/src/CARDStat.c: +dolphin/card/CARDStat.c: .text start:0x801C13BC end:0x801C1884 -dolphin/card/src/CARDStatEx.c: +dolphin/card/CARDStatEx.c: .text start:0x801C1884 end:0x801C1BC4 -dolphin/card/src/CARDNet.c: +dolphin/card/CARDNet.c: .text start:0x801C1BC4 end:0x801C1CF0 .sdata start:0x803CAE80 end:0x803CAE88 -dolphin/db/src/db.c: +dolphin/db/db.c: .text start:0x801C1CF0 end:0x801C1DDC .data start:0x802B40C0 end:0x802B40D8 .sbss start:0x803CC390 end:0x803CC398 -dolphin/dsp/src/dsp.c: +dolphin/dsp/dsp.c: .text start:0x801C1DDC end:0x801C206C .data start:0x802B40D8 end:0x802B4158 .sdata start:0x803CAE88 end:0x803CAE90 .sbss start:0x803CC398 end:0x803CC3A0 -dolphin/dsp/src/dsp_debug.c: +dolphin/dsp/dsp_debug.c: .text start:0x801C206C end:0x801C20BC -dolphin/dsp/src/dsp_task.c: +dolphin/dsp/dsp_task.c: .text start:0x801C20BC end:0x801C2940 .data start:0x802B4158 end:0x802B4298 .sbss start:0x803CC3A0 end:0x803CC3B8 -dolphin/dvd/src/dvdlow.c: +dolphin/dvd/dvdlow.c: .text start:0x801C2940 end:0x801C3784 .bss start:0x8037D6C0 end:0x8037D7A0 .sdata start:0x803CAE90 end:0x803CAE98 .sbss start:0x803CC3B8 end:0x803CC400 -dolphin/dvd/src/dvdfs.c: +dolphin/dvd/dvdfs.c: .text start:0x801C3784 end:0x801C4128 .data start:0x802B4298 end:0x802B4428 .sdata start:0x803CAE98 end:0x803CAEA0 .sbss start:0x803CC400 end:0x803CC420 -dolphin/dvd/src/dvd.c: +dolphin/dvd/dvd.c: .text start:0x801C4128 end:0x801C6B40 .data start:0x802B4428 end:0x802B45A8 .bss start:0x8037D7A0 end:0x8037D838 .sdata start:0x803CAEA0 end:0x803CAEB8 .sbss start:0x803CC420 end:0x803CC470 -dolphin/dvd/src/dvdqueue.c: +dolphin/dvd/dvdqueue.c: .text start:0x801C6B40 end:0x801C6D38 .bss start:0x8037D838 end:0x8037D858 -dolphin/dvd/src/dvderror.c: +dolphin/dvd/dvderror.c: .text start:0x801C6D38 end:0x801C6ED0 .data start:0x802B45A8 end:0x802B45F0 -dolphin/dvd/src/dvdidutils.c: +dolphin/dvd/dvdidutils.c: .text start:0x801C6ED0 end:0x801C6FC8 -dolphin/dvd/src/dvdFatal.c: +dolphin/dvd/dvdFatal.c: .text start:0x801C6FC8 end:0x801C6FF8 .sbss start:0x803CC470 end:0x803CC478 -dolphin/dvd/src/emu_level2/fstload.c: +dolphin/dvd/emu_level2/fstload.c: .text start:0x801C6FF8 end:0x801C7238 .data start:0x802B45F0 end:0x802B4660 .bss start:0x8037D858 end:0x8037D8C8 .sdata start:0x803CAEB8 end:0x803CAEC8 .sbss start:0x803CC478 end:0x803CC488 -dolphin/exi/src/EXIBios.c: +dolphin/exi/EXIBios.c: .text start:0x801C7238 end:0x801C8C14 .data start:0x802B4660 end:0x802B4780 .bss start:0x8037D8C8 end:0x8037D988 .sdata start:0x803CAEC8 end:0x803CAED0 .sbss start:0x803CC488 end:0x803CC490 -dolphin/exi/src/EXIUart.c: +dolphin/exi/EXIUart.c: .text start:0x801C8C14 end:0x801C91E8 .sbss start:0x803CC490 end:0x803CC4A0 -dolphin/gx/src/GXInit.c: +dolphin/gx/GXInit.c: .text start:0x801C91E8 end:0x801CA560 .data start:0x802B4780 end:0x802B49C0 .bss start:0x8037D988 end:0x8037DFC0 @@ -2675,450 +2675,450 @@ dolphin/gx/src/GXInit.c: .sbss start:0x803CC4A0 end:0x803CC4C8 .sdata2 start:0x803CFC78 end:0x803CFCA0 -dolphin/gx/src/GXFifo.c: +dolphin/gx/GXFifo.c: .text start:0x801CA560 end:0x801CAD5C .sbss start:0x803CC4C8 end:0x803CC4E8 -dolphin/gx/src/GXAttr.c: +dolphin/gx/GXAttr.c: .text start:0x801CAD5C end:0x801CBAB0 .data start:0x802B49C0 end:0x802B4B20 .sdata start:0x803CAED8 end:0x803CAEE8 -dolphin/gx/src/GXMisc.c: +dolphin/gx/GXMisc.c: .text start:0x801CBAB0 end:0x801CC198 .sbss start:0x803CC4E8 end:0x803CC500 -dolphin/gx/src/GXGeometry.c: +dolphin/gx/GXGeometry.c: .text start:0x801CC198 end:0x801CC518 -dolphin/gx/src/GXFrameBuf.c: +dolphin/gx/GXFrameBuf.c: .text start:0x801CC518 end:0x801CD0B4 .data start:0x802B4B20 end:0x802B4C10 .sdata2 start:0x803CFCA0 end:0x803CFCB0 -dolphin/gx/src/GXLight.c: +dolphin/gx/GXLight.c: .text start:0x801CD0B4 end:0x801CD6C8 .data start:0x802B4C10 end:0x802B4C30 .sdata2 start:0x803CFCB0 end:0x803CFCE0 -dolphin/gx/src/GXTexture.c: +dolphin/gx/GXTexture.c: .text start:0x801CD6C8 end:0x801CE8CC .data start:0x802B4C30 end:0x802B4E58 .sdata start:0x803CAEE8 end:0x803CAF28 .sdata2 start:0x803CFCE0 end:0x803CFD18 -dolphin/gx/src/GXBump.c: +dolphin/gx/GXBump.c: .text start:0x801CE8CC end:0x801CED74 .sdata2 start:0x803CFD18 end:0x803CFD20 -dolphin/gx/src/GXTev.c: +dolphin/gx/GXTev.c: .text start:0x801CED74 end:0x801CF4D8 .data start:0x802B4E58 end:0x802B4ED0 -dolphin/gx/src/GXPixel.c: +dolphin/gx/GXPixel.c: .text start:0x801CF4D8 end:0x801CFB20 .data start:0x802B4ED0 end:0x802B4EF0 .sdata2 start:0x803CFD20 end:0x803CFD58 -dolphin/gx/src/GXDisplayList.c: +dolphin/gx/GXDisplayList.c: .text start:0x801CFB20 end:0x801CFB90 -dolphin/gx/src/GXTransform.c: +dolphin/gx/GXTransform.c: .text start:0x801CFB90 end:0x801D0124 .sdata2 start:0x803CFD58 end:0x803CFD68 -dolphin/gx/src/GXPerf.c: +dolphin/gx/GXPerf.c: .text start:0x801D0124 end:0x801D097C .data start:0x802B4EF0 end:0x802B4FE0 -dolphin/mtx/src/mtx.c: +dolphin/mtx/mtx.c: .text start:0x801D097C end:0x801D0A9C .sdata start:0x803CAF28 end:0x803CAF30 .sdata2 start:0x803CFD68 end:0x803CFD70 -dolphin/mtx/src/mtx44.c: +dolphin/mtx/mtx44.c: .text start:0x801D0A9C end:0x801D0B34 .sdata2 start:0x803CFD70 end:0x803CFD80 -dolphin/odenotstub/src/odenotstub.c: +dolphin/odenotstub/odenotstub.c: .text start:0x801D0B34 end:0x801D0B3C -dolphin/os/src/OS.c: +dolphin/os/OS.c: .text start:0x801D0B3C end:0x801D1628 .data start:0x802B4FE0 end:0x802B51D8 .bss start:0x8037DFC0 end:0x8037E010 .sdata start:0x803CAF30 end:0x803CAF40 .sbss start:0x803CC500 end:0x803CC540 -dolphin/os/src/OSAlarm.c: +dolphin/os/OSAlarm.c: .text start:0x801D1628 end:0x801D1D54 .sbss start:0x803CC540 end:0x803CC548 -dolphin/os/src/OSAlloc.c: +dolphin/os/OSAlloc.c: .text start:0x801D1D54 end:0x801D2064 .sdata start:0x803CAF40 end:0x803CAF48 .sbss start:0x803CC548 end:0x803CC558 -dolphin/os/src/OSArena.c: +dolphin/os/OSArena.c: .text start:0x801D2064 end:0x801D2084 .sdata start:0x803CAF48 end:0x803CAF50 .sbss start:0x803CC558 end:0x803CC560 -dolphin/os/src/OSAudioSystem.c: +dolphin/os/OSAudioSystem.c: .text start:0x801D2084 end:0x801D2318 .data start:0x802B51D8 end:0x802B5258 -dolphin/os/src/OSCache.c: +dolphin/os/OSCache.c: .text start:0x801D2318 end:0x801D2750 .data start:0x802B5258 end:0x802B5488 -dolphin/os/src/OSContext.c: +dolphin/os/OSContext.c: .text start:0x801D2750 end:0x801D2F04 .data start:0x802B5488 end:0x802B5660 -dolphin/os/src/OSError.c: +dolphin/os/OSError.c: .text start:0x801D2F04 end:0x801D35B0 .data start:0x802B5660 end:0x802B5980 .bss start:0x8037E010 end:0x8037E060 .sdata start:0x803CAF50 end:0x803CAF58 -dolphin/os/src/OSFont.c: +dolphin/os/OSFont.c: .text start:0x801D35B0 end:0x801D4310 .data start:0x802B5980 end:0x802B6490 .sdata start:0x803CAF58 end:0x803CAF60 .sbss start:0x803CC560 end:0x803CC570 .sdata2 start:0x803CFD80 end:0x803CFD88 -dolphin/os/src/OSInterrupt.c: +dolphin/os/OSInterrupt.c: .text start:0x801D4310 end:0x801D4B7C .data start:0x802B6490 end:0x802B64C0 .sbss start:0x803CC570 end:0x803CC588 -dolphin/os/src/OSLink.c: +dolphin/os/OSLink.c: .text start:0x801D4B7C end:0x801D4B94 -dolphin/os/src/OSMemory.c: +dolphin/os/OSMemory.c: .text start:0x801D4B94 end:0x801D4E6C .data start:0x802B64C0 end:0x802B64D0 -dolphin/os/src/OSMutex.c: +dolphin/os/OSMutex.c: .text start:0x801D4E6C end:0x801D4EDC -dolphin/os/src/OSReboot.c: +dolphin/os/OSReboot.c: .text start:0x801D4EDC end:0x801D5238 .bss start:0x8037E060 end:0x8037E080 .sbss start:0x803CC588 end:0x803CC598 -dolphin/os/src/OSReset.c: +dolphin/os/OSReset.c: .text start:0x801D5238 end:0x801D565C .sbss start:0x803CC598 end:0x803CC5A8 -dolphin/os/src/OSResetSW.c: +dolphin/os/OSResetSW.c: .text start:0x801D565C end:0x801D59E8 .sbss start:0x803CC5A8 end:0x803CC5C8 -dolphin/os/src/OSRtc.c: +dolphin/os/OSRtc.c: .text start:0x801D59E8 end:0x801D6588 .bss start:0x8037E080 end:0x8037E0D8 -dolphin/os/src/OSSync.c: +dolphin/os/OSSync.c: .text start:0x801D6588 end:0x801D660C -dolphin/os/src/OSThread.c: +dolphin/os/OSThread.c: .text start:0x801D660C end:0x801D754C .bss start:0x8037E0D8 end:0x8037EAD0 .sdata start:0x803CAF60 end:0x803CAF68 .sbss start:0x803CC5C8 end:0x803CC5D8 -dolphin/os/src/OSTime.c: +dolphin/os/OSTime.c: .text start:0x801D754C end:0x801D79C8 .data start:0x802B64D0 end:0x802B6530 -dolphin/os/src/init/__start.c: +dolphin/os/init/__start.c: .init start:0x80003100 end:0x80003400 .text start:0x801D79C8 end:0x801D79CC .sbss start:0x803CC5D8 end:0x803CC5E0 -dolphin/os/src/init/__ppc_eabi_init.cpp: +dolphin/os/init/__ppc_eabi_init.cpp: .init start:0x80003400 end:0x80003458 .text start:0x801D79CC end:0x801D7A60 -dolphin/pad/src/Padclamp.c: +dolphin/pad/Padclamp.c: .text start:0x801D7A60 end:0x801D7CA4 .rodata start:0x80279920 end:0x80279930 -dolphin/pad/src/Pad.c: +dolphin/pad/Pad.c: .text start:0x801D7CA4 end:0x801D9774 .data start:0x802B6530 end:0x802B6588 .bss start:0x8037EAD0 end:0x8037EB20 .sdata start:0x803CAF68 end:0x803CAF88 .sbss start:0x803CC5E0 end:0x803CC608 -dolphin/si/src/SIBios.c: +dolphin/si/SIBios.c: .text start:0x801D9774 end:0x801DAE64 .data start:0x802B6588 end:0x802B66A0 .bss start:0x8037EB20 end:0x8037ED20 .sdata start:0x803CAF88 end:0x803CAF90 .sbss start:0x803CC608 end:0x803CC618 -dolphin/si/src/SISamplingRate.c: +dolphin/si/SISamplingRate.c: .text start:0x801DAE64 end:0x801DAF6C .data start:0x802B66A0 end:0x802B6738 .sbss start:0x803CC618 end:0x803CC620 -dolphin/vi/src/vi.c: +dolphin/vi/vi.c: .text start:0x801DAF6C end:0x801DCD7C .data start:0x802B6738 end:0x802B6B08 .bss start:0x8037ED20 end:0x8037EE68 .sdata start:0x803CAF90 end:0x803CAFA0 .sbss start:0x803CC620 end:0x803CC680 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/abort_exit.c: +MSL_C/PPC_EABI/abort_exit.c: .text start:0x801DCD7C end:0x801DCF08 .bss start:0x8037EE68 end:0x8037EF68 .sbss start:0x803CC680 end:0x803CC690 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/alloc.c: +MSL_C/MSL_Common/alloc.c: .text start:0x801DCF08 end:0x801DE534 .rodata start:0x80279930 end:0x80279948 .bss start:0x8037EF68 end:0x8037EFA0 .sbss start:0x803CC690 end:0x803CC698 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/errno.c: +MSL_C/MSL_Common/errno.c: .sbss start:0x803CC698 end:0x803CC6A0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/ansi_files.c: +MSL_C/MSL_Common/ansi_files.c: .text start:0x801DE534 end:0x801DE844 .data start:0x802B6B08 end:0x802B6C48 .bss start:0x8037EFA0 end:0x8037F2A0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Src/ansi_fp.c: +MSL_C/MSL_Common_Embedded/ansi_fp.c: .text start:0x801DE844 end:0x801E1E20 .rodata start:0x80279948 end:0x80279A28 .data start:0x802B6C48 end:0x802B6DB0 .sdata2 start:0x803CFD88 end:0x803CFDB8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/arith.c: +MSL_C/MSL_Common/arith.c: .text start:0x801E1E20 end:0x801E1E30 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/buffer_io.c: +MSL_C/MSL_Common/buffer_io.c: .text start:0x801E1E30 end:0x801E215C PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/char_io.c: .text start:0x801E215C end:0x801E25FC -PowerPC_EABI_Support/MSL/MSL_C/PPC_EABI/SRC/critical_regions.gamecube.c: +MSL_C/PPC_EABI/critical_regions.gamecube.c: .text start:0x801E25FC end:0x801E2608 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/ctype.c: +MSL_C/MSL_Common/ctype.c: .text start:0x801E2608 end:0x801E2644 .data start:0x802B6DB0 end:0x802B70B0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/locale.c: +MSL_C/MSL_Common/locale.c: .rodata start:0x80279A28 end:0x80279A30 .data start:0x802B70B0 end:0x802B70E8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/direct_io.c: +MSL_C/MSL_Common/direct_io.c: .text start:0x801E2644 end:0x801E2D98 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/file_io.c: +MSL_C/MSL_Common/file_io.c: .text start:0x801E2D98 end:0x801E3458 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/FILE_POS.C: +MSL_C/MSL_Common/FILE_POS.C: .text start:0x801E3458 end:0x801E37A8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mbstring.c: +MSL_C/MSL_Common/mbstring.c: .text start:0x801E37A8 end:0x801E3ACC .sdata2 start:0x803CFDB8 end:0x803CFDC0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mem.c: +MSL_C/MSL_Common/mem.c: .text start:0x801E3ACC end:0x801E3C3C -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mem_funcs.c: +MSL_C/MSL_Common/mem_funcs.c: .text start:0x801E3C3C end:0x801E3F0C -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/misc_io.c: +MSL_C/MSL_Common/misc_io.c: .text start:0x801E3F0C end:0x801E3F34 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/printf.c: +MSL_C/MSL_Common/printf.c: .text start:0x801E3F34 end:0x801E6074 .rodata start:0x80279A30 end:0x80279A58 .data start:0x802B70E8 end:0x802B7318 .sdata start:0x803CAFA0 end:0x803CAFA8 .sdata2 start:0x803CFDC0 end:0x803CFDC8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/qsort.c: +MSL_C/MSL_Common/qsort.c: .text start:0x801E6074 end:0x801E61E0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/rand.c: +MSL_C/MSL_Common/rand.c: .text start:0x801E61E0 end:0x801E6200 .sdata start:0x803CAFA8 end:0x803CAFB0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/scanf.c: +MSL_C/MSL_Common/scanf.c: .text start:0x801E6200 end:0x801E7248 .rodata start:0x80279A58 end:0x80279A80 .data start:0x802B7318 end:0x802B73E8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/signal.c: +MSL_C/MSL_Common/signal.c: .text start:0x801E7248 end:0x801E7308 .bss start:0x8037F2A0 end:0x8037F2B8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/string.c: +MSL_C/MSL_Common/string.c: .text start:0x801E7308 end:0x801E77D4 .rodata start:0x80279A80 end:0x80279E10 .sdata start:0x803CAFB0 end:0x803CAFB8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/float.c: +MSL_C/MSL_Common/float.c: .sdata start:0x803CAFB8 end:0x803CAFE8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/strtold.c: +MSL_C/MSL_Common/strtold.c: .text start:0x801E77D4 end:0x801E886C .rodata start:0x80279E10 end:0x80279E48 .sdata2 start:0x803CFDC8 end:0x803CFDE0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/strtoul.c: +MSL_C/MSL_Common/strtoul.c: .text start:0x801E886C end:0x801E90B0 .data start:0x802B73E8 end:0x802B7470 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Src/uart_console_io.c: +MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c: .text start:0x801E90B0 end:0x801E917C .sbss start:0x803CC6A0 end:0x803CC6A8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/wchar_io.c: +MSL_C/MSL_Common/wchar_io.c: .text start:0x801E917C end:0x801E9204 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c: .text start:0x801E9204 end:0x801E9514 .sdata2 start:0x803CFDE0 end:0x803CFE70 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c: .text start:0x801E9514 end:0x801E9778 .sdata2 start:0x803CFE70 end:0x803CFF08 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c: .text start:0x801E9778 end:0x801E9A08 .sdata2 start:0x803CFF08 end:0x803CFF60 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c: .text start:0x801E9A08 end:0x801E9C2C .rodata start:0x80279E48 end:0x80279E78 .sdata2 start:0x803CFF60 end:0x803CFFD8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c: .text start:0x801E9C2C end:0x801E9F68 .rodata start:0x80279E78 end:0x80279E88 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c: .text start:0x801E9F68 end:0x801EA1E4 .sbss start:0x803CC6A8 end:0x803CC6B0 .sdata2 start:0x803CFFD8 end:0x803D0058 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c: .text start:0x801EA1E4 end:0x801EAA98 .rodata start:0x80279E88 end:0x80279EB8 .sdata2 start:0x803D0058 end:0x803D0168 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c: .text start:0x801EAA98 end:0x801EAE38 .rodata start:0x80279EB8 end:0x8027A040 .sdata2 start:0x803D0168 end:0x803D01C0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c: .text start:0x801EAE38 end:0x801EAF2C .sdata2 start:0x803D01C0 end:0x803D0208 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c: .text start:0x801EAF2C end:0x801EBD80 .rodata start:0x8027A040 end:0x8027A090 .sdata2 start:0x803D0208 end:0x803D0248 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c: .text start:0x801EBD80 end:0x801EBE20 .sdata2 start:0x803D0248 end:0x803D0280 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c: .text start:0x801EBE20 end:0x801EC034 .rodata start:0x8027A090 end:0x8027A0F8 .sdata2 start:0x803D0280 end:0x803D02B8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c: .text start:0x801EC034 end:0x801EC24C .rodata start:0x8027A0F8 end:0x8027A190 .sdata2 start:0x803D02B8 end:0x803D02E0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c: .text start:0x801EC24C end:0x801EC390 .sdata2 start:0x803D02E0 end:0x803D02F0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c: .text start:0x801EC390 end:0x801EC3B8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c: .text start:0x801EC3B8 end:0x801EC48C .sdata2 start:0x803D02F0 end:0x803D02F8 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c: .text start:0x801EC48C end:0x801EC5D4 .sdata2 start:0x803D02F8 end:0x803D0308 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c: .text start:0x801EC5D4 end:0x801EC660 .sdata2 start:0x803D0308 end:0x803D0310 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c: .text start:0x801EC660 end:0x801EC824 .sdata2 start:0x803D0310 end:0x803D0338 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c: .text start:0x801EC824 end:0x801EC920 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c: .text start:0x801EC920 end:0x801EC9F8 .sdata2 start:0x803D0338 end:0x803D0340 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c: .text start:0x801EC9F8 end:0x801ECA70 .sdata2 start:0x803D0340 end:0x803D0348 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_acos.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/w_acos.c: .text start:0x801ECA70 end:0x801ECA90 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c: .text start:0x801ECA90 end:0x801ECAB0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c: .text start:0x801ECAB0 end:0x801ECAD0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c: .text start:0x801ECAD0 end:0x801ECAF0 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c: .text start:0x801ECAF0 end:0x801ECB10 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log.c: .text start:0x801ECB10 end:0x801ECB30 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c: +MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c: .text start:0x801ECB30 end:0x801ECB50 -PowerPC_EABI_Support/MSL/MSL_C/PPC_EABI/SRC/math_ppc.c: +MSL_C/PPC_EABI/math_ppc.c: .text start:0x801ECB50 end:0x801ECC44 -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/extras.c: +MSL_C/MSL_Common/extras.c: .text start:0x801ECC44 end:0x801ECD5C -PowerPC_EABI_Support/Runtime/Src/__va_arg.c: +Runtime/__va_arg.c: .text start:0x801ECD5C end:0x801ECE24 -PowerPC_EABI_Support/Runtime/Src/global_destructor_chain.c: +Runtime/global_destructor_chain.c: .text start:0x801ECE24 end:0x801ECE6C .dtors start:0x80251D48 end:0x80251D4C .sbss start:0x803CC6B0 end:0x803CC6B8 -PowerPC_EABI_Support/Runtime/Src/CPlusLibPPC.cp: +Runtime/CPlusLibPPC.cp: .text start:0x801ECE6C end:0x801ECE9C -PowerPC_EABI_Support/Runtime/Src/New.cp: +Runtime/New.cp: extab start:0x800056E0 end:0x80005730 extabindex start:0x80005800 end:0x80005818 .text start:0x801ECE9C end:0x801ECF68 @@ -3126,23 +3126,23 @@ PowerPC_EABI_Support/Runtime/Src/New.cp: .data start:0x802B7470 end:0x802B7480 .sdata start:0x803CAFE8 end:0x803CAFF0 -PowerPC_EABI_Support/Runtime/Src/NMWException.cp: +Runtime/NMWException.cp: extab start:0x80005730 end:0x80005770 extabindex start:0x80005818 end:0x80005860 .text start:0x801ECF68 end:0x801ED3DC .sdata start:0x803CAFF0 end:0x803CAFF8 -PowerPC_EABI_Support/Runtime/Src/runtime.c: +Runtime/runtime.c: .text start:0x801ED3DC end:0x801EDB6C .rodata start:0x8027A1B0 end:0x8027A1C8 -PowerPC_EABI_Support/Runtime/Src/__init_cpp_exceptions.cpp: +Runtime/__init_cpp_exceptions.cpp: .text start:0x801EDB6C end:0x801EDBE8 .ctors start:0x80251D00 end:0x80251D04 .dtors start:0x80251D40 end:0x80251D48 .sdata start:0x803CAFF8 end:0x803CB000 -PowerPC_EABI_Support/Runtime/Src/Gecko_ExceptionPPC.cp: +Runtime/Gecko_ExceptionPPC.cp: extab start:0x80005770 end:0x800057E4 extabindex start:0x80005860 end:0x800058B4 .text start:0x801EDBE8 end:0x801EF020 @@ -3151,108 +3151,108 @@ PowerPC_EABI_Support/Runtime/Src/Gecko_ExceptionPPC.cp: .bss start:0x8037F2B8 end:0x8037F2C8 .sdata start:0x803CB000 end:0x803CB010 -PowerPC_EABI_Support/Runtime/Src/GCN_mem_alloc.c: +Runtime/GCN_mem_alloc.c: .text start:0x801EF020 end:0x801EF190 .rodata start:0x8027A260 end:0x8027A2D8 -TRK_MINNOW_DOLPHIN/Portable/mainloop.c: +debugger/embedded/MetroTRK/Portable/mainloop.c: .text start:0x801EF190 end:0x801EF288 -TRK_MINNOW_DOLPHIN/Portable/nubevent.c: +debugger/embedded/MetroTRK/Portable/nubevent.c: .text start:0x801EF288 end:0x801EF4B0 .bss start:0x8037F2C8 end:0x8037F2F0 -TRK_MINNOW_DOLPHIN/Portable/nubinit.c: +debugger/embedded/MetroTRK/Portable/nubinit.c: .text start:0x801EF4B0 end:0x801EF634 .rodata start:0x8027A2D8 end:0x8027A2F8 .bss start:0x8037F2F0 end:0x8037F2F8 -TRK_MINNOW_DOLPHIN/Portable/msg.c: +debugger/embedded/MetroTRK/Portable/msg.c: .text start:0x801EF634 end:0x801EF810 -TRK_MINNOW_DOLPHIN/Portable/msgbuf.c: +debugger/embedded/MetroTRK/Portable/msgbuf.c: .text start:0x801EF810 end:0x801F03EC .rodata start:0x8027A2F8 end:0x8027A318 .bss start:0x8037F2F8 end:0x80380CA8 -TRK_MINNOW_DOLPHIN/Portable/serpoll.c: +debugger/embedded/MetroTRK/Portable/serpoll.c: .text start:0x801F03EC end:0x801F07B8 .bss start:0x80380CA8 end:0x80380CC0 -TRK_MINNOW_DOLPHIN/Portable/usr_put.c: +debugger/embedded/MetroTRK/Os/dolphin/usr_put.c: .text start:0x801F07B8 end:0x801F0844 -TRK_MINNOW_DOLPHIN/Portable/dispatch.c: +debugger/embedded/MetroTRK/Portable/dispatch.c: .text start:0x801F0844 end:0x801F08E0 .data start:0x802B7568 end:0x802B75F0 .bss start:0x80380CC0 end:0x80380CC8 -TRK_MINNOW_DOLPHIN/Portable/msghndlr.c: +debugger/embedded/MetroTRK/Portable/msghndlr.c: .text start:0x801F08E0 end:0x801F3140 .data start:0x802B75F0 end:0x802B7628 .bss start:0x80380CC8 end:0x80380CD0 -TRK_MINNOW_DOLPHIN/Portable/support.c: +debugger/embedded/MetroTRK/Portable/support.c: .text start:0x801F3140 end:0x801F3A00 -TRK_MINNOW_DOLPHIN/Portable/mutex_TRK.c: +debugger/embedded/MetroTRK/Portable/mutex_TRK.c: .text start:0x801F3A00 end:0x801F3A18 -TRK_MINNOW_DOLPHIN/Portable/notify.c: +debugger/embedded/MetroTRK/Portable/notify.c: .text start:0x801F3A18 end:0x801F3AF0 -TRK_MINNOW_DOLPHIN/ppc/Generic/flush_cache.c: +debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c: .text start:0x801F3AF0 end:0x801F3B28 -PowerPC_EABI_Support/Runtime/Src/__mem.c: +Runtime/__mem.c: .init start:0x80003458 end:0x80003590 -TRK_MINNOW_DOLPHIN/Portable/mem_TRK.c: +debugger/embedded/MetroTRK/Portable/mem_TRK.c: .init start:0x80003590 end:0x800035E4 .text start:0x801F3B28 end:0x801F3BE0 -TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.c: +debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c: .text start:0x801F3BE0 end:0x801F5760 .rodata start:0x8027A318 end:0x8027A3A0 .data start:0x802B7628 end:0x802B7658 .bss start:0x80380CD0 end:0x80381250 -TRK_MINNOW_DOLPHIN/ppc/Export/targsupp.s: comment:0 +debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s: comment:0 .text start:0x801F5760 end:0x801F5780 -TRK_MINNOW_DOLPHIN/ppc/Generic/__exception.s: comment:0 +debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s: comment:0 .init start:0x800035E4 end:0x80005518 -TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk.c: +debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c: .init start:0x80005518 end:0x8000563C .text start:0x801F5780 end:0x801F58D8 .data start:0x802B7658 end:0x802B7698 .bss start:0x80381250 end:0x80381258 -TRK_MINNOW_DOLPHIN/ppc/Generic/mpc_7xx_603e.c: +debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c: .text start:0x801F58D8 end:0x801F5C50 -TRK_MINNOW_DOLPHIN/Portable/main_TRK.c: +debugger/embedded/MetroTRK/Portable/main_TRK.c: .text start:0x801F5C50 end:0x801F5C94 .bss start:0x80381258 end:0x80381260 -TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk_glue.c: +debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c: .text start:0x801F5C94 end:0x801F61A4 .rodata start:0x8027A3A0 end:0x8027A3F0 .data start:0x802B7698 end:0x802B76B8 .bss start:0x80381260 end:0x80383488 -TRK_MINNOW_DOLPHIN/Os/dolphin/targcont.c: +debugger/embedded/MetroTRK/Os/dolphin/targcont.c: .text start:0x801F61A4 end:0x801F61D8 -TRK_MINNOW_DOLPHIN/Os/dolphin/target_options.c: +debugger/embedded/MetroTRK/Os/dolphin/target_options.c: .text start:0x801F61D8 end:0x801F61F4 .bss start:0x80383488 end:0x80383490 -TRK_MINNOW_DOLPHIN/MetroTRK/Export/mslsupp.c: +debugger/embedded/MetroTRK/Export/mslsupp.c: .text start:0x801F61F4 end:0x801F6790 -OdemuExi2/DebuggerDriver.c: +dolphin/OdemuExi2/DebuggerDriver.c: .text start:0x801F6790 end:0x801F7210 .sdata start:0x803CB010 end:0x803CB018 .sbss start:0x803CC6B8 end:0x803CC6D0 diff --git a/configure.py b/configure.py index f3f11d844..9350e48da 100644 --- a/configure.py +++ b/configure.py @@ -159,7 +159,7 @@ "-I include", f"-I build/{config.version}/include", f"--defsym BUILD_VERSION={version_num}", - f"--defsym VERSION_{config.version}", + f"--defsym VERSION_={config.version}", ] config.ldflags = [ "-fp hardware", @@ -200,6 +200,9 @@ "-str reuse", "-multibyte", # For Wii compilers, replace with `-enc SJIS` "-i include", + "-i libs/PowerPC_EABI_Support/include", + "-i include/dolphin", + "-i libs", f"-i build/{config.version}/include", f"-DBUILD_VERSION={version_num}", f"-DVERSION_{config.version}", @@ -222,6 +225,19 @@ "-inline auto", ] +# dolphin library flags +cflags_dolphin = [ + *cflags_base, + "-lang=c", + "-fp fmadd", + "-fp_contract off", + "-char signed", + "-str reuse", + "-common off", + "-O4,p", + #"-requireprotos" +] + # REL flags cflags_rel = [ *cflags_base, @@ -232,6 +248,7 @@ # Game-specific flags cflags_bfbb = [ *cflags_base, + "-lang=C++", "-common on", "-char unsigned", "-str reuse,pool,readonly", @@ -240,8 +257,6 @@ "-inline off", "-gccinc", "-i include/bink", - "-i include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include", - "-i include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include", "-i include/inline", "-i include/rwsdk", "-i src/SB/Core/gc", @@ -257,12 +272,36 @@ def DolphinLib(lib_name: str, objects: List[Object]) -> Dict[str, Any]: return { "lib": lib_name, + "src_dir": "libs", "mw_version": "GC/1.2.5n", - "cflags": cflags_base, + "cflags": cflags_dolphin, "progress_category": "sdk", + "host": True, + "objects": objects, + } + +# Helper function for MSL libraries +def mslLib(lib_name: str, extra_cflags: List[str], objects: List[Object]) -> Dict[str, Any]: + return { + "lib": lib_name, + "src_dir": "libs/PowerPC_EABI_Support/src", + "mw_version": "GC/2.6", + "cflags": cflags_runtime + extra_cflags, + "progress_category": "msl", + "host": True, "objects": objects, } +def trkLib(lib_name: str, objects: List[Object]) -> Dict[str, Any]: + return { + "lib": lib_name, + "src_dir": "libs/runtime_libs", + "mw_version": "GC/2.6", + "cflags": cflags_runtime, + "progress_category": "msl", + "host": True, + "objects": objects, + } # Helper function for RenderWare libraries def RenderWareLib(lib_name: str, objects: List[Object]) -> Dict[str, Any]: @@ -270,7 +309,7 @@ def RenderWareLib(lib_name: str, objects: List[Object]) -> Dict[str, Any]: "lib": lib_name, "mw_version": "GC/1.3.2", "cflags": cflags_base, - "progress_category": "sdk", + "progress_category": "RW", "objects": objects, } @@ -557,296 +596,404 @@ def MatchingFor(*versions): DolphinLib( "ai", [ - Object(NonMatching, "dolphin/ai/src/ai.c"), + Object(Matching, "dolphin/ai/ai.c"), ], ), DolphinLib( "amcstubs", [ - Object(NonMatching, "dolphin/amcstubs/src/AmcExi2Stubs.c"), + Object(Matching, "dolphin/amcstubs/AmcExi2Stubs.c"), ], ), DolphinLib( "ar", [ - Object(NonMatching, "dolphin/ar/src/ar.c"), - Object(NonMatching, "dolphin/ar/src/arq.c"), - ], + Object(NonMatching, "dolphin/ar/ar.c"), + Object(Matching, "dolphin/ar/arq.c") + ] ), DolphinLib( "ax", [ - Object(NonMatching, "dolphin/ax/src/AX.c"), - Object(NonMatching, "dolphin/ax/src/AXAlloc.c"), - Object(NonMatching, "dolphin/ax/src/AXAux.c"), - Object(NonMatching, "dolphin/ax/src/AXCL.c"), - Object(NonMatching, "dolphin/ax/src/AXOut.c"), - Object(NonMatching, "dolphin/ax/src/AXSPB.c"), - Object(NonMatching, "dolphin/ax/src/AXVPB.c"), - Object(NonMatching, "dolphin/ax/src/AXComp.c"), - Object(NonMatching, "dolphin/ax/src/DSPCode.c"), - Object(NonMatching, "dolphin/ax/src/AXProf.c"), + Object(Matching, "dolphin/ax/AX.c"), + Object(NonMatching, "dolphin/ax/AXAlloc.c"), + Object(Matching, "dolphin/ax/AXAux.c"), + Object(NonMatching, "dolphin/ax/AXCL.c"), + Object(NonMatching, "dolphin/ax/AXOut.c"), + Object(NonMatching, "dolphin/ax/AXSPB.c"), + Object(NonMatching, "dolphin/ax/AXVPB.c"), + Object(Matching, "dolphin/ax/AXComp.c"), + Object(NonMatching, "dolphin/ax/DSPCode.c"), + Object(Matching, "dolphin/ax/AXProf.c"), ], ), DolphinLib( "base", [ - Object(NonMatching, "dolphin/base/src/PPCArch.c"), - ], + # Needs a lot of Extended ASM work + # Object(NonMatching, "dolphin/base/PPCArch.c") + ] ), DolphinLib( "card", [ - Object(NonMatching, "dolphin/card/src/CARDBios.c"), - Object(NonMatching, "dolphin/card/src/CARDUnlock.c"), - Object(NonMatching, "dolphin/card/src/CARDRdwr.c"), - Object(NonMatching, "dolphin/card/src/CARDBlock.c"), - Object(NonMatching, "dolphin/card/src/CARDDir.c"), - Object(NonMatching, "dolphin/card/src/CARDCheck.c"), - Object(NonMatching, "dolphin/card/src/CARDMount.c"), - Object(NonMatching, "dolphin/card/src/CARDFormat.c"), - Object(NonMatching, "dolphin/card/src/CARDOpen.c"), - Object(NonMatching, "dolphin/card/src/CARDCreate.c"), - Object(NonMatching, "dolphin/card/src/CARDRead.c"), - Object(NonMatching, "dolphin/card/src/CARDWrite.c"), - Object(NonMatching, "dolphin/card/src/CARDDelete.c"), - Object(NonMatching, "dolphin/card/src/CARDStat.c"), - Object(NonMatching, "dolphin/card/src/CARDStatEx.c"), - Object(NonMatching, "dolphin/card/src/CARDNet.c"), - ], + Object(NonMatching, "dolphin/card/CARDBios.c"), + Object(NonMatching, "dolphin/card/CARDUnlock.c"), + Object(Matching, "dolphin/card/CARDRdwr.c"), + Object(Matching, "dolphin/card/CARDBlock.c"), + Object(Matching, "dolphin/card/CARDDir.c"), + Object(Matching, "dolphin/card/CARDCheck.c"), + Object(Matching, "dolphin/card/CARDMount.c"), + Object(Matching, "dolphin/card/CARDFormat.c"), + Object(Matching, "dolphin/card/CARDOpen.c"), + Object(Matching, "dolphin/card/CARDCreate.c"), + Object(Matching, "dolphin/card/CARDRead.c"), + Object(Matching, "dolphin/card/CARDWrite.c"), + Object(Matching, "dolphin/card/CARDDelete.c"), + Object(Matching, "dolphin/card/CARDStat.c"), + Object(Matching,"dolphin/card/CARDStatEx.c"), + Object(NonMatching, "dolphin/card/CARDNet.c"), + ] ), DolphinLib( "db", [ - Object(NonMatching, "dolphin/db/src/db.c"), - ], + Object(Matching, "dolphin/db/db.c"), + ] ), DolphinLib( "dsp", [ - Object(NonMatching, "dolphin/dsp/src/dsp.c"), - Object(NonMatching, "dolphin/dsp/src/dsp_debug.c"), - Object(NonMatching, "dolphin/dsp/src/dsp_task.c"), - ], + Object(NonMatching, "dolphin/dsp/dsp.c"), + Object(Matching, "dolphin/dsp/dsp_debug.c"), + Object(NonMatching, "dolphin/dsp/dsp_task.c") + ] ), DolphinLib( "dvd", [ - Object(NonMatching, "dolphin/dvd/src/dvdlow.c"), - Object(NonMatching, "dolphin/dvd/src/dvdfs.c"), - Object(NonMatching, "dolphin/dvd/src/dvd.c"), - Object(NonMatching, "dolphin/dvd/src/dvdqueue.c"), - Object(NonMatching, "dolphin/dvd/src/dvderror.c"), - Object(NonMatching, "dolphin/dvd/src/dvdidutils.c"), - Object(NonMatching, "dolphin/dvd/src/dvdFatal.c"), - Object(NonMatching, "dolphin/dvd/src/emu_level2/fstload.c"), + Object(NonMatching, "dolphin/dvd/dvdlow.c"), + Object(NonMatching, "dolphin/dvd/dvdfs.c"), + Object(NonMatching, "dolphin/dvd/dvd.c"), + Object(NonMatching, "dolphin/dvd/dvdqueue.c"), + Object(NonMatching, "dolphin/dvd/dvderror.c"), + Object(Matching, "dolphin/dvd/dvdidutils.c"), + Object(NonMatching, "dolphin/dvd/dvdFatal.c"), + Object(NonMatching, "dolphin/dvd/emu_level2/fstload.c"), ], ), + DolphinLib( + "eth", + [ + Object(Matching, "dolphin/eth/eth.c"), + Object(Matching, "dolphin/eth/ethsec.c"), + Object(Matching, "dolphin/eth/md5.c"), + Object(Matching, "dolphin/eth/base64.c") + ] + ), DolphinLib( "exi", [ - Object(NonMatching, "dolphin/exi/src/EXIBios.c"), - Object(NonMatching, "dolphin/exi/src/EXIUart.c"), - ], + Object(NonMatching, "dolphin/exi/EXIBios.c"), + Object(NonMatching, "dolphin/exi/EXIUart.c") + ] + ), + DolphinLib( + "gd", + [ + Object(NonMatching, "dolphin/gd/GDBase.c"), + Object(NonMatching, "dolphin/gd/GDGeometry.c") + ] ), DolphinLib( "gx", [ - Object(NonMatching, "dolphin/gx/src/GXInit.c"), - Object(NonMatching, "dolphin/gx/src/GXFifo.c"), - Object(NonMatching, "dolphin/gx/src/GXAttr.c"), - Object(NonMatching, "dolphin/gx/src/GXMisc.c"), - Object(NonMatching, "dolphin/gx/src/GXGeometry.c"), - Object(NonMatching, "dolphin/gx/src/GXFrameBuf.c"), - Object(NonMatching, "dolphin/gx/src/GXLight.c"), - Object(NonMatching, "dolphin/gx/src/GXTexture.c"), - Object(NonMatching, "dolphin/gx/src/GXBump.c"), - Object(NonMatching, "dolphin/gx/src/GXTev.c"), - Object(NonMatching, "dolphin/gx/src/GXPixel.c"), - Object(NonMatching, "dolphin/gx/src/GXDisplayList.c"), - Object(NonMatching, "dolphin/gx/src/GXTransform.c"), - Object(NonMatching, "dolphin/gx/src/GXPerf.c"), - ], + Object(NonMatching, "dolphin/gx/GXInit.c"), + Object(NonMatching, "dolphin/gx/GXFifo.c"), + Object(NonMatching, "dolphin/gx/GXAttr.c"), + Object(NonMatching, "dolphin/gx/GXMisc.c"), + Object(NonMatching, "dolphin/gx/GXGeometry.c"), + Object(NonMatching, "dolphin/gx/GXFrameBuf.c"), + Object(NonMatching, "dolphin/gx/GXLight.c"), + Object(NonMatching, "dolphin/gx/GXTexture.c"), + Object(NonMatching, "dolphin/gx/GXBump.c"), + Object(NonMatching, "dolphin/gx/GXTev.c"), + Object(NonMatching, "dolphin/gx/GXPixel.c"), + Object(NonMatching, "dolphin/gx/GXDraw.c"), + Object(NonMatching, "dolphin/gx/GXDisplayList.c"), + Object(NonMatching, "dolphin/gx/GXTransform.c"), + Object(NonMatching, "dolphin/gx/GXPerf.c") + ] + ), + DolphinLib( + "hio", + [ + Object(NonMatching, "dolphin/hio/hio.c") + ] + ), + DolphinLib( + "ip", + [ + Object(NonMatching, "dolphin/ip/IP.c"), + Object(NonMatching, "dolphin/ip/IPArp.c"), + Object(NonMatching, "dolphin/ip/IPIcmp.c"), + Object(NonMatching, "dolphin/ip/IPRoute.c"), + Object(NonMatching, "dolphin/ip/IPUdp.c"), + Object(NonMatching, "dolphin/ip/IPFrag.c"), + Object(NonMatching, "dolphin/ip/IPEther.c"), + Object(NonMatching, "dolphin/ip/IFFifo.c"), + Object(NonMatching, "dolphin/ip/IFRing.c"), + Object(NonMatching, "dolphin/ip/IPTcp.c"), + Object(NonMatching, "dolphin/ip/IPTcpOutput.c"), + Object(NonMatching, "dolphin/ip/IPTcpTimer.c"), + Object(NonMatching, "dolphin/ip/IPTcpUser.c"), + Object(NonMatching, "dolphin/ip/IPTcpTimeWait.c"), + Object(NonMatching, "dolphin/ip/IPDns.c"), + Object(NonMatching, "dolphin/ip/IPDhcp.c"), + Object(NonMatching, "dolphin/ip/IPZero.c"), + Object(NonMatching, "dolphin/ip/IPOpt.c"), + Object(NonMatching, "dolphin/ip/IPSocket.c"), + Object(NonMatching, "dolphin/ip/IPPPP.c"), + Object(NonMatching, "dolphin/ip/IPPPPoE.c"), + Object(NonMatching, "dolphin/ip/IPLcp.c"), + Object(NonMatching, "dolphin/ip/IPIpcp.c"), + Object(NonMatching, "dolphin/ip/IPPap.c"), + Object(NonMatching, "dolphin/ip/IPChap.c"), + Object(NonMatching, "dolphin/ip/IPIgmp.c"), + Object(NonMatching, "dolphin/ip/IPUuid.c") + ] + ), + DolphinLib( + "lg", # unofficial name + [ + Object(NonMatching, "dolphin/lg/allsrc.c") + ] ), DolphinLib( "mtx", [ - Object(NonMatching, "dolphin/mtx/src/mtx.c"), - Object(NonMatching, "dolphin/mtx/src/mtx44.c"), - ], + Object(NonMatching, "dolphin/mtx/mtx.c"), + Object(NonMatching, "dolphin/mtx/mtxvec.c"), + Object(NonMatching, "dolphin/mtx/mtx44.c"), + Object(Matching, "dolphin/mtx/mtx44vec.c"), + Object(Matching, "dolphin/mtx/vec.c"), + Object(NonMatching, "dolphin/mtx/quat.c"), + ] + ), + DolphinLib( + "OdemuExi2", + [ + Object(NonMatching, "dolphin/OdemuExi2/DebuggerDriver.c") + ] ), DolphinLib( "odenotstub", [ - Object(NonMatching, "dolphin/odenotstub/src/odenotstub.c"), - ], + Object(NonMatching, "dolphin/odenotstub/odenotstub.c") + ] ), DolphinLib( "os", [ - Object(NonMatching, "dolphin/os/src/OS.c"), - Object(NonMatching, "dolphin/os/src/OSAlarm.c"), - Object(NonMatching, "dolphin/os/src/OSAlloc.c"), - Object(NonMatching, "dolphin/os/src/OSArena.c"), - Object(NonMatching, "dolphin/os/src/OSAudioSystem.c"), - Object(NonMatching, "dolphin/os/src/OSCache.c"), - Object(NonMatching, "dolphin/os/src/OSContext.c"), - Object(NonMatching, "dolphin/os/src/OSError.c"), - Object(NonMatching, "dolphin/os/src/OSFont.c"), - Object(NonMatching, "dolphin/os/src/OSInterrupt.c"), - Object(NonMatching, "dolphin/os/src/OSLink.c"), - Object(NonMatching, "dolphin/os/src/OSMemory.c"), - Object(NonMatching, "dolphin/os/src/OSMutex.c"), - Object(NonMatching, "dolphin/os/src/OSReboot.c"), - Object(NonMatching, "dolphin/os/src/OSReset.c"), - Object(NonMatching, "dolphin/os/src/OSResetSW.c"), - Object(NonMatching, "dolphin/os/src/OSRtc.c"), - Object(NonMatching, "dolphin/os/src/OSSync.c"), - Object(NonMatching, "dolphin/os/src/OSThread.c"), - Object(NonMatching, "dolphin/os/src/OSTime.c"), - Object(NonMatching, "dolphin/os/src/init/__start.c"), - Object(NonMatching, "dolphin/os/src/init/__ppc_eabi_init.cpp"), - ], + Object(NonMatching, "dolphin/os/OS.c"), + Object(NonMatching, "dolphin/os/OSAlarm.c"), + Object(NonMatching, "dolphin/os/OSAlloc.c"), + Object(NonMatching, "dolphin/os/OSArena.c"), + Object(Matching, "dolphin/os/OSAudioSystem.c"), + Object(NonMatching, "dolphin/os/OSCache.c"), + Object(NonMatching, "dolphin/os/OSContext.c"), + Object(NonMatching, "dolphin/os/OSError.c"), + Object(NonMatching, "dolphin/os/OSFont.c"), + Object(NonMatching, "dolphin/os/OSInterrupt.c"), + Object(NonMatching, "dolphin/os/OSLink.c"), + Object(NonMatching, "dolphin/os/OSMessage.c"), + Object(NonMatching, "dolphin/os/OSMemory.c"), + Object(NonMatching, "dolphin/os/OSMutex.c"), + Object(Matching, "dolphin/os/OSReboot.c"), + Object(NonMatching, "dolphin/os/OSReset.c"), + Object(NonMatching, "dolphin/os/OSResetSW.c"), + Object(NonMatching, "dolphin/os/OSRtc.c"), + Object(NonMatching, "dolphin/os/OSThread.c"), + Object(NonMatching, "dolphin/os/OSTime.c"), + Object(NonMatching, "dolphin/os/OSSync.c"), + Object(NonMatching, "dolphin/os/init/__start.c"), + Object(NonMatching, "dolphin/os/init/__ppc_eabi_init.cpp") + ] ), DolphinLib( "pad", [ - Object(NonMatching, "dolphin/pad/src/Padclamp.c"), - Object(NonMatching, "dolphin/pad/src/Pad.c"), - ], + Object(NonMatching, "dolphin/pad/Padclamp.c"), + Object(NonMatching, "dolphin/pad/Pad.c") + ] ), DolphinLib( "si", [ - Object(NonMatching, "dolphin/si/src/SIBios.c"), - Object(NonMatching, "dolphin/si/src/SISamplingRate.c"), - ], + Object(NonMatching, "dolphin/si/SIBios.c"), + Object(Matching, "dolphin/si/SISamplingRate.c"), + ] + ), + DolphinLib( + "upnp", + [ + Object(NonMatching, "dolphin/upnp/UPnP.c"), + Object(NonMatching, "dolphin/upnp/UPnPHttp.c"), + Object(NonMatching, "dolphin/upnp/UPnPSsdp.c"), + Object(NonMatching, "dolphin/upnp/UPnPUuid.c"), + Object(NonMatching, "dolphin/upnp/UPnPUri.c"), + Object(NonMatching, "dolphin/upnp/UPnPHttpd.c"), + Object(NonMatching, "dolphin/upnp/UPnPHttpdResponse.c") + ] ), DolphinLib( "vi", [ - Object(NonMatching, "dolphin/vi/src/vi.c"), + Object(NonMatching, "dolphin/vi/vi.c"), ], ), - { - "lib": "Runtime.PPCEABI.H", - "mw_version": config.linker_version, - "cflags": cflags_runtime, - "progress_category": "sdk", - "objects": [ - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/__mem.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/abort_exit.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/alloc.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/errno.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/ansi_files.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Src/ansi_fp.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/arith.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/buffer_io.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/char_io.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/PPC_EABI/SRC/critical_regions.gamecube.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/ctype.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/locale.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/direct_io.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/file_io.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/FILE_POS.C"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mbstring.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mem.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/mem_funcs.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/misc_io.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/printf.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/qsort.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/rand.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/scanf.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/signal.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/string.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/float.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/strtold.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/strtoul.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Src/uart_console_io.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/wchar_io.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_acos.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/PPC_EABI/SRC/math_ppc.c"), - Object(NonMatching, "PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/extras.c"), - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/__va_arg.c"), - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/global_destructor_chain.c"), - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/CPlusLibPPC.cp"), - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/New.cp"), - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/NMWException.cp"), - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/runtime.c"), - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/__init_cpp_exceptions.cpp"), - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/Gecko_ExceptionPPC.cp"), - Object(NonMatching, "PowerPC_EABI_Support/Runtime/Src/GCN_mem_alloc.c"), - ], - }, - { - "lib": "TRK_Minnow_Dolphin", - "mw_version": "GC/1.3.2", - "cflags": cflags_runtime, - "progress_category": "sdk", - "objects": [ - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/mainloop.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/nubevent.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/nubinit.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/msg.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/msgbuf.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/serpoll.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/usr_put.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/dispatch.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/msghndlr.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/support.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/mutex_TRK.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/notify.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/ppc/Generic/flush_cache.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/mem_TRK.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/ppc/Export/targsupp.s"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/ppc/Generic/__exception.s"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/ppc/Generic/mpc_7xx_603e.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Portable/main_TRK.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk_glue.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Os/dolphin/targcont.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/Os/dolphin/target_options.c"), - Object(NonMatching, "TRK_MINNOW_DOLPHIN/MetroTRK/Export/mslsupp.c"), - ], - }, - { - "lib": "OdemuExi2", - "mw_version": "GC/1.3.2", - "cflags": cflags_runtime, - "progress_category": "sdk", - "objects": [ - Object(NonMatching, "OdemuExi2/DebuggerDriver.c"), - ], - }, + DolphinLib( + "thp", + [ + Object(Matching, "dolphin/thp/THPDec.c"), + Object(Matching, "dolphin/thp/THPAudio.c") + ] + ), + mslLib( + "Runtime.PPCEABI.H", + [], + [ + Object(NonMatching, "Runtime/__mem.c"), + Object(Matching, "Runtime/__va_arg.c"), + Object(NonMatching, "Runtime/global_destructor_chain.c"), + Object(NonMatching, "Runtime/New.cp"), + Object(NonMatching, "Runtime/NMWException.cp"), + Object(NonMatching, "Runtime/CPlusLibPPC.cp"), + Object(NonMatching, "Runtime/ptmf.c"), + #Object(NonMatching, "Runtime/runtime.c"), + Object(NonMatching, "Runtime/__init_cpp_exceptions.cpp"), + Object(NonMatching, "Runtime/Gecko_ExceptionPPC.cp"), + Object(NonMatching, "Runtime/GCN_mem_alloc.c"), + ] + ), + mslLib( + "MSL_C.PPCEABI.H", + ["-str pool", "-opt level=0, peephole, schedule, nospace", "-inline off", "-sym on"], + [ + Object(NonMatching, "MSL_C/PPC_EABI/abort_exit.c"), + Object(NonMatching, "MSL_C/MSL_Common/alloc.c"), + Object(NonMatching, "MSL_C/MSL_Common/ansi_files.c"), + Object(NonMatching, "MSL_C/MSL_Common_Embedded/ansi_fp.c"), + Object(NonMatching, "MSL_C/MSL_Common/arith.c"), + Object(NonMatching, "MSL_C/MSL_Common/bsearch.c"), + Object(NonMatching, "MSL_C/MSL_Common/buffer_io.c"), + Object(NonMatching, "MSL_C/PPC_EABI/critical_regions.gamecube.c"), + Object(NonMatching, "MSL_C/MSL_Common/ctype.c"), + Object(NonMatching, "MSL_C/MSL_Common/direct_io.c"), + Object(Matching, "MSL_C/MSL_Common/errno.c"), + Object(NonMatching, "MSL_C/MSL_Common/file_io.c"), + Object(NonMatching, "MSL_C/MSL_Common/FILE_POS.C"), + Object(NonMatching, "MSL_C/MSL_Common/locale.c"), + Object(NonMatching, "MSL_C/MSL_Common/mbstring.c"), + Object(NonMatching, "MSL_C/MSL_Common/mem.c"), + Object(NonMatching, "MSL_C/MSL_Common/mem_funcs.c"), + Object(NonMatching, "MSL_C/MSL_Common/misc_io.c"), + Object(NonMatching, "MSL_C/MSL_Common/printf.c"), + Object(NonMatching, "MSL_C/MSL_Common/qsort.c"), + Object(NonMatching, "MSL_C/MSL_Common/rand.c"), + Object(NonMatching, "MSL_C/MSL_Common/scanf.c"), + Object(NonMatching, "MSL_C/MSL_Common/signal.c"), + Object(NonMatching, "MSL_C/MSL_Common/string.c"), + Object(NonMatching, "MSL_C/MSL_Common/strtold.c"), + Object(NonMatching, "MSL_C/MSL_Common/strtoul.c"), + Object(NonMatching, "MSL_C/MSL_Common/float.c"), + # Causes cyclic dependency error + # Object(NonMatching, "MSL_C/MSL_Common/char_io.c"), + Object(NonMatching, "MSL_C/MSL_Common/wchar_io.c"), + Object(NonMatching, "MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c") + ] + ), + mslLib( + "fdlibm.PPCEABI.H", + [], + [ + Object(NonMatching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c"), + Object(NonMatching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c"), + Object(NonMatching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c"), + Object(NonMatching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_acos.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c"), + Object(NonMatching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c"), + Object(NonMatching, "MSL_C/PPC_EABI/math_ppc.c"), + ] + ), + trkLib( + "TRK_MINNOW_DOLPHIN", + [ + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/mainloop.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/nubevent.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/nubassrt.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/nubinit.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msg.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msgbuf.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/serpoll.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/dispatch.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msghndlr.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/support.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/mutex_TRK.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/notify.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/main_TRK.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/mem_TRK.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/string_TRK.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s"), + Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s"), + Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/usr_put.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/targcont.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/target_options.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/UDP_Stubs.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Export/mslsupp.c"), + + Object(NonMatching, "gamedev/cust_connection/cc/exi2/GCN/EXI2_DDH_GCN/main.c"), + Object(NonMatching, "gamedev/cust_connection/utils/common/CircleBuffer.c"), + Object(NonMatching, "gamedev/cust_connection/cc/exi2/GCN/EXI2_GDEV_GCN/main.c"), + Object(NonMatching, "gamedev/cust_connection/utils/common/MWTrace.c"), + Object(NonMatching, "gamedev/cust_connection/utils/gc/MWCriticalSection_gc.cpp"), + ] + ), + mslLib( + "MSL_C.PPCEABI.bare.H", + [], + [ + Object(NonMatching, "MSL_C/MSL_Common/extras.c") + ] + ), RenderWareLib( "rpcollis", [ @@ -1047,6 +1194,8 @@ def link_order_callback(module_id: int, objects: List[str]) -> List[str]: config.progress_categories = [ ProgressCategory("game", "Game Code"), ProgressCategory("sdk", "SDK Code"), + ProgressCategory("msl", "MSL"), + ProgressCategory("RW", "Renderware SDK"), ] config.progress_each_module = args.verbose diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cctype b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cctype deleted file mode 100644 index 4e84d98dd..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cctype +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MSL_CLIMITS -#define _MSL_CLIMITS - -#include - -#endif diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/climits b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/climits deleted file mode 100644 index 2a3cdf3e5..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/climits +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MSL_CLIMITS -#define _MSL_CLIMITS - -#include - -#endif diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdarg b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdarg deleted file mode 100644 index 51ecd3f00..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdarg +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _MSL_CSTDDEF -#define _MSL_CSTDDEF - -#include - -#endif - -#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstddef b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstddef deleted file mode 100644 index 64f3ce007..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstddef +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MSL_CSTDDEF -#define _MSL_CSTDDEF - -#include - -#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctime b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctime deleted file mode 100644 index f7b51a432..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctime +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MSL_CTIME -#define _MSL_CTIME - -#include - -#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctype.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctype.h deleted file mode 100644 index 221e2220d..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/ctype.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _MSL_CTYPE_H -#define _MSL_CTYPE_H - -#ifdef __cplusplus -extern "C" { -#endif - -int isprint(int c); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/limits.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/limits.h deleted file mode 100644 index 530c1ee10..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/limits.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MSL_LIMITS_H -#define _MSL_LIMITS_H - -#define SHRT_MAX 32767 - -#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/math.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/math.h deleted file mode 100644 index f2e4cd41a..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/math.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _MSL_MATH_H -#define _MSL_MATH_H - -#define FP_NAN 1 -#define FP_INFINITE 2 -#define FP_ZERO 3 -#define FP_NORMAL 4 -#define FP_SUBNORMAL 5 - -#define fpclassify(x) \ - ((sizeof(x) == sizeof(float)) ? __fpclassifyf((float)(x)) : __fpclassifyd((double)(x))) - -#define isnormal(x) (fpclassify(x) == FP_NORMAL) -#define isnan(x) (fpclassify(x) == FP_NAN) -#define isinf(x) (fpclassify(x) == FP_INFINITE) -#define isfinite(x) ((fpclassify(x) > FP_INFINITE)) - -#ifdef __cplusplus -extern "C" { -#endif - -int __fpclassifyf(float); -int __fpclassifyd(double); - -double sin(double); -double cos(double); -double tan(double); -double atan2(double, double); -double ceil(double); -double asin(double); -double acos(double); -double exp(double); -double floor(double); -double log(double); -double sqrt(double); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdarg.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdarg.h deleted file mode 100644 index 52d613f5d..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdarg.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MSL_STDARG_H -#define _MSL_STDARG_H - -#include - -#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stddef.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stddef.h deleted file mode 100644 index 934197fdb..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stddef.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MSL_STDDEF_H -#define _MSL_STDDEF_H - -#include - -#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdio.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdio.h deleted file mode 100644 index 5174e1851..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdio.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _MSL_STDIO -#define _MSL_STDIO - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _FILE -{ - U8 pad[0x50]; -} FILE; - -extern FILE __files[4]; - -#define stdin &(__files[0]) -#define stdout &(__files[1]) -#define stderr &(__files[2]) - -int sprintf(char* s, const char* format, ...); -void printf(const char* format, ...); -int fprintf(FILE* stream, const char* format, ...); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h deleted file mode 100644 index 73c45e289..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _MSL_STRING_H -#define _MSL_STRING_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void* memset(void*, int, size_t); -void* memcpy(void*, const void*, size_t); -int memcmp(const void* ptr1, const void* ptr2, size_t num); -size_t strlen(const char*); -char* strcpy(char* dest, const char* source); -char* strncpy(char* dest, const char* source, size_t n); -char* strcat(char* dest, const char* source); -int strcmp(const char* a, const char* b); -int stricmp(const char* a, const char* b); -int strcmpi(const char* a, const char* b); -char* strstr(const char* haystack, const char* needle); -char* strtok(char* str, const char* delimiters); -int atoi(const char* s); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/va_list.h b/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/va_list.h deleted file mode 100644 index 47118e307..000000000 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/va_list.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MSL_VA_LIST_H -#define _MSL_VA_LIST_H - -typedef char* va_list; - -#endif \ No newline at end of file diff --git a/include/bink/bink.h b/include/bink/bink.h index 11dc19a72..4762aafac 100644 --- a/include/bink/bink.h +++ b/include/bink/bink.h @@ -1,7 +1,7 @@ #ifndef __BINK_H__ #define __BINK_H__ -#include +#include #define BINKSURFACE8P 0 #define BINKSURFACE24 1 @@ -80,4 +80,3 @@ extern void BinkClose(HBINK bink); #endif #endif - diff --git a/include/dolphin/CARDPriv.h b/include/dolphin/CARDPriv.h new file mode 100644 index 000000000..8b7adeef6 --- /dev/null +++ b/include/dolphin/CARDPriv.h @@ -0,0 +1,139 @@ +#ifndef _DOLPHIN_CARDPRIV +#define _DOLPHIN_CARDPRIV + +#include +#include +#include +#include + +#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 * 1024) + +#define CARD_MAX_MOUNT_STEP (CARD_NUM_SYSTEM_BLOCK + 2) + +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 { + BOOL attached; + s32 result; + u16 size; + u16 pageSize; + s32 sectorSize; + u16 cBlock; + u16 vendorID; + s32 latency; + u8 id[12]; + int mountStep; + int formatStep; + u32 scramble; + DSPTaskInfo task; + void* workArea; + CARDDir* currentDir; + u16* currentFat; + OSThreadQueue threadQueue; + u8 cmd[9]; + s32 cmdlen; + vu32 mode; + int retry; + int repeat; + u32 addr; + void* buffer; + s32 xferred; + u16 freeNo; + u16 startBlock; + CARDFileInfo* fileInfo; + CARDCallback extCallback; + CARDCallback txCallback; + CARDCallback exiCallback; + CARDCallback apiCallback; + CARDCallback xferCallback; + CARDCallback eraseCallback; + CARDCallback unlockCallback; + OSAlarm alarm; + u32 cid; + 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); +void __CARDSyncCallback(s32 channel, s32 result); + +#define CARDIsValidBlockNo(card, iBlock) \ + (CARD_NUM_SYSTEM_BLOCK <= (iBlock) && (iBlock) < (card)->cBlock) +#define __CARDGetDirCheck(dir) ((CARDDirCheck*)&(dir)[CARD_MAX_FILE]) + +CARDDir* __CARDGetDirBlock(CARDControl* card); +u16* __CARDGetFatBlock(CARDControl* card); +s32 __CARDUpdateFatBlock(s32 chan, u16* fat, CARDCallback callback); +void __CARDCheckSum(void* ptr, int length, u16* checkSum, u16* checkSumInv); +u16 __CARDGetFontEncode(); +void __CARDExiHandler(s32 chan, OSContext* context); +void __CARDExtHandler(s32 chan, OSContext* context); +void __CARDUnlockedHandler(s32 chan, OSContext* context); +s32 __CARDAccess(CARDControl* card, CARDDir* ent); +s32 __CARDIsWritable(CARDControl *card, CARDDir *entry); + +#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 __CARDPermMask; + +#ifdef __cplusplus +} +#endif +#endif // _DOLPHIN_CARDPRIV \ No newline at end of file diff --git a/include/dolphin/DVDPriv.h b/include/dolphin/DVDPriv.h new file mode 100644 index 000000000..e65a3d900 --- /dev/null +++ b/include/dolphin/DVDPriv.h @@ -0,0 +1,35 @@ +#ifndef _DOLPHIN_DVDPRIV +#define _DOLPHIN_DVDPRIV + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +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; + +#ifdef __cplusplus +} +#endif // _DOLPHIN_DVDPRIV + +#endif __DVDPRIV_H__ diff --git a/include/dolphin/OSRtcPriv.h b/include/dolphin/OSRtcPriv.h new file mode 100644 index 000000000..464f80323 --- /dev/null +++ b/include/dolphin/OSRtcPriv.h @@ -0,0 +1,38 @@ +#ifndef _DOLPHIN_OSRTCPRIV +#define _DOLPHIN_OSRTCPRIV + +#include + +typedef struct OSSram +{ + u16 checkSum; + u16 checkSumInv; + u32 ead0; + u32 ead1; + u32 counterBias; + s8 displayOffsetH; + u8 ntd; + u8 language; + u8 flags; +} OSSram; + +typedef struct OSSramEx +{ + u8 flashID[2][12]; + u32 wirelessKeyboardID; + u16 wirelessPadID[4]; + u8 dvdErrorCode; + u8 _padding0; + u8 flashIDCheckSum[2]; + u16 gbs; + u8 _padding1[2]; +} OSSramEx; + +OSSram *__OSLockSram(); +OSSramEx *__OSLockSramEx(); +void OSSetWirelessID(s32 chan, u16 id); +u16 OSGetWirelessID(s32 chan); +u16 OSGetGbsMode(); +void OSSetGbsMode(u16 mode); + +#endif // _DOLPHIN_OSRTCPRIV \ No newline at end of file diff --git a/include/dolphin/ai.h b/include/dolphin/ai.h index 84db3343b..af223f153 100644 --- a/include/dolphin/ai.h +++ b/include/dolphin/ai.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_AI_H_ -#define _DOLPHIN_AI_H_ +#ifndef _DOLPHIN_AI +#define _DOLPHIN_AI #include @@ -10,41 +10,35 @@ 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 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); +BOOL AIGetDMAEnableFlag(); +void AIStartDMA(); +void AIStopDMA(); +u32 AIGetDMABytesLeft(); +u32 AIGetDMAStartAddr(); +u32 AIGetDMALength(); +u32 AIGetDSPSampleRate(); +void AISetDSPSampleRate(u32 rate); AISCallback AIRegisterStreamCallback(AISCallback callback); -u32 AIGetStreamSampleCount(void); -void AIResetStreamSampleCount(void); +u32 AIGetStreamSampleCount(); +void AIResetStreamSampleCount(); void AISetStreamTrigger(u32 trigger); -u32 AIGetStreamTrigger(void); +u32 AIGetStreamTrigger(); void AISetStreamPlayState(u32 state); -u32 AIGetStreamPlayState(void); -void AISetDSPSampleRate(u32 rate); -u32 AIGetDSPSampleRate(void); +u32 AIGetStreamPlayState(); void AISetStreamSampleRate(u32 rate); -u32 AIGetStreamSampleRate(void); +u32 AIGetStreamSampleRate(); void AISetStreamVolLeft(u8 vol); -u8 AIGetStreamVolLeft(void); void AISetStreamVolRight(u8 vol); -u8 AIGetStreamVolRight(void); -void AIInit(u8* stack); -void AIReset(void); +u8 AIGetStreamVolLeft(); +u8 AIGetStreamVolRight(); +void AIInit(u8 *stack); +BOOL AICheckInit(); +void AIReset(); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_AI diff --git a/include/dolphin/ar/ar.h b/include/dolphin/ar/ar.h new file mode 100644 index 000000000..287cc3607 --- /dev/null +++ b/include/dolphin/ar/ar.h @@ -0,0 +1,45 @@ +#ifndef _DOLPHIN_AR +#define _DOLPHIN_AR + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define AR_STACK_INDEX_ENTRY_SIZE sizeof(u32) + +#define ARAM_DIR_MRAM_TO_ARAM 0x00 +#define ARAM_DIR_ARAM_TO_MRAM 0x01 + +#define AR_CLEAR_INTERNAL_ALL 0x00 +#define AR_CLEAR_INTERNAL_USER 0x01 +#define AR_CLEAR_EXPANSION 0x02 + +typedef void (*ARCallback)(void); + +ARCallback ARRegisterDMACallback(ARCallback 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 ARGetBaseAddress(void); +BOOL ARCheckInit(void); +void ARReset(void); +u32 ARAlloc(u32 length); +u32 ARFree(u32* length); +u32 ARGetSize(void); +u32 ARGetInternalSize(void); +void ARSetSize(void); +void ARClear(u32 flag); + +void __ARClearInterrupt(void); +u16 __ARGetInterruptStatus(void); + +#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) + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_AR \ No newline at end of file diff --git a/include/dolphin/ar/arq.h b/include/dolphin/ar/arq.h new file mode 100644 index 000000000..3c7d2f167 --- /dev/null +++ b/include/dolphin/ar/arq.h @@ -0,0 +1,51 @@ +#ifndef _DOLPHIN_ARQ +#define _DOLPHIN_ARQ + +#include "dolphin/ar/ar.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define ARQ_DMA_ALIGNMENT 32 +#define ARQ_CHUNK_SIZE_DEFAULT 4096 + +#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 + + typedef void (*ARQCallback)(u32 pointerToARQRequest); + + typedef struct ARQRequest + { + + struct ARQRequest *next; + u32 owner; + u32 type; + u32 priority; + u32 source; + u32 dest; + u32 length; + ARQCallback callback; + + } ARQRequest; + + void ARQInit(void); + void ARQReset(void); + void ARQPostRequest(ARQRequest *task, u32 owner, u32 type, u32 priority, u32 source, u32 dest, + u32 length, ARQCallback callback); + void ARQRemoveRequest(ARQRequest *task); + void ARQRemoveOwnerRequest(u32 owner); + void ARQFlushQueue(void); + void ARQSetChunkSize(u32 size); + u32 ARQGetChunkSize(void); + BOOL ARQCheckInit(void); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_ARQ \ No newline at end of file diff --git a/include/dolphin/base.h b/include/dolphin/base.h new file mode 100644 index 000000000..fc8416e00 --- /dev/null +++ b/include/dolphin/base.h @@ -0,0 +1,13 @@ +#ifndef _DOLPHIN_PUBLIC_BASE_H +#define _DOLPHIN_PUBLIC_BASE_H +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/include/dolphin/base/PPCArch.h b/include/dolphin/base/PPCArch.h index 35f5da9c7..88e48a009 100644 --- a/include/dolphin/base/PPCArch.h +++ b/include/dolphin/base/PPCArch.h @@ -1,542 +1,344 @@ -#ifndef _DOLPHIN_PPCARCH -#define _DOLPHIN_PPCARCH - -#include "dolphin/types.h" +#ifndef _DOLPHIN_PPC_ARCH_H +#define _DOLPHIN_PPC_ARCH_H +#include #ifdef __cplusplus -extern "C" { -#endif - -#define CTR 9 -#define XER 1 -#define LR 8 - -#define UPMC1 937 -#define UPMC2 938 -#define UPMC3 941 -#define UPMC4 942 - -#define USIA 939 - -#define UMMCR0 936 -#define UMMCR1 940 - -#define HID0 1008 -#define HID1 1009 - -#define PVR 287 - -#define IBAT0U 528 -#define IBAT0L 529 -#define IBAT1U 530 -#define IBAT1L 531 -#define IBAT2U 532 -#define IBAT2L 533 -#define IBAT3U 534 -#define IBAT3L 535 - -#define DBAT0U 536 -#define DBAT0L 537 -#define DBAT1U 538 -#define DBAT1L 539 -#define DBAT2U 540 -#define DBAT2L 541 -#define DBAT3U 542 -#define DBAT3L 543 - -#define SDR1 25 - -#define SPRG0 272 -#define SPRG1 273 -#define SPRG2 274 -#define SPRG3 275 - -#define DAR 19 -#define DSISR 18 - -#define SRR0 26 -#define SRR1 27 - -#define EAR 282 - -#define DABR 1013 - -#define TBL 284 -#define TBU 285 - -#define L2CR 1017 - -#define DEC 22 - -#define IABR 1010 - -#define PMC1 953 -#define PMC2 954 -#define PMC3 957 -#define PMC4 958 - -#define SIA 955 - -#define MMCR0 952 -#define MMCR1 956 - -#define THRM1 1020 -#define THRM2 1021 -#define THRM3 1022 - -#define ICTC 1019 - -#define GQR0 912 -#define GQR1 913 -#define GQR2 914 -#define GQR3 915 -#define GQR4 916 -#define GQR5 917 -#define GQR6 918 -#define GQR7 919 - -#define HID2 920 - -#define WPAR 921 - -#define DMA_U 922 -#define DMA_L 923 - -#define MSR_POW 0x00040000 // Power Management -#define MSR_ILE 0x00010000 // Interrupt Little Endian -#define MSR_EE 0x00008000 // external interrupt -#define MSR_PR 0x00004000 // privilege level(should be 0) -#define MSR_FP 0x00002000 // floating point available -#define MSR_ME 0x00001000 // machine check enable -#define MSR_FE0 0x00000800 // floating point exception enable -#define MSR_SE 0x00000400 // single step trace enable -#define MSR_BE 0x00000200 // branch trace enable -#define MSR_FE1 0x00000100 // floating point exception enable -#define MSR_IP 0x00000040 // Exception prefix -#define MSR_IR 0x00000020 // instruction relocate -#define MSR_DR 0x00000010 // data relocate -#define MSR_PM 0x00000004 // Performance monitor marked mode -#define MSR_RI 0x00000002 // Recoverable interrupt -#define MSR_LE 0x00000001 // Little Endian - -#define MSR_POW_BIT 13 // Power Management -#define MSR_ILE_BIT 15 // Interrupt Little Endian -#define MSR_EE_BIT 16 // external interrupt -#define MSR_PR_BIT 17 // privilege level (should be 0) -#define MSR_FP_BIT 18 // floating point available -#define MSR_ME_BIT 19 // machine check enable -#define MSR_FE0_BIT 20 // floating point exception enable -#define MSR_SE_BIT 21 // single step trace enable -#define MSR_BE_BIT 22 // branch trace enable -#define MSR_FE1_BIT 23 // floating point exception enable -#define MSR_IP_BIT 25 // Exception prefix -#define MSR_IR_BIT 26 // instruction relocate -#define MSR_DR_BIT 27 // data relocate -#define MSR_PM_BIT 29 // Performance monitor marked mode -#define MSR_RI_BIT 30 // Recoverable interrupt -#define MSR_LE_BIT 31 // Little Endian - -/*---------------------------------------------------------------------------* - HID0 bits - *---------------------------------------------------------------------------*/ -#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 -#define HID0_ILOCK_BIT 18 // ICache lock -#define HID0_DLOCK_BIT 19 // DCache lock - -#define HID2_LSQE 0x80000000 // L/S quantize enable -#define HID2_WPE 0x40000000 // Write pipe enable -#define HID2_PSE 0x20000000 // Paired single enable -#define HID2_LCE 0x10000000 // Locked cache enable - -#define HID2_DCHERR 0x00800000 // ERROR: dcbz_l cache hit -#define HID2_DNCERR 0x00400000 // ERROR: DMA access to normal cache -#define HID2_DCMERR 0x00200000 // ERROR: DMA cache miss error -#define HID2_DQOERR 0x00100000 // ERROR: DMA queue overflow -#define HID2_DCHEE 0x00080000 // dcbz_l cache hit error enable -#define HID2_DNCEE 0x00040000 // DMA access to normal cache error enable -#define HID2_DCMEE 0x00020000 // DMA cache miss error error enable -#define HID2_DQOEE 0x00010000 // DMA queue overflow error enable - -#define HID2_DMAQL_MASK 0x0F000000 // DMA queue length mask -#define HID2_DMAQL_SHIFT 24 // DMA queue shift - -#define HID2_LSQE_BIT 0 -#define HID2_WPE_BIT 1 -#define HID2_PSE_BIT 2 -#define HID2_LCE_BIT 3 - -#define HID2_DCHERR_BIT 8 -#define HID2_DNCERR_BIT 9 -#define HID2_DCMERR_BIT 10 -#define HID2_DQOERR_BIT 11 -#define HID2_DCHEE_BIT 12 -#define HID2_DNCEE_BIT 13 -#define HID2_DCMEE_BIT 14 -#define HID2_DQOEE_BIT 15 - -#define GQR_LOAD_SCALE_MASK 0x3F000000 // load scale field -#define GQR_LOAD_TYPE_MASK 0x00070000 // load type field -#define GQR_STORE_SCALE_MASK 0x00003F00 // store scale field -#define GQR_STORE_TYPE_MASK 0x00000007 // store type field - -typedef struct -{ - u32 _pad0 :2; - u32 loadScale :6; - u32 _pad1 :5; - u32 loadType :3; - u32 _pad2 :2; - u32 storeScale :6; - u32 _pad3 :5; - u32 storeType :3; -} PPC_GQR_t; - -typedef union -{ - u32 val; - PPC_GQR_t f; -} PPC_GQR_u; - - -#define DMA_U_ADDR_MASK 0xFFFFFFE0 // Start addr in memory -#define DMA_U_LEN_U_MASK 0x0000001F // lines to transfer (U) - -#define DMA_L_LC_ADDR_MASK 0xFFFFFFE0 // Start addr in LC -#define DMA_L_LOAD 0x00000010 // 0 - store, 1 - load -#define DMA_L_STORE 0x00000000 // 0 - store, 1 - load -#define DMA_L_LEN_MASK 0x0000000C // lines to transfer (L) -#define DMA_L_TRIGGER 0x00000002 // 0 - cmd inactive, 1 - cmd rdy -#define DMA_L_FLUSH 0x00000001 // 1 - Flush DMA queue - -typedef struct -{ - u32 memAddr :27; - u32 dmaLenU :5; -} PPC_DMA_U_t; - -typedef union -{ - u32 val; - PPC_DMA_U_t f; -} PPC_DMA_U_u; - - -typedef struct +extern "C" { - u32 lcAddr :27; - u32 dmaLd :1; - u32 dmaLenL :2; - u32 dmaTrigger :1; - u32 dmaFlush :1; -} PPC_DMA_L_t; - - -typedef union -{ - u32 val; - PPC_DMA_L_t f; -} PPC_DMA_L_u; - - -#define WPAR_ADDR 0xFFFFFFE0 // 32byte gather address -#define WPAR_BNE 0x00000001 // Buffer not empty (R) - -#define SRR1_DMA_BIT 0x00200000 -#define SRR1_L2DP_BIT 0x00100000 - -#define L2CR_L2E 0x80000000 // L2 Enable -#define L2CR_L2PE 0x40000000 // L2 data parity generation and checking enable - -#define L2CR_L2SIZ_256K 0x10000000 // L2 size 256K -#define L2CR_L2SIZ_512K 0x20000000 // L2 size 512 -#define L2CR_L2SIZ_1M 0x30000000 // L2 size 1M - -#define L2CR_L2CLK_1_0 0x02000000 // L2 clock ratio 1 -#define L2CR_L2CLK_1_5 0x04000000 // L2 clock ratio 1.5 -#define L2CR_L2CLK_2_0 0x08000000 // L2 clock ratio 2 -#define L2CR_L2CLK_2_5 0x0A000000 // L2 clock ratio 2.5 -#define L2CR_L2CLK_3_0 0x0C000000 // L2 clock ratio 3 - -#define L2CR_RAM_FLOW_THRU_BURST 0x00000000 // L2 RAM type flow-through sync. burst SRAM -#define L2CR_RAM_PIPELINE_BURST 0x01000000 // L2 RAM type pipelined sync. burst SRAM -#define L2CR_RAM_PIPELINE_LATE 0x01800000 // L2 RAM type pipelined sync. late-write SRAM - -#define L2CR_L2DO 0x00400000 // Data only -#define L2CR_L2I 0x00200000 // Global invalidate -#define L2CR_L2CTL 0x00100000 // ZZ enable -#define L2CR_L2WT 0x00080000 // L2 write through -#define L2CR_L2TS 0x00040000 // L2 test support - -#define L2CR_L2OH_0_5 0x00000000 // L2 output hold 0.5 ns -#define L2CR_L2OH_1_0 0x00010000 // L2 output hold 1.0 ns +#endif -#define L2CR_L2SL 0x00008000 // L2 DLL slow -#define L2CR_L2DF 0x00004000 // L2 differential clock -#define L2CR_L2BYP 0x00002000 // L2 DLL bypass -#define L2CR_L2CS 0x00000200 // L2 clock stop -#define L2CR_L2DRO 0x00000100 // L2 DLL rollover checkstop enable -#define L2CR_L2CTR_MASK 0x000000FE // L2 counter value mask -#define L2CR_L2IP 0x00000001 // L2 global invalidate in progress + u32 PPCMfmsr(void); + void PPCMtmsr(u32 val); -#define MMCR0_DIS 0x80000000 // Disables counting unconditionally -#define MMCR0_DP 0x40000000 // Disables counting while in supervisor mode -#define MMCR0_DU 0x20000000 // Disables counting while in user mode -#define MMCR0_DMS 0x10000000 // Disables counting while MSR[PM] is set -#define MMCR0_DMR 0x08000000 // Disables counting while MSR[PM] is zero -#define MMCR0_ENINT 0x04000000 // Enables performance monitor interrupt signaling -#define MMCR0_DISCOUNT 0x02000000 // Disables counting of PMCn when a performance monitor interrupt is signaled or... -#define MMCR0_RTCSELECT_MASK 0x01800000 // 64-bit time base, bit selection enable -#define MMCR0_RTCSELECT_63 0x00000000 // Pick bit 63 to count -#define MMCR0_RTCSELECT_55 0x00800000 // Pick bit 55 to count -#define MMCR0_RTCSELECT_51 0x01000000 // Pick bit 51 to count -#define MMCR0_RTCSELECT_47 0x01800000 // Pick bit 47 to count -#define MMCR0_INTONBITTRANS 0x00400000 // Causes interrupt signaling on bit transition from off to on -#define MMCR0_THRESHOLD_MASK 0x003F0000 // Threshold value -#define MMCR0_THRESHOLD(n) ((n) << 16) // Threshold value (0 - 63) -#define MMCR0_PMC1INTCONTROL 0x00008000 // Enables interrupt signaling due to PMC1 counter overflow -#define MMCR0_PMC2INTCONTROL 0x00004000 // Enables interrupt signaling due to PMC2-PMC4 counter overflow -#define MMCR0_PMCTRIGGER 0x00002000 // Can be used to trigger counting of PMC2-PMC4 after PMC1 has overflowed or... -#define MMCR0_PMC1SELECT_MASK 0x00001FC0 // PMC1 input selector -#define MMCR0_PMC2SELECT_MASK 0x0000003F // PMC2 input selector + u32 PPCMfhid0(void); + void PPCMthid0(u32 val); -#define MMCR1_PMC3SELECT_MASK 0xF8000000 // PMC3 input selector -#define MMCR1_PMC4SELECT_MASK 0x07C00000 // PMC4 input selector + u32 PPCMfl2cr(void); + void PPCMtl2cr(u32 val); -#define PMC1_OV 0x80000000 // Overflow -#define PMC1_COUNTER 0x7FFFFFFF // Counter value -#define PMC2_OV 0x80000000 // Overflow -#define PMC2_COUNTER 0x7FFFFFFF // Counter value -#define PMC3_OV 0x80000000 // Overflow -#define PMC3_COUNTER 0x7FFFFFFF // Counter value -#define PMC4_OV 0x80000000 // Overflow -#define PMC4_COUNTER 0x7FFFFFFF // Counter value + void PPCMtdec(u32 val); -/*---------------------------------------------------------------------------* - PMC1 Events - *---------------------------------------------------------------------------*/ -#define MMCR0_PMC1_HOLD 0x00000000 // Register holds current value -#define MMCR0_PMC1_CYCLE 0x00000040 // Processor cycles -#define MMCR0_PMC1_INSTRUCTION 0x00000080 // # of instructions completed. -#define MMCR0_PMC1_TRANSITION 0x000000C0 // # of transitions for 0 to 1 -#define MMCR0_PMC1_DISPATCHED 0x00000100 // # of instructions dispatched -#define MMCR0_PMC1_EIEIO 0x00000140 // # of eieio instructions completed -#define MMCR0_PMC1_ITLB_CYCLE 0x00000180 // # of cycles spent performing table search op. for the ITLB -#define MMCR0_PMC1_L2_HIT 0x000001C0 // # of access that hit the L2. -#define MMCR0_PMC1_EA 0x00000200 // # of valid instruction EAs delivered to the memory subsystem -#define MMCR0_PMC1_IABR 0x00000240 // # of time the address of an instruction matches the IABR -#define MMCR0_PMC1_L1_MISS 0x00000280 // # of loads that miss the L1 -#define MMCR0_PMC1_Bx_UNRESOLVED 0x000002C0 // # of branches that are unresolved when processed -#define MMCR0_PMC1_Bx_STALL_CYCLE 0x00000300 // # of cycles that dispatcher stalls due to a second - // unresolved branch in the instruction stream -#define MMCR0_PMC1_IC_FETCH_MISS 0x00000340 // # of times an instruction fetch missed the L1 Icache -#define MMCR0_PMC2_HOLD 0x00000000 // Register holds current value -#define MMCR0_PMC2_CYCLE 0x00000001 // Processor cycles -#define MMCR0_PMC2_INSTRUCTION 0x00000002 // # of instructions completed -#define MMCR0_PMC2_TRANSITION 0x00000003 // # of time-base (lower) bit transitions -#define MMCR0_PMC2_DISPATCHED 0x00000004 // # of instructions dispatched -#define MMCR0_PMC2_IC_MISS 0x00000005 // # of L1 instruction cache misses -#define MMCR0_PMC2_ITLB_MISS 0x00000006 // # of ITLB misses -#define MMCR0_PMC2_L2_I_MISS 0x00000007 // # of L2 instruction misses -#define MMCR0_PMC2_Bx_FALL_TROUGH 0x00000008 // # of fall-through branches -#define MMCR0_PMC2_PR_SWITCH 0x00000009 // # of MSR[PR] bit toggles -#define MMCR0_PMC2_RESERVED_LOAD 0x0000000A // # of reserved loads completed -#define MMCR0_PMC2_LOAD_STORE 0x0000000B // # of completed loads and stores -#define MMCR0_PMC2_SNOOP 0x0000000C // # of snoops -#define MMCR0_PMC2_L1_CASTOUT 0x0000000D // # of L1 castouts to L2 -#define MMCR0_PMC2_SYSTEM 0x0000000E // # of completed system unit instructions -#define MMCR0_PMC2_IC_FETCH_MISS 0x0000000F // # of instruction fetch misses in the L1 -#define MMCR0_PMC2_Bx_OUT_OF_ORDER 0x00000010 // # of branches allowing out-of-order execution + void PPCSync(void); + void PPCHalt(void); -/*---------------------------------------------------------------------------* - PMC3 Events - *---------------------------------------------------------------------------*/ -#define MMCR1_PMC3_HOLD 0x00000000 // Register holds current value -#define MMCR1_PMC3_CYCLE 0x08000000 // Processor cycles -#define MMCR1_PMC3_INSTRUCTION 0x10000000 // # of instructions completed -#define MMCR1_PMC3_TRANSITION 0x18000000 // # of time-base (lower) bit transitions -#define MMCR1_PMC3_DISPATCHED 0x20000000 // # of instructions dispatched -#define MMCR1_PMC3_DC_MISS 0x28000000 // # of L1 data cache misses -#define MMCR1_PMC3_DTLB_MISS 0x30000000 // # of DTLB misses -#define MMCR1_PMC3_L2_D_MISS 0x38000000 // # of L2 data misses -#define MMCR1_PMC3_Bx_TAKEN 0x40000000 // # predicted branches that were taken -#define MMCR1_PMC3_PM_SWITCH 0x48000000 // # of transitions between marked and unmarked processes -#define MMCR1_PMC3_COND_STORE 0x50000000 // # of store conditional instructions completed -#define MMCR1_PMC3_FPU 0x58000000 // # of instructions completed from the FPU -#define MMCR1_PMC3_L2_SNOOP_CASTOUT 0x60000000 // # of L2 castout caused by snoops to modified lines -#define MMCR1_PMC3_L2_HIT 0x68000000 // # of cache operations that hit in the L2 cache -#define MMCR1_PMC3_L1_MISS_CYCLE 0x78000000 // # of cycles generated by L1 load misses -#define MMCR1_PMC3_Bx_SECOND 0x80000000 // # of branches in the second speculative branch - // resolved correctly -#define MMCR1_PMC3_BPU_LR_CR 0x88000000 // # of cycles the BPU stalls due to LR or CR unresolved - // dependencies + void PPCMtmmcr0(u32 val); + void PPCMtmmcr1(u32 val); -#define MMCR1_PMC4_HOLD 0x00000000 // Register holds current value -#define MMCR1_PMC4_CYCLE 0x00400000 // Processor cycles -#define MMCR1_PMC4_INSTRUCTION 0x00800000 // # of instructions completed -#define MMCR1_PMC4_TRANSITION 0x00C00000 // # of time-base (lower) bit transitions -#define MMCR1_PMC4_DISPATCHED 0x01000000 // # of instructions dispatched -#define MMCR1_PMC4_L2_CASTOUT 0x01400000 // # of L2 castouts -#define MMCR1_PMC4_DTLB_CYCLE 0x01800000 // # of cycles spent performing table searches for DTLB accesses -#define MMCR1_PMC4_Bx_MISSED 0x02000000 // # of mispredicted branches -#define MMCR1_PMC4_COND_STORE_INT 0x02800000 // # of store conditional instructions completed - // with reservation intact -#define MMCR1_PMC4_SYNC 0x02C00000 // # of completed sync instructions -#define MMCR1_PMC4_SNOOP_RETRY 0x03000000 // # of snoop request retries -#define MMCR1_PMC4_INTEGER 0x03400000 // # of completed integer operations -#define MMCR1_PMC4_BPU_THIRD 0x03800000 // # of cycles the BPU cannot process new branches - // due to having two unresolved branches -#define MMCR1_PMC4_DC_MISS 0x07C00000 // # of L1 data cache misses + void PPCMtpmc1(u32 val); + void PPCMtpmc2(u32 val); + void PPCMtpmc3(u32 val); + void PPCMtpmc4(u32 val); -/*---------------------------------------------------------------------------* - FPSCR bits - *---------------------------------------------------------------------------*/ -#ifndef FPSCR_FX -#define FPSCR_FX 0x80000000 // Exception summary -#define FPSCR_FEX 0x40000000 // Enabled exception summary -#define FPSCR_VX 0x20000000 // Invalid operation -#define FPSCR_OX 0x10000000 // Overflow exception -#define FPSCR_UX 0x08000000 // Underflow exception -#define FPSCR_ZX 0x04000000 // Zero divide exception -#define FPSCR_XX 0x02000000 // Inexact exception -#define FPSCR_VXSNAN 0x01000000 // SNaN -#define FPSCR_VXISI 0x00800000 // Infinity - Infinity -#define FPSCR_VXIDI 0x00400000 // Infinity / Infinity -#define FPSCR_VXZDZ 0x00200000 // 0 / 0 -#define FPSCR_VXIMZ 0x00100000 // Infinity * 0 -#define FPSCR_VXVC 0x00080000 // Invalid compare -#define FPSCR_FR 0x00040000 // Fraction rounded -#define FPSCR_FI 0x00020000 // Fraction inexact -#define FPSCR_VXSOFT 0x00000400 // Software request -#define FPSCR_VXSQRT 0x00000200 // Invalid square root -#define FPSCR_VXCVI 0x00000100 // Invalid integer convert -#define FPSCR_VE 0x00000080 // Invalid operation exception enable -#define FPSCR_OE 0x00000040 // Overflow exception enable -#define FPSCR_UE 0x00000020 // Underflow exception enable -#define FPSCR_ZE 0x00000010 // Zero divide exception enable -#define FPSCR_XE 0x00000008 // Inexact exception enable -#define FPSCR_NI 0x00000004 // Non-IEEE mode -#endif + u32 PPCMffpscr(void); + void PPCMtfpscr(u32 val); -#ifndef FPSCR_FX_BIT -#define FPSCR_FX_BIT 0 // Exception summary -#define FPSCR_FEX_BIT 1 // Enabled exception summary -#define FPSCR_VX_BIT 2 // Invalid operation -#define FPSCR_OX_BIT 3 // Overflow exception -#define FPSCR_UX_BIT 4 // Underflow exception -#define FPSCR_ZX_BIT 5 // Zero divide exception -#define FPSCR_XX_BIT 6 // Inexact exception -#define FPSCR_VXSNAN_BIT 7 // SNaN -#define FPSCR_VXISI_BIT 8 // Infinity - Infinity -#define FPSCR_VXIDI_BIT 9 // Infinity / Infinity -#define FPSCR_VXZDZ_BIT 10 // 0 / 0 -#define FPSCR_VXIMZ_BIT 11 // Infinity * 0 -#define FPSCR_VXVC_BIT 12 // Invalid compare -#define FPSCR_FR_BIT 13 // Fraction rounded -#define FPSCR_FI_BIT 14 // Fraction inexact -#define FPSCR_VXSOFT_BIT 21 // Software request -#define FPSCR_VXSQRT_BIT 22 // Invalid square root -#define FPSCR_VXCVI_BIT 23 // Invalid integer convert -#define FPSCR_VE_BIT 24 // Invalid operation exception enable -#define FPSCR_OE_BIT 25 // Overflow exception enable -#define FPSCR_UE_BIT 26 // Underflow exception enable -#define FPSCR_ZE_BIT 27 // Zero divide exception enable -#define FPSCR_XE_BIT 28 // Inexact exception enable -#define FPSCR_NI_BIT 29 // Non-IEEE mode -#endif + u32 PPCMfhid2(void); + void PPCMthid2(u32 val); -union FpscrUnion { - f64 f; - struct { - u32 fpscr_pad; - u32 fpscr; - } u; -}; + u32 PPCMfwpar(void); + void PPCMtwpar(u32 val); -// 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(); + void PPCDisableSpeculation(void); + void PPCSetFpNonIEEEMode(void); -// PPCPm -void PMBegin(void); -void PMEnd(void); -void PMCycles(void); -void PML1FetchMisses(void); -void PML1MissCycles(void); -void PMInstructions(void); + void PPCMthid4(u32 val); #ifdef __cplusplus } #endif +#endif -#endif // _DOLPHIN_PPCARCH +/** + * MSR + * Machine Status Register + */ +// Power management enable +#define MSR_POW (1 << (31 - 13)) +// Exception little-endian mode +#define MSR_ILE (1 << (31 - 15)) +// External interrupt enable +#define MSR_EE (1 << (31 - 16)) +// Privilege level +#define MSR_PR (1 << (31 - 17)) +// Floating-point available +#define MSR_FP (1 << (31 - 18)) +// Machine check enable +#define MSR_ME (1 << (31 - 19)) +// IEEE floating-point exception mode 0 +#define MSR_FE0 (1 << (31 - 20)) +// Single-step trace enable +#define MSR_SE (1 << (31 - 21)) +// Branch trace enable +#define MSR_BE (1 << (31 - 22)) +// IEEE floating-point exception mode 1 +#define MSR_FE1 (1 << (31 - 23)) +// Exception prefix +#define MSR_IP (1 << (31 - 25)) +// Instruction address translation +#define MSR_IR (1 << (31 - 26)) +// Data address translation +#define MSR_DR (1 << (31 - 27)) +// Performance monitor marked mode +#define MSR_PM (1 << (31 - 29)) +// Indicates whether system reset or machine check exception is recoverable +#define MSR_RI (1 << (31 - 30)) +// Little-endian mode enable +#define MSR_LE (1 << (31 - 31)) + +/** + * HID0 + * Hardware Implementation-Dependent Register 0 + */ +// Enable MCP +#define HID0_EMCP (1 << (31 - 0)) +// Enable/disable 60x bus address and data parity generation +#define HID0_DBP (1 << (31 - 1)) +// Enable/disable 60x bus address parity checking +#define HID0_EBA (1 << (31 - 2)) +// Enable 60x bus data parity checking +#define HID0_EBD (1 << (31 - 3)) +// CLK_OUT enable +#define HID0_BCLK (1 << (31 - 4)) +// CLK_OUT enable +#define HID0_ECLK (1 << (31 - 6)) +// Disable precharge of ARTRY +#define HID0_PAR (1 << (31 - 7)) +// Doze mode enable +#define HID0_DOZE (1 << (31 - 8)) +// Nap mode enable +#define HID0_NAP (1 << (31 - 9)) +// Sleep mode enable +#define HID0_SLEEP (1 << (31 - 10)) +// Dynamic power management enable +#define HID0_DPM (1 << (31 - 11)) +// Not hard reset (software-use only) +#define HID0_NHR (1 << (31 - 15)) +// Instruction cache enable +#define HID0_ICE (1 << (31 - 16)) +// Data cache enable +#define HID0_DCE (1 << (31 - 17)) +// Instruction cache lock +#define HID0_ILOCK (1 << (31 - 18)) +// Data cache lock +#define HID0_DLOCK (1 << (31 - 19)) +// Instruction cache flash invalidate +#define HID0_ICFI (1 << (31 - 20)) +// Data cache flash invalidate +#define HID0_DCFI (1 << (31 - 21)) +// Speculative cache access disable +#define HID0_SPD (1 << (31 - 22)) +// Enable M bit on bus for instruction fetches +#define HID0_IFEM (1 << (31 - 23)) +// Store gathering enable +#define HID0_SGE (1 << (31 - 24)) +// Data cache flush assist +#define HID0_DCFA (1 << (31 - 25)) +// Branch Target Instruction Cache enable +#define HID0_BTIC (1 << (31 - 26)) +// Address broadcast enable +#define HID0_ABE (1 << (31 - 28)) +// Branch history table enable +#define HID0_BHT (1 << (31 - 29)) +// No-op the data cache touch instructions +#define HID0_NOOPTI (1 << (31 - 31)) + +/** + * HID1 + * Hardware Implementation-Dependent Register 1 + */ +// PLL configuration bits (read-only) +#define HID1_PC0 (1 << (31 - 0)) +#define HID1_PC1 (1 << (31 - 1)) +#define HID1_PC2 (1 << (31 - 2)) +#define HID1_PC3 (1 << (31 - 3)) +#define HID1_PC4 (1 << (31 - 4)) + +/** + * L2CR + * L2 Control Register + */ +// L2 enable +#define L2CR_L2E (1 << (31 - 0)) +// L2 Checkstop enable +#define L2CR_L2CE (1 << (31 - 1)) +// L2 data-only +#define L2CR_L2DO (1 << (31 - 9)) +// L2 global invalidate +#define L2CR_L2I (1 << (31 - 10)) +// L2 write-through +#define L2CR_L2WT (1 << (31 - 12)) +// L2 test support +#define L2CR_L2TS (1 << (31 - 13)) +// L2 global invalidate in progress (read only) +#define L2CR_L2IP (1 << (31 - 31)) + +/** + * PMC1-PMC4 + * Performance Monitor Counter Registers + */ +// Overflow +#define PMC_OV (1 << (31 - 0)) + +/** + * FPSCR + * Floating-Point Status and Control Register + */ +// Floating-point exception summary +#define FPSCR_FX (1 << (31 - 0)) +// Floating-point enabled exception summary +#define FPSCR_FEX (1 << (31 - 1)) +// Floating-point invalid operation exception summary +#define FPSCR_VX (1 << (31 - 2)) +// Floating-point overflow exception +#define FPSCR_OX (1 << (31 - 3)) +// Floating-point underflow exception +#define FPSCR_UX (1 << (31 - 4)) +// Floating-point zero divide exception +#define FPSCR_ZX (1 << (31 - 5)) +// Floating-point inexact exception +#define FPSCR_XX (1 << (31 - 6)) +// Floating-point invalid operation exception for SNaN +#define FPSCR_VXSNAN (1 << (31 - 7)) +// Floating-point invalid operation exception for (inf - inf) +#define FPSCR_VXISI (1 << (31 - 8)) +// Floating-point invalid operation exception for (inf / inf) +#define FPSCR_VXIDI (1 << (31 - 9)) +// Floating-point invalid operation exception for (0 / 0) +#define FPSCR_VXZDZ (1 << (31 - 10)) +// Floating-point invalid operation exception for (inf * 0) +#define FPSCR_VXIMZ (1 << (31 - 11)) +// Floating-point invalid operation exception for invalid compare +#define FPSCR_VXVC (1 << (31 - 12)) +// Floating-point fraction rounded +#define FPSCR_FR (1 << (31 - 13)) +// Floating-point fraction inexact +#define FPSCR_FI (1 << (31 - 14)) +// Floating-point result flags +#define FPSCR_FPRF (0x1F << (31 - 19)) +// Unknown +#define FPSCR_UNK20 (1 << (31 - 20)) +// Floating-point invalid operation exception for software request +#define FPSCR_VXSOFT (1 << (31 - 21)) +// Floating-point invalid operation exception for invalid square root +#define FPSCR_VXSQRT (1 << (31 - 22)) +// Floating-point invalid operation exception for invalid integer convert +#define FPSCR_VXCVI (1 << (31 - 23)) +// Floating-point invalid operation exception enable +#define FPSCR_VE (1 << (31 - 24)) +// IEEE floating-point overflow exception enable +#define FPSCR_OE (1 << (31 - 25)) +// IEEE floating-point underflow exception enable +#define FPSCR_UE (1 << (31 - 26)) +// IEEE floating-point zero divide exception enable +#define FPSCR_ZE (1 << (31 - 27)) +// Floating-point inexact exception enable +#define FPSCR_XE (1 << (31 - 28)) +// Floating-point non-IEEE mode +#define FPSCR_NI (1 << (31 - 29)) +// Floating-point rounding control +#define FPSCR_RN (0x3 << (31 - 31)) + +/** + * HID2 + * Hardware Implementation-Dependent Register 2 + */ +// Write pipe enable +#define HID2_WPE (1 << (31 - 1)) +// Paired-single enable +#define HID2_PSE (1 << (31 - 2)) +// Locked cache enable +#define HID2_LCE (1 << (31 - 3)) +// DMA queue length (read only) +#define HID2_DMAQL \ + ((1 << (31 - 4)) | (1 << (31 - 5)) | (1 << (31 - 6)) | (1 << (31 - 7))) +// dcbz_l cache hit error +#define HID2_DCHERR (1 << (31 - 8)) +// DMA access to normal cache error +#define HID2_DNCERR (1 << (31 - 9)) +// DMA cache miss error +#define HID2_DCMERR (1 << (31 - 10)) +// DMA queue overflow error +#define HID2_DQOERR (1 << (31 - 11)) +// dcbz_l cache hit error enable +#define HID2_DCHEE (1 << (31 - 12)) +// DMA access to normal cache error enable +#define HID2_DNCEE (1 << (31 - 13)) +// DMA cache miss error enable +#define HID2_DCMEE (1 << (31 - 14)) +// DMA queue overflow error enable +#define HID2_DQOEE (1 << (31 - 15)) + +#define SRR1_DMA_BIT 0x00200000 +#define SRR1_L2DP_BIT 0x00100000 + +/** + * WPAR + * Write Pipe Address Register + */ +// High order address bits of the data to be gathered +#define WPAR_GB_ADDR (0x07FFFFFF << (31 - 26)) +// Buffer not empty (read only) +#define WPAR_BNE (1 << (31 - 31)) + +/** + * DMAU + * Direct Memory Access Upper Register + */ +// High order address bits of starting address in external memory of the DMA +// transfer +#define DMAU_MEM_ADDR (0x07FFFFFF << (31 - 26)) +// High order bits of transfer length, in cache lines. Low order bits are in +// DMAL +#define DMAU_DMA_LEN_U (0x0000001F << (31 - 31)) + +/** + * DMAL + * Direct Memory Access Lower Register + */ +// High order address bits of starting address in locked cache of the DMA +// transfer +#define DMAL_LC_ADDR (0x07FFFFFF << (31 - 26)) +// DMA load command +#define DMAL_DMA_LD (1 << (31 - 27)) +// Low order bits of transfer length, in cache lines. High order bits are in +// DMAU +#define DMAL_DMA_LEN_L (0x3 << (31 - 29)) +// Trigger bit +#define DMAL_DMA_T (1 << (31 - 30)) +// Flush bit +#define DMAL_DMA_F (1 << (31 - 31)) + +/** + * PVR + * Processor Version Register + */ +// A 16-bit number that uniquely identifies a particular processor version +#define PVR_VER (0xFFFF0000) +// A 16-bit number that distinguishes between various releases of a particular +// version (that is, an engineering change level) +#define PVR_REV (0x0000FFFF) + +/** + * HID4 + * Hardware Implementation-Dependent Register 4 + */ +// Unknown +#define HID4_H4A (1 << (31 - 0)) +// L2 fetch mode +#define HID4_L2FM (0x3 << (31 - 2)) +// Bus pipeline depth +#define HID4_BPD (0x3 << (31 - 4)) +// L2 second castout buffer enable +#define HID4_BCO (1 << (31 - 5)) +// Secondary BAT enable +#define HID4_SBE (1 << (31 - 6)) +// Paired-singles control bit 1 +#define HID4_PS1_CTL (1 << (31 - 7)) +// Data bus parking +#define HID4_DBP (1 << (31 - 9)) +// L2 MUM enable +#define HID4_L2MUM (1 << (31 - 10)) +// L2CFI - L2 complete castout prior to L2 flash invalidate +#define HID4_L2_CCFI (1 << (31 - 11)) +// Paired-singles control bit 2 +#define HID4_PSS2_CTL (1 << (31 - 12)) \ No newline at end of file diff --git a/include/dolphin/card.h b/include/dolphin/card.h index f335a2a8d..ff05e8393 100644 --- a/include/dolphin/card.h +++ b/include/dolphin/card.h @@ -1,166 +1,49 @@ -#ifndef _DOLPHIN_CARD_H_ -#define _DOLPHIN_CARD_H_ +#ifndef _DOLPHIN_CARD +#define _DOLPHIN_CARD -#include -#include -#include +#include #ifdef __cplusplus extern "C" { #endif +#define CARD_ENCODE_ANSI 0u +#define CARD_ENCODE_SJIS 1u -#define CARD_FILENAME_MAX 32 +/* 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_ICON_MAX 8 +#define CARD_ICON_WIDTH 32 +#define CARD_ICON_HEIGHT 32 +#define CARD_BANNER_WIDTH 96 +#define CARD_BANNER_HEIGHT 32 -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) +/* Icon animation */ +#define CARD_MODE_NORMAL 0 +#define CARD_MODE_FAST 1 -#define CARD_MAX_MOUNT_STEP (CARD_NUM_SYSTEM_BLOCK + 2) +#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_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_NUM_CHANS 2 #define CARD_RESULT_UNLOCKED 1 #define CARD_RESULT_READY 0 @@ -180,18 +63,6 @@ typedef struct CARDStat #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 - #define CARD_STAT_ICON_NONE 0 #define CARD_STAT_ICON_C8 1 #define CARD_STAT_ICON_RGB5A3 2 @@ -202,133 +73,106 @@ typedef struct CARDStat #define CARD_STAT_BANNER_RGB5A3 2 #define CARD_STAT_BANNER_MASK 3 -#define CARD_ENCODE_ANSI 0 -#define CARD_ENCODE_SJIS 1 - #define CARD_STAT_ANIM_LOOP 0x00 #define CARD_STAT_ANIM_BOUNCE 0x04 #define CARD_STAT_ANIM_MASK 0x04 -#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_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 -extern u32 __CARDFreq; +#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 -#if DEBUG -#define CARDFreq __CARDFreq -#else -#define CARDFreq EXI_FREQ_16M -#endif +typedef struct CARDFileInfo { + s32 chan; + s32 fileNo; -void CARDInit(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* old, const char* _new, CARDCallback callback); + 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); -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); +BOOL CARDSetFastMode(BOOL enable); -// CARDCheck -s32 CARDCheckExAsync(s32 chan, s32* xferBytes, CARDCallback callback); +s32 CARDCheck(s32 chan); s32 CARDCheckAsync(s32 chan, CARDCallback callback); s32 CARDCheckEx(s32 chan, s32* xferBytes); -s32 CARDCheck(s32 chan); - -// CARDCreate +s32 CARDCheckExAsync(s32 chan, s32* xferBytes, CARDCallback callback); +s32 CARDCreate(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo); s32 CARDCreateAsync(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo, CARDCallback callback); -s32 CARDCreate(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo); - -// 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 CARDDeleteAsync(s32 chan, const char* fileName, CARDCallback callback); +s32 CARDFastDelete(s32 chan, s32 fileNo); +s32 CARDFastDeleteAsync(s32 chan, s32 fileNo, CARDCallback callback); +s32 CARDFastOpen(s32 chan, s32 fileNo, CARDFileInfo* fileInfo); s32 CARDFormat(s32 chan); - -// CARDMount -int CARDProbe(s32 chan); -s32 CARDProbeEx(s32 chan, s32* memSize, s32* sectorSize); +s32 CARDFormatAsync(s32 chan, CARDCallback callback); +s32 CARDFreeBlocks(s32 chan, s32* byteNotUsed, s32* filesNotUsed); +s32 CARDGetAttributes(s32 chan, s32 fileNo, u8* attr); +s32 CARDGetEncoding(s32 chan, u16* encode); +s32 CARDGetMemSize(s32 chan, u16* size); +s32 CARDGetResultCode(s32 chan); +s32 CARDGetSectorSize(s32 chan, u32* size); +s32 CARDGetSerialNo(s32 chan, u64* serialNo); +s32 CARDGetStatus(s32 chan, s32 fileNo, CARDStat* stat); +s32 CARDGetXferredBytes(s32 chan); +s32 CARDMount(s32 chan, void* workArea, CARDCallback detachCallback); s32 CARDMountAsync(s32 chan, void* workArea, CARDCallback detachCallback, CARDCallback attachCallback); -s32 CARDMount(s32 chan, void* workArea, CARDCallback detachCallback); -s32 CARDUnmount(s32 chan); - -// 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 CARDOpen(s32 chan, const char* fileName, CARDFileInfo* fileInfo); +BOOL CARDProbe(s32 chan); +s32 CARDProbeEx(s32 chan, s32* memSize, s32* sectorSize); +s32 CARDRename(s32 chan, const char* oldName, const char* newName); +s32 CARDRenameAsync(s32 chan, const char* oldName, const char* newName, CARDCallback callback); s32 CARDSetAttributesAsync(s32 chan, s32 fileNo, u8 attr, CARDCallback callback); s32 CARDSetAttributes(s32 chan, s32 fileNo, u8 attr); - -// CARDOpen -s32 CARDFastOpen(s32 chan, s32 fileNo, CARDFileInfo* fileInfo); -s32 CARDOpen(s32 chan, const char* fileName, CARDFileInfo* fileInfo); -s32 CARDClose(CARDFileInfo* fileInfo); - -// CARDProgram -s32 CARDProgramAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, - CARDCallback callback); -s32 CARDProgram(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset); - -// 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* old, const char* _new); - -// CARDStat -s32 CARDGetStatus(s32 chan, s32 fileNo, CARDStat* stat); -s32 CARDSetStatusAsync(s32 chan, s32 fileNo, CARDStat* stat, CARDCallback callback); s32 CARDSetStatus(s32 chan, s32 fileNo, CARDStat* stat); - -// CARDWrite -s32 CARDWriteAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, +s32 CARDSetStatusAsync(s32 chan, s32 fileNo, CARDStat* stat, CARDCallback callback); +s32 CARDUnmount(s32 chan); +s32 CARDGetCurrentMode(s32 chan, u32* mode); +s32 CARDCancel(CARDFileInfo* fileInfo); +s32 CARDClose(CARDFileInfo* fileInfo); +s32 CARDRead(CARDFileInfo* fileInfo, void* addr, s32 length, s32 offset); +s32 CARDReadAsync(CARDFileInfo* fileInfo, void* addr, s32 length, s32 offset, + CARDCallback callback); +s32 CARDWrite(CARDFileInfo* fileInfo, const void* addr, s32 length, s32 offset); +s32 CARDWriteAsync(CARDFileInfo* fileInfo, const void* addr, s32 length, s32 offset, CARDCallback callback); -s32 CARDWrite(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset); #ifdef __cplusplus } #endif - -#endif +#endif // _DOLPHIN_CARD \ No newline at end of file diff --git a/include/dolphin/db.h b/include/dolphin/db.h index a126bbe39..dc19c6311 100644 --- a/include/dolphin/db.h +++ b/include/dolphin/db.h @@ -1,20 +1,32 @@ -#ifndef _DOLPHIN_DB_H_ -#define _DOLPHIN_DB_H_ +#ifndef _DOLPHIN_DB +#define _DOLPHIN_DB -#include -#include +#include "types.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #define OS_DBINTERFACE_ADDR 0x00000040 -BOOL DBIsDebuggerPresent(void); -void DBPrintf(char* str, ...); +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); +static void __DBExceptionDestination(void); +void DBPrintf(char *format, ...); #ifdef __cplusplus } #endif -#endif // _DOLPHIN_DB_H_ +#endif // _DOLPHIN_DB \ No newline at end of file diff --git a/include/dolphin/dolphin/ar.h b/include/dolphin/dolphin/ar.h deleted file mode 100644 index 210f136c7..000000000 --- a/include/dolphin/dolphin/ar.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef _DOLPHIN_AR_H_ -#define _DOLPHIN_AR_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*ARQCallback)(u32 pointerToARQRequest); - -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 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); -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 diff --git a/include/dolphin/dolphin/gx.h b/include/dolphin/dolphin/gx.h deleted file mode 100644 index 0e90e543e..000000000 --- a/include/dolphin/dolphin/gx.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef _DOLPHIN_GX_H_ -#define _DOLPHIN_GX_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 - -// GXMisc -void (*GXSetDrawSyncCallback(void (*cb)(u16)))(u16); -void GXSetDrawSync(u16 token); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/dolphin/dolphin/gx/GXBump.h b/include/dolphin/dolphin/gx/GXBump.h deleted file mode 100644 index 2a24dc69f..000000000 --- a/include/dolphin/dolphin/gx/GXBump.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _DOLPHIN_GX_GXBUMP_H_ -#define _DOLPHIN_GX_GXBUMP_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -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 diff --git a/include/dolphin/dolphin/gx/GXCommandList.h b/include/dolphin/dolphin/gx/GXCommandList.h deleted file mode 100644 index b9933c9c7..000000000 --- a/include/dolphin/dolphin/gx/GXCommandList.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _DOLPHIN_GX_GXCOMMANDLIST_H_ -#define _DOLPHIN_GX_GXCOMMANDLIST_H_ - -#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/dolphin/gx/GXCpu2Efb.h b/include/dolphin/dolphin/gx/GXCpu2Efb.h deleted file mode 100644 index 46aa3e336..000000000 --- a/include/dolphin/dolphin/gx/GXCpu2Efb.h +++ /dev/null @@ -1,29 +0,0 @@ -#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/dolphin/gx/GXCull.h b/include/dolphin/dolphin/gx/GXCull.h deleted file mode 100644 index cac438181..000000000 --- a/include/dolphin/dolphin/gx/GXCull.h +++ /dev/null @@ -1,18 +0,0 @@ -#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/dolphin/gx/GXDispList.h b/include/dolphin/dolphin/gx/GXDispList.h deleted file mode 100644 index 15c5eb054..000000000 --- a/include/dolphin/dolphin/gx/GXDispList.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _DOLPHIN_GX_GXDISPLIST_H_ -#define _DOLPHIN_GX_GXDISPLIST_H_ - -#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/dolphin/gx/GXDraw.h b/include/dolphin/dolphin/gx/GXDraw.h deleted file mode 100644 index 1e32f635c..000000000 --- a/include/dolphin/dolphin/gx/GXDraw.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _DOLPHIN_GX_GXDRAW_H_ -#define _DOLPHIN_GX_GXDRAW_H_ - -#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 diff --git a/include/dolphin/dolphin/gx/GXEnum.h b/include/dolphin/dolphin/gx/GXEnum.h deleted file mode 100644 index c3686e538..000000000 --- a/include/dolphin/dolphin/gx/GXEnum.h +++ /dev/null @@ -1,898 +0,0 @@ -#ifndef _DOLPHIN_GX_GXENUM_H_ -#define _DOLPHIN_GX_GXENUM_H_ - -typedef u8 GXBool; - -#define GX_FALSE ((GXBool)0) -#define GX_TRUE ((GXBool)1) - -#define GX_ENABLE ((GXBool)1) -#define GX_DISABLE ((GXBool)0) - -typedef enum _GXProjectionType { - GX_PERSPECTIVE, - GX_ORTHOGRAPHIC, -} GXProjectionType; - -typedef enum _GXCompare { - GX_NEVER, - GX_LESS, - GX_EQUAL, - GX_LEQUAL, - GX_GREATER, - GX_NEQUAL, - GX_GEQUAL, - GX_ALWAYS, -} GXCompare; - -typedef enum _GXAlphaOp { - GX_AOP_AND, - GX_AOP_OR, - GX_AOP_XOR, - GX_AOP_XNOR, - GX_MAX_ALPHAOP, -} GXAlphaOp; - -typedef enum _GXZFmt16 { - GX_ZC_LINEAR, - GX_ZC_NEAR, - GX_ZC_MID, - GX_ZC_FAR, -} GXZFmt16; - -typedef enum _GXGamma { - GX_GM_1_0, - GX_GM_1_7, - GX_GM_2_2, -} GXGamma; - -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; - -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 _GXVtxFmt { - GX_VTXFMT0, - GX_VTXFMT1, - GX_VTXFMT2, - GX_VTXFMT3, - GX_VTXFMT4, - GX_VTXFMT5, - GX_VTXFMT6, - GX_VTXFMT7, - GX_MAX_VTXFMT, -} GXVtxFmt; - -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 { - 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 _GXPosNrmMtx { - 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, - 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, - 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 _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 _GXPerf0 { - 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, - 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, - 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, - GX_PERF0_NONE, -} GXPerf0; - -typedef enum _GXPerf1 { - 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, - 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, - GX_PERF1_CALL_REQ, - GX_PERF1_VC_MISS_REQ, - GX_PERF1_CP_ALL_REQ, - - GX_PERF1_CLOCKS, - GX_PERF1_NONE, -} GXPerf1; - -typedef enum _GXVCachePerf { - GX_VC_POS = 0, - GX_VC_NRM = 1, - GX_VC_CLR0 = 2, - GX_VC_CLR1 = 3, - GX_VC_TEX0 = 4, - GX_VC_TEX1 = 5, - GX_VC_TEX2 = 6, - GX_VC_TEX3 = 7, - GX_VC_TEX4 = 8, - GX_VC_TEX5 = 9, - GX_VC_TEX6 = 10, - GX_VC_TEX7 = 11, - GX_VC_ALL = 15, -} GXVCachePerf; - -typedef enum _GXClipMode { - GX_CLIP_ENABLE = 0, - GX_CLIP_DISABLE = 1, -} GXClipMode; - -typedef enum _GXFBClamp { - GX_CLAMP_NONE = 0, - GX_CLAMP_TOP = 1, - GX_CLAMP_BOTTOM = 2, -} GXFBClamp; - -typedef enum _GXCopyMode { - GX_COPY_PROGRESSIVE = 0, - GX_COPY_INTLC_EVEN = 2, - GX_COPY_INTLC_ODD = 3, -} GXCopyMode; - -typedef enum _GXAlphaReadMode { - GX_READ_00, - GX_READ_FF, - GX_READ_NONE, -} GXAlphaReadMode; - -typedef enum _GXTexCacheSize { - GX_TEXCACHE_32K, - GX_TEXCACHE_128K, - GX_TEXCACHE_512K, - GX_TEXCACHE_NONE, -} GXTexCacheSize; - -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; - -typedef enum _GXTlutFmt { - GX_TL_IA8, - GX_TL_RGB565, - GX_TL_RGB5A3, - GX_MAX_TLUTFMT, -} GXTlutFmt; - -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; - -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; - -#endif diff --git a/include/dolphin/dolphin/gx/GXFifo.h b/include/dolphin/dolphin/gx/GXFifo.h deleted file mode 100644 index 1452975f5..000000000 --- a/include/dolphin/dolphin/gx/GXFifo.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _DOLPHIN_GX_GXFIFO_H_ -#define _DOLPHIN_GX_GXFIFO_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct OSThread; - -typedef struct -{ - u8 pad[128]; -} GXFifoObj; - -typedef void (*GXBreakPtCallback)(void); - -void GXInitFifoBase(GXFifoObj* fifo, void* base, u32 size); -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 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 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 diff --git a/include/dolphin/dolphin/gx/GXFrameBuffer.h b/include/dolphin/dolphin/gx/GXFrameBuffer.h deleted file mode 100644 index 73b513fa3..000000000 --- a/include/dolphin/dolphin/gx/GXFrameBuffer.h +++ /dev/null @@ -1,66 +0,0 @@ -#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/dolphin/gx/GXGeometry.h b/include/dolphin/dolphin/gx/GXGeometry.h deleted file mode 100644 index 188fa7a59..000000000 --- a/include/dolphin/dolphin/gx/GXGeometry.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef _DOLPHIN_GX_GXGEOMETRY_H_ -#define _DOLPHIN_GX_GXGEOMETRY_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -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 diff --git a/include/dolphin/dolphin/gx/GXGet.h b/include/dolphin/dolphin/gx/GXGet.h deleted file mode 100644 index d1ba630a4..000000000 --- a/include/dolphin/dolphin/gx/GXGet.h +++ /dev/null @@ -1,64 +0,0 @@ -#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/dolphin/gx/GXLighting.h b/include/dolphin/dolphin/gx/GXLighting.h deleted file mode 100644 index 83c5aae42..000000000 --- a/include/dolphin/dolphin/gx/GXLighting.h +++ /dev/null @@ -1,32 +0,0 @@ -#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/dolphin/gx/GXManage.h b/include/dolphin/dolphin/gx/GXManage.h deleted file mode 100644 index fd899d361..000000000 --- a/include/dolphin/dolphin/gx/GXManage.h +++ /dev/null @@ -1,36 +0,0 @@ -#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/dolphin/gx/GXPerf.h b/include/dolphin/dolphin/gx/GXPerf.h deleted file mode 100644 index bd1b474aa..000000000 --- a/include/dolphin/dolphin/gx/GXPerf.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _DOLPHIN_GX_GXPERF_H_ -#define _DOLPHIN_GX_GXPERF_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void GXSetGPMetric(GXPerf0 perf0, GXPerf1 perf1); -void GXReadGPMetric(u32* cnt0, u32* cnt1); -void GXClearGPMetric(void); -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 diff --git a/include/dolphin/dolphin/gx/GXPixel.h b/include/dolphin/dolphin/gx/GXPixel.h deleted file mode 100644 index d61838d1a..000000000 --- a/include/dolphin/dolphin/gx/GXPixel.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _DOLPHIN_GX_GXPIXEL_H_ -#define _DOLPHIN_GX_GXPIXEL_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -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 diff --git a/include/dolphin/dolphin/gx/GXStruct.h b/include/dolphin/dolphin/gx/GXStruct.h deleted file mode 100644 index 0e7dc0be6..000000000 --- a/include/dolphin/dolphin/gx/GXStruct.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef _DOLPHIN_GX_GXSTRUCT_H_ -#define _DOLPHIN_GX_GXSTRUCT_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 { - u8 r, g, b, a; -} GXColor; - -typedef struct _GXColorS10 { - s16 r, g, b, a; -} GXColorS10; - -typedef struct _GXTexObj { - u32 dummy[8]; -} GXTexObj; - -typedef struct _GXLightObj { - u32 dummy[16]; -} GXLightObj; - -typedef struct _GXTexRegion { - u32 dummy[4]; -} GXTexRegion; - -typedef struct _GXTlutObj { - u32 dummy[3]; -} GXTlutObj; - -typedef struct _GXTlutRegion { - u32 dummy[4]; -} GXTlutRegion; - -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/dolphin/gx/GXTev.h b/include/dolphin/dolphin/gx/GXTev.h deleted file mode 100644 index 8deb22d08..000000000 --- a/include/dolphin/dolphin/gx/GXTev.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef _DOLPHIN_GX_GXTEV_H_ -#define _DOLPHIN_GX_GXTEV_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 GXSetTevColor(GXTevRegID id, GXColor color); -void GXSetTevColorS10(GXTevRegID id, GXColorS10 color); -void GXSetTevKColor(GXTevKColorID id, GXColor color); -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 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 nStages); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/dolphin/dolphin/gx/GXTexture.h b/include/dolphin/dolphin/gx/GXTexture.h deleted file mode 100644 index f42dc2295..000000000 --- a/include/dolphin/dolphin/gx/GXTexture.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef _DOLPHIN_GX_GXTEXTURE_H_ -#define _DOLPHIN_GX_GXTEXTURE_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef GXTexRegion *(*GXTexRegionCallback)(GXTexObj* t_obj, GXTexMapID id); -typedef GXTlutRegion *(*GXTlutRegionCallback)(u32 idx); - -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* 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 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 diff --git a/include/dolphin/dolphin/gx/GXTransform.h b/include/dolphin/dolphin/gx/GXTransform.h deleted file mode 100644 index 1e7f94e57..000000000 --- a/include/dolphin/dolphin/gx/GXTransform.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef _DOLPHIN_GX_GXTRANSFORM_H_ -#define _DOLPHIN_GX_GXTRANSFORM_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#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 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 diff --git a/include/dolphin/dolphin/gx/GXVerify.h b/include/dolphin/dolphin/gx/GXVerify.h deleted file mode 100644 index 93a1b29e5..000000000 --- a/include/dolphin/dolphin/gx/GXVerify.h +++ /dev/null @@ -1,29 +0,0 @@ -#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/dolphin/gx/GXVert.h b/include/dolphin/dolphin/gx/GXVert.h deleted file mode 100644 index e674041bc..000000000 --- a/include/dolphin/dolphin/gx/GXVert.h +++ /dev/null @@ -1,162 +0,0 @@ -#ifndef _DOLPHIN_GX_GXVERT_H_ -#define _DOLPHIN_GX_GXVERT_H_ - -#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 : (GXFIFO_ADDR); -#else -#define GXWGFifo (*(volatile PPCWGPipe*)GXFIFO_ADDR) -#endif - -#if DEBUG - -// external functions - -#define FUNC_1PARAM(name, T) void name##1##T(T x); -#define FUNC_2PARAM(name, T) void name##2##T(T x, T y); -#define FUNC_3PARAM(name, T) void name##3##T(T x, T y, T z); -#define FUNC_4PARAM(name, T) void name##4##T(T x, T y, T z, T w); -#define FUNC_INDEX8(name) void name##1x8(u8 x); -#define FUNC_INDEX16(name) void name##1x16(u16 x); - -#else - -// inline functions - -#define FUNC_1PARAM(name, T) \ - static inline void name##1##T(T x) \ - { \ - GXWGFifo.T = x; \ - } - -#define FUNC_2PARAM(name, T) \ - static inline void name##2##T(T x, T y) \ - { \ - GXWGFifo.T = x; \ - GXWGFifo.T = y; \ - } - -#define FUNC_3PARAM(name, T) \ - static inline void name##3##T(T x, T y, T z) \ - { \ - GXWGFifo.T = x; \ - GXWGFifo.T = y; \ - GXWGFifo.T = z; \ - } - -#define FUNC_4PARAM(name, T) \ - static inline 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) \ - static inline void name##1x8(u8 x) \ - { \ - GXWGFifo.u8 = x; \ - } - -#define FUNC_INDEX16(name) \ - static inline void name##1x16(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/dolphin/mtx.h b/include/dolphin/dolphin/mtx.h deleted file mode 100644 index aaaaf6f2e..000000000 --- a/include/dolphin/dolphin/mtx.h +++ /dev/null @@ -1,373 +0,0 @@ -#ifndef _DOLPHIN_MTX_H_ -#define _DOLPHIN_MTX_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - f32 x, y, z; -} Vec, *VecPtr, Point3d, *Point3dPtr; - -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]; - -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 sinA, f32 cosA); -void PSMTXRotAxisRad(Mtx m, const Vec* axis, f32 rad); -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); - -#ifdef DEBUG -#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_MTXRotRad -#define MTXTrans C_MTXTrans -#define MTXTransApply C_MTXTransApply -#define MTXScale C_MTXScale -#define MTXScaleApply C_MTXScaleApply -#define MTXQuat C_MTXQuat -#define MTXReflect C_MTXReflect -#else -#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 PSMTXRotRad -#define MTXTrans PSMTXTrans -#define MTXTransApply PSMTXTransApply -#define MTXScale PSMTXScale -#define MTXScaleApply PSMTXScaleApply -#define MTXQuat PSMTXQuat -#define MTXReflect PSMTXReflect -#endif - -// 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 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); - -#ifdef DEBUG -#define MTXMultVec C_MTXMultVec -#define MTXMultVecArray C_MTXMultVecArray -#define MTXMultVecSR C_MTXMultVecSR -#define MTXMultVecArraySR C_MTXMultVecArraySR -#else -#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 diff --git a/include/dolphin/dolphin/vi.h b/include/dolphin/dolphin/vi.h deleted file mode 100644 index af4184426..000000000 --- a/include/dolphin/dolphin/vi.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _DOLPHIN_VI_H_ -#define _DOLPHIN_VI_H_ - -#include -#include - -#endif diff --git a/include/dolphin/dolphin/vi/vifuncs.h b/include/dolphin/dolphin/vi/vifuncs.h deleted file mode 100644 index f9b6086d9..000000000 --- a/include/dolphin/dolphin/vi/vifuncs.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _DOLPHIN_VIFUNCS_H_ -#define _DOLPHIN_VIFUNCS_H_ - -#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/dolphin/vi/vitypes.h b/include/dolphin/dolphin/vi/vitypes.h deleted file mode 100644 index 1334696f8..000000000 --- a/include/dolphin/dolphin/vi/vitypes.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _DOLPHIN_VITYPES_H_ -#define _DOLPHIN_VITYPES_H_ - -#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/dolphin/dsp.h b/include/dolphin/dsp.h index db2975948..472827ad3 100644 --- a/include/dolphin/dsp.h +++ b/include/dolphin/dsp.h @@ -1,35 +1,50 @@ -#ifndef _DOLPHIN_DSP_H_ -#define _DOLPHIN_DSP_H_ +#ifndef _DOLPHIN_DSP +#define _DOLPHIN_DSP +#include "types.h" #include #ifdef __cplusplus extern "C" { #endif +#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 + typedef void (*DSPCallback)(void* task); -typedef struct STRUCT_DSP_TASK DSPTaskInfo; - -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 */ DSPTaskInfo* next; - /* 0x3C */ DSPTaskInfo* prev; - /* 0x40 */ OSTime t_context; - /* 0x48 */ OSTime t_task; + +typedef struct STRUCT_DSP_TASK { + vu32 state; + vu32 priority; + vu32 flags; + u16* iram_mmem_addr; + u32 iram_length; + u32 iram_addr; + + u16* dram_mmem_addr; + u32 dram_length; + u32 dram_addr; + + u16 dsp_init_vector; + u16 dsp_resume_vector; + + DSPCallback init_cb; + DSPCallback res_cb; + DSPCallback done_cb; + DSPCallback req_cb; + + struct STRUCT_DSP_TASK* next; + struct STRUCT_DSP_TASK* prev; + + OSTime t_context; + OSTime t_task; + } DSPTaskInfo; u32 DSPCheckMailToDSP(void); @@ -44,14 +59,26 @@ void DSPReset(void); void DSPHalt(void); void DSPUnhalt(void); u32 DSPGetDMAStatus(void); -DSPTaskInfo* DSPAddTask(DSPTaskInfo* task); -DSPTaskInfo* DSPCancelTask(DSPTaskInfo* task); -DSPTaskInfo* DSPAssertTask(DSPTaskInfo* task); +DSPTaskInfo *DSPAddTask(DSPTaskInfo *task); +DSPTaskInfo *DSPCancelTask(DSPTaskInfo *task); +DSPTaskInfo *DSPAssertTask(DSPTaskInfo *task); -DSPTaskInfo* __DSPGetCurrentTask(void); +DSPTaskInfo *__DSPGetCurrentTask(void); + +extern DSPTaskInfo *__DSP_curr_task; +extern DSPTaskInfo *__DSP_last_task; +extern DSPTaskInfo *__DSP_first_task; + +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 +#endif // _DOLPHIN_DSP \ No newline at end of file diff --git a/include/dolphin/dvd.h b/include/dolphin/dvd.h index 4bbe3190e..0774f0459 100644 --- a/include/dolphin/dvd.h +++ b/include/dolphin/dvd.h @@ -1,237 +1,18 @@ -#ifndef _DOLPHIN_DVD_H_ -#define _DOLPHIN_DVD_H_ - -#include +#ifndef _DOLPHIN_PUBLIC_DVD_H +#define _DOLPHIN_PUBLIC_DVD_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -// needed for matching release -#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) - -#define DVD_ASSERTMSG2LINE(line, cond, msg, arg1, arg2) \ - if (!(cond)) \ - OSPanic(__FILE__, line, msg, arg1, arg2) - -#define DVD_RESULT_GOOD 0 -#define DVD_RESULT_FATAL_ERROR -1 -#define DVD_RESULT_IGNORED -2 -#define DVD_RESULT_CANCELED -6 - -#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 { - char gameName[4]; - char company[2]; - u8 diskNumber; - u8 gameVersion; - u8 streaming; - u8 streamingBufSize; - u8 padding[22]; -} DVDDiskID; - -typedef struct DVDCommandBlock DVDCommandBlock; -typedef void (*DVDCBCallback)(s32 result, DVDCommandBlock* block); -typedef void (*DVDLowCallback)(u32); - -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* addr; - /* 0x1C */ u32 currTransferSize; - /* 0x20 */ u32 transferredSize; - /* 0x24 */ DVDDiskID* id; - /* 0x28 */ DVDCBCallback callback; - /* 0x2C */ void* userData; -}; - -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; -}; - -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 revisionLevel; - /* 0x02 */ u16 deviceCode; - /* 0x04 */ u32 releaseDate; - /* 0x08 */ u8 padding[24]; -} DVDDriveInfo; - -// DVD -void DVDInit(void); -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); -int DVDCancelAsync(DVDCommandBlock* block, DVDCBCallback callback); -s32 DVDCancel(volatile DVDCommandBlock* block); -int DVDCancelAllAsync(DVDCBCallback callback); -s32 DVDCancelAll(void); -DVDDiskID* DVDGetCurrentDiskID(void); -BOOL DVDCheckDisk(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); +#include +#include +#include +#include #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_PUBLIC_DVD_H \ No newline at end of file diff --git a/include/dolphin/dvd/dvd.h b/include/dolphin/dvd/dvd.h new file mode 100644 index 000000000..2a0adc52e --- /dev/null +++ b/include/dolphin/dvd/dvd.h @@ -0,0 +1,169 @@ +#ifndef _DOLPHIN_DVD_H +#define _DOLPHIN_DVD_H + +#include "types.h" +#include + +#define DVD_MIN_TRANSFER_SIZE 32 + +#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_FILEINFO_READY 0 +#define DVD_FILEINFO_BUSY 1 + +#define DVD_RESULT_GOOD 0 +#define DVD_RESULT_FATAL_ERROR -1 +#define DVD_RESULT_IGNORED -2 +#define DVD_RESULT_CANCELED -3 + +#define DVD_AIS_SUCCESS 0x0 + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct DVDDiskID +{ + char gameName[4]; + char company[2]; + u8 diskNumber; + u8 gameVersion; + u8 streaming; + u8 streamingBufSize; // 0 = default + u8 padding[22]; // 0's are stored +} DVDDiskID; + +typedef struct DVDCommandBlock DVDCommandBlock; + +typedef void (*DVDCBCallback)(s32 result, DVDCommandBlock *block); + +struct DVDCommandBlock +{ + DVDCommandBlock *next; + DVDCommandBlock *prev; + u32 command; + s32 state; + u32 offset; + u32 length; + void *addr; + u32 currTransferSize; + u32 transferredSize; + DVDDiskID *id; + DVDCBCallback callback; + void *userData; +}; + +typedef struct DVDFileInfo DVDFileInfo; + +typedef void (*DVDCallback)(s32 result, DVDFileInfo *fileInfo); + +struct DVDFileInfo +{ + DVDCommandBlock cb; + u32 startAddr; + u32 length; + DVDCallback callback; +}; + +typedef struct +{ + u32 entryNum; + u32 location; + u32 next; +} DVDDir; + +typedef struct +{ + u32 entryNum; + BOOL isDir; + char *name; +} DVDDirEntry; + +typedef struct DVDDriveInfo +{ + u16 revisionLevel; + u16 deviceCode; + u32 releaseDate; + u8 padding[24]; +} DVDDriveInfo; + +void DVDInit(); +BOOL DVDClose(DVDFileInfo *f); +BOOL DVDSetAutoFatalMessaging(BOOL); +BOOL DVDSetAutoInvalidation(BOOL autoInval); +void DVDPause(); +void DVDReset(); +void DVDResume(); +s32 DVDCancel(DVDCommandBlock *block); + +BOOL DVDFastOpen(s32 entrynum, DVDFileInfo *fileInfo); +s32 DVDGetCommandBlockStatus(const DVDCommandBlock *block); +BOOL DVDCancelAsync(DVDCommandBlock *block, DVDCBCallback callback); +s32 DVDCancel(DVDCommandBlock *block); +BOOL DVDCancelAllAsync(DVDCBCallback callback); +s32 DVDCancelAll(); +BOOL DVDPrepareStreamAsync(DVDFileInfo *fInfo, u32 length, u32 offset, DVDCallback callback); + +BOOL DVDPrepareStreamAbsAsync(DVDCommandBlock *block, u32 length, u32 offset, + DVDCBCallback callback); +s32 DVDPrepareStream(DVDFileInfo *fInfo, u32 length, u32 offset); + +BOOL DVDCancelStreamAsync(DVDCommandBlock *block, DVDCBCallback callback); +s32 DVDCancelStream(DVDCommandBlock *block); + +BOOL DVDStopStreamAtEndAsync(DVDCommandBlock *block, DVDCBCallback callback); +s32 DVDStopStreamAtEnd(DVDCommandBlock *block); + +BOOL DVDGetStreamErrorStatusAsync(DVDCommandBlock *block, DVDCBCallback callback); +s32 DVDGetStreamErrorStatus(DVDCommandBlock *block); + +BOOL DVDGetStreamPlayAddrAsync(DVDCommandBlock *block, DVDCBCallback callback); +s32 DVDGetStreamPlayAddr(DVDCommandBlock *block); + +BOOL DVDInquiryAsync(DVDCommandBlock *block, DVDDriveInfo *info, DVDCBCallback callback); + +BOOL DVDReadDiskID(DVDCommandBlock *block, DVDDiskID *diskID, DVDCBCallback callback); + +s32 DVDGetDriveStatus(); +DVDDiskID *DVDGetCurrentDiskID(); +int DVDCheckDisk(); + +BOOL DVDReadAsyncPrio(DVDFileInfo *fileInfo, void *addr, s32 length, s32 offset, + DVDCallback callback, s32 prio); + +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 __DVDTestAlarm(OSAlarm *alarm); +void __DVDPrepareResetAsync(DVDCBCallback callback); + +#define DVDReadAsync(fileInfo, addr, length, offset, callback) \ + DVDReadAsyncPrio((fileInfo), (addr), (length), (offset), (callback), 2) +#define DVDSeekAsync(fileInfo, offset, callback) \ + DVDSeekAsyncPrio((fileInfo), (offset), (callback), 2) + +BOOL DVDCompareDiskID(DVDDiskID *id1, DVDDiskID *id2); +void __DVDStoreErrorCode(u32 error); +void __DVDPrintFatalMessage(); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_DVD \ No newline at end of file diff --git a/include/dolphin/dvd/dvdfs.h b/include/dolphin/dvd/dvdfs.h new file mode 100644 index 000000000..9a18215b4 --- /dev/null +++ b/include/dolphin/dvd/dvdfs.h @@ -0,0 +1,49 @@ +#ifndef _DOLPHIN_DVDFS_H +#define _DOLPHIN_DVDFS_H + +#include + +#ifdef __cplusplus +extern "C" +{ +// clang-format off +#endif + +// TODO + + +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(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); + +BOOL DVDSeekAsyncPrio(DVDFileInfo *fileInfo, s32 offset, DVDCallback callback, s32 prio); +s32 DVDSeekPrio(DVDFileInfo *fileInfo, s32 offset, s32 prio); + +s32 DVDGetFileInfoStatus(DVDFileInfo *fileInfo); +BOOL DVDFastOpenDir(s32 entrynum, DVDDir *dir); +BOOL DVDOpenDir(char *dirName, DVDDir *dir); +BOOL DVDReadDir(DVDDir *dir, DVDDirEntry *dirent); +BOOL DVDCloseDir(DVDDir *dir); +void DVDRewindDir(DVDDir *dir); +void *DVDGetFSTLocation(); + +BOOL DVDPrepareStreamAsync(DVDFileInfo *fileInfo, u32 length, u32 offset, DVDCallback callback); +s32 DVDPrepareStream(DVDFileInfo *fileInfo, u32 length, u32 offset); + +s32 DVDGetTransferredSize(DVDFileInfo *fileinfo); + +extern OSThreadQueue __DVDThreadQueue; + +#ifdef __cplusplus +} +// clang-format on +#endif + +#endif \ No newline at end of file diff --git a/include/dolphin/dvd/dvdlow.h b/include/dolphin/dvd/dvdlow.h new file mode 100644 index 000000000..ab3d05e0a --- /dev/null +++ b/include/dolphin/dvd/dvdlow.h @@ -0,0 +1,41 @@ +#ifndef _DOLPHIN_DVDLOW_H +#define _DOLPHIN_DVDLOW_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +// clang-format off +#endif + +typedef void (*DVDLowCallback)(u32 intType); + +void __DVDInitWA(); +void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext *context); + +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(); + +DVDLowCallback DVDLowClearCallback(); + +void __DVDLowSetWAType(u32 type, u32 location); +BOOL __DVDLowTestAlarm(OSAlarm *alarm); + +#ifdef __cplusplus +} +// clang-format on +#endif + +#endif \ No newline at end of file diff --git a/include/dolphin/dvd/dvdqueue.h b/include/dolphin/dvd/dvdqueue.h new file mode 100644 index 000000000..2f1b3ceab --- /dev/null +++ b/include/dolphin/dvd/dvdqueue.h @@ -0,0 +1,28 @@ +#ifndef _DOLPHIN_DVDQUEUE_H +#define _DOLPHIN_DVDQUEUE_H + +#include + +#ifdef __cplusplus +extern "C" +{ +// clang-format off +#endif + +typedef void (*DVDOptionalCommandChecker)(DVDCommandBlock* block, void (*cb)(u32 intType)); + +void __DVDClearWaitingQueue(); +BOOL __DVDPushWaitingQueue(s32 prio, DVDCommandBlock *block); +DVDCommandBlock *__DVDPopWaitingQueue(); +BOOL __DVDCheckWaitingQueue(); +BOOL __DVDDequeueWaitingQueue(DVDCommandBlock *block); +BOOL __DVDIsBlockInWaitingQueue(DVDCommandBlock *block); + +DVDCommandBlock* __DVDPopWaitingQueue(); + +#ifdef __cplusplus +} +// clang-format on +#endif + +#endif \ No newline at end of file diff --git a/include/dolphin/eth/eth.h b/include/dolphin/eth/eth.h new file mode 100644 index 000000000..6411d51d8 --- /dev/null +++ b/include/dolphin/eth/eth.h @@ -0,0 +1,72 @@ +#ifndef _DOLPHIN_OS_ETH_H_ +#define _DOLPHIN_OS_ETH_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define ME_NCRA_TXFIFO (1 << 2) + +#define ETH_OK 1 + +#define ETH_TYPE_AUTO 0 +#define ETH_TYPE_100FULL 1 +#define ETH_TYPE_100HALF 2 +#define ETH_TYPE_10FULL 3 +#define ETH_TYPE_10HALF 4 +#define ETH_TYPE_NONE 5 + +typedef struct ETHHeader { + u8 dst[6]; + u8 src[6]; + u16 type; +} ETHHeader; + +typedef struct ETHStat { + u32 rcvcount; + u32 sendcount; + u16 cntof; + u16 re; + u16 te; + u16 fifoe; + u16 rbf; + u16 rx_bf; + u16 rx_crc; + u16 rx_fae; + u16 rx_fo; + u16 rx_rw; + u16 rx_rf; + u16 tx_crs; + u16 tx_uf; + u16 tx_owc; +} ETHStat; + +s32 ETHInit(s32 mode); +void ETHSendAsync(void* addr, s32 length, void (*callback2)(u8)); +void ETHGetMACAddr(u8* macaddr); +void ETHSetMACAddr(u8* macaddr); +void ETHSetRecvCallback(void* (*cb0)(u16, s32, u8), void (*cb1)(u8*, s32)); +BOOL ETHGetLinkStateAsync(BOOL* status); +s32 ETHGetNWAYMode(void); +void ETHSetProtoType(u16* array, s32 num); +void ETHGetStatus(ETHStat* stat); +s32 ETHGetLibraryVersion(void); +s32 ETHGetBBAType(void); +void ETHAddMulticastAddress(const u8* macaddr); +void ETHChangeIntPriority(BOOL flag); +u32 ETHGetREVID(void); +void ETHClearMulticastAddresses(void); + +BOOL __ETHPostSend(u8, void (*)(u8), void*); +BOOL __ETHFilter(u8 *, s32); + +extern OSTime __ETHInterruptTime; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/eth/hashfunc.c b/include/dolphin/eth/hashfunc.c new file mode 100644 index 000000000..250924746 --- /dev/null +++ b/include/dolphin/eth/hashfunc.c @@ -0,0 +1,20 @@ +#include + +static u32 hashfunc(u32 seccode) { + u8 p; + u8 q; + u8 r; + u8 s; + u8 a[sizeof(seccode)]; + u8 dev[sizeof(__devid)]; + + memcpy(a, &seccode, sizeof(seccode)); + memcpy(dev, &__devid, sizeof(__devid)); + + p = (a[0] + a[1] * 0xC1 + 0x18 + __revid) ^ (a[3] * a[2] + 0x90); + q = (a[1] + a[2] + 0x90) ^ (p - 0xC1 + a[0]); + r = (a[2] + 0xC8) ^ (p + ((dev[0] + __revid * 0x23) ^ 0x19)); + s = (a[0] + 0xC1) ^ (a[3] + ((dev[1] + 0xC8) ^ 0x90)); + + return (p << 24) | (q << 16) | (r << 8) | s; +} diff --git a/include/dolphin/exi.h b/include/dolphin/exi.h index f094c3613..47ab75d9a 100644 --- a/include/dolphin/exi.h +++ b/include/dolphin/exi.h @@ -1,78 +1,9 @@ #ifndef _DOLPHIN_EXI_H_ #define _DOLPHIN_EXI_H_ -#include +#include -#ifdef __cplusplus -extern "C" { -#endif - -#define EXI_MEMORY_CARD_59 0x00000004 -#define EXI_MEMORY_CARD_123 0x00000008 -#define EXI_MEMORY_CARD_251 0x00000010 -#define EXI_MEMORY_CARD_507 0x00000020 - -#define EXI_MEMORY_CARD_1019 0x00000040 -#define EXI_MEMORY_CARD_2043 0x00000080 - -#define EXI_MEMORY_CARD_1019A 0x00000140 -#define EXI_MEMORY_CARD_1019B 0x00000240 -#define EXI_MEMORY_CARD_1019C 0x00000340 -#define EXI_MEMORY_CARD_1019D 0x00000440 -#define EXI_MEMORY_CARD_1019E 0x00000540 -#define EXI_MEMORY_CARD_1019F 0x00000640 -#define EXI_MEMORY_CARD_1019G 0x00000740 - -#define EXI_MEMORY_CARD_2043A 0x00000180 -#define EXI_MEMORY_CARD_2043B 0x00000280 -#define EXI_MEMORY_CARD_2043C 0x00000380 -#define EXI_MEMORY_CARD_2043D 0x00000480 -#define EXI_MEMORY_CARD_2043E 0x00000580 -#define EXI_MEMORY_CARD_2043F 0x00000680 -#define EXI_MEMORY_CARD_2043G 0x00000780 - -#define EXI_USB_ADAPTER 0x01010000 -#define EXI_NPDP_GDEV 0x01020000 - -#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 - -#define EXI_MARLIN 0x03010000 - -#define EXI_IS_VIEWER 0x05070000 - -#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 - -typedef void (*EXICallback)(s32 chan, OSContext* context); -typedef struct EXIControl { - EXICallback exiCallback; - EXICallback tcCallback; - EXICallback extCallback; - volatile u32 state; - int immLen; - u8* immBuf; - u32 dev; - u32 id; - s32 idTime; - int items; - struct { - u32 dev; - EXICallback callback; - } queue[3]; -} EXIControl; +typedef void (*EXICallback)(s32 chan, OSContext *context); EXICallback EXISetExiCallback(s32 channel, EXICallback callback); @@ -81,9 +12,9 @@ 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 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); @@ -92,12 +23,5 @@ 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 diff --git a/include/dolphin/gd.h b/include/dolphin/gd.h index 57c929dad..4fcfdcdca 100644 --- a/include/dolphin/gd.h +++ b/include/dolphin/gd.h @@ -1,14 +1,92 @@ -#ifndef _DOLPHIN_GD_H_ -#define _DOLPHIN_GD_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include +#ifndef _DOLPHIN_GD_H +#define _DOLPHIN_GD_H + +#include "dolphin/gx.h" +#include "types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif // ifdef __cplusplus + + //////////////// GD TYPES ////////////////// + // Overflow callback function type. + typedef void (*GDOverflowCallback)(void); + + // Struct for data download (size 0x10). + typedef struct GDCurrentDL + { + u8 *begin; // _00 + s32 length; // _04 + u8 *pDisplayListData; // _08 + u8 *end; // _0C + } GDCurrentDL; + + //////////////////////////////////////////// + + ////////////// GD FUNCTIONS //////////////// + // GD base functions. + void GDInitGDLObj(GDCurrentDL *obj, u8 *start, s32 len); + void GDFlushCurrToMem(); + void GDPadCurr32(); + void GDOverflowed(void); + + // GD geometry functions. + void GDSetVtxDescv(GXVtxDescList *list); + void GDSetArray(GXAttr attr, const void *data, u8 stride); + void GDSetArrayRaw(GXAttr attr, u32 data, u8 stride); + + //////////////////////////////////////////// + + ///////////// GD DECLARATIONS ////////////// + + extern GDCurrentDL *__GDCurrentDL; + extern GDOverflowCallback overflowcb; + + //////////////////////////////////////////// + + /////////// GD HELPER FUNCTIONS //////////// + + static inline void __GDWrite(u8 data) { *__GDCurrentDL->pDisplayListData++ = data; } + + static inline void __GDCheckOverflowed(size_t size) + { + if (__GDCurrentDL->pDisplayListData + size > __GDCurrentDL->end) + { + GDOverflowed(); + } + } + + static inline void __GDSetCurrent(GDCurrentDL *obj) { __GDCurrentDL = obj; } + + static inline void __GDWriteU32(u32 data) + { + __GDWrite((data >> 24) & 0xFF); + __GDWrite((data >> 16) & 0xFF); + __GDWrite((data >> 8) & 0xFF); + __GDWrite((data >> 0) & 0xFF); + } + + static inline void __GDWriteU16(u16 data) + { + __GDWrite((data >> 8) & 0xFF); + __GDWrite((data >> 0) & 0xFF); + } + + static inline void __GDWriteU8(u8 data) { __GDWrite((data >> 0) & 0xFF); } + + static inline void __GDWriteF32(f32 data) + { + __GDWrite(((u8 *)&data)[0]); + __GDWrite(((u8 *)&data)[1]); + __GDWrite(((u8 *)&data)[2]); + __GDWrite(((u8 *)&data)[3]); + } + + //////////////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus #endif diff --git a/include/dolphin/gx.h b/include/dolphin/gx.h index 0e90e543e..b822fb6a6 100644 --- a/include/dolphin/gx.h +++ b/include/dolphin/gx.h @@ -1,40 +1,26 @@ -#ifndef _DOLPHIN_GX_H_ -#define _DOLPHIN_GX_H_ +#ifndef _DOLPHIN_GX +#define _DOLPHIN_GX +#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 #include -#include -#include - -// unsorted GX externs - -#ifdef __cplusplus -extern "C" { -#endif - -// GXMisc -void (*GXSetDrawSyncCallback(void (*cb)(u16)))(u16); -void GXSetDrawSync(u16 token); - -#ifdef __cplusplus -} -#endif +#include +#include +#include +#include +#include -#endif +#endif // _DOLPHIN_GX diff --git a/include/dolphin/gx/GXBump.h b/include/dolphin/gx/GXBump.h index 2a24dc69f..88c7cfba6 100644 --- a/include/dolphin/gx/GXBump.h +++ b/include/dolphin/gx/GXBump.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_GX_GXBUMP_H_ -#define _DOLPHIN_GX_GXBUMP_H_ +#ifndef _DOLPHIN_GXBUMP +#define _DOLPHIN_GXBUMP #include @@ -7,23 +7,20 @@ extern "C" { #endif -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); +void GXSetNumIndStages(u8 nIndStages); +void GXSetIndTexMtx(GXIndTexMtxID mtx_sel, const f32 offset[2][3], s8 scale_exp); +void GXSetIndTexOrder(GXIndTexStageID ind_stage, GXTexCoordID tex_coord, GXTexMapID tex_map); +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 ind_lod, + GXIndTexAlphaSel alpha_sel); +void GXSetTevIndWarp(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXBool signed_offsets, + GXBool replace_mode, GXIndTexMtxID matrix_sel); +void GXSetIndTexCoordScale(GXIndTexStageID ind_state, GXIndTexScale scale_s, GXIndTexScale scale_t); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXBUMP diff --git a/include/dolphin/gx/GXCommandList.h b/include/dolphin/gx/GXCommandList.h index 9adae3cb7..cf3a5172e 100644 --- a/include/dolphin/gx/GXCommandList.h +++ b/include/dolphin/gx/GXCommandList.h @@ -1,37 +1,35 @@ -#ifndef _DOLPHIN_GX_GXCOMMANDLIST_H_ -#define _DOLPHIN_GX_GXCOMMANDLIST_H_ +#ifndef _DOLPHIN_GXCOMMANDLIST +#define _DOLPHIN_GXCOMMANDLIST -#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 +#ifdef __cplusplus +extern "C" { +#endif -#define GX_DRAW_QUADS 0x80 -#define GX_DRAW_TRIANGLES 0x90 +#define GX_NOP 0x00 +#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_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_LOAD_BP_REG 0x61 +#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_OPCODE_MASK 0xF8 -#define GX_VAT_MASK 0x07 +#define GX_CMD_CALL_DL 0x40 +#define GX_CMD_INVL_VC 0x48 -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]; +#define GX_OPCODE_MASK 0xF8 +#define GX_VAT_MASK 0x07 +#ifdef __cplusplus +} #endif + +#endif // _DOLPHIN_GXCOMMANDLIST diff --git a/include/dolphin/gx/GXCull.h b/include/dolphin/gx/GXCull.h index cac438181..b2526e523 100644 --- a/include/dolphin/gx/GXCull.h +++ b/include/dolphin/gx/GXCull.h @@ -1,13 +1,12 @@ -#ifndef _DOLPHIN_GX_GXCULL_H_ -#define _DOLPHIN_GX_GXCULL_H_ +#ifndef _DOLPHIN_GXCULL +#define _DOLPHIN_GXCULL -#include +#include #ifdef __cplusplus extern "C" { #endif -void GXSetScissor(u32 left, u32 top, u32 wd, u32 ht); void GXSetCullMode(GXCullMode mode); void GXSetCoPlanar(GXBool enable); @@ -15,4 +14,4 @@ void GXSetCoPlanar(GXBool enable); } #endif -#endif +#endif // _DOLPHIN_GXCULL diff --git a/include/dolphin/gx/GXDispList.h b/include/dolphin/gx/GXDispList.h index 357fb8f7e..552eda2db 100644 --- a/include/dolphin/gx/GXDispList.h +++ b/include/dolphin/gx/GXDispList.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_GX_GXDISPLIST_H_ -#define _DOLPHIN_GX_GXDISPLIST_H_ +#ifndef _DOLPHIN_GXDISPLIST +#define _DOLPHIN_GXDISPLIST #include @@ -9,10 +9,10 @@ extern "C" { void GXBeginDisplayList(void* list, u32 size); u32 GXEndDisplayList(void); -void GXCallDisplayList(void* list, u32 nbytes); +void GXCallDisplayList(const void* list, u32 nbytes); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXDISPLIST diff --git a/include/dolphin/gx/GXDraw.h b/include/dolphin/gx/GXDraw.h index c8e779345..542460be1 100644 --- a/include/dolphin/gx/GXDraw.h +++ b/include/dolphin/gx/GXDraw.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_GX_GXDRAW_H_ -#define _DOLPHIN_GX_GXDRAW_H_ +#ifndef _DOLPHIN_GXDRAW +#define _DOLPHIN_GXDRAW #include @@ -7,18 +7,12 @@ 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); +void GXDrawCylinder(u8 numEdges); +void GXDrawCube(); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXDRAW diff --git a/include/dolphin/gx/GXEnum.h b/include/dolphin/gx/GXEnum.h index db4ea87d2..e69c621b7 100644 --- a/include/dolphin/gx/GXEnum.h +++ b/include/dolphin/gx/GXEnum.h @@ -1,8 +1,12 @@ -#ifndef _DOLPHIN_GX_GXENUM_H_ -#define _DOLPHIN_GX_GXENUM_H_ +#ifndef _DOLPHIN_GXENUM +#define _DOLPHIN_GXENUM #include +#ifdef __cplusplus +extern "C" { +#endif + typedef u8 GXBool; #define GX_FALSE ((GXBool)0) @@ -12,889 +16,890 @@ typedef u8 GXBool; #define GX_DISABLE ((GXBool)0) typedef enum _GXProjectionType { - GX_PERSPECTIVE, - GX_ORTHOGRAPHIC, + GX_PERSPECTIVE, + GX_ORTHOGRAPHIC, } GXProjectionType; typedef enum _GXCompare { - GX_NEVER, - GX_LESS, - GX_EQUAL, - GX_LEQUAL, - GX_GREATER, - GX_NEQUAL, - GX_GEQUAL, - GX_ALWAYS, + GX_NEVER, + GX_LESS, + GX_EQUAL, + GX_LEQUAL, + GX_GREATER, + GX_NEQUAL, + GX_GEQUAL, + GX_ALWAYS, } GXCompare; typedef enum _GXAlphaOp { - GX_AOP_AND, - GX_AOP_OR, - GX_AOP_XOR, - GX_AOP_XNOR, - GX_MAX_ALPHAOP, + GX_AOP_AND, + GX_AOP_OR, + GX_AOP_XOR, + GX_AOP_XNOR, + GX_MAX_ALPHAOP, } GXAlphaOp; +typedef enum _GXFBClamp { + GX_CLAMP_NONE, + GX_CLAMP_TOP, + GX_CLAMP_BOTTOM, +} GXFBClamp; + typedef enum _GXZFmt16 { - GX_ZC_LINEAR, - GX_ZC_NEAR, - GX_ZC_MID, - GX_ZC_FAR, + GX_ZC_LINEAR, + GX_ZC_NEAR, + GX_ZC_MID, + GX_ZC_FAR, } GXZFmt16; typedef enum _GXGamma { - GX_GM_1_0, - GX_GM_1_7, - GX_GM_2_2, + GX_GM_1_0, + GX_GM_1_7, + GX_GM_2_2, } GXGamma; 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, + 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; typedef enum _GXPrimitive { - GX_QUADS = 0x80, - GX_TRIANGLES = 0x90, - GX_TRIANGLESTRIP = 0x98, - GX_TRIANGLEFAN = 0xA0, - GX_LINES = 0xA8, - GX_LINESTRIP = 0xB0, - GX_POINTS = 0xB8, + GX_QUADS = 0x80, + GX_TRIANGLES = 0x90, + GX_TRIANGLESTRIP = 0x98, + GX_TRIANGLEFAN = 0xA0, + GX_LINES = 0xA8, + GX_LINESTRIP = 0xB0, + GX_POINTS = 0xB8, } GXPrimitive; typedef enum _GXVtxFmt { - GX_VTXFMT0, - GX_VTXFMT1, - GX_VTXFMT2, - GX_VTXFMT3, - GX_VTXFMT4, - GX_VTXFMT5, - GX_VTXFMT6, - GX_VTXFMT7, - GX_MAX_VTXFMT, + GX_VTXFMT0, + GX_VTXFMT1, + GX_VTXFMT2, + GX_VTXFMT3, + GX_VTXFMT4, + GX_VTXFMT5, + GX_VTXFMT6, + GX_VTXFMT7, + GX_MAX_VTXFMT, } GXVtxFmt; 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, + 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; +#define GX_MAX_VTXDESCLIST_SZ (GX_VA_MAX_ATTR + 1) + typedef enum _GXAttrType { - GX_NONE, - GX_DIRECT, - GX_INDEX8, - GX_INDEX16, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + GX_MODULATE, + GX_DECAL, + GX_BLEND, + GX_REPLACE, + GX_PASSCLR, } GXTevMode; typedef enum _GXTexMtxType { - GX_MTX3x4, - GX_MTX2x4, + GX_MTX3x4, + GX_MTX2x4, } GXTexMtxType; typedef enum _GXTexGenType { - 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, + 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 _GXPosNrmMtx { - 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, + 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, - 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, + 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, + 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, + 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, + GX_MAX_TEXGENSRC, } GXTexGenSrc; typedef enum _GXBlendMode { - GX_BM_NONE, - GX_BM_BLEND, - GX_BM_LOGIC, - GX_BM_SUBTRACT, - GX_MAX_BLENDMODE, + 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, + 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, + 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, + 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, + 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, - 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, + 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 _GXTevRegID { - GX_TEVPREV, - GX_TEVREG0, - GX_TEVREG1, - GX_TEVREG2, - GX_MAX_TEVREG, + GX_TEVPREV, + GX_TEVREG0, + GX_TEVREG1, + GX_TEVREG2, + GX_MAX_TEVREG, } GXTevRegID; typedef enum _GXDiffuseFn { - GX_DF_NONE, - GX_DF_SIGN, - GX_DF_CLAMP, + GX_DF_NONE, + GX_DF_SIGN, + GX_DF_CLAMP, } GXDiffuseFn; typedef enum _GXColorSrc { - GX_SRC_REG, - GX_SRC_VTX, + GX_SRC_REG, + GX_SRC_VTX, } GXColorSrc; typedef enum _GXAttnFn { - GX_AF_SPEC, - GX_AF_SPOT, - GX_AF_NONE, + 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, + 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, + 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, + 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, + 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 + 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 + 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 + 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, + 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 = GX_FOG_PERSP_LIN, + GX_FOG_EXP = GX_FOG_PERSP_EXP, + GX_FOG_EXP2 = GX_FOG_PERSP_EXP2, + GX_FOG_REVEXP = GX_FOG_PERSP_REVEXP, + GX_FOG_REVEXP2 = GX_FOG_PERSP_REVEXP2, } 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, + GX_CC_CPREV, + GX_CC_APREV, + GX_CC_C0, + GX_CC_A0, + GX_CC_C1, + GX_CC_A1, + GX_CC_C2, + GX_CC_A2, + GX_CC_TEXC, + GX_CC_TEXA, + GX_CC_RASC, + GX_CC_RASA, + GX_CC_ONE, + GX_CC_HALF, + GX_CC_KONST, + GX_CC_ZERO, } 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, + GX_CA_APREV, + GX_CA_A0, + GX_CA_A1, + GX_CA_A2, + GX_CA_TEXA, + GX_CA_RASA, + GX_CA_KONST, + GX_CA_ZERO, } 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 + 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 + 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 + 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 + GX_TEV_KCSEL_8_8 = 0x00, + GX_TEV_KCSEL_7_8 = 0x01, + GX_TEV_KCSEL_6_8 = 0x02, + GX_TEV_KCSEL_5_8 = 0x03, + GX_TEV_KCSEL_4_8 = 0x04, + GX_TEV_KCSEL_3_8 = 0x05, + GX_TEV_KCSEL_2_8 = 0x06, + GX_TEV_KCSEL_1_8 = 0x07, + GX_TEV_KCSEL_1 = GX_TEV_KCSEL_8_8, + GX_TEV_KCSEL_3_4 = GX_TEV_KCSEL_6_8, + GX_TEV_KCSEL_1_2 = GX_TEV_KCSEL_4_8, + GX_TEV_KCSEL_1_4 = GX_TEV_KCSEL_2_8, + 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 + GX_TEV_KASEL_8_8 = 0x00, + GX_TEV_KASEL_7_8 = 0x01, + GX_TEV_KASEL_6_8 = 0x02, + GX_TEV_KASEL_5_8 = 0x03, + GX_TEV_KASEL_4_8 = 0x04, + GX_TEV_KASEL_3_8 = 0x05, + GX_TEV_KASEL_2_8 = 0x06, + GX_TEV_KASEL_1_8 = 0x07, + GX_TEV_KASEL_1 = GX_TEV_KASEL_8_8, + GX_TEV_KASEL_3_4 = GX_TEV_KASEL_6_8, + GX_TEV_KASEL_1_2 = GX_TEV_KASEL_4_8, + GX_TEV_KASEL_1_4 = GX_TEV_KASEL_2_8, + 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 + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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 _GXPerf0 { - 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, - 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, - 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, - GX_PERF0_NONE, -} GXPerf0; - -typedef enum _GXPerf1 { - 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, - 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, - GX_PERF1_CALL_REQ, - GX_PERF1_VC_MISS_REQ, - GX_PERF1_CP_ALL_REQ, - - GX_PERF1_CLOCKS, - GX_PERF1_NONE, -} GXPerf1; - -typedef enum _GXVCachePerf { - GX_VC_POS = 0, - GX_VC_NRM = 1, - GX_VC_CLR0 = 2, - GX_VC_CLR1 = 3, - GX_VC_TEX0 = 4, - GX_VC_TEX1 = 5, - GX_VC_TEX2 = 6, - GX_VC_TEX3 = 7, - GX_VC_TEX4 = 8, - GX_VC_TEX5 = 9, - GX_VC_TEX6 = 10, - GX_VC_TEX7 = 11, - GX_VC_ALL = 15, -} GXVCachePerf; - typedef enum _GXClipMode { - GX_CLIP_ENABLE = 0, - GX_CLIP_DISABLE = 1, + GX_CLIP_ENABLE = 0, + GX_CLIP_DISABLE = 1, } GXClipMode; -typedef enum _GXFBClamp { - GX_CLAMP_NONE = 0, - GX_CLAMP_TOP = 1, - GX_CLAMP_BOTTOM = 2, -} GXFBClamp; - -typedef enum _GXCopyMode { - GX_COPY_PROGRESSIVE = 0, - GX_COPY_INTLC_EVEN = 2, - GX_COPY_INTLC_ODD = 3, -} GXCopyMode; - -typedef enum _GXAlphaReadMode { - GX_READ_00, - GX_READ_FF, - GX_READ_NONE, -} GXAlphaReadMode; - -typedef enum _GXTexCacheSize { - GX_TEXCACHE_32K, - GX_TEXCACHE_128K, - GX_TEXCACHE_512K, - GX_TEXCACHE_NONE, -} GXTexCacheSize; - 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, + GX_TLUT0 = 0, + GX_TLUT1 = 1, + GX_TLUT2 = 2, + GX_TLUT3 = 3, + GX_TLUT4 = 4, + GX_TLUT5 = 5, + GX_TLUT6 = 6, + GX_TLUT7 = 7, + GX_TLUT8 = 8, + GX_TLUT9 = 9, + GX_TLUT10 = 10, + GX_TLUT11 = 11, + GX_TLUT12 = 12, + GX_TLUT13 = 13, + GX_TLUT14 = 14, + GX_TLUT15 = 15, + GX_BIGTLUT0 = 16, + GX_BIGTLUT1 = 17, + GX_BIGTLUT2 = 18, + GX_BIGTLUT3 = 19, } GXTlut; typedef enum _GXTlutFmt { - GX_TL_IA8, - GX_TL_RGB565, - GX_TL_RGB5A3, - GX_MAX_TLUTFMT, + GX_TL_IA8, + GX_TL_RGB565, + GX_TL_RGB5A3, + GX_MAX_TLUTFMT, } GXTlutFmt; 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, + 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; typedef enum _GXMiscToken { - GX_MT_XF_FLUSH = 1, - GX_MT_DL_SAVE_CONTEXT = 2, - GX_MT_ABORT_WAIT_COPYOUT = 3, - GX_MT_NULL = 0, + GX_MT_NULL = 0, + GX_MT_XF_FLUSH = 1, + GX_MT_DL_SAVE_CONTEXT = 2, + GX_MT_ABORT_WAIT_COPYOUT = 3, } GXMiscToken; +typedef enum _GXTexCacheSize { + GX_TEXCACHE_32K, + GX_TEXCACHE_128K, + GX_TEXCACHE_512K, + GX_TEXCACHE_NONE +} GXTexCacheSize; + +typedef enum _GXPerf0 { + 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, + 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, + 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, + GX_PERF0_NONE + +} GXPerf0; + +typedef enum _GXPerf1 { + 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, + 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, + GX_PERF1_CALL_REQ, + GX_PERF1_VC_MISS_REQ, + GX_PERF1_CP_ALL_REQ, + + GX_PERF1_CLOCKS, + GX_PERF1_NONE + +} GXPerf1; + +typedef enum _GXVCachePerf { + GX_VC_POS, + GX_VC_NRM, + GX_VC_CLR0, + GX_VC_CLR1, + GX_VC_TEX0, + GX_VC_TEX1, + GX_VC_TEX2, + GX_VC_TEX3, + GX_VC_TEX4, + GX_VC_TEX5, + GX_VC_TEX6, + GX_VC_TEX7, + GX_VC_ALL = 0xf + +} GXVCachePerf; + +#ifdef __cplusplus +} #endif + +#endif // _DOLPHIN_GXENUM diff --git a/include/dolphin/gx/GXFifo.h b/include/dolphin/gx/GXFifo.h index 069f36a4e..85d61685b 100644 --- a/include/dolphin/gx/GXFifo.h +++ b/include/dolphin/gx/GXFifo.h @@ -1,46 +1,37 @@ -#ifndef _DOLPHIN_GX_GXFIFO_H_ -#define _DOLPHIN_GX_GXFIFO_H_ +#ifndef _DOLPHIN_GXFIFO +#define _DOLPHIN_GXFIFO #include -#include #ifdef __cplusplus extern "C" { #endif typedef struct { - u8 pad[128]; + u8 pad[128]; } GXFifoObj; typedef void (*GXBreakPtCallback)(void); void GXInitFifoBase(GXFifoObj* fifo, void* base, u32 size); void GXInitFifoPtrs(GXFifoObj* fifo, void* readPtr, void* writePtr); -void GXInitFifoLimits(GXFifoObj* fifo, u32 hiWatermark, u32 loWatermark); +void GXGetFifoPtrs(GXFifoObj* fifo, void** readPtr, void** writePtr); +GXFifoObj* GXGetCPUFifo(void); +GXFifoObj* GXGetGPFifo(void); void GXSetCPUFifo(GXFifoObj* fifo); void GXSetGPFifo(GXFifoObj* fifo); void GXSaveCPUFifo(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); +void GXGetFifoStatus(GXFifoObj* fifo, GXBool* overhi, GXBool* underlow, u32* fifoCount, + GXBool* cpu_write, GXBool* gp_read, GXBool* fifowrap); +void GXGetGPStatus(GXBool* overhi, GXBool* underlow, GXBool* readIdle, GXBool* cmdIdle, + GXBool* brkpt); +void GXInitFifoLimits(GXFifoObj* fifo, u32 hiWaterMark, u32 loWaterMark); GXBreakPtCallback GXSetBreakPtCallback(GXBreakPtCallback cb); -void GXEnableBreakPt(void* break_pt); +void GXEnableBreakPt(void* breakPt); 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 +#endif // _DOLPHIN_GXFIFO diff --git a/include/dolphin/gx/GXFrameBuffer.h b/include/dolphin/gx/GXFrameBuffer.h index 73b513fa3..2579fc00f 100644 --- a/include/dolphin/gx/GXFrameBuffer.h +++ b/include/dolphin/gx/GXFrameBuffer.h @@ -1,15 +1,13 @@ -#ifndef _DOLPHIN_GX_GXFRAMEBUFFER_H_ -#define _DOLPHIN_GX_GXFRAMEBUFFER_H_ +#ifndef _DOLPHIN_GXFRAMEBUFFER +#define _DOLPHIN_GXFRAMEBUFFER -#include #include +#include #ifdef __cplusplus extern "C" { #endif -#define GX_MAX_Z24 0x00ffffff - extern GXRenderModeObj GXNtsc240Ds; extern GXRenderModeObj GXNtsc240DsAa; extern GXRenderModeObj GXNtsc240Int; @@ -18,6 +16,7 @@ extern GXRenderModeObj GXNtsc480IntDf; extern GXRenderModeObj GXNtsc480Int; extern GXRenderModeObj GXNtsc480IntAa; extern GXRenderModeObj GXNtsc480Prog; +extern GXRenderModeObj GXNtsc480ProgSoft; extern GXRenderModeObj GXNtsc480ProgAa; extern GXRenderModeObj GXMpal240Ds; extern GXRenderModeObj GXMpal240DsAa; @@ -32,7 +31,7 @@ extern GXRenderModeObj GXPal264Int; extern GXRenderModeObj GXPal264IntAa; extern GXRenderModeObj GXPal528IntDf; extern GXRenderModeObj GXPal528Int; -extern GXRenderModeObj GXPal528IntAa; +extern GXRenderModeObj GXPal524IntAa; extern GXRenderModeObj GXEurgb60Hz240Ds; extern GXRenderModeObj GXEurgb60Hz240DsAa; extern GXRenderModeObj GXEurgb60Hz240Int; @@ -41,26 +40,27 @@ extern GXRenderModeObj GXEurgb60Hz480IntDf; extern GXRenderModeObj GXEurgb60Hz480Int; extern GXRenderModeObj GXEurgb60Hz480IntAa; -void GXAdjustForOverscan(const GXRenderModeObj* rmin, GXRenderModeObj* rmout, u16 hor, u16 ver); +#define GX_MAX_Z24 0x00FFFFFF + +void GXSetCopyClear(GXColor clear_clr, u32 clear_z); +void GXAdjustForOverscan(GXRenderModeObj* rmin, GXRenderModeObj* rmout, u16 hor, u16 ver); +void GXCopyDisp(void* dest, GXBool clear); +void GXSetDispCopyGamma(GXGamma gamma); 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); +f32 GXGetYScaleFactor(u16 efbHeight, u16 xfbHeight); 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); +void GXSetCopyFilter(GXBool aa, u8 sample_pattern[12][2], GXBool vf, u8 vfilter[7]); +void GXSetPixelFmt(GXPixelFmt pix_fmt, GXZFmt16 z_fmt); +void GXSetTexCopySrc(u16 left, u16 top, u16 wd, u16 ht); +void GXSetTexCopyDst(u16 wd, u16 ht, GXTexFmt fmt, GXBool mipmap); +void GXCopyTex(void* dest, GXBool clear); + +void GXSetCopyClamp(GXFBClamp clamp); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXFRAMEBUFFER diff --git a/include/dolphin/gx/GXGeometry.h b/include/dolphin/gx/GXGeometry.h index d9f47ba8d..870e7d2e9 100644 --- a/include/dolphin/gx/GXGeometry.h +++ b/include/dolphin/gx/GXGeometry.h @@ -1,63 +1,33 @@ -#ifndef _DOLPHIN_GX_GXGEOMETRY_H_ -#define _DOLPHIN_GX_GXGEOMETRY_H_ +#ifndef _DOLPHIN_GXGEOMETRY +#define _DOLPHIN_GXGEOMETRY #include -#include #ifdef __cplusplus extern "C" { #endif -void __GXCalculateVLim(); void GXSetVtxDesc(GXAttr attr, GXAttrType type); -void GXSetVtxDescv(const GXVtxDescList* attrPtr); +void GXSetVtxDescv(GXVtxDescList* list); 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 -} - -static inline void GXTexCoord2s16(int r3, int r4) // possible inline req. -{ - int ptr = 0xcc010000; - *(short*)((char*)(ptr) - 0x8000) = r3; - *(short*)((char*)(ptr) - 0x8000) = r4; -} - - -static inline void GXPosition3s16(int r3, int r4, int r5) // possible inline req. -{ - int ptr = 0xcc010000; - *(short*)((char*)(ptr) - 0x8000) = r3; - *(short*)((char*)(ptr) - 0x8000) = r4; - *(short*)((char*)(ptr) - 0x8000) = r5; -} - +void GXSetTexCoordGen2(GXTexCoordID dst_coord, GXTexGenType func, GXTexGenSrc src_param, u32 mtx, + GXBool normalize, u32 postmtx); void GXSetLineWidth(u8 width, GXTexOffset texOffsets); void GXSetPointSize(u8 pointSize, GXTexOffset texOffsets); -void GXEnableTexOffsets(GXTexCoordID coord, u8 line_enable, u8 point_enable); +void GXEnableTexOffsets(GXTexCoordID coord, GXBool line_enable, GXBool point_enable); +void GXSetArray(GXAttr attr, const void* data, u8 stride); +void GXInvalidateVtxCache(void); + +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); +} #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXGEOMETRY diff --git a/include/dolphin/gx/GXGet.h b/include/dolphin/gx/GXGet.h index d1ba630a4..487043144 100644 --- a/include/dolphin/gx/GXGet.h +++ b/include/dolphin/gx/GXGet.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_GX_GXGET_H_ -#define _DOLPHIN_GX_GXGET_H_ +#ifndef _DOLPHIN_GXGET +#define _DOLPHIN_GXGET #include #include @@ -8,57 +8,22 @@ 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); +GXBool GXGetTexObjMipMap(const GXTexObj* obj); +GXTexFmt GXGetTexObjFmt(const GXTexObj* obj); +u16 GXGetTexObjHeight(const GXTexObj* obj); +u16 GXGetTexObjWidth(const GXTexObj* obj); +GXTexWrapMode GXGetTexObjWrapS(const GXTexObj* obj); +GXTexWrapMode GXGetTexObjWrapT(const GXTexObj* obj); 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* GXGetTexObjData(const GXTexObj* obj); +void GXGetProjectionv(f32* p); 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); +void GXGetVtxAttrFmt(GXVtxFmt idx, GXAttr attr, GXCompCnt* compCnt, GXCompType* compType, + u8* shift); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXGET diff --git a/include/dolphin/gx/GXLighting.h b/include/dolphin/gx/GXLighting.h index 83c5aae42..a7e0ccc67 100644 --- a/include/dolphin/gx/GXLighting.h +++ b/include/dolphin/gx/GXLighting.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_GX_GXLIGHTING_H_ -#define _DOLPHIN_GX_GXLIGHTING_H_ +#ifndef _DOLPHIN_GXLIGHTING +#define _DOLPHIN_GXLIGHTING #include #include @@ -8,25 +8,25 @@ 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 GXSetNumChans(u8 nChans); +void GXSetChanCtrl(GXChannelID chan, GXBool enable, GXColorSrc amb_src, GXColorSrc mat_src, + u32 light_mask, GXDiffuseFn diff_fn, GXAttnFn attn_fn); +void GXSetChanAmbColor(GXChannelID chan, GXColor amb_color); +void GXSetChanMatColor(GXChannelID chan, GXColor mat_color); + 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 GXInitLightDistAttn(GXLightObj* lt_obj, f32 ref_distance, f32 ref_brightness, + 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); +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 GXLoadLightObjImm(GXLightObj* lt_obj, GXLightID light); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXLIGHTING diff --git a/include/dolphin/gx/GXManage.h b/include/dolphin/gx/GXManage.h index fd899d361..ab3a72c84 100644 --- a/include/dolphin/gx/GXManage.h +++ b/include/dolphin/gx/GXManage.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_GX_GXMANAGE_H_ -#define _DOLPHIN_GX_GXMANAGE_H_ +#ifndef _DOLPHIN_GXMANAGE +#define _DOLPHIN_GXMANAGE #include @@ -7,30 +7,18 @@ 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); +GXDrawDoneCallback GXSetDrawDoneCallback(GXDrawDoneCallback cb); void GXDrawDone(void); +void GXSetDrawDone(void); +void GXFlush(void); void GXPixModeSync(void); -void GXTexModeSync(void); -GXDrawSyncCallback GXSetDrawSyncCallback(GXDrawSyncCallback cb); -GXDrawDoneCallback GXSetDrawDoneCallback(GXDrawDoneCallback cb); +void GXSetMisc(GXMiscToken token, u32 val); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXMANAGE diff --git a/include/dolphin/gx/GXMisc.h b/include/dolphin/gx/GXMisc.h new file mode 100644 index 000000000..809a61ae4 --- /dev/null +++ b/include/dolphin/gx/GXMisc.h @@ -0,0 +1,21 @@ +#ifndef RVL_SDK_GX_MISC_H +#define RVL_SDK_GX_MISC_H +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +void GXSetMisc(GXMiscToken token, u32 val); +void GXFlush(); +void GXResetWriteGatherPipe(); +void GXPeekARGB(u16 x, u16 y, u32 *color); + +void GXAbortFrame(); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/include/dolphin/gx/GXPerf.h b/include/dolphin/gx/GXPerf.h index bd1b474aa..c3850dc3c 100644 --- a/include/dolphin/gx/GXPerf.h +++ b/include/dolphin/gx/GXPerf.h @@ -1,30 +1,16 @@ -#ifndef _DOLPHIN_GX_GXPERF_H_ -#define _DOLPHIN_GX_GXPERF_H_ +#ifndef _DOLPHIN_GXPERF +#define _DOLPHIN_GXPERF -#include +#include #ifdef __cplusplus extern "C" { #endif -void GXSetGPMetric(GXPerf0 perf0, GXPerf1 perf1); -void GXReadGPMetric(u32* cnt0, u32* cnt1); -void GXClearGPMetric(void); -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 +#endif // _DOLPHIN_GXPERF diff --git a/include/dolphin/gx/GXPixel.h b/include/dolphin/gx/GXPixel.h index d61838d1a..7dfae08fb 100644 --- a/include/dolphin/gx/GXPixel.h +++ b/include/dolphin/gx/GXPixel.h @@ -1,17 +1,17 @@ -#ifndef _DOLPHIN_GX_GXPIXEL_H_ -#define _DOLPHIN_GX_GXPIXEL_H_ +#ifndef _DOLPHIN_GXPIXEL +#define _DOLPHIN_GXPIXEL #include -#include #ifdef __cplusplus extern "C" { #endif 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 GXSetFogColor(GXColor color); +// ? GXSetFogRangeAdj(); +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); @@ -19,12 +19,11 @@ 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); +// ? GXSetFieldMask(); +// ? GXSetFieldMode(); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXPIXEL diff --git a/include/dolphin/gx/GXPriv.h b/include/dolphin/gx/GXPriv.h new file mode 100644 index 000000000..db0286b80 --- /dev/null +++ b/include/dolphin/gx/GXPriv.h @@ -0,0 +1,38 @@ +#ifndef _DOLPHIN_GXPRIV +#define _DOLPHIN_GXPRIV + +#include "dolphin/gx/GXVert.h" + +typedef struct GXLightObj_ { + u32 padding[3]; + u32 color; + float a0; + float a1; + float a2; + float k0; + float k1; + float k2; + float px; + float py; + float pz; + float nx; + float ny; + float nz; +} GXLightObj_; + +#define XF_LIGHT_BASE 0x0600 +#define XF_LIGHT_SIZE 0x10 + +#define GX_FIFO_ADDR 0xCC008000 + +#define GX_WRITE_U8(v) (GXWGFifo.u8 = v) +#define GX_WRITE_U32(v) (GXWGFifo.u32 = v) + +typedef struct GXData { + u16 cpSRreg; + u16 cpCRreg; +} GXData; + +extern GXData* __GXData; + +#endif // _DOLPHIN_GXPRIV diff --git a/include/dolphin/gx/GXStruct.h b/include/dolphin/gx/GXStruct.h index 0e7dc0be6..8ba5ba1b4 100644 --- a/include/dolphin/gx/GXStruct.h +++ b/include/dolphin/gx/GXStruct.h @@ -1,75 +1,82 @@ -#ifndef _DOLPHIN_GX_GXSTRUCT_H_ -#define _DOLPHIN_GX_GXSTRUCT_H_ +#ifndef _DOLPHIN_GXSTRUCT +#define _DOLPHIN_GXSTRUCT #include -#include +#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]; + VITVMode viTVmode; + u16 fbWidth; + u16 efbHeight; + u16 xfbHeight; + u16 viXOrigin; + u16 viYOrigin; + u16 viWidth; + u16 viHeight; + VIXFBMode xFBmode; + u8 field_rendering; + u8 aa; + u8 sample_pattern[12][2]; + u8 vfilter[7]; } GXRenderModeObj; typedef struct _GXColor { - u8 r, g, b, a; + u8 r; + u8 g; + u8 b; + u8 a; } GXColor; -typedef struct _GXColorS10 { - s16 r, g, b, a; -} GXColorS10; - typedef struct _GXTexObj { - u32 dummy[8]; + u32 dummy[8]; } GXTexObj; +typedef struct _GXTlutObj { + u32 dummy[3]; +} GXTlutObj; + typedef struct _GXLightObj { - u32 dummy[16]; + u32 dummy[16]; } GXLightObj; +typedef struct _GXVtxDescList { + GXAttr attr; + GXAttrType type; +} GXVtxDescList; + +typedef struct _GXVtxAttrFmtList { + GXAttr attr; + GXCompCnt cnt; + GXCompType type; + u8 frac; +} GXVtxAttrFmtList; + +typedef struct _GXColorS10 { + s16 r; + s16 g; + s16 b; + s16 a; +} GXColorS10; + typedef struct _GXTexRegion { - u32 dummy[4]; + u32 dummy[4]; } GXTexRegion; -typedef struct _GXTlutObj { - u32 dummy[3]; -} GXTlutObj; - typedef struct _GXTlutRegion { - u32 dummy[4]; + u32 dummy[4]; } GXTlutRegion; typedef struct _GXFogAdjTable { - u16 r[10]; + u16 fogVals[10]; // _00 } 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 +#endif // _DOLPHIN_GXSTRUCT diff --git a/include/dolphin/gx/GXTev.h b/include/dolphin/gx/GXTev.h index 8deb22d08..01290a9d5 100644 --- a/include/dolphin/gx/GXTev.h +++ b/include/dolphin/gx/GXTev.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_GX_GXTEV_H_ -#define _DOLPHIN_GX_GXTEV_H_ +#ifndef _DOLPHIN_GXTEV +#define _DOLPHIN_GXTEV #include #include @@ -9,18 +9,22 @@ 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 sel); void GXSetTevKAlphaSel(GXTevStageID stage, GXTevKAlphaSel sel); void GXSetTevSwapMode(GXTevStageID stage, GXTevSwapSel ras_sel, GXTevSwapSel tex_sel); -void GXSetTevSwapModeTable(GXTevSwapSel table, GXTevColorChan red, GXTevColorChan green, GXTevColorChan blue, GXTevColorChan alpha); -void GXSetTevClampMode(void); +void GXSetTevSwapModeTable(GXTevSwapSel table, GXTevColorChan red, GXTevColorChan green, + GXTevColorChan blue, GXTevColorChan alpha); 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); @@ -30,4 +34,4 @@ void GXSetNumTevStages(u8 nStages); } #endif -#endif +#endif // _DOLPHIN_GXTEV diff --git a/include/dolphin/gx/GXTexture.h b/include/dolphin/gx/GXTexture.h index f42dc2295..76bae19c1 100644 --- a/include/dolphin/gx/GXTexture.h +++ b/include/dolphin/gx/GXTexture.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_GX_GXTEXTURE_H_ -#define _DOLPHIN_GX_GXTEXTURE_H_ +#ifndef _DOLPHIN_GXTEXTURE +#define _DOLPHIN_GXTEXTURE #include #include @@ -8,45 +8,30 @@ extern "C" { #endif -typedef GXTexRegion *(*GXTexRegionCallback)(GXTexObj* t_obj, GXTexMapID id); -typedef GXTlutRegion *(*GXTlutRegionCallback)(u32 idx); +typedef GXTexRegion* (*GXTexRegionCallback)(const GXTexObj* obj, GXTexMapID id); -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 GXInitTexObj(GXTexObj* obj, void* image_ptr, u16 width, u16 height, GXTexFmt format, + GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, GXBool mipmap); +void GXInitTexObjCI(GXTexObj* obj, const void* data, u16 width, u16 height, GXCITexFmt format, + GXTexWrapMode wrapS, GXTexWrapMode wrapT, GXBool mipmap, u32 tlut); +void GXInitTexObjData(GXTexObj* obj, const void* data); +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 GXLoadTexObj(GXTexObj* obj, GXTexMapID id); -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 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); +u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, GXBool mipmap, u8 max_lod); +void GXInvalidateTexAll(); +void GXInitTexObjWrapMode(GXTexObj* obj, GXTexWrapMode s, GXTexWrapMode t); +void GXInitTlutObj(GXTlutObj* obj, const void* data, GXTlutFmt format, u16 entries); +void GXLoadTlut(const GXTlutObj* obj, u32 idx); +void GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 ss, u16 ts); +void GXInitTexCacheRegion(GXTexRegion* region, GXBool is_32b_mipmap, u32 tmem_even, + GXTexCacheSize size_even, u32 tmem_odd, GXTexCacheSize size_odd); +GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback callback); +void GXInvalidateTexRegion(const GXTexRegion* region); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXTEXTURE diff --git a/include/dolphin/gx/GXTransform.h b/include/dolphin/gx/GXTransform.h index 1e7f94e57..3d15e5e66 100644 --- a/include/dolphin/gx/GXTransform.h +++ b/include/dolphin/gx/GXTransform.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_GX_GXTRANSFORM_H_ -#define _DOLPHIN_GX_GXTRANSFORM_H_ +#ifndef _DOLPHIN_GXTRANSFORM +#define _DOLPHIN_GXTRANSFORM #include @@ -7,28 +7,22 @@ extern "C" { #endif -#define GX_PROJECTION_SZ 7 -#define GX_VIEWPORT_SZ 6 +#define GX_PROJECTION_SZ 7 -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 GXSetProjection(f32 mtx[4][4], GXProjectionType type); +void GXLoadPosMtxImm(f32 mtx[3][4], u32 id); +void GXLoadNrmMtxImm(f32 mtx[3][4], u32 id); +void GXLoadTexMtxImm(f32 mtx[][4], u32 id, GXTexMtxType type); +void GXSetViewport(f32 left, f32 top, f32 wd, f32 ht, f32 nearz, f32 farz); void GXSetCurrentMtx(u32 id); -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 GXSetScissor(u32 left, u32 top, u32 wd, u32 ht); +void GXGetScissor(u32 *x, u32 *y, u32 *w, u32 *h); void GXSetClipMode(GXClipMode mode); -void GXSetZScaleOffset(f32 scale, f32 offset); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXTRANSFORM diff --git a/include/dolphin/gx/GXVert.h b/include/dolphin/gx/GXVert.h index edb245cbc..7bce7e4ac 100644 --- a/include/dolphin/gx/GXVert.h +++ b/include/dolphin/gx/GXVert.h @@ -1,8 +1,7 @@ -#ifndef _DOLPHIN_GX_GXVERT_H_ -#define _DOLPHIN_GX_GXVERT_H_ +#ifndef _DOLPHIN_GXVERT +#define _DOLPHIN_GXVERT #include -#include #ifdef __cplusplus extern "C" { @@ -11,130 +10,108 @@ extern "C" { #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; + 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); +/*volatile*/ PPCWGPipe GXWGFifo : GXFIFO_ADDR; #else -#define GXWGFifo (*(volatile PPCWGPipe *)GXFIFO_ADDR) +#define GXWGFifo (*(volatile PPCWGPipe*)GXFIFO_ADDR) #endif -#if DEBUG +static inline void GXPosition2f32(const f32 x, const f32 y) +{ + GXWGFifo.f32 = x; + GXWGFifo.f32 = y; +} -// external functions +static inline void GXPosition3s16(const s16 x, const s16 y, const s16 z) +{ + GXWGFifo.s16 = x; + GXWGFifo.s16 = y; + GXWGFifo.s16 = z; +} -#define FUNC_1PARAM(name, T) void name##1##T(T x); -#define FUNC_2PARAM(name, T) void name##2##T(T x, T y); -#define FUNC_3PARAM(name, T) void name##3##T(T x, T y, T z); -#define FUNC_4PARAM(name, T) void name##4##T(T x, T y, T z, T w); -#define FUNC_INDEX8(name) void name##1x8(u8 x); -#define FUNC_INDEX16(name) void name##1x16(u16 x); +static inline void GXPosition3u16(const u16 x, const u16 y, const u16 z) +{ + GXWGFifo.u16 = x; + GXWGFifo.u16 = y; + GXWGFifo.u16 = z; +} -#else +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; +} -// inline functions +static inline void GXColor1u32(const u32 c) { GXWGFifo.u32 = c; } -#define FUNC_1PARAM(name, T) \ -static inline void name##1##T(T x) { GXWGFifo.T = x; } +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; +} -#define FUNC_2PARAM(name, T) \ -static inline void name##2##T(T x, T y) { GXWGFifo.T = x; GXWGFifo.T = y; } +static inline void GXTexCoord2s8(const s8 u, const s8 v) +{ + GXWGFifo.s8 = u; + GXWGFifo.s8 = v; +} -#define FUNC_3PARAM(name, T) \ -static inline void name##3##T(T x, T y, T z) { GXWGFifo.T = x; GXWGFifo.T = y; GXWGFifo.T = z; } +static inline void GXTexCoord2u8(const u8 s, const u8 t) +{ + GXWGFifo.u8 = s; + GXWGFifo.u8 = t; +} -#define FUNC_4PARAM(name, T) \ -static inline void name##4##T(T x, T y, T z, T w) { GXWGFifo.T = x; GXWGFifo.T = y; GXWGFifo.T = z; GXWGFifo.T = w; } +static inline void GXPosition2u16(u16 x, u16 y) +{ + GXWGFifo.u16 = x; + GXWGFifo.u16 = y; +} -#define FUNC_INDEX8(name) \ -static inline void name##1x8(u8 x) { GXWGFifo.u8 = x; } +static inline void GXTexCoord2s16(const s16 u, const s16 v) +{ + GXWGFifo.s16 = u; + GXWGFifo.s16 = v; +} -#define FUNC_INDEX16(name) \ -static inline void name##1x16(u16 x) { GXWGFifo.u16 = x; } +static inline void GXTexCoord2u16(const u16 u, const u16 v) +{ + GXWGFifo.u16 = u; + GXWGFifo.u16 = v; +} -#endif +static inline void GXTexCoord2f32(const f32 u, const f32 v) +{ + GXWGFifo.f32 = u; + GXWGFifo.f32 = v; +} -// 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 +static inline void GXEnd(void) {} #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_GXVERT diff --git a/include/dolphin/hio.h b/include/dolphin/hio.h index dc83ee19a..1e5aae25b 100644 --- a/include/dolphin/hio.h +++ b/include/dolphin/hio.h @@ -1,25 +1,37 @@ -#ifndef _DOLPHIN_HIO_H_ -#define _DOLPHIN_HIO_H_ +#ifndef _DOLPHIN_HOSTIO_H +#define _DOLPHIN_HOSTIO_H + +#ifdef __cplusplus +extern "C" +{ +#endif // ifdef __cplusplus + +#include #include -#ifdef __cplusplus -extern "C" { -#endif +typedef enum +{ + HIO_DEVICE_INVALID = -1, + HIO_DEVICE_EXI2USB_0 = 0, + HIO_DEVICE_EXI2USB_1 = 1, + HIO_DEVICE_MrEXI = 2 +} HostIOType; + +typedef enum +{ + GRAB_NOT_TRANSFERRING = 0, + GRAB_TRANSFERRING = 1 +} HostIOGrabStatus; -typedef void (*HIOCallback)(void); typedef BOOL (*HIOEnumCallback)(s32 chan); +typedef void (*HIOCallback)(void); -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); +BOOL HIOInit(s32 channel, HIOCallback cb); +BOOL HIOEnumDevices(HIOEnumCallback); +BOOL HIOWrite(u32 chunkSize, void * buf, u32 bufSize); +BOOL HIOReadMailbox(u32 *); +BOOL HIOWriteMailbox(u32); #ifdef __cplusplus } diff --git a/include/dolphin/hw_regs.h b/include/dolphin/hw_regs.h index 1f5700a16..627128c7e 100644 --- a/include/dolphin/hw_regs.h +++ b/include/dolphin/hw_regs.h @@ -1,29 +1,33 @@ -#ifndef _DOLPHIN_HW_REGS_H_ -#define _DOLPHIN_HW_REGS_H_ +#ifndef _DOLPHIN_HW_REGS +#define _DOLPHIN_HW_REGS -#include +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif #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); +vu16 __VIRegs[59] : 0xCC002000; +vu32 __PIRegs[12] : 0xCC003000; +vu16 __MEMRegs[64] : 0xCC004000; +vu16 __DSPRegs[32] : 0xCC005000; +vu32 __DIRegs[16] : 0xCC006000; +vu32 __SIRegs[64] : 0xCC006400; +vu32 __EXIRegs[16] : 0xCC006800; +vu32 __AIRegs[8] : 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) +#define __VIRegs ((vu16*)0xCC002000) +#define __PIRegs ((vu32*)0xCC003000) +#define __MEMRegs ((vu16*)0xCC004000) +#define __DSPRegs ((vu16*)0xCC005000) +#define __DIRegs ((vu32*)0xCC006000) +#define __SIRegs ((vu32*)0xCC006400) +#define __EXIRegs ((vu32*)0xCC006800) +#define __AIRegs ((vu32*)0xCC006C00) #endif -// Offsets for __VIRegs // offsets for __VIRegs[i] #define VI_VERT_TIMING (0) @@ -89,6 +93,50 @@ volatile u32 __AIRegs[8] AT_ADDRESS(0xCC006C00); #define VI_WIDTH (56) + +// offsets for __PIRegs[i] +#define PI_INTRPT_SRC (0) // interrupt cause +#define PI_INTRPT_MASK (1) // interrupt mask +#define PI_FIFO_START (3) // FIFO base start +#define PI_FIFO_END (4) // FIFO base end +#define PI_FIFO_PTR (5) // FIFO current write pointer + +#define PI_RESETCODE (9) // reset code, used by OSReset + +// PI Interrupt causes. +#define PI_INTRPT_ERR (0x1) // GP runtime error +#define PI_INTRPT_RSW (0x2) // reset switch +#define PI_INTRPT_DVD (0x4) // DVD/DI interrupt +#define PI_INTRPT_SI (0x8) // serial/controller interrupt +#define PI_INTRPT_EXI (0x10) // external mem interrupt +#define PI_INTRPT_AI (0x20) // audio streaming interrupt +#define PI_INTRPT_DSP (0x40) // digital signal proc interrupt +#define PI_INTRPT_MEM (0x80) // memory interface interrupt +#define PI_INTRPT_VI (0x100) // video interface interrupt +#define PI_INTRPT_PE_TOKEN (0x200) // pixel engine token +#define PI_INTRPT_PE_FINISH (0x400) // pixel engine finish +#define PI_INTRPT_CP (0x800) // command FIFO +#define PI_INTRPT_DEBUG (0x1000) // external debugger +#define PI_INTRPT_HSP (0x2000) // high speed port +#define PI_INTRPT_RSWST (0x10000) // reset switch state (1 when pressed) + + +// offsets for __MEMRegs[i] +#define MEM_PROT_1 (0) // protected region 1 +#define MEM_PROT_2 (2) // protected region 1 +#define MEM_PROT_3 (4) // protected region 1 +#define MEM_PROT_4 (6) // protected region 1 +#define MEM_PROT_TYPE (8) // protection type + +#define MEM_INTRPT_MASK (14) // interrupt mask +#define MEM_INTRPT_SRC (15) // interrupt cause +#define MEM_INTRPT_FLAG (16) // set when interrupt happens +#define MEM_INTRPT_ADDR_LO (17) // address that caused interrupt +#define MEM_INTRPT_ADDR_HI (18) // address that caused interrupt + +#define MEM_UNK_FLAG (20) // unknown memory flag, set in __OSInitMemoryProtection + + // offsets for __DSPRegs[i] #define DSP_MAILBOX_IN_HI (0) #define DSP_MAILBOX_IN_LO (1) @@ -113,4 +161,82 @@ volatile u32 __AIRegs[8] AT_ADDRESS(0xCC006C00); #define DSP_DMA_START_FLAG (0x8000) // set to start DSP + +// offsets for __DIRegs[i] +#define DI_STATUS (0) +#define DI_COVER_STATUS (1) // cover status - 0=normal, 1=interrupt/open +#define DI_CMD_BUF_0 (2) // command buffer 0 +#define DI_CMD_BUF_1 (3) // command buffer 1 +#define DI_CMD_BUF_2 (4) // command buffer 2 +#define DI_DMA_MEM_ADDR (5) // DMA address +#define DI_DMA_LENGTH (6) // transfer length address +#define DI_CONTROL (7) +#define DI_MM_BUF (8) // Main memory buffer +#define DI_CONFIG (9) + + +// offsets for __SIRegs[i] +// Channel 0/Joy-channel 1 +#define SI_CHAN_0_BUF (0) // output buffer +#define SI_CHAN_0_BTN_1 (1) // button 1 +#define SI_CHAN_0_BTN_2 (2) // button 2 +// Channel 1/Joy-channel 2 +#define SI_CHAN_1_BUF (3) // output buffer +#define SI_CHAN_1_BTN_1 (4) // button 1 +#define SI_CHAN_1_BTN_2 (5) // button 2 +// Channel 2/Joy-channel 3 +#define SI_CHAN_2_BUF (6) // output buffer +#define SI_CHAN_2_BTN_1 (7) // button 1 +#define SI_CHAN_2_BTN_2 (8) // button 2 +// Channel 3/Joy-channel 4 +#define SI_CHAN_3_BUF (9) // output buffer +#define SI_CHAN_3_BTN_1 (10) // button 1 +#define SI_CHAN_3_BTN_2 (11) // button 2 + +#define SI_POLL (12) +#define SI_CC_STAT (13) // communication control status +#define SI_STAT (14) +#define SI_EXI_LOCK (15) // exi clock lock + +#define SI_IO_BUFFER (32) // start of buffer (32 to 63) + + +// offsets for __EXIRegs[i] +// Channel 0 +#define EXI_CHAN_0_STAT (0) // parameters/status +#define EXI_CHAN_0_DMA_ADDR (1) // DMA start address +#define EXI_CHAN_0_LEN (2) // DMA transfer length +#define EXI_CHAN_0_CONTROL (3) // control register +#define EXI_CHAN_0_IMM (4) // immediate data +// Channel 1 +#define EXI_CHAN_1_STAT (5) // parameters/status +#define EXI_CHAN_1_DMA_ADDR (6) // DMA start address +#define EXI_CHAN_1_LEN (7) // DMA transfer length +#define EXI_CHAN_1_CONTROL (8) // control register +#define EXI_CHAN_1_IMM (9) // immediate data +// Channel 2 +#define EXI_CHAN_2_STAT (10) // parameters/status +#define EXI_CHAN_2_DMA_ADDR (11) // DMA start address +#define EXI_CHAN_2_LEN (12) // DMA transfer length +#define EXI_CHAN_2_CONTROL (13) // control register +#define EXI_CHAN_2_IMM (14) // immediate data + + +// offsets for __AIRegs[i] +#define AI_CONTROL (0) // control +#define AI_VOLUME (1) // volume +#define AI_SAMPLE_COUNTER (2) // number of stereo samples output +#define AI_INTRPT_TIMING (3) // interrupt timing + +#define AI_CONTROL_PLAY_STATE (0x1) +#define AI_CONTROL_STREAM_SAMPLE_RATE (0x2) +#define AI_CONTROL_DSP_SAMPLE_COUNT (0x4) +#define AI_CONTROL_UNKNOWN8 (0x8) +#define AI_CONTROL_STREAM_SAMPLE_COUNT (0x20) +#define AI_CONTROL_DSP_SAMPLE_RATE (0x40) + +#ifdef __cplusplus +} #endif + +#endif // _DOLPHIN_HW_REGS diff --git a/include/dolphin/ip/ip.h b/include/dolphin/ip/ip.h new file mode 100644 index 000000000..6ffaa80bb --- /dev/null +++ b/include/dolphin/ip/ip.h @@ -0,0 +1,26 @@ +#ifndef _DOLPHIN_IP_H_ +#define _DOLPHIN_IP_H_ + +#include + +// Protocols +#define IP_PROTO_ICMP 1 +#define IP_PROTO_TCP 6 +#define IP_PROTO_UDP 17 + +typedef struct IPHeader { + u8 verlen; + u8 tos; + u16 len; + u16 id; + u16 frag; + u8 ttl; + u8 proto; + u16 sum; + u8 src[4]; + u8 dst[4]; +} IPHeader; + +BOOL IPIsLocalAddr(u32, const u8 *addr); + +#endif diff --git a/include/dolphin/lg.h b/include/dolphin/lg.h new file mode 100644 index 000000000..9aaf6fea0 --- /dev/null +++ b/include/dolphin/lg.h @@ -0,0 +1,29 @@ +#ifndef DOLPHIN_LG_H +#define DOLPHIN_LG_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif // ifdef __cplusplus + +// This file presumably was for a logitech steering wheel, as it is some sort of controller handler + +struct LGPosition { // seems really similar to PADStatus but is slightly different + u16 button; + s8 _2; + s8 steerDirection; + u8 gasPedal; + u8 brakePedal; + u8 _6; // unknown, are there any other analog buttons?(start maybe) + u8 analogL; + u8 analogR; + s8 err; // -1 probably means disconnected? +}; + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/include/dolphin/md5.h b/include/dolphin/md5.h new file mode 100644 index 000000000..d4a7b613e --- /dev/null +++ b/include/dolphin/md5.h @@ -0,0 +1,52 @@ +#ifndef __DOLPHIN_OS_MD5_H__ +#define __DOLPHIN_OS_MD5_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* MD5.H - header file for MD5C.C */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + rights reserved. + + License to copy and use this software is granted provided that it + is identified as the "RSA Data Security, Inc. MD5 Message-Digest + Algorithm" in all material mentioning or referencing this software + or this function. + + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD5 Message-Digest Algorithm" in all material + mentioning or referencing the derived work. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + */ + +/* MD5 context. */ +typedef struct MD5Context MD5_CTX; +typedef struct MD5Context MD5Context; +struct MD5Context +{ + u32 state[4]; // state (ABCD) + u32 count[2]; // number of bits, modulo 2^64 (lsb first) + u8 buffer[64]; // input buffer +}; + +void MD5Init (MD5Context* context); +void MD5Update(MD5Context* context, u8* input, u32 inputLen); +void MD5Final (u8 digest[16], MD5Context* context); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/mtx.h b/include/dolphin/mtx.h index 5346bc75e..4cf62ffec 100644 --- a/include/dolphin/mtx.h +++ b/include/dolphin/mtx.h @@ -1,375 +1,115 @@ -#ifndef _DOLPHIN_MTX_H_ -#define _DOLPHIN_MTX_H_ +#ifndef _DOLPHIN_MTX_H +#define _DOLPHIN_MTX_H -#include +#include "types.h" #ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - f32 x, y, z; -} Vec, *VecPtr, Point3d, *Point3dPtr; - -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]; - -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 sinA, f32 cosA); -void PSMTXRotAxisRad(Mtx m, const Vec* axis, f32 rad); -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); - -#ifdef DEBUG -#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_MTXRotRad -#define MTXTrans C_MTXTrans -#define MTXTransApply C_MTXTransApply -#define MTXScale C_MTXScale -#define MTXScaleApply C_MTXScaleApply -#define MTXQuat C_MTXQuat -#define MTXReflect C_MTXReflect -#else -#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 PSMTXRotRad -#define MTXTrans PSMTXTrans -#define MTXTransApply PSMTXTransApply -#define MTXScale PSMTXScale -#define MTXScaleApply PSMTXScaleApply -#define MTXQuat PSMTXQuat -#define MTXReflect PSMTXReflect -#endif - -// 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 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); - -#ifdef DEBUG -#define MTXMultVec C_MTXMultVec -#define MTXMultVecArray C_MTXMultVecArray -#define MTXMultVecSR C_MTXMultVecSR -#define MTXMultVecArraySR C_MTXMultVecArraySR -#else -#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 +extern "C" +{ +#endif // ifdef __cplusplus + + typedef float Mtx[3][4]; + typedef float (*MtxPtr)[4]; + typedef float Mtx23[2][3]; + typedef float Mtx33[3][3]; + typedef float Mtx44[4][4]; + typedef float PSQuaternion[4]; + + typedef struct + { + f32 x, y, z; + } Vec, *VecPtr; + + typedef struct + { + s16 x, y, z; + } S16Vec, *S16VecPtr; + + typedef struct + { + f32 x, y, z, w; + } Quaternion, *QuaternionPtr; + +// (pi/180) +#define MTXDegToRad(a) ((a) * 0.01745329252f) + + // Paired single versions + + 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 PSMTXMultVec(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); + void PSMTXQuat(Mtx m, const Quaternion *q); + void PSMTXReflect(Mtx m, const Vec *p, const Vec *n); + 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 PSMTXRotRad(Mtx m, char axis, f32 rad); + void PSMTXRotTrig(Mtx m, char axis, f32 sinA, f32 cosA); + void PSMTXRotAxisRad(Mtx m, const Vec *axis, f32 rad); + + // move to vec.h? + void PSVECAdd(const Vec *a, const Vec *b, Vec *ab); + void PSVECSubtract(const Vec *a, const Vec *b, Vec *ab); + 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 *ab); + f32 PSVECSquareDistance(const Vec *a, const Vec *b); + f32 PSVECDistance(const Vec *a, const Vec *b); + + 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); + + // C Versions + + 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_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); + void C_MTXQuat(Mtx m, const Quaternion *q); + void C_MTXReflect(Mtx m, const Vec *p, const Vec *n); + 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_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_MTXLookAt(Mtx m, const Vec *camPos, const Vec *camUp, const Vec *target); + 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); + 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); #ifdef __cplusplus } #endif -#endif +#endif \ No newline at end of file diff --git a/include/dolphin/os.h b/include/dolphin/os.h index 05ea543a3..b5952f99f 100644 --- a/include/dolphin/os.h +++ b/include/dolphin/os.h @@ -1,258 +1,245 @@ -#ifndef _DOLPHIN_OS_H_ -#define _DOLPHIN_OS_H_ +#ifndef _DOLPHIN_OS +#define _DOLPHIN_OS +#include #include -#include #ifdef __cplusplus -extern "C" { +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) #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); - -// 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); +#define AT_ADDRESS(xyz) : (xyz) #else -#define __OSBusClock (*(u32 *)(OS_BASE_CACHED | 0x00F8)) -#define __OSCoreClock (*(u32 *)(OS_BASE_CACHED | 0x00FC)) +#define AT_ADDRESS +#endif +volatile int __OSTVMode AT_ADDRESS(OS_BASE_CACHED | 0xCC); +u32 __OSBusClock AT_ADDRESS(OS_BASE_CACHED | 0x00F8); // sync with OSLoMem.h +u32 __OSCoreClock AT_ADDRESS(OS_BASE_CACHED | 0x00FC); // sync with OSLoMem.h +#define OS_BUS_CLOCK (u32) __OSBusClock +#define OS_CORE_CLOCK __OSCoreClock +#define OS_TIMER_CLOCK (OS_BUS_CLOCK / 4) + +#ifndef _DEBUG +#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))) +#else +u32 OSPhysicalToCached(void *paddr); +u32 OSPhysicalToUncached(void *paddr); +u32 OSCachedToPhysical(void *caddr); +u32 OSUncachedToPhysical(void *ucaddr); +u32 OSCachedToUncached(void *caddr); +u32 OSUncachedToCached(void *ucaddr); #endif -#define OS_BUS_CLOCK __OSBusClock -#define OS_CORE_CLOCK __OSCoreClock -#define OS_TIMER_CLOCK (OS_BUS_CLOCK/4) - -#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* 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 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 OSDiffTick(tick1, tick0) ((s32)(tick1) - (s32)(tick0)) + +#define OSRoundUp32B(v) ((((u32)v + 31) & ~31)) +#define OSRoundDown32B(v) (((u32)(v) & ~31)) -#define OS_CONSOLE_MASK 0xF0000000 -#define OS_CONSOLE_RETAIL 0x00000000 +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); + +void OSInit(); + +#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_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_CONSOLE_EMULATOR 0x10000000 -#define OS_SOUND_MODE_MONO 0 -#define OS_SOUND_MODE_STEREO 1 +u32 OSGetConsoleType(); + +#define OS_SOUND_MODE_MONO 0u +#define OS_SOUND_MODE_STEREO 1u 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); - -#define OSRoundUp32B(x) (((u32)(x) + 32 - 1) & ~(32 - 1)) -#define OSRoundDown32B(x) (((u32)(x)) & ~(32 - 1)) - -void* OSPhysicalToCached(u32 paddr); -void* OSPhysicalToUncached(u32 paddr); -u32 OSCachedToPhysical(void* caddr); -u32 OSUncachedToPhysical(void* ucaddr); -void* OSCachedToUncached(void* caddr); -void* OSUncachedToCached(void* ucaddr); - -#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))) +#define OS_PROGRESSIVE_MODE_OFF 0u +#define OS_PROGRESSIVE_MODE_ON 1u + +u32 OSGetProgressiveMode(void); +void OSSetProgressiveMode(u32 on); + +#define OS_LANG_ENGLISH 0u +#define OS_LANG_GERMAN 1u +#define OS_LANG_FRENCH 2u +#define OS_LANG_SPANISH 3u +#define OS_LANG_ITALIAN 4u +#define OS_LANG_DUTCH 5u + +u8 OSGetLanguage(void); +void OSSetLanguage(u8 language); + +#define OS_EURGB60_OFF 0u +#define OS_EURGB60_ON 1u + +u32 OSGetEuRgb60Mode(void); +void OSSetEuRgb60Mode(u32 on); + +void OSRegisterVersion(const char *id); + +BOOL OSDisableInterrupts(void); +BOOL OSEnableInterrupts(void); +BOOL OSRestoreInterrupts(BOOL level); + +#ifndef REGION_EU +#define OSGetVideoMode() OSGetProgressiveMode() +#define OSSetVideoMode(on) OSSetProgressiveMode(on) +#else +#define OSGetVideoMode() OSGetEuRgb60Mode() +#define OSSetVideoMode(on) OSSetEuRgb60Mode(on) +#endif + +#define OSHalt(msg) OSPanic(__FILE__, __LINE__, msg) + +#ifdef _DEBUG + +#ifndef ASSERT +#define ASSERT(exp) (void)((exp) || (OSPanic(__FILE__, __LINE__, "Failed assertion " #exp), 0)) #endif -// 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) +#ifndef ASSERTMSG +#if defined(__STDC_VERSION__) && (199901L <= __STDC_VERSION__) || defined(__MWERKS__) || \ + defined(__SN__) +#define ASSERTMSG(exp, ...) (void)((exp) || (OSPanic(__FILE__, __LINE__, __VA_ARGS__), 0)) #else - #define LINE(l0, l1, l2) (l2) +#define ASSERTMSG(exp, msg) (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg)), 0)) +#endif #endif +#ifndef ASSERTMSG1 +#define ASSERTMSG1(exp, msg, param1) \ + (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1)), 0)) +#endif -#ifdef DEBUG -#define ASSERTLINE(line, cond) \ - ((cond) || (OSPanic(__FILE__, line, "Failed assertion " #cond), 0)) +#ifndef ASSERTMSG2 +#define ASSERTMSG2(exp, msg, param1, param2) \ + (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1), (param2)), 0)) +#endif -#define ASSERTMSGLINE(line, cond, msg) \ - ((cond) || (OSPanic(__FILE__, line, msg), 0)) +#ifndef ASSERTMSG3 +#define ASSERTMSG3(exp, msg, param1, param2, param3) \ + (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1), (param2), (param3)), 0)) +#endif + +#ifndef ASSERTMSG4 +#define ASSERTMSG4(exp, msg, param1, param2, param3, param4) \ + (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1), (param2), (param3), (param4)), 0)) +#endif + +#else // _DEBUG + +#ifndef ASSERT +#define ASSERT(exp) ((void)0) +#endif + +#ifndef ASSERTMSG +#if defined(__STDC_VERSION__) && (199901L <= __STDC_VERSION__) || defined(__MWERKS__) || \ + defined(__SN__) +#define ASSERTMSG(exp, ...) ((void)0) +#else +#define ASSERTMSG(exp, msg) ((void)0) +#endif +#endif + +#ifndef ASSERTMSG1 +#define ASSERTMSG1(exp, msg, param1) ((void)0) +#endif +#ifndef ASSERTMSG2 +#define ASSERTMSG2(exp, msg, param1, param2) ((void)0) +#endif +#ifndef ASSERTMSG3 +#define ASSERTMSG3(exp, msg, param1, param2, param3) ((void)0) +#endif +#ifndef ASSERTMSG4 +#define ASSERTMSG4(exp, msg, param1, param2, param3, param4) ((void)0) +#endif -// 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)) +#endif // _DEBUG -#define ASSERTMSGLINEV(line, cond, ...) \ - ((cond) || (OSPanic(__FILE__, line, __VA_ARGS__), 0)) +void OSReport(const char *msg, ...); +void OSPanic(const char *file, int line, const char *msg, ...); +void OSFatal(GXColor fg, GXColor bg, const char *msg); +#define OSError(...) OSPanic(__FILE__, __LINE__, __VA_ARGS__) +#ifndef MATCHING +#define OSErrorLine(line, ...) OSError(__VA_ARGS__) #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 +#define OSErrorLine(line, ...) OSPanic(__FILE__, line, __VA_ARGS__) #endif - -#define ASSERT(cond) ASSERTLINE(__LINE__, cond) #ifdef __cplusplus } #endif -#endif +// TODO: put this somewhere else +extern BOOL __OSInIPL; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif // _DOLPHIN_OS diff --git a/include/dolphin/os/OSAlarm.h b/include/dolphin/os/OSAlarm.h index 310503918..7b4a266e2 100644 --- a/include/dolphin/os/OSAlarm.h +++ b/include/dolphin/os/OSAlarm.h @@ -1,7 +1,9 @@ -#ifndef _DOLPHIN_OSALARM_H_ -#define _DOLPHIN_OSALARM_H_ +#ifndef _DOLPHIN_OSALARM +#define _DOLPHIN_OSALARM -#include +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -9,28 +11,30 @@ extern "C" { 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; + OSAlarmHandler handler; + u32 tag; + OSTime fire; + OSAlarm* prev; + OSAlarm* next; + OSTime period; + OSTime start; }; -BOOL OSCheckAlarmQueue(void); void OSInitAlarm(void); -void OSCreateAlarm(OSAlarm* alarm); void OSSetAlarm(OSAlarm* alarm, OSTime tick, OSAlarmHandler handler); +void OSSetAlarmTag(OSAlarm* alarm, u32 tag); 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 OSCreateAlarm(OSAlarm* alarm); +void OSCancelAlarm(OSAlarm* alarm); void OSCancelAlarms(u32 tag); +BOOL OSCheckAlarmQueue(void); + #ifdef __cplusplus } #endif -#endif // _DOLPHIN_OSALARM_H_ +#endif // _DOLPHIN_OSALARM diff --git a/include/dolphin/os/OSAlloc.h b/include/dolphin/os/OSAlloc.h index 77eb88661..afa1d9be1 100644 --- a/include/dolphin/os/OSAlloc.h +++ b/include/dolphin/os/OSAlloc.h @@ -1,34 +1,30 @@ -#ifndef _DOLPHIN_OSALLOC_H_ -#define _DOLPHIN_OSALLOC_H_ +#ifndef _DOLPHIN_OSALLOC +#define _DOLPHIN_OSALLOC #include #ifdef __cplusplus extern "C" { #endif - typedef int OSHeapHandle; - -extern volatile OSHeapHandle __OSCurrHeap; - -void* OSAllocFromHeap(int heap, u32 size); -void* OSAllocFixed(void* rstart, void* rend); -void OSFreeToHeap(int heap, void* ptr); -int OSSetCurrentHeap(int heap); +typedef void (*OSAllocVisitor)(void* obj, u32 size); 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); +OSHeapHandle OSCreateHeap(void* start, void* end); +void OSDestroyHeap(OSHeapHandle heap); +void OSAddToHeap(OSHeapHandle heap, void* start, void* end); +OSHeapHandle OSSetCurrentHeap(OSHeapHandle heap); +void* OSAllocFromHeap(OSHeapHandle heap, u32 size); +void* OSAllocFixed(void** rstart, void** rend); +void OSFreeToHeap(OSHeapHandle heap, void* ptr); +long OSCheckHeap(OSHeapHandle heap); +void OSDumpHeap(OSHeapHandle heap); u32 OSReferentSize(void* ptr); -void OSDumpHeap(int heap); -void OSVisitAllocated(void (*visitor)(void*, u32)); - +void OSVisitAllocated(OSAllocVisitor visitor); +extern volatile OSHeapHandle __OSCurrHeap; #define OSAlloc(size) OSAllocFromHeap(__OSCurrHeap, (size)) -#define OSFree(ptr) OSFreeToHeap(__OSCurrHeap, (ptr)) - +#define OSFree(ptr) OSFreeToHeap(__OSCurrHeap, (ptr)) #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_OSALLOC diff --git a/include/dolphin/os/OSArena.h b/include/dolphin/os/OSArena.h new file mode 100644 index 000000000..9dc157011 --- /dev/null +++ b/include/dolphin/os/OSArena.h @@ -0,0 +1,13 @@ +#ifndef _DOLPHIN_OSARENA +#define _DOLPHIN_OSARENA + +#include + +void* OSGetArenaHi(void); +void* OSGetArenaLo(void); +void OSSetArenaHi(void* addr); +void OSSetArenaLo(void* addr); +void* OSAllocFromArenaLo(u32 size, u32 align); +void* OSAllocFromArenaLo(u32 size, u32 align); + +#endif // _DOLPHIN_OSARENA diff --git a/include/dolphin/os/OSBootInfo.h b/include/dolphin/os/OSBootInfo.h new file mode 100644 index 000000000..fd7c3c0d2 --- /dev/null +++ b/include/dolphin/os/OSBootInfo.h @@ -0,0 +1,41 @@ +#ifndef _DOLPHIN_OSBOOTINFO +#define _DOLPHIN_OSBOOTINFO + +#define OS_BOOTROM_ADDR 0x81300000 + +typedef struct OSBootInfo { + DVDDiskID DVDDiskID; + u32 magic; + u32 version; + u32 memorySize; + u32 consoleType; + void* arenaLo; + void* arenaHi; + void* FSTLocation; + u32 FSTMaxLength; +} OSBootInfo; + +typedef struct { + BOOL valid; + u32 restartCode; + u32 bootDol; + void* regionStart; + void* regionEnd; + BOOL argsUseDefault; + void* argsAddr; // valid only when argsUseDefault = FALSE + +} OSExecParams; + +typedef struct BI2Debug { + s32 debugMonSize; // 0x0 + s32 simMemSize; // 0x4 + u32 argOffset; // 0x8 + u32 debugFlag; // 0xC + int trackLocation; // 0x10 + int trackSize; // 0x14 + u32 countryCode; // 0x18 + u8 unk[8]; // 0x1C + u32 padSpec; // 0x24 +} BI2Debug; + +#endif // _DOLPHIN_OSBOOTINFO diff --git a/include/dolphin/os/OSCache.h b/include/dolphin/os/OSCache.h index 89e7ce96b..b3dd94a21 100644 --- a/include/dolphin/os/OSCache.h +++ b/include/dolphin/os/OSCache.h @@ -1,7 +1,7 @@ -#ifndef _DOLPHIN_OSCACHE_H_ -#define _DOLPHIN_OSCACHE_H_ +#ifndef _DOLPHIN_OSCACHE +#define _DOLPHIN_OSCACHE -#include +#include "dolphin/types.h" #ifdef __cplusplus extern "C" { @@ -20,7 +20,7 @@ void ICInvalidateRange(void* addr, u32 nBytes); #define LC_BASE (LC_BASE_PREFIX << 16) #define LCGetBase() ((void*)LC_BASE) -void LCEnable(void); +void LCEnable(); void LCDisable(void); void LCLoadBlocks(void* destTag, void* srcAddr, u32 numBlocks); void LCStoreBlocks(void* destAddr, void* srcTag, u32 numBlocks); @@ -29,10 +29,9 @@ u32 LCStoreData(void* destAddr, void* srcAddr, u32 nBytes); u32 LCQueueLength(void); void LCQueueWait(u32 len); void LCFlushQueue(void); -void __OSCacheInit(void); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_OSCACHE diff --git a/include/dolphin/os/OSContext.h b/include/dolphin/os/OSContext.h index cbb0b92e4..fb024f8c5 100644 --- a/include/dolphin/os/OSContext.h +++ b/include/dolphin/os/OSContext.h @@ -1,7 +1,7 @@ -#ifndef _DOLPHIN_OSCONTEXT_H_ -#define _DOLPHIN_OSCONTEXT_H_ +#ifndef _DOLPHIN_OSCONTEXT +#define _DOLPHIN_OSCONTEXT -#include +#include #ifdef __cplusplus extern "C" { @@ -135,39 +135,38 @@ extern "C" { #define OS_CONTEXT_STATE_FPSAVED 0x01u typedef struct OSContext { - /* 0x000 */ u32 gpr[32]; - /* 0x080 */ u32 cr; - /* 0x084 */ u32 lr; - /* 0x088 */ u32 ctr; - /* 0x08C */ u32 xer; - /* 0x090 */ f64 fpr[32]; - /* 0x190 */ u32 fpscr_pad; - /* 0x194 */ u32 fpscr; - /* 0x198 */ u32 srr0; - /* 0x19C */ u32 srr1; - /* 0x1A0 */ u16 mode; - /* 0x1A2 */ u16 state; - /* 0x1A4 */ u32 gqr[8]; - /* 0x1C4 */ u32 psf_pad; - /* 0x1C8 */ f64 psf[32]; + u32 gpr[32]; + u32 cr; + u32 lr; + u32 ctr; + u32 xer; + + f64 fpr[32]; + + u32 fpscr_pad; + u32 fpscr; + + u32 srr0; + u32 srr1; + + u16 mode; + u16 state; + + u32 gqr[8]; + u32 psf_pad; + f64 psf[32]; + } OSContext; -u32 OSGetStackPointer(void); -void OSDumpContext(OSContext* context); -void OSLoadContext(OSContext* context); u32 OSSaveContext(OSContext* context); void OSClearContext(OSContext* context); -OSContext* OSGetCurrentContext(void); +OSContext* OSGetCurrentContext(); 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); +void OSFillFPUContext(OSContext *context); +u32 OSGetStackPointer(); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_OSCONTEXT diff --git a/include/dolphin/os/OSError.h b/include/dolphin/os/OSError.h index 4a2fc7bd7..151bfb480 100644 --- a/include/dolphin/os/OSError.h +++ b/include/dolphin/os/OSError.h @@ -1,38 +1,43 @@ -#ifndef _DOLPHIN_OSERROR_H_ -#define _DOLPHIN_OSERROR_H_ +#ifndef _DOLPHIN_OSERROR +#define _DOLPHIN_OSERROR -#include +#include #ifdef __cplusplus extern "C" { #endif -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_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_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) +#define OS_ERROR_BREAKPOINT 12 +#define OS_ERROR_SYSTEM_INTERRUPT 13 +#define OS_ERROR_THERMAL_INTERRUPT 14 +#define OS_ERROR_PROTECTION 15 +#define OS_ERROR_FPE 16 + +#define OS_ERROR_MAX (OS_ERROR_FPE + 1) + +typedef u16 OSError; +typedef void (*OSErrorHandler)( OSError error, OSContext* context, ... ); + +OSErrorHandler OSSetErrorHandler(OSError code, OSErrorHandler handler); -OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler); +// Error table. +extern OSErrorHandler __OSErrorTable[OS_ERROR_MAX]; extern u32 __OSFpscrEnableBits; -extern OSErrorHandler __OSErrorTable[17]; #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_OSERROR diff --git a/include/dolphin/os/OSException.h b/include/dolphin/os/OSException.h index e9a2f2256..f34236972 100644 --- a/include/dolphin/os/OSException.h +++ b/include/dolphin/os/OSException.h @@ -1,5 +1,6 @@ -#ifndef _DOLPHIN_OSEXCEPTION_H_ -#define _DOLPHIN_OSEXCEPTION_H_ + +#ifndef _DOLPHIN_OSEXCEPTION +#define _DOLPHIN_OSEXCEPTION #include #include @@ -7,33 +8,27 @@ #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 \ +#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_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); \ @@ -58,4 +53,4 @@ __OSExceptionHandler __OSGetExceptionHandler(__OSException exception); } #endif -#endif // _DOLPHIN_OSEXCEPTION_H_ +#endif // _DOLPHIN_OSEXCEPTION diff --git a/include/dolphin/os/OSExpansion.h b/include/dolphin/os/OSExpansion.h new file mode 100644 index 000000000..6e848b884 --- /dev/null +++ b/include/dolphin/os/OSExpansion.h @@ -0,0 +1,79 @@ +#ifndef _DOLPHIN_OSEXPANSION +#define _DOLPHIN_OSEXPANSION + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define EXI_MEMORY_CARD_59 0x00000004 +#define EXI_MEMORY_CARD_123 0x00000008 +#define EXI_MEMORY_CARD_251 0x00000010 +#define EXI_MEMORY_CARD_507 0x00000020 + +#define EXI_MEMORY_CARD_1019 0x00000040 +#define EXI_MEMORY_CARD_2043 0x00000080 + +#define EXI_MEMORY_CARD_1019A 0x00000140 +#define EXI_MEMORY_CARD_1019B 0x00000240 +#define EXI_MEMORY_CARD_1019C 0x00000340 +#define EXI_MEMORY_CARD_1019D 0x00000440 +#define EXI_MEMORY_CARD_1019E 0x00000540 +#define EXI_MEMORY_CARD_1019F 0x00000640 +#define EXI_MEMORY_CARD_1019G 0x00000740 + +#define EXI_MEMORY_CARD_2043A 0x00000180 +#define EXI_MEMORY_CARD_2043B 0x00000280 +#define EXI_MEMORY_CARD_2043C 0x00000380 +#define EXI_MEMORY_CARD_2043D 0x00000480 +#define EXI_MEMORY_CARD_2043E 0x00000580 +#define EXI_MEMORY_CARD_2043F 0x00000680 +#define EXI_MEMORY_CARD_2043G 0x00000780 + +#define EXI_USB_ADAPTER 0x01010000 +#define EXI_NPDP_GDEV 0x01020000 + +#define EXI_MODEM 0x02020000 +#define EXI_ETHER 0x04020200 +#define EXI_ETHER_VIEWER 0x04220001 +#define EXI_STREAM_HANGER 0x04130000 + +#define EXI_MARLIN 0x03010000 + +#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_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 + +BOOL EXIProbe(s32 chan); +s32 EXIProbeEx(s32 chan); + +s32 EXIGetType(s32 chan, u32 dev, u32* type); +char* EXIGetTypeString(u32 type); +u32 EXIClearInterrupts(s32 chan, BOOL exi, BOOL tc, BOOL ext); +s32 EXIGetID(s32 chan, u32 dev, u32* id); + +typedef void (*EXICallback)(s32 chan, OSContext* context); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_OSEXPANSION diff --git a/include/dolphin/os/OSFastCast.h b/include/dolphin/os/OSFastCast.h new file mode 100644 index 000000000..79e61fe79 --- /dev/null +++ b/include/dolphin/os/OSFastCast.h @@ -0,0 +1,86 @@ +#ifndef _DOLPHIN_OSFASTCAST +#define _DOLPHIN_OSFASTCAST + +#ifdef __cplusplus +extern "C" { +#endif + +#include "dolphin/types.h" + +#define OS_GQR_F32 0x0000 +#define OS_GQR_U8 0x0004 +#define OS_GQR_U16 0x0005 +#define OS_GQR_S8 0x0006 +#define OS_GQR_S16 0x0007 + +#define OS_FASTCAST_U8 2 +#define OS_FASTCAST_U16 3 +#define OS_FASTCAST_S8 4 +#define OS_FASTCAST_S16 5 +// clang-format off +static inline void OSInitFastCast(void) { +#ifdef __MWERKS__ + asm + { + li r3, OS_GQR_U8 + oris r3, r3, OS_GQR_U8 + mtspr GQR2, r3 + + li r3, OS_GQR_U16 + oris r3, r3, OS_GQR_U16 + mtspr GQR3, r3 + + li r3, OS_GQR_S8 + oris r3, r3, OS_GQR_S8 + mtspr GQR4, r3 + + li r3, OS_GQR_S16 + oris r3, r3, OS_GQR_S16 + mtspr GQR5, r3 + } +#else + +#endif +} +// clang-format off + + +static inline s16 __OSf32tos16(register f32 inF) +{ + register s16 out; + u32 tmp; + register u32* tmpPtr = &tmp; + // clang-format off + asm { + psq_st inF, 0(tmpPtr), 0x1, OS_FASTCAST_S16 + lha out, 0(tmpPtr) + } + // clang-format on + + return out; +} + +static inline void OSf32tos16(f32 *f, s16 *out) { *out = __OSf32tos16(*f); } + +static inline u8 __OSf32tou8(register f32 inF) +{ + register u8 out; + u32 tmp; + register u32 *tmpPtr = &tmp; + // clang-format off + asm { + psq_st inF, 0(tmpPtr), 0x1, OS_FASTCAST_U8 + lbz out, 0(tmpPtr) + } + // clang-format on + + return out; +} + +static inline void OSf32tou8(f32 *f, u8 *out) { *out = __OSf32tou8(*f); } + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_OSFASTCAST diff --git a/include/dolphin/os/OSFont.h b/include/dolphin/os/OSFont.h index 1fff41a62..ba312bde0 100644 --- a/include/dolphin/os/OSFont.h +++ b/include/dolphin/os/OSFont.h @@ -1,58 +1,58 @@ -#ifndef _DOLPHIN_OSFONT_H_ -#define _DOLPHIN_OSFONT_H_ +#ifndef _DOLPHIN_OSFONT +#define _DOLPHIN_OSFONT -#include -#include +#include #ifdef __cplusplus extern "C" { #endif +typedef struct OSFontHeader +{ + u16 fontType; // _00 + u16 firstChar; // _02, first char code defined in font. + u16 lastChar; // _04, last char code defined in font. + u16 invalChar; // _06, code to sub for invalid chars. + u16 ascent; // _08 + u16 descent; // _0A + u16 width; // _0C, max width. + u16 leading; // _0E + u16 cellWidth; // _10 + u16 cellHeight; // _12 + u32 sheetSize; // _14 + u16 sheetFormat; // _18, see GX_TF_* part of GXTexFmt enum + u16 sheetColumn; // _1A + u16 sheetRow; // _1C + u16 sheetWidth; // _1E + u16 sheetHeight; // _20 + u16 widthTable; // _22 + u32 sheetImage; // _24 + u32 sheetFullSize; // _28 + u8 c0; // _2C, font color components? + u8 c1; // _2D + u8 c2; // _2E + u8 c3; // _2F +} OSFontHeader; + +#define OS_FONT_ENCODE_NULL -1 #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 { - 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; +#define OS_FONT_ENCODE_UTF8 3u // UTF-8 [RFC 3629] +#define OS_FONT_ENCODE_UTF16 4u // UTF-16BE [RFC 2781] +#define OS_FONT_ENCODE_UTF32 5u // UTF-32 +#define OS_FONT_ENCODE_MAX 5u +#define OS_FONT_ENCODE_VOID 0xffffu + +#define OS_FONT_PROPORTIONAL FALSE +#define OS_FONT_FIXED TRUE u16 OSGetFontEncode(void); 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 +#endif // _DOLPHIN_OSFONT diff --git a/include/dolphin/os/OSFst.h b/include/dolphin/os/OSFst.h new file mode 100644 index 000000000..ee3ca6f80 --- /dev/null +++ b/include/dolphin/os/OSFst.h @@ -0,0 +1,19 @@ +#ifndef _DOLPHIN_OSFST_H +#define _DOLPHIN_OSFST_H + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +typedef struct OSFstEntry +{ + int entryNum; + int nextEntryNum; + char *fileNameMaybe; +} OSFstEntry; + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif \ No newline at end of file diff --git a/include/dolphin/os/OSInterrupt.h b/include/dolphin/os/OSInterrupt.h index fb74135a2..9e5d2aa03 100644 --- a/include/dolphin/os/OSInterrupt.h +++ b/include/dolphin/os/OSInterrupt.h @@ -1,44 +1,41 @@ -#ifndef _DOLPHIN_OSINTERRUPT_H_ -#define _DOLPHIN_OSINTERRUPT_H_ +#ifndef _DOLPHIN_OSINTERRUPT +#define _DOLPHIN_OSINTERRUPT +#include #include -#include #ifdef __cplusplus extern "C" { #endif -typedef s16 __OSInterrupt; -typedef u32 OSInterruptMask; - -#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_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_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)) @@ -47,9 +44,6 @@ typedef u32 OSInterruptMask; #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) @@ -94,8 +88,11 @@ typedef u32 OSInterruptMask; OS_INTERRUPTMASK_PI_PE_TOKEN | OS_INTERRUPTMASK_PI_PE_FINISH | OS_INTERRUPTMASK_PI_DEBUG | \ OS_INTERRUPTMASK_PI_HSP) +typedef s16 __OSInterrupt; typedef void (*__OSInterruptHandler)(__OSInterrupt interrupt, OSContext* context); +typedef u32 OSInterruptMask; + extern volatile __OSInterrupt __OSLastInterrupt; extern volatile u32 __OSLastInterruptSrr0; extern volatile OSTime __OSLastInterruptTime; @@ -115,4 +112,4 @@ OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask mask); } #endif -#endif +#endif // _DOLPHIN_OSINTERRUPT diff --git a/include/dolphin/os/OSMemory.h b/include/dolphin/os/OSMemory.h index a5debebc9..5e34d092a 100644 --- a/include/dolphin/os/OSMemory.h +++ b/include/dolphin/os/OSMemory.h @@ -1,7 +1,7 @@ -#ifndef _DOLPHIN_OSMEMORY_H_ -#define _DOLPHIN_OSMEMORY_H_ +#ifndef _DOLPHIN_OSMEMORY +#define _DOLPHIN_OSMEMORY -#include +#include "types.h" #ifdef __cplusplus extern "C" { @@ -18,11 +18,11 @@ extern "C" { #define OS_PROTECT_CONTROL_RDWR (OS_PROTECT_CONTROL_READ | OS_PROTECT_CONTROL_WRITE) void OSProtectRange(u32 chan, void* addr, u32 nBytes, u32 control); -u32 OSGetPhysicalMemSize(void); u32 OSGetConsoleSimulatedMemSize(void); +u32 OSGetPhysicalMemSize(void); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_OSMEMORY diff --git a/include/dolphin/os/OSMessage.h b/include/dolphin/os/OSMessage.h index 192f998fb..f67a84e38 100644 --- a/include/dolphin/os/OSMessage.h +++ b/include/dolphin/os/OSMessage.h @@ -1,28 +1,34 @@ -#ifndef _DOLPHIN_OSMESSAGE_H_ -#define _DOLPHIN_OSMESSAGE_H_ - -#include +#ifndef _DOLPHIN_OSMESSAGE +#define _DOLPHIN_OSMESSAGE #ifdef __cplusplus extern "C" { #endif -typedef struct { - OSThreadQueue queueSend; - OSThreadQueue queueReceive; - void* msgArray; - s32 msgCount; - s32 firstIndex; - s32 usedCount; -} OSMessageQueue; +#include +typedef struct OSMessageQueue OSMessageQueue; +typedef void* OSMessage; + +struct OSMessageQueue { + OSThreadQueue queueSend; + OSThreadQueue queueReceive; + OSMessage* msgArray; + s32 msgCount; + s32 firstIndex; + s32 usedCount; +}; + +// Flags to turn blocking on/off when sending/receiving message +#define OS_MESSAGE_NOBLOCK 0 +#define OS_MESSAGE_BLOCK 1 -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); +void OSInitMessageQueue(OSMessageQueue* mq, OSMessage* msgArray, s32 msgCount); +BOOL OSSendMessage(OSMessageQueue* mq, OSMessage msg, s32 flags); +BOOL OSJamMessage(OSMessageQueue* mq, OSMessage msg, s32 flags); +BOOL OSReceiveMessage(OSMessageQueue* mq, OSMessage* msg, s32 flags); #ifdef __cplusplus } #endif -#endif // _DOLPHIN_OSMESSAGE_H_ +#endif // _DOLPHIN_OSMESSAGE diff --git a/include/dolphin/os/OSModule.h b/include/dolphin/os/OSModule.h index 6e66e9b00..7baf2a9fc 100644 --- a/include/dolphin/os/OSModule.h +++ b/include/dolphin/os/OSModule.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_OSMODULE_H_ -#define _DOLPHIN_OSMODULE_H_ +#ifndef _DOLPHIN_OSMODULE +#define _DOLPHIN_OSMODULE #include @@ -7,7 +7,7 @@ extern "C" { #endif -#define OS_MODULE_VERSION 3 +#define OS_MODULE_VERSION 2 typedef struct OSModuleHeader OSModuleHeader; typedef u32 OSModuleID; @@ -19,59 +19,59 @@ typedef struct OSImportInfo OSImportInfo; typedef struct OSRel OSRel; struct OSModuleQueue { - OSModuleInfo* head; - OSModuleInfo* tail; + OSModuleInfo* head; + OSModuleInfo* tail; }; struct OSModuleLink { - OSModuleInfo* next; - OSModuleInfo* prev; + 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 + 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 + // 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 + u32 align; // module alignment constraint + u32 bssAlign; // bss alignment constraint #endif - // OS_MODULE_VERSION == 3 + // OS_MODULE_VERSION == 3 #if (3 <= OS_MODULE_VERSION) - u32 fixSize; + u32 fixSize; #endif }; #define OSGetSectionInfo(module) ((OSSectionInfo*)(((OSModuleInfo*)(module))->sectionInfoOffset)) struct OSSectionInfo { - u32 offset; - u32 size; + u32 offset; + u32 size; }; // OSSectionInfo.offset bit @@ -79,15 +79,15 @@ struct OSSectionInfo { #define OS_SECTIONINFO_OFFSET(offset) ((offset) & ~0x1) struct OSImportInfo { - OSModuleID id; // external module id - u32 offset; // offset to OSRel instructions + 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; + u16 offset; // byte offset from the previous entry + u8 type; + u8 section; + u32 addend; }; #define R_DOLPHIN_NOP 201 // C9h current offset += OSRel.offset @@ -95,13 +95,11 @@ struct OSRel { #define R_DOLPHIN_END 203 // CBh #define R_DOLPHIN_MRKREF 204 // CCh -void OSSetStringTable(void* stringTable); +void OSSetStringTable(const 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); @@ -114,4 +112,4 @@ void OSNotifyUnlink(OSModuleInfo* module); } #endif -#endif +#endif // _DOLPHIN_OSMODULE diff --git a/include/dolphin/os/OSMutex.h b/include/dolphin/os/OSMutex.h index ef5565eb6..9ee6ffe3e 100644 --- a/include/dolphin/os/OSMutex.h +++ b/include/dolphin/os/OSMutex.h @@ -1,22 +1,24 @@ -#ifndef _DOLPHIN_OSMUTEX_H_ -#define _DOLPHIN_OSMUTEX_H_ +#ifndef _DOLPHIN_OSMUTEX +#define _DOLPHIN_OSMUTEX -#include +#include "types.h" + +#include "dolphin/os/OSThread.h" #ifdef __cplusplus extern "C" { #endif struct OSMutex { - /* 0x00 */ OSThreadQueue queue; - /* 0x08 */ OSThread* thread; - /* 0x0C */ s32 count; - /* 0x10 */ OSMutexLink link; + OSThreadQueue queue; + OSThread* thread; // the current owner + s32 count; // lock count + OSMutexLink link; // for OSThread.queueMutex }; -typedef struct OSCond { - OSThreadQueue queue; -} OSCond; +struct OSCond { + OSThreadQueue queue; +}; void OSInitMutex(OSMutex* mutex); void OSLockMutex(OSMutex* mutex); @@ -30,4 +32,4 @@ void OSSignalCond(OSCond* cond); } #endif -#endif +#endif // _DOLPHIN_OSMUTEX diff --git a/include/dolphin/os/OSPriv.h b/include/dolphin/os/OSPriv.h new file mode 100644 index 000000000..8b914f258 --- /dev/null +++ b/include/dolphin/os/OSPriv.h @@ -0,0 +1,18 @@ +#ifndef _DOLPHIN_OSPRIV +#define _DOLPHIN_OSPRIV + +#include "dolphin/os.h" + +#ifdef __cplusplus +extern "C" { +#endif + +__OSExceptionHandler __OSGetExceptionHandler(__OSException exception); +OSTime __OSGetSystemTime(); +OSTime __OSTimeToSystemTime(OSTime); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_OSPRIV diff --git a/include/dolphin/os/OSReset.h b/include/dolphin/os/OSReset.h index 15c2ba62f..3613e1d37 100644 --- a/include/dolphin/os/OSReset.h +++ b/include/dolphin/os/OSReset.h @@ -1,39 +1,51 @@ -#ifndef _DOLPHIN_OSRESET_H_ -#define _DOLPHIN_OSRESET_H_ +#ifndef _DOLPHIN_OSRESET +#define _DOLPHIN_OSRESET -#include +#include #ifdef __cplusplus extern "C" { #endif -#define OS_RESET_RESTART 0 +#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_HOTRESET 1 #define OS_RESET_SHUTDOWN 2 -typedef struct OSResetFunctionInfo OSResetFunctionInfo; -typedef struct OSResetFunctionQueue { - OSResetFunctionInfo* head; - OSResetFunctionInfo* tail; -} OSResetFunctionQueue; +#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 BOOL (*OSResetFunction)(BOOL); +extern BOOL __OSIsGcam; + +typedef BOOL (*OSResetFunction)(BOOL final); +typedef struct OSResetFunctionInfo OSResetFunctionInfo; struct OSResetFunctionInfo { - OSResetFunction func; - u32 priority; - OSResetFunctionInfo* next; - OSResetFunctionInfo* prev; + // public + OSResetFunction func; + u32 priority; + + // private + OSResetFunctionInfo* next; + OSResetFunctionInfo* prev; }; -void OSRegisterResetFunction(OSResetFunctionInfo* info); -void OSUnregisterResetFunction(OSResetFunctionInfo* info); -void OSResetSystem(int reset, u32 resetCode, BOOL forceMenu); -u32 OSGetResetCode(); -u32 OSSetBootDol(u32 dolOffset); +void OSResetSystem(BOOL reset, u32 resetCode, BOOL forceMenu); +void OSRegisterResetFunction(OSResetFunctionInfo *func); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_OSRESET diff --git a/include/dolphin/os/OSResetSW.h b/include/dolphin/os/OSResetSW.h index 3c630b857..5cf0334ae 100644 --- a/include/dolphin/os/OSResetSW.h +++ b/include/dolphin/os/OSResetSW.h @@ -1,6 +1,7 @@ -#ifndef _DOLPHIN_OSRESETSW_H_ -#define _DOLPHIN_OSRESETSW_H_ +#ifndef _DOLPHIN_OSRESETSW +#define _DOLPHIN_OSRESETSW +#include #include #ifdef __cplusplus @@ -9,12 +10,12 @@ extern "C" { typedef void (*OSResetCallback)(void); -OSResetCallback OSSetResetCallback(OSResetCallback callback); -BOOL OSGetResetSwitchState(void); BOOL OSGetResetButtonState(void); +BOOL OSGetResetSwitchState(void); +OSResetCallback OSSetResetCallback(OSResetCallback callback); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_OSRESETSW diff --git a/include/dolphin/os/OSSerial.h b/include/dolphin/os/OSSerial.h index 7c38395f7..f0a6a4d3c 100644 --- a/include/dolphin/os/OSSerial.h +++ b/include/dolphin/os/OSSerial.h @@ -1,6 +1,69 @@ -#ifndef _DOLPHIN_OSSERIAL_H -#define _DOLPHIN_OSSERIAL_H +#ifndef _DOLPHIN_OSSERIAL +#define _DOLPHIN_OSSERIAL -#include +#include -#endif // _DOLPHIN_OSSERIAL_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) + +u32 SIProbe(s32 chan); +char* SIGetTypeString(u32 type); +void SIRefreshSamplingRate(void); +void SISetSamplingRate(u32 msec); + +#ifdef __cplusplus +} +#endif +#endif // _DOLPHIN_OSSERIAL diff --git a/include/dolphin/os/OSThread.h b/include/dolphin/os/OSThread.h index 5511c7595..c149ba068 100644 --- a/include/dolphin/os/OSThread.h +++ b/include/dolphin/os/OSThread.h @@ -1,5 +1,5 @@ -#ifndef _DOLPHIN_OSTHREAD_H_ -#define _DOLPHIN_OSTHREAD_H_ +#ifndef _DOLPHIN_OSTHREAD +#define _DOLPHIN_OSTHREAD #include @@ -7,106 +7,121 @@ extern "C" { #endif -typedef s32 OSPriority; +#define OS_THREAD_SPECIFIC_MAX 2 typedef struct OSThread OSThread; -typedef struct OSMutex OSMutex; typedef struct OSThreadQueue OSThreadQueue; -typedef struct OSMutexQueue OSMutexQueue; typedef struct OSThreadLink OSThreadLink; +typedef s32 OSPriority; // 0 highest, 31 lowest + +typedef struct OSMutex OSMutex; +typedef struct OSMutexQueue OSMutexQueue; typedef struct OSMutexLink OSMutexLink; +typedef struct OSCond OSCond; + +// Idle function type. +typedef void (*OSIdleFunction)(void *param); + +// Start function. +typedef void *(*OSThreadStartFunction)(void *); + +// Thread switching function. +typedef void (*OSSwitchThreadCallback)(OSThread *from, OSThread *to); struct OSThreadQueue { - OSThread* head; - OSThread* tail; + OSThread* head; + OSThread* tail; }; struct OSThreadLink { - OSThread* next; - OSThread* prev; + OSThread* next; + OSThread* prev; }; struct OSMutexQueue { - OSMutex* head; - OSMutex* tail; + OSMutex* head; + OSMutex* tail; }; struct OSMutexLink { - OSMutex* next; - OSMutex* prev; + OSMutex* next; + OSMutex* prev; }; 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]; + OSContext context; + u16 state; + u16 attr; + s32 suspend; + OSPriority priority; + OSPriority base; + void* val; + OSThreadQueue* queue; + OSThreadLink link; + OSThreadQueue queueJoin; + OSMutex* mutex; + OSMutexQueue queueMutex; + OSThreadLink linkActive; + u8* stackBase; + u32* stackEnd; + s32 error; + void* specific[OS_THREAD_SPECIFIC_MAX]; }; -enum OS_THREAD_STATE { - OS_THREAD_STATE_READY = 1, - OS_THREAD_STATE_RUNNING = 2, - OS_THREAD_STATE_WAITING = 4, - OS_THREAD_STATE_MORIBUND = 8, +enum OS_THREAD_STATE +{ + OS_THREAD_STATE_NULL = 0, + OS_THREAD_STATE_READY = 1, + OS_THREAD_STATE_RUNNING = 2, + OS_THREAD_STATE_WAITING = 4, + OS_THREAD_STATE_MORIBUND = 8, // set for death. }; +#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 -#define OS_THREAD_SPECIFIC_MAX 2 +//////// THREAD FUNCTIONS //////// +// Basic thread functions. +OSSwitchThreadCallback OSSetSwitchThreadCallback(OSSwitchThreadCallback); +void OSInitThreadQueue(OSThreadQueue *queue); +OSThread *OSGetCurrentThread(); +BOOL OSIsThreadTerminated(OSThread *thread); + +// Scheduler functions. +s32 OSDisableScheduler(); +s32 OSEnableScheduler(); + +// Thread manip functions. +void OSYieldThread(); +BOOL OSCreateThread(OSThread *thread, OSThreadStartFunction func, void *param, void *stack, u32 stackSize, OSPriority prio, u16 attr); +void OSExitThread(void *val); +void OSCancelThread(OSThread *thread); +void OSDetachThread(OSThread *thread); +s32 OSResumeThread(OSThread *thread); +s32 OSSuspendThread(OSThread *thread); +void OSSleepThread(OSThreadQueue *queue); +void OSWakeupThread(OSThreadQueue *queue); -#define OS_THREAD_ATTR_DETACH 0x0001u +void OSClearStack(u8 val); -#define OS_THREAD_STACK_MAGIC 0xDEADBABE +// Priority functions. +OSPriority OSGetThreadPriority(OSThread *thread); -typedef void (*OSSwitchThreadCallback)(OSThread*, OSThread*); -typedef void (*OSIdleFunction)(void*); - -void OSInitThreadQueue(OSThreadQueue* queue); -void OSSleepThread(OSThreadQueue* queue); -void OSWakeupThread(OSThreadQueue* queue); -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); -OSThread* OSSetIdleFunction(OSIdleFunction idleFunction, void* param, void* stack, u32 stackSize); -OSThread* OSGetIdleFunction(void); -s32 OSCheckActiveThreads(void); -void OSSetThreadSpecific(s32 index, void* ptr); -void* OSGetThreadSpecific(s32 index); - -OSSwitchThreadCallback OSSetSwitchThreadCallback(OSSwitchThreadCallback callback); - -#define IsSuspended(suspend) (suspend > 0) +// Unused/inlined in P2. +BOOL OSIsThreadSuspended(OSThread *thread); +BOOL OSJoinThread(OSThread *thread, void **val); +BOOL OSSetThreadPriority(OSThread *thread, OSPriority prio); +OSThread *OSSetIdleFunction(OSIdleFunction idleFunc, void *param, void *stack, u32 stackSize); +OSThread *OSGetIdleFunction(); +long OSCheckActiveThreads(); #ifdef __cplusplus } #endif -#endif +#endif // _DOLPHIN_OSTHREAD diff --git a/include/dolphin/os/OSTime.h b/include/dolphin/os/OSTime.h index 118adee7c..44e65a700 100644 --- a/include/dolphin/os/OSTime.h +++ b/include/dolphin/os/OSTime.h @@ -1,44 +1,39 @@ -#ifndef _DOLPHIN_OSTIME_H_ -#define _DOLPHIN_OSTIME_H_ - +#ifndef _DOLPHIN_OSTIME_H +#define _DOLPHIN_OSTIME_H #include - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -// Time base frequency = 1/4 bus clock -#define OS_TIME_SPEED (OS_BUS_CLOCK / 4) - -// 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 s64 OSTime; +typedef u32 OSTick; -// 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) +typedef struct OSCalendarTime +{ + int sec; // seconds after the minute [0, 61] + int min; // minutes after the hour [0, 59] + int hour; // hours since midnight [0, 23] + int mday; // day of the month [1, 31] + int mon; // month since January [0, 11] + int year; // years in AD [1, ...] + int wday; // days since Sunday [0, 6] + int yday; // days since January 1 [0, 365] -#define USEC_MAX 1000 -#define MSEC_MAX 1000 -#define MONTH_MAX 12 -#define WEEK_DAY_MAX 7 -#define YEAR_DAY_MAX 365 + int msec; // milliseconds after the second [0,999] + int usec; // microseconds after the millisecond [0,999] +} OSCalendarTime; -#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) +OSTime OSGetTime(void); +OSTick OSGetTick(void); -#define BIAS 0xB2575 +OSTime __OSGetSystemTime(void); +OSTime __OSTimeToSystemTime(OSTime time); -#define __OSSystemTime (OSTime*)0x800030D8 +void OSTicksToCalendarTime(OSTime time, OSCalendarTime *cal); +OSTime OSCalendarTimeToTicks(const OSCalendarTime *cal); #ifdef __cplusplus } #endif - -#endif // _DOLPHIN_OSTIME_H_ +#endif diff --git a/include/dolphin/os/init/__start.h b/include/dolphin/os/init/__start.h new file mode 100644 index 000000000..3c84bc243 --- /dev/null +++ b/include/dolphin/os/init/__start.h @@ -0,0 +1,46 @@ +#ifndef _DOLPHIN__START +#define _DOLPHIN__START + +#include "dolphin/db.h" +#include "types.h" + +#define PAD3_BUTTON_ADDR 0x800030E4 +#define OS_RESET_RESTART 0 +#define EXCEPTIONMASK_ADDR 0x80000044 +#define BOOTINFO2_ADDR 0x800000F4 +#define OS_BI2_DEBUGFLAG_OFFSET 0xC +#define ARENAHI_ADDR 0x80000034 +#define DEBUGFLAG_ADDR 0x800030E8 +#define DVD_DEVICECODE_ADDR 0x800030E6 + +#define MSR_FP 0x2000 + +extern void InitMetroTRK(); + +u16 Pad3Button : PAD3_BUTTON_ADDR; +static u8 Debug_BBA = 0; + +extern void memset(void *, int, int); +extern int main(int argc, char *argv[]); +extern void exit(int); +extern void __init_user(void); +extern void OSInit(void); +extern void DBInit(void); +extern void OSResetSystem(BOOL reset, u32 resetCode, BOOL forceMenu); +extern void __OSCacheInit(void); +extern void __OSPSInit(void); + +__declspec(section ".init") extern void __check_pad3(void); +__declspec(section ".init") extern void __set_debug_bba(void); +__declspec(section ".init") extern u8 __get_debug_bba(void); +__declspec(section ".init") extern void __start(void); +__declspec(section ".init") extern void __init_registers(void); +__declspec(section ".init") extern void __init_data(void); +__declspec(section ".init") extern void __init_hardware(void); +__declspec(section ".init") extern void __flush_cache(void *address, unsigned int size); + +__declspec(section ".init") extern char _stack_addr[]; +__declspec(section ".init") extern char _SDA_BASE_[]; +__declspec(section ".init") extern char _SDA2_BASE_[]; + +#endif // _DOLPHIN__START \ No newline at end of file diff --git a/include/dolphin/pad.h b/include/dolphin/pad.h index d966b8094..117c10e76 100644 --- a/include/dolphin/pad.h +++ b/include/dolphin/pad.h @@ -14,8 +14,8 @@ extern "C" { #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_CHAN0_BIT 0x80000000 @@ -23,30 +23,31 @@ extern "C" { #define PAD_CHAN2_BIT 0x20000000 #define PAD_CHAN3_BIT 0x10000000 -#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_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 PAD_ERR_NOT_READY -2 +#define PAD_ERR_TRANSFER -3 #define RES_WIRELESS_LITE 0x40000 -typedef struct PADStatus { +typedef struct PADStatus +{ /* 0x00 */ u16 button; /* 0x02 */ s8 stickX; /* 0x03 */ s8 stickY; @@ -59,7 +60,8 @@ typedef struct PADStatus { /* 0x0A */ s8 err; } PADStatus; -typedef struct PADClampRegion { +typedef struct PADClampRegion +{ u8 minTrigger; u8 maxTrigger; s8 minStick; diff --git a/include/dolphin/sipriv.h b/include/dolphin/sipriv.h new file mode 100644 index 000000000..8f971da1a --- /dev/null +++ b/include/dolphin/sipriv.h @@ -0,0 +1,42 @@ +#ifndef _DOLPHIN_SIPRIV +#define _DOLPHIN_SIPRIV + +#include "dolphin/os.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*SICallback)(s32 chan, u32 sr, OSContext* context); +typedef void (*SITypeAndStatusCallback)(s32 chan, u32 type); + +void SIInit(void); +u32 SIGetStatus(s32 chan); + +BOOL SIBusy(void); +BOOL SIIsChanBusy(s32 chan); + +BOOL SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, + SICallback callback, OSTime delay); +u32 SISync(void); + +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 SIRegisterPollingHandler(__OSInterruptHandler handler); +BOOL SIUnregisterPollingHandler(__OSInterruptHandler handler); + +u32 SIGetType(s32 chan); +u32 SIGetTypeAsync(s32 chan, SITypeAndStatusCallback callback); +u32 SIDecodeType(u32 type); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_SIPRIV \ No newline at end of file diff --git a/include/dolphin/tcp/tcp.h b/include/dolphin/tcp/tcp.h new file mode 100644 index 000000000..2de25604f --- /dev/null +++ b/include/dolphin/tcp/tcp.h @@ -0,0 +1,29 @@ +#ifndef _DOLPHIN_TCP_H_ +#define _DOLPHIN_TCP_H_ + +#include + +typedef struct TCPHeader { + u16 src; + u16 dst; + s32 seq; + s32 ack; + u16 flag; + u16 win; + u16 sum; + u16 urg; +} TCPHeader; + +typedef struct TCPResetInfo { + u8 addr[6]; + u8 dstAddr[4]; + u8 srcAddr[4]; + u16 dstPort; + u16 srcPort; + s32 seq; + s32 ack; + u16 flag; + u16 id; +} TCPResetInfo; + +#endif diff --git a/include/dolphin/thp.h b/include/dolphin/thp.h new file mode 100644 index 000000000..abdab02b8 --- /dev/null +++ b/include/dolphin/thp.h @@ -0,0 +1,129 @@ +#ifndef _DOLPHIN_THP_H +#define _DOLPHIN_THP_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef u8 THPSample; + typedef s16 THPCoeff; + typedef float THPQuantTab[64]; + + typedef struct _THPHuffmanTab + { + u8 quick[32]; + u8 increment[32]; + u8 *Vij; + s32 maxCode[18]; + s32 valPtr[18]; + u8 Vij1; + u8 pad[11]; + } THPHuffmanTab; + + typedef struct _THPComponent + { + u8 quantizationTableSelector; + u8 DCTableSelector; + u8 ACTableSelector; + THPCoeff predDC; + } THPComponent; + + typedef struct _THPFileInfo + { + THPQuantTab quantTabs[3]; + THPHuffmanTab huffmanTabs[4]; + THPComponent components[3]; + u16 xPixelSize; + u16 yPixelSize; + u16 MCUsPerRow; + u16 decompressedY; + u8 *c; + u32 currByte; + u32 cnt; + u8 validHuffmanTabs; + u8 RST; + u16 nMCU; + u16 currMCU; + u8 *dLC[3]; + } THPFileInfo; + + typedef struct + { + u32 offsetNextChannel; + u32 sampleSize; + s16 lCoef[8][2]; + s16 rCoef[8][2]; + s16 lYn1; + s16 lYn2; + s16 rYn1; + s16 rYn2; + } THPAudioRecordHeader; + + typedef struct + { + u8 *encodeData; + u32 offsetNibbles; + u8 predictor; + u8 scale; + s16 yn1; + s16 yn2; + } THPAudioDecodeInfo; + + BOOL THPInit(); + s32 THPVideoDecode(void *file, void *tileY, void *tileU, void *tileV, void *work); + u32 THPAudioDecode(s16 *audioBuffer, u8 *audioFrame, s32 flag); + + s32 __THPAudioGetNewSample(THPAudioDecodeInfo *); + void __THPAudioInitialize(THPAudioDecodeInfo *, u8 *); + + void __THPSetupBuffers(void); + u8 __THPReadFrameHeader(void); + u8 __THPReadScaneHeader(void); + u8 __THPReadQuantizationTable(void); + u8 __THPReadHuffmanTableSpecification(void); + void __THPHuffGenerateSizeTable(void); + void __THPHuffGenerateCodeTable(void); + void __THPHuffGenerateDecoderTables(u8 tabIndex); + void __THPRestartDefinition(void); + void __THPPrepBitStream(void); + static void __THPDecompressYUV(void *, void *, void *); + void __THPGQRRestore(void); + void __THPDecompressiMCURow512x448(void); + void __THPDecompressiMCURow640x480(void); + void __THPDecompressiMCURowNxN(void); + void __THPInverseDCTNoYPos(THPCoeff *, u32); + void __THPHuffDecodeDCTCompY(THPFileInfo *, THPCoeff *); + void __THPHuffDecodeDCTCompU(THPFileInfo *, THPCoeff *); + void __THPHuffDecodeDCTCompV(THPFileInfo *, THPCoeff *); + + static const u8 __THPJpegNaturalOrder[80] = { + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63}; + + static const f64 __THPAANScaleFactor[8] = { + 1.0f, + 1.387039845f, + 1.306562965f, + 1.175875602f, + 1.0f, + 0.785694958f, + 0.541196100f, + 0.275899379f, + }; + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/include/dolphin/types.h b/include/dolphin/types.h index b77602b10..e402fc670 100644 --- a/include/dolphin/types.h +++ b/include/dolphin/types.h @@ -1,47 +1,46 @@ -#ifndef _DOLPHIN_TYPES_H_ -#define _DOLPHIN_TYPES_H_ +#ifndef DOLPHIN_TYPES_H +#define DOLPHIN_TYPES_H typedef signed char s8; -typedef unsigned char u8; -typedef signed short int s16; -typedef unsigned short int u16; +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 signed long long int s64; -typedef unsigned long long int u64; +typedef unsigned long long u64; +typedef unsigned long size_t; + +typedef volatile u8 vu8; +typedef volatile u16 vu16; +typedef volatile u32 vu32; +typedef volatile u64 vu64; +typedef volatile s8 vs8; +typedef volatile s16 vs16; +typedef volatile s32 vs32; +typedef volatile s64 vs64; typedef float f32; typedef double f64; - -typedef char* Ptr; +typedef volatile f32 vf32; +typedef volatile f64 vf64; typedef int BOOL; -#define FALSE 0 +#ifndef TRUE #define TRUE 1 +#endif // TRUE -#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 ATTRIBUTE_ALIGN(num) __attribute__((aligned(num))) - -#define INT_MAX 2147483647 +#ifndef FALSE +#define FALSE 0 +#endif // FALSE #ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else // __cplusplus #define NULL ((void*)0) -#endif - -#include "stdio.h" -#include "stdarg.h" -#include "string.h" -#include "ctype.h" - -#include "cmath" +#endif // __cplusplus +#endif // NULL -#endif +#endif \ No newline at end of file diff --git a/include/dolphin/vi.h b/include/dolphin/vi.h index af4184426..a2daddeda 100644 --- a/include/dolphin/vi.h +++ b/include/dolphin/vi.h @@ -1,7 +1,174 @@ -#ifndef _DOLPHIN_VI_H_ -#define _DOLPHIN_VI_H_ +#ifndef _DOLPHIN_VI_H +#define _DOLPHIN_VI_H -#include -#include +#ifdef __cplusplus +extern "C" +{ +#endif // ifdef __cplusplus + +#include "types.h" + +#define VI_DISPLAY_PIX_SZ 2 + +#define VI_INTERLACE 0 +#define VI_NON_INTERLACE 1 +#define VI_PROGRESSIVE 2 +#define VI_3D 3 + +#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 + +#define VI_TVMODE(FMT, INT) (((FMT) << 2) + (INT)) + +typedef enum +{ + 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 + + VI_TVMODE_PAL_INT = VI_TVMODE(VI_PAL, VI_INTERLACE), // 4 + VI_TVMODE_PAL_DS = VI_TVMODE(VI_PAL, VI_NON_INTERLACE), // 5 + + VI_TVMODE_MPAL_INT = VI_TVMODE(VI_MPAL, VI_INTERLACE), // 8 + VI_TVMODE_MPAL_DS = VI_TVMODE(VI_MPAL, VI_NON_INTERLACE), // 9 + + VI_TVMODE_DEBUG_INT = VI_TVMODE(VI_DEBUG, VI_INTERLACE), // 12 + + 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 + + VI_TVMODE_EURGB60_INT = VI_TVMODE(VI_EURGB60, VI_INTERLACE), // 20 + VI_TVMODE_EURGB60_DS = VI_TVMODE(VI_EURGB60, VI_NON_INTERLACE), // 21 + + 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, // progressive scan + VI_XFBMODE_DF // interlaced +} VIXFBMode; + +// Structure to use with timing in vi.c (size 0x28). +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; + +// Structure to use with HorVer in vi.c (size 0x58). +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; + +#define VI_FIELD_ABOVE 1 +#define VI_FIELD_BELOW 0 + +// Maximum screen space +#define VI_MAX_WIDTH_NTSC 720 +#define VI_MAX_HEIGHT_NTSC 480 + +#define VI_MAX_WIDTH_PAL 720 +#define VI_MAX_HEIGHT_PAL 574 + +#define VI_MAX_WIDTH_MPAL 720 +#define VI_MAX_HEIGHT_MPAL 480 + +#define VI_MAX_WIDTH_EURGB60 VI_MAX_WIDTH_NTSC +#define VI_MAX_HEIGHT_EURGB60 VI_MAX_HEIGHT_NTSC + +#define VI_DTV_STAT (55) + +typedef void (*VIRetraceCallback)(u32 retraceCount); +typedef void (*VIPositionCallback)(s16 x, s16 y); + +#define VIPadFrameBufferWidth(width) ((u16)(((u16)(width) + 15) & ~15)) + +void VIInit(void); +void VIFlush(void); +void *VIGetNextFrameBuffer(); +void VIWaitForRetrace(void); + +void VIConfigure(const struct _GXRenderModeObj *rm); +void VIConfigurePan(u16 PanPosX, u16 PanPosY, u16 PanSizeX, u16 PanSizeY); +void VISetNextFrameBuffer(void *fb); +void *VIGetCurrentFrameBuffer(); + +void __VIGetCurrentPosition(s16* x, s16* y); + +VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback callback); +VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback callback); + +void VISetBlack(BOOL black); +u32 VIGetRetraceCount(); +u32 VIGetNextField(); +u32 VIGetCurrentLine(); +u32 VIGetTvFormat(); + +u32 VIGetDTVStatus(); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus #endif diff --git a/include/dolphin/vi/vitypes.h b/include/dolphin/vi/vitypes.h index 983a89b7e..51be069e3 100644 --- a/include/dolphin/vi/vitypes.h +++ b/include/dolphin/vi/vitypes.h @@ -3,38 +3,42 @@ #include -#define VI_TVMODE(format, interlace) (((format) << 2) + (interlace)) +#define VI_TVMODE(format, interlace) (((format) << 2) + (interlace)) -#define VI_INTERLACE 0 +#define VI_INTERLACE 0 #define VI_NON_INTERLACE 1 -#define VI_PROGRESSIVE 2 +#define VI_PROGRESSIVE 2 -#define VI_NTSC 0 -#define VI_PAL 1 -#define VI_MPAL 2 -#define VI_DEBUG 3 +#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; +#define VI_EURGB60 5 + +// Already declared in vi.h? + +// 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); diff --git a/include/inline/fastmath.h b/include/inline/fastmath.h index c293bbba2..88af178bb 100644 --- a/include/inline/fastmath.h +++ b/include/inline/fastmath.h @@ -23,7 +23,7 @@ psq_l fp0, 0(src), 0, 0; /* Load src->x and src->y into fp0. */ \ psq_l fp1, 8(src), 1, 0; /* Load src->z only into fp1. */ \ psq_st fp0, 0(dst), 0, 0; /* Store fp0 into dst->x and dst->y. */ \ - psq_st fp1, 8(dst), 1, 0; /* Store only the first half of fp1 into dst->z. */ \ + psq_st fp1, 8(dst), 1, 0; /* Store only the first half of fp1 into dst->z. */ \ } // I can't figure out how to get this as a C-style inline function, so use this in an ASM function or block. diff --git a/include/macros.h b/include/macros.h new file mode 100644 index 000000000..05f9f76c5 --- /dev/null +++ b/include/macros.h @@ -0,0 +1,80 @@ +#ifndef MACROS_H +#define MACROS_H + +#define MAX(x, y) ((x) > (y) ? (x) : (y)) +#define MIN(x, y) ((x) < (y) ? (x) : (y)) + +#define CLAMP(low, high, x) \ + ((x) > (high) ? (high) : ((x) < (low) ? (low) : (x))) + +#define ROUND_UP(x, align) (((x) + (align)-1) & (-(align))) +#define ROUND_UP_PTR(x, align) \ + ((void *)((((u32)(x)) + (align)-1) & (~((align)-1)))) + +#define ROUND_DOWN(x, align) ((x) & (-(align))) +#define ROUND_DOWN_PTR(x, align) ((void *)(((u32)(x)) & (~((align)-1)))) + +#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0])) +#define STRING_SIZE(x) (sizeof(x) - 1) // for char arrays, subtract 1 to act as null terminator? + +#define CLEAR_PATH(x) __memclr((x), sizeof((x))) + +#define ALIGN(x) __attribute__((aligned(x))) +#define ATTRIBUTE_ALIGN(x) __attribute__((aligned(x))) +#ifdef __MWERKS__ +#define DECL_SECTION(x) __declspec(section x) +#define DECL_WEAK __declspec(weak) +#define DONT_INLINE __attribute__((never_inline)) +#else +#define DECL_SECTION(x) +#define DECL_WEAK __attribute__((weak)) +#define DONT_INLINE __attribute__((noinline)) +#endif + +// Align X to the previous N bytes (N must be power of two) +#define ALIGN_PREV(X, N) ((X) & ~((N)-1)) +// Align X to the next N bytes (N must be power of two) +#define ALIGN_NEXT(X, N) ALIGN_PREV(((X) + (N)-1), N) +#define IS_ALIGNED(X, N) (((X) & ((N)-1)) == 0) +#define IS_NOT_ALIGNED(X, N) (((X) & ((N)-1)) != 0) + +#define READU32_BE(ptr, offset) \ + (((u32)ptr[offset] << 24) | ((u32)ptr[offset + 1] << 16) | ((u32)ptr[offset + 2] << 8) | (u32)ptr[offset + 3]); + +#define FLAG_ON(V, F) (((V) & (F)) == 0) +#define FLAG_OFF(V, F) (((V) & (F))) + +// Codewarrior tricks for matching decomp +// (Functions are given prototypes for -requireprotos) +#ifdef __MWERKS__ +// Force BSS order +#define CW_FORCE_BSS(module, ...) \ + void fake_function(...); \ + void FORCE_BSS##module##x(void); \ + void FORCE_BSS##module##x(void) \ + { \ + fake_function(__VA_ARGS__); \ + } +// Force strings into pool +#define CW_FORCE_STRINGS(module, ...) \ + void fake_function(...); \ + void FORCE_STRINGS##module(void); \ + void FORCE_STRINGS##module(void) \ + { \ + fake_function(__VA_ARGS__); \ + } +#define ASM asm +#else +#define CW_FORCE_BSS(module, ...) +#define CW_FORCE_STRINGS(module, ...) +#define ASM +#endif + +// For VSCode +#ifdef __INTELLISENSE__ +#define asm +#define __attribute__(x) +#define __declspec(x) +#endif + +#endif diff --git a/include/mathHelper.h b/include/mathHelper.h new file mode 100644 index 000000000..0ff0d8e21 --- /dev/null +++ b/include/mathHelper.h @@ -0,0 +1,14 @@ +#ifndef MATHHELPER_H +#define MATHHELPER_H + +#include + + +inline void QuaternionReset(Quaternion *pDest) +{ + const Quaternion q = {0.0f, 0.0f, 0.0f, 1.0f}; + *pDest = q; +} + + +#endif \ No newline at end of file diff --git a/include/rwsdk/rwplcore.h b/include/rwsdk/rwplcore.h index 20d679042..12a9352b0 100644 --- a/include/rwsdk/rwplcore.h +++ b/include/rwsdk/rwplcore.h @@ -2,7 +2,7 @@ #define RWPLCORE_H #include -#include +//#include #define rwBIGENDIAN diff --git a/include/std/bitset.h b/include/std/bitset.h new file mode 100644 index 000000000..c813f2f13 --- /dev/null +++ b/include/std/bitset.h @@ -0,0 +1,116 @@ +#ifndef MSL_BITSET_H_ +#define MSL_BITSET_H_ + +#include +#include +#include +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/abort_exit.h" + +namespace std +{ + // TODO: where does this go? + inline void __msl_error(const char *param_0) + { + fprintf(stderr, param_0); + abort(); + } + + template + class __bitset_base + { + public: + __bitset_base(); + + void set(size_t pos, bool val); + void reset(size_t pos); + bool test(size_t pos) const; + bool any() const; + private: + size_t data[N]; + }; + + template + __bitset_base::__bitset_base() + { + std::fill(data, data + N, 0); + } + + template + bool __bitset_base::any() const + { + for (size_t i = 0; i < N; i++) + { + if (data[i] != 0) + return true; + } + return false; + } + + template + bool __bitset_base::test(size_t pos) const + { + size_t i = pos / (sizeof(size_t) * 8); + size_t mask = 1 << (pos % (sizeof(size_t) * 8)); + return data[i] & mask; + } + + template + void __bitset_base::set(size_t pos, bool val) + { + size_t i = pos / (sizeof(size_t) * 8); + size_t mask = 1 << (pos % (sizeof(size_t) * 8)); + if (val) + { + data[i] |= mask; + } + else + { + data[i] &= ~mask; + } + } + + template + void __bitset_base::reset(size_t pos) + { + size_t i = pos / (sizeof(size_t) * 8); + size_t mask = 1 << (pos % (sizeof(size_t) * 8)); + data[i] &= ~mask; + } + + template + class bitset : private __bitset_base<(N - 1) / (sizeof(size_t) * 8) + 1> + { + public: + typedef __bitset_base<(N - 1) / (sizeof(size_t) * 8) + 1> base; + + bitset() {} + bool any() const { return base::any(); } + void set(size_t pos, bool val) + { + if (pos >= N) + { + __msl_error("index out of range of bitset::set"); + } + base::set(pos, val); + } + void reset(size_t pos) + { + if (pos >= N) + { + __msl_error("index out of range of bitset::reset"); + } + base::reset(pos); + } + bool test(size_t pos) const + { + if (pos >= N) + { + __msl_error("index out of range of bitset::test"); + } + return base::test(pos); + } + + }; +} // namespace std + +#endif \ No newline at end of file diff --git a/include/std/math.h b/include/std/math.h new file mode 100644 index 000000000..bc2d3f27a --- /dev/null +++ b/include/std/math.h @@ -0,0 +1,79 @@ +#ifndef STD_MATH_H +#define STD_MATH_H + +// TODO: Get rid of this file, it should use the one from MSL_C instead + +#include +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h" +#include "types.h" + +#ifdef __cplusplus +namespace std +{ +#endif + +#if __MWERKS__ > 0x2301 +extern inline float sqrtf(float x) +{ + static const double _half = .5f; + static const double _three = 3.0f; + if (x > 0.0f) + { + double xd = (double)x; + double guess = __frsqrte(xd); // returns an approximation to + guess = _half * guess * (_three - guess * guess * xd); // now have 12 sig bits + guess = _half * guess * (_three - guess * guess * xd); // now have 24 sig bits + guess = _half * guess * (_three - guess * guess * xd); // now have 32 sig bits + return (float)(xd * guess); + } + else if (x < 0.0) + { + return NAN; + } + else if (isnan(x)) + { + return NAN; + } + else + { + return x; + } +} +#else +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; +} +#endif + +extern inline float inv_sqrtf(float x) { + return 1.0f / sqrtf(x); +} + +#ifdef __cplusplus +extern inline float fabsf(float x) { return ::fabs(x); } +extern inline float fabs(float x) { return fabsf(x); } + +extern inline float atan2f(float y, float x) { return ::atan2(y, x); } +extern inline float cosf(float x) { return ::cos(x); } +extern inline float sinf(float x) { return ::sin(x); } +extern inline float tanf(float x) { return ::tan(x); } +extern inline float tan(float x) { return tanf(x); } +#endif +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/types.h b/include/types.h index c2c1c166d..84a3b6ec0 100644 --- a/include/types.h +++ b/include/types.h @@ -1,6 +1,8 @@ #ifndef BFBB_TYPES_H #define BFBB_TYPES_H +#include "macros.h" + // Note: only include this header inside BFBB-related headers/source code files. // Don't include this in any RenderWare, system, bink, etc. files @@ -41,4 +43,53 @@ typedef double F64; #define WEAK __declspec(weak) +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 size_t; +typedef unsigned long long u64; + +typedef unsigned short ushort; +typedef unsigned int uint; + +typedef volatile u8 vu8; +typedef volatile u16 vu16; +typedef volatile u32 vu32; +typedef volatile u64 vu64; +typedef volatile s8 vs8; +typedef volatile s16 vs16; +typedef volatile s32 vs32; +typedef volatile s64 vs64; + +typedef float f32; +typedef double f64; +typedef volatile f32 vf32; +typedef volatile f64 vf64; + +typedef int BOOL; + +typedef int unknown; + +#ifndef __cplusplus +typedef unsigned short wchar_t; +typedef wchar_t wint_t; +#endif + +// Basic defines to allow newer-like C++ code to be written +#define TRUE 1 +#define FALSE 0 + +#define nullptr 0 +#define null 0 + +#ifndef NULL +#define NULL 0 #endif + +#define UINT32_MAX 0xffffffff + +#endif // !TYPES_H \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/exception b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/exception similarity index 100% rename from include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/exception rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/exception diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/exception.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/exception.h similarity index 100% rename from include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/exception.h rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/exception.h diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/new similarity index 100% rename from include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/new diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/new.h similarity index 94% rename from include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new.h rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/new.h index a347550ef..62c08045c 100644 --- a/include/PowerPC_EABI_Support/MSL/MSL_C++/MSL_Common/Include/new.h +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C++/MSL_Common/Include/new.h @@ -1,7 +1,7 @@ #ifndef _NEW_H #define _NEW_H -#include +#include #include namespace std diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h new file mode 100644 index 000000000..1ded27ed9 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h @@ -0,0 +1,20 @@ +#ifndef _MSL_FILE_POS_H +#define _MSL_FILE_POS_H + +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + + int fseek(FILE *stream, fpos_t offset, int whence); + int _fseek(FILE *stream, fpos_t offset, int whence); + int ftell(FILE *stream); + int _ftell(FILE *stream); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/abort_exit.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/abort_exit.h new file mode 100644 index 000000000..dad87c708 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/abort_exit.h @@ -0,0 +1,17 @@ +#ifndef ABORT_EXIT_H +#define ABORT_EXIT_H + +#ifdef __cplusplus +extern "C" +{ +#endif // ifdef __cplusplus + +void abort(); +void exit(int status); +void __exit(int status); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/alloc.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/alloc.h new file mode 100644 index 000000000..a189b1814 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/alloc.h @@ -0,0 +1,8 @@ +#ifndef _MSL_ALLOC_H +#define _MSL_ALLOC_H + +#include "types.h" + +void free(void*); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h new file mode 100644 index 000000000..aa8b8cae0 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h @@ -0,0 +1,90 @@ +#ifndef _MSL_COMMON_ANSI_FILES_H +#define _MSL_COMMON_ANSI_FILES_H + +#include "types.h" + +typedef unsigned long __file_handle; +typedef unsigned long fpos_t; +typedef struct _IO_FILE _IO_FILE, *P_IO_FILE; + +#define __ungetc_buffer_size 2 + +enum __file_kinds { __closed_file, __disk_file, __console_file, __unavailable_file }; + +enum __file_orientation { __unoriented, __char_oriented, __wide_oriented }; + +typedef struct __file_modes { + u32 open_mode : 2; + u32 io_mode : 3; + u32 buffer_mode : 2; + u32 file_kind : 3; + +#ifdef _MSL_WIDE_CHAR + u32 file_orientation : 2; +#endif /* _MSL_WIDE_CHAR */ + + u32 binary_io : 1; +} file_modes; + +enum __io_states { __neutral, __writing, __reading, __rereading }; + +typedef struct __file_states { + u32 io_state : 3; + u32 free_buffer : 1; + + u8 eof; + u8 error; +} file_states; + +typedef void* __ref_con; +typedef void (*__idle_proc)(void); +typedef int (*__pos_proc)(__file_handle file, fpos_t* position, int mode, __ref_con ref_con); +typedef int (*__io_proc)(__file_handle file, char* buff, size_t* count, __ref_con ref_con); +typedef int (*__close_proc)(__file_handle file); + +struct _IO_FILE { + __file_handle mHandle; // _00 + file_modes mMode; // _04 + file_states mState; // _08 + u8 mIsDynamicallyAllocated; // _0C + u8 mCharBuffer; // _0D + u8 mCharBufferOverflow; // _0E + u8 mUngetcBuffer[__ungetc_buffer_size]; // _0F + wchar_t mUngetcWideBuffer[__ungetc_buffer_size]; // _12 + u32 mPosition; // _18 + char* mBuffer; // _1C + u32 mBufferSize; // _20 + char* mBufferPtr; // _24 + u32 mBufferLength; // _28 + u32 mBufferAlignment; // _2C + u32 mBufferLength2; // _30 + u32 mBufferPosition; // _34 + __pos_proc positionFunc; // _38 + __io_proc readFunc; // _3C + __io_proc writeFunc; // _40 + __close_proc closeFunc; // _44 + __ref_con ref_con; // _48 + _IO_FILE* mNextFile; // _4C +}; + +typedef struct _IO_FILE FILE; + +extern FILE __files[4]; + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +void __convert_from_newlines(char *buffer, size_t *length); + +int fflush(FILE* __stream); +void free(void*); +int __flush_buffer(FILE* file, size_t* length); +void __prep_buffer(FILE* file); +u32 __flush_all(); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_fp.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_fp.h new file mode 100644 index 000000000..95fc4409b --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_fp.h @@ -0,0 +1,40 @@ +#ifndef _MSL_C_ANSI_FP_H +#define _MSL_C_ANSI_FP_H + +#include "types.h" +#include "math.h" +#include "float.h" +#include "fdlibm.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h" + +#define SIGDIGLEN 36 + +typedef struct decimal { + char sign; + char unk1; + s16 exp; + struct { + u8 length; + u8 text[36]; + u8 unk41; + } sig; +} decimal; + +typedef struct decform { + char style; + char unk1; + short digits; +} decform; + +void __ull2dec(decimal*, u64); +void __timesdec(decimal*, const decimal*, const decimal*); +void __str2dec(decimal*, const char*, short); +void __two_exp(decimal*, long); +BOOL __equals_dec(const decimal*, const decimal*); +BOOL __less_dec(const decimal*, const decimal*); +void __minus_dec(decimal*, const decimal*, const decimal*); +void __num2dec_internal(decimal*, double); +void __num2dec(const decform*, double, decimal*); +double __dec2num(const decimal*); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_params.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_params.h new file mode 100644 index 000000000..2d25687a6 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_params.h @@ -0,0 +1,14 @@ +#ifndef ANSI_PARAMS_H +#define ANSI_PARAMS_H + +#define _MSL_CANT_THROW __attribute__((nothrow)) + +#define _MSL_THROW throw() + +#ifndef _MSL_LOCALDATA +#define _MSL_LOCALDATA(_a) _a +#endif + +#define __std(ref) ref + +#endif // ANSI_PARAMS_H \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/arith.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/arith.h new file mode 100644 index 000000000..1c0053537 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/arith.h @@ -0,0 +1,24 @@ +#ifndef _MSL_COMMON_ARITH_H +#define _MSL_COMMON_ARITH_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + int quot; /* quotient */ + int rem; /* remainder */ +} div_t; + +long abs(long __x); +long labs(long __x); +div_t div(s32 __numer, s32 __denom); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/bsearch.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/bsearch.h new file mode 100644 index 000000000..05f918130 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/bsearch.h @@ -0,0 +1,18 @@ +#ifndef MSL_BSEARCH_H +#define MSL_BSEARCH_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif // ifdef __cplusplus + +void *bsearch(const void *key, const void *base0, size_t nmemb, size_t size, + int (*compar)(const void *, const void *)); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cmath b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/cmath similarity index 100% rename from include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cmath rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/cmath diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h new file mode 100644 index 000000000..cc80ccbab --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h @@ -0,0 +1,32 @@ +#ifndef _MSL_CRITICAL_REGIONS_H +#define _MSL_CRITICAL_REGIONS_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +enum critical_regions { + atexit_funcs_access, + malloc_pool_access, + stdin_access, + stdout_access, + stderr_access, + files_access, + console_status_access, + signal_funcs_access, + thread_access, + num_critical_regions +}; + +void __init_critical_regions(void); +void __kill_critical_regions(void); +void __begin_critical_region(int region); +void __end_critical_region(int region); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdlib b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/cstdlib similarity index 100% rename from include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstdlib rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/cstdlib diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/cstring similarity index 100% rename from include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/cstring diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ctype_api.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ctype_api.h new file mode 100644 index 000000000..e39701f18 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/ctype_api.h @@ -0,0 +1,36 @@ +#ifndef _MSL_CTYPE_API_H +#define _MSL_CTYPE_API_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +int isprint(int c); + +extern unsigned char __ctype_map[256]; +extern unsigned char __lower_map[256]; +extern unsigned char __upper_map[256]; + +#define __control_char 0x01 +#define __motion_char 0x02 +#define __space_char 0x04 +#define __punctuation 0x08 +#define __digit 0x10 +#define __hex_digit 0x20 +#define __lower_case 0x40 +#define __upper_case 0x80 + +#define __letter (__lower_case | __upper_case) +#define __alphanumeric (__letter | __digit) +#define __graphic (__alphanumeric | __punctuation) +#define __printable (__graphic | __space_char) +#define __whitespace (__motion_char | __space_char) +#define __control (__motion_char | __control_char) + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/direct_io.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/direct_io.h new file mode 100644 index 000000000..4679ca0ab --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/direct_io.h @@ -0,0 +1,10 @@ +#ifndef _MSL_DIRECT_IO_H +#define _MSL_DIRECT_IO_H + +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +// fread +size_t fwrite(const void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_io.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_io.h new file mode 100644 index 000000000..d649b4936 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_io.h @@ -0,0 +1,10 @@ +#ifndef _MSL_FILE_IO_H +#define _MSL_FILE_IO_H + +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +int fclose(FILE* file); +int fflush(FILE* file); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_struc.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_struc.h new file mode 100644 index 000000000..a4ec16d7d --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_struc.h @@ -0,0 +1,10 @@ +#ifndef _MSL_COMMON_FILE_STRUC_H +#define _MSL_COMMON_FILE_STRUC_H +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +#define stdin &(__files[0]) +#define stdout &(__files[1]) +#define stderr &(__files[2]) + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/locale_api.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/locale_api.h new file mode 100644 index 000000000..70f19d7e7 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/locale_api.h @@ -0,0 +1,9 @@ +#ifndef _MSL_LOCALE_API_H +#define _MSL_LOCALE_API_H + +#include "types.h" + +typedef int (*__decode_mbyte)(wchar_t*, const char*, size_t); +typedef int (*__encode_mbyte)(char*, wchar_t); + +#endif \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h new file mode 100644 index 000000000..45d502265 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h @@ -0,0 +1,93 @@ +#ifndef _MSL_MATH_API_H +#define _MSL_MATH_API_H + +#include "types.h" +#include "fdlibm.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +int __fpclassifyf(float); +int __signbitd(double); +int __fpclassifyd(double); + +#ifndef MATH_INLINE +#define MATH_INLINE inline +#endif + +MATH_INLINE int __fpclassifyf(f32 x) +{ + switch ((*(s32*)&x) & 0x7f800000) + { + case 0x7f800000: + { + if ((*(s32*)&x) & 0x007fffff) + return 1; + else + return 2; + break; + } + case 0: + { + if ((*(s32*)&x) & 0x007fffff) + return 5; + else + return 3; + break; + } + } + return 4; +} + +MATH_INLINE int __fpclassifyd(f64 x) +{ + switch (__HI(x) & 0x7ff00000) + { + case 0x7ff00000: + { + if ((__HI(x) & 0x000fffff) || (__LO(x) & 0xffffffff)) + return 1; + else + return 2; + break; + } + case 0: + { + if ((__HI(x) & 0x000fffff) || (__LO(x) & 0xffffffff)) + return 5; + else + return 3; + break; + } + } + return 4; +} + +MATH_INLINE float cosf(float __x) +{ + return cos((double)__x); +} + +MATH_INLINE float sinf(float __x) +{ + return sin((double)__x); +} + +MATH_INLINE float tanf(float __x) +{ + return tan((double)__x); +} + +#define fpclassify(x) \ + ((sizeof(x) == sizeof(float)) ? __fpclassifyf((float)(x)) : __fpclassifyd((double)(x))) + +#define isinf(x) ((fpclassify(x) == 2)) +#define isnan(x) ((fpclassify(x) == 1)) +#define isfinite(x) ((fpclassify(x) > 2)) + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mbstring.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mbstring.h new file mode 100644 index 000000000..0c1fb5a54 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mbstring.h @@ -0,0 +1,21 @@ +#ifndef _MSL_MBSTRING_H +#define _MSL_MBSTRING_H + +#include "types.h" +#ifdef __cplusplus +extern "C" { +#endif + +int __mbtowc_noconv(wchar_t*, const char*, size_t); +int __wctomb_noconv(char*, wchar_t); +size_t wcstombs(char* s, const wchar_t* pwcs, size_t n); +int mbstowcs(wchar_t* pwc, const char* s, size_t n); +int wctomb(char* s, wchar_t wchar); +static int unicode_to_UTF8(char* s, wchar_t wchar); +int mbtowc(wchar_t* pwc, const char* s, size_t n); +static int is_utf8_complete(const char* s, size_t n); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mem_funcs.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mem_funcs.h new file mode 100644 index 000000000..6d62aebbc --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/mem_funcs.h @@ -0,0 +1,11 @@ +#ifndef _MSL_MEM_FUNCS_H +#define _MSL_MEM_FUNCS_H + +#include "types.h" + +void __copy_longs_aligned(void* dst, const void* src, size_t len); +void __copy_longs_rev_aligned(void* dst, const void* src, size_t len); +void __copy_longs_unaligned(void* dst, const void* src, size_t len); +void __copy_longs_rev_unaligned(void* dst, const void* src, size_t len); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h new file mode 100644 index 000000000..7ef4118f9 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h @@ -0,0 +1,8 @@ +#ifndef _MSL_MATH_API_H +#define _MSL_MATH_API_H + +extern void (*__stdio_exit)(void); + +void __stdio_atexit(); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/printf.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/printf.h new file mode 100644 index 000000000..ce88b029b --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/printf.h @@ -0,0 +1,25 @@ +#ifndef _MSL_PRINTF_H +#define _MSL_PRINTF_H + +#include "stdarg.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/file_struc.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +void printf(const char*, ...); +// printf_s +int fprintf(FILE*, const char* format, ...); +// fprintf_s +int vprintf(const char*, va_list); +// vprintf_s +// vfprintf +// vfprintf_s +int vsnprintf(char*, size_t, const char*, va_list); +// vsnprintf_s +int vsprintf(char*, const char*, va_list); +// vsprintf_s +int snprintf(char*, size_t, const char*, ...); +// snprintf_s +int sprintf(char*, const char*, ...); +// sprintf_s + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/rand.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/rand.h new file mode 100644 index 000000000..7ca4d5904 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/rand.h @@ -0,0 +1,17 @@ +#ifndef _MSL_RAND_H +#define _MSL_RAND_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +int rand(); +void srand(u32 seed); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/scanf.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/scanf.h new file mode 100644 index 000000000..e9a5e7b6e --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/scanf.h @@ -0,0 +1,18 @@ +#ifndef _MSL_SCANF_H +#define _MSL_SCANF_H + +#include "stdarg.h" + +// fscanf +// fscanf_s +// vscanf +// scanf +// scanf_s +// vfscanf +// vfscanf_s +int vsscanf(const char*, const char*, va_list); +// vsscanf_s +int sscanf(const char*, const char*, ...); +// sscanf_s + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/secure_error.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/secure_error.h new file mode 100644 index 000000000..e47145557 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/secure_error.h @@ -0,0 +1,10 @@ +#ifndef _MSL_SECURE_ERROR_H +#define _MSL_SECURE_ERROR_H + +#include "types.h" + +typedef void (*msl_constraint_handler)(int, int, int); + +void __msl_runtime_constraint_violation_s(int param1, int param2, int param3); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/signal.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/signal.h new file mode 100644 index 000000000..37d6709fd --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/signal.h @@ -0,0 +1,17 @@ +#ifndef SIGNAL_H +#define SIGNAL_H + +#ifdef __cplusplus +extern "C" +{ +#endif // ifdef __cplusplus + +typedef void (*__signal_func_ptr)(int); + +int raise(int); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif // SIGNAL_H \ No newline at end of file diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/size_t.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/size_t.h similarity index 100% rename from include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/size_t.h rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/size_t.h diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h new file mode 100644 index 000000000..308903bdf --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h @@ -0,0 +1,38 @@ +#ifndef _STDIO_API_H +#define _STDIO_API_H + +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +enum __ReadProcActions { __GetAChar, __UngetAChar, __TestForError }; + +enum __WReadProcActions { __GetAwChar, __UngetAwChar, __TestForwcsError }; + +typedef struct { + char* CharStr; + size_t MaxCharCount; + size_t CharsWritten; +} __OutStrCtrl; + +typedef struct { + char* NextChar; + int NullCharDetected; +} __InStrCtrl; + +typedef struct { + wchar_t* wCharStr; + size_t MaxCharCount; + size_t CharsWritten; +} __wOutStrCtrl; + +typedef struct { + wchar_t* wNextChar; + int wNullCharDetected; +} __wInStrCtrl; + +// __fread +size_t __fwrite(const void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile); +int __StringRead(void*, int, int); +// wint_t __wStringRead(void*, wint_t, int); + +#endif // STDIO_API_H diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdlib.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/stdlib.h similarity index 71% rename from include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdlib.h rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/stdlib.h index ffd0d5c7c..01945d6c1 100644 --- a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/stdlib.h +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/stdlib.h @@ -1,7 +1,7 @@ #ifndef _MSL_STDLIB #define _MSL_STDLIB -#include +#include #ifdef __cplusplus extern "C" { @@ -9,7 +9,7 @@ extern "C" { int rand(void); int atoi(const char* nptr); -double atof(const char* nptr); +double atof(const char*); // double (const char*)? void exit(int __status); void qsort(void*, size_t, size_t, int (*)(const void*, const void*)); long abs(long n); diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtold.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtold.h new file mode 100644 index 000000000..b4458967e --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtold.h @@ -0,0 +1,6 @@ +#ifndef _MSL_STRTOLD_H +#define _MSL_STRTOLD_H + +long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, int* chars_scanned, int* overflow); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtoul.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtoul.h new file mode 100644 index 000000000..73d273d16 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/strtoul.h @@ -0,0 +1,20 @@ +#ifndef _MSL_STRTOUL_H +#define _MSL_STRTOUL_H + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned long strtoul(const char* str, char** end, int base); +unsigned long __strtoul(int base, int max_width, int (*ReadProc)(void*, int, int), + void* ReadProcArg, int* chars_scanned, int* negative, int* overflow); +unsigned long long __strtoull(int base, int max_width, int (*ReadProc)(void*, int, int), + void* ReadProcArg, int* chars_scanned, int* negative, int* overflow); +int atoi(const char* str); +char* strtok(char* str, const char* delimiters); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/time.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/time.h similarity index 100% rename from include/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/time.h rename to libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/time.h diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/wchar_io.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/wchar_io.h new file mode 100644 index 000000000..984294c4a --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/wchar_io.h @@ -0,0 +1,9 @@ +#ifndef _MSL_WCHAR_IO_H +#define _MSL_WCHAR_IO_H + +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +int fwide(FILE* stream, int mode); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/PPC_EABI/math_ppc.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/PPC_EABI/math_ppc.h new file mode 100644 index 000000000..a281719c0 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/PPC_EABI/math_ppc.h @@ -0,0 +1,18 @@ +#ifndef _MATH_PPC_H +#define _MATH_PPC_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif +f64 nan(const char *); +f32 cosf(f32 __x); +f32 sinf(f32 __x); +f32 tanf(f32 __x); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/custconn/CircleBuffer.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/custconn/CircleBuffer.h new file mode 100644 index 000000000..cdc396efc --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/custconn/CircleBuffer.h @@ -0,0 +1,24 @@ +#ifndef TRK_CIRCLE_BUFFER_H +#define TRK_CIRCLE_BUFFER_H + +#include "types.h" + +typedef struct CircleBuffer { + u8* unk0; + u8* unk4; + u8* unk8; + u32 unkC; + u32 mBytesToRead; + u32 mBytesToWrite; + uint mSection; + u32 unk1C; +} CircleBuffer; + +u32 CBGetBytesAvailableForRead(CircleBuffer* cb); +u32 CBGetBytesAvailableForWrite(CircleBuffer* cb); +void CircleBufferInitialize(CircleBuffer* cb, u8* buf, u32 size); +void CircleBufferTerminate(CircleBuffer* cb); +int CircleBufferWriteBytes(CircleBuffer* cb, u8* buf, u32 size); +int CircleBufferReadBytes(CircleBuffer* cb, u8* buf, u32 size); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/custconn/cc_gdev.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/custconn/cc_gdev.h new file mode 100644 index 000000000..218cbe27f --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/custconn/cc_gdev.h @@ -0,0 +1,23 @@ +#ifndef TRK_CC_GDEV_H +#define TRK_CC_GDEV_H + +#include "types.h" +#include "NdevExi2A/DebuggerDriver.h" + +// TODO: figure out what these values represent +typedef enum { GDEV_RESULT_10009 = -10009, GDEV_RESULT_10005 = -10005, GDEV_RESULT_10001 = -10001 } UnkGdevEnum; + +void OutputData(); +BOOL IsInitialized(); +int gdev_cc_initialize(u8** flagOut, OSInterruptHandler handler); +int gdev_cc_shutdown(); +int gdev_cc_open(); +int gdev_cc_close(); +int gdev_cc_read(u8* dest, int size); +int gdev_cc_write(const u8* src, int size); +int gdev_cc_pre_continue(); +int gdev_cc_post_stop(); +int gdev_cc_peek(); +int gdev_cc_initinterrupts(); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dispatch.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dispatch.h new file mode 100644 index 000000000..8da561ef0 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dispatch.h @@ -0,0 +1,25 @@ +#ifndef _METROTRK_DISPATCH_H +#define _METROTRK_DISPATCH_H + +#include "types.h" + +typedef struct MessageBuffer { + u8 filler[0x10]; + u8 commandId; +} MessageBuffer; + +extern u32 TRKDoConnect(MessageBuffer*); +extern u32 TRKDoDisconnect(MessageBuffer*); +extern u32 TRKDoReset(MessageBuffer*); +extern u32 TRKDoOverride(MessageBuffer*); +extern u32 TRKDoReadMemory(MessageBuffer*); +extern u32 TRKDoWriteMemory(MessageBuffer*); +extern u32 TRKDoReadRegisters(MessageBuffer*); +extern u32 TRKDoWriteRegisters(MessageBuffer*); +extern u32 TRKDoSetOption(MessageBuffer*); +extern u32 TRKDoContinue(MessageBuffer*); +extern u32 TRKDoStep(MessageBuffer*); +extern u32 TRKDoStop(MessageBuffer*); +extern void SetBufferPosition(MessageBuffer*, u32); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dolphin_trk.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dolphin_trk.h new file mode 100644 index 000000000..d46e6c7ce --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dolphin_trk.h @@ -0,0 +1,16 @@ +#ifndef METROTRK_DOLPHIN_TRK_H +#define METROTRK_DOLPHIN_TRK_H +#include "types.h" +#ifdef __cplusplus +extern "C" { +#endif + +void InitMetroTRK(void); +void InitMetroTRK_BBA(void); + +void EnableMetroTRKInterrupts(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/target_options.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/target_options.h new file mode 100644 index 000000000..af197e3d0 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/target_options.h @@ -0,0 +1,9 @@ +#ifndef _TRK_TARGET_OPTIONS_H +#define _TRK_TARGET_OPTIONS_H + +#include "types.h" + +void SetUseSerialIO(u8); +u8 GetUseSerialIO(void); + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trk.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trk.h new file mode 100644 index 000000000..e11a7854c --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trk.h @@ -0,0 +1,219 @@ +#ifndef _DOLPHIN_TRK_H +#define _DOLPHIN_TRK_H + +#include "types.h" +#include "Dolphin/db.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +/* TRK */ + +#define TRK_DISPATCH_CMD_CONNECT 1 /* Connect to the console */ +#define TRK_DISPATCH_CMD_DISCONNECT 2 /* Disconnect from the console */ +#define TRK_DISPATCH_CMD_RESET 3 /* Reset the debugger */ +#define TRK_DISPATCH_CMD_GETVERSION 4 /* Get debugger version */ +#define TRK_DISPATCH_CMD_GETSUPPORTMASK 5 /* Get Support Mask */ +#define TRK_DISPATCH_CMD_OVERRIDE 7 /* Override? */ +#define TRK_DISPATCH_CMD_READMEM 16 /* Reading from memory */ +#define TRK_DISPATCH_CMD_WRITEMEM 17 /* Writing to memory */ +#define TRK_DISPATCH_CMD_READREGS 18 /* Read a register value */ +#define TRK_DISPATCH_CMD_WRITEREGS 19 /* Set a register */ +#define TRK_DISPATCH_CMD_SETOPTION 23 /* Set an option? */ +#define TRK_DISPATCH_CMD_CONTINUE 24 /* Continue debugging */ +#define TRK_DISPATCH_CMD_STEP 25 /* Step through an instruction */ +#define TRK_DISPATCH_CMD_STOP 26 /* Stop the debugger */ + +typedef struct _TRK_Msg { + u8 _00[8]; // _00 + u32 mMsgLength; // _08 + u32 _0C; // _0C + u32 mMsg; // _10 +} TRK_Msg; + +/** + * @size{0xC} + */ +typedef struct TRKEvent { + int mEventType; + int _04; + int mBufferIndex; +} TRKEvent; + +/** + * @size{0x28} + */ +typedef struct TRKEventQueue { + u8 _00[4]; + int mCurrEvtID; + int mNextSlotToOverwrite; + TRKEvent mEvents[2]; + u32 _24; /* max of 0x100? */ +} TRKEventQueue; + +/** + * @size{0xA4} + */ +typedef struct TRKState { + u32 _00; + u32 _04; + u32 _08; + u32 _0C; + u32 _10; + u32 _14; + u32 _18; + u32 _1C; + u32 _20; + u32 _24; + u32 _28; + u32 _2C; + u32 _30; + u32 _34; + u32 _38; + u32 _3C; + u32 _40; + u32 _44; + u32 _48; + u32 _4C; + u32 _50; + u32 _54; + u32 _58; + u32 _5C; + u32 _60; + u32 _64; + u32 _68; + u32 _6C; + u32 _70; + u32 _74; + u32 _78; + u32 _7C; + u32 _80; + u32 _84; + u32 _88; + u32 _8C; + u32 _90; + u32 _94; + BOOL mIsStopped; + u32 _9C; + u32 _A0; + u32 _A4; + u32 _A8; + u32 _AC; +} TRKState; + +typedef struct TRKBuffer { + u8 _00[4]; + u32 _04; + s32 _08; + u32 _0C; + u32 _10; + u8 mBuffer[0x87C]; /* _10 */ +} TRKBuffer; +typedef enum { TRKSuccess = 0, TRKError100 = 0x100, TRKError301 = 0x301, TRKError302 = 0x302 } TRKResult; + +extern BOOL gTRKBigEndian; + +u32 TRKDoConnect(TRKBuffer*); +u32 TRKDoDisconnect(TRKBuffer*); +u32 TRKDoReset(TRKBuffer*); +u32 TRKDoVersions(TRKBuffer*); +u32 TRKDoSupportMask(TRKBuffer*); +u32 TRKDoOverride(TRKBuffer*); +u32 TRKDoReadMemory(TRKBuffer*); +u32 TRKDoWriteMemory(TRKBuffer*); +u32 TRKDoReadRegisters(TRKBuffer*); +u32 TRKDoWriteRegisters(TRKBuffer*); +u32 TRKDoSetOption(TRKBuffer*); +u32 TRKDoContinue(TRKBuffer*); +u32 TRKDoStep(TRKBuffer*); +u32 TRKDoStop(TRKBuffer*); + +void InitMetroTRK(void); +void InitMetroTRK_BBA(void); +void EnableMetroTRKInterrupts(void); + +void TRKDestructEvent(TRKEvent*); +TRKResult TRKDispatchMessage(TRKBuffer*); +void* TRKGetBuffer(int); +void TRKReleaseBuffer(int); +void TRKGetInput(); +BOOL TRKGetNextEvent(TRKEvent*); + +TRKResult TRKTargetContinue(void); +TRKResult TRKTargetInterrupt(TRKEvent*); +BOOL TRKTargetStopped(); +void TRKTargetSetStopped(uint); +TRKResult TRKTargetSupportRequest(); + +TRKResult TRKAppendBuffer_ui8(TRKBuffer*, u8*, int); +TRKResult TRKSetBufferPosition(TRKBuffer*, u32); + +TRKResult TRKMessageSend(TRK_Msg*); +void TRKSwapAndGo(void); +TRKResult TRKWriteUARTN(const void* bytes, u32 length); +TRKResult TRKInitializeNub(void); +TRKResult TRKTerminateNub(void); +void TRKNubWelcome(void); +void TRKNubMainLoop(void); + +TRKResult TRKInitializeMutex(void*); +TRKResult TRKAcquireMutex(void*); +TRKResult TRKReleaseMutex(void*); +void* TRK_memcpy(void* dst, const void* src, size_t n); + +TRKResult TRKInitializeEventQueue(); +TRKResult TRKInitializeMessageBuffers(); +TRKResult TRKInitializeDispatcher(); +TRKResult InitializeProgramEndTrap(); +TRKResult TRKInitializeSerialHandler(); +TRKResult TRKInitializeTarget(); + +/* EXI2 */ +void UnreserveEXI2Port(void); +void ReserveEXI2Port(void); + +/* MW */ +void MWTRACE(u8, char*, ...); + +/* UART */ +typedef int UARTError; + +enum { + kUARTNoError = 0, + kUARTUnknownBaudRate, + kUARTConfigurationError, + kUARTBufferOverflow, /* specified buffer was too small */ + kUARTNoData /* no data available from polling */ +}; + +typedef enum { + kBaudHWSet = -1, /* use HW settings such as DIP switches */ + kBaud300 = 300, /* valid baud rates */ + kBaud600 = 600, + kBaud1200 = 1200, + kBaud1800 = 1800, + kBaud2000 = 2000, + kBaud2400 = 2400, + kBaud3600 = 3600, + kBaud4800 = 4800, + kBaud7200 = 7200, + kBaud9600 = 9600, + kBaud19200 = 19200, + kBaud38400 = 38400, + kBaud57600 = 57600, + kBaud115200 = 115200, + kBaud230400 = 230400 +} UARTBaudRate; + +UARTError InitializeUART(UARTBaudRate baudRate); +TRKResult TRKInitializeIntDrivenUART(unknown, unknown, unknown, void*); +void usr_put_initialize(); +void TRKTargetSetInputPendingPtr(void*); +extern void* gTRKInputPendingPtr; + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/Gecko_ExceptionPPC.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/Gecko_ExceptionPPC.h new file mode 100644 index 000000000..749e4ea57 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/Gecko_ExceptionPPC.h @@ -0,0 +1,231 @@ +#ifndef _RUNTIME_GECKO_EXCEPTIONPPC_H +#define _RUNTIME_GECKO_EXCEPTIONPPC_H + +#include "types.h" + +typedef u8 exaction_type; + +#define EXACTION_ENDBIT 0x80 +#define EXACTION_MASK 0x7F + +// EXAction structs + +#define EXACTION_ENDOFLIST 0 +#define EXACTION_BRANCH 1 + +typedef struct ex_branch { + exaction_type action; + u8 unused; + u16 target; +} ex_branch; + +#define EXACTION_DESTROYLOCAL 2 + +typedef struct ex_destroylocal { + exaction_type action; + u8 unused; + s16 local; + void* dtor; +} ex_destroylocal; + +#define EXACTION_DESTROYLOCALCOND 3 + +typedef struct ex_destroylocalcond { + exaction_type action; + u8 dlc_field; + s16 cond; + s16 local; + void* dtor; +} ex_destroylocalcond; + +#define ex_destroylocalcond_MakeField(regcond) (((regcond) << 7)) +#define ex_destroylocalcond_GetRegCond(field) ((field) >> 7) + +#define EXACTION_DESTROYLOCALPOINTER 4 + +typedef struct ex_destroylocalpointer { + exaction_type action; + u8 dlp_field; + s16 pointer; + void* dtor; +} ex_destroylocalpointer; + +#define ex_destroylocalpointer_MakeField(regpointer) (((regpointer) << 7)) +#define ex_destroylocalpointer_GetRegPointer(field) ((field) >> 7) + +#define EXACTION_DESTROYLOCALARRAY 5 + +typedef struct ex_destroylocalarray { + exaction_type action; + u8 unused; + s16 localarray; + u16 elements; + u16 element_size; + void* dtor; +} ex_destroylocalarray; + +#define EXACTION_DESTROYBASE 6 +#define EXACTION_DESTROYMEMBER 7 + +typedef struct ex_destroymember { + exaction_type action; + u8 dm_field; + s16 objectptr; + s32 offset; + void* dtor; +} ex_destroymember; + +#define ex_destroymember_MakeField(regpointer) (((regpointer) << 7)) +#define ex_destroymember_GetRegPointer(field) ((field) >> 7) + +#define EXACTION_DESTROYMEMBERCOND 8 + +typedef struct ex_destroymembercond { + exaction_type action; + u8 dmc_field; + s16 cond; + s16 objectptr; + s32 offset; + void* dtor; +} ex_destroymembercond; + +#define ex_destroymembercond_MakeField(regcond, regpointer) (((regcond) << 7) | (((regpointer)&0x1) << 6)) +#define ex_destroymembercond_GetRegCond(field) ((field) >> 7) +#define ex_destroymembercond_GetRegPointer(field) (((field) >> 6) & 0x1) + +#define EXACTION_DESTROYMEMBERARRAY 9 + +typedef struct ex_destroymemberarray { + exaction_type action; + u8 dma_field; + s16 objectptr; + s32 offset; + s32 elements; + s32 element_size; + void* dtor; +} ex_destroymemberarray; + +#define ex_destroymemberarray_MakeField(regpointer) (((regpointer) << 7)) +#define ex_destroymemberarray_GetRegPointer(field) ((field) >> 7) + +#define EXACTION_DELETEPOINTER 10 + +typedef struct ex_deletepointer { + exaction_type action; + u8 dp_field; + s16 objectptr; + void* deletefunc; +} ex_deletepointer; + +#define ex_deletepointer_MakeField(regpointer) (((regpointer) << 7)) +#define ex_deletepointer_GetRegPointer(field) ((field) >> 7) + +#define EXACTION_DELETEPOINTERCOND 11 + +typedef struct ex_deletepointercond { + exaction_type action; + u8 dpc_field; + s16 cond; + s16 objectptr; + void* deletefunc; +} ex_deletepointercond; + +#define ex_deletepointercond_MakeField(regcond, regpointer) (((regcond) << 7) | (((regpointer)&0x1) << 6)) +#define ex_deletepointercond_GetRegCond(field) ((field) >> 7) +#define ex_deletepointercond_GetRegPointer(field) (((field) >> 6) & 0x1) + +#define EXACTION_CATCHBLOCK 12 + +typedef struct ex_catchblock { + exaction_type action; + u8 unused; + char* catch_type; + u16 catch_pcoffset; + s16 cinfo_ref; +} ex_catchblock; + +#define EXACTION_ACTIVECATCHBLOCK 13 + +typedef struct ex_activecatchblock { + exaction_type action; + u8 unused; + s16 cinfo_ref; +} ex_activecatchblock; + +#define EXACTION_TERMINATE 14 + +typedef struct ex_terminate { + exaction_type action; + u8 unused; +} ex_terminate; + +#define EXACTION_SPECIFICATION 15 + +typedef struct ex_specification { + exaction_type action; + u8 unused; + u16 specs; + s32 pcoffset; + s32 cinfo_ref; + char* spec[]; +} ex_specification; + +#define EXACTION_CATCHBLOCK_32 16 + +typedef struct ex_catchblock_32 { + exaction_type action; + u8 unused; + char* catch_type; + s32 catch_pcoffset; + s32 cinfo_ref; +} ex_catchblock_32; + +// Other structs + +typedef struct ExceptionRangeSmall { + u16 start; + u16 end; + u16 action; +} ExceptionRangeSmall; + +typedef struct ExceptionTableSmall { + u16 et_field; + ExceptionRangeSmall ranges[0]; +} ExceptionTableSmall; + +typedef struct ExceptionRangeLarge { + u32 start; + u16 size; + u16 action; +} ExceptionRangeLarge; + +typedef struct ExceptionTableLarge { + u16 et_field; + u16 et_field2; + ExceptionRangeLarge ranges[]; +} ExceptionTableLarge; + +#define ET_MakeField(savedGPRs, savedFPRs, savedCR, hasframeptr, isLarge) \ + (((savedGPRs) << 11) | ((savedFPRs & 0x1f) << 6) | ((savedCR & 0x1) << 5) | ((hasframeptr & 0x1) << 4) | ((isLarge & 1) << 3)) + +#define ET_GetSavedGPRs(field) ((field) >> 11) +#define ET_GetSavedFPRs(field) (((field) >> 6) & 0x1f) +#define ET_GetSavedCR(field) (((field) >> 5) & 0x1) +#define ET_GetHasFramePtr(field) (((field) >> 4) & 0x1) +#define ET_IsLargeTable(field) (((field) >> 3) & 0x1) +#define ET_ClearLargeBit(field) ((field) & ~(1 << 3)) +#define ET_SetLargeBit(field) ((field) | (1 << 3)) + +#define ET_HasElfVector(field) (((field) >> 1) & 0x1) + +typedef struct ExceptionTableIndex { + u32 functionoffset; + u32 eti_field; + u32 exceptionoffset; +} ExceptionTableIndex; + +#define ETI_MakeField(direct, fsize) ((((s32)(direct)) << 31) | ((fsize)&0x7fffffff)) +#define ETI_GetDirectStore(field) ((field) >> 31) +#define ETI_GetFunctionSize(field) ((field)&0x7fffffff) + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/MWCPlusPlusLib.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/MWCPlusPlusLib.h new file mode 100644 index 000000000..5dcb01bef --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/MWCPlusPlusLib.h @@ -0,0 +1,46 @@ +#ifndef _RUNTIME_MWCPLUSLIB_H +#define _RUNTIME_MWCPLUSLIB_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define CTORARG_TYPE int +#define CTORARG_PARTIAL (0) +#define CTORARG_COMPLETE (1) + +#define CTORCALL_COMPLETE(ctor, objptr) (((void (*)(void *, CTORARG_TYPE))ctor)(objptr, CTORARG_COMPLETE)) + +#define DTORARG_TYPE int + +#define DTORCALL_COMPLETE(dtor, objptr) (((void (*)(void *, DTORARG_TYPE))dtor)(objptr, -1)) +#define DTORCALL_PARTIAL(dtor, objptr) (((void (*)(void *, DTORARG_TYPE))dtor)(objptr, 0)) + +typedef void *ConstructorDestructor; + +typedef struct PTMF +{ + long this_delta; // self-explanatory + long v_offset; // vtable offset + union + { + void *f_addr; // function address + long ve_offset; // virtual function entry offset (of vtable) + } f_data; +} PTMF; + +extern void __construct_array(void *ptr, ConstructorDestructor ctor, ConstructorDestructor dtor, size_t size, size_t n); +extern void __destroy_arr(void *block, ConstructorDestructor *dtor, size_t size, size_t n); +extern void *__construct_new_array(void *block, ConstructorDestructor ctor, ConstructorDestructor dtor_arg, size_t size, size_t n); +extern void __destroy_new_array(void *block, ConstructorDestructor dtor); +extern void __destroy_new_array2(); +extern void __destroy_new_array3(); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/NMWException.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/NMWException.h new file mode 100644 index 000000000..692055e35 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/NMWException.h @@ -0,0 +1,34 @@ +#ifndef _NMWEXCEPTION +#define _NMWEXCEPTION + +#include "types.h" +#include "exception" //#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef s16 vbase_ctor_arg_type; +typedef char local_cond_type; + +typedef struct CatchInfo { + void* location; + void* typeinfo; + void* dtor; + void* sublocation; + s32 pointercopy; + void* stacktop; +} CatchInfo; + +void __unregister_fragment(int fragmentID); +// struct __eti_init_info* info +int __register_fragment(void* info, char* TOC); +void* __register_global_object(void* object, void* destructor, void* regmem); +void __destroy_global_chain(void); +extern char __throw_catch_compare(const char* throwtype, const char* catchtype, s32* offset_result); + +#ifdef __cplusplus +} +#endif + +#endif // _NMWEXCEPTION diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__init_cpp_exceptions.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__init_cpp_exceptions.h new file mode 100644 index 000000000..2ee636c3f --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__init_cpp_exceptions.h @@ -0,0 +1,14 @@ +#pragma once + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void __init_cpp_exceptions(void); +void __fini_cpp_exceptions(void); + +#ifdef __cplusplus +} +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__mem.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__mem.h new file mode 100644 index 000000000..198d2b446 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__mem.h @@ -0,0 +1,16 @@ +#ifndef RUNTIME_MEM_H +#define RUNTIME_MEM_H +#include "macros.h" +#include "types.h" +#ifdef __cplusplus +extern "C" { +#endif + +DECL_SECTION(".init") void* memcpy(void* dest, const void* src, size_t n); +DECL_SECTION(".init") void __fill_mem(void* dest, int val, size_t count); +DECL_SECTION(".init") void* memset(void* dest, int val, size_t count); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h new file mode 100644 index 000000000..e8ad606c4 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h @@ -0,0 +1,74 @@ +#ifndef __PPC_EABI_LINKER +#define __ppc_eabi_linker + +#include "macros.h" + +DECL_SECTION(".init") extern char _stack_addr[]; +DECL_SECTION(".init") extern char _stack_end[]; +DECL_SECTION(".init") extern char _heap_addr[]; +DECL_SECTION(".init") extern char _heap_end[]; +DECL_SECTION(".init") extern const char _fextabindex_rom[]; +DECL_SECTION(".init") extern char _fextabindex[]; +DECL_SECTION(".init") extern char _eextabindex[]; + +DECL_SECTION(".init") extern char _SDA_BASE_[]; + +DECL_SECTION(".init") extern char _SDA2_BASE_[]; + +typedef struct __rom_copy_info { + char* rom; + char* addr; + unsigned int size; +} __rom_copy_info; + +DECL_SECTION(".init") extern __rom_copy_info _rom_copy_info[]; + +typedef struct __bss_init_info { + char* addr; + unsigned int size; +} __bss_init_info; + +DECL_SECTION(".init") extern __bss_init_info _bss_init_info[]; + +typedef struct __eti_init_info { + void* eti_start; + void* eti_end; + void* code_start; + unsigned long code_size; +} __eti_init_info; + +DECL_SECTION(".init") extern __eti_init_info _eti_init_info[]; +DECL_SECTION(".init") extern const char _f_init_rom[]; +DECL_SECTION(".init") extern char _f_init[]; +DECL_SECTION(".init") extern char _e_init[]; +DECL_SECTION(".init") extern const char _f_text_rom[]; +DECL_SECTION(".init") extern char _f_text[]; +DECL_SECTION(".init") extern char _e_text[]; +DECL_SECTION(".init") extern const char _f_rodata_rom[]; +DECL_SECTION(".init") extern char _f_rodata[]; +DECL_SECTION(".init") extern char _e_rodata[]; +DECL_SECTION(".init") extern const char _fextab_rom[]; +DECL_SECTION(".init") extern char _fextab[]; +DECL_SECTION(".init") extern char _eextab[]; +DECL_SECTION(".init") extern const char _f_data_rom[]; +DECL_SECTION(".init") extern char _f_data[]; +DECL_SECTION(".init") extern char _e_data[]; +DECL_SECTION(".init") extern char _f_bss[]; +DECL_SECTION(".init") extern char _e_bss[]; +DECL_SECTION(".init") extern const char _f_sdata_rom[]; +DECL_SECTION(".init") extern char _f_sdata[]; +DECL_SECTION(".init") extern char _e_sdata[]; +DECL_SECTION(".init") extern char _f_sbss[]; +DECL_SECTION(".init") extern char _e_sbss[]; +DECL_SECTION(".init") extern const char _f_sdata2_rom[]; +DECL_SECTION(".init") extern char _f_sdata2[]; +DECL_SECTION(".init") extern char _e_sdata2[]; +DECL_SECTION(".init") extern char _f_sbss2[]; +DECL_SECTION(".init") extern char _e_sbss2[]; +DECL_SECTION(".init") extern const char _f_PPC_EMB_sdata0_rom[]; +DECL_SECTION(".init") extern char _f_PPC_EMB_sdata0[]; +DECL_SECTION(".init") extern char _e_PPC_EMB_sdata0[]; +DECL_SECTION(".init") extern char _f_PPC_EMB_sbss0[]; +DECL_SECTION(".init") extern char _e_PPC_EMB_sbss0[]; + +#endif // __PPC_EABI_LINKER diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__va_arg.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__va_arg.h new file mode 100644 index 000000000..6b9fc6e47 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__va_arg.h @@ -0,0 +1,13 @@ +#ifndef _RUNTIME_VA_ARG_H +#define _RUNTIME_VA_ARG_H +#include "types.h" +struct va_list { + char mG_register; + char mFloat_register; + char mPadding[2]; + char* mInput_arg_area; + char* mReg_save_area; +}; + +void *__va_arg(struct va_list *v_list, s32 type); +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/global_destructor_chain.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/global_destructor_chain.h new file mode 100644 index 000000000..52046c89c --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/global_destructor_chain.h @@ -0,0 +1,26 @@ +#ifndef _GLOBALDESTRUCTORCHAIN +#define _GLOBALDESTRUCTORCHAIN + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct DestructorChain { + struct DestructorChain* next; + void* destructor; + void* object; +} DestructorChain; + +void* __register_global_object(void* object, void* destructor, void* registration); + +void __destroy_global_chain(void); + +int __register_atexit(void (*)(void)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/runtime.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/runtime.h new file mode 100644 index 000000000..184bfe0e3 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/runtime.h @@ -0,0 +1,19 @@ +#ifndef _DOLPHIN_RUNTIME_H +#define _DOLPHIN_RUNTIME_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +unsigned long __cvt_fp2unsigned(f64); +// TODO: The rest + +void* __copy(char*, char*, size_t); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/algorithm b/libs/PowerPC_EABI_Support/include/algorithm new file mode 100644 index 000000000..c535a8fd4 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/algorithm @@ -0,0 +1,51 @@ +#ifndef _STD_ALGORITHM_H +#define _STD_ALGORITHM_H + +#include "types.h" + +#include + +namespace std +{ + template + inline s32 + __distance(InputIterator first, InputIterator last, input_iterator_tag) + { + s32 result = 0; + for (; first != last; ++first) + ++result; + return result; + } + + template + inline s32 + distance(InputIterator first, InputIterator last) + { + input_iterator_tag tag; + return __distance(first, last, tag); + } + + template + inline InputIterator find_if(InputIterator first, InputIterator last, Predicate p) + { + for (; first != last && !p(*first); ++first) + { + } + return first; + } + + template + ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, const Element &value, Predicate predicate); + + template + inline void fill(ForwardIt first, ForwardIt last, const T &value) + { + for (; first != last; ++first) + { + *first = value; + } + } + +} // namespace std + +#endif diff --git a/libs/PowerPC_EABI_Support/include/ctype.h b/libs/PowerPC_EABI_Support/include/ctype.h new file mode 100644 index 000000000..0937a8f7f --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/ctype.h @@ -0,0 +1,54 @@ +#ifndef _CTYPE_H +#define _CTYPE_H + +#include "types.h" +#include "locale.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ctype_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +__declspec(weak) int isalpha(int __c); +__declspec(weak) int isdigit(int __c); +__declspec(weak) int isspace(int __c); +__declspec(weak) int isupper(int __c); +__declspec(weak) int isxdigit(int __c); + +__declspec(weak) int tolower(int __c); +__declspec(weak) int toupper(int __c); + +// added underscore to avoid naming conflicts +inline int _isalpha(int c) +{ + return (int)(__ctype_map[(u8)c] & __letter); +} +inline int _isdigit(int c) +{ + return (int)(__ctype_map[(u8)c] & __digit); +} +inline int _isspace(int c) +{ + return (int)(__ctype_map[(u8)c] & __whitespace); +} +inline int _isupper(int c) +{ + return (int)(__ctype_map[(u8)c] & __upper_case); +} +inline int _isxdigit(int c) +{ + return (int)(__ctype_map[(u8)c] & __hex_digit); +} +inline int _tolower(int c) +{ + return (c == -1 ? -1 : (int)__lower_map[(u8)c]); +} +inline int _toupper(int c) +{ + return (c == -1 ? -1 : (int)__upper_map[(u8)c]); +} + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/PowerPC_EABI_Support/include/errno.h b/libs/PowerPC_EABI_Support/include/errno.h new file mode 100644 index 000000000..7a28c1ef4 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/errno.h @@ -0,0 +1,59 @@ +#ifndef _ERRNO_H +#define _ERRNO_H + +#ifdef __cplusplus +extern "C" { +#endif + +// Error constants +#define E2BIG 7 +#define EACCES 13 +#define EAGAIN 11 +#define EBADF 9 +#define EBUSY 16 +#define ECHILD 10 +#define EDEADLK 35 +#define EDEADLOCK EDEADLK +#define EDOM 33 +#define EEXIST 17 +#define EFAULT 14 +#define EFBIG 27 +#define EFPOS 40 +#define EILSEQ 88 +#define EINTR 4 +#define EINVAL 22 +#define EIO 5 +#define EISDIR 21 +#define EMFILE 24 +#define EMLINK 31 +#define ENFILE 23 +#define ENAMETOOLONG 36 +#define ENODEV 19 +#define ENOENT 2 +#define ENOERR 0 +#define ENOEXEC 8 +#define ENOLCK 77 +#define ENOMEM 12 +#define ENOSPC 28 +#define ENOSYS 38 +#define ENOTDIR 20 +#define ENOTEMPTY 39 +#define ENOTTY 25 +#define ENXIO 6 +#define EPERM 1 +#define EPIPE 32 +#define ERANGE 34 +#define EROFS 30 +#define ESIGPARM 26 +#define ESPIPE 29 +#define ESRCH 3 +#define EUNKNOWN 99 +#define EXDEV 18 + +extern int errno; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/PowerPC_EABI_Support/include/exception b/libs/PowerPC_EABI_Support/include/exception new file mode 100644 index 000000000..8daa7e3c7 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/exception @@ -0,0 +1,20 @@ +#ifndef _EXCEPTION +#define _EXCEPTION + +namespace std +{ + static void dthandler(); + static void duhandler(); + extern void terminate(); + extern void unexpected(); + typedef void (*terminate_handler)(); + typedef void (*unexpected_handler)(); + extern terminate_handler thandler; + extern unexpected_handler uhandler; + + class exception + { + }; +} + +#endif \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/include/extras.h b/libs/PowerPC_EABI_Support/include/extras.h new file mode 100644 index 000000000..0ca683907 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/extras.h @@ -0,0 +1,14 @@ +#ifndef _EXTRAS_H +#define _EXTRAS_H +#include "types.h" +#ifdef __cplusplus +extern "C" { +#endif + +int stricmp(const char*, const char*); +int strnicmp(const char *s1, const char *s2, int n); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/PowerPC_EABI_Support/include/fdlibm.h b/libs/PowerPC_EABI_Support/include/fdlibm.h new file mode 100644 index 000000000..f2e5097c8 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/fdlibm.h @@ -0,0 +1,230 @@ +#ifndef _FDLIBM_H +#define _FDLIBM_H + +/* @(#)fdlibm.h 1.5 04/04/22 */ +/* + * ==================================================== + * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. + * + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +/* Sometimes it's necessary to define __LITTLE_ENDIAN explicitly + but these catch some common cases. */ + +#if defined(i386) || defined(i486) || defined(intel) || defined(x86) || defined(i86pc) || defined(__alpha) || defined(__osf__) +#define __LITTLE_ENDIAN +#endif + +#ifdef __LITTLE_ENDIAN +#define __HI(x) *(1 + (int*)&x) +#define __LO(x) *(int*)&x +#define __HIp(x) *(1 + (int*)x) +#define __LOp(x) *(int*)x +#else +#define __HI(x) *(int*)&x +#define __LO(x) *(1 + (int*)&x) +#define __HIp(x) *(int*)x +#define __LOp(x) *(1 + (int*)x) +#endif + +// TODO: should __STDC__ actually be defined? +// #ifdef __STDC__ +#define __P(p) p +// #else +// #define __P(p) () +// #endif + +/* + * ANSI/POSIX + */ + +extern int signgam; + +#define MAXFLOAT ((float)3.40282346638528860e+38) + +enum fdversion { fdlibm_ieee = -1, fdlibm_svid, fdlibm_xopen, fdlibm_posix }; + +#define _LIB_VERSION_TYPE enum fdversion +#define _LIB_VERSION _fdlib_version + +/* if global variable _LIB_VERSION is not desirable, one may + * change the following to be a constant by: + * #define _LIB_VERSION_TYPE const enum version + * In that case, after one initializes the value _LIB_VERSION (see + * s_lib_version.c) during compile time, it cannot be modified + * in the middle of a program + */ +extern _LIB_VERSION_TYPE _LIB_VERSION; + +#define _IEEE_ fdlibm_ieee +#define _SVID_ fdlibm_svid +#define _XOPEN_ fdlibm_xopen +#define _POSIX_ fdlibm_posix + +struct exception { + int type; + char* name; + double arg1; + double arg2; + double retval; +}; + +#define HUGE MAXFLOAT + +/* + * set X_TLOSS = pi*2**52, which is possibly defined in + * (one may replace the following line by "#include ") + */ + +#define X_TLOSS 1.41484755040568800000e+16 + +#define DOMAIN 1 +#define SING 2 +#define OVERFLOW 3 +#define UNDERFLOW 4 +#define TLOSS 5 +#define PLOSS 6 + +/* + * ANSI/POSIX + */ +extern double acos __P((double)); +extern double asin __P((double)); +extern double atan __P((double)); +extern double atan2 __P((double, double)); +extern double cos __P((double)); +extern double sin __P((double)); +extern double tan __P((double)); + +extern double cosh __P((double)); +extern double sinh __P((double)); +extern double tanh __P((double)); + +extern double exp __P((double)); +extern double frexp __P((double, int*)); +extern double ldexp __P((double, int)); +extern double scalbn __P((double, int)); +extern double log __P((double)); +extern double log10 __P((double)); +extern double modf __P((double, double*)); + +extern double pow __P((double, double)); +extern double sqrt __P((double)); + +extern double ceil __P((double)); +extern double fabs __P((double)); +extern double floor __P((double)); +extern double fmod __P((double, double)); + +extern double erf __P((double)); +extern double erfc __P((double)); +extern double gamma __P((double)); +extern double hypot __P((double, double)); +extern int isnan __P((double)); +extern int finite __P((double)); +extern double j0 __P((double)); +extern double j1 __P((double)); +extern double jn __P((int, double)); +extern double lgamma __P((double)); +extern double y0 __P((double)); +extern double y1 __P((double)); +extern double yn __P((int, double)); + +extern double acosh __P((double)); +extern double asinh __P((double)); +extern double atanh __P((double)); +extern double cbrt __P((double)); +extern double logb __P((double)); +extern double nextafter __P((double, double)); +extern double remainder __P((double, double)); +#ifdef _SCALB_INT +extern double scalb __P((double, int)); +#else +extern double scalb __P((double, double)); +#endif + +extern int matherr __P((struct exception*)); + +/* + * IEEE Test Vector + */ +extern double significand __P((double)); + +/* + * Functions callable from C, intended to support IEEE arithmetic. + */ +extern double copysign __P((double, double)); +extern int ilogb __P((double)); +extern double rint __P((double)); +extern double scalbn __P((double, int)); + +/* + * BSD math library entry points + */ +extern double expm1 __P((double)); +extern double log1p __P((double)); + +/* + * Reentrant version of gamma & lgamma; passes signgam back by reference + * as the second argument; user must allocate space for signgam. + */ +#ifdef _REENTRANT +extern double gamma_r __P((double, int*)); +extern double lgamma_r __P((double, int*)); +#endif /* _REENTRANT */ + +/* ieee style elementary functions */ +extern double __ieee754_sqrt __P((double)); +extern double __ieee754_acos __P((double)); +extern double __ieee754_acosh __P((double)); +extern double __ieee754_log __P((double)); +extern double __ieee754_atanh __P((double)); +extern double __ieee754_asin __P((double)); +extern double __ieee754_atan2 __P((double, double)); +extern double __ieee754_exp __P((double)); +extern double __ieee754_cosh __P((double)); +extern double __ieee754_fmod __P((double, double)); +extern double __ieee754_pow __P((double, double)); +extern double __ieee754_lgamma_r __P((double, int*)); +extern double __ieee754_gamma_r __P((double, int*)); +extern double __ieee754_lgamma __P((double)); +extern double __ieee754_gamma __P((double)); +extern double __ieee754_log10 __P((double)); +extern double __ieee754_sinh __P((double)); +extern double __ieee754_hypot __P((double, double)); +extern double __ieee754_j0 __P((double)); +extern double __ieee754_j1 __P((double)); +extern double __ieee754_y0 __P((double)); +extern double __ieee754_y1 __P((double)); +extern double __ieee754_jn __P((int, double)); +extern double __ieee754_yn __P((int, double)); +extern double __ieee754_remainder __P((double, double)); +extern int __ieee754_rem_pio2 __P((double, double*)); +#ifdef _SCALB_INT +extern double __ieee754_scalb __P((double, int)); +#else +extern double __ieee754_scalb __P((double, double)); +#endif + +/* fdlibm kernel function */ +extern double __kernel_standard __P((double, double, int)); +extern double __kernel_sin __P((double, double, int)); +extern double __kernel_cos __P((double, double)); +extern double __kernel_tan __P((double, double, int)); +extern int __kernel_rem_pio2 __P((double*, double*, int, int, int, const int*)); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#include "math.h" + +#endif diff --git a/libs/PowerPC_EABI_Support/include/float.h b/libs/PowerPC_EABI_Support/include/float.h new file mode 100644 index 000000000..e90e6b5a8 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/float.h @@ -0,0 +1,59 @@ +#ifndef _FLOAT_H +#define _FLOAT_H + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +extern int __double_max[]; +extern int __extended_min[]; +extern int __extended_max[]; +extern int __float_max[]; +extern int __float_epsilon[]; + +#define FLT_MANT_DIG 24 +#define FLT_DIG 6 +#define FLT_MIN_EXP (-125) +#define FLT_MIN_10_EXP (-37) +#define FLT_MAX_EXP 128 +#define FLT_MAX_10_EXP 38 + +//#define FLT_MAX 0x1.fffffeP127F +//#define FLT_EPSILON 0x1.000000P-23F +#define FLT_MIN 0x1.000000P-126F + +#define FLT_MAX (*(float*)__float_max) +#define FLT_EPSILON (*(float*)__float_epsilon) + +#define DBL_MANT_DIG 53 +#define DBL_DIG 15 +#define DBL_MIN_EXP (-1021) +#define DBL_MIN_10_EXP (-308) +#define DBL_MAX_EXP 1024 +#define DBL_MAX_10_EXP 308 + +//#define DBL_MAX 0x1.fffffffffffffP1023 +#define DBL_EPSILON 0x1.0000000000000P-52 +#define DBL_MIN 0x1.0000000000000P-1022 + +#define DBL_MAX (*(double*)__double_max) + +#define LDBL_MANT_DIG 53 +#define LDBL_DIG 15 +#define LDBL_MIN_EXP (-1021) +#define LDBL_MIN_10_EXP (-308) +#define LDBL_MAX_EXP 1024 +#define LDBL_MAX_10_EXP 308 + +//#define LDBL_MAX 0x1.fffffffffffffP1023L +#define LDBL_EPSILON 0x1.0000000000000P-52L +//#define LDBL_MIN 0x1.0000000000000P-1022L + +#define LDBL_MAX (*(long double*)__extended_max) +#define LDBL_MIN (*(long double*)__extended_min) + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/functional b/libs/PowerPC_EABI_Support/include/functional new file mode 100644 index 000000000..9c74735b1 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/functional @@ -0,0 +1,20 @@ +#ifndef _STD_FUNCTIONAL_H +#define _STD_FUNCTIONAL_H + +#include "types.h" + +namespace std { +template +struct binary_function { + typedef LHS first_argument_type; + typedef RHS second_argument_type; + typedef Result result_type; +}; + +template +struct less : public binary_function { + bool operator()(const T& lhs, const T& rhs) const { return lhs < rhs; } +}; +} // namespace std + +#endif diff --git a/libs/PowerPC_EABI_Support/include/iterator b/libs/PowerPC_EABI_Support/include/iterator new file mode 100644 index 000000000..726024727 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/iterator @@ -0,0 +1,41 @@ +#ifndef _STD_ITERATOR_H +#define _STD_ITERATOR_H + +#include "types.h" + +namespace std { +typedef long ptrdiff_t; + +struct input_iterator_tag { +}; +struct output_iterator_tag { +}; +struct forward_iterator_tag : public input_iterator_tag { +}; +struct bidirectional_iterator_tag : public forward_iterator_tag { +}; +struct random_access_iterator_tag : public bidirectional_iterator_tag +{ +}; + +template +struct iterator_traits { + typedef typename Iterator::difference_type difference_type; + typedef typename Iterator::value_type value_type; + typedef typename Iterator::pointer pointer; + typedef typename Iterator::reference reference; + typedef typename Iterator::iterator_category iterator_category; +}; + +template +struct iterator { + typedef IteratorTag iterator_category; + typedef ValueType value_type; + typedef DifferenceType difference_type; + typedef Pointer pointer; + typedef Reference reference; +}; +} // namespace std + +#endif diff --git a/libs/PowerPC_EABI_Support/include/limits b/libs/PowerPC_EABI_Support/include/limits new file mode 100644 index 000000000..58b012269 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/limits @@ -0,0 +1,70 @@ +#ifndef _STD_LIMITS_H +#define _STD_LIMITS_H + +namespace std { +template +class numeric_limits { +public: + inline static T min(); + inline static T max(); +}; + +template <> +class numeric_limits { +public: + inline static char min() { return -0x80; } + inline static char max() { return 0x7F; } +}; + +template <> +class numeric_limits { +public: + inline static short min() { return -0x8000; } + inline static short max() { return 0x7FFF; } +}; + +template <> +class numeric_limits { +public: + inline static int min() { return -0x80000000; } + inline static int max() { return 0x7FFFFFFF; } +}; + +template <> +class numeric_limits { +public: + inline static long min() { return -0x80000000; } + inline static long max() { return 0x7FFFFFFF; } +}; + +template <> +class numeric_limits { +public: + inline static unsigned char min() { return 0x0; } + inline static unsigned char max() { return 0xFF; } +}; + +template <> +class numeric_limits { +public: + inline static unsigned short min() { return 0x0; } + inline static unsigned short max() { return 0xFFFF; } +}; + +template <> +class numeric_limits { +public: + inline static unsigned int min() { return 0x0; } + inline static unsigned int max() { return 0xFFFFFFFF; } +}; + +template <> +class numeric_limits { +public: + inline static unsigned long min() { return 0x0; } + inline static unsigned long max() { return 0xFFFFFFFF; } +}; + +} // namespace std + +#endif diff --git a/libs/PowerPC_EABI_Support/include/limits.h b/libs/PowerPC_EABI_Support/include/limits.h new file mode 100644 index 000000000..f8ffdbb5f --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/limits.h @@ -0,0 +1,36 @@ +#ifndef _LIMITS_H +#define _LIMITS_H +#include "types.h" +#ifdef __cplusplus +extern "C" { +#endif + +#define CHAR_BIT 8 + +#define SCHAR_MIN (-0x7F - 1) +#define SCHAR_MAX 0x7F +#define UCHAR_MAX 0xFF + +#define CHAR_MIN 0 +#define CHAR_MAX SCHAR_MAX + +#define SHRT_MIN (-0x7FFF - 1) +#define SHRT_MAX 0x7FFF +#define USHRT_MAX 0xFFFF + +#define INT_MIN (-0x7FFFFFFF - 1) +#define INT_MAX 0x7FFFFFFF +#define UINT_MAX 0xFFFFFFFF + +#define LONG_MIN (-0x7FFFFFFFL - 1) +#define LONG_MAX 0x7FFFFFFFL +#define ULONG_MAX 0xFFFFFFFFUL + +#define LLONG_MIN (-0x7FFFFFFFFFFFFFFFLL - 1) +#define LLONG_MAX 0x7FFFFFFFFFFFFFFFLL +#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/PowerPC_EABI_Support/include/locale.h b/libs/PowerPC_EABI_Support/include/locale.h new file mode 100644 index 000000000..12ca1d325 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/locale.h @@ -0,0 +1,129 @@ +#ifndef _LOCALE_H +#define _LOCALE_H + +#include "types.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int (*__decode_mbyte)(wchar_t*, const char*, size_t); +typedef int (*__encode_mbyte)(char*, wchar_t); + +struct lconv +{ + char* decimal_point; + char* thousands_sep; + char* grouping; + char* mon_decimal_point; + char* mon_thousands_sep; + char* mon_grouping; + char* positive_sign; + char* negative_sign; + char* currency_symbol; + char frac_digits; + char p_cs_precedes; + char n_cs_precedes; + char p_sep_by_space; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; + char* int_curr_symbol; + char int_frac_digits; + char int_p_cs_precedes; + char int_n_cs_precedes; + char int_p_sep_by_space; + char int_n_sep_by_space; + char int_p_sign_posn; + char int_n_sign_posn; +}; + +struct _loc_mon_cmpt +{ + char CmptName[8]; + char* mon_decimal_point; + char* mon_thousands_sep; + char* mon_grouping; + char* positive_sign; + char* negative_sign; + char* currency_symbol; + char frac_digits; + char p_cs_precedes; + char n_cs_precedes; + char p_sep_by_space; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; + char* int_curr_symbol; + char int_frac_digits; + char int_p_cs_precedes; + char int_n_cs_precedes; + char int_p_sep_by_space; + char int_n_sep_by_space; + char int_p_sign_posn; + char int_n_sign_posn; +}; + +struct _loc_num_cmpt +{ + char CmptName[8]; + char* decimal_point; + char* thousands_sep; + char* grouping; +}; + +struct _loc_time_cmpt +{ + char CmptName[8]; + char* am_pm; + char* DateTime_Format; + char* Twelve_hr_format; + char* Date_Format; + char* Time_Format; + char* Day_Names; + char* MonthNames; + char* TimeZone; +}; + +struct _loc_coll_cmpt +{ + char CmptName[8]; + int char_start_value; + int char_coll_tab_size; + short char_spec_accents; + unsigned short* char_coll_table_ptr; + unsigned short* wchar_coll_seq_ptr; +}; + +struct _loc_ctype_cmpt +{ + char CmptName[8]; + const unsigned short* ctype_map_ptr; + const unsigned char* upper_map_ptr; + const unsigned char* lower_map_ptr; + const unsigned short* wctype_map_ptr; + const wchar_t* wupper_map_ptr; + const wchar_t* wlower_map_ptr; + __decode_mbyte decode_mb; + __encode_mbyte encode_wc; +}; + +struct __locale +{ + struct __locale* next_locale; + char locale_name[48]; + struct _loc_coll_cmpt* coll_cmpt_ptr; + struct _loc_ctype_cmpt* ctype_cmpt_ptr; + struct _loc_mon_cmpt* mon_cmpt_ptr; + struct _loc_num_cmpt* num_cmpt_ptr; + struct _loc_time_cmpt* time_cmpt_ptr; +}; + +extern struct __locale _current_locale; +extern struct lconv __lconv; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/PowerPC_EABI_Support/include/math.h b/libs/PowerPC_EABI_Support/include/math.h new file mode 100644 index 000000000..edf13528a --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/math.h @@ -0,0 +1,99 @@ +#ifndef _MATH_H +#define _MATH_H + +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h" +#include "PowerPC_EABI_Support/MSL_C/PPC_EABI/math_ppc.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#ifndef __MWERKS__ +// Get clangd to shut up about __fabs being undefined. +#define __fabs(x) (x) +#define __fabsf(x) (x) +#define __frsqrte(x) (x) +#endif + +#define FABS(x) (float)__fabs(x) +// #define __frsqrtes opword + +#define SQUARE(v) ((v) * (v)) + +#define signbit(x) ((int)(__HI(x) & 0x80000000)) + +#define TAU 6.2831855f +#define PI 3.1415927f +#define HALF_PI 1.5707964f + +#define LONG_TAU 6.2831854820251465 + +extern int __float_nan[]; +extern int __float_huge[]; +extern int __double_huge[]; + +#define INFINITY (*(float*)__float_huge) +#define NAN (*(float*)__float_nan) +#define HUGE_VAL (*(double*)__double_huge) + +inline long double fabsl(long double x) +{ + return __fabs((double)x); +} + +inline double fabs(double x) +{ + return __fabs(x); +} + +double acos(double); +double asin(double); +double atan(double); +double atan2(double, double); +double ceil(double); +double floor(double); +float floorf(float x); +double frexp(double, int*); +double ldexp(double, int); +double sqrt(double); + +double pow(double, double); + +double log(double); +double log10(double); + +double fmod(double, double); + +double sin(double x); +double cos(double x); + +double __ieee754_acos(double); +double __ieee754_fmod(double, double); +double __ieee754_log(double); +double __ieee754_log10(double); +double __ieee754_pow(double, double); +double __ieee754_sqrt(double); +double __ieee754_atan2(double, double); +double __ieee754_asin(double); + +double scalbn(double, int); + +double __kernel_sin(double, double, int); +double __kernel_cos(double, double); +double __kernel_tan(double, double, int); + +int __ieee754_rem_pio2(double, double*); + +// static inline float atan2f(float y, float x) +// { +// return atan2(y, x); +// } + +// float sqrtf(float); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/mem.h b/libs/PowerPC_EABI_Support/include/mem.h new file mode 100644 index 000000000..a43890932 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/mem.h @@ -0,0 +1,20 @@ +#ifndef _MEM_H +#define _MEM_H + +#include "types.h" +#include "PowerPC_EABI_Support\Runtime\__mem.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +int memcmp(const void*, const void*, size_t); +void* __memrchr(const void* src, int val, size_t n); +void* memchr(const void* src, int val, size_t n); +void* memmove(void*, const void*, size_t); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/signal.h b/libs/PowerPC_EABI_Support/include/signal.h new file mode 100644 index 000000000..180ee669c --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/signal.h @@ -0,0 +1,18 @@ +#ifndef _SIGNAL_H +#define _SIGNAL_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*sig_func)(int sig); + +int raise(int sig); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/PowerPC_EABI_Support/include/stdarg.h b/libs/PowerPC_EABI_Support/include/stdarg.h new file mode 100644 index 000000000..5b4cc2185 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/stdarg.h @@ -0,0 +1,40 @@ + +#ifndef _STDARG_H_ +#define _STDARG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __MWERKS__ +typedef struct __va_list_struct +{ + char gpr; + char fpr; + char reserved[2]; + char *input_arg_area; + char *reg_save_area; +} __va_list[1]; +typedef __va_list va_list; + +#ifndef __MWERKS__ +extern void __builtin_va_info(va_list*); +#endif + +void* __va_arg(va_list v_list, unsigned char type); + +#define va_start(ap, fmt) ((void)fmt, __builtin_va_info(&ap)) +#define va_arg(ap, t) (*((t*)__va_arg(ap, _var_arg_typeof(t)))) +#define va_end(ap) (void)0 + +#else +typedef __builtin_va_list va_list; +#define va_start(v, l) __builtin_va_start(v, l) +#define va_end(v) __builtin_va_end(v) +#define va_arg(v, l) __builtin_va_arg(v, l) +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/PowerPC_EABI_Support/include/stddef.h b/libs/PowerPC_EABI_Support/include/stddef.h new file mode 100644 index 000000000..a0a90f9b4 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/stddef.h @@ -0,0 +1,6 @@ +#ifndef _MSL_STDDEF_H +#define _MSL_STDDEF_H + +#include + +#endif \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/include/stdio.h b/libs/PowerPC_EABI_Support/include/stdio.h new file mode 100644 index 000000000..1e8f9f66e --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/stdio.h @@ -0,0 +1,19 @@ +#ifndef _STDIO_H +#define _STDIO_H + +#include "types.h" +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/direct_io.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/file_io.h" +#include +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/scanf.h" + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/stdlib.h b/libs/PowerPC_EABI_Support/include/stdlib.h new file mode 100644 index 000000000..f573b4565 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/stdlib.h @@ -0,0 +1,20 @@ +#ifndef _STDLIB_H +#define _STDLIB_H + +#include "types.h" +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/alloc.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/arith.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/mbstring.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/rand.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/strtold.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/strtoul.h" + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/string.h b/libs/PowerPC_EABI_Support/include/string.h new file mode 100644 index 000000000..3d5f5cb5e --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/string.h @@ -0,0 +1,31 @@ +#ifndef _STRING_H +#define _STRING_H + +#include "types.h" +#include "mem.h" +#include "extras.h" +#ifdef __cplusplus +extern "C" { +#endif + +char* strcpy(char*, const char*); +char* strncpy(char*, const char*, size_t); + +char* strcat(char*, const char*); +char* strncat(char*, const char*, size_t); + +int strcmp(const char*, const char*); +int strncmp(const char*, const char*, size_t); +int strcmpi(const char* a, const char* b); +char* strchr(const char*, int); +char* strstr(const char*, const char*); +char* strrchr(const char* str, int chr); +size_t strlen(const char*); +long strtol(const char* str, char** end, int base); + +int __msl_strnicmp(const char* s1, const char* s2, int n); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/PowerPC_EABI_Support/include/utility b/libs/PowerPC_EABI_Support/include/utility new file mode 100644 index 000000000..223183a2c --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/utility @@ -0,0 +1,21 @@ +#ifndef _STD_PAIR_H +#define _STD_PAIR_H + +namespace std { +template +struct pair { + T1 first; + T2 second; +}; + +template <> +struct pair { + pair() + : first(0.0f) + , second(0.0f) {}; + float first; + float second; +}; +} // namespace std + +#endif diff --git a/libs/PowerPC_EABI_Support/include/wchar.h b/libs/PowerPC_EABI_Support/include/wchar.h new file mode 100644 index 000000000..2df951877 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/wchar.h @@ -0,0 +1,16 @@ +#ifndef _WCHAR_H +#define _WCHAR_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/wchar_io.h" + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/FILE_POS.C b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/FILE_POS.C new file mode 100644 index 000000000..b4b6d28d2 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/FILE_POS.C @@ -0,0 +1,130 @@ +#include "types.h" + +#ifndef _MSL_WIDE_CHAR +#define _MSL_WIDE_CHAR +#endif + +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h" +#include "errno.h" + +// define standard C file pointer location names +#define SEEK_SET (0) +#define SEEK_CUR (1) +#define SEEK_END (2) + +int _ftell(FILE* file) +{ + int charsInUndoBuffer = 0; + int position; + + u8 tmp_kind = file->mMode.file_kind; + if (!(tmp_kind == __disk_file || tmp_kind == __console_file) || file->mState.error) { + errno = 0x28; + return -1; + } + + if (file->mState.io_state == __neutral) + return (file->mPosition); + + position = file->mBufferPosition + (file->mBufferPtr - file->mBuffer); + + if (file->mState.io_state >= __rereading) { + charsInUndoBuffer = file->mState.io_state - __rereading + 1; + position -= charsInUndoBuffer; + } + + // got added in later it seems? + /*if (!file->mMode.binary_io) { + int n = file->mBufferPtr - file->mBuffer - charsInUndoBuffer; + u8* p = (u8*)file->mBuffer; + + while (n--) + if (*p++ == '\n') + position++; + }*/ + + return (position); +} + +int ftell(FILE* stream) +{ + int retval; + + __begin_critical_region(stdin_access); + retval = (long)_ftell(stream); + __end_critical_region(stdin_access); + return retval; +} + +int _fseek(FILE *file, fpos_t offset, int whence) +{ + fpos_t pos; + __pos_proc func; + + unsigned char fileKind = file->mMode.file_kind; + if (fileKind != 1 || file->mState.error != 0) { + errno = 0x28; + return -1; + } + + if (file->mState.io_state == 1) { + if (__flush_buffer(file, nullptr) != 0) { + file->mState.error = 1; + file->mBufferLength = 0; + errno = 0x28; + return -1; + } + } + + if (whence == SEEK_CUR) { + whence = SEEK_SET; + + if ((pos = _ftell(file)) < 0) + pos = 0; + + offset += pos; + } + + if ((whence != SEEK_END) && (file->mMode.io_mode != 3) && (file->mState.io_state == 2 || file->mState.io_state == 3)) { + if ((offset >= file->mPosition) || !(offset >= file->mBufferPosition)) { + file->mState.io_state = 0; + } else { + file->mBufferPtr = file->mBuffer + (offset - file->mBufferPosition); + file->mBufferLength = file->mPosition - offset; + file->mState.io_state = 2; + } + } else { + file->mState.io_state = 0; + } + + if (file->mState.io_state == 0) { + + if ((func = file->positionFunc) != nullptr && func(file->mHandle, &offset, whence, file->ref_con) != 0) + { + file->mState.error = 1; + file->mBufferLength = 0; + errno = 0x28; + return -1; + } + else + { + file->mState.eof = 0; + file->mPosition = offset; + file->mBufferLength = 0; + } + } + + return 0; +} + +int fseek(FILE *stream, fpos_t offset, int whence) +{ + fpos_t start; + int code; + start = offset; + __begin_critical_region(stdin_access); + code = _fseek(stream, start, whence); // 0 if successful, -1 if error + __end_critical_region(stdin_access); + return code; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/alloc.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/alloc.c new file mode 100644 index 000000000..016240ad6 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/alloc.c @@ -0,0 +1,452 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/alloc.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" + +typedef struct Block { + struct Block* prev; + struct Block* next; + unsigned long max_size; + unsigned long size; +} Block; + +typedef struct SubBlock { + unsigned long size; + Block* block; + struct SubBlock* prev; + struct SubBlock* next; +} SubBlock; + +struct FixSubBlock; + +typedef struct FixBlock { + struct FixBlock* prev_; + struct FixBlock* next_; + unsigned long client_size_; + struct FixSubBlock* start_; + unsigned long n_allocated_; +} FixBlock; + +typedef struct FixSubBlock { + FixBlock* block_; + struct FixSubBlock* next_; +} FixSubBlock; + +typedef struct FixStart { + FixBlock* tail_; + FixBlock* head_; +} FixStart; + +typedef struct __mem_pool_obj { + Block* start_; + FixStart fix_start[6]; +} __mem_pool_obj; + +typedef struct __mem_pool { + void* reserved[14]; +} __mem_pool; + +typedef signed long tag_word; + +typedef struct block_header { + tag_word tag; + struct block_header* prev; + struct block_header* next; +} block_header; + +typedef struct list_header { + block_header* rover; + block_header header; +} list_header; + +typedef struct heap_header { + struct heap_header* prev; + struct heap_header* next; +} heap_header; + +struct mem_pool_obj; +typedef void* (*sys_alloc_ptr)(unsigned long, struct mem_pool_obj*); +typedef void (*sys_free_ptr)(void*, struct mem_pool_obj*); + +typedef struct pool_options { + sys_alloc_ptr sys_alloc_func; + sys_free_ptr sys_free_func; + unsigned long min_heap_size; + int always_search_first; +} pool_options; + +typedef struct mem_pool_obj { + list_header free_list; + pool_options options; + heap_header* heap_list; + void* userData; + +} mem_pool_obj; + +mem_pool_obj __malloc_pool; +static int initialized = 0; + +static SubBlock* SubBlock_merge_prev(SubBlock*, SubBlock**); +static void SubBlock_merge_next(SubBlock*, SubBlock**); + +static const unsigned long fix_pool_sizes[] = { 4, 12, 20, 36, 52, 68 }; + +#define SubBlock_size(ths) ((ths)->size & 0xFFFFFFF8) +#define SubBlock_block(ths) ((Block*)((unsigned long)((ths)->block) & ~0x1)) +#define Block_size(ths) ((ths)->size & 0xFFFFFFF8) +#define Block_start(ths) (*(SubBlock**)((char*)(ths) + Block_size((ths)) - sizeof(unsigned long))) + +#define SubBlock_set_free(ths) \ + unsigned long this_size = SubBlock_size((ths)); \ + (ths)->size &= ~0x2; \ + *(unsigned long*)((char*)(ths) + this_size) &= ~0x4; \ + *(unsigned long*)((char*)(ths) + this_size - sizeof(unsigned long)) = this_size + +#define SubBlock_is_free(ths) !((ths)->size & 2) +#define SubBlock_set_size(ths, sz) \ + (ths)->size &= ~0xFFFFFFF8; \ + (ths)->size |= (sz)&0xFFFFFFF8; \ + if (SubBlock_is_free((ths))) \ + *(unsigned long*)((char*)(ths) + (sz) - sizeof(unsigned long)) = (sz) + +#define SubBlock_from_pointer(ptr) ((SubBlock*)((char*)(ptr)-8)) +#define FixSubBlock_from_pointer(ptr) ((FixSubBlock*)((char*)(ptr)-4)) + +#define FixBlock_client_size(ths) ((ths)->client_size_) +#define FixSubBlock_size(ths) (FixBlock_client_size((ths)->block_)) + +#define classify(ptr) (*(unsigned long*)((char*)(ptr) - sizeof(unsigned long)) & 1) +#define __msize_inline(ptr) \ + (!classify(ptr) ? FixSubBlock_size(FixSubBlock_from_pointer(ptr)) : SubBlock_size(SubBlock_from_pointer(ptr)) - 8) + +#define Block_empty(ths) (_sb = (SubBlock*)((char*)(ths) + 16)), SubBlock_is_free(_sb) && SubBlock_size(_sb) == Block_size((ths)) - 24 + +void Block_construct(void) +{ + // UNUSED FUNCTION +} + +void Block_subBlock(void) +{ + // UNUSED FUNCTION +} + +void Block_link(Block* ths, SubBlock* sb) +{ + SubBlock** st; + SubBlock_set_free(sb); + st = &Block_start(ths); + + if (*st != 0) { + sb->prev = (*st)->prev; + sb->prev->next = sb; + sb->next = *st; + (*st)->prev = sb; + *st = sb; + *st = SubBlock_merge_prev(*st, st); + SubBlock_merge_next(*st, st); + } else { + *st = sb; + sb->prev = sb; + sb->next = sb; + } + if (ths->max_size < SubBlock_size(*st)) + ths->max_size = SubBlock_size(*st); +} + +void Block_unlink(void) +{ + // UNUSED FUNCTION +} + +void Block_report(void) +{ + // UNUSED FUNCTION +} + +void SubBlock_construct(void) +{ + // UNUSED FUNCTION +} + +void SubBlock_split(void) +{ + // UNUSED FUNCTION +} + +static SubBlock* SubBlock_merge_prev(SubBlock* ths, SubBlock** start) +{ + unsigned long prevsz; + SubBlock* p; + + if (!(ths->size & 0x04)) { + prevsz = *(unsigned long*)((char*)ths - sizeof(unsigned long)); + if (prevsz & 0x2) + return ths; + p = (SubBlock*)((char*)ths - prevsz); + SubBlock_set_size(p, prevsz + SubBlock_size(ths)); + + if (*start == ths) + *start = (*start)->next; + ths->next->prev = ths->prev; + ths->next->prev->next = ths->next; + return p; + } + return ths; +} + +static void SubBlock_merge_next(SubBlock* pBlock, SubBlock** pStart) +{ + SubBlock* next_sub_block; + unsigned long this_cur_size; + + next_sub_block = (SubBlock*)((char*)pBlock + (pBlock->size & 0xFFFFFFF8)); + + if (!(next_sub_block->size & 2)) { + this_cur_size = (pBlock->size & 0xFFFFFFF8) + (next_sub_block->size & 0xFFFFFFF8); + + pBlock->size &= ~0xFFFFFFF8; + pBlock->size |= this_cur_size & 0xFFFFFFF8; + + if (!(pBlock->size & 2)) { + *(unsigned long*)((char*)(pBlock) + (this_cur_size)-4) = (this_cur_size); + } + + if (!(pBlock->size & 2)) { + *(unsigned long*)((char*)pBlock + this_cur_size) &= ~4; + } else { + *(unsigned long*)((char*)pBlock + this_cur_size) |= 4; + } + + if (*pStart == next_sub_block) { + *pStart = (*pStart)->next; + } + + if (*pStart == next_sub_block) { + *pStart = 0; + } + + next_sub_block->next->prev = next_sub_block->prev; + next_sub_block->prev->next = next_sub_block->next; + } +} + +void SubBlock_report(void) +{ + // UNUSED FUNCTION +} + +void link(void) +{ + // UNUSED FUNCTION +} + +static Block* __unlink(__mem_pool_obj* pool_obj, Block* bp) +{ + Block* result = bp->next; + if (result == bp) { + result = 0; + } + + if (pool_obj->start_ == bp) { + pool_obj->start_ = result; + } + + if (result != 0) { + result->prev = bp->prev; + result->prev->next = result; + } + + bp->next = 0; + bp->prev = 0; + return result; +} + +void link_new_block(void) +{ + // UNUSED FUNCTION +} + +void allocate_from_var_pools(void) +{ + // UNUSED FUNCTION +} + +void soft_allocate_from_var_pools(void) +{ + // UNUSED FUNCTION +} + +static void deallocate_from_var_pools(__mem_pool_obj* pool_obj, void* ptr) +{ + SubBlock* sb = SubBlock_from_pointer(ptr); + SubBlock* _sb; + + Block* bp = SubBlock_block(sb); + Block_link(bp, sb); + + if (Block_empty(bp)) { + __unlink(pool_obj, bp); + __sys_free(bp); + } +} + +void FixBlock_construct(void) +{ + // UNUSED FUNCTION +} + +void __init_pool_obj(__mem_pool* pool_obj) { memset(pool_obj, 0, sizeof(__mem_pool_obj)); } + +static __mem_pool* get_malloc_pool(void) +{ + static __mem_pool protopool; + static unsigned char init = 0; + if (!init) { + __init_pool_obj(&protopool); + init = 1; + } + + return &protopool; +} + +void allocate_from_fixed_pools(void) +{ + // UNUSED FUNCTION +} + +void deallocate_from_fixed_pools(__mem_pool_obj* pool_obj, void* ptr, unsigned long size) +{ + unsigned long i = 0; + FixSubBlock* p; + FixBlock* b; + FixStart* fs; + + while (size > fix_pool_sizes[i]) { + ++i; + } + + fs = &pool_obj->fix_start[i]; + p = FixSubBlock_from_pointer(ptr); + b = p->block_; + + if (b->start_ == 0 && fs->head_ != b) { + if (fs->tail_ == b) { + fs->head_ = fs->head_->prev_; + fs->tail_ = fs->tail_->prev_; + } else { + b->prev_->next_ = b->next_; + b->next_->prev_ = b->prev_; + b->next_ = fs->head_; + b->prev_ = b->next_->prev_; + b->prev_->next_ = b; + b->next_->prev_ = b; + fs->head_ = b; + } + } + + p->next_ = b->start_; + b->start_ = p; + + if (--b->n_allocated_ == 0) { + if (fs->head_ == b) { + fs->head_ = b->next_; + } + + if (fs->tail_ == b) { + fs->tail_ = b->prev_; + } + + b->prev_->next_ = b->next_; + b->next_->prev_ = b->prev_; + + if (fs->head_ == b) { + fs->head_ = 0; + } + + if (fs->tail_ == b) { + fs->tail_ = 0; + } + + deallocate_from_var_pools(pool_obj, b); + } +} + +void __report_on_pool_heap(void) +{ + // UNUSED FUNCTION +} + +void __report_on_heap(void) +{ + // UNUSED FUNCTION +} + +void __msize(void) +{ + // UNUSED FUNCTION +} + +void __pool_alloc(void) +{ + // UNUSED FUNCTION +} + +void __pool_free(__mem_pool* pool, void* ptr) +{ + __mem_pool_obj* pool_obj; + unsigned long size; + + if (ptr == 0) { + return; + } + + pool_obj = (__mem_pool_obj*)pool; + size = __msize_inline(ptr); + + if (size <= 68) { + deallocate_from_fixed_pools(pool_obj, ptr, size); + } else { + deallocate_from_var_pools(pool_obj, ptr); + } +} + +void __pool_realloc(void) +{ + // UNUSED FUNCTION +} + +void __pool_alloc_clear(void) +{ + // UNUSED FUNCTION +} + +void malloc(void) +{ + // UNUSED FUNCTION +} + +void free(void* ptr) +{ + __begin_critical_region(malloc_pool_access); + __pool_free(get_malloc_pool(), ptr); + __end_critical_region(malloc_pool_access); +} + +void realloc(void) +{ + // UNUSED FUNCTION +} + +void calloc(void) +{ + // UNUSED FUNCTION +} + +void __pool_free_all(void) +{ + // UNUSED FUNCTION +} + +void __malloc_free_all(void) +{ + // UNUSED FUNCTION +} \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ansi_files.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ansi_files.c new file mode 100644 index 000000000..a210e106f --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ansi_files.c @@ -0,0 +1,154 @@ +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" + +static char stdin_buff[0x100]; +static char stdout_buff[0x100]; +static char stderr_buff[0x100]; + +extern void fclose(FILE*); +extern int __read_console(u32, char*, u32*, void*); +extern int __write_console(u32, char*, u32*, void*); +extern int __close_console(u32); + +// clang-format off +FILE __files[4] = +{ + { 0, // _00 + 0, // _04, open_mode + 1, // _04, io_mode + 1, // _04, buffer_mode + 2, // _04, file_kind + 0, // _04, binary_io + 0, // _08, io_state + 0, // _08, free_buffer + 0, // _08, eof + 0, // _08, error + 0, // _0C + 0, // _0D + 0, // _0E + 0, // _0F + 0, // _10 + 0, // _12 + 0, // _14 + 0, // _18 + stdin_buff, // _1C + sizeof(stdin_buff), // _20 + stdin_buff, // _24 + 0, // _28 + 0, // _2C + 0, // _30 + 0, // _34 + nullptr, // _38 + &__read_console, // _3C + &__write_console, // _40 + &__close_console, // _44 + 0, // _48 + &__files[1] // _4C + }, + { 1, // _00 + 0, // _04, open_mode + 2, // _04, io_mode + 1, // _04, buffer_mode + 2, // _04, file_kind + 0, // _04, binary_io + 0, // _08, io_state + 0, // _08, free_buffer + 0, // _08, eof + 0, // _08, error + 0, // _0C + 0, // _0D + 0, // _0E + 0, // _0F + 0, // _10 + 0, // _12 + 0, // _14 + 0, // _18 + stdout_buff, // _1C + sizeof(stdout_buff), // _20 + stdout_buff, // _24 + 0, // _28 + 0, // _2C + 0, // _30 + 0, // _34 + nullptr, // _38 + &__read_console, // _3C + &__write_console, // _40 + &__close_console, // _44 + 0, // _48 + &__files[2] // _4C + }, + { 2, // _00 + 0, // _04, open_mode + 2, // _04, io_mode + 0, // _04, buffer_mode + 2, // _04, file_kind + 0, // _04, binary_io + 0, // _08, io_state + 0, // _08, free_buffer + 0, // _08, eof + 0, // _08, error + 0, // _0C + 0, // _0D + 0, // _0E + 0, // _0F + 0, // _10 + 0, // _12 + 0, // _14 + 0, // _18 + stderr_buff, // _1C + sizeof(stderr_buff), // _20 + stderr_buff, // _24 + 0, // _28 + 0, // _2C + 0, // _30 + 0, // _34 + nullptr, // _38 + &__read_console, // _3C + &__write_console, // _40 + &__close_console, // _44 + 0, // _48 + &__files[3] // _4C + }, +}; +// clang-format on + +void __close_all() +{ + FILE* p = &__files[0]; + FILE* plast; + + __begin_critical_region(stdin_access); + + while (p) { + if (p->mMode.file_kind != __closed_file) { + fclose(p); + } + + plast = p; + p = p->mNextFile; + if (plast->mIsDynamicallyAllocated) + free(plast); + else { + plast->mMode.file_kind = __unavailable_file; + if ((p != NULL) && p->mIsDynamicallyAllocated) + plast->mNextFile = nullptr; + } + } + + __end_critical_region(stdin_access); +} + +u32 __flush_all() +{ + u32 retval = 0; + FILE* __stream; + __stream = &__files[0]; + while (__stream) { + if ((__stream->mMode.file_kind) && (fflush(__stream))) { + retval = -1; + } + __stream = __stream->mNextFile; + }; + return retval; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/arith.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/arith.c new file mode 100644 index 000000000..fd9e3667a --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/arith.c @@ -0,0 +1,120 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/arith.h" + +long abs(long x) +{ + if (x < 0) + return -x; + else + return x; +} + +long labs(long x) +{ + // UNUSED FUNCTION + if (x < 0) + return -x; + else + return x; +} + +void llabs(void) +{ + // UNUSED FUNCTION +} + +div_t div(s32 __numer, s32 __denom) +{ + // UNUSED FUNCTION + int iVar1; + int iVar2; + int iVar3; + div_t ret; + + iVar2 = 1; + iVar3 = 1; + if (__numer < 0) + { + __numer = -__numer; + iVar2 = -1; + } + if (__denom < 0) + { + __denom = -__denom; + iVar3 = -1; + } + iVar1 = (__numer / __denom) * (iVar2 * iVar3); + + ret.quot = iVar1; + ret.rem = __numer * iVar2 - iVar3 * (iVar1 * __denom); + return ret; +} + +void ldiv(void) +{ + // UNUSED FUNCTION +} + +void lldiv(void) +{ + // UNUSED FUNCTION +} + +void __msl_add(void) +{ + // UNUSED FUNCTION +} + +void __msl_ladd(void) +{ + // UNUSED FUNCTION +} + +void __lladd(void) +{ + // UNUSED FUNCTION +} + +void __msl_mul(void) +{ + // UNUSED FUNCTION +} + +void __msl_lmul(void) +{ + // UNUSED FUNCTION +} + +void __llmul(void) +{ + // UNUSED FUNCTION +} + +void __msl_div(void) +{ + // UNUSED FUNCTION +} + +void __msl_ldiv(void) +{ + // UNUSED FUNCTION +} + +void __lldiv(void) +{ + // UNUSED FUNCTION +} + +void __msl_mod(void) +{ + // UNUSED FUNCTION +} + +void __msl_lmod(void) +{ + // UNUSED FUNCTION +} + +void __llmod(void) +{ + // UNUSED FUNCTION +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/bsearch.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/bsearch.c new file mode 100644 index 000000000..d8ea8e560 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/bsearch.c @@ -0,0 +1,40 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/bsearch.h" + +void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *)) +{ + int cmp; + size_t lower, upper; + size_t index; + const void *p; + + if (key == NULL || base == NULL || nmemb == 0 || size == 0 || compar == NULL) + return NULL; + + p = base; + cmp = (*compar)(key, p); + if(cmp == 0) + return (void *)p; + + if(cmp < 0) + return NULL; + + lower = 1; + upper = nmemb - 1; + + while (lower <= upper) + { + index = (lower + upper) / 2; + p = (const char *)base + (size * index); + cmp = (*compar)(key, p); + + if (cmp == 0) + return (void *)p; + if (cmp < 0) + upper = index - 1; + else + lower = index + 1; + } + + return NULL; +} \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/buffer_io.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/buffer_io.c new file mode 100644 index 000000000..9e3ed8afb --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/buffer_io.c @@ -0,0 +1,53 @@ +#ifndef _MSL_WIDE_CHAR +#define _MSL_WIDE_CHAR +#endif + +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" +#include "types.h" + +void __convert_from_newlines(char *buffer, size_t *length) +{ + return; +} + +void __convert_to_newlines() +{ + // UNUSED +} + +void __prep_buffer(FILE *file) +{ + file->mBufferPtr = file->mBuffer; + file->mBufferLength = file->mBufferSize; + file->mBufferLength = file->mBufferLength - (file->mPosition & file->mBufferAlignment); + file->mBufferPosition = file->mPosition; + return; +} + +int __flush_buffer(FILE *file, size_t *length) +{ + size_t bufferLen; + int writeCode; + char binmode; + + bufferLen = file->mBufferPtr - file->mBuffer; + if (bufferLen) { + file->mBufferLength = bufferLen; + + if (file->mMode.binary_io == 0) { + __convert_from_newlines(file->mBuffer, &file->mBufferLength); + } + + writeCode = file->writeFunc(file->mHandle, file->mBuffer, &file->mBufferLength, file->ref_con); + if (length) { + *length = file->mBufferLength; + } + if (writeCode) { + return writeCode; + } + file->mPosition += file->mBufferLength; + } + + __prep_buffer(file); + return 0; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ctype.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ctype.c new file mode 100644 index 000000000..bc673a86d --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ctype.c @@ -0,0 +1,137 @@ +#include "ctype.h" +#include "types.h" + +#define octrl 0x01 +#define omotn 0x02 +#define ospac 0x04 +#define opunc 0x08 +#define odigi 0x10 +#define ohexd 0x20 +#define olowc 0x40 +#define ouppc 0x80 +#define odhex ohexd | odigi +#define ouhex ohexd | ouppc +#define olhex ohexd | olowc + +unsigned char __ctype_map[256] = { + octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, omotn, omotn, omotn, omotn, + omotn, octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, + octrl, octrl, octrl, octrl, octrl, octrl, ospac, opunc, opunc, opunc, opunc, opunc, opunc, + opunc, opunc, opunc, opunc, opunc, opunc, opunc, opunc, opunc, odhex, odhex, odhex, odhex, + odhex, odhex, odhex, odhex, odhex, odhex, opunc, opunc, opunc, opunc, opunc, opunc, opunc, + ouhex, ouhex, ouhex, ouhex, ouhex, ouhex, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, + ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, + opunc, opunc, opunc, opunc, opunc, opunc, olhex, olhex, olhex, olhex, olhex, olhex, olowc, + olowc, olowc, olowc, olowc, olowc, olowc, olowc, olowc, olowc, olowc, olowc, olowc, olowc, + olowc, olowc, olowc, olowc, olowc, olowc, opunc, opunc, opunc, opunc, octrl +}; + +unsigned char __lower_map[256] = { + 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, 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, 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, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +}; + +unsigned char __upper_map[256] = { + 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, 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, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +}; + +void isalnum(void) +{ + // UNUSED FUNCTION +} + +int isalpha(int c) +{ + return (int)(__ctype_map[(u8)c] & __letter); +} + +void iscntrl(void) +{ + // UNUSED FUNCTION +} + +BOOL isdigit(int c) +{ + { + return (int)(__ctype_map[(u8)c] & __digit); + } +} + +void isgraph(void) +{ + // UNUSED FUNCTION +} + +BOOL islower(unsigned char c) +{ + return __ctype_map[c] & olowc; +} + +// void isprint(void) +// { +// // UNUSED FUNCTION +// } + +void ispunct(void) +{ + // UNUSED FUNCTION +} + +int isspace(int c) +{ + return (int)(__ctype_map[(u8)c] & __whitespace); +} + +BOOL isupper(int c) +{ + return (int)(__ctype_map[(u8)c] & __upper_case); +} + +BOOL isxdigit(int c) +{ + return (int)(__ctype_map[(u8)c] & __hex_digit); +} + +int tolower(int c) +{ + return (c == -1 ? -1 : (int)__lower_map[(u8)c]); +} + +int toupper(int c) +{ + return (c == -1 ? -1 : (int)__upper_map[(u8)c]); +} + +void iswblank(void) +{ + // UNUSED FUNCTION +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/direct_io.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/direct_io.c new file mode 100644 index 000000000..4364c3533 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/direct_io.c @@ -0,0 +1,143 @@ +#include "types.h" + +#ifndef _MSL_WIDE_CHAR +#define _MSL_WIDE_CHAR +#endif + +#include "wchar.h" +#include "stdio.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" + +void fread(void) +{ + // UNUSED FUNCTION +} + + +void __fread(void) +{ + // UNUSED FUNCTION +} + +size_t fwrite(const void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile) +{ + size_t retval; + + __begin_critical_region(stdin_access); + retval = __fwrite(pPtr, memb_size, num_memb, pFile); + __end_critical_region(stdin_access); + + return retval; +} + +size_t __fwrite(const void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile) +{ + unsigned char* cur_ptr; + size_t num_bytes, rem_bytes, bytes_written; + int res, buff; + + if (fwide(pFile, 0) == 0) { + fwide(pFile, -1); + } + + rem_bytes = memb_size * num_memb; + + if (rem_bytes == 0 || pFile->mState.error || pFile->mMode.file_kind == 0) { + return 0; + } + + if (pFile->mMode.file_kind == 2) { + __stdio_atexit(); + } + + buff = (!pFile->mMode.binary_io || pFile->mMode.buffer_mode == 2 || pFile->mMode.buffer_mode == 1); + + if (pFile->mState.io_state == 0 && pFile->mMode.io_mode & 2) { + if (pFile->mMode.io_mode & 4) { + if (fseek(pFile, 0, 2)) { + return 0; + } + } + + pFile->mState.io_state = 1; + __prep_buffer(pFile); + } + + if (pFile->mState.io_state != 1) { + pFile->mState.error = 1; + pFile->mBufferLength = 0; + return 0; + } + + cur_ptr = (unsigned char*)pPtr; + bytes_written = 0; + + if (rem_bytes && (pFile->mBufferPtr != pFile->mBuffer || buff)) { + pFile->mBufferLength = pFile->mBufferSize - (pFile->mBufferPtr - pFile->mBuffer); + + do { + unsigned char* nw = 0; + num_bytes = pFile->mBufferLength; + + if (num_bytes > rem_bytes) { + num_bytes = rem_bytes; + } + + if (pFile->mMode.buffer_mode == 1 && num_bytes) { + if ((nw = (unsigned char*)__memrchr(cur_ptr, '\n', num_bytes)) != 0) { + num_bytes = nw + 1 - cur_ptr; + } + } + + if (num_bytes != 0) { + memcpy(pFile->mBufferPtr, cur_ptr, num_bytes); + cur_ptr += num_bytes; + bytes_written += num_bytes; + rem_bytes -= num_bytes; + pFile->mBufferPtr += num_bytes; + pFile->mBufferLength -= num_bytes; + } + + if (pFile->mBufferLength == 0 || nw != 0 || (!pFile->mMode.buffer_mode)) { + res = __flush_buffer(pFile, 0); + + if (res != 0) { + pFile->mState.error = 1; + pFile->mBufferLength = 0; + rem_bytes = 0; + break; + } + } + + } while (rem_bytes && buff); + } + + if (rem_bytes && buff == 0) { + unsigned char* save_buf = (unsigned char*)pFile->mBuffer; + size_t save_size = pFile->mBufferSize; + + pFile->mBuffer = (char*)cur_ptr; + pFile->mBufferSize = rem_bytes; + pFile->mBufferPtr = (char*)cur_ptr + rem_bytes; + + if (__flush_buffer(pFile, &num_bytes) != 0) { + pFile->mState.error = 1; + pFile->mBufferLength = 0; + } + + bytes_written += num_bytes; + + pFile->mBuffer = (char*)save_buf; + pFile->mBufferSize = save_size; + __prep_buffer(pFile); + pFile->mBufferLength = 0; + } + + if (pFile->mMode.buffer_mode != 2) { + pFile->mBufferLength = 0; + } + + return (bytes_written + memb_size - 1) / memb_size; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/errno.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/errno.c new file mode 100644 index 000000000..afee599b7 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/errno.c @@ -0,0 +1,3 @@ +#include "errno.h" + +int errno; diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/extras.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/extras.c new file mode 100644 index 000000000..6e056b18c --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/extras.c @@ -0,0 +1,401 @@ +#include "types.h" +#include "ctype.h" + +void strdup(void) +{ + // UNUSED FUNCTION +} + +void _strdup(void) +{ + // UNUSED FUNCTION +} + +void strlwr(void) +{ + // UNUSED FUNCTION +} + +void _strlwr(void) +{ + // UNUSED FUNCTION +} + +void ultoa(void) +{ + // UNUSED FUNCTION +} + +void _ultoa(void) +{ + // UNUSED FUNCTION +} + +void gcvt(void) +{ + // UNUSED FUNCTION +} + +void _gcvt(void) +{ + // UNUSED FUNCTION +} + +void heapmin(void) +{ + // UNUSED FUNCTION +} + +void _heapmin(void) +{ + // UNUSED FUNCTION +} + +int stricmp(char* param_1, char* param_2) +{ + s8 a_var; + s8 b_var; + + do { + a_var = *param_1; + param_1++; + b_var = _tolower(a_var); + + a_var = *param_2; + param_2++; + a_var = _tolower(a_var); + + if (b_var < a_var) { + return -1; + } + if (b_var > a_var) { + return 1; + } + } while (b_var != 0); + return 0; +} + +void _stricmp(void) +{ + // UNUSED FUNCTION +} + +int strnicmp(const char *s1, const char *s2, int n) +{ + return __msl_strnicmp(s1, s2, n); +} + +void _strnicmp(void) +{ + // UNUSED FUNCTION +} + +void strupr(void) +{ + // UNUSED FUNCTION +} + +void _strupr(void) +{ + // UNUSED FUNCTION +} + +void strdate(void) +{ + // UNUSED FUNCTION +} + +void _strdate(void) +{ + // UNUSED FUNCTION +} + +void strset(void) +{ + // UNUSED FUNCTION +} + +void _strset(void) +{ + // UNUSED FUNCTION +} + +void strnset(void) +{ + // UNUSED FUNCTION +} + +void _strnset(void) +{ + // UNUSED FUNCTION +} + +void strspnp(void) +{ + // UNUSED FUNCTION +} + +void _strspnp(void) +{ + // UNUSED FUNCTION +} + +void strncasecmp(void) +{ + // UNUSED FUNCTION +} + +void _strncasecmp(void) +{ + // UNUSED FUNCTION +} + +void strcmpi(void) +{ + // UNUSED FUNCTION +} + +void _strcmpi(void) +{ + // UNUSED FUNCTION +} + +void strncmpi(void) +{ + // UNUSED FUNCTION +} + +void _strncmpi(void) +{ + // UNUSED FUNCTION +} + +void strcasecmp(void) +{ + // UNUSED FUNCTION +} + +void _strcasecmp(void) +{ + // UNUSED FUNCTION +} + +void _stricoll(void) +{ + // UNUSED FUNCTION +} + +void _strncoll(void) +{ + // UNUSED FUNCTION +} + +void _strnicoll(void) +{ + // UNUSED FUNCTION +} + +void stricoll(void) +{ + // UNUSED FUNCTION +} + +void strncoll(void) +{ + // UNUSED FUNCTION +} + +void strnicoll(void) +{ + // UNUSED FUNCTION +} + +void itoa(void) +{ + // UNUSED FUNCTION +} + +void _itoa(void) +{ + // UNUSED FUNCTION +} + +void strrev(void) +{ + // UNUSED FUNCTION +} + +void _strrev(void) +{ + // UNUSED FUNCTION +} + +void filelength(void) +{ + // UNUSED FUNCTION +} + +void _filelength(void) +{ + // UNUSED FUNCTION +} + +void chsize(void) +{ + // UNUSED FUNCTION +} + +void _chsize(void) +{ + // UNUSED FUNCTION +} + +void wtoi(void) +{ + // UNUSED FUNCTION +} + +void _wtoi(void) +{ + // UNUSED FUNCTION +} + +void wcslwr(void) +{ + // UNUSED FUNCTION +} + +void _wcslwr(void) +{ + // UNUSED FUNCTION +} + +void wcsupr(void) +{ + // UNUSED FUNCTION +} + +void _wcsupr(void) +{ + // UNUSED FUNCTION +} + +void wcsicmp(void) +{ + // UNUSED FUNCTION +} + +void _wcsicmp(void) +{ + // UNUSED FUNCTION +} + +void wcsnicmp(void) +{ + // UNUSED FUNCTION +} + +void _wcsnicmp(void) +{ + // UNUSED FUNCTION +} + +void wcsrev(void) +{ + // UNUSED FUNCTION +} + +void _wcsrev(void) +{ + // UNUSED FUNCTION +} + +void wcsset(void) +{ + // UNUSED FUNCTION +} + +void _wcsset(void) +{ + // UNUSED FUNCTION +} + +void wcsnset(void) +{ + // UNUSED FUNCTION +} + +void _wcsnset(void) +{ + // UNUSED FUNCTION +} + +void wcsspnp(void) +{ + // UNUSED FUNCTION +} + +void _wcsspnp(void) +{ + // UNUSED FUNCTION +} + +void wcsdup(void) +{ + // UNUSED FUNCTION +} + +void _wcsdup(void) +{ + // UNUSED FUNCTION +} + +void wstrrev(void) +{ + // UNUSED FUNCTION +} + +void _wstrrev(void) +{ + // UNUSED FUNCTION +} + +void _wcsicoll(void) +{ + // UNUSED FUNCTION +} + +void _wcsncoll(void) +{ + // UNUSED FUNCTION +} + +void _wcsnicoll(void) +{ + // UNUSED FUNCTION +} + +void wcsicoll(void) +{ + // UNUSED FUNCTION +} + +void wcsncoll(void) +{ + // UNUSED FUNCTION +} + +void wcsnicoll(void) +{ + // UNUSED FUNCTION +} + +void itow(void) +{ + // UNUSED FUNCTION +} + +void _itow(void) +{ + // UNUSED FUNCTION +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/file_io.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/file_io.c new file mode 100644 index 000000000..ae3b5d100 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/file_io.c @@ -0,0 +1,93 @@ +#include "types.h" +#include "string.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +int fclose(FILE* file) +{ + int flush_result, close_result; + + if (file == nullptr) + return (-1); + if (file->mMode.file_kind == __closed_file) + return (0); + + flush_result = fflush(file); + + close_result = (*file->closeFunc)(file->mHandle); + + file->mMode.file_kind = __closed_file; + file->mHandle = 0; + + if (file->mState.free_buffer) + free(file->mBuffer); + return ((flush_result || close_result) ? -1 : 0); +} + +int fflush(FILE* file) +{ + u32 pos; + + if (file == nullptr) { + return __flush_all(); + } + + if (file->mState.error != 0 || file->mMode.file_kind == __closed_file) { + return -1; + } + + if (file->mMode.io_mode == 1) { + return 0; + } + + if (file->mState.io_state >= 3) { + file->mState.io_state = 2; + } + + if (file->mState.io_state == 2) { + file->mBufferLength = 0; + } + + if (file->mState.io_state != 1) { + file->mState.io_state = 0; + return 0; + } + + if (file->mMode.file_kind != __disk_file || (pos = ftell(file)) < 0) + pos = 0; + + if (__flush_buffer(file, 0) != 0) { + file->mState.error = 1; + file->mBufferLength = 0; + return -1; + } + + file->mState.io_state = 0; + file->mPosition = pos; + file->mBufferLength = 0; + return 0; +} + +int __msl_strnicmp(const char *s1, const char *s2, int n) +{ + int i; + char c1, c2; + + for (i = 0; i < n; i++) { + c1 = tolower(*s1++); + c2 = tolower(*s2++); + + if(c1 < c2) { + return -1; + } + + if (c1 > c2) { + return 1; + } + + if(c1 == '\0') { + return 0; + } + } + return 0; + +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/float.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/float.c new file mode 100644 index 000000000..1aa55ea34 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/float.c @@ -0,0 +1,8 @@ +long __float_nan[] = { 0x7FFFFFFF }; +long __float_huge[] = { 0x7F800000 }; +long __double_max[] = { 0x7FEFFFFF, 0xFFFFFFFF }; +long __double_huge[] = { 0x7FF00000, 0 }; +long __extended_min[] = { 0x00100000, 0 }; +long __extended_max[] = { 0x7FEFFFFF, 0xFFFFFFFF }; +long __float_max[] = { 0x7F7FFFFF }; +long __float_epsilon[] = { 0x34000000 }; diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/locale.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/locale.c new file mode 100644 index 000000000..7b7961b9e --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/locale.c @@ -0,0 +1,33 @@ +#include "types.h" + +typedef struct { + char* _0; + char* _4; + char* _8; + char* _C; + char* _10; + char* _14; + char* _18; + char* _1C; + char* _20; + char _24; + char _25; + char _26; + char _27; + char _28; + char _29; + char _2A; + char* _2C; + char _30; + char _31; + char _32; + char _33; + char _34; + char _35; + char _36; +} lconv; + +lconv __lconv + = { ".", "", "", "", "", "", "", "", "", 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, "", 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F }; + +const char* dummy = "C"; diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mbstring.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mbstring.c new file mode 100644 index 000000000..ae40b6f31 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mbstring.c @@ -0,0 +1,260 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/mbstring.h" + +void mblen(void) +{ + // UNUSED FUNCTION +} + +static int is_utf8_complete(const char* s, size_t n) +{ + if (n == 0) { // must have more than zero characters + return -1; + } + + if (s[0] == 0x00) { // first char is 0 + return 0; + } + + if ((s[0] & 0x80) == 0x00) { + return (1); + } else if ((s[0] & 0xe0) == 0xc0) { + if (n >= 2) { + if ((*(s + 1) & 0x80) == 0x80) { + return 2; + } + return -1; + } + return -2; + } else if ((s[0] & 0xf0) == 0xe0) { + if (n >= 3) { + if ((s[1] & 0x80) == 0x80) { + if ((s[2] & 0x80) == 0x80) { + return 3; + } + } + return -1; + } else if ((n == 2 && ((s[1] & 0x80) == 0x80)) || n == 1) { + return -2; + } + return -1; + } else { + return (-1); + } +} + +static int utf8_to_unicode(wchar_t *pwc, const char *s, size_t n) +{ + int number_of_bytes; + int isUTF8; + char *source; + u16 result_chr = 0; + + if (!s) + { + return 0; + } + + if (n <= 0) + { + return -1; + } + + number_of_bytes = is_utf8_complete(s, n); + if (number_of_bytes < 0) + { + return -1; + } + + source = (char *)s; + switch (number_of_bytes) + { + case 3: + result_chr |= (*source++ & 0x0f); + result_chr <<= 6; + case 2: + result_chr |= (*source++ & 0x3f); + result_chr <<= 6; + case 1: + result_chr |= (*source++ & 0x7f); + } + + if (result_chr == 0) + { + isUTF8 = 0; + } + else if (result_chr < 0x00000080) + { + isUTF8 = 1; + } + else if (result_chr < 0x00000800) + { + isUTF8 = 2; + } + else + { + isUTF8 = 3; + } + + if (isUTF8 != number_of_bytes) + { + return -1; + } + if (pwc) + { + *pwc = result_chr; + } + + return number_of_bytes; +} + +int mbtowc(wchar_t *pwc, const char *s, size_t n) { return utf8_to_unicode(pwc, s, n); } + +inline static int unicode_to_UTF8(char* s, wchar_t wchar) +{ + int number_of_bytes; + wchar_t wide_char; + char* target_ptr; + char first_byte_mark[4] = { 0x00, 0x00, 0xc0, 0xe0 }; + + if (!s) + return (0); + + wide_char = wchar; + if (wide_char < 0x0080) + number_of_bytes = 1; + else if (wide_char < 0x0800) + number_of_bytes = 2; + else + number_of_bytes = 3; + + target_ptr = s + number_of_bytes; + + switch (number_of_bytes) { + case 3: + *--target_ptr = (wide_char & 0x003f) | 0x80; + wide_char >>= 6; + case 2: + *--target_ptr = (wide_char & 0x003f) | 0x80; + wide_char >>= 6; + case 1: + *--target_ptr = wide_char | first_byte_mark[number_of_bytes]; + } + + return number_of_bytes; +} + +inline int wctomb(char* s, wchar_t wchar) { return (unicode_to_UTF8(s, wchar)); } + +inline int mbstowcs(wchar_t* pwc, const char* s, size_t n) +{ + u32 result_chr; + int number_of_bytes = 0; + int isUTF8; + char* source; + + if (!s) { + number_of_bytes = 0; + return (number_of_bytes); + } + + if (n <= 0) { + number_of_bytes = -1; + return (number_of_bytes); + } + + isUTF8 = is_utf8_complete(s, n); + if (isUTF8 < 0) { + number_of_bytes = -1; + return number_of_bytes; + } + + source = (char*)s; + switch (isUTF8) { + case 3: + result_chr = (*source & 0x1f); + source++; + number_of_bytes = (result_chr << 6) & 0x3C0; + case 2: + result_chr = number_of_bytes | (*source & 0x3f); + source++; + number_of_bytes = (result_chr << 6) & 0xFFC0; + case 1: + result_chr = number_of_bytes | (*source & 0x7f); + source++; + number_of_bytes = result_chr & 0xFFFF; + } + + result_chr = number_of_bytes & 0xFFFF; + + if (!(result_chr)) { + result_chr = 0; + } else if (result_chr < 0x00000080) { + result_chr = 1; + } else if (result_chr < 0x00000800) { + result_chr = 2; + } else { + result_chr = 3; + } + + if ((int)result_chr != isUTF8) { + number_of_bytes = -1; + return (number_of_bytes); + } + if (pwc) { + *pwc = number_of_bytes; + } + return isUTF8; +} + +size_t wcstombs(char* s, const wchar_t* pwcs, size_t n) +{ + int chars_written = 0; + int result; + char temp[3]; + wchar_t* source; + + if (!s || !pwcs) + return (0); + + source = (wchar_t*)pwcs; + while (chars_written <= n) { + if (!*source) { + *(s + chars_written) = '\0'; + break; + } else { + result = wctomb(temp, *source++); + if ((chars_written + result) <= n) { + strncpy(s + chars_written, temp, result); + chars_written += result; + } else + break; + } + } + + return chars_written; +} + +void mbrlen(void) +{ + // UNUSED FUNCTION +} + +void mbrtowc(void) +{ + // UNUSED FUNCTION +} + +void wcrtomb(void) +{ + // UNUSED FUNCTION +} + +void mbsrtowcs(void) +{ + // UNUSED FUNCTION +} + +void wcsrtombs(void) +{ + // UNUSED FUNCTION +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem.c new file mode 100644 index 000000000..e5a397182 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem.c @@ -0,0 +1,105 @@ +#include "types.h" +#include "mem.h" + +void *memmove(void *dst, const void *src, size_t len) +{ + const char *csrc; + char *cdst; + + int reverse = (u32)src < (u32)dst; + + if (len >= 32) + { + if (((int)dst ^ (int)src) & 3) + { + if (!reverse) + { + __copy_longs_unaligned(dst, src, len); + } + else + { + __copy_longs_rev_unaligned(dst, src, len); + } + } + else + { + if (!reverse) + { + __copy_longs_aligned(dst, src, len); + } + else + { + __copy_longs_rev_aligned(dst, src, len); + } + } + + return dst; + } + else + { + if (!reverse) + { + for (csrc = (const char *)src - 1, cdst = (char *)dst - 1, len++; --len;) + { + *++cdst = *++csrc; + } + } + else + { + for (csrc = (const char *)src + len, cdst = (char *)dst + len, len++; --len;) + { + *--cdst = *--csrc; + } + } + } + + return dst; +} + +void *memchr(const void *src, int val, size_t n) +{ + const u8 *p; + u32 v = val & 0xFF; + + for (p = (u8 *)src - 1, n++; --n;) + { + if ((*++p & 0xFF) == v) + { + return (void *)p; + } + } + + return NULL; +} + +void *__memrchr(const void *src, int val, size_t n) +{ + const u8 *p; + u32 v = val & 0xFF; + + for (p = (u8 *)src + n, n++; --n;) + { + if (*--p == v) + { + return (void *)p; + } + } + + return NULL; +} + +int memcmp(const void *src1, const void *src2, size_t n) +{ + const u8 *p1; + const u8 *p2; + + for (p1 = (const u8 *)src1 - 1, p2 = (const u8 *)src2 - 1, n++; --n;) + { + if (*++p1 != *++p2) + { + return (*p1 < *p2) ? -1 : 1; + } + } + + return 0; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem_funcs.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem_funcs.c new file mode 100644 index 000000000..bfa043e1e --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem_funcs.c @@ -0,0 +1,217 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/mem_funcs.h" + +#define srcCharPtr ((unsigned char*)pSrc) +#define destCharPtr ((unsigned char*)pDest) +#define srcLongPtr ((unsigned long*)pSrc) +#define destLongPtr ((unsigned long*)pDest) + +void __copy_mem(void) +{ + // UNUSED FUNCTION +} + +void __move_mem(void) +{ + // UNUSED FUNCTION +} + +void __copy_longs_aligned(void* pDest, const void* pSrc, unsigned long len) +{ + unsigned long i = (-(unsigned long)pDest) & 3; + srcCharPtr = ((unsigned char*)pSrc) - 1; + destCharPtr = ((unsigned char*)pDest) - 1; + + if (i != 0) { + len -= i; + + do { + *++(destCharPtr) = *++(srcCharPtr); + } while (--i); + } + + srcLongPtr = ((unsigned long*)(srcCharPtr + 1)) - 1; + destLongPtr = ((unsigned long*)(destCharPtr + 1)) - 1; + + i = len >> 5; + + if (i != 0) { + do { + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + } while (--i); + } + + i = (len & 31) >> 2; + + if (i != 0) { + do { + *++(destLongPtr) = *++(srcLongPtr); + } while (--i); + } + + srcCharPtr = ((unsigned char*)(srcLongPtr + 1)) - 1; + destCharPtr = ((unsigned char*)(destLongPtr + 1)) - 1; + + len &= 3; + + if (len != 0) { + do + *++(destCharPtr) = *++(srcCharPtr); + while (--len); + } +} + +void __copy_longs_rev_aligned(void* pDest, const void* pSrc, unsigned long len) +{ + unsigned long i; + srcCharPtr = ((unsigned char*)pSrc) + len; + destCharPtr = ((unsigned char*)pDest) + len; + i = ((unsigned long)destCharPtr) & 3; + + if (i != 0) { + len -= i; + + do { + *--destCharPtr = *--srcCharPtr; + } while (--i); + } + + i = len >> 5; + + if (i != 0) { + do { + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + } while (--i); + } + + i = (len & 31) >> 2; + + if (i != 0) { + do { + *--destLongPtr = *--srcLongPtr; + } while (--i); + } + + len &= 3; + + if (len != 0) { + do { + *--destCharPtr = *--srcCharPtr; + } while (--len); + } +} + +void __copy_longs_unaligned(void* pDest, const void* pSrc, unsigned long len) +{ + unsigned long i, v1, v2; + unsigned int src, ls, rs; + + i = (-(unsigned long)pDest) & 3; + srcCharPtr = ((unsigned char*)pSrc) - 1; + destCharPtr = ((unsigned char*)pDest) - 1; + + if (i != 0) { + len -= i; + + do { + *++destCharPtr = *++srcCharPtr; + } while (--i); + } + + src = ((unsigned int)(srcCharPtr + 1)) & 3; + ls = src << 3; + rs = 32 - ls; + + srcCharPtr -= src; + + srcLongPtr = ((unsigned long*)(srcCharPtr + 1)) - 1; + destLongPtr = ((unsigned long*)(destCharPtr + 1)) - 1; + + i = len >> 3; + v1 = *++srcLongPtr; + + do { + v2 = *++srcLongPtr; + *++destLongPtr = (v1 << ls) | (v2 >> rs); + v1 = *++srcLongPtr; + *++destLongPtr = (v2 << ls) | (v1 >> rs); + } while (--i); + + if (len & 4) { + v2 = *++srcLongPtr; + *++destLongPtr = (v1 << ls) | (v2 >> rs); + } + + srcCharPtr = ((unsigned char*)(srcLongPtr + 1)) - 1; + destCharPtr = ((unsigned char*)(destLongPtr + 1)) - 1; + + len &= 3; + + if (len != 0) { + srcCharPtr -= 4 - src; + do { + *++destCharPtr = *++srcCharPtr; + } while (--len); + } +} + +void __copy_longs_rev_unaligned(void* pDest, const void* pSrc, unsigned long len) +{ + unsigned long i, v1, v2; + unsigned int src, ls, rs; + + srcCharPtr = ((unsigned char*)pSrc) + len; + destCharPtr = ((unsigned char*)pDest) + len; + i = ((unsigned long)pDest) & 3; + + if (i != 0) { + len -= i; + + do { + *--destCharPtr = *--srcCharPtr; + } while (--i); + } + + src = ((unsigned int)(srcCharPtr)) & 3; + ls = src << 3; + rs = 32 - ls; + + srcCharPtr += 4 - src; + + i = len >> 3; + v1 = *--srcLongPtr; + + do { + v2 = *--srcLongPtr; + *--destLongPtr = (v2 << ls) | (v1 >> rs); + v1 = *--srcLongPtr; + *--destLongPtr = (v1 << ls) | (v2 >> rs); + } while (--i); + + if (len & 4) { + v2 = *--srcLongPtr; + *--destLongPtr = (v2 << ls) | (v1 >> rs); + } + + len &= 3; + + if (len != 0) { + srcCharPtr += src; + do { + *--destCharPtr = *--srcCharPtr; + } while (--len); + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/misc_io.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/misc_io.c new file mode 100644 index 000000000..dc4b05c1e --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/misc_io.c @@ -0,0 +1,25 @@ +extern void (*__stdio_exit)(void); + +extern void __close_all(void); + +void clearerr(void) +{ + // UNUSED FUNCTION +} + +void feof(void) +{ + // UNUSED FUNCTION +} + +void ferror(void) +{ + // UNUSED FUNCTION +} + +void perror(void) +{ + // UNUSED FUNCTION +} + +void __stdio_atexit(void) { __stdio_exit = __close_all; } diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/printf.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/printf.c new file mode 100644 index 000000000..039757e64 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/printf.c @@ -0,0 +1,1250 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_fp.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/secure_error.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" +#include "ctype.h" +#include "math.h" +#include "mem.h" +#include "stdarg.h" +#include "string.h" +#include "stdio.h" +#include "stdlib.h" + +#define TARGET_FLOAT_BITS 64 +#define TARGET_FLOAT_BYTES (TARGET_FLOAT_BITS / 8) +#define TARGET_FLOAT_MAX_EXP LDBL_MAX_EXP +#define TARGET_FLOAT_MANT_DIG LDBL_MANT_DIG +#define TARGET_FLOAT_IMPLICIT_J_BIT 1 +#define TARGET_FLOAT_MANT_BITS (TARGET_FLOAT_MANT_DIG - TARGET_FLOAT_IMPLICIT_J_BIT) +#define TARGET_FLOAT_EXP_BITS (TARGET_FLOAT_BITS - TARGET_FLOAT_MANT_BITS - 1) + +typedef long long intmax_t; + +#define PTRDIFF __typeof__((char*)0 - (char*)0) +typedef PTRDIFF ptrdiff_t; + +enum justification_options { left_justification, right_justification, zero_fill }; + +enum sign_options { only_minus, sign_always, space_holder }; + +enum argument_options { + normal_argument, + char_argument, + short_argument, + long_argument, + long_long_argument, + long_double_argument, + wchar_argument +}; + +typedef struct { + unsigned char justification_options; // _0 + unsigned char sign_options; // _1 + unsigned char precision_specified; // _2 + unsigned char alternate_form; // _3 + unsigned char argument_options; // _4 + unsigned char conversion_char; // _5 + int field_width; // _8 + int precision; // _C +} print_format; + +static const char* parse_format(const char* format_string, va_list* arg, print_format* format) +{ + print_format f; + const char* s = format_string; + int c; + int flag_found; + f.justification_options = right_justification; + f.sign_options = only_minus; + f.precision_specified = 0; + f.alternate_form = 0; + f.argument_options = normal_argument; + f.field_width = 0; + f.precision = 0; + + if ((c = *++s) == '%') { + f.conversion_char = c; + *format = f; + return ((const char*)s + 1); + } + + for (;;) { + flag_found = 1; + + switch (c) { + case '-': + f.justification_options = left_justification; + break; + case '+': + f.sign_options = sign_always; + break; + case ' ': + if (f.sign_options != sign_always) { + f.sign_options = space_holder; + } + break; + case '#': + f.alternate_form = 1; + break; + case '0': + if (f.justification_options != left_justification) { + f.justification_options = zero_fill; + } + break; + default: + flag_found = 0; + break; + } + + if (flag_found) { + c = *++s; + } else { + break; + } + } + + if (c == '*') { + if ((f.field_width = va_arg(*arg, int)) < 0) { + f.justification_options = left_justification; + f.field_width = -f.field_width; + } + + c = *++s; + } else { + while (isdigit(c)) { + f.field_width = (f.field_width * 10) + (c - '0'); + c = *++s; + } + } + + if (f.field_width > 509) { + f.conversion_char = 0xFF; + *format = f; + return ((const char*)s + 1); + } + + if (c == '.') { + f.precision_specified = 1; + + if ((c = *++s) == '*') { + if ((f.precision = va_arg(*arg, int)) < 0) { + f.precision_specified = 0; + } + + c = *++s; + } else { + while (isdigit(c)) { + f.precision = (f.precision * 10) + (c - '0'); + c = *++s; + } + } + } + + flag_found = 1; + + switch (c) { + case 'h': + f.argument_options = short_argument; + + if (s[1] == 'h') { + f.argument_options = char_argument; + c = *++s; + } + + break; + + case 'l': + f.argument_options = long_argument; + + if (s[1] == 'l') { + f.argument_options = long_long_argument; + c = *++s; + } + + break; + + case 'L': + f.argument_options = long_double_argument; + break; + default: + flag_found = 0; + break; + } + + if (flag_found) { + c = *++s; + } + + f.conversion_char = c; + + switch (c) { + case 'd': + case 'i': + case 'u': + case 'o': + case 'x': + case 'X': + if (f.argument_options == long_double_argument) { + f.conversion_char = 0xFF; + break; + } + + if (!f.precision_specified) { + f.precision = 1; + } else if (f.justification_options == zero_fill) { + f.justification_options = right_justification; + } + break; + + case 'f': + case 'F': + if (f.argument_options == short_argument || f.argument_options == long_long_argument) { + f.conversion_char = 0xFF; + break; + } + + if (!f.precision_specified) { + f.precision = 6; + } + break; + + case 'a': + case 'A': + if (!f.precision_specified) { + f.precision = 0xD; + } + + if (f.argument_options == short_argument || f.argument_options == long_long_argument || f.argument_options == char_argument) { + f.conversion_char = 0xFF; + } + + break; + + case 'g': + case 'G': + if (!f.precision) { + f.precision = 1; + } + + case 'e': + case 'E': + if (f.argument_options == short_argument || f.argument_options == long_long_argument || f.argument_options == char_argument) { + f.conversion_char = 0xFF; + break; + } + + if (!f.precision_specified) { + f.precision = 6; + } + break; + + case 'p': + f.conversion_char = 'x'; + f.alternate_form = 1; + f.argument_options = long_argument; + f.precision = 8; + break; + + case 'c': + if (f.argument_options == long_argument) { + f.argument_options = wchar_argument; + } else { + if (f.precision_specified || f.argument_options != normal_argument) { + f.conversion_char = 0xFF; + } + } + + break; + + case 's': + if (f.argument_options == long_argument) { + f.argument_options = wchar_argument; + } else { + if (f.argument_options != normal_argument) { + f.conversion_char = 0xFF; + } + } + + break; + + case 'n': + if (f.argument_options == long_double_argument) { + f.conversion_char = 0xFF; + } + + break; + + default: + f.conversion_char = 0xFF; + break; + } + + *format = f; + return ((const char*)s + 1); +} + +static char* long2str(long num, char* buff, print_format format) +{ + unsigned long unsigned_num, base; + char* p; + int n, digits; + int minus = 0; + unsigned_num = num; + minus = 0; + + p = buff; + *--p = 0; + digits = 0; + + if (!num && !format.precision && !(format.alternate_form && format.conversion_char == 'o')) { + return p; + } + + switch (format.conversion_char) { + case 'd': + case 'i': + base = 10; + + if (num < 0) { + unsigned_num = -unsigned_num; + minus = 1; + } + break; + + case 'o': + base = 8; + format.sign_options = only_minus; + break; + + case 'u': + base = 10; + format.sign_options = only_minus; + break; + + case 'x': + case 'X': + base = 16; + format.sign_options = only_minus; + break; + } + + do { + n = unsigned_num % base; + unsigned_num /= base; + + if (n < 10) { + n += '0'; + } else { + n -= 10; + + if (format.conversion_char == 'x') { + n += 'a'; + } else { + n += 'A'; + } + } + + *--p = n; + ++digits; + } while (unsigned_num != 0); + + if (base == 8 && format.alternate_form && *p != '0') { + *--p = '0'; + ++digits; + } + + if (format.justification_options == zero_fill) { + format.precision = format.field_width; + + if (minus || format.sign_options != only_minus) + --format.precision; + + if (base == 16 && format.alternate_form) + format.precision -= 2; + } + + if (buff - p + format.precision > 509) + return (0); + + while (digits < format.precision) { + *--p = '0'; + ++digits; + } + + if (base == 16 && format.alternate_form) { + *--p = format.conversion_char; + *--p = '0'; + } + + if (minus) { + *--p = '-'; + } else if (format.sign_options == sign_always) { + *--p = '+'; + } else if (format.sign_options == space_holder) { + *--p = ' '; + } + + return p; +} + +static char* longlong2str(long long num, char* pBuf, print_format fmt) +{ + unsigned long long unsigned_num, base; + char* p; + int n, digits; + int minus = 0; + unsigned_num = num; + minus = 0; + p = pBuf; + *--p = 0; + digits = 0; + + if (!num && !fmt.precision && !(fmt.alternate_form && fmt.conversion_char == 'o')) { + return p; + } + + switch (fmt.conversion_char) { + case 'd': + case 'i': + base = 10; + + if (num < 0) { + unsigned_num = -unsigned_num; + minus = 1; + } + break; + case 'o': + base = 8; + fmt.sign_options = only_minus; + break; + case 'u': + base = 10; + fmt.sign_options = only_minus; + break; + case 'x': + case 'X': + base = 16; + fmt.sign_options = only_minus; + break; + } + + do { + n = unsigned_num % base; + unsigned_num /= base; + + if (n < 10) { + n += '0'; + } else { + n -= 10; + if (fmt.conversion_char == 'x') { + n += 'a'; + } else { + n += 'A'; + } + } + + *--p = n; + ++digits; + } while (unsigned_num != 0); + + if (base == 8 && fmt.alternate_form && *p != '0') { + *--p = '0'; + ++digits; + } + + if (fmt.justification_options == zero_fill) { + fmt.precision = fmt.field_width; + + if (minus || fmt.sign_options != only_minus) { + --fmt.precision; + } + + if (base == 16 && fmt.alternate_form) { + fmt.precision -= 2; + } + } + + if (pBuf - p + fmt.precision > 509) { + return 0; + } + + while (digits < fmt.precision) { + *--p = '0'; + ++digits; + } + + if (base == 16 && fmt.alternate_form) { + *--p = fmt.conversion_char; + *--p = '0'; + } + + if (minus) { + *--p = '-'; + } else if (fmt.sign_options == sign_always) { + *--p = '+'; + } else if (fmt.sign_options == space_holder) { + *--p = ' '; + } + + return p; +} + +static char* double2hex(long double num, char* buff, print_format format) +{ + char *p, *q; + char working_byte; + long double ld; + short* sptr; + short snum; + long exp; + print_format exp_format; + int hex_precision; + decform form; + decimal dec; + + p = buff; + ld = num; + sptr = (short*)&ld; + + if (format.precision > 509) { + return 0; + } + + form.style = (char)0; + form.digits = 0x20; + __num2dec(&form, num, &dec); + + if (*dec.sig.text == 'I') { + if (*sptr & 0x8000) { + p = buff - 5; + if (format.conversion_char == 'A') + strcpy(p, "-INF"); + else + strcpy(p, "-inf"); + } else { + p = buff - 4; + if (format.conversion_char == 'A') + strcpy(p, "INF"); + else + strcpy(p, "inf"); + } + + return p; + } else if (*dec.sig.text == 'N') { + if (*(char*)&num & 0x80) { + p = buff - 5; + if (format.conversion_char == 'A') + strcpy(p, "-NAN"); + else + strcpy(p, "-nan"); + } else { + p = buff - 4; + if (format.conversion_char == 'A') + strcpy(p, "NAN"); + else + strcpy(p, "nan"); + } + + return p; + } + + exp_format.justification_options = right_justification; + exp_format.sign_options = sign_always; + exp_format.precision_specified = 0; + exp_format.alternate_form = 0; + exp_format.argument_options = normal_argument; + exp_format.field_width = 0; + exp_format.precision = 1; + exp_format.conversion_char = 'd'; + + snum = (*sptr & 0x7ff0) >> 4; + + exp = snum - 0x3FF; + + p = long2str(exp, buff, exp_format); + if (format.conversion_char == 'a') + *--p = 'p'; + else + *--p = 'P'; + + q = (char*)# + + for (hex_precision = format.precision; hex_precision >= 1; --hex_precision) { + working_byte = *(q + (hex_precision / 2) + 1); + if (hex_precision % 2) + working_byte = working_byte & 0x0f; + else + working_byte = (working_byte >> 4) & 0x0f; + + if (working_byte < 10) { + working_byte += '0'; + } else { + working_byte -= 10; + + if (format.conversion_char == 'a') { + working_byte += 'a'; + } else { + working_byte += 'A'; + } + } + + *--p = working_byte; + } + + if (format.precision || format.alternate_form) { + *--p = '.'; + } + + *--p = '1'; + + if (format.conversion_char == 'a') { + *--p = 'x'; + } else { + *--p = 'X'; + } + + *--p = '0'; + + if (*sptr & 0x8000) { + *--p = '-'; + } else if (format.sign_options == sign_always) { + *--p = '+'; + } else if (format.sign_options == space_holder) { + *--p = ' '; + } + + return p; +} + +static void round_decimal(decimal* dec, int new_length) +{ + char c; + char* p; + int carry; + + if (new_length < 0) { + return_zero: + dec->exp = 0; + dec->sig.length = 1; + *dec->sig.text = '0'; + return; + } + + if (new_length >= dec->sig.length) { + return; + } + + p = (char*)dec->sig.text + new_length + 1; + c = *--p - '0'; + + if (c == 5) { + char* q = &((char*)dec->sig.text)[dec->sig.length]; + + while (--q > p && *q == '0') + ; + carry = (q == p) ? p[-1] & 1 : 1; + } else { + carry = (c > 5); + } + + while (new_length != 0) { + c = *--p - '0' + carry; + + if ((carry = (c > 9)) != 0 || c == 0) { + --new_length; + } else { + *p = c + '0'; + break; + } + } + + if (carry != 0) { + dec->exp += 1; + dec->sig.length = 1; + *dec->sig.text = '1'; + return; + } else if (new_length == 0) { + goto return_zero; + } + + dec->sig.length = new_length; +} + +static char* float2str(long double num, char* buff, print_format format) +{ + decimal dec; + decform form; + char* p; + char* q; + int n, digits, sign; + int int_digits, frac_digits; + + if (format.precision > 509) { + return 0; + } + + form.style = 0; + form.digits = 0x20; + __num2dec(&form, num, &dec); + p = (char*)dec.sig.text + dec.sig.length; + + while (dec.sig.length > 1 && *--p == '0') { + --dec.sig.length; + ++dec.exp; + } + + switch (*dec.sig.text) { + case '0': + dec.exp = 0; + break; + case 'I': + if (num < 0) { + p = buff - 5; + + if (isupper(format.conversion_char)) { + strcpy(p, "-INF"); + } else { + strcpy(p, "-inf"); + } + } else { + p = buff - 4; + if (isupper(format.conversion_char)) { + strcpy(p, "INF"); + } else { + strcpy(p, "inf"); + } + } + + return p; + + case 'N': + if (dec.sign) { + p = buff - 5; + + if (isupper(format.conversion_char)) { + strcpy(p, "-NAN"); + } else { + strcpy(p, "-nan"); + } + } else { + p = buff - 4; + if (isupper(format.conversion_char)) { + strcpy(p, "NAN"); + } else { + strcpy(p, "nan"); + } + } + + return p; + } + + dec.exp += dec.sig.length - 1; + p = buff; + *--p = 0; + + switch (format.conversion_char) { + case 'g': + case 'G': + + if (dec.sig.length > format.precision) { + round_decimal(&dec, format.precision); + } + + if (dec.exp < -4 || dec.exp >= format.precision) { + if (format.alternate_form) { + --format.precision; + } else { + format.precision = dec.sig.length - 1; + } + + if (format.conversion_char == 'g') { + format.conversion_char = 'e'; + } else { + format.conversion_char = 'E'; + } + + goto e_format; + } + + if (format.alternate_form) { + format.precision -= dec.exp + 1; + } else { + if ((format.precision = dec.sig.length - (dec.exp + 1)) < 0) { + format.precision = 0; + } + } + + goto f_format; + + case 'e': + case 'E': + e_format: + + if (dec.sig.length > format.precision + 1) { + round_decimal(&dec, format.precision + 1); + } + + n = dec.exp; + sign = '+'; + + if (n < 0) { + n = -n; + sign = '-'; + } + + for (digits = 0; n || digits < 2; ++digits) { + *--p = n % 10 + '0'; + n /= 10; + } + + *--p = sign; + *--p = format.conversion_char; + + if (buff - p + format.precision > 509) { + return 0; + } + + if (dec.sig.length < format.precision + 1) { + for (n = format.precision + 1 - dec.sig.length + 1; --n;) { + *--p = '0'; + } + } + + for (n = dec.sig.length, q = (char*)dec.sig.text + dec.sig.length; --n;) { + *--p = *--q; + } + + if (format.precision || format.alternate_form) { + *--p = '.'; + } + + *--p = *dec.sig.text; + + if (dec.sign) + *--p = '-'; + else if (format.sign_options == sign_always) + *--p = '+'; + else if (format.sign_options == space_holder) + *--p = ' '; + + break; + + case 'f': + case 'F': + f_format: + + if ((frac_digits = -dec.exp + dec.sig.length - 1) < 0) + frac_digits = 0; + + if (frac_digits > format.precision) { + round_decimal(&dec, dec.sig.length - (frac_digits - format.precision)); + + if ((frac_digits = -dec.exp + dec.sig.length - 1) < 0) + frac_digits = 0; + } + + if ((int_digits = dec.exp + 1) < 0) + int_digits = 0; + + if (int_digits + frac_digits > 509) + return 0; + + q = (char*)dec.sig.text + dec.sig.length; + + for (digits = 0; digits < (format.precision - frac_digits); ++digits) + *--p = '0'; + + for (digits = 0; digits < frac_digits && digits < dec.sig.length; ++digits) + *--p = *--q; + + for (; digits < frac_digits; ++digits) + *--p = '0'; + + if (format.precision || format.alternate_form) + *--p = '.'; + + if (int_digits) { + for (digits = 0; digits < int_digits - dec.sig.length; ++digits) { + *--p = '0'; + } + + for (; digits < int_digits; ++digits) { + *--p = *--q; + } + } else { + *--p = '0'; + } + + if (dec.sign) { + *--p = '-'; + } else if (format.sign_options == sign_always) { + *--p = '+'; + } else if (format.sign_options == space_holder) { + *--p = ' '; + } + + break; + } + + return p; +} + +static int __pformatter(void* (*WriteProc)(void*, const char*, size_t), void* WriteProcArg, const char* format_str, va_list arg) +{ + int num_chars, chars_written, field_width; + const char* format_ptr; + const char* curr_format; + print_format format; + long long_num; + long long long_long_num; + long double long_double_num; + char buff[512]; + char* buff_ptr; + char* string_end; + char fill_char = ' '; + + format_ptr = format_str; + chars_written = 0; + + while (*format_ptr) { + if (!(curr_format = strchr(format_ptr, '%'))) { + num_chars = strlen(format_ptr); + chars_written += num_chars; + + if (num_chars && !(*WriteProc)(WriteProcArg, format_ptr, num_chars)) { + return -1; + } + + break; + } + + num_chars = curr_format - format_ptr; + chars_written += num_chars; + + if (num_chars && !(*WriteProc)(WriteProcArg, format_ptr, num_chars)) { + return -1; + } + + format_ptr = curr_format; + format_ptr = parse_format(format_ptr, (va_list*)arg, &format); + + switch (format.conversion_char) { + case 'd': + case 'i': + if (format.argument_options == long_argument) { + long_num = va_arg(arg, long); + } else if (format.argument_options == long_long_argument) { + long_long_num = va_arg(arg, long long); + } else { + long_num = va_arg(arg, int); + } + + if (format.argument_options == short_argument) { + long_num = (short)long_num; + } + + if (format.argument_options == char_argument) { + long_num = (signed char)long_num; + } + + if ((format.argument_options == long_long_argument)) { + if (!(buff_ptr = longlong2str(long_long_num, buff + 512, format))) { + goto conversion_error; + } + } else { + if (!(buff_ptr = long2str(long_num, buff + 512, format))) { + goto conversion_error; + } + } + + num_chars = buff + 512 - 1 - buff_ptr; + break; + + case 'o': + case 'u': + case 'x': + case 'X': + if (format.argument_options == long_argument) { + long_num = va_arg(arg, unsigned long); + } else if (format.argument_options == long_long_argument) { + long_long_num = va_arg(arg, long long); + } else { + long_num = va_arg(arg, unsigned int); + } + + if (format.argument_options == short_argument) { + long_num = (unsigned short)long_num; + } + + if (format.argument_options == char_argument) { + long_num = (unsigned char)long_num; + } + + if ((format.argument_options == long_long_argument)) { + if (!(buff_ptr = longlong2str(long_long_num, buff + 512, format))) { + goto conversion_error; + } + } else { + if (!(buff_ptr = long2str(long_num, buff + 512, format))) { + goto conversion_error; + } + } + + num_chars = buff + 512 - 1 - buff_ptr; + break; + + case 'f': + case 'F': + case 'e': + case 'E': + case 'g': + case 'G': + if (format.argument_options == long_double_argument) { + long_double_num = va_arg(arg, long double); + } else { + long_double_num = va_arg(arg, double); + } + + if (!(buff_ptr = float2str(long_double_num, buff + 512, format))) { + goto conversion_error; + } + + num_chars = buff + 512 - 1 - buff_ptr; + break; + + case 'a': + case 'A': + if (format.argument_options == long_double_argument) { + long_double_num = va_arg(arg, long double); + } else { + long_double_num = va_arg(arg, double); + } + + if (!(buff_ptr = double2hex(long_double_num, buff + 512, format))) { + goto conversion_error; + } + + num_chars = buff + 512 - 1 - buff_ptr; + break; + + case 's': + if (format.argument_options == wchar_argument) { + wchar_t* wcs_ptr = va_arg(arg, wchar_t*); + + if (wcs_ptr == NULL) { + wcs_ptr = L""; + } + + if ((num_chars = wcstombs(buff, wcs_ptr, sizeof(buff))) < 0) { + goto conversion_error; + } + + buff_ptr = &buff[0]; + } else { + buff_ptr = va_arg(arg, char*); + } + + if (buff_ptr == NULL) { + buff_ptr = ""; + } + + if (format.alternate_form) { + num_chars = (unsigned char)*buff_ptr++; + + if (format.precision_specified && num_chars > format.precision) { + num_chars = format.precision; + } + } else if (format.precision_specified) { + num_chars = format.precision; + + if ((string_end = (char*)memchr((unsigned char*)buff_ptr, 0, num_chars)) != 0) { + num_chars = string_end - buff_ptr; + } + } else { + num_chars = strlen(buff_ptr); + } + + break; + + case 'n': + buff_ptr = va_arg(arg, char*); + + switch (format.argument_options) { + case normal_argument: + *(int*)buff_ptr = chars_written; + break; + case short_argument: + *(short*)buff_ptr = chars_written; + break; + case long_argument: + *(long*)buff_ptr = chars_written; + break; + case long_long_argument: + *(long long*)buff_ptr = chars_written; + break; + } + + continue; + + case 'c': + buff_ptr = buff; + *buff_ptr = va_arg(arg, int); + num_chars = 1; + break; + + case '%': + buff_ptr = buff; + *buff_ptr = '%'; + num_chars = 1; + break; + + case 0xFF: + default: + conversion_error: + num_chars = strlen(curr_format); + chars_written += num_chars; + + if (num_chars && !(*WriteProc)(WriteProcArg, curr_format, num_chars)) { + return -1; + } + + return chars_written; + break; + } + + field_width = num_chars; + + if (format.justification_options != left_justification) { + fill_char = (format.justification_options == zero_fill) ? '0' : ' '; + + if (((*buff_ptr == '+') || (*buff_ptr == '-') || (*buff_ptr == ' ')) && (fill_char == '0')) { + if ((*WriteProc)(WriteProcArg, buff_ptr, 1) == 0) { + return -1; + } + + ++buff_ptr; + num_chars--; + } + + while (field_width < format.field_width) { + if ((*WriteProc)(WriteProcArg, &fill_char, 1) == 0) { + return -1; + } + + ++field_width; + } + } + + if (num_chars && !(*WriteProc)(WriteProcArg, buff_ptr, num_chars)) { + return -1; + } + + if (format.justification_options == left_justification) { + while (field_width < format.field_width) { + char blank = ' '; + + if ((*WriteProc)(WriteProcArg, &blank, 1) == 0) { + return -1; + } + + ++field_width; + } + } + + chars_written += field_width; + } + + return chars_written; +} + +static void* __FileWrite(void* pFile, const char* pBuffer, size_t char_num) +{ + return (fwrite(pBuffer, 1, char_num, (FILE*)pFile) == char_num ? pFile : 0); +} + +static void* __StringWrite(void* pCtrl, const char* pBuffer, size_t char_num) +{ + size_t chars; + __OutStrCtrl* ctrl = (__OutStrCtrl*)pCtrl; + void* res; + + chars = ((ctrl->CharsWritten + char_num) <= ctrl->MaxCharCount) ? char_num : ctrl->MaxCharCount - ctrl->CharsWritten; + res = memcpy(ctrl->CharStr + ctrl->CharsWritten, pBuffer, chars); + ctrl->CharsWritten += chars; + return (void*)1; +} + +void printf(const char* format, ...) +{ + // UNUSED FUNCTION +} + +int fprintf(FILE* file, const char* format, ...) +{ + int ret; + va_list args; + + if (fwide(file, -1) >= 0) { + return -1; + } + + __begin_critical_region(stdin_access); + + va_start(args, format); + ret = __pformatter(&__FileWrite, file, format, args); + va_end(args); + __end_critical_region(stdin_access); + return ret; +} + +int vprintf(const char* pFormat, va_list arg) +{ + int ret; + + if (fwide(stdout, -1) >= 0) { + return -1; + } + + __begin_critical_region(stdin_access); + ret = __pformatter(&__FileWrite, (void*)stdout, pFormat, arg); + __end_critical_region(stdin_access); + return ret; +} + +void vfprintf(void) +{ + // UNUSED FUNCTION +} + +int vsnprintf(char* s, size_t n, const char* format, va_list arg) +{ + int end; + __OutStrCtrl osc; + osc.CharStr = s; + osc.MaxCharCount = n; + osc.CharsWritten = 0; + + end = __pformatter(&__StringWrite, &osc, format, arg); + + if (s) { + s[(end < n) ? end : n - 1] = '\0'; + } + + return end; +} + +int vsprintf(char* s, const char* format, va_list arg) { return vsnprintf(s, 0xFFFFFFFF, format, arg); } + +int snprintf(char* s, size_t n, const char* format, ...) +{ + va_list args; + va_start(args, format); + return vsnprintf(s, n, format, args); +} + +int sprintf(char* s, const char* format, ...) +{ + va_list args; + va_start(args, format); + return vsnprintf(s, 0xFFFFFFFF, format, args); +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/rand.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/rand.c new file mode 100644 index 000000000..f6ed2b702 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/rand.c @@ -0,0 +1,14 @@ +#include "types.h" + +static u32 next = 1; + +int rand() +{ + next = next * 1103515245 + 12345; + return ((next >> 16) & 0x7fff); +} + +void srand(u32 seed) +{ + next = seed; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/scanf.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/scanf.c new file mode 100644 index 000000000..1393de9ed --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/scanf.c @@ -0,0 +1,670 @@ +#include "math.h" +#include "stdarg.h" +#include "ctype.h" +#include "stdio.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h" + +typedef long long intmax_t; + +#define PTRDIFF __typeof__((char*)0 - (char*)0) +typedef PTRDIFF ptrdiff_t; + +enum argument_options { + normal_argument, + char_argument, + short_argument, + long_argument, + long_long_argument, + double_argument, + long_double_argument, + wchar_argument +}; + +typedef unsigned char char_map[32]; + +typedef struct { + unsigned char suppress_assignment; + unsigned char field_width_specified; + unsigned char argument_options; + unsigned char conversion_char; + int field_width; + char_map char_set; +} scan_format; + +#define set_char_map(map, ch) map[(unsigned char)ch >> 3] |= (1 << (ch & 7)) +#define tst_char_map(map, ch) (map[(unsigned char)ch >> 3] & (1 << (ch & 7))) + +static const char* parse_format(const char* format_string, scan_format* format) +{ + const char* s = format_string; + int c; + int flag_found, invert; + scan_format f = { 0, 0, normal_argument, 0, 2147483647, { 0 } }; + + if (((c = *++s) == '%')) { + f.conversion_char = c; + *format = f; + return ((const char*)s + 1); + } + + if (c == '*') { + f.suppress_assignment = 1; + c = *++s; + } + + if (isdigit(c)) { + f.field_width = 0; + + do { + f.field_width = (f.field_width * 10) + (c - '0'); + c = *++s; + } while (isdigit(c)); + + if (f.field_width == 0) { + f.conversion_char = 0xFF; + *format = f; + return ((const char*)s + 1); + } + + f.field_width_specified = 1; + } + + flag_found = 1; + + switch (c) { + case 'h': + f.argument_options = short_argument; + + if (s[1] == 'h') { + f.argument_options = char_argument; + c = *++s; + } + + break; + case 'l': + f.argument_options = long_argument; + + if (s[1] == 'l') { + f.argument_options = long_long_argument; + c = *++s; + } + break; + case 'L': + f.argument_options = long_double_argument; + break; + default: + flag_found = 0; + } + + if (flag_found) { + c = *++s; + } + + f.conversion_char = c; + + switch (c) { + case 'd': + case 'i': + case 'u': + case 'o': + case 'x': + case 'X': + if (f.argument_options == long_double_argument) { + f.conversion_char = 0xFF; + break; + } + + break; + + case 'a': + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + if (f.argument_options == char_argument || f.argument_options == short_argument || f.argument_options == long_long_argument) { + f.conversion_char = 0xFF; + break; + } + + if (f.argument_options == long_argument) { + f.argument_options = double_argument; + } + + break; + + case 'p': + f.argument_options = long_argument; + f.conversion_char = 'x'; + break; + + case 'c': + if (f.argument_options == long_argument) { + f.argument_options = wchar_argument; + } else { + if (f.argument_options != normal_argument) { + f.conversion_char = 0xFF; + } + } + + break; + + case 's': + if (f.argument_options == long_argument) { + f.argument_options = wchar_argument; + } else { + if (f.argument_options != normal_argument) { + f.conversion_char = 0xFF; + } + } + + { + int i; + unsigned char* p; + + for (i = sizeof(f.char_set), p = f.char_set; i; --i) { + *p++ = 0xFF; + } + + f.char_set[1] = 0xC1; + f.char_set[4] = 0xFE; + } + + break; + + case 'n': + break; + + case '[': + if (f.argument_options == long_argument) { + f.argument_options = wchar_argument; + } else { + if (f.argument_options != normal_argument) { + f.conversion_char = 0xFF; + } + } + + c = *++s; + invert = 0; + + if (c == '^') { + invert = 1; + c = *++s; + } + + if (c == ']') { + set_char_map(f.char_set, ']'); + c = *++s; + } + + while (c && c != ']') { + int d; + set_char_map(f.char_set, c); + + if (*(s + 1) == '-' && (d = *(s + 2)) != 0 && d != ']') { + while (++c <= d) { + set_char_map(f.char_set, c); + } + + c = *(s += 3); + } else { + c = *++s; + } + } + + if (!c) { + f.conversion_char = 0xFF; + break; + } + + if (invert) { + int i; + unsigned char* p; + + for (i = sizeof(f.char_set), p = f.char_set; i; --i, ++p) { + *p = ~*p; + } + + break; + } + + break; + default: + f.conversion_char = 0xFF; + break; + } + + *format = f; + return ((const char*)s + 1); +} + +static int __sformatter(int (*ReadProc)(void*, int, int), void* ReadProcArg, const char* format_str, va_list arg) +{ + int num_chars, chars_read, items_assigned, conversions; + int base, negative, overflow; + const char* format_ptr; + char format_char; + char c; + scan_format format; + long long_num; + unsigned long u_long_num; + long long long_long_num; + unsigned long long u_long_long_num; + long double long_double_num; + char* arg_ptr; + int terminate = 0; + + format_ptr = format_str; + chars_read = 0; + items_assigned = 0; + conversions = 0; + + while (!terminate && (format_char = *format_ptr) != 0) { + if (isspace(format_char)) { + do { + format_char = *++format_ptr; + } while (isspace(format_char)); + + while (isspace(c = (*ReadProc)(ReadProcArg, 0, __GetAChar))) + ++chars_read; + + (*ReadProc)(ReadProcArg, c, __UngetAChar); + + continue; + } + + if (format_char != '%') { + if ((c = (*ReadProc)(ReadProcArg, 0, __GetAChar)) != (unsigned char)format_char) { + (*ReadProc)(ReadProcArg, c, __UngetAChar); + goto exit; + } + + chars_read++; + format_ptr++; + + continue; + } + + format_ptr = parse_format(format_ptr, &format); + + if (!format.suppress_assignment && format.conversion_char != '%') { + arg_ptr = va_arg(arg, char*); + } else { + arg_ptr = 0; + } + + if ((format.conversion_char != 'n') && (*ReadProc)(ReadProcArg, 0, __TestForError)) { + terminate = 1; + goto exit; + } + + switch (format.conversion_char) { + case 'd': + base = 10; + goto signed_int; + case 'i': + base = 0; + signed_int: + if ((format.argument_options == long_long_argument)) + u_long_long_num = __strtoull(base, format.field_width, ReadProc, ReadProcArg, &num_chars, &negative, &overflow); + else + u_long_num = __strtoul(base, format.field_width, ReadProc, ReadProcArg, &num_chars, &negative, &overflow); + + if (!num_chars) { + goto exit; + } + + chars_read += num_chars; + + if ((format.argument_options == long_long_argument)) + long_long_num = (negative ? -u_long_long_num : u_long_long_num); + else + long_num = (negative ? -u_long_num : u_long_num); + + signed_int_assign: + + if (arg_ptr) { + switch (format.argument_options) { + case normal_argument: + *(int*)arg_ptr = long_num; + break; + case char_argument: + *(signed char*)arg_ptr = long_num; + break; + case short_argument: + *(short*)arg_ptr = long_num; + break; + case long_argument: + *(long*)arg_ptr = long_num; + break; + case long_long_argument: + *(long long*)arg_ptr = long_long_num; + break; + } + + items_assigned++; + } + + conversions++; + break; + case 'o': + base = 8; + goto unsigned_int; + case 'u': + base = 10; + goto unsigned_int; + case 'x': + case 'X': + base = 16; + unsigned_int: + if ((format.argument_options == long_long_argument)) + u_long_long_num = __strtoull(base, format.field_width, ReadProc, ReadProcArg, &num_chars, &negative, &overflow); + else + u_long_num = __strtoul(base, format.field_width, ReadProc, ReadProcArg, &num_chars, &negative, &overflow); + + if (!num_chars) { + goto exit; + } + + chars_read += num_chars; + + if (negative) { + if (format.argument_options == long_long_argument) + u_long_long_num = -u_long_long_num; + else + u_long_num = -u_long_num; + } + + unsigned_int_assign: + + if (arg_ptr) { + switch (format.argument_options) { + case normal_argument: + *(unsigned int*)arg_ptr = u_long_num; + break; + case char_argument: + *(unsigned char*)arg_ptr = u_long_num; + break; + case short_argument: + *(unsigned short*)arg_ptr = u_long_num; + break; + case long_argument: + *(unsigned long*)arg_ptr = u_long_num; + break; + case long_long_argument: + *(unsigned long long*)arg_ptr = u_long_long_num; + break; + } + + items_assigned++; + } + + conversions++; + break; + case 'a': + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + flt: + long_double_num = __strtold(format.field_width, ReadProc, ReadProcArg, &num_chars, &overflow); + + if (!num_chars) { + goto exit; + } + + chars_read += num_chars; + + assign_float: + + if (arg_ptr) { + switch (format.argument_options) { + case normal_argument: + *(float*)arg_ptr = long_double_num; + break; + case double_argument: + *(double*)arg_ptr = long_double_num; + break; + case long_double_argument: + *(long double*)arg_ptr = long_double_num; + break; + } + + items_assigned++; + } + + conversions++; + break; + + case 'c': + + if (!format.field_width_specified) + format.field_width = 1; + + if (arg_ptr) { + int rval; + num_chars = 0; + + while (format.field_width-- && ((rval = ((*ReadProc)(ReadProcArg, 0, __GetAChar))) != -1)) { + c = rval; + + if (format.argument_options == wchar_argument) { + mbtowc(((wchar_t*)arg_ptr), (char*)(&c), 1); + (wchar_t*)arg_ptr++; + } else { + *arg_ptr++ = c; + } + num_chars++; + } + + if (!num_chars) { + goto exit; + } + + chars_read += num_chars; + + items_assigned++; + } else { + num_chars = 0; + + while (format.field_width-- && ((c = ((*ReadProc)(ReadProcArg, 0, __GetAChar))) != -1)) { + num_chars++; + } + if (!num_chars) + goto exit; + } + + conversions++; + break; + case '%': + while (isspace(c = (*ReadProc)(ReadProcArg, 0, __GetAChar))) + chars_read++; + + if (c != '%') { + (*ReadProc)(ReadProcArg, c, __UngetAChar); + goto exit; + } + + chars_read++; + break; + case 's': + c = (*ReadProc)(ReadProcArg, 0, __GetAChar); + while (isspace(c)) { + chars_read++; + c = (*ReadProc)(ReadProcArg, 0, __GetAChar); + } + + (*ReadProc)(ReadProcArg, c, __UngetAChar); + case '[': + if (arg_ptr) { + num_chars = 0; + + while (format.field_width-- && ((c = ((*ReadProc)(ReadProcArg, 0, __GetAChar))) != -1) + && tst_char_map(format.char_set, c)) { + if (format.argument_options == wchar_argument) { + mbtowc(((wchar_t*)arg_ptr), (char*)&c, 1); + arg_ptr = (char*)((wchar_t*)arg_ptr + 1); + } else { + *arg_ptr++ = c; + } + num_chars++; + } + + if (!num_chars) { + (*ReadProc)(ReadProcArg, c, __UngetAChar); + goto exit; + } + + chars_read += num_chars; + + if (format.argument_options == wchar_argument) + *(wchar_t*)arg_ptr = L'\0'; + else + *arg_ptr = 0; + + items_assigned++; + } else { + num_chars = 0; + + while (format.field_width-- && ((c = ((*ReadProc)(ReadProcArg, 0, __GetAChar))) != -1) + && tst_char_map(format.char_set, c)) { + + num_chars++; + } + + if (!num_chars) { + (*ReadProc)(ReadProcArg, c, __UngetAChar); + break; + } + chars_read += num_chars; + } + + if (format.field_width >= 0) + (*ReadProc)(ReadProcArg, c, __UngetAChar); + + conversions++; + break; + case 'n': + if (arg_ptr) + switch (format.argument_options) { + case normal_argument: + *(int*)arg_ptr = chars_read; + break; + case short_argument: + *(short*)arg_ptr = chars_read; + break; + case long_argument: + *(long*)arg_ptr = chars_read; + break; + case char_argument: + *(char*)arg_ptr = chars_read; + break; + case long_long_argument: + *(long long*)arg_ptr = chars_read; + break; + } + continue; + case 0xFF: + default: + goto exit; + } + } + +exit: + + if ((*ReadProc)(ReadProcArg, 0, __TestForError) && conversions == 0) + return -1; + + return items_assigned; +} + +void __FileRead(void) +{ + // UNUSED FUNCTION +} + +int __StringRead(void* pPtr, int ch, int act) +{ + char ret; + __InStrCtrl* Iscp = (__InStrCtrl*)pPtr; + + switch (act) { + case __GetAChar: + ret = *(Iscp->NextChar); + + if (ret == '\0') { + Iscp->NullCharDetected = 1; + return -1; + } else { + Iscp->NextChar++; + return (unsigned char)ret; + } + + case __UngetAChar: + if (Iscp->NullCharDetected == 0) { + Iscp->NextChar--; + } else { + Iscp->NullCharDetected = 0; + } + + return ch; + + case __TestForError: + return Iscp->NullCharDetected; + } + + return 0; +} + +void fscanf(void) +{ + // UNUSED FUNCTION +} + +void vscanf(void) +{ + // UNUSED FUNCTION +} + +void scanf(void) +{ + // UNUSED FUNCTION +} + +void vfscanf(void) +{ + // UNUSED FUNCTION +} + +inline int isspace_string(const char* s) +{ + int i = 0; + + while (s[i] != '\0') { + if (!isspace(s[i++])) + return 0; + } + + return 1; +} + +inline int vsscanf(const char* s, const char* format, va_list arg) +{ + __InStrCtrl isc; + isc.NextChar = (char*)s; + + if ((s == 0) || (*isc.NextChar == '\0')) { + return -1; + } + + isc.NullCharDetected = 0; + return __sformatter(&__StringRead, (void*)&isc, format, arg); +} + +int sscanf(const char* s, const char* pFormat, ...) +{ + va_list args; + va_start(args, pFormat); + return vsscanf(s, pFormat, args); +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/signal.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/signal.c new file mode 100644 index 000000000..22584b4f5 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/signal.c @@ -0,0 +1,39 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/signal.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_params.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/abort_exit.h" + +__signal_func_ptr signal_funcs[6]; + +int raise(int sig) +{ + __signal_func_ptr signal_func; + + if (sig < 1 || sig > 6) + { + return -1; + } + + __begin_critical_region(stderr_access); + signal_func = signal_funcs[sig - 1]; + + if (signal_func != ((__std(__signal_func_ptr))1)) + { + signal_funcs[sig - 1] = ((__std(__signal_func_ptr))0); + } + + __end_critical_region(stderr_access); + + if (signal_func == ((__std(__signal_func_ptr))1) || (signal_func == ((__std(__signal_func_ptr))0) && sig == 1)) + { + return 0; + } + + if (signal_func == ((__std(__signal_func_ptr))0)) + { + exit(0); + } + + (*signal_func)(sig); + return 0; +} \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/string.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/string.c new file mode 100644 index 000000000..d70c70bbc --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/string.c @@ -0,0 +1,306 @@ +#include "types.h" +//#define K1 0x80808080 +//#define K2 0xFEFEFEFF + +size_t(strlen)(const char* str) +{ + size_t len = -1; + u8* p = (u8*)str - 1; + + do + len++; + while (*++p); + return (len); +} + +char*(strcpy)(char* dst, const char* src) +{ + register u8 *destb, *fromb; + register u32 w, t, align; + + u32 K1, K2; + + fromb = (u8*)src; + destb = (u8*)dst; + + if ((align = ((int)fromb & 3)) != ((int)destb & 3)) { + goto bytecopy; + } + + if (align) { + if ((*destb = *fromb) == 0) + return (dst); + for (align = 3 - align; align; align--) { + if ((*(++destb) = *(++fromb)) == 0) + return (dst); + } + ++destb; + ++fromb; + } + + w = *((int*)(fromb)); + + K2 = 0xFEFEFEFF; + t = w + K2; + + K1 = 0x80808080; + + t &= K1; + if (t) + goto bytecopy; + --((int*)(destb)); + + do { + *(++((int*)(destb))) = w; + w = *(++((int*)(fromb))); + + t = w + K2; + t &= K1; + if (t) + goto adjust; + } while (1); + +adjust: + ++((int*)(destb)); +bytecopy: + if ((*destb = *fromb) == 0) + return dst; + do { + if ((*(++destb) = *(++fromb)) == 0) + return dst; + } while (1); + + return dst; +} + +char* strncpy(char* dst, const char* src, size_t n) +{ + const unsigned char* p = (const unsigned char*)src - 1; + unsigned char* q = (unsigned char*)dst - 1; + unsigned char zero = 0; + + n++; + + while (--n) + if (!(*++q = *++p)) { + while (--n) + *++q = 0; + break; + } + return (dst); +} + +char* strcat(char* dst, const char* src) +{ + const u8* p = (u8*)src - 1; + u8* q = (u8*)dst - 1; + + while (*++q) + ; + + q--; + + while (*++q = *++p) + ; + + return (dst); +} + +void strncat(void) +{ + // UNUSED FUNCTION +} + +int strcmp(const char* str1, const char* str2) +{ + // bless metrowerks for this implementation + + register u8* left = (u8*)str1; + register u8* right = (u8*)str2; + u32 align, l1, r1, x; + + u32 K1, K2; + + l1 = *left; + r1 = *right; + if (l1 - r1) { + return (l1 - r1); + } + + if ((align = ((int)left & 3)) != ((int)right & 3)) { + goto bytecopy; + } + if (align) { + if (l1 == 0) { + return 0; + } + for (align = 3 - align; align; align--) { + l1 = *(++left); + r1 = *(++right); + if (l1 - r1) { + return (l1 - r1); + } + if (l1 == 0) { + return 0; + } + } + left++; + right++; + } + + l1 = *(int*)left; + r1 = *(int*)right; + + K1 = 0x80808080; + K2 = 0xFEFEFEFF; + + x = l1 + K2; + if (x & K1) { + goto adjust; + } + while (l1 == r1) { + l1 = *(++((int*)(left))); + r1 = *(++((int*)(right))); + x = l1 + K2; + if (x & K1) { + goto adjust; + } + } + if (l1 > r1) + return 1; + return -1; + +adjust: + l1 = *left; + r1 = *right; + if (l1 - r1) { + return (l1 - r1); + } +bytecopy: + if (l1 == 0) { + return 0; + } + do { + l1 = *(++left); + r1 = *(++right); + if (l1 - r1) { + return (l1 - r1); + } + if (l1 == 0) { + return 0; + } + } while (1); +} + +int strncmp(const char* str1, const char* str2, size_t n) +{ + const u8* p1 = (u8*)str1 - 1; + const u8* p2 = (u8*)str2 - 1; + u32 c1, c2; + + n++; + + while (--n) + if ((c1 = *++p1) != (c2 = *++p2)) + return (c1 - c2); + else if (!c1) + break; + return 0; +} + +char* strchr(const char* str, int chr) +{ + const u8* p = (u8*)str - 1; + u32 c = (chr & 0xFF); + u32 ch; + + while (ch = *++p) + if (ch == c) + return ((char*)p); + + return (c ? 0 : (char*)p); +} + +void strcoll(void) +{ + // UNUSED FUNCTION +} + +void strxfrm(void) +{ + // UNUSED FUNCTION +} + +char* strrchr(const char* str, int chr) +{ + const u8* p = (u8*)str - 1; + const u8* q = 0; + u32 c = (chr & 0xFF); + u32 ch; + + while (ch = *++p) + if (ch == c) + q = p; + + if (q) + return ((char*)q); + + return (c ? 0 : (char*)p); +} + +void strpbrk(void) +{ + // UNUSED FUNCTION +} + +void strspn(void) +{ + // UNUSED FUNCTION +} + +void strcspn(void) +{ + // UNUSED FUNCTION +} + +void strtok(void) +{ + // UNUSED FUNCTION +} + +char* strstr(const char *str, const char *pat) { + unsigned char* s1 = (unsigned char*)str - 1; + unsigned char* p1 = (unsigned char*)pat - 1; + unsigned long firstc, c1, c2; + + if ((pat == 0) || (!(firstc = *++p1))) { + return ((char*)str); + } + + while (c1 = *++s1) { + if (c1 == firstc) { + const unsigned char* s2 = s1 - 1; + const unsigned char* p2 = p1 - 1; + + while ((c1 = *++s2) == (c2 = *++p2) && c1) { + + } + + if (!c2) { + return ((char*)s1); + } + } + } + + return NULL; +} + +void strerror(void) +{ + // UNUSED FUNCTION +} + +void __strerror(void) +{ + // UNUSED FUNCTION +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtold.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtold.c new file mode 100644 index 000000000..20072c860 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtold.c @@ -0,0 +1,703 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/strtold.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_fp.h" +#include "PowerPC_EABI_Support/MSL_C/PPC_EABI/math_ppc.h" +#include "errno.h" +#include "locale.h" +#include "ctype.h" +#include "math.h" +#include "mem.h" +#include "limits.h" + +#define TARGET_FLOAT_BITS 64 +#define TARGET_FLOAT_BYTES (TARGET_FLOAT_BITS / 8) +#define TARGET_FLOAT_MAX_EXP LDBL_MAX_EXP +#define TARGET_FLOAT_MANT_DIG LDBL_MANT_DIG +#define TARGET_FLOAT_IMPLICIT_J_BIT 1 +#define TARGET_FLOAT_MANT_BITS (TARGET_FLOAT_MANT_DIG - TARGET_FLOAT_IMPLICIT_J_BIT) +#define TARGET_FLOAT_EXP_BITS (TARGET_FLOAT_BITS - TARGET_FLOAT_MANT_BITS - 1) + +enum scan_states +{ + start = 0x0001, + sig_start = 0x0002, + leading_sig_zeroes = 0x0004, + int_digit_loop = 0x0008, + frac_start = 0x0010, + frac_digit_loop = 0x0020, + sig_end = 0x0040, + exp_start = 0x0080, + leading_exp_digit = 0x0100, + leading_exp_zeroes = 0x0200, + exp_digit_loop = 0x0400, + finished = 0x0800, + failure = 0x1000, + nan_state = 0x2000, + infin_state = 0x4000, + hex_state = 0x8000 +}; + +enum hex_scan_states +{ + not_hex = 0x0000, + hex_start = 0x0001, + hex_leading_sig_zeroes = 0x0002, + hex_int_digit_loop = 0x0004, + hex_frac_digit_loop = 0x0008, + hex_sig_end = 0x0010, + hex_exp_start = 0x0020, + hex_leading_exp_digit = 0x0040, + hex_leading_exp_zeroes = 0x0080, + hex_exp_digit_loop = 0x0100 +}; + +#define final_state(scan_state) (scan_state & (finished | failure)) +#define success(scan_state) \ + (scan_state & (leading_sig_zeroes | int_digit_loop | frac_digit_loop | leading_exp_zeroes | \ + exp_digit_loop | finished)) +#define hex_success(count, scan_state) \ + (count - 1 > 2 && \ + scan_state & (hex_leading_sig_zeroes | hex_int_digit_loop | hex_frac_digit_loop | \ + hex_leading_exp_zeroes | hex_exp_digit_loop)) + +#define fetch() (count++, (*ReadProc)(ReadProcArg, 0, __GetAChar)) +#define unfetch(c) (*ReadProc)(ReadProcArg, c, __UngetAChar) + +long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, + int* chars_scanned, int* overflow) +{ + int scan_state = start; + int hex_scan_state = not_hex; + int count = 0; + int spaces = 0; + int c; + decimal d = { 0, 0, 0, { 0, "" } }; + int sig_negative = 0; + int exp_negative = 0; + long exp_value = 0; + int exp_adjust = 0; + long double result; + int sign_detected = 0; + + unsigned char* chptr = (unsigned char*)&result; + unsigned char uch, uch1; + int ui; + int chindex; + int NibbleIndex; + int expsign = 0; + int exp_digits = 0; + int intdigits = 0; + int RadixPointFound = 0; + short exponent = 0; + int dot; + + dot = *(unsigned char*)(__lconv).decimal_point; + + *overflow = 0; + c = fetch(); + + while (count <= max_width && c != -1 && !final_state(scan_state)) + { + switch (scan_state) + { + case start: + if (isspace(c)) + { + c = fetch(); + count--; + spaces++; + break; + } + + switch (toupper(c)) + { + case '-': + sig_negative = 1; + + case '+': + c = fetch(); + sign_detected = 1; + break; + case 'I': + c = fetch(); + scan_state = infin_state; + break; + + case 'N': + c = fetch(); + scan_state = nan_state; + break; + + default: + scan_state = sig_start; + break; + } + break; + + case infin_state: + { + int i = 1; + char model[] = "INFINITY"; + + while ((i < 8) && (toupper(c) == model[i])) + { + i++; + c = fetch(); + } + + if ((i == 3) || (i == 8)) + { + if (sig_negative) + { + result = -INFINITY; + } + else + { + result = INFINITY; + } + + *chars_scanned = spaces + i + sign_detected; + return result; + } + else + { + scan_state = failure; + } + + break; + } + + case nan_state: + { + int i = 1, j = 0; + char model[] = "NAN("; + char nan_arg[32] = ""; + while ((i < 4) && (toupper(c) == model[i])) + { + i++; + c = fetch(); + } + + if ((i == 3) || (i == 4)) + { + if (i == 4) + { + while ((j < 32) && (isdigit(c) || isalpha(c))) + { + nan_arg[j++] = c; + c = fetch(); + } + + if (c != ')') + { + scan_state = failure; + break; + } + else + { + j++; + } + } + nan_arg[j] = '\0'; + + if (sig_negative) + { + result = -NAN; + } + else + { + result = NAN; + } + + *chars_scanned = spaces + i + j + sign_detected; + return result; + } + else + { + scan_state = failure; + } + break; + } + + case sig_start: + if (c == dot) + { + scan_state = frac_start; + c = fetch(); + break; + } + if (!isdigit(c)) + { + scan_state = failure; + break; + } + + if (c == '0') + { + c = fetch(); + if (toupper(c) == 'X') + { + scan_state = hex_state; + hex_scan_state = hex_start; + } + else + { + scan_state = leading_sig_zeroes; + } + break; + } + + scan_state = int_digit_loop; + break; + + case leading_sig_zeroes: + if (c == '0') + { + c = fetch(); + + break; + } + scan_state = int_digit_loop; + break; + + case int_digit_loop: + if (!isdigit(c)) + { + if (c == dot) + { + scan_state = frac_digit_loop; + c = fetch(); + } + else + { + scan_state = sig_end; + } + break; + } + if (d.sig.length < 20) + { + d.sig.text[d.sig.length++] = c; + } + else + { + exp_adjust++; + } + + c = fetch(); + break; + + case frac_start: + if (!isdigit(c)) + { + scan_state = failure; + break; + } + + scan_state = frac_digit_loop; + break; + + case frac_digit_loop: + if (!isdigit(c)) + { + scan_state = sig_end; + break; + } + + if (d.sig.length < 20) + { + if (c != '0' || d.sig.length) + { + d.sig.text[d.sig.length++] = c; + } + + exp_adjust--; + } + c = fetch(); + break; + + case sig_end: + if (toupper(c) == 'E') + { + scan_state = exp_start; + c = fetch(); + break; + } + scan_state = finished; + break; + + case exp_start: + if (c == '+') + { + c = fetch(); + } + else if (c == '-') + { + c = fetch(); + exp_negative = 1; + } + + scan_state = leading_exp_digit; + break; + + case leading_exp_digit: + if (!isdigit(c)) + { + scan_state = failure; + break; + } + + if (c == '0') + { + scan_state = leading_exp_zeroes; + c = fetch(); + break; + } + + scan_state = exp_digit_loop; + break; + + case leading_exp_zeroes: + if (c == '0') + { + c = fetch(); + break; + } + + scan_state = exp_digit_loop; + break; + + case exp_digit_loop: + if (!isdigit(c)) + { + scan_state = finished; + break; + } + + exp_value = exp_value * 10 + (c - '0'); + if (exp_value > SHRT_MAX) + { + *overflow = 1; + } + + c = fetch(); + break; + + case hex_state: + { + switch (hex_scan_state) + { + case hex_start: + for (chindex = 0; chindex < 8; chindex++) + { + *(chptr + chindex) = '\0'; + } + NibbleIndex = 2; + hex_scan_state = hex_leading_sig_zeroes; + c = fetch(); + break; + + case hex_leading_sig_zeroes: + if (c == '0') + { + c = fetch(); + break; + } + + hex_scan_state = hex_int_digit_loop; + break; + + case hex_int_digit_loop: + if (!isxdigit(c)) + { + if (c == dot) + { + hex_scan_state = hex_frac_digit_loop; + c = fetch(); + } + else + { + hex_scan_state = hex_sig_end; + } + break; + } + + if (NibbleIndex < 17) + { + intdigits++; + uch = *(chptr + NibbleIndex / 2); + ui = toupper(c); + + if (ui >= 'A') + { + ui = ui - 'A' + 10; + } + else + { + ui -= '0'; + } + + uch1 = ui; + + if ((NibbleIndex % 2) != 0) + { + uch |= uch1; + } + else + { + uch |= uch1 << 4; + } + + *(chptr + NibbleIndex++ / 2) = uch; + c = fetch(); + } + + else + { + c = fetch(); + } + + break; + + case hex_frac_digit_loop: + if (!isxdigit(c)) + { + hex_scan_state = hex_sig_end; + break; + } + + if (NibbleIndex < 17) + { + uch = *(chptr + NibbleIndex / 2); + ui = toupper(c); + + if (ui >= 'A') + { + ui = ui - 'A' + 10; + } + else + { + ui -= '0'; + } + + uch1 = ui; + + if ((NibbleIndex % 2) != 0) + { + uch |= uch1; + } + else + { + uch |= uch1 << 4; + } + + *(chptr + NibbleIndex++ / 2) = uch; + c = fetch(); + } + else + { + c = fetch(); + } + break; + + case hex_sig_end: + if (toupper(c) == 'P') + { + hex_scan_state = hex_exp_start; + exp_digits++; + c = fetch(); + } + else + { + scan_state = finished; + } + + break; + + case hex_exp_start: + exp_digits++; + if (c == '-') + { + expsign = 1; + } + else if (c != '+') + { + c = unfetch(c); + exp_digits--; + } + + hex_scan_state = hex_leading_exp_digit; + c = fetch(); + break; + + case hex_leading_exp_digit: + if (!isdigit(c)) + { + scan_state = failure; + break; + } + + if (c == '0') + { + exp_digits++; + hex_scan_state = hex_leading_exp_zeroes; + c = fetch(); + break; + } + + hex_scan_state = hex_exp_digit_loop; + break; + case hex_exp_digit_loop: + if (!isdigit(c)) + { + scan_state = finished; + break; + } + + exponent = exponent * 10 + (c - '0'); + + if (exp_value > SHRT_MAX) + { + *overflow = 1; + } + + exp_digits++; + c = fetch(); + + break; + } + } + break; + } + } + + if (!success(scan_state)) + { + count = 0; + *chars_scanned = 0; + } + else + { + count--; + *chars_scanned = count + spaces; + } + + unfetch(c); + + if (hex_scan_state == not_hex) + { + if (exp_negative) + { + exp_value = -exp_value; + } + + { + int n = d.sig.length; + unsigned char* p = &d.sig.text[n]; + + while (n-- && *--p == '0') + { + exp_adjust++; + } + + d.sig.length = n + 1; + + if (d.sig.length == 0) + { + d.sig.text[d.sig.length++] = '0'; + } + } + + exp_value += exp_adjust; + + if (exp_value < SHRT_MIN || exp_value > SHRT_MAX) + { + *overflow = 1; + } + + if (*overflow) + { + if (exp_negative) + { + return 0.0; + } + else + { + return sig_negative ? -HUGE_VAL : HUGE_VAL; + } + } + + d.exp = exp_value; + + result = __dec2num(&d); + + if (result != 0.0 && result < LDBL_MIN) + { + *overflow = 1; + } + else if (result > LDBL_MAX) + { + *overflow = 1; + result = HUGE_VAL; + } + + if (sig_negative && success(scan_state)) + { + result = -result; + } + + return result; + } + else + { + unsigned long long* uptr = (unsigned long long*)&result; + + if (result) + { + if (expsign) + { + exponent = -exponent; + } + + while ((*(short*)(&result) & 0x00f0) != 0x0010) + { + *uptr >>= 1; + exponent++; + } + + exponent += 4 * (intdigits - 1); + *(short*)&result &= 0x000f; + *(short*)(&result) |= ((exponent + 1023) << 4); + + *chars_scanned = spaces + sign_detected + NibbleIndex + 1 + exp_digits; + if (result != 0.0 && result < LDBL_MIN) + { + *overflow = 1; + result = 0.0; + } + else if (result > LDBL_MAX) + { + *overflow = 1; + result = HUGE_VAL; + } + if (sig_negative) + { + *(short*)(&result) |= 0x8000; + } + } + else + { + result = 0.0; + } + return result; + } +} + +void strtold(void) +{ + // UNUSED FUNCTION +} + +void strtod(void) +{ + // UNUSED FUNCTION +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtoul.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtoul.c new file mode 100644 index 000000000..5019f7213 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtoul.c @@ -0,0 +1,353 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/strtoul.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h" +#include "ctype.h" +#include "errno.h" +#include "limits.h" + +enum scan_states { + start = 0x01, + check_for_zero = 0x02, + leading_zero = 0x04, + need_digit = 0x08, + digit_loop = 0x10, + finished = 0x20, + failure = 0x40 +}; + +#define final_state(scan_state) (scan_state & (finished | failure)) +#define success(scan_state) (scan_state & (leading_zero | digit_loop | finished)) +#define fetch() (count++, (*ReadProc)(ReadProcArg, 0, __GetAChar)) +#define unfetch(c) (*ReadProc)(ReadProcArg, c, __UngetAChar) + +unsigned long __strtoul(int base, int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, int* chars_scanned, int* negative, + int* overflow) +{ + int scan_state = start; + int count = 0; + int spaces = 0; + unsigned long value = 0; + unsigned long value_max = 0; + int c; + + *negative = *overflow = 0; + + if (base < 0 || base == 1 || base > 36 || max_width < 1) { + scan_state = failure; + } else { + c = fetch(); + } + + if (base != 0) { + value_max = ULONG_MAX / base; + } + + while (count <= max_width && c != -1 && !final_state(scan_state)) { + switch (scan_state) { + case start: + if (isspace(c)) { + c = fetch(); + count--; + spaces++; + break; + } + + if (c == '+') { + c = fetch(); + } else if (c == '-') { + c = fetch(); + *negative = 1; + } + + scan_state = check_for_zero; + break; + + case check_for_zero: + if (base == 0 || base == 16) { + if (c == '0') { + scan_state = leading_zero; + c = fetch(); + break; + } + } + + scan_state = need_digit; + break; + + case 4: + if (c == 'X' || c == 'x') { + base = 16; + scan_state = need_digit; + c = fetch(); + break; + } + + if (base == 0) { + base = 8; + } + + scan_state = digit_loop; + break; + + case need_digit: + case digit_loop: + if (base == 0) { + base = 10; + } + + if (!value_max) { + value_max = ULONG_MAX / base; + } + + if (isdigit(c)) { + if ((c -= '0') >= base) { + if (scan_state == digit_loop) { + scan_state = finished; + } else { + scan_state = failure; + } + + c += '0'; + break; + } + } else if (!isalpha(c) || (toupper(c) - 'A' + 10) >= base) { + if (scan_state == digit_loop) { + scan_state = finished; + } else { + scan_state = failure; + } + + break; + } else { + c = toupper(c) - 'A' + 10; + } + + if (value > value_max) { + *overflow = 1; + } + + value *= base; + + if (c > (ULONG_MAX - value)) { + *overflow = 1; + } + + value += c; + scan_state = digit_loop; + c = fetch(); + break; + } + } + + if (!success(scan_state)) { + count = value = *chars_scanned = 0; + } else { + count--; + *chars_scanned = count + spaces; + } + + unfetch(c); + return value; +} + +unsigned long long __strtoull(int base, int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, int* chars_scanned, + int* negative, int* overflow) +{ + int scan_state = start; + int count = 0; + int spaces = 0; + unsigned long long value = 0; + unsigned long long value_max = 0; + unsigned long long ullmax = ULLONG_MAX; + int c; + + *negative = *overflow = 0; + + if (base < 0 || base == 1 || base > 36 || max_width < 1) { + scan_state = failure; + } else { + c = fetch(); + } + + if (base != 0) { + value_max = ullmax / base; + } + + while (count <= max_width && c != -1 && !final_state(scan_state)) { + switch (scan_state) { + case start: + if (isspace(c)) { + c = fetch(); + count--; + spaces++; + break; + } + + if (c == '+') { + c = fetch(); + } else if (c == '-') { + c = fetch(); + *negative = 1; + } + + scan_state = check_for_zero; + break; + + case check_for_zero: + if (base == 0 || base == 16) { + if (c == '0') { + scan_state = leading_zero; + c = fetch(); + break; + } + } + + scan_state = need_digit; + break; + + case leading_zero: + if (c == 'X' || c == 'x') { + base = 16; + scan_state = need_digit; + c = fetch(); + break; + } + + if (base == 0) { + base = 8; + } + + scan_state = digit_loop; + break; + + case need_digit: + case digit_loop: + if (base == 0) { + base = 10; + } + + if (!value_max) { + value_max = ullmax / base; + } + + if (isdigit(c)) { + if ((c -= '0') >= base) { + if (scan_state == digit_loop) { + scan_state = finished; + } else { + scan_state = failure; + } + + c += '0'; + break; + } + } else if (!isalpha(c) || (toupper(c) - 'A' + 10) >= base) { + if (scan_state == digit_loop) { + scan_state = finished; + } else { + scan_state = failure; + } + + break; + } else { + c = toupper(c) - 'A' + 10; + } + + if (value > value_max) { + *overflow = 1; + } + + value *= base; + + if (c > (ullmax - value)) { + *overflow = 1; + } + + value += c; + scan_state = digit_loop; + c = fetch(); + break; + } + } + + if (!success(scan_state)) { + count = value = *chars_scanned = 0; + + } else { + count--; + *chars_scanned = count + spaces; + } + + unfetch(c); + return value; +} + +unsigned long strtoul(const char* str, char** end, int base) +{ + unsigned long value; + int count, negative, overflow; + + __InStrCtrl isc; + isc.NextChar = (char*)str; + isc.NullCharDetected = 0; + + value = __strtoul(base, 0x7FFFFFFF, &__StringRead, (void*)&isc, &count, &negative, &overflow); + + if (end) { + *end = (char*)str + count; + } + + if (overflow) { + value = ULONG_MAX; + errno = 0x22; + } else if (negative) { + value = -value; + } + + return value; +} + +void strtoull(void) +{ + // UNUSED FUNCTION +} + +long strtol(const char* str, char** end, int base) +{ + unsigned long uvalue; + long svalue; + int count, negative, overflow; + + __InStrCtrl isc; + isc.NextChar = (char*)str; + isc.NullCharDetected = 0; + + uvalue = __strtoul(base, 0x7FFFFFFF, &__StringRead, (void*)&isc, &count, &negative, &overflow); + + if (end) { + *end = (char*)str + count; + } + + if (overflow || (!negative && uvalue > LONG_MAX) || (negative && uvalue > -LONG_MIN)) { + svalue = (negative ? -LONG_MIN : LONG_MAX); + errno = ERANGE; + } else { + svalue = (negative ? (long)-uvalue : (long)uvalue); + } + + return svalue; +} + +void strtoll(void) +{ + // UNUSED FUNCTION +} + +int atoi(const char* str) +{ + // UNUSED FUNCTION +} + +void atol(void) +{ + // UNUSED FUNCTION +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/wchar_io.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/wchar_io.c new file mode 100644 index 000000000..da6a0378a --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/wchar_io.c @@ -0,0 +1,82 @@ +#include "types.h" + +#ifndef _MSL_WIDE_CHAR +#define _MSL_WIDE_CHAR +#endif + +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + +void putwc(void) +{ + // UNUSED FUNCTION +} + +void putwchar(void) +{ + // UNUSED FUNCTION +} + +void fputwc(void) +{ + // UNUSED FUNCTION +} + +void getwc(void) +{ + // UNUSED FUNCTION +} + +void getwchar(void) +{ + // UNUSED FUNCTION +} + +void fgetwc(void) +{ + // UNUSED FUNCTION +} + +void ungetwc(void) +{ + // UNUSED FUNCTION +} + +void fputws(void) +{ + // UNUSED FUNCTION +} + +void fgetws(void) +{ + // UNUSED FUNCTION +} + +int fwide(FILE* stream, int mode) +{ + int res; + int orientation; + + if (stream == nullptr || stream->mMode.file_kind == __closed_file) + return 0; + + orientation = stream->mMode.file_orientation; + switch (orientation) { + case __unoriented: + if (mode > 0) + stream->mMode.file_orientation = __wide_oriented; + else if (mode < 0) + stream->mMode.file_orientation = __char_oriented; + + res = mode; + break; + + case __wide_oriented: + res = 1; + break; + + case __char_oriented: + res = -1; + break; + } + return res; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c new file mode 100644 index 000000000..40d8aaa60 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c @@ -0,0 +1,117 @@ + +/* @(#)e_asin.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_asin(x) + * Method : + * Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ... + * we approximate asin(x) on [0,0.5] by + * asin(x) = x + x*x^2*R(x^2) + * where + * R(x^2) is a rational approximation of (asin(x)-x)/x^3 + * and its remez error is bounded by + * |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75) + * + * For x in [0.5,1] + * asin(x) = pi/2-2*asin(sqrt((1-x)/2)) + * Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2; + * then for x>0.98 + * asin(x) = pi/2 - 2*(s+s*z*R(z)) + * = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo) + * For x<=0.98, let pio4_hi = pio2_hi/2, then + * f = hi part of s; + * c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z) + * and + * asin(x) = pi/2 - 2*(s+s*z*R(z)) + * = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo) + * = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c)) + * + * Special cases: + * if x is NaN, return x itself; + * if |x|>1, return NaN with invalid signal. + * + */ + +#include "fdlibm.h" +#include "math.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif + one + = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ + huge = 1.000e+300, pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ + pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */ + pio4_hi = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */ + /* coefficient for R(x^2) */ + pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */ + pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */ + pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */ + pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */ + pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */ + pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */ + qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */ + qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ + qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ + qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ + +#ifdef __STDC__ +double __ieee754_asin(double x) +#else +double __ieee754_asin(x) double x; +#endif +{ + double t, w, p, q, c, r, s; + int hx, ix; + hx = __HI(x); + ix = hx & 0x7fffffff; + if (ix >= 0x3ff00000) { /* |x|>= 1 */ + if (((ix - 0x3ff00000) | __LO(x)) == 0) + /* asin(1)=+-pi/2 with inexact */ + return x * pio2_hi + x * pio2_lo; + return NAN; /* asin(|x|>1) is NaN */ + } else if (ix < 0x3fe00000) { /* |x|<0.5 */ + if (ix < 0x3e400000) { /* if |x| < 2**-27 */ + if (huge + x > one) + return x; /* return x with inexact if x!=0*/ + } else + t = x * x; + p = t * (pS0 + t * (pS1 + t * (pS2 + t * (pS3 + t * (pS4 + t * pS5))))); + q = one + t * (qS1 + t * (qS2 + t * (qS3 + t * qS4))); + w = p / q; + return x + x * w; + } + /* 1> |x|>= 0.5 */ + w = one - fabs(x); + t = w * 0.5; + p = t * (pS0 + t * (pS1 + t * (pS2 + t * (pS3 + t * (pS4 + t * pS5))))); + q = one + t * (qS1 + t * (qS2 + t * (qS3 + t * qS4))); + s = sqrt(t); + if (ix >= 0x3FEF3333) { /* if |x| > 0.975 */ + w = p / q; + t = pio2_hi - (2.0 * (s + s * w) - pio2_lo); + } else { + w = s; + __LO(w) = 0; + c = (t - w * w) / (s + w); + r = p / q; + p = 2.0 * s * r - (pio2_lo - 2.0 * c); + q = pio4_hi - 2.0 * w; + t = pio4_hi - (p - q); + } + if (hx > 0) + return t; + else + return -t; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c new file mode 100644 index 000000000..4b75220c1 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c @@ -0,0 +1,143 @@ + +/* @(#)e_atan2.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* __ieee754_atan2(y,x) + * Method : + * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x). + * 2. Reduce x to positive by (if x and y are unexceptional): + * ARG (x+iy) = arctan(y/x) ... if x > 0, + * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0, + * + * Special cases: + * + * ATAN2((anything), NaN ) is NaN; + * ATAN2(NAN , (anything) ) is NaN; + * ATAN2(+-0, +(anything but NaN)) is +-0 ; + * ATAN2(+-0, -(anything but NaN)) is +-pi ; + * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2; + * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ; + * ATAN2(+-(anything but INF and NaN), -INF) is +-pi; + * ATAN2(+-INF,+INF ) is +-pi/4 ; + * ATAN2(+-INF,-INF ) is +-3pi/4; + * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2; + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif + tiny + = 1.0e-300, + zero = 0.0, pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */ + pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */ + pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */ + pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */ + +#ifdef __STDC__ +double __ieee754_atan2(double y, double x) +#else +double __ieee754_atan2(y, x) double y, x; +#endif +{ + double z; + int k, m, hx, hy, ix, iy; + unsigned lx, ly; + + hx = __HI(x); + ix = hx & 0x7fffffff; + lx = __LO(x); + hy = __HI(y); + iy = hy & 0x7fffffff; + ly = __LO(y); + if (((ix | ((lx | -lx) >> 31)) > 0x7ff00000) || ((iy | ((ly | -ly) >> 31)) > 0x7ff00000)) /* x or y is NaN */ + return x + y; + if ((hx - 0x3ff00000 | lx) == 0) + return atan(y); /* x=1.0 */ + m = ((hy >> 31) & 1) | ((hx >> 30) & 2); /* 2*sign(x)+sign(y) */ + + /* when y = 0 */ + if ((iy | ly) == 0) { + switch (m) { + case 0: + case 1: + return y; /* atan(+-0,+anything)=+-0 */ + case 2: + return pi + tiny; /* atan(+0,-anything) = pi */ + case 3: + return -pi - tiny; /* atan(-0,-anything) =-pi */ + } + } + /* when x = 0 */ + if ((ix | lx) == 0) + return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny; + + /* when x is INF */ + if (ix == 0x7ff00000) { + if (iy == 0x7ff00000) { + switch (m) { + case 0: + return pi_o_4 + tiny; /* atan(+INF,+INF) */ + case 1: + return -pi_o_4 - tiny; /* atan(-INF,+INF) */ + case 2: + return 3.0 * pi_o_4 + tiny; /*atan(+INF,-INF)*/ + case 3: + return -3.0 * pi_o_4 - tiny; /*atan(-INF,-INF)*/ + } + } else { + switch (m) { + case 0: + return zero; /* atan(+...,+INF) */ + case 1: + return -zero; /* atan(-...,+INF) */ + case 2: + return pi + tiny; /* atan(+...,-INF) */ + case 3: + return -pi - tiny; /* atan(-...,-INF) */ + } + } + } + /* when y is INF */ + if (iy == 0x7ff00000) + return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny; + + /* compute y/x */ + k = (iy - ix) >> 20; + if (k > 60) + z = pi_o_2 + 0.5 * pi_lo; /* |y/x| > 2**60 */ + else if (hx < 0 && k < -60) + z = 0.0; /* |y|/x < -2**60 */ + else + z = atan(__fabs(y / x)); /* safe to do y/x */ + switch (m) { + case 0: + return z; /* atan(+,+) */ + case 1: + __HI(z) ^= 0x80000000; + return z; /* atan(-,+) */ + case 2: + return pi - (z - pi_lo); /* atan(+,-) */ + default: /* case 3 */ + return (z - pi_lo) - pi; /* atan(-,-) */ + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c new file mode 100644 index 000000000..90e9f2918 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c @@ -0,0 +1,162 @@ + +/* @(#)e_exp.c 1.6 04/04/22 */ +/* + * ==================================================== + * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. + * + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_exp(x) + * Returns the exponential of x. + * + * Method + * 1. Argument reduction: + * Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658. + * Given x, find r and integer k such that + * + * x = k*ln2 + r, |r| <= 0.5*ln2. + * + * Here r will be represented as r = hi-lo for better + * accuracy. + * + * 2. Approximation of exp(r) by a special rational function on + * the interval [0,0.34658]: + * Write + * R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ... + * We use a special Remes algorithm on [0,0.34658] to generate + * a polynomial of degree 5 to approximate R. The maximum error + * of this polynomial approximation is bounded by 2**-59. In + * other words, + * R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5 + * (where z=r*r, and the values of P1 to P5 are listed below) + * and + * | 5 | -59 + * | 2.0+P1*z+...+P5*z - R(z) | <= 2 + * | | + * The computation of exp(r) thus becomes + * 2*r + * exp(r) = 1 + ------- + * R - r + * r*R1(r) + * = 1 + r + ----------- (for better accuracy) + * 2 - R1(r) + * where + * 2 4 10 + * R1(r) = r - (P1*r + P2*r + ... + P5*r ). + * + * 3. Scale back to obtain exp(x): + * From step 1, we have + * exp(x) = 2^k * exp(r) + * + * Special cases: + * exp(INF) is INF, exp(NaN) is NaN; + * exp(-INF) is 0, and + * for finite argument, only exp(0)=1 is exact. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Misc. info. + * For IEEE double + * if x > 7.09782712893383973096e+02 then exp(x) overflow + * if x < -7.45133219101941108420e+02 then exp(x) underflow + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +one = 1.0, +halF[2] = {0.5,-0.5,}, +huge = 1.0e+300, +twom1000= 9.33263618503218878990e-302, /* 2**-1000=0x01700000,0*/ +o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */ +u_threshold= -7.45133219101941108420e+02, /* 0xc0874910, 0xD52D3051 */ +ln2HI[2] ={ 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */ + -6.93147180369123816490e-01,},/* 0xbfe62e42, 0xfee00000 */ +ln2LO[2] ={ 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */ + -1.90821492927058770002e-10,},/* 0xbdea39ef, 0x35793c76 */ +invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */ +P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ +P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ +P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ +P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ +P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ + +#ifdef __STDC__ +double __ieee754_exp(double x) /* default IEEE double exp */ +#else +double __ieee754_exp(x) /* default IEEE double exp */ + double x; +#endif +{ + double y, hi, lo, c, t; + int k, xsb; + unsigned hx; + + hx = __HI(x); /* high word of x */ + xsb = (hx >> 31) & 1; /* sign bit of x */ + hx &= 0x7fffffff; /* high word of |x| */ + + /* filter out non-finite argument */ + if (hx >= 0x40862E42) { /* if |x|>=709.78... */ + if (hx >= 0x7ff00000) { + if (((hx & 0xfffff) | __LO(x)) != 0) + return x + x; /* NaN */ + else + return (xsb == 0) ? x : 0.0; /* exp(+-inf)={inf,0} */ + } + if (x > o_threshold) + return huge * huge; /* overflow */ + if (x < u_threshold) + return twom1000 * twom1000; /* underflow */ + } + + /* argument reduction */ + if (hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ + if (hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ + hi = x - ln2HI[xsb]; + lo = ln2LO[xsb]; + k = 1 - xsb - xsb; + } else { + k = (int)(invln2 * x + halF[xsb]); + t = k; + hi = x - t * ln2HI[0]; /* t*ln2HI is exact here */ + lo = t * ln2LO[0]; + } + x = hi - lo; + } else if (hx < 0x3e300000) { /* when |x|<2**-28 */ + if (huge + x > one) + return one + x; /* trigger inexact */ + } else + k = 0; + + /* x is now in primary range */ + t = x * x; + c = x - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5)))); + if (k == 0) + return one - ((x * c) / (c - 2.0) - x); + else + y = one - ((lo - (x * c) / (2.0 - c)) - hi); + if (k >= -1021) { + __HI(y) += (k << 20); /* add k to y's exponent */ + return y; + } else { + __HI(y) += ((k + 1000) << 20); /* add k to y's exponent */ + return y * twom1000; + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c new file mode 100644 index 000000000..8ebc894ba --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c @@ -0,0 +1,167 @@ + +/* @(#)e_fmod.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * __ieee754_fmod(x,y) + * Return x mod y in exact arithmetic + * Method: shift and subtract + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double one = 1.0, Zero[] = { + 0.0, + -0.0, +}; +#else +static double one = 1.0, Zero[] = { + 0.0, + -0.0, +}; +#endif + +#ifdef __STDC__ +double __ieee754_fmod(double x, double y) +#else +double __ieee754_fmod(x, y) double x, y; +#endif +{ + int n, hx, hy, hz, ix, iy, sx, i; + unsigned lx, ly, lz; + + hx = __HI(x); /* high word of x */ + lx = __LO(x); /* low word of x */ + hy = __HI(y); /* high word of y */ + ly = __LO(y); /* low word of y */ + sx = hx & 0x80000000; /* sign of x */ + hx ^= sx; /* |x| */ + hy &= 0x7fffffff; /* |y| */ + + /* purge off exception values */ + if ((hy | ly) == 0 || (hx >= 0x7ff00000) || /* y=0,or x not finite */ + ((hy | ((ly | -ly) >> 31)) > 0x7ff00000)) /* or y is NaN */ + return (x * y) / (x * y); + if (hx <= hy) { + if ((hx < hy) || (lx < ly)) + return x; /* |x|<|y| return x */ + if (lx == ly) + return Zero[(unsigned)sx >> 31]; /* |x|=|y| return x*0*/ + } + + /* determine ix = ilogb(x) */ + if (hx < 0x00100000) { /* subnormal x */ + if (hx == 0) { + for (ix = -1043, i = lx; i > 0; i <<= 1) + ix -= 1; + } else { + for (ix = -1022, i = (hx << 11); i > 0; i <<= 1) + ix -= 1; + } + } else + ix = (hx >> 20) - 1023; + + /* determine iy = ilogb(y) */ + if (hy < 0x00100000) { /* subnormal y */ + if (hy == 0) { + for (iy = -1043, i = ly; i > 0; i <<= 1) + iy -= 1; + } else { + for (iy = -1022, i = (hy << 11); i > 0; i <<= 1) + iy -= 1; + } + } else + iy = (hy >> 20) - 1023; + + /* set up {hx,lx}, {hy,ly} and align y to x */ + if (ix >= -1022) + hx = 0x00100000 | (0x000fffff & hx); + else { /* subnormal x, shift x to normal */ + n = -1022 - ix; + if (n <= 31) { + hx = (hx << n) | (lx >> (32 - n)); + lx <<= n; + } else { + hx = lx << (n - 32); + lx = 0; + } + } + if (iy >= -1022) + hy = 0x00100000 | (0x000fffff & hy); + else { /* subnormal y, shift y to normal */ + n = -1022 - iy; + if (n <= 31) { + hy = (hy << n) | (ly >> (32 - n)); + ly <<= n; + } else { + hy = ly << (n - 32); + ly = 0; + } + } + + /* fix point fmod */ + n = ix - iy; + while (n--) { + hz = hx - hy; + lz = lx - ly; + if (lx < ly) + hz -= 1; + if (hz < 0) { + hx = hx + hx + (lx >> 31); + lx = lx + lx; + } else { + if ((hz | lz) == 0) /* return sign(x)*0 */ + return Zero[(unsigned)sx >> 31]; + hx = hz + hz + (lz >> 31); + lx = lz + lz; + } + } + hz = hx - hy; + lz = lx - ly; + if (lx < ly) + hz -= 1; + if (hz >= 0) { + hx = hz; + lx = lz; + } + + /* convert back to floating value and restore the sign */ + if ((hx | lx) == 0) /* return sign(x)*0 */ + return Zero[(unsigned)sx >> 31]; + while (hx < 0x00100000) { /* normalize x */ + hx = hx + hx + (lx >> 31); + lx = lx + lx; + iy -= 1; + } + if (iy >= -1022) { /* normalize output */ + hx = ((hx - 0x00100000) | ((iy + 1023) << 20)); + __HI(x) = hx | sx; + __LO(x) = lx; + } else { /* subnormal output */ + n = -1022 - iy; + if (n <= 20) { + lx = (lx >> n) | ((unsigned)hx << (32 - n)); + hx >>= n; + } else if (n <= 31) { + lx = (hx << (32 - n)) | (lx >> n); + hx = sx; + } else { + lx = hx >> (n - 32); + hx = sx; + } + __HI(x) = hx | sx; + __LO(x) = lx; + x *= one; /* create necessary signal */ + } + return x; /* exact output */ +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c new file mode 100644 index 000000000..4b2340097 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c @@ -0,0 +1,157 @@ +/* @(#)e_log.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_log(x) + * Return the logrithm of x + * + * Method : + * 1. Argument Reduction: find k and f such that + * x = 2^k * (1+f), + * where sqrt(2)/2 < 1+f < sqrt(2) . + * + * 2. Approximation of log(1+f). + * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) + * = 2s + 2/3 s**3 + 2/5 s**5 + ....., + * = 2s + s*R + * We use a special Reme algorithm on [0,0.1716] to generate + * a polynomial of degree 14 to approximate R The maximum error + * of this polynomial approximation is bounded by 2**-58.45. In + * other words, + * 2 4 6 8 10 12 14 + * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s + * (the values of Lg1 to Lg7 are listed in the program) + * and + * | 2 14 | -58.45 + * | Lg1*s +...+Lg7*s - R(z) | <= 2 + * | | + * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. + * In order to guarantee error in log below 1ulp, we compute log + * by + * log(1+f) = f - s*(f - R) (if f is not too large) + * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy) + * + * 3. Finally, log(x) = k*ln2 + log(1+f). + * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) + * Here ln2 is split into two floating point number: + * ln2_hi + ln2_lo, + * where n*ln2_hi is always exact for |n| < 2000. + * + * Special cases: + * log(x) is NaN with signal if x < 0 (including -INF) ; + * log(+INF) is +INF; log(0) is -INF with signal; + * log(NaN) is that NaN with no signal. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" +#include "errno.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif + ln2_hi + = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ + ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ + two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */ + Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ + Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ + Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ + Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ + Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ + Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ + Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ + +static double zero = 0.0; + +#ifdef __STDC__ +double __ieee754_log(double x) +#else +double __ieee754_log(x) double x; +#endif +{ + double hfsq, f, s, z, R, w, t1, t2, dk; + int k, hx, i, j; + unsigned lx; + + hx = __HI(x); /* high word of x */ + lx = __LO(x); /* low word of x */ + + k = 0; + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx & 0x7fffffff) | lx) == 0) + return -two54 / zero; /* log(+-0)=-inf */ + if (hx < 0) { + errno = 33; + return (x - x) / zero; + } /* log(-#) = NaN */ + k -= 54; + x *= two54; /* subnormal number, scale up x */ + hx = __HI(x); /* high word of x */ + } + if (hx >= 0x7ff00000) + return x + x; + k += (hx >> 20) - 1023; + hx &= 0x000fffff; + i = (hx + 0x95f64) & 0x100000; + __HI(x) = hx | (i ^ 0x3ff00000); /* normalize x or x/2 */ + k += (i >> 20); + f = x - 1.0; + if ((0x000fffff & (2 + hx)) < 3) { /* |f| < 2**-20 */ + if (f == zero) + if (k == 0) + return zero; + else { + dk = (double)k; + return dk * ln2_hi + dk * ln2_lo; + } + R = f * f * (0.5 - 0.33333333333333333 * f); + if (k == 0) + return f - R; + else { + dk = (double)k; + return dk * ln2_hi - ((R - dk * ln2_lo) - f); + } + } + s = f / (2.0 + f); + dk = (double)k; + z = s * s; + i = hx - 0x6147a; + w = z * z; + j = 0x6b851 - hx; + t1 = w * (Lg2 + w * (Lg4 + w * Lg6)); + t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7))); + i |= j; + R = t2 + t1; + if (i > 0) { + hfsq = 0.5 * f * f; + if (k == 0) + return f - (hfsq - s * (hfsq + R)); + else + return dk * ln2_hi - ((hfsq - (s * (hfsq + R) + dk * ln2_lo)) - f); + } else { + if (k == 0) + return f - s * (f - R); + else + return dk * ln2_hi - ((s * (f - R) - dk * ln2_lo) - f); + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log10.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log10.c new file mode 100644 index 000000000..2f2ddffa3 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log10.c @@ -0,0 +1,99 @@ + +/* @(#)e_log10.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_log10(x) + * Return the base 10 logarithm of x + * + * Method : + * Let log10_2hi = leading 40 bits of log10(2) and + * log10_2lo = log10(2) - log10_2hi, + * ivln10 = 1/log(10) rounded. + * Then + * n = ilogb(x), + * if(n<0) n = n+1; + * x = scalbn(x,-n); + * log10(x) := n*log10_2hi + (n*log10_2lo + ivln10*log(x)) + * + * Note 1: + * To guarantee log10(10**n)=n, where 10**n is normal, the rounding + * mode must set to Round-to-Nearest. + * Note 2: + * [1/log(10)] rounded to 53 bits has error .198 ulps; + * log10 is monotonic at all binary break points. + * + * Special cases: + * log10(x) is NaN with signal if x < 0; + * log10(+INF) is +INF with no signal; log10(0) is -INF with signal; + * log10(NaN) is that NaN with no signal; + * log10(10**N) = N for N=0,1,...,22. + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "fdlibm.h" +#include "errno.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif + two54 + = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ + ivln10 = 4.34294481903251816668e-01, /* 0x3FDBCB7B, 0x1526E50E */ + log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */ + log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */ + +static double zero = 0.0; + +#ifdef __STDC__ +double __ieee754_log10(double x) +#else +double __ieee754_log10(x) double x; +#endif +{ + double y, z; + int i, k, hx; + unsigned lx; + + hx = __HI(x); /* high word of x */ + lx = __LO(x); /* low word of x */ + + k = 0; + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx & 0x7fffffff) | lx) == 0) { + errno = 33; + return -two54 / zero; + } /* log(+-0)=-inf */ + if (hx < 0) { + errno = 33; + return (x - x) / zero; + } /* log(-#) = NaN */ + k -= 54; + x *= two54; /* subnormal number, scale up x */ + hx = __HI(x); /* high word of x */ + } + if (hx >= 0x7ff00000) + return x + x; + k += (hx >> 20) - 1023; + i = ((unsigned)k & 0x80000000) >> 31; + hx = (hx & 0x000fffff) | ((0x3ff - i) << 20); + y = (double)(k + i); + __HI(x) = hx; + z = y * log10_2lo + ivln10 * __ieee754_log(x); + return z + y * log10_2hi; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c new file mode 100644 index 000000000..5f9af1132 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c @@ -0,0 +1,408 @@ +//======================================================================== +// +// e_pow.c +// +// Part of the standard mathematical function library +// +//======================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//======================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jlarmour +// Contributors: +// Date: 2001-07-20 +// Purpose: +// Description: +// Usage: +// +//####DESCRIPTIONEND#### +// +//======================================================================== + +// CONFIGURATION + +/* @(#)e_pow.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_pow(x,y) return x**y + * + * n + * Method: Let x = 2 * (1+f) + * 1. Compute and return log2(x) in two pieces: + * log2(x) = w1 + w2, + * where w1 has 53-24 = 29 bit trailing zeros. + * 2. Perform y*log2(x) = n+y' by simulating muti-precision + * arithmetic, where |y'|<=0.5. + * 3. Return x**y = 2**n*exp(y'*log2) + * + * Special cases: + * 1. (anything) ** 0 is 1 + * 2. (anything) ** 1 is itself + * 3. (anything) ** NAN is NAN + * 4. NAN ** (anything except 0) is NAN + * 5. +-(|x| > 1) ** +INF is +INF + * 6. +-(|x| > 1) ** -INF is +0 + * 7. +-(|x| < 1) ** +INF is +0 + * 8. +-(|x| < 1) ** -INF is +INF + * 9. +-1 ** +-INF is NAN + * 10. +0 ** (+anything except 0, NAN) is +0 + * 11. -0 ** (+anything except 0, NAN, odd integer) is +0 + * 12. +0 ** (-anything except 0, NAN) is +INF + * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF + * 14. -0 ** (odd integer) = -( +0 ** (odd integer) ) + * 15. +INF ** (+anything except 0,NAN) is +INF + * 16. +INF ** (-anything except 0,NAN) is +0 + * 17. -INF ** (anything) = -0 ** (-anything) + * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer) + * 19. (-anything except 0 and inf) ** (non-integer) is NAN + * + * Accuracy: + * pow(x,y) returns x**y nearly rounded. In particular + * pow(integer,integer) + * always returns the correct integer provided it is + * representable. + * + * Constants : + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "types.h" +#include "errno.h" +#include "math.h" +#include "fdlibm.h" + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double +#else +static double +#endif +bp[] = {1.0, 1.5,}, +dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */ +dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */ +zero = 0.0, +one = 1.0, +two = 2.0, +two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */ +huge = 1.0e300, +tiny = 1.0e-300, + /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ +L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */ +L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */ +L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */ +L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */ +L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */ +L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */ +P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ +P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ +P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ +P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ +P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */ +lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ +lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */ +lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */ +ovt = 8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */ +cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */ +cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */ +cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/ +ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */ +ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/ +ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ + +#ifdef __STDC__ +double __ieee754_pow(double x, double y) +#else +double __ieee754_pow(x, y) double x, y; +#endif +{ + double z, ax, z_h, z_l, p_h, p_l; + double y1, t1, t2, r, s, t, u, v, w; + double qqq; // necessary temp + int i0, i1, i, j, k, yisint, n; + int hx, hy, ix, iy; + u32 lx, ly; + + i0 = ((*(int*)&one) >> 29) ^ 1; + i1 = 1 - i0; + hx = __HI(x); + lx = __LO(x); + hy = __HI(y); + ly = __LO(y); + ix = hx & 0x7fffffff; + iy = hy & 0x7fffffff; + + /* y==zero: x**0 = 1 */ + if ((iy | ly) == 0) + return one; + + /* +-NaN return x+y */ + if (ix > 0x7ff00000 || ((ix == 0x7ff00000) && (lx != 0)) || iy > 0x7ff00000 || ((iy == 0x7ff00000) && (ly != 0))) + return x + y; + + /* determine if y is an odd int when x < 0 + * yisint = 0 ... y is not an integer + * yisint = 1 ... y is an odd int + * yisint = 2 ... y is an even int + */ + yisint = 0; + if (hx < 0) { + if (iy >= 0x43400000) + yisint = 2; /* even integer y */ + else if (iy >= 0x3ff00000) { + k = (iy >> 20) - 0x3ff; /* exponent */ + if (k > 20) { + j = ly >> (52 - k); + if ((j << (52 - k)) == ly) + yisint = 2 - (j & 1); + } else if (ly == 0) { + j = iy >> (20 - k); + if ((j << (20 - k)) == iy) + yisint = 2 - (j & 1); + } + } + } + + /* special value of y */ + if (ly == 0) { + if (iy == 0x7ff00000) { /* y is +-inf */ + if (((ix - 0x3ff00000) | lx) == 0) + return y - y; /* inf**+-1 is NaN */ + else if (ix >= 0x3ff00000) /* (|x|>1)**+-inf = inf,0 */ + return (hy >= 0) ? y : zero; + else /* (|x|<1)**-,+inf = inf,0 */ + return (hy < 0) ? -y : zero; + } + if (iy == 0x3ff00000) { /* y is +-1 */ + if (hy < 0) + return one / x; + else + return x; + } + if (hy == 0x40000000) + return x * x; /* y is 2 */ + if (hy == 0x3fe00000) { /* y is 0.5 */ + if (hx >= 0) /* x >= +0 */ + return sqrt(x); + } + } + + ax = __fabs(x); + qqq = ax; /*x is +-0,+-inf,+-1*/ + /* special value of x */ + if (lx == 0) { + if (ix == 0x7ff00000 || ix == 0 || ix == 0x3ff00000) { + z = qqq; /*x is +-0,+-inf,+-1*/ + if (hy < 0) + z = one / z; /* z = (1/|x|) */ + if (hx < 0) { + if (((ix - 0x3ff00000) | yisint) == 0) { + z = (z - z) / (z - z); /* (-1)**non-int is NaN */ + } else if (yisint == 1) + z = -z; /* (x<0)**odd = -(|x|**odd) */ + } + return z; + } + } + + /* (x<0)**(non-int) is NaN */ + /* CYGNUS LOCAL: This used to be + if((((hx>>31)+1)|yisint)==0) return (x-x)/(x-x); + but ANSI C says a right shift of a signed negative quantity is + implementation defined. */ + + if (((((int)hx >> 31) + 1) | yisint) == 0) { + errno = 33; + return (double)NAN; + }; + + /* |y| is huge */ + if (iy > 0x41e00000) { /* if |y| > 2**31 */ + if (iy > 0x43f00000) { /* if |y| > 2**64, must o/uflow */ + if (ix <= 0x3fefffff) + return (hy < 0) ? huge * huge : tiny * tiny; + if (ix >= 0x3ff00000) + return (hy > 0) ? huge * huge : tiny * tiny; + } + /* over/underflow if x is not close to one */ + if (ix < 0x3fefffff) + return (hy < 0) ? huge * huge : tiny * tiny; + if (ix > 0x3ff00000) + return (hy > 0) ? huge * huge : tiny * tiny; + /* now |1-x| is tiny <= 2**-20, suffice to compute + log(x) by x-x^2/2+x^3/3-x^4/4 */ + t = x - 1; /* t has 20 trailing zeros */ + w = (t * t) * (0.5 - t * (0.3333333333333333333333 - t * 0.25)); + u = ivln2_h * t; /* ivln2_h has 21 sig. bits */ + v = t * ivln2_l - w * ivln2; + t1 = u + v; + __LO(t1) = 0; + t2 = v - (t1 - u); + } else { + double s2, s_h, s_l, t_h, t_l; + n = 0; + /* take care subnormal number */ + if (ix < 0x00100000) { + ax *= two53; + n -= 53; + ix = __HI(ax); + } + n += ((ix) >> 20) - 0x3ff; + j = ix & 0x000fffff; + /* determine interval */ + ix = j | 0x3ff00000; /* normalize ix */ + if (j <= 0x3988E) + k = 0; /* |x|> 1) | 0x20000000) + 0x00080000 + (k << 18); + t_l = ax - (t_h - bp[k]); + s_l = v * ((u - s_h * t_h) - s_h * t_l); + /* compute log(ax) */ + s2 = s * s; + r = s2 * s2 * (L1 + s2 * (L2 + s2 * (L3 + s2 * (L4 + s2 * (L5 + s2 * L6))))); + r += s_l * (s_h + s); + s2 = s_h * s_h; + t_h = 3.0 + s2 + r; + __LO(t_h) = 0; + t_l = r - ((t_h - 3.0) - s2); + /* u+v = s*(1+...) */ + u = s_h * t_h; + v = s_l * t_h + t_l * s; + /* 2/(3log2)*(s+...) */ + p_h = u + v; + __LO(p_h) = 0; + p_l = v - (p_h - u); + z_h = cp_h * p_h; /* cp_h+cp_l = 2/(3*log2) */ + z_l = cp_l * p_h + p_l * cp + dp_l[k]; + /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ + t = (double)n; + t1 = (((z_h + z_l) + dp_h[k]) + t); + __LO(t1) = 0; + t2 = z_l - (((t1 - t) - dp_h[k]) - z_h); + } + + s = one; /* s (sign of result -ve**odd) = -1 else = 1 */ + if (((((int)hx >> 31) + 1) | (yisint - 1)) == 0) + s = -one; /* (-ve)**(odd int) */ + + /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ + y1 = y; + __LO(y1) = 0; + p_l = (y - y1) * t1 + y * t2; + p_h = y1 * t1; + z = p_l + p_h; + j = __HI(z); + i = __LO(z); + if (j >= 0x40900000) { /* z >= 1024 */ + if (((j - 0x40900000) | i) != 0) /* if z > 1024 */ + return s * huge * huge; /* overflow */ + else { + if (p_l + ovt > z - p_h) + return s * huge * huge; /* overflow */ + } + } else if ((j & 0x7fffffff) >= 0x4090cc00) { /* z <= -1075 */ + if (((j - 0xc090cc00) | i) != 0) /* z < -1075 */ + return s * tiny * tiny; /* underflow */ + else { + if (p_l <= z - p_h) + return s * tiny * tiny; /* underflow */ + } + } + /* + * compute 2**(p_h+p_l) + */ + i = j & 0x7fffffff; + k = (i >> 20) - 0x3ff; + n = 0; + if (i > 0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */ + n = j + (0x00100000 >> (k + 1)); + k = ((n & 0x7fffffff) >> 20) - 0x3ff; /* new k for n */ + t = zero; + __HI(t) = (n & ~(0x000fffff >> k)); + n = ((n & 0x000fffff) | 0x00100000) >> (20 - k); + if (j < 0) + n = -n; + p_h -= t; + } + t = p_l + p_h; + __LO(t) = 0; + u = t * lg2_h; + v = (p_l - (t - p_h)) * lg2 + t * lg2_l; + z = u + v; + w = v - (z - u); + t = z * z; + t1 = z - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5)))); + r = (z * t1) / (t1 - two) - (w + z * w); + z = one - (r - z); + j = __HI(z); + j += (n << 20); + if ((j >> 20) <= 0) + z = ldexp(z, n); /* subnormal output */ + else + __HI(z) += (n << 20); + return s * z; +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ + +// EOF e_pow.c diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c new file mode 100644 index 000000000..86e0cd14e --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c @@ -0,0 +1,181 @@ + +/* @(#)e_rem_pio2.c 1.4 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* __ieee754_rem_pio2(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + * use __kernel_rem_pio2() + */ + +#include "fdlibm.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h" + +/* + * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi + */ +#ifdef __STDC__ +static const int two_over_pi[] = { +#else +static int two_over_pi[] = { +#endif + 0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, 0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, + 0x246E3A, 0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, 0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, + 0x7026B4, 0x5F7E41, 0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8, 0x97FFDE, 0x05980F, 0xEF2F11, + 0x8B5A0A, 0x6D1F6D, 0x367ECF, 0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5, 0xF17B3D, 0x0739F7, + 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, 0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, 0x91615E, + 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, 0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, +}; + +#ifdef __STDC__ +static const int npio2_hw[] = { +#else +static int npio2_hw[] = { +#endif + 0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C, 0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, + 0x4032D97C, 0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A, 0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, + 0x4042106C, 0x4042D97C, 0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB, 0x404858EB, 0x404921FB, +}; + +/* + * invpio2: 53 bits of 2/pi + * pio2_1: first 33 bit of pi/2 + * pio2_1t: pi/2 - pio2_1 + * pio2_2: second 33 bit of pi/2 + * pio2_2t: pi/2 - (pio2_1+pio2_2) + * pio2_3: third 33 bit of pi/2 + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) + */ + +#ifdef __STDC__ +static const double +#else +static double +#endif + zero + = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ + half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ + two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ + invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ + pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ + pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */ + pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */ + pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */ + pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */ + pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */ + +#ifdef __STDC__ +int __ieee754_rem_pio2(double x, double* y) +#else +int __ieee754_rem_pio2(x, y) double x, y[]; +#endif +{ + double z, w, t, r, fn; + double tx[3]; + int e0, i, j, nx, n, ix, hx; + + hx = __HI(x); /* high word of x */ + ix = hx & 0x7fffffff; + if (ix <= 0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */ + { + y[0] = x; + y[1] = 0; + return 0; + } + if (ix < 0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */ + if (hx > 0) { + z = x - pio2_1; + if (ix != 0x3ff921fb) { /* 33+53 bit pi is good enough */ + y[0] = z - pio2_1t; + y[1] = (z - y[0]) - pio2_1t; + } else { /* near pi/2, use 33+33+53 bit pi */ + z -= pio2_2; + y[0] = z - pio2_2t; + y[1] = (z - y[0]) - pio2_2t; + } + return 1; + } else { /* negative x */ + z = x + pio2_1; + if (ix != 0x3ff921fb) { /* 33+53 bit pi is good enough */ + y[0] = z + pio2_1t; + y[1] = (z - y[0]) + pio2_1t; + } else { /* near pi/2, use 33+33+53 bit pi */ + z += pio2_2; + y[0] = z + pio2_2t; + y[1] = (z - y[0]) + pio2_2t; + } + return -1; + } + } + if (ix <= 0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */ + t = fabs(x); + n = (int)(t * invpio2 + half); + fn = (double)n; + r = t - fn * pio2_1; + w = fn * pio2_1t; /* 1st round good to 85 bit */ + if (n < 32 && ix != npio2_hw[n - 1]) { + y[0] = r - w; /* quick check no cancellation */ + } else { + j = ix >> 20; + y[0] = r - w; + i = j - (((__HI(y[0])) >> 20) & 0x7ff); + if (i > 16) { /* 2nd iteration needed, good to 118 */ + t = r; + r = t - fn * pio2_2; + w = fn * pio2_2t - ((t - r) - fn * pio2_2); + y[0] = r - w; + i = j - (((__HI(y[0])) >> 20) & 0x7ff); + if (i > 49) { /* 3rd iteration need, 151 bits acc */ + t = r; /* will cover all possible cases */ + w = fn * pio2_3; + r = t - w; + w = fn * pio2_3t - ((t - r) - w); + y[0] = r - w; + } + } + } + y[1] = (r - y[0]) - w; + if (hx < 0) { + y[0] = -y[0]; + y[1] = -y[1]; + return -n; + } else + return n; + } + /* + * all other (large) arguments + */ + if (ix >= 0x7ff00000) { /* x is inf or NaN */ + y[0] = y[1] = x - x; + return 0; + } + /* set z = scalbn(|x|,ilogb(x)-23) */ + __LO(z) = __LO(x); + e0 = (ix >> 20) - 1046; /* e0 = ilogb(z)-23; */ + __HI(z) = ix - (e0 << 20); + for (i = 0; i < 2; i++) { + tx[i] = (double)((int)(z)); + z = (z - tx[i]) * two24; + } + tx[2] = z; + nx = 3; + while (tx[nx - 1] == zero) + nx--; /* skip zero term */ + n = __kernel_rem_pio2(tx, y, e0, nx, 2, two_over_pi); + if (hx < 0) { + y[0] = -y[0]; + y[1] = -y[1]; + return -n; + } + return n; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_sqrt.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_sqrt.c new file mode 100644 index 000000000..fdef23781 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_sqrt.c @@ -0,0 +1,462 @@ +/* @(#)e_sqrt.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_sqrt(x) + * Return correctly rounded sqrt. + * ------------------------------------------ + * | Use the hardware sqrt if you have one | + * ------------------------------------------ + * Method: + * Bit by bit method using integer arithmetic. (Slow, but portable) + * 1. Normalization + * Scale x to y in [1,4) with even powers of 2: + * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then + * sqrt(x) = 2^k * sqrt(y) + * 2. Bit by bit computation + * Let q = sqrt(y) truncated to i bit after binary point (q = 1), + * i 0 + * i+1 2 + * s = 2*q , and y = 2 * ( y - q ). (1) + * i i i i + * + * To compute q from q , one checks whether + * i+1 i + * + * -(i+1) 2 + * (q + 2 ) <= y. (2) + * i + * -(i+1) + * If (2) is false, then q = q ; otherwise q = q + 2 . + * i+1 i i+1 i + * + * With some algebric manipulation, it is not difficult to see + * that (2) is equivalent to + * -(i+1) + * s + 2 <= y (3) + * i i + * + * The advantage of (3) is that s and y can be computed by + * i i + * the following recurrence formula: + * if (3) is false + * + * s = s , y = y ; (4) + * i+1 i i+1 i + * + * otherwise, + * -i -(i+1) + * s = s + 2 , y = y - s - 2 (5) + * i+1 i i+1 i i + * + * One may easily use induction to prove (4) and (5). + * Note. Since the left hand side of (3) contain only i+2 bits, + * it does not necessary to do a full (53-bit) comparison + * in (3). + * 3. Final rounding + * After generating the 53 bits result, we compute one more bit. + * Together with the remainder, we can decide whether the + * result is exact, bigger than 1/2ulp, or less than 1/2ulp + * (it will never equal to 1/2ulp). + * The rounding mode can be detected by checking whether + * huge + tiny is equal to huge, and whether huge - tiny is + * equal to huge for some floating point number "huge" and "tiny". + * + * Special cases: + * sqrt(+-0) = +-0 ... exact + * sqrt(inf) = inf + * sqrt(-ve) = NaN ... with invalid signal + * sqrt(NaN) = NaN ... with invalid signal for signaling NaN + * + * Other methods : see the appended file at the end of the program below. + *--------------- + */ + +#include "fdlibm.h" +#include "errno.h" +#include "math.h" + +#ifdef __STDC__ +static const double one = 1.0, tiny = 1.0e-300; +#else +static double one = 1.0, tiny = 1.0e-300; +#endif + +#ifdef __STDC__ +double __ieee754_sqrt(double x) +#else +double __ieee754_sqrt(x) double x; +#endif +{ + double z; + int sign = (int)0x80000000; + unsigned r, t1, s1, ix1, q1; + int ix0, s0, q, m, t, i; + + ix0 = __HI(x); /* high word of x */ + ix1 = __LO(x); /* low word of x */ + + /* take care of Inf and NaN */ + if ((ix0 & 0x7ff00000) == 0x7ff00000) { + errno = 33; + return x * x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf + sqrt(-inf)=sNaN */ + } + /* take care of zero */ + if (ix0 <= 0) { + if (((ix0 & (~sign)) | ix1) == 0) + return x; /* sqrt(+-0) = +-0 */ + else if (ix0 < 0) { + errno = 33; + return NAN; + } /* sqrt(-ve) = sNaN */ + } + /* normalize x */ + m = (ix0 >> 20); + if (m == 0) { /* subnormal x */ + while (ix0 == 0) { + m -= 21; + ix0 |= (ix1 >> 11); + ix1 <<= 21; + } + for (i = 0; (ix0 & 0x00100000) == 0; i++) + ix0 <<= 1; + m -= i - 1; + ix0 |= (ix1 >> (32 - i)); + ix1 <<= i; + } + m -= 1023; /* unbias exponent */ + ix0 = (ix0 & 0x000fffff) | 0x00100000; + if (m & 1) { /* odd m, double x to make it even */ + ix0 += ix0 + ((ix1 & sign) >> 31); + ix1 += ix1; + } + m >>= 1; /* m = [m/2] */ + + /* generate sqrt(x) bit by bit */ + ix0 += ix0 + ((ix1 & sign) >> 31); + ix1 += ix1; + q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */ + r = 0x00200000; /* r = moving bit from right to left */ + + while (r != 0) { + t = s0 + r; + if (t <= ix0) { + s0 = t + r; + ix0 -= t; + q += r; + } + ix0 += ix0 + ((ix1 & sign) >> 31); + ix1 += ix1; + r >>= 1; + } + + r = sign; + while (r != 0) { + t1 = s1 + r; + t = s0; + if ((t < ix0) || ((t == ix0) && (t1 <= ix1))) { + s1 = t1 + r; + if (((t1 & sign) == sign) && (s1 & sign) == 0) + s0 += 1; + ix0 -= t; + if (ix1 < t1) + ix0 -= 1; + ix1 -= t1; + q1 += r; + } + ix0 += ix0 + ((ix1 & sign) >> 31); + ix1 += ix1; + r >>= 1; + } + + /* use floating add to find out rounding direction */ + if ((ix0 | ix1) != 0) { + z = one - tiny; /* trigger inexact flag */ + if (z >= one) { + z = one + tiny; + if (q1 == (unsigned)0xffffffff) { + q1 = 0; + q += 1; + } else if (z > one) { + if (q1 == (unsigned)0xfffffffe) + q += 1; + q1 += 2; + } else + q1 += (q1 & 1); + } + } + ix0 = (q >> 1) + 0x3fe00000; + ix1 = q1 >> 1; + if ((q & 1) == 1) + ix1 |= sign; + ix0 += (m << 20); + __HI(z) = ix0; + __LO(z) = ix1; + return z; +} + +/* +Other methods (use floating-point arithmetic) +------------- +(This is a copy of a drafted paper by Prof W. Kahan +and K.C. Ng, written in May, 1986) + + Two algorithms are given here to implement sqrt(x) + (IEEE double precision arithmetic) in software. + Both supply sqrt(x) correctly rounded. The first algorithm (in + Section A) uses newton iterations and involves four divisions. + The second one uses reciproot iterations to avoid division, but + requires more multiplications. Both algorithms need the ability + to chop results of arithmetic operations instead of round them, + and the INEXACT flag to indicate when an arithmetic operation + is executed exactly with no roundoff error, all part of the + standard (IEEE 754-1985). The ability to perform shift, add, + subtract and logical AND operations upon 32-bit words is needed + too, though not part of the standard. + +A. sqrt(x) by Newton Iteration + + (1) Initial approximation + + Let x0 and x1 be the leading and the trailing 32-bit words of + a floating point number x (in IEEE double format) respectively + + 1 11 52 ...widths + ------------------------------------------------------ + x: |s| e | f | + ------------------------------------------------------ + msb lsb msb lsb ...order + + + ------------------------ ------------------------ + x0: |s| e | f1 | x1: | f2 | + ------------------------ ------------------------ + + By performing shifts and subtracts on x0 and x1 (both regarded + as integers), we obtain an 8-bit approximation of sqrt(x) as + follows. + + k := (x0>>1) + 0x1ff80000; + y0 := k - T1[31&(k>>15)]. ... y ~ sqrt(x) to 8 bits + Here k is a 32-bit integer and T1[] is an integer array containing + correction terms. Now magically the floating value of y (y's + leading 32-bit word is y0, the value of its trailing word is 0) + approximates sqrt(x) to almost 8-bit. + + Value of T1: + static int T1[32]= { + 0, 1024, 3062, 5746, 9193, 13348, 18162, 23592, + 29598, 36145, 43202, 50740, 58733, 67158, 75992, 85215, + 83599, 71378, 60428, 50647, 41945, 34246, 27478, 21581, + 16499, 12183, 8588, 5674, 3403, 1742, 661, 130,}; + + (2) Iterative refinement + + Apply Heron's rule three times to y, we have y approximates + sqrt(x) to within 1 ulp (Unit in the Last Place): + + y := (y+x/y)/2 ... almost 17 sig. bits + y := (y+x/y)/2 ... almost 35 sig. bits + y := y-(y-x/y)/2 ... within 1 ulp + + + Remark 1. + Another way to improve y to within 1 ulp is: + + y := (y+x/y) ... almost 17 sig. bits to 2*sqrt(x) + y := y - 0x00100006 ... almost 18 sig. bits to sqrt(x) + + 2 + (x-y )*y + y := y + 2* ---------- ...within 1 ulp + 2 + 3y + x + + + This formula has one division fewer than the one above; however, + it requires more multiplications and additions. Also x must be + scaled in advance to avoid spurious overflow in evaluating the + expression 3y*y+x. Hence it is not recommended uless division + is slow. If division is very slow, then one should use the + reciproot algorithm given in section B. + + (3) Final adjustment + + By twiddling y's last bit it is possible to force y to be + correctly rounded according to the prevailing rounding mode + as follows. Let r and i be copies of the rounding mode and + inexact flag before entering the square root program. Also we + use the expression y+-ulp for the next representable floating + numbers (up and down) of y. Note that y+-ulp = either fixed + point y+-1, or multiply y by nextafter(1,+-inf) in chopped + mode. + + I := FALSE; ... reset INEXACT flag I + R := RZ; ... set rounding mode to round-toward-zero + z := x/y; ... chopped quotient, possibly inexact + If(not I) then { ... if the quotient is exact + if(z=y) { + I := i; ... restore inexact flag + R := r; ... restore rounded mode + return sqrt(x):=y. + } else { + z := z - ulp; ... special rounding + } + } + i := TRUE; ... sqrt(x) is inexact + If (r=RN) then z=z+ulp ... rounded-to-nearest + If (r=RP) then { ... round-toward-+inf + y = y+ulp; z=z+ulp; + } + y := y+z; ... chopped sum + y0:=y0-0x00100000; ... y := y/2 is correctly rounded. + I := i; ... restore inexact flag + R := r; ... restore rounded mode + return sqrt(x):=y. + + (4) Special cases + + Square root of +inf, +-0, or NaN is itself; + Square root of a negative number is NaN with invalid signal. + + +B. sqrt(x) by Reciproot Iteration + + (1) Initial approximation + + Let x0 and x1 be the leading and the trailing 32-bit words of + a floating point number x (in IEEE double format) respectively + (see section A). By performing shifs and subtracts on x0 and y0, + we obtain a 7.8-bit approximation of 1/sqrt(x) as follows. + + k := 0x5fe80000 - (x0>>1); + y0:= k - T2[63&(k>>14)]. ... y ~ 1/sqrt(x) to 7.8 bits + + Here k is a 32-bit integer and T2[] is an integer array + containing correction terms. Now magically the floating + value of y (y's leading 32-bit word is y0, the value of + its trailing word y1 is set to zero) approximates 1/sqrt(x) + to almost 7.8-bit. + + Value of T2: + static int T2[64]= { + 0x1500, 0x2ef8, 0x4d67, 0x6b02, 0x87be, 0xa395, 0xbe7a, 0xd866, + 0xf14a, 0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f, + 0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d, + 0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0, + 0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989, + 0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd, + 0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e, + 0x1527f,0x1334a,0x11051,0xe951, 0xbe01, 0x8e0d, 0x5924, 0x1edd,}; + + (2) Iterative refinement + + Apply Reciproot iteration three times to y and multiply the + result by x to get an approximation z that matches sqrt(x) + to about 1 ulp. To be exact, we will have + -1ulp < sqrt(x)-z<1.0625ulp. + + ... set rounding mode to Round-to-nearest + y := y*(1.5-0.5*x*y*y) ... almost 15 sig. bits to 1/sqrt(x) + y := y*((1.5-2^-30)+0.5*x*y*y)... about 29 sig. bits to 1/sqrt(x) + ... special arrangement for better accuracy + z := x*y ... 29 bits to sqrt(x), with z*y<1 + z := z + 0.5*z*(1-z*y) ... about 1 ulp to sqrt(x) + + Remark 2. The constant 1.5-2^-30 is chosen to bias the error so that + (a) the term z*y in the final iteration is always less than 1; + (b) the error in the final result is biased upward so that + -1 ulp < sqrt(x) - z < 1.0625 ulp + instead of |sqrt(x)-z|<1.03125ulp. + + (3) Final adjustment + + By twiddling y's last bit it is possible to force y to be + correctly rounded according to the prevailing rounding mode + as follows. Let r and i be copies of the rounding mode and + inexact flag before entering the square root program. Also we + use the expression y+-ulp for the next representable floating + numbers (up and down) of y. Note that y+-ulp = either fixed + point y+-1, or multiply y by nextafter(1,+-inf) in chopped + mode. + + R := RZ; ... set rounding mode to round-toward-zero + switch(r) { + case RN: ... round-to-nearest + if(x<= z*(z-ulp)...chopped) z = z - ulp; else + if(x<= z*(z+ulp)...chopped) z = z; else z = z+ulp; + break; + case RZ:case RM: ... round-to-zero or round-to--inf + R:=RP; ... reset rounding mod to round-to-+inf + if(x=(z+ulp)*(z+ulp) ...rounded up) z = z+ulp; + break; + case RP: ... round-to-+inf + if(x>(z+ulp)*(z+ulp)...chopped) z = z+2*ulp; else + if(x>z*z ...chopped) z = z+ulp; + break; + } + + Remark 3. The above comparisons can be done in fixed point. For + example, to compare x and w=z*z chopped, it suffices to compare + x1 and w1 (the trailing parts of x and w), regarding them as + two's complement integers. + + ...Is z an exact square root? + To determine whether z is an exact square root of x, let z1 be the + trailing part of z, and also let x0 and x1 be the leading and + trailing parts of x. + + If ((z1&0x03ffffff)!=0) ... not exact if trailing 26 bits of z!=0 + I := 1; ... Raise Inexact flag: z is not exact + else { + j := 1 - [(x0>>20)&1] ... j = logb(x) mod 2 + k := z1 >> 26; ... get z's 25-th and 26-th + fraction bits + I := i or (k&j) or ((k&(j+j+1))!=(x1&3)); + } + R:= r ... restore rounded mode + return sqrt(x):=z. + + If multiplication is cheaper then the foregoing red tape, the + Inexact flag can be evaluated by + + I := i; + I := (z*z!=x) or I. + + Note that z*z can overwrite I; this value must be sensed if it is + True. + + Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be + zero. + + -------------------- + z1: | f2 | + -------------------- + bit 31 bit 0 + + Further more, bit 27 and 26 of z1, bit 0 and 1 of x1, and the odd + or even of logb(x) have the following relations: + + ------------------------------------------------- + bit 27,26 of z1 bit 1,0 of x1 logb(x) + ------------------------------------------------- + 00 00 odd and even + 01 01 even + 10 10 odd + 10 00 even + 11 01 even + ------------------------------------------------- + + (4) Special cases (see (4) of Section A). + + */ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c new file mode 100644 index 000000000..616f4ba9e --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c @@ -0,0 +1,93 @@ + +/* @(#)k_cos.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * __kernel_cos( x, y ) + * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164 + * Input x is assumed to be bounded by ~pi/4 in magnitude. + * Input y is the tail of x. + * + * Algorithm + * 1. Since cos(-x) = cos(x), we need only to consider positive x. + * 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0. + * 3. cos(x) is approximated by a polynomial of degree 14 on + * [0,pi/4] + * 4 14 + * cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x + * where the remez error is + * + * | 2 4 6 8 10 12 14 | -58 + * |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2 + * | | + * + * 4 6 8 10 12 14 + * 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then + * cos(x) = 1 - x*x/2 + r + * since cos(x+y) ~ cos(x) - sin(x)*y + * ~ cos(x) - x*y, + * a correction term is necessary in cos(x) and hence + * cos(x+y) = 1 - (x*x/2 - (r - x*y)) + * For better accuracy when x > 0.3, let qx = |x|/4 with + * the last 32 bits mask off, and if x > 0.78125, let qx = 0.28125. + * Then + * cos(x+y) = (1-qx) - ((x*x/2-qx) - (r-x*y)). + * Note that 1-qx and (x*x/2-qx) is EXACT here, and the + * magnitude of the latter is at least a quarter of x*x/2, + * thus, reducing the rounding error in the subtraction. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif + one + = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ + C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */ + C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */ + C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */ + C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */ + C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */ + C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */ + +#ifdef __STDC__ +double __kernel_cos(double x, double y) +#else +double __kernel_cos(x, y) double x, y; +#endif +{ + double a, hz, z, r, qx; + int ix; + ix = __HI(x) & 0x7fffffff; /* ix = |x|'s high word*/ + if (ix < 0x3e400000) { /* if x < 2**27 */ + if (((int)x) == 0) + return one; /* generate inexact */ + } + z = x * x; + r = z * (C1 + z * (C2 + z * (C3 + z * (C4 + z * (C5 + z * C6))))); + if (ix < 0x3FD33333) /* if |x| < 0.3 */ + return one - (0.5 * z - (z * r - x * y)); + else { + if (ix > 0x3fe90000) { /* x > 0.78125 */ + qx = 0.28125; + } else { + __HI(qx) = ix - 0x00200000; /* x/4 */ + __LO(qx) = 0; + } + hz = 0.5 * z - qx; + a = one - qx; + return a - (hz - (z * r - x * y)); + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c new file mode 100644 index 000000000..ec31cfd8b --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c @@ -0,0 +1,355 @@ + +#ifndef _No_Floating_Point +/* @(#)k_rem_pio2.c 1.2 95/01/04 */ +/* $Id: k_rem_pio2.c,v 1.2.14.1 2002/01/31 15:24:13 ceciliar Exp $ */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2) + * double x[],y[]; int e0,nx,prec; int ipio2[]; + * + * __kernel_rem_pio2 return the last three digits of N with + * y = x - N*pi/2 + * so that |y| < pi/2. + * + * The method is to compute the integer (mod 8) and fraction parts of + * (2/pi)*x without doing the full multiplication. In general we + * skip the part of the product that are known to be a huge integer ( + * more accurately, = 0 mod 8 ). Thus the number of operations are + * independent of the exponent of the input. + * + * (2/pi) is represented by an array of 24-bit integers in ipio2[]. + * + * Input parameters: + * x[] The input value (must be positive) is broken into nx + * pieces of 24-bit integers in double precision format. + * x[i] will be the i-th 24 bit of x. The scaled exponent + * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0 + * match x's up to 24 bits. + * + * Example of breaking a double positive z into x[0]+x[1]+x[2]: + * e0 = ilogb(z)-23 + * z = ldexp(z,-e0) + * for i = 0,1,2 + * x[i] = floor(z) + * z = (z-x[i])*2**24 + * + * + * y[] ouput result in an array of double precision numbers. + * The dimension of y[] is: + * 24-bit precision 1 + * 53-bit precision 2 + * 64-bit precision 2 + * 113-bit precision 3 + * The actual value is the sum of them. Thus for 113-bit + * precison, one may have to do something like: + * + * long double t,w,r_head, r_tail; + * t = (long double)y[2] + (long double)y[1]; + * w = (long double)y[0]; + * r_head = t+w; + * r_tail = w - (r_head - t); + * + * e0 The exponent of x[0] + * + * nx dimension of x[] + * + * prec an integer indicating the precision: + * 0 24 bits (single) + * 1 53 bits (double) + * 2 64 bits (extended) + * 3 113 bits (quad) + * + * ipio2[] + * integer array, contains the (24*i)-th to (24*i+23)-th + * bit of 2/pi after binary point. The corresponding + * floating value is + * + * ipio2[i] * 2^(-24(i+1)). + * + * External function: + * double ldexp(), floor(); + * + * + * Here is the description of some local variables: + * + * jk jk+1 is the initial number of terms of ipio2[] needed + * in the computation. The recommended value is 2,3,4, + * 6 for single, double, extended,and quad. + * + * jz local integer variable indicating the number of + * terms of ipio2[] used. + * + * jx nx - 1 + * + * jv index for pointing to the suitable ipio2[] for the + * computation. In general, we want + * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8 + * is an integer. Thus + * e0-3-24*jv >= 0 or (e0-3)/24 >= jv + * Hence jv = max(0,(e0-3)/24). + * + * jp jp+1 is the number of terms in PIo2[] needed, jp = jk. + * + * q[] double array with integral value, representing the + * 24-bits chunk of the product of x and 2/pi. + * + * q0 the corresponding exponent of q[0]. Note that the + * exponent for q[i] would be q0-24*i. + * + * PIo2[] double precision array, obtained by cutting pi/2 + * into 24 bits chunks. + * + * f[] ipio2[] in floating point + * + * iq[] integer array by breaking up q[] in 24-bits chunk. + * + * fq[] final product of x*(2/pi) in fq[0],..,fq[jk] + * + * ih integer. If >0 it indicates q[] is >= 0.5, hence + * it also indicates the *sign* of the result. + * + */ + +/* + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const int init_jk[] = { 2, 3, 4, 6 }; +/* initial value for jk */ /*- cc 020130 -*/ +#else +static int init_jk[] = { 2, 3, 4, 6 }; /*- cc 020130 -*/ +#endif + +#ifdef __STDC__ +static const double PIo2[] = { +#else +static double PIo2[] = { +#endif + 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */ + 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */ + 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */ + 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */ + 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */ + 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */ + 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */ + 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */ +}; + +#ifdef __STDC__ +static const double +#else +static double +#endif + zero + = 0.0, + one = 1.0, two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ + twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */ + +#ifdef __STDC__ +int __kernel_rem_pio2(double* x, double* y, int e0, int nx, int prec, const int* ipio2) /*- cc 020130 -*/ +#else +int __kernel_rem_pio2(x, y, e0, nx, prec, ipio2) /*- cc 020130 -*/ + double x[], + y[]; +int e0, nx, prec; +int ipio2[]; /*- cc 020130 -*/ +#endif +{ + int jz, jx, jv, jp, jk, carry, n, iq[20], i, j, k, m, q0, ih; /*- cc 020130 -*/ + double z, fw, f[20], fq[20], q[20]; + + /* initialize jk*/ + jk = init_jk[prec]; + jp = jk; + + /* determine jx,jv,q0, note that 3>q0 */ + jx = nx - 1; + jv = (e0 - 3) / 24; + if (jv < 0) + jv = 0; + q0 = e0 - 24 * (jv + 1); + + /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ + j = jv - jx; + m = jx + jk; + for (i = 0; i <= m; i++, j++) + f[i] = (j < 0) ? zero : (double)ipio2[j]; + + /* compute q[0],q[1],...q[jk] */ + for (i = 0; i <= jk; i++) { + for (j = 0, fw = 0.0; j <= jx; j++) + fw += x[j] * f[jx + i - j]; + q[i] = fw; + } + + jz = jk; +recompute: + /* distill q[] into iq[] reversingly */ + for (i = 0, j = jz, z = q[jz]; j > 0; i++, j--) { + fw = (double)((int)(twon24 * z)); /*- cc 020130 -*/ + iq[i] = (int)(z - two24 * fw); /*- cc 020130 -*/ + z = q[j - 1] + fw; + } + + /* compute n */ + z = ldexp(z, q0); /* actual value of z */ + z -= 8.0 * floor(z * 0.125); /* trim off integer >= 8 */ + n = (int)z; /*- cc 020130 -*/ + z -= (double)n; + ih = 0; + if (q0 > 0) { /* need iq[jz-1] to determine n */ + i = (iq[jz - 1] >> (24 - q0)); + n += i; + iq[jz - 1] -= i << (24 - q0); + ih = iq[jz - 1] >> (23 - q0); + } else if (q0 == 0) + ih = iq[jz - 1] >> 23; + else if (z >= 0.5) + ih = 2; + + if (ih > 0) { /* q > 0.5 */ + n += 1; + carry = 0; + for (i = 0; i < jz; i++) { /* compute 1-q */ + j = iq[i]; + if (carry == 0) { + if (j != 0) { + carry = 1; + iq[i] = 0x1000000 - j; + } + } else + iq[i] = 0xffffff - j; + } + if (q0 > 0) { /* rare case: chance is 1 in 12 */ + switch (q0) { + case 1: + iq[jz - 1] &= 0x7fffff; + break; + case 2: + iq[jz - 1] &= 0x3fffff; + break; + } + } + if (ih == 2) { + z = one - z; + if (carry != 0) + z -= ldexp(one, q0); + } + } + + /* check if recomputation is needed */ + if (z == zero) { + j = 0; + for (i = jz - 1; i >= jk; i--) + j |= iq[i]; + if (j == 0) { /* need recomputation */ + for (k = 1; iq[jk - k] == 0; k++) + ; /* k = no. of terms needed */ + + for (i = jz + 1; i <= jz + k; i++) { /* add q[jz+1] to q[jz+k] */ + f[jx + i] = (double)ipio2[jv + i]; + for (j = 0, fw = 0.0; j <= jx; j++) + fw += x[j] * f[jx + i - j]; + q[i] = fw; + } + jz += k; + goto recompute; + } + } + + /* chop off zero terms */ + if (z == 0.0) { + jz -= 1; + q0 -= 24; + while (iq[jz] == 0) { + jz--; + q0 -= 24; + } + } else { /* break z into 24-bit if necessary */ + z = ldexp(z, -q0); + if (z >= two24) { + fw = (double)((int)(twon24 * z)); /*- cc 020130 -*/ + iq[jz] = (int)(z - two24 * fw); /*- cc 020130 -*/ + jz += 1; + q0 += 24; + iq[jz] = (int)fw; /*- cc 020130 -*/ + } else + iq[jz] = (int)z; /*- cc 020130 -*/ + } + + /* convert integer "bit" chunk to floating-point value */ + fw = ldexp(one, q0); + for (i = jz; i >= 0; i--) { + q[i] = fw * (double)iq[i]; + fw *= twon24; + } + + /* compute PIo2[0,...,jp]*q[jz,...,0] */ + for (i = jz; i >= 0; i--) { + for (fw = 0.0, k = 0; k <= jp && k <= jz - i; k++) + fw += PIo2[k] * q[i + k]; + fq[jz - i] = fw; + } + + /* compress fq[] into y[] */ + switch (prec) { + case 0: + fw = 0.0; + for (i = jz; i >= 0; i--) + fw += fq[i]; + y[0] = (ih == 0) ? fw : -fw; + break; + case 1: + case 2: + fw = 0.0; + for (i = jz; i >= 0; i--) + fw += fq[i]; + y[0] = (ih == 0) ? fw : -fw; + fw = fq[0] - fw; + for (i = 1; i <= jz; i++) + fw += fq[i]; + y[1] = (ih == 0) ? fw : -fw; + break; + case 3: /* painful */ + for (i = jz; i > 0; i--) { + fw = fq[i - 1] + fq[i]; + fq[i] += fq[i - 1] - fw; + fq[i - 1] = fw; + } + for (i = jz; i > 1; i--) { + fw = fq[i - 1] + fq[i]; + fq[i] += fq[i - 1] - fw; + fq[i - 1] = fw; + } + for (fw = 0.0, i = jz; i >= 2; i--) + fw += fq[i]; + if (ih == 0) { + y[0] = fq[0]; + y[1] = fq[1]; + y[2] = fw; + } else { + y[0] = -fq[0]; + y[1] = -fq[1]; + y[2] = -fw; + } + } + return n & 7; +} +#endif /* _No_Floating_Point */ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c new file mode 100644 index 000000000..14c628cd3 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_sin.c @@ -0,0 +1,80 @@ + +/* @(#)k_sin.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __kernel_sin( x, y, iy) + * kernel sin function on [-pi/4, pi/4], pi/4 ~ 0.7854 + * Input x is assumed to be bounded by ~pi/4 in magnitude. + * Input y is the tail of x. + * Input iy indicates whether y is 0. (if iy=0, y assume to be 0). + * + * Algorithm + * 1. Since sin(-x) = -sin(x), we need only to consider positive x. + * 2. if x < 2^-27 (hx<0x3e400000 0), return x with inexact if x!=0. + * 3. sin(x) is approximated by a polynomial of degree 13 on + * [0,pi/4] + * 3 13 + * sin(x) ~ x + S1*x + ... + S6*x + * where + * + * |sin(x) 2 4 6 8 10 12 | -58 + * |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2 + * | x | + * + * 4. sin(x+y) = sin(x) + sin'(x')*y + * ~ sin(x) + (1-x*x/2)*y + * For better accuracy, let + * 3 2 2 2 2 + * r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6)))) + * then 3 2 + * sin(x) = x + (S1*x + (x *(r-y/2)+y)) + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif + half + = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ + S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */ + S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */ + S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */ + S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */ + S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */ + S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */ + +#ifdef __STDC__ +double __kernel_sin(double x, double y, int iy) +#else +double __kernel_sin(x, y, iy) double x, y; +int iy; /* iy=0 if y is zero */ +#endif +{ + double z, r, v; + int ix; + ix = __HI(x) & 0x7fffffff; /* high word of x */ + if (ix < 0x3e400000) /* |x| < 2**-27 */ + { + if ((int)x == 0) + return x; + } /* generate inexact */ + z = x * x; + v = z * x; + r = S2 + z * (S3 + z * (S4 + z * (S5 + z * S6))); + if (iy == 0) + return x + v * (S1 + z * r); + else + return x - ((z * (half * y - v * r) - y) - v * S1); +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c new file mode 100644 index 000000000..86dba2f09 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/k_tan.c @@ -0,0 +1,181 @@ +//=========================================================================== +// +// k_tan.c +// +// Part of the standard mathematical function library +// +//=========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jlarmour +// Contributors: jlarmour +// Date: 1998-02-13 +// Purpose: +// Description: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// Derived from code with the following copyright + +/* @(#)k_tan.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __kernel_tan( x, y, k ) + * kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854 + * Input x is assumed to be bounded by ~pi/4 in magnitude. + * Input y is the tail of x. + * Input k indicates whether tan (if k=1) or + * -1/tan (if k= -1) is returned. + * + * Algorithm + * 1. Since tan(-x) = -tan(x), we need only to consider positive x. + * 2. if x < 2^-28 (hx<0x3e300000 0), return x with inexact if x!=0. + * 3. tan(x) is approximated by a odd polynomial of degree 27 on + * [0,0.67434] + * 3 27 + * tan(x) ~ x + T1*x + ... + T13*x + * where + * + * |tan(x) 2 4 26 | -59.2 + * |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2 + * | x | + * + * Note: tan(x+y) = tan(x) + tan'(x)*y + * ~ tan(x) + (1+x*x)*y + * Therefore, for better accuracy in computing tan(x+y), let + * 3 2 2 2 2 + * r = x *(T2+x *(T3+x *(...+x *(T12+x *T13)))) + * then + * 3 2 + * tan(x+y) = x + (T1*x + (x *(r+y)+y)) + * + * 4. For x in [0.67434,pi/4], let y = pi/4 - x, then + * tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y)) + * = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y))) + */ + +#include "fdlibm.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h" +static const double one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ + pio4 = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */ + pio4lo = 3.06161699786838301793e-17, /* 0x3C81A626, 0x33145C07 */ + T[] = { + 3.33333333333334091986e-01, /* 0x3FD55555, 0x55555563 */ + 1.33333333333201242699e-01, /* 0x3FC11111, 0x1110FE7A */ + 5.39682539762260521377e-02, /* 0x3FABA1BA, 0x1BB341FE */ + 2.18694882948595424599e-02, /* 0x3F9664F4, 0x8406D637 */ + 8.86323982359930005737e-03, /* 0x3F8226E3, 0xE96E8493 */ + 3.59207910759131235356e-03, /* 0x3F6D6D22, 0xC9560328 */ + 1.45620945432529025516e-03, /* 0x3F57DBC8, 0xFEE08315 */ + 5.88041240820264096874e-04, /* 0x3F4344D8, 0xF2F26501 */ + 2.46463134818469906812e-04, /* 0x3F3026F7, 0x1A8D1068 */ + 7.81794442939557092300e-05, /* 0x3F147E88, 0xA03792A6 */ + 7.14072491382608190305e-05, /* 0x3F12B80F, 0x32F0A7E9 */ + -1.85586374855275456654e-05, /* 0xBEF375CB, 0xDB605373 */ + 2.59073051863633712884e-05, /* 0x3EFB2A70, 0x74BF7AD4 */ + }; + +double __kernel_tan(double x, double y, int iy) +{ + double z, r, v, w, s; + int ix, hx; + hx = __HI(x); /* high word of x */ + ix = hx & 0x7fffffff; /* high word of |x| */ + if (ix < 0x3e300000) /* x < 2**-28 */ + { + if ((int)x == 0) { /* generate inexact */ + if (((ix | __LO(x)) | (iy + 1)) == 0) { + double ret = fabs(x); + return one / ret; + } else + return (iy == 1) ? x : -one / x; + } + } + if (ix >= 0x3FE59428) { /* |x|>=0.6744 */ + if (hx < 0) { + x = -x; + y = -y; + } + z = pio4 - x; + w = pio4lo - y; + x = z + w; + y = 0.0; + } + z = x * x; + w = z * z; + /* Break x^5*(T[1]+x^2*T[2]+...) into + * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) + + * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12])) + */ + r = T[1] + w * (T[3] + w * (T[5] + w * (T[7] + w * (T[9] + w * T[11])))); + v = z * (T[2] + w * (T[4] + w * (T[6] + w * (T[8] + w * (T[10] + w * T[12]))))); + s = z * x; + r = y + z * (s * (r + v) + y); + r += T[0] * s; + w = x + r; + if (ix >= 0x3FE59428) { + v = (double)iy; + return (double)(1 - ((hx >> 30) & 2)) * (v - 2.0 * (x - (w * w / (w + v) - r))); + } + if (iy == 1) + return w; + else { /* if allow error up to 2 ulp, + simply return -1.0/(x+r) here */ + /* compute -1.0/(x+r) accurately */ + double a, t; + z = w; + __LO(z) = 0; + v = r - (z - x); /* z+v = r+x */ + t = a = -1.0 / w; /* a = -1.0/w */ + __LO(t) = 0; + s = 1.0 + t * z; + return t + a * (s + t * v); + } +} + +// EOF k_tan.c diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c new file mode 100644 index 000000000..f3435bc81 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_atan.c @@ -0,0 +1,143 @@ + +/* @(#)s_atan.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* atan(x) + * Method + * 1. Reduce x to positive by atan(x) = -atan(-x). + * 2. According to the integer k=4t+0.25 chopped, t=x, the argument + * is further reduced to one of the following intervals and the + * arctangent of t is evaluated by the corresponding formula: + * + * [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...) + * [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) ) + * [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) ) + * [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) ) + * [39/16,INF] atan(x) = atan(INF) + atan( -1/t ) + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double atanhi[] = { +#else +static double atanhi[] = { +#endif + 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */ + 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */ + 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */ + 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */ +}; + +#ifdef __STDC__ +static const double atanlo[] = { +#else +static double atanlo[] = { +#endif + 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */ + 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */ + 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */ + 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */ +}; + +#ifdef __STDC__ +static const double aT[] = { +#else +static double aT[] = { +#endif + 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */ + -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */ + 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */ + -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */ + 9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */ + -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */ + 6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */ + -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */ + 4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */ + -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */ + 1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */ +}; + +#ifdef __STDC__ +static const double +#else +static double +#endif + one + = 1.0, + huge = 1.0e300; + +#ifdef __STDC__ +double atan(double x) +#else +double atan(x) double x; +#endif +{ + double w, s1, s2, z; + int ix, hx, id; + + hx = __HI(x); + ix = hx & 0x7fffffff; + if (ix >= 0x44100000) { /* if |x| >= 2^66 */ + if (ix > 0x7ff00000 || (ix == 0x7ff00000 && (__LO(x) != 0))) + return x + x; /* NaN */ + if (hx > 0) + return atanhi[3] + atanlo[3]; + else + return -atanhi[3] - atanlo[3]; + } + if (ix < 0x3fdc0000) { /* |x| < 0.4375 */ + if (ix < 0x3e200000) { /* |x| < 2^-29 */ + if (huge + x > one) + return x; /* raise inexact */ + } + id = -1; + } else { + x = __fabs(x); + if (ix < 0x3ff30000) { /* |x| < 1.1875 */ + if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */ + id = 0; + x = (2.0 * x - one) / (2.0 + x); + } else { /* 11/16<=|x|< 19/16 */ + id = 1; + x = (x - one) / (x + one); + } + } else { + if (ix < 0x40038000) { /* |x| < 2.4375 */ + id = 2; + x = (x - 1.5) / (one + 1.5 * x); + } else { /* 2.4375 <= |x| < 2^66 */ + id = 3; + x = -1.0 / x; + } + } + } + /* end of argument reduction */ + z = x * x; + w = z * z; + /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ + s1 = z * (aT[0] + w * (aT[2] + w * (aT[4] + w * (aT[6] + w * (aT[8] + w * aT[10]))))); + s2 = w * (aT[1] + w * (aT[3] + w * (aT[5] + w * (aT[7] + w * aT[9])))); + if (id < 0) + return x - x * (s1 + s2); + else { + z = atanhi[id] - ((x * (s1 + s2) - atanlo[id]) - x); + return (hx < 0) ? -z : z; + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c new file mode 100644 index 000000000..08f180a42 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ceil.c @@ -0,0 +1,90 @@ + +/* @(#)s_ceil.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * ceil(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to ceil(x). + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double huge = 1.0e300; +#else +static double huge = 1.0e300; +#endif + +#ifdef __STDC__ +double ceil(double x) +#else +double ceil(x) double x; +#endif +{ + int i0, i1, j0; + unsigned i, j; + i0 = __HI(x); + i1 = __LO(x); + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; + if (j0 < 20) { + if (j0 < 0) { /* raise inexact if x != 0 */ + if (huge + x > 0.0) { /* return 0*sign(x) if |x|<1 */ + if (i0 < 0) { + i0 = 0x80000000; + i1 = 0; + } else if ((i0 | i1) != 0) { + i0 = 0x3ff00000; + i1 = 0; + } + } + } else { + i = (0x000fffff) >> j0; + if (((i0 & i) | i1) == 0) + return x; /* x is integral */ + if (huge + x > 0.0) { /* raise inexact flag */ + if (i0 > 0) + i0 += (0x00100000) >> j0; + i0 &= (~i); + i1 = 0; + } + } + } else if (j0 > 51) { + if (j0 == 0x400) + return x + x; /* inf or NaN */ + else + return x; /* x is integral */ + } else { + i = ((unsigned)(0xffffffff)) >> (j0 - 20); + if ((i1 & i) == 0) + return x; /* x is integral */ + if (huge + x > 0.0) { /* raise inexact flag */ + if (i0 > 0) { + if (j0 == 20) + i0 += 1; + else { + j = i1 + (1 << (52 - j0)); + if (j < i1) + i0 += 1; /* got a carry */ + i1 = j; + } + } + i1 &= (~i); + } + } + __HI(x) = i0; + __LO(x) = i1; + return x; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c new file mode 100644 index 000000000..8476b36e1 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_copysign.c @@ -0,0 +1,30 @@ + +/* @(#)s_copysign.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * copysign(double x, double y) + * copysign(x,y) returns a value with the magnitude of x and + * with the sign bit of y. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +double copysign(double x, double y) +#else +double copysign(x, y) double x, y; +#endif +{ + __HI(x) = (__HI(x) & 0x7fffffff) | (__HI(y) & 0x80000000); + return x; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c new file mode 100644 index 000000000..f1b3111d9 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_cos.c @@ -0,0 +1,82 @@ + +/* @(#)s_cos.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* cos(x) + * Return cosine function of x. + * + * kernel function: + * __kernel_sin ... sine function on [-pi/4,pi/4] + * __kernel_cos ... cosine function on [-pi/4,pi/4] + * __ieee754_rem_pio2 ... argument reduction routine + * + * Method. + * Let S,C and T denote the sin, cos and tan respectively on + * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 + * in [-pi/4 , +pi/4], and let n = k mod 4. + * We have + * + * n sin(x) cos(x) tan(x) + * ---------------------------------------------------------- + * 0 S C T + * 1 C -S -1/T + * 2 -S -C T + * 3 -C S -1/T + * ---------------------------------------------------------- + * + * Special cases: + * Let trig be any of sin, cos, or tan. + * trig(+-INF) is NaN, with signals; + * trig(NaN) is that NaN; + * + * Accuracy: + * TRIG(x) returns trig(x) nearly rounded + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +double cos(double x) +#else +double cos(x) double x; +#endif +{ + double y[2], z = 0.0; + int n, ix; + + /* High word of x. */ + ix = __HI(x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if (ix <= 0x3fe921fb) + return __kernel_cos(x, z); + + /* cos(Inf or NaN) is NaN */ + else if (ix >= 0x7ff00000) + return x - x; + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2(x, y); + switch (n & 3) { + case 0: + return __kernel_cos(y[0], y[1]); + case 1: + return -__kernel_sin(y[0], y[1], 1); + case 2: + return -__kernel_cos(y[0], y[1]); + default: + return __kernel_sin(y[0], y[1], 1); + } + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c new file mode 100644 index 000000000..b0198e3b3 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_floor.c @@ -0,0 +1,89 @@ + +/* @(#)s_floor.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * floor(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to floor(x). + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double huge = 1.0e300; +#else +static double huge = 1.0e300; +#endif + +#ifdef __STDC__ +double floor(double x) +#else +double floor(x) double x; +#endif +{ + int i0, i1, j0; + unsigned i, j; + i0 = __HI(x); + i1 = __LO(x); + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; + if (j0 < 20) { + if (j0 < 0) { /* raise inexact if x != 0 */ + if (huge + x > 0.0) { /* return 0*sign(x) if |x|<1 */ + if (i0 >= 0) { + i0 = i1 = 0; + } else if (((i0 & 0x7fffffff) | i1) != 0) { + i0 = 0xbff00000; + i1 = 0; + } + } + } else { + i = (0x000fffff) >> j0; + if (((i0 & i) | i1) == 0) + return x; /* x is integral */ + if (huge + x > 0.0) { /* raise inexact flag */ + if (i0 < 0) + i0 += (0x00100000) >> j0; + i0 &= (~i); + i1 = 0; + } + } + } else if (j0 > 51) { + if (j0 == 0x400) + return x + x; /* inf or NaN */ + else + return x; /* x is integral */ + } else { + i = ((unsigned)(0xffffffff)) >> (j0 - 20); + if ((i1 & i) == 0) + return x; /* x is integral */ + if (huge + x > 0.0) { /* raise inexact flag */ + if (i0 < 0) { + if (j0 == 20) + i0 += 1; + else { + j = i1 + (1 << (52 - j0)); + if (j < i1) + i0 += 1; /* got a carry */ + i1 = j; + } + } + i1 &= (~i); + } + } + __HI(x) = i0; + __LO(x) = i1; + return x; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c new file mode 100644 index 000000000..c91b7d9ea --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_frexp.c @@ -0,0 +1,58 @@ + +/* @(#)s_frexp.c 1.4 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * for non-zero x + * x = frexp(arg,&exp); + * return a double fp quantity x such that 0.5 <= |x| <1.0 + * and the corresponding binary exponent "exp". That is + * arg = x*2^exp. + * If arg is inf, 0.0, or NaN, then frexp(arg,&exp) returns arg + * with *exp=0. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif + two54 + = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */ + +#ifdef __STDC__ +double frexp(double x, int* eptr) +#else +double frexp(x, eptr) double x; +int* eptr; +#endif +{ + int hx, ix, lx; + hx = __HI(x); + ix = 0x7fffffff & hx; + lx = __LO(x); + *eptr = 0; + if (ix >= 0x7ff00000 || ((ix | lx) == 0)) + return x; /* 0,inf,nan */ + if (ix < 0x00100000) { /* subnormal */ + x *= two54; + hx = __HI(x); + ix = hx & 0x7fffffff; + *eptr = -54; + } + *eptr += (ix >> 20) - 1022; + hx = (hx & 0x800fffff) | 0x3fe00000; + __HI(x) = hx; + return x; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c new file mode 100644 index 000000000..74609e3fd --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_ldexp.c @@ -0,0 +1,63 @@ +#ifndef _No_Floating_Point +/* @(#)s_ldexp.c 1.2 95/01/04 */ +/* $Id: s_ldexp.c,v 1.3.14.1 2002/01/31 15:24:14 ceciliar Exp $ */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h" /* for isfinite macro */ +static const double + + two54 + = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ + twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ + big = 1.0e+300, tiny = 1.0e-300; + +double ldexp(double x, int n) +{ + s32 k, hx, lx; /*- cc 020130 -*/ + if (!isfinite(x) || x == 0.0) + return x; + + hx = __HI(x); + lx = __LO(x); + k = (hx & 0x7ff00000) >> 20; /* extract exponent */ + if (k == 0) { /* 0 or subnormal x */ + if ((lx | (hx & 0x7fffffff)) == 0) + return x; /* +-0 */ + x *= two54; + hx = __HI(x); + k = ((hx & 0x7ff00000) >> 20) - 54; + if (n < -50000) + return tiny * x; /*underflow*/ + } + if (k == 0x7ff) + return x + x; /* NaN or Inf */ + k = k + n; + if (k > 0x7fe) + return big * copysign(big, x); /* overflow */ + if (k > 0) /* normal result */ + { + __HI(x) = (hx & 0x800fffff) | (k << 20); + return x; + } + if (k <= -54) + if (n > 50000) /* in case integer overflow in n+k */ + return big * copysign(big, x); /*overflow*/ + else + return tiny * copysign(tiny, x); /*underflow*/ + k += 54; /* subnormal result */ + __HI(x) = (hx & 0x800fffff) | (k << 20); + return x * twom54; +} + +/* changed __finite to __isfinite to match new naming convention 141097 bds */ +#endif /* _No_Floating_Point */ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c new file mode 100644 index 000000000..0c4e40137 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c @@ -0,0 +1,79 @@ + +/* @(#)s_modf.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * modf(double x, double *iptr) + * return fraction part of x, and return x's integral part in *iptr. + * Method: + * Bit twiddling. + * + * Exception: + * No exception. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double one = 1.0; +#else +static double one = 1.0; +#endif + +#ifdef __STDC__ +double modf(double x, double* iptr) +#else +double modf(x, iptr) double x, *iptr; +#endif +{ + int i0, i1, j0; + unsigned i; + i0 = __HI(x); /* high x */ + i1 = __LO(x); /* low x */ + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; /* exponent of x */ + if (j0 < 20) { /* integer part in high x */ + if (j0 < 0) { /* |x|<1 */ + __HIp(iptr) = i0 & 0x80000000; + __LOp(iptr) = 0; /* *iptr = +-0 */ + return x; + } else { + i = (0x000fffff) >> j0; + if (((i0 & i) | i1) == 0) { /* x is integral */ + *iptr = x; + __HI(x) &= 0x80000000; + __LO(x) = 0; /* return +-0 */ + return x; + } else { + __HIp(iptr) = i0 & (~i); + __LOp(iptr) = 0; + return x - *iptr; + } + } + } else if (j0 > 51) { /* no fraction part */ + *iptr = x * one; + __HI(x) &= 0x80000000; + __LO(x) = 0; /* return +-0 */ + return x; + } else { /* fraction part in low x */ + i = ((unsigned)(0xffffffff)) >> (j0 - 20); + if ((i1 & i) == 0) { /* x is integral */ + *iptr = x; + __HI(x) &= 0x80000000; + __LO(x) = 0; /* return +-0 */ + return x; + } else { + __HIp(iptr) = i0; + __LOp(iptr) = i1 & (~i); + return x - *iptr; + } + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c new file mode 100644 index 000000000..af4273ad2 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c @@ -0,0 +1,82 @@ + +/* @(#)s_sin.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* sin(x) + * Return sine function of x. + * + * kernel function: + * __kernel_sin ... sine function on [-pi/4,pi/4] + * __kernel_cos ... cose function on [-pi/4,pi/4] + * __ieee754_rem_pio2 ... argument reduction routine + * + * Method. + * Let S,C and T denote the sin, cos and tan respectively on + * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 + * in [-pi/4 , +pi/4], and let n = k mod 4. + * We have + * + * n sin(x) cos(x) tan(x) + * ---------------------------------------------------------- + * 0 S C T + * 1 C -S -1/T + * 2 -S -C T + * 3 -C S -1/T + * ---------------------------------------------------------- + * + * Special cases: + * Let trig be any of sin, cos, or tan. + * trig(+-INF) is NaN, with signals; + * trig(NaN) is that NaN; + * + * Accuracy: + * TRIG(x) returns trig(x) nearly rounded + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +double sin(double x) +#else +double sin(x) double x; +#endif +{ + double y[2], z = 0.0; + int n, ix; + + /* High word of x. */ + ix = __HI(x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if (ix <= 0x3fe921fb) + return __kernel_sin(x, z, 0); + + /* sin(Inf or NaN) is NaN */ + else if (ix >= 0x7ff00000) + return x - x; + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2(x, y); + switch (n & 3) { + case 0: + return __kernel_sin(y[0], y[1], 1); + case 1: + return __kernel_cos(y[0], y[1]); + case 2: + return -__kernel_sin(y[0], y[1], 1); + default: + return -__kernel_cos(y[0], y[1]); + } + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c new file mode 100644 index 000000000..a2feba55f --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c @@ -0,0 +1,73 @@ + +/* @(#)s_tan.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* tan(x) + * Return tangent function of x. + * + * kernel function: + * __kernel_tan ... tangent function on [-pi/4,pi/4] + * __ieee754_rem_pio2 ... argument reduction routine + * + * Method. + * Let S,C and T denote the sin, cos and tan respectively on + * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 + * in [-pi/4 , +pi/4], and let n = k mod 4. + * We have + * + * n sin(x) cos(x) tan(x) + * ---------------------------------------------------------- + * 0 S C T + * 1 C -S -1/T + * 2 -S -C T + * 3 -C S -1/T + * ---------------------------------------------------------- + * + * Special cases: + * Let trig be any of sin, cos, or tan. + * trig(+-INF) is NaN, with signals; + * trig(NaN) is that NaN; + * + * Accuracy: + * TRIG(x) returns trig(x) nearly rounded + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +double tan(double x) +#else +double tan(x) double x; +#endif +{ + double y[2], z = 0.0; + int n, ix; + + /* High word of x. */ + ix = __HI(x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if (ix <= 0x3fe921fb) + return __kernel_tan(x, z, 1); + + /* tan(Inf or NaN) is NaN */ + else if (ix >= 0x7ff00000) + return x - x; /* NaN */ + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2(x, y); + return __kernel_tan(y[0], y[1], 1 - ((n & 1) << 1)); /* 1 -- n even + -1 -- n odd */ + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c new file mode 100644 index 000000000..7f229356d --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c @@ -0,0 +1,15 @@ +extern double __ieee754_asin(); + +double asin(double __x) { return (double)__ieee754_asin(); } + +/* +.loc_0x0: + stwu r1, -0x10(r1) + mflr r0 + stw r0, 0x14(r1) + bl -0x35C8 + lwz r0, 0x14(r1) + mtlr r0 + addi r1, r1, 0x10 + blr +*/ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c new file mode 100644 index 000000000..b87b4a81d --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c @@ -0,0 +1,15 @@ +extern double __ieee754_atan2(); + +double atan2(double __x, double __y) { return (double)__ieee754_atan2(); } + +/* +.loc_0x0: + stwu r1, -0x10(r1) + mflr r0 + stw r0, 0x14(r1) + bl -0x33B0 + lwz r0, 0x14(r1) + mtlr r0 + addi r1, r1, 0x10 + blr +*/ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c new file mode 100644 index 000000000..bfd7e50f9 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c @@ -0,0 +1,15 @@ +extern double __ieee754_exp(); + +double exp(double __x) { return (double)__ieee754_exp(); } + +/* +.loc_0x0: + stwu r1, -0x10(r1) + mflr r0 + stw r0, 0x14(r1) + bl -0x3140 + lwz r0, 0x14(r1) + mtlr r0 + addi r1, r1, 0x10 + blr +*/ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c new file mode 100644 index 000000000..c51a18dc2 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c @@ -0,0 +1,15 @@ +extern double __ieee754_fmod(); + +double fmod(double __x, double __y) { return (double)__ieee754_fmod(); } + +/* +.loc_0x0: + stwu r1, -0x10(r1) + mflr r0 + stw r0, 0x14(r1) + bl -0x2F3C + lwz r0, 0x14(r1) + mtlr r0 + addi r1, r1, 0x10 + blr +*/ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log10.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log10.c new file mode 100644 index 000000000..62495bbd1 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log10.c @@ -0,0 +1,15 @@ +extern double __ieee754_log10(); + +double log10(double __x) { return (double)__ieee754_log10(); } + +/* +.loc_0x0: + stwu r1, -0x10(r1) + mflr r0 + stw r0, 0x14(r1) + bl -0x29A4 + lwz r0, 0x14(r1) + mtlr r0 + addi r1, r1, 0x10 + blr +*/ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c new file mode 100644 index 000000000..4454adb97 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c @@ -0,0 +1,15 @@ +extern double __ieee754_pow(); + +double pow(double __x, double __y) { return (double)__ieee754_pow(); } + +/* +.loc_0x0: + stwu r1, -0x10(r1) + mflr r0 + stw r0, 0x14(r1) + bl -0x28B4 + lwz r0, 0x14(r1) + mtlr r0 + addi r1, r1, 0x10 + blr +*/ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_sqrt.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_sqrt.c new file mode 100644 index 000000000..909f7cb51 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_sqrt.c @@ -0,0 +1,15 @@ +extern double __ieee754_sqrt(); + +double sqrt(double __x) { return (double)__ieee754_sqrt(); } + +/* +.loc_0x0: + stwu r1, -0x10(r1) + mflr r0 + stw r0, 0x14(r1) + bl -0x29C + lwz r0, 0x14(r1) + mtlr r0 + addi r1, r1, 0x10 + blr +*/ diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/ansi_fp.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/ansi_fp.c new file mode 100644 index 000000000..1cb1d9c57 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/ansi_fp.c @@ -0,0 +1,779 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_fp.h" +#include "ctype.h" +#include "limits.h" + +static int __count_trailing_zerol(unsigned long x) +{ + int result = 0; + int bits_not_checked = sizeof(unsigned long) * CHAR_BIT; + int n = bits_not_checked / 2; + int mask_size = n; + unsigned long mask = (~0UL) >> (bits_not_checked - n); + + while (bits_not_checked) { + if (!(x & mask)) { + result += mask_size; + x >>= mask_size; + bits_not_checked -= mask_size; + } else if (mask == 1) { + break; + } + + if (n > 1) { + n /= 2; + } + + if (mask > 1) { + mask >>= n; + mask_size -= n; + } + } + return result; +} + +static int __count_trailing_zero(double x) +{ + unsigned long* l = (unsigned long*)&x; + + if (l[1] != 0) { + return __count_trailing_zerol(l[1]); + } + + return (int)(sizeof(unsigned long) * CHAR_BIT + __count_trailing_zerol(l[0] | 0x00100000)); +} + +static int __must_round(const decimal* d, int digits) +{ + u8 const* i = d->sig.text + digits; + + if (*i > 5) { + return 1; + } + + if (*i < 5) { + return -1; + } + + { + u8 const* e = d->sig.text + d->sig.length; + + for (i++; i < e; i++) { + if (*i != 0) { + return 1; + } + } + } + + if (d->sig.text[digits - 1] & 1) { + return 1; + } + + return -1; +} + +static void __dorounddecup(decimal* d, int digits) +{ + u8* b = d->sig.text; + u8* i = b + digits - 1; + + while (1) { + if (*i < 9) { + *i += 1; + break; + } + if (i == b) { + *i = 1; + d->exp++; + break; + } + *i-- = 0; + } +} + +static void __rounddec(decimal* d, int digits) +{ + int unkBool; + if (digits <= 0 || digits >= d->sig.length) + return; + + unkBool = __must_round(d, digits); + d->sig.length = digits; + + if (unkBool >= 0) { + __dorounddecup(d, digits); + } + + +} + +void __ull2dec(decimal* result, u64 val) +{ + result->sign = 0; + + if (val == 0) { + result->exp = 0; + result->sig.length = 1; + result->sig.text[0] = 0; + return; + } + + if (val < 0) { + val = -val; + result->sign = 1; + } + + result->sig.length = 0; + + for (; val != 0; val /= 10) { + result->sig.text[result->sig.length++] = (u8)(val % 10); + } + + { + u8* i = result->sig.text; + u8* j = result->sig.text + result->sig.length; + + for (; i < --j; ++i) { + u8 t = *i; + *i = *j; + *j = t; + } + } + + result->exp = result->sig.length - 1; +} + +void __timesdec(decimal* result, const decimal* x, const decimal* y) +{ + u32 accumulator = 0; + u8 mantissa[SIGDIGLEN * 2]; + int i = x->sig.length + y->sig.length - 1; + u8* pDigit; + u8* ip = mantissa + i + 1; + u8* ep = ip; + + result->sign = 0; + + for (; i > 0; i--) { + int k = y->sig.length - 1; + int j = i - k - 1; + int l; + int t; + const u8* jp; + const u8* kp; + + if (j < 0) { + j = 0; + k = i - 1; + } + + jp = x->sig.text + j; + kp = y->sig.text + k; + l = k + 1; + t = x->sig.length - j; + + if (l > t) + l = t; + + for (; l > 0; --l, ++jp, --kp) { + accumulator += *jp * *kp; + } + + *--ip = (u8)(accumulator % 10); + accumulator /= 10; + } + + result->exp = (short)(x->exp + y->exp); + + if (accumulator) { + *--ip = (u8)(accumulator); + result->exp++; + } + + for (i = 0; i < SIGDIGLEN && ip < ep; ++i, ++ip) { + result->sig.text[i] = *ip; + } + result->sig.length = (u8)(i); + + if (ip < ep && *ip >= 5) { + if (*ip == 5) { + u8* jp = ip + 1; + for (; jp < ep; jp++) { + if (*jp != 0) + goto round; + } + if ((ip[-1] & 1) == 0) + return; + } + round: + __dorounddecup(result, result->sig.length); + } +} + +void __str2dec(decimal* d, const char* s, short exp) +{ + int i; + + d->exp = exp; + d->sign = 0; + + for (i = 0; i < SIGDIGLEN && *s;) { + d->sig.text[i++] = *s++ - '0'; + } + d->sig.length = i; + + if (*s != 0) { + if (*s < 5) + return; + if (*s > 5) + goto round; + + { + const char* p = s + 1; + + for (; *p != 0; p++) { + if (*p != '0') + goto round; + } + + if ((d->sig.text[i - 1] & 1) == 0) + return; + } + round: + __dorounddecup(d, d->sig.length); + } +} + +void __two_exp(decimal* result, long exp) +{ + switch (exp) { + case -64: + __str2dec(result, "542101086242752217003726400434970855712890625", -20); + return; + case -53: + __str2dec(result, "11102230246251565404236316680908203125", -16); + return; + case -32: + __str2dec(result, "23283064365386962890625", -10); + return; + case -16: + __str2dec(result, "152587890625", -5); + return; + case -8: + __str2dec(result, "390625", -3); + return; + case -7: + __str2dec(result, "78125", -3); + return; + case -6: + __str2dec(result, "15625", -2); + return; + case -5: + __str2dec(result, "3125", -2); + return; + case -4: + __str2dec(result, "625", -2); + return; + case -3: + __str2dec(result, "125", -1); + return; + case -2: + __str2dec(result, "25", -1); + return; + case -1: + __str2dec(result, "5", -1); + return; + case 0: + __str2dec(result, "1", 0); + return; + case 1: + __str2dec(result, "2", 0); + return; + case 2: + __str2dec(result, "4", 0); + return; + case 3: + __str2dec(result, "8", 0); + return; + case 4: + __str2dec(result, "16", 1); + return; + case 5: + __str2dec(result, "32", 1); + return; + case 6: + __str2dec(result, "64", 1); + return; + case 7: + __str2dec(result, "128", 2); + return; + case 8: + __str2dec(result, "256", 2); + return; + } + + { + decimal x2, temp; + + __two_exp(&x2, exp / 2); + __timesdec(result, &x2, &x2); + + if (exp & 1) { + temp = *result; + if (exp > 0) { + __str2dec(&x2, "2", 0); + } else { + __str2dec(&x2, "5", -1); + } + __timesdec(result, &temp, &x2); + } + } +} + +BOOL __equals_dec(const decimal* x, const decimal* y) +{ + if (x->sig.text[0] == 0) { + if (y->sig.text[0] == 0) + return TRUE; + return FALSE; + } + if (y->sig.text[0] == 0) { + if (x->sig.text[0] == 0) + return TRUE; + return FALSE; + } + + if (x->exp == y->exp) { + int i; + int l = x->sig.length; + + if (l > y->sig.length) { + l = y->sig.length; + } + + for (i = 0; i < l; i++) { + if (x->sig.text[i] != y->sig.text[i]) { + return FALSE; + } + } + + if (l == x->sig.length) { + for (; i < y->sig.length; ++i) { + if (y->sig.text[i] != 0) { + return FALSE; + } + } + } else { + for (; i < x->sig.length; ++i) { + if (x->sig.text[i] != 0) { + return FALSE; + } + } + } + + return TRUE; + } + return FALSE; +} + +BOOL __less_dec(const decimal* x, const decimal* y) +{ + if (x->sig.text[0] == 0) { + if (y->sig.text[0] != 0) + return TRUE; + return FALSE; + } + + if (y->sig.text[0] == 0) { + return FALSE; + } + + if (x->exp == y->exp) { + int i; + int l = x->sig.length; + + if (l > y->sig.length) { + l = y->sig.length; + } + + for (i = 0; i < l; i++) { + if (x->sig.text[i] < y->sig.text[i]) { + return TRUE; + } else if (y->sig.text[i] < x->sig.text[i]) { + return FALSE; + } + } + + if (l == x->sig.length) { + for (; i < y->sig.length; i++) { + if (y->sig.text[i] != 0) { + return TRUE; + } + } + } + return FALSE; + } + + return x->exp < y->exp; +} + +void __minus_dec(decimal* z, const decimal* x, const decimal* y) +{ + int zlen, dexp; + u8 *ib, *i, *ie; + u8 const *jb, *j, *jn; + + *z = *x; + + if (y->sig.text[0] == 0) + return; + + zlen = z->sig.length; + if (zlen < y->sig.length) + zlen = y->sig.length; + + dexp = z->exp - y->exp; + zlen += dexp; + + if (zlen > SIGDIGLEN) + zlen = SIGDIGLEN; + + while (z->sig.length < zlen) { + z->sig.text[z->sig.length++] = 0; + } + + ib = z->sig.text; + i = ib + zlen; + + if (y->sig.length + dexp < zlen) { + i = ib + (y->sig.length + dexp); + } + + jb = y->sig.text; + j = jb + (i - ib - dexp); + jn = j; + + while (i > ib && j > jb) { + i--; + j--; + if (*i < *j) { + u8* k = i - 1; + while (*k == 0) + k--; + while (k != i) { + --*k; + *++k += 10; + } + } + *i -= *j; + } + + if (jn - jb < y->sig.length) { + BOOL round_down = FALSE; + if (*jn < 5) + round_down = TRUE; + else if (*jn == 5) { + u8 const* ibPtr = y->sig.text + y->sig.length; + + for (j = jn + 1; j < ibPtr; j++) { + if (*j != 0) + goto done; + } + i = ib + (jn - jb) + dexp - 1; + if (*i & 1) + round_down = 1; + } + if (round_down) { + if (*i < 1) { + u8* k = i - 1; + while (*k == 0) + k--; + while (k != i) { + --*k; + *++k += 10; + } + } + *i -= 1; + } + } +done: + for (i = ib; *i == 0; ++i) { } + + if (i > ib) { + u8 dl = (u8)(i - ib); + z->exp -= dl; + ie = ib + z->sig.length; + for (; i < ie; ++i, ++ib) + *ib = *i; + z->sig.length -= dl; + } + + ib = z->sig.text; + for (i = ib + z->sig.length; i > ib;) { + i--; + if (*i != 0) + break; + } + z->sig.length = (u8)(i - ib + 1); +} + +void __num2dec_internal(decimal* d, double x) +{ + s8 sign = (s8)(signbit(x) != 0); + + if (x == 0) { + d->sign = sign; + d->exp = 0; + d->sig.length = 1; + d->sig.text[0] = 0; + return; + } + + if (!isfinite(x)) { + d->sign = sign; + d->exp = 0; + d->sig.length = 1; + d->sig.text[0] = fpclassify(x) == 1 ? 'N' : 'I'; + return; + } + + if (sign != 0) { + x = -x; + } + + { + int exp; + double frac = frexp(x, &exp); + long num_bits_extract = DBL_MANT_DIG - __count_trailing_zero(frac); + double integer; + decimal int_d, pow2_d; + + __two_exp(&pow2_d, exp - num_bits_extract); + frac = modf(ldexp(frac, num_bits_extract), &integer); + __ull2dec(&int_d, (u64)integer); + __timesdec(d, &int_d, &pow2_d); + d->sign = sign; + } +} + +void __num2dec(const decform* form, double x, decimal* d) +{ + short digits = form->digits; + int i; + __num2dec_internal(d, x); + + if (d->sig.text[0] > 9) { + return; + } + + if (digits > SIGDIGLEN) { + digits = SIGDIGLEN; + } + + __rounddec(d, digits); + + while (d->sig.length < digits) { + d->sig.text[d->sig.length++] = 0; + } + + d->exp -= d->sig.length - 1; + + for (i = 0; i < d->sig.length; i++) { + d->sig.text[i] += '0'; + } +} + +double __dec2num(const decimal* d) +{ + if (d->sig.length <= 0) { + return copysign(0.0, d->sign == 0 ? 1.0 : -1.0); + } + + switch (d->sig.text[0]) { + case '0': + return copysign(0.0, d->sign == 0 ? 1.0 : -1.0); + case 'I': + return copysign((double)INFINITY, d->sign == 0 ? 1.0 : -1.0); + case 'N': { + double result; + u64* ll = (u64*)&result; + + *ll = 0x7FF0000000000000; + if (d->sign) + *ll |= 0x8000000000000000; + + if (d->sig.length == 1) + *ll |= 0x8000000000000; + else { + unsigned char* p = (unsigned char*)&result + 1; + int placed_non_zero = 0; + int low = 1; + int i; + int e = d->sig.length; + if (e > 14) + e = 14; + + for (i = 1; i < e; ++i) { + unsigned char c = d->sig.text[i]; + + if (isdigit(c)) { + c -= '0'; + } else { + c = (unsigned char)(tolower(c) - 'a' + 10); + } + + if (c != 0) { + placed_non_zero = 1; + } + + if (low) { + *p++ |= c; + } else { + *p = (unsigned char)(c << 4); + } + + low = !low; + } + + if (!placed_non_zero) { + *ll |= 0x0008000000000000; + } + } + + return result; + } + } + + { + static double pow_10[8] = { 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8 }; + + decimal dec = *d; + u8* i = dec.sig.text; + u8* e = i + dec.sig.length; + double first_guess; + int exponent; + + for (; i < e; ++i) + *i -= '0'; + dec.exp += dec.sig.length - 1; + exponent = dec.exp; + + i = dec.sig.text; + first_guess = *i++; + + while (i < e) { + u32 ival = 0; + int j; + double temp1, temp2; + int ndig = (int)(e - i) % 8; + + if (ndig == 0) + ndig = 8; + + for (j = 0; j < ndig; ++j, ++i) { + ival = ival * 10 + *i; + } + + temp1 = first_guess * pow_10[ndig - 1]; + temp2 = temp1 + ival; + + if (ival != 0 && temp1 == temp2) + break; + + first_guess = temp2; + exponent -= ndig; + } + + if (exponent < 0) { + first_guess /= pow(5.0, -exponent); + } else { + first_guess *= pow(5.0, exponent); + } + + first_guess = ldexp(first_guess, exponent); + + if (isinf(first_guess)) { + decimal max; + __str2dec(&max, "179769313486231580793729011405303420", 308); + if (__less_dec(&max, &dec)) + goto done; + first_guess = DBL_MAX; + } + + { + decimal feedback1; + + __num2dec_internal(&feedback1, first_guess); + + if (__equals_dec(&feedback1, &dec)) { + goto done; + } + + if (__less_dec(&feedback1, &dec)) { + + decimal feedback2, difflow, diffhigh; + double next_guess = first_guess; + u64* ull = (u64*)&next_guess; + ++*ull; + + if (isinf(next_guess)) { + first_guess = next_guess; + goto done; + } + + __num2dec_internal(&feedback2, next_guess); + + while (__less_dec(&feedback2, &dec)) { + feedback1 = feedback2; + first_guess = next_guess; + ++*ull; + if (isinf(next_guess)) { + first_guess = next_guess; + goto done; + } + __num2dec_internal(&feedback2, next_guess); + } + + __minus_dec(&difflow, &dec, &feedback1); + __minus_dec(&diffhigh, &feedback2, &dec); + + if (__equals_dec(&difflow, &diffhigh)) { + if (*(u64*)&first_guess & 1) { + first_guess = next_guess; + } + } else if (!__less_dec(&difflow, &diffhigh)) { + first_guess = next_guess; + } + } else { + decimal feedback2, difflow, diffhigh; + double next_guess = first_guess; + unsigned long long* ull = (unsigned long long*)&next_guess; + --*ull; + + __num2dec_internal(&feedback2, next_guess); + + while (__less_dec(&dec, &feedback2)) { + feedback1 = feedback2; + first_guess = next_guess; + --*ull; + __num2dec_internal(&feedback2, next_guess); + } + + __minus_dec(&difflow, &dec, &feedback2); + __minus_dec(&diffhigh, &feedback1, &dec); + + if (__equals_dec(&difflow, &diffhigh)) { + if (*(unsigned long long*)&first_guess & 1) { + first_guess = next_guess; + } + } else if (__less_dec(&difflow, &diffhigh)) { + first_guess = next_guess; + } + } + } + done: + if (dec.sign) { + first_guess = -first_guess; + } + return first_guess; + } +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c new file mode 100644 index 000000000..9d427a732 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c @@ -0,0 +1,57 @@ +#include "types.h" + +s32 InitializeUART(u32); /* extern */ +s32 OSGetConsoleType(); /* extern */ +s32 WriteUARTN(s32, s32); /* extern */ +s32 __TRK_write_console(s32, s32, s32*, s32); /* extern */ + +BOOL __write_console(s32 arg0, s32 arg1, s32* arg2, s32 arg3) +{ + + if ((OSGetConsoleType() & 0x20000000) == 0) { + if (__init_uart_console() != 0) { + return TRUE; + } + if (WriteUARTN(arg1, *arg2) != 0) { + *arg2 = 0; + return TRUE; + } + } + __TRK_write_console(arg0, arg1, arg2, arg3); + return FALSE; +} + +int __close_console() +{ + return 0; +} + +int __init_uart_console(void) +{ + static BOOL initialized; + int ret = 0; + + if (initialized == 0) { + ret = InitializeUART(0xE100); + if (ret == 0) { + initialized = 1; + } + } + + return ret; +} + +void __delete_file(void) +{ + // UNUSED FUNCTION +} + +void __rename_file(void) +{ + // UNUSED FUNCTION +} + +void __temp_file_name(void) +{ + // UNUSED FUNCTION +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/abort_exit.c b/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/abort_exit.c new file mode 100644 index 000000000..634c65d93 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/abort_exit.c @@ -0,0 +1,70 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/signal.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/abort_exit.h" + +void __destroy_global_chain(void); +void _ExitProcess(void); + +extern void (*_dtors[])(void); + +static void (*__console_exit)(void); +void (*__stdio_exit)(void); +static int __atexit_curr_func; +int __aborting; + +static void (*__atexit_funcs[64])(void); + +void abort(void) +{ + raise(1); + __aborting = 1; + exit(1); +} + +void atexit(void) +{ + // UNUSED FUNCTION +} + +void __atexit(void) +{ + // UNUSED FUNCTION +} + +void exit(int status) +{ + int i; + void (**dtor)(void); + + if (!__aborting) { + __begin_critical_region(atexit_funcs_access); + __end_critical_region(atexit_funcs_access); + __destroy_global_chain(); + dtor = _dtors; + while (*dtor != NULL) { + (*dtor)(); + dtor++; + } + if (__stdio_exit != NULL) { + __stdio_exit(); + __stdio_exit = NULL; + } + } + __exit(status); +} + +void __exit(int status) +{ + __begin_critical_region(atexit_funcs_access); + while (__atexit_curr_func > 0) + __atexit_funcs[--__atexit_curr_func](); + __end_critical_region(atexit_funcs_access); + __kill_critical_regions(); + if (__console_exit != NULL) + { + + __console_exit(); + __console_exit = NULL; + } + _ExitProcess(); +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/critical_regions.gamecube.c b/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/critical_regions.gamecube.c new file mode 100644 index 000000000..9cbd811b7 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/critical_regions.gamecube.c @@ -0,0 +1,10 @@ +#include "types.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" + +void __init_critical_regions(void) { return; } + +void __kill_critical_regions(void) { return; } + +void __begin_critical_region(int region) { return; } + +void __end_critical_region(int region) { return; } diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/math_ppc.c b/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/math_ppc.c new file mode 100644 index 000000000..ae9047d99 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/math_ppc.c @@ -0,0 +1,520 @@ +#define MATH_INLINE +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h" +#include "fdlibm.h" + +// Generated via math_api.h +// int __fpclassifyf(float x); + +// Generated via math_api.h +// int __fpclassifyd(double x); + +/*double scalbn(double x, int y) +{ + // UNUSED FUNCTION +} + +void scalbln(void) +{ + // UNUSED FUNCTION +} + +void acosl(void) +{ + // UNUSED FUNCTION +} + +void asinl(void) +{ + // UNUSED FUNCTION +} + +void atanl(void) +{ + // UNUSED FUNCTION +} + +void atan2l(void) +{ + // UNUSED FUNCTION +} + +void cosl(void) +{ + // UNUSED FUNCTION +} + +void sinl(void) +{ + // UNUSED FUNCTION +} + +void tanl(void) +{ + // UNUSED FUNCTION +} + +void coshl(void) +{ + // UNUSED FUNCTION +} + +void sinhl(void) +{ + // UNUSED FUNCTION +} + +void tanhl(void) +{ + // UNUSED FUNCTION +} + +void acoshl(void) +{ + // UNUSED FUNCTION +} + +void asinhl(void) +{ + // UNUSED FUNCTION +} + +void atanhl(void) +{ + // UNUSED FUNCTION +} + +void expl(void) +{ + // UNUSED FUNCTION +} + +void frexpl(void) +{ + // UNUSED FUNCTION +} + +void ldexpl(void) +{ + // UNUSED FUNCTION +} + +void logl(void) +{ + // UNUSED FUNCTION +} + +void log10l(void) +{ + // UNUSED FUNCTION +} + +void modfl(void) +{ + // UNUSED FUNCTION +} + +void exp2l(void) +{ + // UNUSED FUNCTION +} + +void expm1l(void) +{ + // UNUSED FUNCTION +} + +void log1pl(void) +{ + // UNUSED FUNCTION +} + +void log2l(void) +{ + // UNUSED FUNCTION +} + +void logbl(void) +{ + // UNUSED FUNCTION +} + +void scalbnl(void) +{ + // UNUSED FUNCTION +} + +void scalblnl(void) +{ + // UNUSED FUNCTION +} + +void fabsl(void) +{ + // UNUSED FUNCTION +} + +void powl(void) +{ + // UNUSED FUNCTION +} + +void sqrtl(void) +{ + // UNUSED FUNCTION +} + +void hypotl(void) +{ + // UNUSED FUNCTION +} + +void erfl(void) +{ + // UNUSED FUNCTION +} + +void erfcl(void) +{ + // UNUSED FUNCTION +} + +void gammal(void) +{ + // UNUSED FUNCTION +} + +void lgammal(void) +{ + // UNUSED FUNCTION +} + +void nextafterl(void) +{ + // UNUSED FUNCTION +} + +void ceill(void) +{ + // UNUSED FUNCTION +} + +void floorl(void) +{ + // UNUSED FUNCTION +} + +void nearbyintl(void) +{ + // UNUSED FUNCTION +} + +void rintl(void) +{ + // UNUSED FUNCTION +} + +void lrintl(void) +{ + // UNUSED FUNCTION +} + +void llrintl(void) +{ + // UNUSED FUNCTION +} + +void truncl(void) +{ + // UNUSED FUNCTION +} + +void fmodl(void) +{ + // UNUSED FUNCTION +} + +void remainderl(void) +{ + // UNUSED FUNCTION +} + +void copysignl(void) +{ + // UNUSED FUNCTION +} + +void remquol(void) +{ + // UNUSED FUNCTION +} + +void fdiml(void) +{ + // UNUSED FUNCTION +} + +void fmaxl(void) +{ + // UNUSED FUNCTION +} + +void fminl(void) +{ + // UNUSED FUNCTION +} + +void acosf(void) +{ + // UNUSED FUNCTION +} + +void asinf(void) +{ + // UNUSED FUNCTION +} + +void atanf(void) +{ + // UNUSED FUNCTION +} + +void atan2f(void) +{ + // UNUSED FUNCTION +}*/ + + +/*void coshf(void) +{ + // UNUSED FUNCTION +} + +void sinhf(void) +{ + // UNUSED FUNCTION +} + +void tanhf(void) +{ + // UNUSED FUNCTION +} + +void expf(void) +{ + // UNUSED FUNCTION +} + +void frexpf(void) +{ + // UNUSED FUNCTION +} + +void ldexpf(void) +{ + // UNUSED FUNCTION +} + +void logf(void) +{ + // UNUSED FUNCTION +} + +void log10f(void) +{ + // UNUSED FUNCTION +} + +void fabsf(void) +{ + // UNUSED FUNCTION +} + +void powf(void) +{ + // UNUSED FUNCTION +} + +void ceilf(void) +{ + // UNUSED FUNCTION +} + +void floorf(void) +{ + // UNUSED FUNCTION +} + +void fmodf(void) +{ + // UNUSED FUNCTION +} + +void log2f(void) +{ + // UNUSED FUNCTION +} + +void sqrtf(void) +{ + // UNUSED FUNCTION +} + +void _inv_sqrtf(void) +{ + // UNUSED FUNCTION +}*/ + +/*extern inline double fabs(double x) +{ + return __fabs(x); +}*/ + +/*void modff(float f1, float* fp) +{ + // UNUSED FUNCTION +} + +void acoshf(void) +{ + // UNUSED FUNCTION +} + +void asinhf(void) +{ + // UNUSED FUNCTION +} + +void atanhf(void) +{ + // UNUSED FUNCTION +} + +void exp2f(void) +{ + // UNUSED FUNCTION +} + +void expm1f(void) +{ + // UNUSED FUNCTION +} + +void log1pf(void) +{ + // UNUSED FUNCTION +} + +void logbf(void) +{ + // UNUSED FUNCTION +} + +void scalbnf(void) +{ + // UNUSED FUNCTION +} + +void scalblnf(void) +{ + // UNUSED FUNCTION +} + +void hypotf(void) +{ + // UNUSED FUNCTION +} + +void erff(void) +{ + // UNUSED FUNCTION +} + +void erfcf(void) +{ + // UNUSED FUNCTION +} + +void gammaf(void) +{ + // UNUSED FUNCTION +} + +void lgammaf(void) +{ + // UNUSED FUNCTION +} + +void nextafterf(void) +{ + // UNUSED FUNCTION +} + +void nearbyintf(void) +{ + // UNUSED FUNCTION +} + +void rintf(void) +{ + // UNUSED FUNCTION +} + +void lrintf(void) +{ + // UNUSED FUNCTION +} + +void llroundf(void) +{ + // UNUSED FUNCTION +} + +void llrintf(void) +{ + // UNUSED FUNCTION +} + +void truncf(void) +{ + // UNUSED FUNCTION +} + +void remainderf(void) +{ + // UNUSED FUNCTION +} + +void copysignf(void) +{ + // UNUSED FUNCTION +} + +void remquof(void) +{ + // UNUSED FUNCTION +} + +void fdimf(void) +{ + // UNUSED FUNCTION +} + +void fmaxf(void) +{ + // UNUSED FUNCTION +} + +void fminf(void) +{ + // UNUSED FUNCTION +} + +void log2(void) +{ + // UNUSED FUNCTION +} + +void exp2(void) +{ + // UNUSED FUNCTION +}*/ diff --git a/libs/PowerPC_EABI_Support/src/Runtime/CPlusLibPPC.cp b/libs/PowerPC_EABI_Support/src/Runtime/CPlusLibPPC.cp new file mode 100644 index 000000000..b9efdad8b --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/CPlusLibPPC.cp @@ -0,0 +1,41 @@ +#include "types.h" +extern "C"{ + +void* __copy(char *dest, char *src, size_t size) +{ + char *p; + + if (dest && size) { + p = dest; + do { + *p = *src; + ++p; + ++src; + --size; + } while (size); + } + + return(dest); +} + +void __init_arr(void) +{ + // UNUSED FUNCTION +} + +void __new_arr(void) +{ + // UNUSED FUNCTION +} + +void __del_arr(void) +{ + // UNUSED FUNCTION +} + +void __dc_arr(void) +{ + // UNUSED FUNCTION +} + +} diff --git a/libs/PowerPC_EABI_Support/src/Runtime/GCN_mem_alloc.c b/libs/PowerPC_EABI_Support/src/Runtime/GCN_mem_alloc.c new file mode 100644 index 000000000..8bd49fcdf --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/GCN_mem_alloc.c @@ -0,0 +1,36 @@ +#include "types.h" +#include "Dolphin/os.h" + +static void InitDefaultHeap() +{ + void* arenaLo; + void* arenaHi; + + OSReport("GCN_Mem_Alloc.c : InitDefaultHeap. No Heap Available\n"); + OSReport("Metrowerks CW runtime library initializing default heap\n"); + + 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); +} + +// unused +void __sys_alloc() +{ +} + +__declspec(weak) extern void __sys_free(void* ptr) +{ + if (__OSCurrHeap == -1) { + InitDefaultHeap(); + } + OSFreeToHeap(__OSCurrHeap, ptr); +} diff --git a/libs/PowerPC_EABI_Support/src/Runtime/Gecko_ExceptionPPC.cp b/libs/PowerPC_EABI_Support/src/Runtime/Gecko_ExceptionPPC.cp new file mode 100644 index 000000000..293c10010 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/Gecko_ExceptionPPC.cp @@ -0,0 +1,891 @@ +#include "PowerPC_EABI_Support/Runtime/Gecko_ExceptionPPC.h" +#include "PowerPC_EABI_Support/Runtime/MWCPlusPlusLib.h" +#include "PowerPC_EABI_Support/Runtime/NMWException.h" +#include "PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h" + + +#define RETURN_ADDRESS 4 + +union MWE_GeckoVector64 { + double d; + float f[2]; +}; + +typedef union MWE_GeckoVector64 MWE_GeckoVector64; + +struct GeckoFPRContext { + double d; + MWE_GeckoVector64 v; +}; + +typedef struct GeckoFPRContext GeckoFPRContext; + +typedef struct ThrowContext { + GeckoFPRContext FPR[32]; + long GPR[32]; + long CR; + char* SP; + char* FP; + char* throwSP; + char* returnaddr; + char* throwtype; + void* location; + void* dtor; + CatchInfo *catchinfo; +} ThrowContext; + +typedef ThrowContext* ThrowContextPtr; + +typedef struct MWExceptionInfo { + ExceptionTableSmall* exception_record; + char* current_function; + char* action_pointer; + char* code_section; + char* data_section; + char* TOC; +} MWExceptionInfo; + +typedef struct FragmentInfo { + ExceptionTableIndex* exception_start; + ExceptionTableIndex* exception_end; + char* code_start; + char* code_end; + char* data_start; + char* data_end; + char* TOC; + int active; +} FragmentInfo; + +typedef struct ProcessInfo { + __eti_init_info* exception_info; + char* TOC; + int active; +} ProcessInfo; + +typedef struct ActionIterator { + MWExceptionInfo info; + char* current_SP; + char* current_FP; + long current_R31; +} ActionIterator; + +#define MAXFRAGMENTS 32 +static ProcessInfo fragmentinfo[MAXFRAGMENTS]; + +typedef void (*DeleteFunc)(void *); + + + +//Likely a fakematch +#pragma schedule once +int __register_fragment(struct __eti_init_info* info, char* TOC){ + + ProcessInfo* f = fragmentinfo; + int i; + + for(i = 0; i < MAXFRAGMENTS; i++, f++){ + if(f->active == 0){ + f->exception_info = info; + f->TOC = TOC; + f->active = 1; + return i; + } + } + + return -1; +} +#pragma schedule twice + +void __unregister_fragment(int fragmentID){ + ProcessInfo* f; + + if(fragmentID >= 0 && fragmentID < MAXFRAGMENTS){ + f = &fragmentinfo[fragmentID]; + f->exception_info = 0; + f->TOC = 0; + f->active = 0; + } +} + +static int ExPPC_FindExceptionFragment(char* returnaddr, FragmentInfo* frag) +{ + ProcessInfo* f; + int i; + __eti_init_info* eti_info; + + for(i = 0, f = fragmentinfo; i < MAXFRAGMENTS; ++i, ++f){ + if(f->active){ + eti_info = f->exception_info; + while (1) { + if(eti_info->code_size == 0) break; + if(returnaddr >= eti_info->code_start && returnaddr < (char*)eti_info->code_start+eti_info->code_size) { + frag->exception_start = (ExceptionTableIndex*)eti_info->eti_start; + frag->exception_end = (ExceptionTableIndex*)eti_info->eti_end; + frag->code_start = 0; + frag->code_end = 0; + frag->data_start = 0; + frag->data_end = 0; + frag->TOC = f->TOC; + frag->active = f->active; + return 1; + } + eti_info++; + } + } + } + + return 0; +} + + +static void ExPPC_FindExceptionRecord(char* returnaddr, MWExceptionInfo* info){ + FragmentInfo* fragment; + FragmentInfo frag; + ExceptionTableIndex *exceptionindex,*p; + unsigned long returnoffset; + long i,m,n; + + info->exception_record=0; + info->action_pointer=0; + + if ((ExPPC_FindExceptionFragment(returnaddr, &frag)) == 0) return; + fragment = &frag; + + info->code_section = fragment->code_start; + info->data_section = fragment->data_start; + info->TOC = fragment->TOC; + + returnoffset = returnaddr-fragment->code_start; + exceptionindex = fragment->exception_start; + for(i = 0, n = fragment->exception_end-fragment->exception_start;;){ + if(i > n) return; + p = &exceptionindex[m = (i+n)/2]; + + if(returnoffset < p->functionoffset){ + n = m - 1; + }else if(returnoffset > p->functionoffset + ETI_GetFunctionSize(p->eti_field)){ + i = m + 1; + }else break; + } + info->current_function = fragment->code_start + p->functionoffset; + info->exception_record = ETI_GetDirectStore(p->eti_field) ? (ExceptionTableSmall*)(&p->exceptionoffset) : (ExceptionTableSmall*)(fragment->data_start + p->exceptionoffset); + + returnoffset -= p->functionoffset; + + if (ET_IsLargeTable(info->exception_record->et_field)){ + ExceptionTableLarge* etl = (ExceptionTableLarge*)info->exception_record; + ExceptionRangeLarge* erl; + + for(erl = etl->ranges; erl->start != 0; erl++){ + unsigned long range_end = erl->start + (erl->size * 4); + + if (erl->start <= returnoffset && range_end >= returnoffset){ + info->action_pointer = (char*)etl + erl->action; + break; + } + } + }else{ + ExceptionTableSmall* ets = (ExceptionTableSmall*)info->exception_record; + ExceptionRangeSmall* ers; + + for(ers = ets->ranges; ers->start != 0; ers++){ + if(ers->start <= returnoffset && ers->end >= returnoffset){ + info->action_pointer = (char*)ets + ers->action; + break; + } + } + + } +} + +static long ExPPC_PopR31(char *SP,MWExceptionInfo *info){ + double* FPR_save_area; + long* GPR_save_area; + int saved_GPRs, saved_FPRs; + + saved_FPRs = ET_GetSavedFPRs(info->exception_record->et_field); + FPR_save_area = (double*)(SP-saved_FPRs * 8); + saved_GPRs = ET_GetSavedGPRs(info->exception_record->et_field); + GPR_save_area = (long*)FPR_save_area; + + return GPR_save_area[-1]; +} + +static exaction_type ExPPC_CurrentAction(const ActionIterator* iter){ + if(iter->info.action_pointer == 0){ + return EXACTION_ENDOFLIST; + } + + return ((ex_destroylocal*)iter->info.action_pointer)->action & EXACTION_MASK; +} + +static exaction_type ExPPC_NextAction(ActionIterator* iter){ + exaction_type action; + + for(;;){ + if(iter->info.action_pointer == 0 || ((action = ((ex_destroylocal*)iter->info.action_pointer)->action) & EXACTION_ENDBIT) != 0){ + char* return_addr, *callers_SP; + + callers_SP = *(char**)iter->current_SP; + + if(ET_GetSavedGPRs(iter->info.exception_record->et_field)){ + iter->current_R31 = ExPPC_PopR31(callers_SP, &iter->info); + } + + return_addr = *(char**)(callers_SP + RETURN_ADDRESS); + + ExPPC_FindExceptionRecord(return_addr, &iter->info); + + if(iter->info.exception_record == 0){ + std::terminate(); + } + + iter->current_SP = callers_SP; + iter->current_FP = (ET_GetHasFramePtr(iter->info.exception_record->et_field)) ? (char*)iter->current_R31 : iter->current_SP; + + if(iter->info.action_pointer == 0) continue; + }else{ + switch(action){ + case EXACTION_DESTROYLOCAL: + iter->info.action_pointer += sizeof(ex_destroylocal); + break; + case EXACTION_DESTROYLOCALCOND: + iter->info.action_pointer += sizeof(ex_destroylocalcond); + break; + case EXACTION_DESTROYLOCALPOINTER: + iter->info.action_pointer += sizeof(ex_destroylocalpointer); + break; + case EXACTION_DESTROYLOCALARRAY: + iter->info.action_pointer += sizeof(ex_destroylocalarray); + break; + case EXACTION_DESTROYBASE: + case EXACTION_DESTROYMEMBER: + iter->info.action_pointer += sizeof(ex_destroymember); + break; + case EXACTION_DESTROYMEMBERCOND: + iter->info.action_pointer += sizeof(ex_destroymembercond); + break; + case EXACTION_DESTROYMEMBERARRAY: + iter->info.action_pointer += sizeof(ex_destroymemberarray); + break; + case EXACTION_DELETEPOINTER: + iter->info.action_pointer += sizeof(ex_deletepointer); + break; + case EXACTION_DELETEPOINTERCOND: + iter->info.action_pointer += sizeof(ex_deletepointercond); + break; + case EXACTION_CATCHBLOCK: + iter->info.action_pointer += sizeof(ex_catchblock); + break; + case EXACTION_CATCHBLOCK_32: + iter->info.action_pointer += sizeof(ex_catchblock_32); + break; + case EXACTION_ACTIVECATCHBLOCK: + iter->info.action_pointer += sizeof(ex_activecatchblock); + break; + case EXACTION_SPECIFICATION: + iter->info.action_pointer += sizeof(ex_specification) + ((ex_specification*)iter->info.action_pointer)->specs * sizeof(void*); + break; + default: + std::terminate(); + } + } + + action = ((ex_destroylocal*)iter->info.action_pointer)->action & EXACTION_MASK; + + if(action == EXACTION_BRANCH){ + iter->info.action_pointer = ((char*)iter->info.exception_record) + ((ex_branch*)iter->info.action_pointer)->target; + action = ((ex_destroylocal*)iter->info.action_pointer)->action & EXACTION_MASK; + } + return action; + } +} + +static char* ExPPC_PopStackFrame(ThrowContext* context, MWExceptionInfo* info){ + char *SP, *callers_SP; + double* FPR_save_area; + long* GPR_save_area; + int saved_GPRs, saved_FPRs; + GeckoFPRContext* Vector_save_area; + int i, j; + + SP = context->SP; + callers_SP = *(char**)SP; + saved_FPRs = ET_GetSavedFPRs(info->exception_record->et_field); + + if(ET_HasElfVector(info->exception_record->et_field)){ + Vector_save_area = (GeckoFPRContext *)(callers_SP - saved_FPRs*16); + FPR_save_area = (double*)Vector_save_area; + }else{ + FPR_save_area = (double*)(callers_SP - saved_FPRs*8); + } + + if (ET_HasElfVector(info->exception_record->et_field)){ + for(i = 32 - saved_FPRs, j = 0; i < 32; ++i, ++j){ + context->FPR[i].v.f[0] = Vector_save_area[j].v.f[0]; + context->FPR[i].v.f[1] = Vector_save_area[j].v.f[1]; + context->FPR[i].d = Vector_save_area[j].d; + } + }else{ + for(i = 32 - saved_FPRs, j = 0; i < 32; ++i, ++j){ + context->FPR[i].d = FPR_save_area[j]; + } + } + + saved_GPRs = ET_GetSavedGPRs(info->exception_record->et_field); + GPR_save_area = (long*)FPR_save_area; + GPR_save_area -= saved_GPRs; + + for(i = 32 - saved_GPRs, j = 0; i < 32; ++i, ++j){ + context->GPR[i] = GPR_save_area[j]; + } + + context->SP = callers_SP; + return *(char**)(callers_SP + RETURN_ADDRESS); +} + +static void ExPPC_DestroyLocal(ThrowContext* context, const ex_destroylocal* ex){ + DTORCALL_COMPLETE(ex->dtor, context->FP + ex->local); +} + +static void ExPPC_DestroyLocalCond(ThrowContext* context, const ex_destroylocalcond* ex){ + int cond = ex_destroylocalcond_GetRegCond(ex->dlc_field) ? (local_cond_type)context->GPR[ex->cond] : *(local_cond_type*)(context->FP + ex->cond); + + if(cond){ + DTORCALL_COMPLETE(ex->dtor, context->FP + ex->local); + } +} + +static void ExPPC_DestroyLocalPointer(ThrowContext* context, const ex_destroylocalpointer* ex){ + void *pointer = ex_destroylocalpointer_GetRegPointer(ex->dlp_field) ? (void*)context->GPR[ex->pointer] : *(void**)(context->FP + ex->pointer); + + DTORCALL_COMPLETE(ex->dtor, pointer); +} + +static void ExPPC_DestroyLocalArray(ThrowContext* context, const ex_destroylocalarray* ex){ + char* ptr = context->FP + ex->localarray; + long n = ex->elements; + long size = ex->element_size; + + for(ptr = ptr + size*n; n > 0; n--){ + ptr -= size; + DTORCALL_COMPLETE(ex->dtor, ptr); + } +} + +static void ExPPC_DestroyMember(ThrowContext* context, const ex_destroymember* ex){ + char *objectptr = ex_destroymember_GetRegPointer(ex->dm_field) ? (char*)context->GPR[ex->objectptr] : *(char**)(context->FP + ex->objectptr); + + DTORCALL_COMPLETE(ex->dtor,objectptr + ex->offset); +} + +static void ExPPC_DestroyBase(ThrowContext* context, const ex_destroymember* ex){ + char* objectptr = ex_destroymember_GetRegPointer(ex->dm_field) ? (char*)context->GPR[ex->objectptr] : *(char**)(context->FP + ex->objectptr); + + DTORCALL_PARTIAL(ex->dtor,objectptr + ex->offset); +} + +static void ExPPC_DestroyMemberCond(ThrowContext* context, const ex_destroymembercond* ex){ + char* objectptr = ex_destroymembercond_GetRegPointer(ex->dmc_field) ? (char*)context->GPR[ex->objectptr] : *(char**)(context->FP + ex->objectptr); + int cond = ex_destroymembercond_GetRegCond(ex->dmc_field) ? (vbase_ctor_arg_type)context->GPR[ex->cond] : *(vbase_ctor_arg_type*)(context->FP + ex->cond); + + if(cond){ + DTORCALL_PARTIAL(ex->dtor, objectptr + ex->offset); + } +} + +static void ExPPC_DestroyMemberArray(ThrowContext* context, const ex_destroymemberarray* ex){ + char* ptr = ex_destroymemberarray_GetRegPointer(ex->dma_field) ? (char*)context->GPR[ex->objectptr] : *(char**)(context->FP + ex->objectptr); + long n = ex->elements; + long size = ex->element_size; + + ptr += ex->offset; + + for(ptr = ptr + size*n; n > 0; n--){ + ptr -= size; + DTORCALL_COMPLETE(ex->dtor, ptr); + } +} + +static void ExPPC_DeletePointer(ThrowContext* context, const ex_deletepointer* ex){ + char* objectptr = ex_deletepointer_GetRegPointer(ex->dp_field) ? (char*)context->GPR[ex->objectptr] : *(char**)(context->FP + ex->objectptr); + + ((DeleteFunc)ex->deletefunc)(objectptr); +} + +static void ExPPC_DeletePointerCond(ThrowContext* context, const ex_deletepointercond* ex){ + char* objectptr = ex_deletepointercond_GetRegPointer(ex->dpc_field) ? (char*)context->GPR[ex->objectptr] : *(char**)(context->FP + ex->objectptr); + int cond = ex_deletepointercond_GetRegCond(ex->dpc_field) ? (local_cond_type)context->GPR[ex->cond] : *(local_cond_type*)(context->FP+ex->cond); + + if(cond){ + ((DeleteFunc)ex->deletefunc)(objectptr); + } +} + +static void ExPPC_UnwindStack(ThrowContext* context, MWExceptionInfo* info, void* catcher){ + exaction_type action; + + #pragma exception_terminate + + for(;;){ + if(info->action_pointer == 0){ + char* return_addr; + + return_addr = ExPPC_PopStackFrame(context, info); + ExPPC_FindExceptionRecord(return_addr, info); + + if(info->exception_record == 0){ + std::terminate(); + } + + context->FP = (ET_GetHasFramePtr(info->exception_record->et_field)) ? (char*)context->GPR[31] : context->SP; + continue; + } + + action = ((ex_destroylocal*)info->action_pointer)->action; + + switch(action & EXACTION_MASK){ + case EXACTION_BRANCH: + info->action_pointer = ((char*)info->exception_record) + ((ex_branch*)info->action_pointer)->target; + break; + case EXACTION_DESTROYLOCAL: + ExPPC_DestroyLocal(context, (ex_destroylocal*)info->action_pointer); + info->action_pointer += sizeof(ex_destroylocal); + break; + case EXACTION_DESTROYLOCALCOND: + ExPPC_DestroyLocalCond(context, (ex_destroylocalcond*)info->action_pointer); + info->action_pointer += sizeof(ex_destroylocalcond); + break; + case EXACTION_DESTROYLOCALPOINTER: + ExPPC_DestroyLocalPointer(context, (ex_destroylocalpointer*)info->action_pointer); + info->action_pointer += sizeof(ex_destroylocalpointer); + break; + case EXACTION_DESTROYLOCALARRAY: + ExPPC_DestroyLocalArray(context, (ex_destroylocalarray*)info->action_pointer); + info->action_pointer += sizeof(ex_destroylocalarray); + break; + case EXACTION_DESTROYBASE: + ExPPC_DestroyBase(context, (ex_destroymember*)info->action_pointer); + info->action_pointer += sizeof(ex_destroymember); + break; + case EXACTION_DESTROYMEMBER: + ExPPC_DestroyMember(context, (ex_destroymember*)info->action_pointer); + info->action_pointer += sizeof(ex_destroymember); + break; + case EXACTION_DESTROYMEMBERCOND: + ExPPC_DestroyMemberCond(context, (ex_destroymembercond*)info->action_pointer); + info->action_pointer += sizeof(ex_destroymembercond); + break; + case EXACTION_DESTROYMEMBERARRAY: + ExPPC_DestroyMemberArray(context, (ex_destroymemberarray*)info->action_pointer); + info->action_pointer += sizeof(ex_destroymemberarray); + break; + case EXACTION_DELETEPOINTER: + ExPPC_DeletePointer(context, (ex_deletepointer*)info->action_pointer); + info->action_pointer += sizeof(ex_deletepointer); + break; + case EXACTION_DELETEPOINTERCOND: + ExPPC_DeletePointerCond(context, (ex_deletepointercond*)info->action_pointer); + info->action_pointer += sizeof(ex_deletepointercond); + break; + case EXACTION_CATCHBLOCK: + if(catcher == (void *)info->action_pointer) return; + info->action_pointer += sizeof(ex_catchblock); + break; + case EXACTION_CATCHBLOCK_32: + if(catcher == (void *)info->action_pointer) return; + info->action_pointer += sizeof(ex_catchblock_32); + break; + case EXACTION_ACTIVECATCHBLOCK: + { + CatchInfo* catchinfo; + + catchinfo = (CatchInfo*)(context->FP + ((ex_activecatchblock*)info->action_pointer)->cinfo_ref); + + if (catchinfo->dtor){ + if (context->location == catchinfo->location){ + context->dtor = catchinfo->dtor; + }else{ + DTORCALL_COMPLETE(catchinfo->dtor, catchinfo->location); + } + } + info->action_pointer += sizeof(ex_activecatchblock); + } + break; + case EXACTION_SPECIFICATION: + if(catcher == (void*)info->action_pointer) return; + info->action_pointer += sizeof(ex_specification) + ((ex_specification*)info->action_pointer)->specs * sizeof(void*); + break; + default: + std::terminate(); + } + + if(action & EXACTION_ENDBIT) info->action_pointer = 0; + } +} + +static int ExPPC_IsInSpecification(char* extype, ex_specification* spec){ + long i, offset; + + for(i = 0; i < spec->specs; i++){ + if(__throw_catch_compare(extype, spec->spec[i], &offset)) return 1; + } + + return 0; +} + +//unused +extern void __unexpected(CatchInfo* catchinfo){ +} + +static asm void ExPPC_LongJump(register ThrowContext* context, register void* newRTOC, register void* newPC){ + nofralloc + + mr r8, newPC + mr RTOC, newRTOC + lwz r0, context->CR + mtcrf 255, r0 + + lmw r13, context->GPR[13] + + la r7, context->FPR[14].v + psq_lx fp14, 0, r7, 0, 0 + lfd fp14, context->FPR[14].d + + la r7, context->FPR[15].v + psq_lx fp15, 0, r7, 0, 0 + lfd fp15, context->FPR[15].d + + la r7, context->FPR[16].v + psq_lx fp16, 0, r7, 0, 0 + lfd fp16, context->FPR[16].d + + la r7, context->FPR[17].v + psq_lx fp17, 0, r7, 0, 0 + lfd fp17, context->FPR[17].d + + la r7, context->FPR[18].v + psq_lx fp18, 0, r7, 0, 0 + lfd fp18, context->FPR[18].d + + la r7, context->FPR[19].v + psq_lx fp19, 0, r7, 0, 0 + lfd fp19, context->FPR[19].d + + la r7, context->FPR[20].v + psq_lx fp20, 0, r7, 0, 0 + lfd fp20, context->FPR[20].d + + la r7, context->FPR[21].v + psq_lx fp21, 0, r7, 0, 0 + lfd fp21, context->FPR[21].d + + la r7, context->FPR[22].v + psq_lx fp22, 0, r7, 0, 0 + lfd fp22, context->FPR[22].d + + la r7, context->FPR[23].v + psq_lx fp23, 0, r7, 0, 0 + lfd fp23, context->FPR[23].d + + la r7, context->FPR[24].v + psq_lx fp24, 0, r7, 0, 0 + lfd fp24, context->FPR[24].d + + la r7, context->FPR[25].v + psq_lx fp25, 0, r7, 0, 0 + lfd fp25, context->FPR[25].d + + la r7, context->FPR[26].v + psq_lx fp26, 0, r7, 0, 0 + lfd fp26, context->FPR[26].d + + la r7, context->FPR[27].v + psq_lx fp27, 0, r7, 0, 0 + lfd fp27, context->FPR[27].d + + la r7, context->FPR[28].v + psq_lx fp28, 0, r7, 0, 0 + lfd fp28, context->FPR[28].d + + la r7, context->FPR[29].v + psq_lx fp29, 0, r7, 0, 0 + lfd fp29, context->FPR[29].d + + la r7, context->FPR[30].v + psq_lx fp30, 0, r7, 0, 0 + lfd fp30, context->FPR[30].d + + la r7, context->FPR[31].v + psq_lx fp31, 0, r7, 0, 0 + lfd fp31, context->FPR[31].d + + mtlr r8 + + lwz SP, context->throwSP + lwz r3, context->SP + lwz r3, 0(r3) + stw r3, 0(SP) + blr +} + +static void ExPPC_HandleUnexpected(ThrowContext* context, MWExceptionInfo* info, ex_specification* unexp){ + CatchInfo* catchinfo; + + #pragma exception_terminate + + ExPPC_UnwindStack(context, info, unexp); + + catchinfo = (CatchInfo*)(context->FP + unexp->cinfo_ref); + catchinfo->location = context->location; + catchinfo->typeinfo = context->throwtype; + catchinfo->dtor = context->dtor; + catchinfo->stacktop = unexp; + + ExPPC_LongJump(context, info->TOC, info->current_function + unexp->pcoffset); +} + +static void ExPPC_ThrowHandler(ThrowContext* context){ + ActionIterator iter; + MWExceptionInfo info; + exaction_type action; + CatchInfo* catchinfo; + long offset; + + ExPPC_FindExceptionRecord(context->returnaddr, &info); + + if(info.exception_record == 0){ + std::terminate(); + } + + context->FP = (ET_GetHasFramePtr(info.exception_record->et_field)) ? (char*)context->GPR[31] : context->SP; + + if(context->throwtype == 0){ + iter.info = info; + iter.current_SP = context->SP; + iter.current_FP = context->FP; + iter.current_R31 = context->GPR[31]; + + for(action = ExPPC_CurrentAction(&iter);; action = ExPPC_NextAction(&iter)){ + switch(action){ + case EXACTION_ACTIVECATCHBLOCK: + break; + case EXACTION_ENDOFLIST: + case EXACTION_DESTROYLOCAL: + case EXACTION_DESTROYLOCALCOND: + case EXACTION_DESTROYLOCALPOINTER: + case EXACTION_DESTROYLOCALARRAY: + case EXACTION_DESTROYBASE: + case EXACTION_DESTROYMEMBER: + case EXACTION_DESTROYMEMBERCOND: + case EXACTION_DESTROYMEMBERARRAY: + case EXACTION_DELETEPOINTER: + case EXACTION_DELETEPOINTERCOND: + case EXACTION_CATCHBLOCK: + case EXACTION_CATCHBLOCK_32: + case EXACTION_SPECIFICATION: + continue; + case EXACTION_TERMINATE: + default: + std::terminate(); + } + break; + } + + catchinfo = (CatchInfo*)(iter.current_FP + ((ex_activecatchblock*)iter.info.action_pointer)->cinfo_ref); + context->throwtype = (char*)catchinfo->typeinfo; + context->location = catchinfo->location; + context->dtor = 0; + context->catchinfo = catchinfo; + }else{ + context->catchinfo = 0L; + } + + iter.info = info; + iter.current_SP = context->SP; + iter.current_FP = context->FP; + iter.current_R31 = context->GPR[31]; + + for(action = ExPPC_CurrentAction(&iter);; action = ExPPC_NextAction(&iter)){ + switch(action){ + case EXACTION_CATCHBLOCK_32: + if(__throw_catch_compare(context->throwtype, ((ex_catchblock_32*)iter.info.action_pointer)->catch_type, &offset)){ + break; + } + continue; + case EXACTION_CATCHBLOCK: + if(__throw_catch_compare(context->throwtype, ((ex_catchblock*)iter.info.action_pointer)->catch_type, &offset)){ + break; + } + continue; + case EXACTION_SPECIFICATION: + if(!ExPPC_IsInSpecification(context->throwtype, (ex_specification*)iter.info.action_pointer)){ + ExPPC_HandleUnexpected(context, &info, (ex_specification *)iter.info.action_pointer); + } + continue; + case EXACTION_ENDOFLIST: + case EXACTION_DESTROYLOCAL: + case EXACTION_DESTROYLOCALCOND: + case EXACTION_DESTROYLOCALPOINTER: + case EXACTION_DESTROYLOCALARRAY: + case EXACTION_DESTROYBASE: + case EXACTION_DESTROYMEMBER: + case EXACTION_DESTROYMEMBERCOND: + case EXACTION_DESTROYMEMBERARRAY: + case EXACTION_DELETEPOINTER: + case EXACTION_DELETEPOINTERCOND: + case EXACTION_ACTIVECATCHBLOCK: + continue; + case EXACTION_TERMINATE: + default: + std::terminate(); + } + break; + } + + if (action == EXACTION_CATCHBLOCK_32) { + ex_catchblock_32* catchblock_32; + catchblock_32 = (ex_catchblock_32*)iter.info.action_pointer; + + ExPPC_UnwindStack(context, &info, catchblock_32); + + catchinfo = (CatchInfo*)(context->FP + catchblock_32->cinfo_ref); + catchinfo->location = context->location; + catchinfo->typeinfo = context->throwtype; + catchinfo->dtor = context->dtor; + + if(*context->throwtype == '*'){ + catchinfo->sublocation = &catchinfo->pointercopy; + catchinfo->pointercopy = *(long*)context->location + offset; + }else{ + catchinfo->sublocation = (char*)context->location + offset; + } + + ExPPC_LongJump(context, info.TOC, info.current_function + catchblock_32->catch_pcoffset); + }else{ + ex_catchblock* catchblock; + + catchblock = (ex_catchblock*)iter.info.action_pointer; + ExPPC_UnwindStack(context, &info, catchblock); + + catchinfo = (CatchInfo*)(context->FP+catchblock->cinfo_ref); + catchinfo->location = context->location; + catchinfo->typeinfo = context->throwtype; + catchinfo->dtor = context->dtor; + + if(*context->throwtype == '*'){ + catchinfo->sublocation = &catchinfo->pointercopy; + catchinfo->pointercopy = *(long*)context->location+offset; + }else{ + catchinfo->sublocation = (char*)context->location+offset; + } + + ExPPC_LongJump(context, info.TOC, info.current_function + catchblock->catch_pcoffset); + } +} + +asm void __throw(char* throwtype, void* location, void* dtor){ + ThrowContext throwcontext; + + fralloc + + stmw r13, throwcontext.GPR[13] + + stfd fp14, throwcontext.FPR[14].d + la r3, throwcontext.FPR[14].v + psq_stx fp14, 0, r3,0,0 + + stfd fp15, throwcontext.FPR[15].d + la r3, throwcontext.FPR[15].v + psq_stx fp15, 0, r3, 0, 0 + + stfd fp16, throwcontext.FPR[16].d + la r3, throwcontext.FPR[16].v + psq_stx fp16, 0, r3, 0, 0 + + stfd fp17, throwcontext.FPR[17].d + la r3, throwcontext.FPR[17].v + psq_stx fp17, 0, r3, 0, 0 + + stfd fp18, throwcontext.FPR[18].d + la r3, throwcontext.FPR[18].v + psq_stx fp18, 0, r3, 0, 0 + + stfd fp19, throwcontext.FPR[19].d + la r3, throwcontext.FPR[19].v + psq_stx fp19, 0, r3, 0, 0 + + stfd fp20, throwcontext.FPR[20].d + la r3, throwcontext.FPR[20].v + psq_stx fp20, 0, r3, 0, 0 + + stfd fp21, throwcontext.FPR[21].d + la r3, throwcontext.FPR[21].v + psq_stx fp21, 0, r3, 0, 0 + + stfd fp22, throwcontext.FPR[22].d + la r3, throwcontext.FPR[22].v + psq_stx fp22, 0, r3, 0, 0 + + stfd fp23, throwcontext.FPR[23].d + la r3, throwcontext.FPR[23].v + psq_stx fp23, 0, r3, 0, 0 + + stfd fp24, throwcontext.FPR[24].d + la r3, throwcontext.FPR[24].v + psq_stx fp24, 0, r3, 0, 0 + + stfd fp25, throwcontext.FPR[25].d + la r3, throwcontext.FPR[25].v + psq_stx fp25, 0, r3, 0, 0 + + stfd fp26, throwcontext.FPR[26].d + la r3, throwcontext.FPR[26].v + psq_stx fp26, 0, r3, 0, 0 + + stfd fp27, throwcontext.FPR[27].d + la r3, throwcontext.FPR[27].v + psq_stx fp27, 0, r3, 0, 0 + + stfd fp28, throwcontext.FPR[28].d + la r3, throwcontext.FPR[28].v + psq_stx fp28, 0, r3, 0, 0 + + stfd fp29, throwcontext.FPR[29].d + la r3, throwcontext.FPR[29].v + psq_stx fp29, 0, r3, 0, 0 + + stfd fp30, throwcontext.FPR[30].d + la r3, throwcontext.FPR[30].v + psq_stx fp30, 0, r3, 0, 0 + + stfd fp31, throwcontext.FPR[31].d + la r3, throwcontext.FPR[31].v + psq_stx fp31, 0, r3, 0, 0 + + + mfcr r3 + stw r3, throwcontext.CR; + + lwz r3, 0(sp) + lwz r4, RETURN_ADDRESS(r3) + stw r3, throwcontext.SP; + stw r3, throwcontext.throwSP; + stw r4, throwcontext.returnaddr; + + lwz r3,throwtype + stw r3, throwcontext.throwtype + lwz r3,location + stw r3, throwcontext.location + lwz r3,dtor + stw r3, throwcontext.dtor + la r3, throwcontext + bl ExPPC_ThrowHandler + nop + frfree + blr +} + +//unused +void __end__catch(CatchInfo* catchinfo){ +} diff --git a/libs/PowerPC_EABI_Support/src/Runtime/NMWException.cp b/libs/PowerPC_EABI_Support/src/Runtime/NMWException.cp new file mode 100644 index 000000000..bef12ad6c --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/NMWException.cp @@ -0,0 +1,91 @@ +#include "PowerPC_EABI_Support/Runtime/NMWException.h" +#include "PowerPC_EABI_Support/Runtime/MWCPlusPlusLib.h" + +#pragma exceptions on + +extern "C" +{ + void abort(); +} + +namespace std +{ + static void dthandler() + { + abort(); + } + + terminate_handler thandler = dthandler; + + static void duhandler() + { + terminate(); + } + + unexpected_handler uhandler = duhandler; + + extern void terminate() + { + thandler(); + } + + extern void unexpected() { + uhandler(); + } +} + +extern "C" char __throw_catch_compare(const char* throwtype, const char* catchtype, s32* offset_result) +{ + return 0; +} + +extern "C" void *__construct_new_array(void *block, ConstructorDestructor ctor, ConstructorDestructor dtor_arg, size_t size, size_t n) +{ + return 0 ; +} + +class __partial_array_destructor +{ +private: + void *p; + size_t size; + size_t n; + void *dtor; + +public: + size_t i; + + __partial_array_destructor(void *array, size_t elementsize, size_t nelements, void *destructor) + { + p = array; + size = elementsize; + n = nelements; + dtor = destructor; + i = n; + } + + ~__partial_array_destructor() + { + char *ptr; + + if (i < n && dtor) + { + for (ptr = (char *)p + size * i; i > 0; i--) + { + ptr -= size; + DTORCALL_COMPLETE(dtor, ptr); + } + } + } +}; + + +extern "C" void __construct_array(void *ptr, void *ctor, void *dtor, size_t size, size_t n) +{ + +} + +extern "C" void __destroy_arr(void *block, ConstructorDestructor *dtor, size_t size, size_t n) +{ + +} diff --git a/libs/PowerPC_EABI_Support/src/Runtime/__init_cpp_exceptions.cpp b/libs/PowerPC_EABI_Support/src/Runtime/__init_cpp_exceptions.cpp new file mode 100644 index 000000000..617b7374d --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/__init_cpp_exceptions.cpp @@ -0,0 +1,37 @@ +#include "types.h" +#include "PowerPC_EABI_Support/Runtime/NMWException.h" +#include "PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h" +#include "PowerPC_EABI_Support/Runtime/__init_cpp_exceptions.h" + +static int fragmentID = -2; + +extern char *GetR2() ; + +void __init_cpp_exceptions() +{ + if ((s32)fragmentID == -2) { + char* R2 = GetR2(); + fragmentID = __register_fragment(&_eti_init_info, R2); + } +} + +// clang-format on +void __fini_cpp_exceptions() +{ + if ((s32)fragmentID != -2) { + __unregister_fragment(fragmentID); + fragmentID = -2; + } +} + +// clang-format off +asm char* GetR2() +{ + nofralloc + mr r3, r2 + blr +} + +__declspec(section ".ctors") extern void* const __init_cpp_exceptions_reference = __init_cpp_exceptions; +__declspec(section ".dtors") extern void* const __destroy_global_chain_reference = __destroy_global_chain; +__declspec(section ".dtors") extern void* const __fini_cpp_exceptions_reference = __fini_cpp_exceptions; \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/Runtime/__mem.c b/libs/PowerPC_EABI_Support/src/Runtime/__mem.c new file mode 100644 index 000000000..51d788a94 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/__mem.c @@ -0,0 +1,102 @@ +#include +#include + +void *memcpy(void *dst, const void *src, size_t n) +{ + u8 *__src; + u8 *__dst; + int i; + + if (src >= dst) + { + __src = ((u8 *)src) - 1; + __dst = ((u8 *)dst) - 1; + i = n + 1; + while (--i) + { + *((u8 *)++__dst) = *((u8 *)++__src); + } + return dst; + } + else + { + __src = ((u8 *)src) + n; + __dst = ((u8 *)dst) + n; + i = n + 1; + while (--i) + { + *((u8 *)--__dst) = *((u8 *)--__src); + } + return dst; + } +} +void __fill_mem(void *dst, int c, size_t n) +{ + u8 *cdest; + u32 *idest; + u32 i; + u32 cval; + + cval = (u8)c; + cdest = (u8 *)dst - 1; + + if (n >= 32) + { + i = ~(u32)cdest & 3; + if (i != 0) + { + n = n - i; + do + { + *(++cdest) = (u8)cval; + } while (--i); + } + if (cval != 0) + { + cval = cval << 24 | cval << 16 | cval << 8 | cval; + } + + idest = (u32 *)(cdest - 3); + i = n >> 5; + if (i != 0) + { + do + { + idest[1] = cval; // 4 + idest[2] = cval; // 8 + idest[3] = cval; // c + idest[4] = cval; // 10 + idest[5] = cval; // 14 + idest[6] = cval; // 18 + idest[7] = cval; // 1c + *(idest += 8) = cval; // 20 + } while (--i); + } + + i = (n >> 2) & 7; + + if (i != 0) + { + do + { + *++idest = cval; + } while (--i); + } + + cdest = (u8 *)idest + 3; + n &= 3; + } + if (n != 0) + { + do + { + *++cdest = (u8)cval; + } while (--n); + } +} + +void *memset(void *dst, int c, size_t n) +{ + __fill_mem(dst, c, n); + return dst; +} \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/Runtime/__va_arg.c b/libs/PowerPC_EABI_Support/src/Runtime/__va_arg.c new file mode 100644 index 000000000..e06cf858e --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/__va_arg.c @@ -0,0 +1,44 @@ +#include "types.h" +#include "PowerPC_EABI_Support/Runtime/__va_arg.h" + +void* __va_arg(struct va_list* v_list, s32 type) +{ + char* addr; + char* reg = &(v_list->mG_register); + s32 g_reg = v_list->mG_register; + s32 maxsize = 8; + s32 size = 4; + s32 increment = 1; + s32 even = 0; + s32 fpr_offset = 0; + s32 regsize = 4; + + if (type == 3) { + reg = &(v_list->mFloat_register); + g_reg = v_list->mFloat_register; + size = 8; + fpr_offset = 32; + regsize = 8; + } + if (type == 2) { + size = 8; + maxsize--; + if (g_reg & 1) + even = 1; + increment = 2; + } + if (g_reg < maxsize) { + g_reg += even; + addr = v_list->mReg_save_area + fpr_offset + (g_reg * regsize); + *reg = g_reg + increment; + } else { + *reg = 8; + addr = v_list->mInput_arg_area; + addr = (char*)(((u32)(addr) + ((size)-1)) & ~((size)-1)); + v_list->mInput_arg_area = addr + size; + } + if (type == 0) + addr = *((char**)addr); + + return addr; +} diff --git a/libs/PowerPC_EABI_Support/src/Runtime/global_destructor_chain.c b/libs/PowerPC_EABI_Support/src/Runtime/global_destructor_chain.c new file mode 100644 index 000000000..c017fde19 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/global_destructor_chain.c @@ -0,0 +1,32 @@ +#include "PowerPC_EABI_Support/Runtime/global_destructor_chain.h" +#include "PowerPC_EABI_Support/Runtime/MWCPlusPlusLib.h" + +DestructorChain *__global_destructor_chain; + +void *__register_global_object(void *object, void *destructor, void *regmem) +{ + ((DestructorChain *)regmem)->next = __global_destructor_chain; + ((DestructorChain *)regmem)->destructor = destructor; + ((DestructorChain *)regmem)->object = object; + __global_destructor_chain = (DestructorChain *)regmem; + + return object; +} + +void __destroy_global_chain(void) +{ + DestructorChain *iter; + + while ((iter = __global_destructor_chain) != 0) + { + __global_destructor_chain = iter->next; + DTORCALL_COMPLETE(iter->destructor, iter->object); + } +} + +// unused +int __register_atexit(void (*func)(void)) +{ +} + +__declspec(section ".dtors") static void *const __destroy_global_chain_reference = __destroy_global_chain; diff --git a/libs/PowerPC_EABI_Support/src/Runtime/ptmf.c b/libs/PowerPC_EABI_Support/src/Runtime/ptmf.c new file mode 100644 index 000000000..ce716ecf4 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/ptmf.c @@ -0,0 +1,104 @@ +// presumably, ptmf = pointer to member function + +typedef struct PTMF { + long this_delta; // self-explanatory + long v_offset; // vtable offset + union { + void* f_addr; // function address + long ve_offset; // virtual function entry offset (of vtable) + } f_data; +} PTMF; + +const PTMF __ptmf_null = { 0, 0, 0 }; + +long __ptmf_test(PTMF *ptmf); +long __ptmf_cmpr(PTMF *ptmf1, PTMF *ptmf2); +void __ptmf_scall(...); + +// clang-format off +asm long __ptmf_test(register PTMF* ptmf) +{ + nofralloc + lwz r5, PTMF.this_delta(r3) + lwz r6, PTMF.v_offset(r3) + lwz r7, PTMF.f_data(r3) + li r3, 0x1 + cmpwi r5, 0 + cmpwi cr6, r6, 0 + cmpwi cr7, r7, 0 + bnelr- + bnelr- cr6 + bnelr- cr7 + li r3, 0 + blr +} + + +asm long __ptmf_cmpr(PTMF *ptmf1, PTMF *ptmf2) +{ + nofralloc + lwz r5, PTMF.this_delta(r3) + lwz r6, PTMF.this_delta(r4) + lwz r7, PTMF.v_offset(r3) + lwz r8, PTMF.v_offset(r4) + lwz r9, PTMF.f_data(r3) + lwz r10, PTMF.f_data(r4) + li r3, 1 + cmpw r5, r6 + cmpw cr6, r7, r8 + cmpw cr7, r9, r10 + bnelr- + bnelr- cr6 + bnelr- cr7 + li r3, 0 + blr +} + + +/*void __ptmf_call(void) +{ + // UNUSED FUNCTION +}*/ + +/*void __ptmf_call4(void) +{ + // UNUSED FUNCTION +}*/ + +asm void __ptmf_scall(...) +{ + nofralloc + lwz r0, PTMF.this_delta(r12) + lwz r11, PTMF.v_offset(r12) + lwz r12, PTMF.f_data(r12) + add r3, r3, r0 + cmpwi r11, 0 + blt- cr0, loc_0x20 + lwzx r12, r3, r12 + lwzx r12, r12, r11 + loc_0x20: + mtctr r12 + bctr +} + +// clang-format on +asm void __ptmf_scall4(...) +{ + nofralloc + lwz r0, PTMF.this_delta(r12) + lwz r11, PTMF.v_offset(r12) + lwz r12, PTMF.f_data(r12) + add r4, r4, r0 + cmpwi r11, 0 + blt- cr0, loc_0x20 + lwzx r12, r4, r12 + lwzx r12, r12, r11 + loc_0x20: + mtctr r12 + bctr +} + +/*void __ptmf_cast(void) +{ + // UNUSED FUNCTION +}*/ diff --git a/libs/PowerPC_EABI_Support/src/Runtime/runtime.c b/libs/PowerPC_EABI_Support/src/Runtime/runtime.c new file mode 100644 index 000000000..68cb136c6 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/runtime.c @@ -0,0 +1,920 @@ +#ifdef __cplusplus +extern "C" { +#endif + +/* macros for GPR/FPR resting and saving */ +#define SAVE_FPR(reg) _savefpr_##reg +#define RESTORE_FPR(reg) _restfpr_##reg +#define SAVE_GPR(reg) _savegpr_##reg +#define RESTORE_GPR(reg) _restgpr_##reg +#define ENTRY_SAVE_FPR(reg) entry SAVE_FPR(reg) +#define ENTRY_RESTORE_FPR(reg) entry RESTORE_FPR(reg) +#define ENTRY_SAVE_GPR(reg) entry SAVE_GPR(reg) +#define ENTRY_RESTORE_GPR(reg) entry RESTORE_GPR(reg) +#define SAVE_FPR2(reg) _savef##reg +#define RESTORE_FPR2(reg) _restf##reg +#define ENTRY_SAVE_FPR2(reg) +#define ENTRY_RESTORE_FPR2(reg) + +#define save_restore_reg r11 + +asm void __div2u(void); +asm void __div2i(void); +asm void __mod2u(void); +asm void __mod2i(void); +asm void __shl2i(void); +asm void __shr2u(void); +asm void __shr2i(void); +asm void __cvt_sll_dbl(void); +asm void __cvt_ull_dbl(void); +asm void __cvt_sll_flt(void); +asm void __cvt_ull_flt(void); +asm void __cvt_dbl_usll(void); +asm void __cvt_dbl_ull(void); + +void SAVE_FPR(14)(void); +void SAVE_FPR(15)(void); +void SAVE_FPR(16)(void); +void SAVE_FPR(17)(void); +void SAVE_FPR(18)(void); +void SAVE_FPR(19)(void); +void SAVE_FPR(20)(void); +void SAVE_FPR(21)(void); +void SAVE_FPR(22)(void); +void SAVE_FPR(23)(void); +void SAVE_FPR(24)(void); +void SAVE_FPR(25)(void); +void SAVE_FPR(26)(void); +void SAVE_FPR(27)(void); +void SAVE_FPR(28)(void); +void SAVE_FPR(29)(void); +void SAVE_FPR(30)(void); +void SAVE_FPR(31)(void); +void SAVE_FPR2(14)(void); +void SAVE_FPR2(15)(void); +void SAVE_FPR2(16)(void); +void SAVE_FPR2(17)(void); +void SAVE_FPR2(18)(void); +void SAVE_FPR2(19)(void); +void SAVE_FPR2(20)(void); +void SAVE_FPR2(21)(void); +void SAVE_FPR2(22)(void); +void SAVE_FPR2(23)(void); +void SAVE_FPR2(24)(void); +void SAVE_FPR2(25)(void); +void SAVE_FPR2(26)(void); +void SAVE_FPR2(27)(void); +void SAVE_FPR2(28)(void); +void SAVE_FPR2(29)(void); +void SAVE_FPR2(30)(void); +void SAVE_FPR2(31)(void); +void RESTORE_FPR(14)(void); +void RESTORE_FPR(15)(void); +void RESTORE_FPR(16)(void); +void RESTORE_FPR(17)(void); +void RESTORE_FPR(18)(void); +void RESTORE_FPR(19)(void); +void RESTORE_FPR(20)(void); +void RESTORE_FPR(21)(void); +void RESTORE_FPR(22)(void); +void RESTORE_FPR(23)(void); +void RESTORE_FPR(24)(void); +void RESTORE_FPR(25)(void); +void RESTORE_FPR(26)(void); +void RESTORE_FPR(27)(void); +void RESTORE_FPR(28)(void); +void RESTORE_FPR(29)(void); +void RESTORE_FPR(30)(void); +void RESTORE_FPR(31)(void); +void RESTORE_FPR2(14)(void); +void RESTORE_FPR2(15)(void); +void RESTORE_FPR2(16)(void); +void RESTORE_FPR2(17)(void); +void RESTORE_FPR2(18)(void); +void RESTORE_FPR2(19)(void); +void RESTORE_FPR2(20)(void); +void RESTORE_FPR2(21)(void); +void RESTORE_FPR2(22)(void); +void RESTORE_FPR2(23)(void); +void RESTORE_FPR2(24)(void); +void RESTORE_FPR2(25)(void); +void RESTORE_FPR2(26)(void); +void RESTORE_FPR2(27)(void); +void RESTORE_FPR2(28)(void); +void RESTORE_FPR2(29)(void); +void RESTORE_FPR2(30)(void); +void RESTORE_FPR2(31)(void); +void SAVE_GPR(14)(void); +void SAVE_GPR(15)(void); +void SAVE_GPR(16)(void); +void SAVE_GPR(17)(void); +void SAVE_GPR(18)(void); +void SAVE_GPR(19)(void); +void SAVE_GPR(20)(void); +void SAVE_GPR(21)(void); +void SAVE_GPR(22)(void); +void SAVE_GPR(23)(void); +void SAVE_GPR(24)(void); +void SAVE_GPR(25)(void); +void SAVE_GPR(26)(void); +void SAVE_GPR(27)(void); +void SAVE_GPR(28)(void); +void SAVE_GPR(29)(void); +void SAVE_GPR(30)(void); +void SAVE_GPR(31)(void); +void RESTORE_GPR(14)(void); +void RESTORE_GPR(15)(void); +void RESTORE_GPR(16)(void); +void RESTORE_GPR(17)(void); +void RESTORE_GPR(18)(void); +void RESTORE_GPR(19)(void); +void RESTORE_GPR(20)(void); +void RESTORE_GPR(21)(void); +void RESTORE_GPR(22)(void); +void RESTORE_GPR(23)(void); +void RESTORE_GPR(24)(void); +void RESTORE_GPR(25)(void); +void RESTORE_GPR(26)(void); +void RESTORE_GPR(27)(void); +void RESTORE_GPR(28)(void); +void RESTORE_GPR(29)(void); +void RESTORE_GPR(30)(void); +void RESTORE_GPR(31)(void); + +static const unsigned long __constants[] = { + 0x00000000, 0x00000000, 0x41F00000, 0x00000000, 0x41E00000, 0x00000000, +}; + +asm unsigned long __cvt_fp2unsigned(register double d) +{ + nofralloc stwu r1, -16(r1)lis r4, __constants @h ori r4, r4, __constants @l li r3, 0 lfd fp0, + 0(r4)lfd fp3, 8(r4)lfd fp4, 16(r4)fcmpu cr0, fp1, fp0 fcmpu cr6, fp1, fp3 blt cr0, + @exit addi r3, r3, -1 bge cr6, @exit fcmpu cr7, fp1, fp4 fmr fp2, fp1 blt cr7, @1 fsub fp2, + fp1, fp4 @1 fctiwz fp2, fp2 stfd fp2, 8(r1)lwz r3, 12(r1)blt cr7, @exit addis r3, r3, + -0x8000 @exit : addi r1, r1, 16 blr +} + +static asm void __save_fpr(void) +{ + nofralloc ENTRY_SAVE_FPR(14) ENTRY_SAVE_FPR2(14) stfd fp14, + -144(save_restore_reg)ENTRY_SAVE_FPR(15) ENTRY_SAVE_FPR2(15) stfd fp15, + -136(save_restore_reg)ENTRY_SAVE_FPR(16) ENTRY_SAVE_FPR2(16) stfd fp16, + -128(save_restore_reg)ENTRY_SAVE_FPR(17) ENTRY_SAVE_FPR2(17) stfd fp17, + -120(save_restore_reg)ENTRY_SAVE_FPR(18) ENTRY_SAVE_FPR2(18) stfd fp18, + -112(save_restore_reg)ENTRY_SAVE_FPR(19) ENTRY_SAVE_FPR2(19) stfd fp19, + -104(save_restore_reg)ENTRY_SAVE_FPR(20) ENTRY_SAVE_FPR2(20) stfd fp20, + -96(save_restore_reg)ENTRY_SAVE_FPR(21) ENTRY_SAVE_FPR2(21) stfd fp21, + -88(save_restore_reg)ENTRY_SAVE_FPR(22) ENTRY_SAVE_FPR2(22) stfd fp22, + -80(save_restore_reg)ENTRY_SAVE_FPR(23) ENTRY_SAVE_FPR2(23) stfd fp23, + -72(save_restore_reg)ENTRY_SAVE_FPR(24) ENTRY_SAVE_FPR2(24) stfd fp24, + -64(save_restore_reg)ENTRY_SAVE_FPR(25) ENTRY_SAVE_FPR2(25) stfd fp25, + -56(save_restore_reg)ENTRY_SAVE_FPR(26) ENTRY_SAVE_FPR2(26) stfd fp26, + -48(save_restore_reg)ENTRY_SAVE_FPR(27) ENTRY_SAVE_FPR2(27) stfd fp27, + -40(save_restore_reg)ENTRY_SAVE_FPR(28) ENTRY_SAVE_FPR2(28) stfd fp28, + -32(save_restore_reg)ENTRY_SAVE_FPR(29) ENTRY_SAVE_FPR2(29) stfd fp29, + -24(save_restore_reg)ENTRY_SAVE_FPR(30) ENTRY_SAVE_FPR2(30) stfd fp30, + -16(save_restore_reg)ENTRY_SAVE_FPR(31) ENTRY_SAVE_FPR2(31) stfd fp31, + -8(save_restore_reg)blr +} + +static asm void __restore_fpr(void) +{ + nofralloc ENTRY_RESTORE_FPR(14) ENTRY_RESTORE_FPR2(14) lfd fp14, + -144(save_restore_reg)ENTRY_RESTORE_FPR(15) ENTRY_RESTORE_FPR2(15) lfd fp15, + -136(save_restore_reg)ENTRY_RESTORE_FPR(16) ENTRY_RESTORE_FPR2(16) lfd fp16, + -128(save_restore_reg)ENTRY_RESTORE_FPR(17) ENTRY_RESTORE_FPR2(17) lfd fp17, + -120(save_restore_reg)ENTRY_RESTORE_FPR(18) ENTRY_RESTORE_FPR2(18) lfd fp18, + -112(save_restore_reg)ENTRY_RESTORE_FPR(19) ENTRY_RESTORE_FPR2(19) lfd fp19, + -104(save_restore_reg)ENTRY_RESTORE_FPR(20) ENTRY_RESTORE_FPR2(20) lfd fp20, + -96(save_restore_reg)ENTRY_RESTORE_FPR(21) ENTRY_RESTORE_FPR2(21) lfd fp21, + -88(save_restore_reg)ENTRY_RESTORE_FPR(22) ENTRY_RESTORE_FPR2(22) lfd fp22, + -80(save_restore_reg)ENTRY_RESTORE_FPR(23) ENTRY_RESTORE_FPR2(23) lfd fp23, + -72(save_restore_reg)ENTRY_RESTORE_FPR(24) ENTRY_RESTORE_FPR2(24) lfd fp24, + -64(save_restore_reg)ENTRY_RESTORE_FPR(25) ENTRY_RESTORE_FPR2(25) lfd fp25, + -56(save_restore_reg)ENTRY_RESTORE_FPR(26) ENTRY_RESTORE_FPR2(26) lfd fp26, + -48(save_restore_reg)ENTRY_RESTORE_FPR(27) ENTRY_RESTORE_FPR2(27) lfd fp27, + -40(save_restore_reg)ENTRY_RESTORE_FPR(28) ENTRY_RESTORE_FPR2(28) lfd fp28, + -32(save_restore_reg)ENTRY_RESTORE_FPR(29) ENTRY_RESTORE_FPR2(29) lfd fp29, + -24(save_restore_reg)ENTRY_RESTORE_FPR(30) ENTRY_RESTORE_FPR2(30) lfd fp30, + -16(save_restore_reg)ENTRY_RESTORE_FPR(31) ENTRY_RESTORE_FPR2(31) lfd fp31, + -8(save_restore_reg)blr +} + +static asm void __save_gpr(void) +{ + nofralloc ENTRY_SAVE_GPR(14) stw r14, -72(save_restore_reg)ENTRY_SAVE_GPR(15) stw r15, + -68(save_restore_reg)ENTRY_SAVE_GPR(16) stw r16, + -64(save_restore_reg)ENTRY_SAVE_GPR(17) stw r17, + -60(save_restore_reg)ENTRY_SAVE_GPR(18) stw r18, + -56(save_restore_reg)ENTRY_SAVE_GPR(19) stw r19, + -52(save_restore_reg)ENTRY_SAVE_GPR(20) stw r20, + -48(save_restore_reg)ENTRY_SAVE_GPR(21) stw r21, + -44(save_restore_reg)ENTRY_SAVE_GPR(22) stw r22, + -40(save_restore_reg)ENTRY_SAVE_GPR(23) stw r23, + -36(save_restore_reg)ENTRY_SAVE_GPR(24) stw r24, + -32(save_restore_reg)ENTRY_SAVE_GPR(25) stw r25, + -28(save_restore_reg)ENTRY_SAVE_GPR(26) stw r26, + -24(save_restore_reg)ENTRY_SAVE_GPR(27) stw r27, + -20(save_restore_reg)ENTRY_SAVE_GPR(28) stw r28, + -16(save_restore_reg)ENTRY_SAVE_GPR(29) stw r29, + -12(save_restore_reg)ENTRY_SAVE_GPR(30) stw r30, + -8(save_restore_reg)ENTRY_SAVE_GPR(31) stw r31, -4(save_restore_reg)blr +} + +static asm void __restore_gpr(void) +{ + nofralloc ENTRY_RESTORE_GPR(14) lwz r14, -72(save_restore_reg)ENTRY_RESTORE_GPR(15) lwz r15, + -68(save_restore_reg)ENTRY_RESTORE_GPR(16) lwz r16, + -64(save_restore_reg)ENTRY_RESTORE_GPR(17) lwz r17, + -60(save_restore_reg)ENTRY_RESTORE_GPR(18) lwz r18, + -56(save_restore_reg)ENTRY_RESTORE_GPR(19) lwz r19, + -52(save_restore_reg)ENTRY_RESTORE_GPR(20) lwz r20, + -48(save_restore_reg)ENTRY_RESTORE_GPR(21) lwz r21, + -44(save_restore_reg)ENTRY_RESTORE_GPR(22) lwz r22, + -40(save_restore_reg)ENTRY_RESTORE_GPR(23) lwz r23, + -36(save_restore_reg)ENTRY_RESTORE_GPR(24) lwz r24, + -32(save_restore_reg)ENTRY_RESTORE_GPR(25) lwz r25, + -28(save_restore_reg)ENTRY_RESTORE_GPR(26) lwz r26, + -24(save_restore_reg)ENTRY_RESTORE_GPR(27) lwz r27, + -20(save_restore_reg)ENTRY_RESTORE_GPR(28) lwz r28, + -16(save_restore_reg)ENTRY_RESTORE_GPR(29) lwz r29, + -12(save_restore_reg)ENTRY_RESTORE_GPR(30) lwz r30, + -8(save_restore_reg)ENTRY_RESTORE_GPR(31) lwz r31, -4(save_restore_reg)blr +} + +asm void __div2u(void) +{ + nofralloc cmpwi cr0, r3, 0 cntlzw r0, r3 cntlzw r9, r4 bne cr0, lab1 addi r0, r9, + 32 lab1 : cmpwi cr0, + r5, + 0 cntlzw r9, + r5 cntlzw r10, + r6 bne cr0, + lab2 addi r9, + r10, + 32 lab2 : cmpw cr0, + r0, + r9 subfic r10, + r0, + 64 bgt cr0, + lab9 addi r9, + r9, + 1 subfic r9, + r9, + 64 add r0, + r0, + r9 subf r9, + r9, + r10 mtctr r9 cmpwi cr0, + r9, + 32 addi r7, + r9, + -32 blt cr0, + lab3 srw r8, + r3, + r7 li r7, + 0 b lab4 lab3 : srw r8, + r4, + r9 subfic r7, + r9, + 32 slw r7, + r3, + r7 or r8, + r8, + r7 srw r7, + r3, + r9 lab4 : cmpwi cr0, + r0, + 32 addic r9, + r0, + -32 blt cr0, + lab5 slw r3, + r4, + r9 li r4, + 0 b lab6 lab5 : slw r3, + r3, + r0 subfic r9, + r0, + 32 srw r9, + r4, + r9 or r3, + r3, + r9 slw r4, + r4, + r0 lab6 : li r10, + -1 addic r7, + r7, + 0 lab7 + : adde r4, + r4, + r4 adde r3, + r3, + r3 adde r8, + r8, + r8 adde r7, + r7, + r7 subfc r0, + r6, + r8 subfe.r9, + r5, + r7 blt cr0, + lab8 mr r8, + r0 mr r7, + r9 addic r0, + r10, + 1 lab8 : bdnz lab7 adde r4, + r4, + r4 adde r3, + r3, + r3 blr lab9 : li r4, + 0 li r3, + 0 blr +} + +#pragma push +#pragma optimization_level 0 +#pragma optimizewithasm off +asm void __div2i(void) +{ + nofralloc stwu r1, -16(r1)rlwinm.r9, r3, 0, 0, 0 beq cr0, positive1 subfic r4, r4, 0 subfze r3, + r3 positive1 : stw r9, + 8(r1)rlwinm.r10, + r5, + 0, + 0, + 0 beq cr0, + positive2 subfic r6, + r6, + 0 subfze r5, + r5 positive2 : stw r10, + 12(r1)cmpwi cr0, + r3, + 0 cntlzw r0, + r3 cntlzw r9, + r4 bne cr0, + lab1 addi r0, + r9, + 32 lab1 : cmpwi cr0, + r5, + 0 cntlzw r9, + r5 cntlzw r10, + r6 bne cr0, + lab2 addi r9, + r10, + 32 lab2 : cmpw cr0, + r0, + r9 subfic r10, + r0, + 64 bgt cr0, + lab9 addi r9, + r9, + 1 subfic r9, + r9, + 64 add r0, + r0, + r9 subf r9, + r9, + r10 mtctr r9 cmpwi cr0, + r9, + 32 addi r7, + r9, + -32 blt cr0, + lab3 srw r8, + r3, + r7 li r7, + 0 b lab4 lab3 : srw r8, + r4, + r9 subfic r7, + r9, + 32 slw r7, + r3, + r7 or r8, + r8, + r7 srw r7, + r3, + r9 lab4 : cmpwi cr0, + r0, + 32 addic r9, + r0, + -32 blt cr0, + lab5 slw r3, + r4, + r9 li r4, + 0 b lab6 lab5 + : slw r3, + r3, + r0 subfic r9, + r0, + 32 srw r9, + r4, + r9 or r3, + r3, + r9 slw r4, + r4, + r0 lab6 : li r10, + -1 addic r7, + r7, + 0 lab7 : adde r4, + r4, + r4 adde r3, + r3, + r3 adde r8, + r8, + r8 adde r7, + r7, + r7 subfc r0, + r6, + r8 subfe.r9, + r5, + r7 blt cr0, + lab8 mr r8, + r0 mr r7, + r9 addic r0, + r10, + 1 lab8 : bdnz lab7 adde r4, + r4, + r4 adde r3, + r3, + r3 lwz r9, + 8(r1)lwz r10, + 12(r1) xor.r7, + r9, + r10 beq func_end cmpwi cr0, + r9, + 0 subfic r4, + r4, + 0 subfze r3, + r3 + + no_adjust : b func_end + + lab9 : li r4, + 0 li r3, + 0 func_end : addi r1, + r1, + 16 blr +} +#pragma pop + +#pragma push +#pragma optimization_level 0 +#pragma optimizewithasm off +asm void __mod2u(void) +{ + nofralloc cmpwi cr0, r3, 0 cntlzw r0, r3 cntlzw r9, r4 bne cr0, lab1 addi r0, r9, + 32 lab1 : cmpwi cr0, + r5, + 0 cntlzw r9, + r5 cntlzw r10, + r6 bne cr0, + lab2 addi r9, + r10, + 32 lab2 : cmpw cr0, + r0, + r9 subfic r10, + r0, + 64 bgtlr cr0 addi r9, + r9, + 1 subfic r9, + r9, + 64 add r0, + r0, + r9 subf r9, + r9, + r10 mtctr r9 cmpwi cr0, + r9, + 32 addi r7, + r9, + -32 blt cr0, + lab3 srw r8, + r3, + r7 li r7, + 0 b lab4 lab3 : srw r8, + r4, + r9 subfic r7, + r9, + 32 slw r7, + r3, + r7 or r8, + r8, + r7 srw r7, + r3, + r9 lab4 : cmpwi cr0, + r0, + 32 addic r9, + r0, + -32 blt cr0, + lab5 slw r3, + r4, + r9 li r4, + 0 b lab6 lab5 : slw r3, + r3, + r0 subfic r9, + r0, + 32 srw r9, + r4, + r9 or r3, + r3, + r9 slw r4, + r4, + r0 lab6 : li r10, + -1 addic r7, + r7, + 0 lab7 + : adde r4, + r4, + r4 adde r3, + r3, + r3 adde r8, + r8, + r8 adde r7, + r7, + r7 subfc r0, + r6, + r8 subfe.r9, + r5, + r7 blt cr0, + lab8 mr r8, + r0 mr r7, + r9 addic r0, + r10, + 1 lab8 : bdnz lab7 mr r4, + r8 mr r3, + r7 blr lab9 : blr +} +#pragma pop + +#pragma push +#pragma optimization_level 0 +#pragma optimizewithasm off +asm void __mod2i(void) +{ + nofralloc + + cmpwi cr7, + r3, 0 bge cr7, positive1 subfic r4, r4, 0 subfze r3, + r3 positive1 : cmpwi cr0, + r5, + 0 bge cr0, + positive2 subfic r6, + r6, + 0 subfze r5, + r5 positive2 : cmpwi cr0, + r3, + 0 cntlzw r0, + r3 cntlzw r9, + r4 bne cr0, + lab1 addi r0, + r9, + 32 lab1 : cmpwi cr0, + r5, + 0 cntlzw r9, + r5 cntlzw r10, + r6 bne cr0, + lab2 addi r9, + r10, + 32 lab2 : cmpw cr0, + r0, + r9 subfic r10, + r0, + 64 bgt cr0, + lab9 addi r9, + r9, + 1 subfic r9, + r9, + 64 add r0, + r0, + r9 subf r9, + r9, + r10 mtctr r9 cmpwi cr0, + r9, + 32 addi r7, + r9, + -32 blt cr0, + lab3 srw r8, + r3, + r7 li r7, + 0 b lab4 lab3 : srw r8, + r4, + r9 subfic r7, + r9, + 32 slw r7, + r3, + r7 or r8, + r8, + r7 srw r7, + r3, + r9 lab4 : cmpwi cr0, + r0, + 32 addic r9, + r0, + -32 blt cr0, + lab5 slw r3, + r4, + r9 li r4, + 0 b lab6 lab5 + : slw r3, + r3, + r0 subfic r9, + r0, + 32 srw r9, + r4, + r9 or r3, + r3, + r9 slw r4, + r4, + r0 lab6 : li r10, + -1 addic r7, + r7, + 0 lab7 : adde r4, + r4, + r4 adde r3, + r3, + r3 adde r8, + r8, + r8 adde r7, + r7, + r7 subfc r0, + r6, + r8 subfe.r9, + r5, + r7 blt cr0, + lab8 mr r8, + r0 mr r7, + r9 addic r0, + r10, + 1 lab8 : bdnz lab7 mr r4, + r8 mr r3, + r7 lab9 : bgelr cr7 subfic r4, + r4, + 0 subfze r3, + r3 no_adjust : blr +} +#pragma pop + +asm void __shl2i(void) +{ + nofralloc subfic r8, r5, 32 subic r9, r5, 32 slw r3, r3, r5 srw r10, r4, r8 or r3, r3, + r10 slw r10, r4, r9 or r3, r3, r10 slw r4, r4, r5 blr +} + +//unused +asm void __shr2u(void) +{ + nofralloc subfic r8, r5, 32 subic r9, r5, 32 srw r4, r4, r5 slw r10, r3, r8 or r4, r4, + r10 srw r10, r3, r9 or r4, r4, r10 srw r3, r3, r5 blr +} + +asm void __shr2i(void) +{ + subfic r8, r5, 0x20 addic.r9, r5, -0x20 srw r4, r4, r5 slw r10, r3, r8 or r4, r4, r10 sraw r10, + r3, r9 ble L_802BA610 or r4, r4, r10 L_802BA610 : sraw r3, r3, r5 blr +} + +asm void __cvt_sll_dbl(void) +{ + // clang-format off + stwu r1, -0x10(r1) + rlwinm. r5, r3, 0, 0, 0 + beq- lbl_802b2b1c + subfic r4, r4, 0x0 + subfze r3, r3 +lbl_802b2b1c: + or. r7, r3, r4 + li r6, 0x0 + beq- lbl_802b2ba4 + cntlzw r7, r3 + cntlzw r8, r4 + rlwinm r9, r7, 0x1a, 0, 4 + srawi r9, r9, 0x1f + and r9, r9, r8 + add r7, r7, r9 + subfic r8, r7, 0x20 + addic r9, r7, -0x20 + slw r3, r3, r7 + srw r10, r4, r8 + or r3, r3, r10 + slw r10, r4, r9 + or r3, r3, r10 + slw r4, r4, r7 + subf r6, r7, r6 + clrlwi r7, r4, 0x15 + cmpwi r7, 0x400 + addi r6, r6, 0x43e + blt- lbl_802b2b8c + bgt- lbl_802b2b80 + rlwinm. r7, r4, 0, 0x14, 0x14 + beq- lbl_802b2b8c +lbl_802b2b80: + addic r4, r4, 0x800 + addze r3, r3 + addze r6, r6 +lbl_802b2b8c: + rotlwi r4, r4, 0x15 + rlwimi r4, r3, 0x15, 0, 0xa + rlwinm r3, r3, 0x15, 0xc, 0x1f + slwi r6, r6, 0x14 + or r3, r6, r3 + or r3, r5, r3 +lbl_802b2ba4: + stw r3, 8(r1) + stw r4, 0xc(r1) + lfd f1, 8(r1) + addi r1, r1, 0x10 + frfree + blr + // clang-format on +} + +//unused +asm void __cvt_ull_dbl(void) +{ +} + +asm void __cvt_sll_flt(void) +{ + stwu r1, -0x10(r1)clrrwi.r5, r3, 31 beq L_802BA62C subfic r4, r4, 0x0 subfze r3, + r3 L_802BA62C : or.r7, r3, r4 li r6, 0x0 beq L_802BA6B4 cntlzw r7, r3 cntlzw r8, + r4 extlwi r9, r7, 5, 26 srawi r9, r9, 31 and r9, r9, r8 add r7, r7, r9 subfic r8, r7, + 0x20 addic r9, r7, -0x20 slw r3, r3, r7 srw r10, r4, r8 or r3, r3, r10 slw r10, r4, + r9 or r3, r3, r10 slw r4, r4, r7 subf r6, r7, r6 clrlwi r7, r4, 21 cmpwi r7, 0x400 addi r6, + r6, 0x43e blt L_802BA69C bgt L_802BA690 rlwinm.r7, r4, 0, 20, + 20 beq L_802BA69C L_802BA690 : addic r4, + r4, + 0x800 addze r3, + r3 addze r6, + r6 L_802BA69C : rotrwi r4, + r4, + 11 rlwimi r4, + r3, + 21, + 0, + 10 extrwi r3, + r3, + 20, + 1 slwi r6, + r6, + 20 or r3, + r6, + r3 or r3, + r5, + r3 L_802BA6B4 : stw r3, + 0x8(r1)stw r4, + 0xc(r1)lfd f1, + 0x8(r1)frsp f1, + f1 addi r1, + r1, + 0x10 blr +} + +//unused +asm void __cvt_ull_flt(void) +{ +} + +//unused +asm void __cvt_dbl_usll(void) +{ + nofralloc stwu r1, -16(r1)stfd f1, 8(r1)lwz r3, 8(r1)lwz r4, 12(r1)rlwinm r5, r3, 12, 21, + 31 cmpli cr0, 0, r5, 1023 bge cr0, not_fraction li r3, 0 li r4, + 0 b func_end not_fraction : mr r6, + r3 rlwinm r3, + r3, + 0, + 12, + 31 oris r3, + r3, + 0x0010 addi r5, + r5, + -1075 cmpwi cr0, + r5, + 0 bge cr0, + left neg r5, + r5 subfic r8, + r5, + 32 subic r9, + r5, + 32 srw r4, + r4, + r5 slw r10, + r3, + r8 or r4, + r4, + r10 srw r10, + r3, + r9 or r4, + r4, + r10 srw r3, + r3, + r5 b around left : cmpwi cr0, + r5, + 10 ble + no_overflow rlwinm.r6, + r6, + 0, + 0, + 0 beq cr0, + max_positive lis r3, + 0x8000 li r4, + 0 b func_end max_positive + : lis r3, + 0x7FFF ori r3, + r3, + 0xFFFF li r4, + -1 b func_end no_overflow : subfic r8, + r5, + 32 subic r9, + r5, + 32 slw r3, + r3, + r5 srw r10, + r4, + r8 or r3, + r3, + r10 slw r10, + r4, + r9 or r3, + r3, + r10 slw r4, + r4, + r5 around : rlwinm.r6, + r6, + 0, + 0, + 0 beq cr0, + positive subfic r4, + r4, + 0 subfze r3, + r3 positive : func_end : addi r1, + r1, + 16 blr +} + +void __cvt_dbl_ull(void) +{ + nofralloc stwu r1, -0x10(r1)stfd f1, 8(r1)lwz r3, 8(r1)lwz r4, 0xC(r1)extrwi r5, r3, 11, + 1 cmplwi r5, + 0x3FF bge loc_80518FB4 + + loc_80518FA8 : li r3, + 0 li r4, + 0 b end + + loc_80518FB4 : clrrwi.r6, + r3, + 31 bne loc_80518FA8 clrlwi r3, + r3, + 12 oris r3, + r3, + 0x10 addi r5, + r5, + -0x433 cmpwi r5, + 0 bge loc_80518FF8 neg r5, + r5 subfic r8, + r5, + 0x20 addic r9, + r5, + -0x20 srw r4, + r4, + r5 slw r10, + r3, + r8 or r4, + r4, + r10 srw r10, + r3, + r9 or r4, + r4, + r10 srw r3, + r3, + r5 b end + + loc_80518FF8 : cmpwi r5, + 0xB ble + loc_8051900C li r3, + -1 li r4, + -1 b end + + loc_8051900C : subfic r8, + r5, + 0x20 addic r9, + r5, + -0x20 slw r3, + r3, + r5 srw r10, + r4, + r8 or r3, + r3, + r10 slw r10, + r4, + r9 or r3, + r3, + r10 slw r4, + r4, + r5 + + end : addi r1, + r1, + 0x10 blr +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/runtime3/READ_ME.txt b/libs/PowerPC_EABI_Support/src/runtime3/READ_ME.txt new file mode 100644 index 000000000..b2a060cb8 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/runtime3/READ_ME.txt @@ -0,0 +1,6 @@ +These files are files that have issues that need to be fixed before the file can be +added back into the "Runtime" folder. + +These are outside of the scope of what I am aiming to do at the moment. + +- Colin \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/runtime3/runtime.c b/libs/PowerPC_EABI_Support/src/runtime3/runtime.c new file mode 100644 index 000000000..68cb136c6 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/runtime3/runtime.c @@ -0,0 +1,920 @@ +#ifdef __cplusplus +extern "C" { +#endif + +/* macros for GPR/FPR resting and saving */ +#define SAVE_FPR(reg) _savefpr_##reg +#define RESTORE_FPR(reg) _restfpr_##reg +#define SAVE_GPR(reg) _savegpr_##reg +#define RESTORE_GPR(reg) _restgpr_##reg +#define ENTRY_SAVE_FPR(reg) entry SAVE_FPR(reg) +#define ENTRY_RESTORE_FPR(reg) entry RESTORE_FPR(reg) +#define ENTRY_SAVE_GPR(reg) entry SAVE_GPR(reg) +#define ENTRY_RESTORE_GPR(reg) entry RESTORE_GPR(reg) +#define SAVE_FPR2(reg) _savef##reg +#define RESTORE_FPR2(reg) _restf##reg +#define ENTRY_SAVE_FPR2(reg) +#define ENTRY_RESTORE_FPR2(reg) + +#define save_restore_reg r11 + +asm void __div2u(void); +asm void __div2i(void); +asm void __mod2u(void); +asm void __mod2i(void); +asm void __shl2i(void); +asm void __shr2u(void); +asm void __shr2i(void); +asm void __cvt_sll_dbl(void); +asm void __cvt_ull_dbl(void); +asm void __cvt_sll_flt(void); +asm void __cvt_ull_flt(void); +asm void __cvt_dbl_usll(void); +asm void __cvt_dbl_ull(void); + +void SAVE_FPR(14)(void); +void SAVE_FPR(15)(void); +void SAVE_FPR(16)(void); +void SAVE_FPR(17)(void); +void SAVE_FPR(18)(void); +void SAVE_FPR(19)(void); +void SAVE_FPR(20)(void); +void SAVE_FPR(21)(void); +void SAVE_FPR(22)(void); +void SAVE_FPR(23)(void); +void SAVE_FPR(24)(void); +void SAVE_FPR(25)(void); +void SAVE_FPR(26)(void); +void SAVE_FPR(27)(void); +void SAVE_FPR(28)(void); +void SAVE_FPR(29)(void); +void SAVE_FPR(30)(void); +void SAVE_FPR(31)(void); +void SAVE_FPR2(14)(void); +void SAVE_FPR2(15)(void); +void SAVE_FPR2(16)(void); +void SAVE_FPR2(17)(void); +void SAVE_FPR2(18)(void); +void SAVE_FPR2(19)(void); +void SAVE_FPR2(20)(void); +void SAVE_FPR2(21)(void); +void SAVE_FPR2(22)(void); +void SAVE_FPR2(23)(void); +void SAVE_FPR2(24)(void); +void SAVE_FPR2(25)(void); +void SAVE_FPR2(26)(void); +void SAVE_FPR2(27)(void); +void SAVE_FPR2(28)(void); +void SAVE_FPR2(29)(void); +void SAVE_FPR2(30)(void); +void SAVE_FPR2(31)(void); +void RESTORE_FPR(14)(void); +void RESTORE_FPR(15)(void); +void RESTORE_FPR(16)(void); +void RESTORE_FPR(17)(void); +void RESTORE_FPR(18)(void); +void RESTORE_FPR(19)(void); +void RESTORE_FPR(20)(void); +void RESTORE_FPR(21)(void); +void RESTORE_FPR(22)(void); +void RESTORE_FPR(23)(void); +void RESTORE_FPR(24)(void); +void RESTORE_FPR(25)(void); +void RESTORE_FPR(26)(void); +void RESTORE_FPR(27)(void); +void RESTORE_FPR(28)(void); +void RESTORE_FPR(29)(void); +void RESTORE_FPR(30)(void); +void RESTORE_FPR(31)(void); +void RESTORE_FPR2(14)(void); +void RESTORE_FPR2(15)(void); +void RESTORE_FPR2(16)(void); +void RESTORE_FPR2(17)(void); +void RESTORE_FPR2(18)(void); +void RESTORE_FPR2(19)(void); +void RESTORE_FPR2(20)(void); +void RESTORE_FPR2(21)(void); +void RESTORE_FPR2(22)(void); +void RESTORE_FPR2(23)(void); +void RESTORE_FPR2(24)(void); +void RESTORE_FPR2(25)(void); +void RESTORE_FPR2(26)(void); +void RESTORE_FPR2(27)(void); +void RESTORE_FPR2(28)(void); +void RESTORE_FPR2(29)(void); +void RESTORE_FPR2(30)(void); +void RESTORE_FPR2(31)(void); +void SAVE_GPR(14)(void); +void SAVE_GPR(15)(void); +void SAVE_GPR(16)(void); +void SAVE_GPR(17)(void); +void SAVE_GPR(18)(void); +void SAVE_GPR(19)(void); +void SAVE_GPR(20)(void); +void SAVE_GPR(21)(void); +void SAVE_GPR(22)(void); +void SAVE_GPR(23)(void); +void SAVE_GPR(24)(void); +void SAVE_GPR(25)(void); +void SAVE_GPR(26)(void); +void SAVE_GPR(27)(void); +void SAVE_GPR(28)(void); +void SAVE_GPR(29)(void); +void SAVE_GPR(30)(void); +void SAVE_GPR(31)(void); +void RESTORE_GPR(14)(void); +void RESTORE_GPR(15)(void); +void RESTORE_GPR(16)(void); +void RESTORE_GPR(17)(void); +void RESTORE_GPR(18)(void); +void RESTORE_GPR(19)(void); +void RESTORE_GPR(20)(void); +void RESTORE_GPR(21)(void); +void RESTORE_GPR(22)(void); +void RESTORE_GPR(23)(void); +void RESTORE_GPR(24)(void); +void RESTORE_GPR(25)(void); +void RESTORE_GPR(26)(void); +void RESTORE_GPR(27)(void); +void RESTORE_GPR(28)(void); +void RESTORE_GPR(29)(void); +void RESTORE_GPR(30)(void); +void RESTORE_GPR(31)(void); + +static const unsigned long __constants[] = { + 0x00000000, 0x00000000, 0x41F00000, 0x00000000, 0x41E00000, 0x00000000, +}; + +asm unsigned long __cvt_fp2unsigned(register double d) +{ + nofralloc stwu r1, -16(r1)lis r4, __constants @h ori r4, r4, __constants @l li r3, 0 lfd fp0, + 0(r4)lfd fp3, 8(r4)lfd fp4, 16(r4)fcmpu cr0, fp1, fp0 fcmpu cr6, fp1, fp3 blt cr0, + @exit addi r3, r3, -1 bge cr6, @exit fcmpu cr7, fp1, fp4 fmr fp2, fp1 blt cr7, @1 fsub fp2, + fp1, fp4 @1 fctiwz fp2, fp2 stfd fp2, 8(r1)lwz r3, 12(r1)blt cr7, @exit addis r3, r3, + -0x8000 @exit : addi r1, r1, 16 blr +} + +static asm void __save_fpr(void) +{ + nofralloc ENTRY_SAVE_FPR(14) ENTRY_SAVE_FPR2(14) stfd fp14, + -144(save_restore_reg)ENTRY_SAVE_FPR(15) ENTRY_SAVE_FPR2(15) stfd fp15, + -136(save_restore_reg)ENTRY_SAVE_FPR(16) ENTRY_SAVE_FPR2(16) stfd fp16, + -128(save_restore_reg)ENTRY_SAVE_FPR(17) ENTRY_SAVE_FPR2(17) stfd fp17, + -120(save_restore_reg)ENTRY_SAVE_FPR(18) ENTRY_SAVE_FPR2(18) stfd fp18, + -112(save_restore_reg)ENTRY_SAVE_FPR(19) ENTRY_SAVE_FPR2(19) stfd fp19, + -104(save_restore_reg)ENTRY_SAVE_FPR(20) ENTRY_SAVE_FPR2(20) stfd fp20, + -96(save_restore_reg)ENTRY_SAVE_FPR(21) ENTRY_SAVE_FPR2(21) stfd fp21, + -88(save_restore_reg)ENTRY_SAVE_FPR(22) ENTRY_SAVE_FPR2(22) stfd fp22, + -80(save_restore_reg)ENTRY_SAVE_FPR(23) ENTRY_SAVE_FPR2(23) stfd fp23, + -72(save_restore_reg)ENTRY_SAVE_FPR(24) ENTRY_SAVE_FPR2(24) stfd fp24, + -64(save_restore_reg)ENTRY_SAVE_FPR(25) ENTRY_SAVE_FPR2(25) stfd fp25, + -56(save_restore_reg)ENTRY_SAVE_FPR(26) ENTRY_SAVE_FPR2(26) stfd fp26, + -48(save_restore_reg)ENTRY_SAVE_FPR(27) ENTRY_SAVE_FPR2(27) stfd fp27, + -40(save_restore_reg)ENTRY_SAVE_FPR(28) ENTRY_SAVE_FPR2(28) stfd fp28, + -32(save_restore_reg)ENTRY_SAVE_FPR(29) ENTRY_SAVE_FPR2(29) stfd fp29, + -24(save_restore_reg)ENTRY_SAVE_FPR(30) ENTRY_SAVE_FPR2(30) stfd fp30, + -16(save_restore_reg)ENTRY_SAVE_FPR(31) ENTRY_SAVE_FPR2(31) stfd fp31, + -8(save_restore_reg)blr +} + +static asm void __restore_fpr(void) +{ + nofralloc ENTRY_RESTORE_FPR(14) ENTRY_RESTORE_FPR2(14) lfd fp14, + -144(save_restore_reg)ENTRY_RESTORE_FPR(15) ENTRY_RESTORE_FPR2(15) lfd fp15, + -136(save_restore_reg)ENTRY_RESTORE_FPR(16) ENTRY_RESTORE_FPR2(16) lfd fp16, + -128(save_restore_reg)ENTRY_RESTORE_FPR(17) ENTRY_RESTORE_FPR2(17) lfd fp17, + -120(save_restore_reg)ENTRY_RESTORE_FPR(18) ENTRY_RESTORE_FPR2(18) lfd fp18, + -112(save_restore_reg)ENTRY_RESTORE_FPR(19) ENTRY_RESTORE_FPR2(19) lfd fp19, + -104(save_restore_reg)ENTRY_RESTORE_FPR(20) ENTRY_RESTORE_FPR2(20) lfd fp20, + -96(save_restore_reg)ENTRY_RESTORE_FPR(21) ENTRY_RESTORE_FPR2(21) lfd fp21, + -88(save_restore_reg)ENTRY_RESTORE_FPR(22) ENTRY_RESTORE_FPR2(22) lfd fp22, + -80(save_restore_reg)ENTRY_RESTORE_FPR(23) ENTRY_RESTORE_FPR2(23) lfd fp23, + -72(save_restore_reg)ENTRY_RESTORE_FPR(24) ENTRY_RESTORE_FPR2(24) lfd fp24, + -64(save_restore_reg)ENTRY_RESTORE_FPR(25) ENTRY_RESTORE_FPR2(25) lfd fp25, + -56(save_restore_reg)ENTRY_RESTORE_FPR(26) ENTRY_RESTORE_FPR2(26) lfd fp26, + -48(save_restore_reg)ENTRY_RESTORE_FPR(27) ENTRY_RESTORE_FPR2(27) lfd fp27, + -40(save_restore_reg)ENTRY_RESTORE_FPR(28) ENTRY_RESTORE_FPR2(28) lfd fp28, + -32(save_restore_reg)ENTRY_RESTORE_FPR(29) ENTRY_RESTORE_FPR2(29) lfd fp29, + -24(save_restore_reg)ENTRY_RESTORE_FPR(30) ENTRY_RESTORE_FPR2(30) lfd fp30, + -16(save_restore_reg)ENTRY_RESTORE_FPR(31) ENTRY_RESTORE_FPR2(31) lfd fp31, + -8(save_restore_reg)blr +} + +static asm void __save_gpr(void) +{ + nofralloc ENTRY_SAVE_GPR(14) stw r14, -72(save_restore_reg)ENTRY_SAVE_GPR(15) stw r15, + -68(save_restore_reg)ENTRY_SAVE_GPR(16) stw r16, + -64(save_restore_reg)ENTRY_SAVE_GPR(17) stw r17, + -60(save_restore_reg)ENTRY_SAVE_GPR(18) stw r18, + -56(save_restore_reg)ENTRY_SAVE_GPR(19) stw r19, + -52(save_restore_reg)ENTRY_SAVE_GPR(20) stw r20, + -48(save_restore_reg)ENTRY_SAVE_GPR(21) stw r21, + -44(save_restore_reg)ENTRY_SAVE_GPR(22) stw r22, + -40(save_restore_reg)ENTRY_SAVE_GPR(23) stw r23, + -36(save_restore_reg)ENTRY_SAVE_GPR(24) stw r24, + -32(save_restore_reg)ENTRY_SAVE_GPR(25) stw r25, + -28(save_restore_reg)ENTRY_SAVE_GPR(26) stw r26, + -24(save_restore_reg)ENTRY_SAVE_GPR(27) stw r27, + -20(save_restore_reg)ENTRY_SAVE_GPR(28) stw r28, + -16(save_restore_reg)ENTRY_SAVE_GPR(29) stw r29, + -12(save_restore_reg)ENTRY_SAVE_GPR(30) stw r30, + -8(save_restore_reg)ENTRY_SAVE_GPR(31) stw r31, -4(save_restore_reg)blr +} + +static asm void __restore_gpr(void) +{ + nofralloc ENTRY_RESTORE_GPR(14) lwz r14, -72(save_restore_reg)ENTRY_RESTORE_GPR(15) lwz r15, + -68(save_restore_reg)ENTRY_RESTORE_GPR(16) lwz r16, + -64(save_restore_reg)ENTRY_RESTORE_GPR(17) lwz r17, + -60(save_restore_reg)ENTRY_RESTORE_GPR(18) lwz r18, + -56(save_restore_reg)ENTRY_RESTORE_GPR(19) lwz r19, + -52(save_restore_reg)ENTRY_RESTORE_GPR(20) lwz r20, + -48(save_restore_reg)ENTRY_RESTORE_GPR(21) lwz r21, + -44(save_restore_reg)ENTRY_RESTORE_GPR(22) lwz r22, + -40(save_restore_reg)ENTRY_RESTORE_GPR(23) lwz r23, + -36(save_restore_reg)ENTRY_RESTORE_GPR(24) lwz r24, + -32(save_restore_reg)ENTRY_RESTORE_GPR(25) lwz r25, + -28(save_restore_reg)ENTRY_RESTORE_GPR(26) lwz r26, + -24(save_restore_reg)ENTRY_RESTORE_GPR(27) lwz r27, + -20(save_restore_reg)ENTRY_RESTORE_GPR(28) lwz r28, + -16(save_restore_reg)ENTRY_RESTORE_GPR(29) lwz r29, + -12(save_restore_reg)ENTRY_RESTORE_GPR(30) lwz r30, + -8(save_restore_reg)ENTRY_RESTORE_GPR(31) lwz r31, -4(save_restore_reg)blr +} + +asm void __div2u(void) +{ + nofralloc cmpwi cr0, r3, 0 cntlzw r0, r3 cntlzw r9, r4 bne cr0, lab1 addi r0, r9, + 32 lab1 : cmpwi cr0, + r5, + 0 cntlzw r9, + r5 cntlzw r10, + r6 bne cr0, + lab2 addi r9, + r10, + 32 lab2 : cmpw cr0, + r0, + r9 subfic r10, + r0, + 64 bgt cr0, + lab9 addi r9, + r9, + 1 subfic r9, + r9, + 64 add r0, + r0, + r9 subf r9, + r9, + r10 mtctr r9 cmpwi cr0, + r9, + 32 addi r7, + r9, + -32 blt cr0, + lab3 srw r8, + r3, + r7 li r7, + 0 b lab4 lab3 : srw r8, + r4, + r9 subfic r7, + r9, + 32 slw r7, + r3, + r7 or r8, + r8, + r7 srw r7, + r3, + r9 lab4 : cmpwi cr0, + r0, + 32 addic r9, + r0, + -32 blt cr0, + lab5 slw r3, + r4, + r9 li r4, + 0 b lab6 lab5 : slw r3, + r3, + r0 subfic r9, + r0, + 32 srw r9, + r4, + r9 or r3, + r3, + r9 slw r4, + r4, + r0 lab6 : li r10, + -1 addic r7, + r7, + 0 lab7 + : adde r4, + r4, + r4 adde r3, + r3, + r3 adde r8, + r8, + r8 adde r7, + r7, + r7 subfc r0, + r6, + r8 subfe.r9, + r5, + r7 blt cr0, + lab8 mr r8, + r0 mr r7, + r9 addic r0, + r10, + 1 lab8 : bdnz lab7 adde r4, + r4, + r4 adde r3, + r3, + r3 blr lab9 : li r4, + 0 li r3, + 0 blr +} + +#pragma push +#pragma optimization_level 0 +#pragma optimizewithasm off +asm void __div2i(void) +{ + nofralloc stwu r1, -16(r1)rlwinm.r9, r3, 0, 0, 0 beq cr0, positive1 subfic r4, r4, 0 subfze r3, + r3 positive1 : stw r9, + 8(r1)rlwinm.r10, + r5, + 0, + 0, + 0 beq cr0, + positive2 subfic r6, + r6, + 0 subfze r5, + r5 positive2 : stw r10, + 12(r1)cmpwi cr0, + r3, + 0 cntlzw r0, + r3 cntlzw r9, + r4 bne cr0, + lab1 addi r0, + r9, + 32 lab1 : cmpwi cr0, + r5, + 0 cntlzw r9, + r5 cntlzw r10, + r6 bne cr0, + lab2 addi r9, + r10, + 32 lab2 : cmpw cr0, + r0, + r9 subfic r10, + r0, + 64 bgt cr0, + lab9 addi r9, + r9, + 1 subfic r9, + r9, + 64 add r0, + r0, + r9 subf r9, + r9, + r10 mtctr r9 cmpwi cr0, + r9, + 32 addi r7, + r9, + -32 blt cr0, + lab3 srw r8, + r3, + r7 li r7, + 0 b lab4 lab3 : srw r8, + r4, + r9 subfic r7, + r9, + 32 slw r7, + r3, + r7 or r8, + r8, + r7 srw r7, + r3, + r9 lab4 : cmpwi cr0, + r0, + 32 addic r9, + r0, + -32 blt cr0, + lab5 slw r3, + r4, + r9 li r4, + 0 b lab6 lab5 + : slw r3, + r3, + r0 subfic r9, + r0, + 32 srw r9, + r4, + r9 or r3, + r3, + r9 slw r4, + r4, + r0 lab6 : li r10, + -1 addic r7, + r7, + 0 lab7 : adde r4, + r4, + r4 adde r3, + r3, + r3 adde r8, + r8, + r8 adde r7, + r7, + r7 subfc r0, + r6, + r8 subfe.r9, + r5, + r7 blt cr0, + lab8 mr r8, + r0 mr r7, + r9 addic r0, + r10, + 1 lab8 : bdnz lab7 adde r4, + r4, + r4 adde r3, + r3, + r3 lwz r9, + 8(r1)lwz r10, + 12(r1) xor.r7, + r9, + r10 beq func_end cmpwi cr0, + r9, + 0 subfic r4, + r4, + 0 subfze r3, + r3 + + no_adjust : b func_end + + lab9 : li r4, + 0 li r3, + 0 func_end : addi r1, + r1, + 16 blr +} +#pragma pop + +#pragma push +#pragma optimization_level 0 +#pragma optimizewithasm off +asm void __mod2u(void) +{ + nofralloc cmpwi cr0, r3, 0 cntlzw r0, r3 cntlzw r9, r4 bne cr0, lab1 addi r0, r9, + 32 lab1 : cmpwi cr0, + r5, + 0 cntlzw r9, + r5 cntlzw r10, + r6 bne cr0, + lab2 addi r9, + r10, + 32 lab2 : cmpw cr0, + r0, + r9 subfic r10, + r0, + 64 bgtlr cr0 addi r9, + r9, + 1 subfic r9, + r9, + 64 add r0, + r0, + r9 subf r9, + r9, + r10 mtctr r9 cmpwi cr0, + r9, + 32 addi r7, + r9, + -32 blt cr0, + lab3 srw r8, + r3, + r7 li r7, + 0 b lab4 lab3 : srw r8, + r4, + r9 subfic r7, + r9, + 32 slw r7, + r3, + r7 or r8, + r8, + r7 srw r7, + r3, + r9 lab4 : cmpwi cr0, + r0, + 32 addic r9, + r0, + -32 blt cr0, + lab5 slw r3, + r4, + r9 li r4, + 0 b lab6 lab5 : slw r3, + r3, + r0 subfic r9, + r0, + 32 srw r9, + r4, + r9 or r3, + r3, + r9 slw r4, + r4, + r0 lab6 : li r10, + -1 addic r7, + r7, + 0 lab7 + : adde r4, + r4, + r4 adde r3, + r3, + r3 adde r8, + r8, + r8 adde r7, + r7, + r7 subfc r0, + r6, + r8 subfe.r9, + r5, + r7 blt cr0, + lab8 mr r8, + r0 mr r7, + r9 addic r0, + r10, + 1 lab8 : bdnz lab7 mr r4, + r8 mr r3, + r7 blr lab9 : blr +} +#pragma pop + +#pragma push +#pragma optimization_level 0 +#pragma optimizewithasm off +asm void __mod2i(void) +{ + nofralloc + + cmpwi cr7, + r3, 0 bge cr7, positive1 subfic r4, r4, 0 subfze r3, + r3 positive1 : cmpwi cr0, + r5, + 0 bge cr0, + positive2 subfic r6, + r6, + 0 subfze r5, + r5 positive2 : cmpwi cr0, + r3, + 0 cntlzw r0, + r3 cntlzw r9, + r4 bne cr0, + lab1 addi r0, + r9, + 32 lab1 : cmpwi cr0, + r5, + 0 cntlzw r9, + r5 cntlzw r10, + r6 bne cr0, + lab2 addi r9, + r10, + 32 lab2 : cmpw cr0, + r0, + r9 subfic r10, + r0, + 64 bgt cr0, + lab9 addi r9, + r9, + 1 subfic r9, + r9, + 64 add r0, + r0, + r9 subf r9, + r9, + r10 mtctr r9 cmpwi cr0, + r9, + 32 addi r7, + r9, + -32 blt cr0, + lab3 srw r8, + r3, + r7 li r7, + 0 b lab4 lab3 : srw r8, + r4, + r9 subfic r7, + r9, + 32 slw r7, + r3, + r7 or r8, + r8, + r7 srw r7, + r3, + r9 lab4 : cmpwi cr0, + r0, + 32 addic r9, + r0, + -32 blt cr0, + lab5 slw r3, + r4, + r9 li r4, + 0 b lab6 lab5 + : slw r3, + r3, + r0 subfic r9, + r0, + 32 srw r9, + r4, + r9 or r3, + r3, + r9 slw r4, + r4, + r0 lab6 : li r10, + -1 addic r7, + r7, + 0 lab7 : adde r4, + r4, + r4 adde r3, + r3, + r3 adde r8, + r8, + r8 adde r7, + r7, + r7 subfc r0, + r6, + r8 subfe.r9, + r5, + r7 blt cr0, + lab8 mr r8, + r0 mr r7, + r9 addic r0, + r10, + 1 lab8 : bdnz lab7 mr r4, + r8 mr r3, + r7 lab9 : bgelr cr7 subfic r4, + r4, + 0 subfze r3, + r3 no_adjust : blr +} +#pragma pop + +asm void __shl2i(void) +{ + nofralloc subfic r8, r5, 32 subic r9, r5, 32 slw r3, r3, r5 srw r10, r4, r8 or r3, r3, + r10 slw r10, r4, r9 or r3, r3, r10 slw r4, r4, r5 blr +} + +//unused +asm void __shr2u(void) +{ + nofralloc subfic r8, r5, 32 subic r9, r5, 32 srw r4, r4, r5 slw r10, r3, r8 or r4, r4, + r10 srw r10, r3, r9 or r4, r4, r10 srw r3, r3, r5 blr +} + +asm void __shr2i(void) +{ + subfic r8, r5, 0x20 addic.r9, r5, -0x20 srw r4, r4, r5 slw r10, r3, r8 or r4, r4, r10 sraw r10, + r3, r9 ble L_802BA610 or r4, r4, r10 L_802BA610 : sraw r3, r3, r5 blr +} + +asm void __cvt_sll_dbl(void) +{ + // clang-format off + stwu r1, -0x10(r1) + rlwinm. r5, r3, 0, 0, 0 + beq- lbl_802b2b1c + subfic r4, r4, 0x0 + subfze r3, r3 +lbl_802b2b1c: + or. r7, r3, r4 + li r6, 0x0 + beq- lbl_802b2ba4 + cntlzw r7, r3 + cntlzw r8, r4 + rlwinm r9, r7, 0x1a, 0, 4 + srawi r9, r9, 0x1f + and r9, r9, r8 + add r7, r7, r9 + subfic r8, r7, 0x20 + addic r9, r7, -0x20 + slw r3, r3, r7 + srw r10, r4, r8 + or r3, r3, r10 + slw r10, r4, r9 + or r3, r3, r10 + slw r4, r4, r7 + subf r6, r7, r6 + clrlwi r7, r4, 0x15 + cmpwi r7, 0x400 + addi r6, r6, 0x43e + blt- lbl_802b2b8c + bgt- lbl_802b2b80 + rlwinm. r7, r4, 0, 0x14, 0x14 + beq- lbl_802b2b8c +lbl_802b2b80: + addic r4, r4, 0x800 + addze r3, r3 + addze r6, r6 +lbl_802b2b8c: + rotlwi r4, r4, 0x15 + rlwimi r4, r3, 0x15, 0, 0xa + rlwinm r3, r3, 0x15, 0xc, 0x1f + slwi r6, r6, 0x14 + or r3, r6, r3 + or r3, r5, r3 +lbl_802b2ba4: + stw r3, 8(r1) + stw r4, 0xc(r1) + lfd f1, 8(r1) + addi r1, r1, 0x10 + frfree + blr + // clang-format on +} + +//unused +asm void __cvt_ull_dbl(void) +{ +} + +asm void __cvt_sll_flt(void) +{ + stwu r1, -0x10(r1)clrrwi.r5, r3, 31 beq L_802BA62C subfic r4, r4, 0x0 subfze r3, + r3 L_802BA62C : or.r7, r3, r4 li r6, 0x0 beq L_802BA6B4 cntlzw r7, r3 cntlzw r8, + r4 extlwi r9, r7, 5, 26 srawi r9, r9, 31 and r9, r9, r8 add r7, r7, r9 subfic r8, r7, + 0x20 addic r9, r7, -0x20 slw r3, r3, r7 srw r10, r4, r8 or r3, r3, r10 slw r10, r4, + r9 or r3, r3, r10 slw r4, r4, r7 subf r6, r7, r6 clrlwi r7, r4, 21 cmpwi r7, 0x400 addi r6, + r6, 0x43e blt L_802BA69C bgt L_802BA690 rlwinm.r7, r4, 0, 20, + 20 beq L_802BA69C L_802BA690 : addic r4, + r4, + 0x800 addze r3, + r3 addze r6, + r6 L_802BA69C : rotrwi r4, + r4, + 11 rlwimi r4, + r3, + 21, + 0, + 10 extrwi r3, + r3, + 20, + 1 slwi r6, + r6, + 20 or r3, + r6, + r3 or r3, + r5, + r3 L_802BA6B4 : stw r3, + 0x8(r1)stw r4, + 0xc(r1)lfd f1, + 0x8(r1)frsp f1, + f1 addi r1, + r1, + 0x10 blr +} + +//unused +asm void __cvt_ull_flt(void) +{ +} + +//unused +asm void __cvt_dbl_usll(void) +{ + nofralloc stwu r1, -16(r1)stfd f1, 8(r1)lwz r3, 8(r1)lwz r4, 12(r1)rlwinm r5, r3, 12, 21, + 31 cmpli cr0, 0, r5, 1023 bge cr0, not_fraction li r3, 0 li r4, + 0 b func_end not_fraction : mr r6, + r3 rlwinm r3, + r3, + 0, + 12, + 31 oris r3, + r3, + 0x0010 addi r5, + r5, + -1075 cmpwi cr0, + r5, + 0 bge cr0, + left neg r5, + r5 subfic r8, + r5, + 32 subic r9, + r5, + 32 srw r4, + r4, + r5 slw r10, + r3, + r8 or r4, + r4, + r10 srw r10, + r3, + r9 or r4, + r4, + r10 srw r3, + r3, + r5 b around left : cmpwi cr0, + r5, + 10 ble + no_overflow rlwinm.r6, + r6, + 0, + 0, + 0 beq cr0, + max_positive lis r3, + 0x8000 li r4, + 0 b func_end max_positive + : lis r3, + 0x7FFF ori r3, + r3, + 0xFFFF li r4, + -1 b func_end no_overflow : subfic r8, + r5, + 32 subic r9, + r5, + 32 slw r3, + r3, + r5 srw r10, + r4, + r8 or r3, + r3, + r10 slw r10, + r4, + r9 or r3, + r3, + r10 slw r4, + r4, + r5 around : rlwinm.r6, + r6, + 0, + 0, + 0 beq cr0, + positive subfic r4, + r4, + 0 subfze r3, + r3 positive : func_end : addi r1, + r1, + 16 blr +} + +void __cvt_dbl_ull(void) +{ + nofralloc stwu r1, -0x10(r1)stfd f1, 8(r1)lwz r3, 8(r1)lwz r4, 0xC(r1)extrwi r5, r3, 11, + 1 cmplwi r5, + 0x3FF bge loc_80518FB4 + + loc_80518FA8 : li r3, + 0 li r4, + 0 b end + + loc_80518FB4 : clrrwi.r6, + r3, + 31 bne loc_80518FA8 clrlwi r3, + r3, + 12 oris r3, + r3, + 0x10 addi r5, + r5, + -0x433 cmpwi r5, + 0 bge loc_80518FF8 neg r5, + r5 subfic r8, + r5, + 0x20 addic r9, + r5, + -0x20 srw r4, + r4, + r5 slw r10, + r3, + r8 or r4, + r4, + r10 srw r10, + r3, + r9 or r4, + r4, + r10 srw r3, + r3, + r5 b end + + loc_80518FF8 : cmpwi r5, + 0xB ble + loc_8051900C li r3, + -1 li r4, + -1 b end + + loc_8051900C : subfic r8, + r5, + 0x20 addic r9, + r5, + -0x20 slw r3, + r3, + r5 srw r10, + r4, + r8 or r3, + r3, + r10 slw r10, + r4, + r9 or r3, + r3, + r10 slw r4, + r4, + r5 + + end : addi r1, + r1, + 0x10 blr +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libs/dolphin/OdemuExi2/DebuggerDriver.c b/libs/dolphin/OdemuExi2/DebuggerDriver.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ai/ai.c b/libs/dolphin/ai/ai.c new file mode 100644 index 000000000..a351534ba --- /dev/null +++ b/libs/dolphin/ai/ai.c @@ -0,0 +1,354 @@ +#include "dolphin/ai.h" +#include "dolphin/hw_regs.h" +#include "dolphin/os.h" + +const char* __AIVersion = "<< Dolphin SDK - AI\trelease build: Apr 17 2003 12:33:54 (0x2301) >>"; + +static AISCallback __AIS_Callback = NULL; +static AIDCallback __AID_Callback = NULL; +static u8* __CallbackStack; +static u8* __OldStack; +static volatile s32 __AI_init_flag = FALSE; +static volatile s32 __AID_Active = FALSE; + +static OSTime bound_32KHz; +static OSTime bound_48KHz; +static OSTime min_wait; +static OSTime max_wait; +static OSTime buffer; + +void __AISHandler(s16 interrupt, OSContext* context); +void __AIDHandler(s16 interrupt, OSContext* context); +void __AICallbackStackSwitch(register AIDCallback cb); +void __AI_SRC_INIT(void); + +AIDCallback AIRegisterDMACallback(AIDCallback callback) +{ + s32 oldInts; + AIDCallback ret; + + ret = __AID_Callback; + oldInts = OSDisableInterrupts(); + __AID_Callback = callback; + OSRestoreInterrupts(oldInts); + return ret; +} + +void AIInitDMA(u32 addr, u32 length) +{ + s32 oldInts; + oldInts = OSDisableInterrupts(); + __DSPRegs[24] = (u16)((__DSPRegs[24] & ~0x3FF) | (addr >> 16)); + __DSPRegs[25] = (u16)((__DSPRegs[25] & ~0xFFE0) | (0xffff & addr)); + __DSPRegs[27] = (u16)((__DSPRegs[27] & ~0x7FFF) | (u16)((length >> 5) & 0xFFFF)); + OSRestoreInterrupts(oldInts); +} + +void AIStartDMA() +{ + __DSPRegs[27] |= 0x8000; +} + +void AIStopDMA(void) +{ + __DSPRegs[27] &= ~0x8000; +} + +void AISetStreamPlayState(u32 state) +{ + s32 oldInts; + u8 volRight; + u8 volLeft; + + if (state == AIGetStreamPlayState()) + { + return; + } + if ((AIGetStreamSampleRate() == 0U) && (state == 1)) + { + volRight = AIGetStreamVolRight(); + volLeft = AIGetStreamVolLeft(); + AISetStreamVolRight(0); + AISetStreamVolLeft(0); + oldInts = OSDisableInterrupts(); + __AI_SRC_INIT(); + __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20; + __AIRegs[0] = (__AIRegs[0] & ~1) | 1; + OSRestoreInterrupts(oldInts); + AISetStreamVolLeft(volRight); + AISetStreamVolRight(volLeft); + } + else + { + __AIRegs[0] = (__AIRegs[0] & ~1) | state; + } +} + +u32 AIGetStreamPlayState() +{ + return __AIRegs[0] & 1; +} + +void AISetDSPSampleRate(u32 rate) +{ + u32 state; + s32 oldInts; + u8 left; + u8 right; + u32 sampleRate; + + if (rate == AIGetDSPSampleRate()) + { + return; + } + + __AIRegs[0] &= ~0x40; + if (rate == 0) + { + left = AIGetStreamVolLeft(); + right = AIGetStreamVolRight(); + state = AIGetStreamPlayState(); + sampleRate = AIGetStreamSampleRate(); + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + oldInts = OSDisableInterrupts(); + __AI_SRC_INIT(); + __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20; + __AIRegs[0] = (__AIRegs[0] & ~2) | (sampleRate * 2); + __AIRegs[0] = (__AIRegs[0] & ~1) | state; + __AIRegs[0] |= 0x40; + OSRestoreInterrupts(oldInts); + AISetStreamVolLeft(left); + AISetStreamVolRight(right); + } +} + +u32 AIGetDSPSampleRate() +{ + return ((__AIRegs[0] >> 6) & 1) ^ 1; +} + +void __AI_set_stream_sample_rate(u32 rate) +{ + s32 oldInts; + s32 state; + u8 left; + u8 right; + s32 temp_r26; + + if (rate == AIGetStreamSampleRate()) + { + return; + } + state = AIGetStreamPlayState(); + left = AIGetStreamVolLeft(); + right = AIGetStreamVolRight(); + AISetStreamVolRight(0); + AISetStreamVolLeft(0); + temp_r26 = __AIRegs[0] & 0x40; + __AIRegs[0] &= ~0x40; + oldInts = OSDisableInterrupts(); + __AI_SRC_INIT(); + __AIRegs[0] |= temp_r26; + __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20; + __AIRegs[0] = (__AIRegs[0] & ~2) | (rate * 2); + OSRestoreInterrupts(oldInts); + AISetStreamPlayState(state); + AISetStreamVolLeft(left); + AISetStreamVolRight(right); +} + +u32 AIGetStreamSampleRate() +{ + return (__AIRegs[0] >> 1) & 1; +} + +void AISetStreamVolLeft(u8 volume) +{ + __AIRegs[1] = (__AIRegs[1] & ~0xFF) | (volume & 0xFF); +} + +u8 AIGetStreamVolLeft() +{ + return __AIRegs[1]; +} + +void AISetStreamVolRight(u8 volume) +{ + __AIRegs[1] = (__AIRegs[1] & ~0xFF00) | ((volume & 0xFF) << 8); +} + +u8 AIGetStreamVolRight() +{ + return __AIRegs[1] >> 8; +} + +void AIInit(u8* stack) +{ + if (__AI_init_flag == TRUE) + { + return; + } + + 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); + __AIRegs[3] = 0; + __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20; + __AI_set_stream_sample_rate(1); + AISetDSPSampleRate(0); + __AIS_Callback = 0; + __AID_Callback = 0; + __CallbackStack = stack; + __OSSetInterruptHandler(5, __AIDHandler); + __OSUnmaskInterrupts(0x04000000); + __OSSetInterruptHandler(8, __AISHandler); + __OSUnmaskInterrupts(0x800000); + __AI_init_flag = TRUE; +} + +void __AISHandler(s16 interrupt, OSContext* context) +{ + OSContext tmpContext; + __AIRegs[0] |= 8; + OSClearContext(&tmpContext); + OSSetCurrentContext(&tmpContext); + if (__AIS_Callback != NULL) + { + __AIS_Callback(__AIRegs[2]); + } + OSClearContext(&tmpContext); + OSSetCurrentContext(context); +} + +void __AIDHandler(s16 interrupt, OSContext* context) +{ + OSContext tempContext; + u32 temp = __DSPRegs[5]; + __DSPRegs[5] = (temp & ~0xA0) | 8; + OSClearContext(&tempContext); + OSSetCurrentContext(&tempContext); + if (__AID_Callback && !__AID_Active) + { + __AID_Active = TRUE; + if (__CallbackStack) + { + __AICallbackStackSwitch(__AID_Callback); + } + else + { + __AID_Callback(); + } + + __AID_Active = FALSE; + } + + OSClearContext(&tempContext); + OSSetCurrentContext(context); +} + +// clang-format off +asm void __AICallbackStackSwitch(register AIDCallback cb) { + // Allocate stack frame + fralloc + + // Store current stack + lis r5, __OldStack@ha + addi r5, r5, __OldStack@l + stw r1, 0(r5) + + // Load stack for callback + lis r5, __CallbackStack@ha + addi r5, r5, __CallbackStack@l + lwz r1,0(r5) + + // Move stack down 8 bytes + subi r1, r1, 8 + // Call callback + mtlr cb + blrl + + // Restore old stack + lis r5, __OldStack @ha + addi r5, r5, __OldStack@l + lwz r1,0(r5) + + // Free stack frame + frfree + + blr +} +// clang-format on + +void __AI_SRC_INIT(void) +{ + OSTime rising_32khz = 0; + OSTime rising_48khz = 0; + OSTime diff = 0; + OSTime t1 = 0; + OSTime temp = 0; + u32 temp0 = 0; + u32 temp1 = 0; + u32 done = 0; + u32 volume = 0; + u32 Init_Cnt = 0; + u32 walking = 0; + + walking = 0; + Init_Cnt = 0; + temp = 0; + + while (!done) + { + __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20; + __AIRegs[0] &= ~2; + __AIRegs[0] = (__AIRegs[0] & ~1) | 1; + + temp0 = __AIRegs[2]; + + while (temp0 == __AIRegs[2]) + ; + rising_32khz = OSGetTime(); + + __AIRegs[0] = (__AIRegs[0] & ~2) | 2; + __AIRegs[0] = (__AIRegs[0] & ~1) | 1; + + temp1 = __AIRegs[2]; + while (temp1 == __AIRegs[2]) + ; + + rising_48khz = OSGetTime(); + + diff = rising_48khz - rising_32khz; + __AIRegs[0] &= ~2; + __AIRegs[0] &= ~1; + + if (diff < (bound_32KHz - buffer)) + { + temp = min_wait; + done = 1; + ++Init_Cnt; + } + else if (diff >= (bound_32KHz + buffer) && diff < (bound_48KHz - buffer)) + { + temp = max_wait; + done = 1; + ++Init_Cnt; + } + else + { + done = 0; + walking = 1; + ++Init_Cnt; + } + } + + while ((rising_48khz + temp) > OSGetTime()) + ; +} \ No newline at end of file diff --git a/libs/dolphin/ar/ar.c b/libs/dolphin/ar/ar.c new file mode 100644 index 000000000..c3ed78946 --- /dev/null +++ b/libs/dolphin/ar/ar.c @@ -0,0 +1,383 @@ +#include "dolphin/ar/ar.h" + +#include "dolphin/hw_regs.h" +#include "dolphin/os.h" + +static const char* __ARVersion = + "<< Dolphin SDK - AR\trelease build: Apr 17 2003 12:33:55 (0x2301) >>"; + +static ARCallback __AR_Callback; +static u32 __AR_Size; +static u32 __AR_InternalSize; +static u32 __AR_ExpansionSize; + +static u32 __AR_StackPointer; +static u32 __AR_FreeBlocks; +static u32* __AR_BlockLength; + +static volatile BOOL __AR_init_flag = FALSE; + +static void __ARHandler(__OSInterrupt interrupt, OSContext* context); +static void __ARChecksize(void); +static void __ARClearArea(u32 start_addr, u32 length); + +ARCallback ARRegisterDMACallback(ARCallback callback) +{ + ARCallback oldCb; + BOOL enabled; + oldCb = __AR_Callback; + enabled = OSDisableInterrupts(); + __AR_Callback = callback; + OSRestoreInterrupts(enabled); + return oldCb; +} + +void ARStartDMA(u32 type, u32 mainmem_addr, u32 aram_addr, u32 length) +{ + BOOL enabled; + + enabled = OSDisableInterrupts(); + + __DSPRegs[16] = (u16)(__DSPRegs[16] & ~0x3ff) | (u16)(mainmem_addr >> 16); + __DSPRegs[17] = (u16)(__DSPRegs[17] & ~0xffe0) | (u16)(mainmem_addr & 0xffff); + __DSPRegs[18] = (u16)(__DSPRegs[18] & ~0x3ff) | (u16)(aram_addr >> 16); + __DSPRegs[19] = (u16)(__DSPRegs[19] & ~0xffe0) | (u16)(aram_addr & 0xffff); + __DSPRegs[20] = (u16)((__DSPRegs[20] & ~0x8000) | (type << 15)); + __DSPRegs[20] = (u16)(__DSPRegs[20] & ~0x3ff) | (u16)(length >> 16); + __DSPRegs[21] = (u16)(__DSPRegs[21] & ~0xffe0) | (u16)(length & 0xffff); + OSRestoreInterrupts(enabled); +} + +u32 ARAlloc(u32 length) +{ + u32 tmp; + BOOL enabled; + + enabled = OSDisableInterrupts(); + tmp = __AR_StackPointer; + __AR_StackPointer += length; + *__AR_BlockLength = length; + __AR_BlockLength++; + __AR_FreeBlocks--; + OSRestoreInterrupts(enabled); + + return tmp; +} + +u32 ARFree(u32* length) +{ + BOOL old; + + old = OSDisableInterrupts(); + + __AR_BlockLength--; + + if (length) + { + *length = *__AR_BlockLength; + } + + __AR_StackPointer -= *__AR_BlockLength; + + __AR_FreeBlocks++; + + OSRestoreInterrupts(old); + + return __AR_StackPointer; +} + +u32 ARInit(u32* stack_index_addr, u32 num_entries) +{ + BOOL old; + u16 refresh; + + if (__AR_init_flag == TRUE) + { + return 0x4000; + } + + OSRegisterVersion(__ARVersion); + + old = OSDisableInterrupts(); + + __AR_Callback = NULL; + + __OSSetInterruptHandler(__OS_INTERRUPT_DSP_ARAM, __ARHandler); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_DSP_ARAM); + + __AR_StackPointer = 0x4000; + __AR_FreeBlocks = num_entries; + __AR_BlockLength = stack_index_addr; + + refresh = (u16)(__DSPRegs[13] & 0x000000ff); + + __DSPRegs[13] = (u16)((__DSPRegs[13] & ~0x000000ff) | (refresh & 0x000000ff)); + + __ARChecksize(); + + __AR_init_flag = TRUE; + + OSRestoreInterrupts(old); + + return __AR_StackPointer; +} + +static void __ARHandler(__OSInterrupt interrupt, OSContext* context) +{ + OSContext exceptionContext; + u16 tmp; + + tmp = __DSPRegs[5]; + tmp = (u16)((tmp & ~0x00000088) | 0x20); + __DSPRegs[5] = tmp; + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + if (__AR_Callback) + { + (*__AR_Callback)(); + } + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +#define RoundUP32(x) (((u32)(x) + 32 - 1) & ~(32 - 1)) + +static void __ARWriteDMA(u32 mmem_addr, u32 aram_addr, u32 length) +{ + u16 tmp; + __DSPRegs[16] = (u16)((__DSPRegs[16] & ~0x03ff) | (u16)(mmem_addr >> 16)); + __DSPRegs[16 + 1] = (u16)((__DSPRegs[16 + 1] & ~0xffe0) | (u16)(mmem_addr & 0xffff)); + + __DSPRegs[18] = (u16)((__DSPRegs[18] & ~0x03ff) | (u16)(aram_addr >> 16)); + __DSPRegs[18 + 1] = (u16)((__DSPRegs[18 + 1] & ~0xffe0) | (u16)(aram_addr & 0xffff)); + + __DSPRegs[20] = (u16)(__DSPRegs[20] & ~0x8000); + + __DSPRegs[20] = (u16)((__DSPRegs[20] & ~0x03ff) | (u16)(length >> 16)); + __DSPRegs[20 + 1] = (u16)((__DSPRegs[20 + 1] & ~0xffe0) | (u16)(length & 0xffff)); + + while (__DSPRegs[5] & 0x0200) + { + } + + tmp = __DSPRegs[5]; + tmp = (u16)((tmp & ~(0x00000080 | 0x00000008)) | 0x00000020); + __DSPRegs[5] = tmp; +} + +static void __ARReadDMA(u32 mmem_addr, u32 aram_addr, u32 length) +{ + u16 tmp; + __DSPRegs[16] = (u16)((__DSPRegs[16] & ~0x03ff) | (u16)(mmem_addr >> 16)); + __DSPRegs[16 + 1] = (u16)((__DSPRegs[16 + 1] & ~0xffe0) | (u16)(mmem_addr & 0xffff)); + + __DSPRegs[18] = (u16)((__DSPRegs[18] & ~0x03ff) | (u16)(aram_addr >> 16)); + __DSPRegs[18 + 1] = (u16)((__DSPRegs[18 + 1] & ~0xffe0) | (u16)(aram_addr & 0xffff)); + + __DSPRegs[20] = (u16)(__DSPRegs[20] | 0x8000); + + __DSPRegs[20] = (u16)((__DSPRegs[20] & ~0x03ff) | (u16)(length >> 16)); + __DSPRegs[20 + 1] = (u16)((__DSPRegs[20 + 1] & ~0xffe0) | (u16)(length & 0xffff)); + + while (__DSPRegs[5] & 0x0200) + { + } + + tmp = __DSPRegs[5]; + tmp = (u16)((tmp & ~(0x00000080 | 0x00000008)) | 0x00000020); + __DSPRegs[5] = tmp; +} + +static void __ARChecksize(void) +{ + 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]; + + u32* test_data; + u32* dummy_data; + u32* buffer; + u32* save1; + u32* save2; + u32* save3; + u32* save4; + u32* save5; + + u16 ARAM_mode = 0; + u32 ARAM_size = 0; + + u32 i; + + while (!(__DSPRegs[11] & 1)) + ; + + ARAM_mode = 3; + ARAM_size = __AR_InternalSize = 0x1000000; + __DSPRegs[9] = (u16)((__DSPRegs[9] & ~(0x00000007 | 0x00000038)) | 0x20 | 2 | 1); + + test_data = (u32*)(RoundUP32((u32)(test_data_pad))); + dummy_data = (u32*)(RoundUP32((u32)(dummy_data_pad))); + buffer = (u32*)(RoundUP32((u32)(buffer_pad))); + + save1 = (u32*)(RoundUP32((u32)(save_pad_1))); + save2 = (u32*)(RoundUP32((u32)(save_pad_2))); + save3 = (u32*)(RoundUP32((u32)(save_pad_3))); + save4 = (u32*)(RoundUP32((u32)(save_pad_4))); + save5 = (u32*)(RoundUP32((u32)(save_pad_5))); + + for (i = 0; i < 8; i++) + { + *(test_data + i) = 0xdeadbeef; + *(dummy_data + i) = 0xbad0bad0; + } + + DCFlushRange((void*)test_data, 0x20); + DCFlushRange((void*)dummy_data, 0x20); + + __AR_ExpansionSize = 0; + + DCInvalidateRange((void*)save1, 0x20); + __ARReadDMA((u32)save1, ARAM_size + 0, 0x20); + PPCSync(); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0000000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) + { + DCInvalidateRange((void*)save2, 0x20); + __ARReadDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + PPCSync(); + + DCInvalidateRange((void*)save3, 0x20); + __ARReadDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + PPCSync(); + + DCInvalidateRange((void*)save4, 0x20); + __ARReadDMA((u32)save4, ARAM_size + 0x0000200, 0x20); + PPCSync(); + + DCInvalidateRange((void*)save5, 0x20); + __ARReadDMA((u32)save5, ARAM_size + 0x0400000, 0x20); + PPCSync(); + + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0200000, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0200000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) + { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + + ARAM_mode |= 0 << 1; + ARAM_size += 0x0200000; + __AR_ExpansionSize = 0x0200000; + } + else + { + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x1000000, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x1000000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) + { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + + ARAM_mode |= 4 << 1; + ARAM_size += 0x0400000; + __AR_ExpansionSize = 0x0400000; + } + else + { + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0000200, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0000200, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) + { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + + ARAM_mode |= 8 << 1; + ARAM_size += 0x0800000; + __AR_ExpansionSize = 0x0800000; + } + else + { + __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0400000, 0x20); + + __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20); + + memset((void*)buffer, 0, 0x20); + DCFlushRange((void*)buffer, 0x20); + + __ARReadDMA((u32)buffer, ARAM_size + 0x0400000, 0x20); + PPCSync(); + + if (buffer[0] == test_data[0]) + { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + __ARWriteDMA((u32)save4, ARAM_size + 0x0000200, 0x20); + + ARAM_mode |= 12 << 1; + ARAM_size += 0x1000000; + __AR_ExpansionSize = 0x1000000; + } + else + { + __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20); + __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20); + __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20); + __ARWriteDMA((u32)save4, ARAM_size + 0x0000200, 0x20); + __ARWriteDMA((u32)save5, ARAM_size + 0x0400000, 0x20); + + ARAM_mode |= 16 << 1; + ARAM_size += 0x2000000; + __AR_ExpansionSize = 0x2000000; + } + } + } + } + __DSPRegs[9] = (u16)((__DSPRegs[9] & ~(0x07 | 0x38)) | ARAM_mode); + } + + *(u32*)OSPhysicalToUncached(0x00D0) = ARAM_size; + + __AR_Size = ARAM_size; +} \ No newline at end of file diff --git a/libs/dolphin/ar/arq.c b/libs/dolphin/ar/arq.c new file mode 100644 index 000000000..504a89159 --- /dev/null +++ b/libs/dolphin/ar/arq.c @@ -0,0 +1,271 @@ + +#include +#include + +#include "dolphin/ax/__ax.h" + +#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 17 2003 12:33:56 (0x2301) >>"; +#endif + +static ARQRequest* __ARQRequestQueueHi; +static ARQRequest* __ARQRequestTailHi; +static ARQRequest* __ARQRequestQueueLo; +static ARQRequest* __ARQRequestTailLo; +static ARQRequest* __ARQRequestQueueTemp; +static ARQRequest* __ARQRequestTailTemp; +static ARQRequest* __ARQRequestPendingHi; +static ARQRequest* __ARQRequestPendingLo; +static ARQCallback __ARQCallbackHi; +static ARQCallback __ARQCallbackLo; +static u32 __ARQChunkSize; +static BOOL __ARQ_init_flag; + +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; + } + + if (__ARQRequestQueueHi) + { + if (__ARQRequestQueueHi->type == 0) + { + ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->source, + __ARQRequestQueueHi->dest, __ARQRequestQueueHi->length); + } + else + { + ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->dest, + __ARQRequestQueueHi->source, __ARQRequestQueueHi->length); + } + __ARQCallbackHi = __ARQRequestQueueHi->callback; + __ARQRequestPendingHi = __ARQRequestQueueHi; + __ARQRequestQueueHi = __ARQRequestQueueHi->next; + } + + if (__ARQRequestPendingHi == 0) + { + __ARQServiceQueueLo(); + } +} + +void ARQInit(void) +{ + if (__ARQ_init_flag != TRUE) + { + OSRegisterVersion(__ARQVersion); + + __ARQRequestQueueHi = __ARQRequestQueueLo = NULL; + __ARQChunkSize = 0x1000; + ARRegisterDMACallback(__ARQInterruptServiceRoutine); + __ARQRequestPendingHi = NULL; + __ARQRequestPendingLo = NULL; + __ARQCallbackHi = NULL; + __ARQCallbackLo = NULL; + __ARQ_init_flag = TRUE; + } +} + +void ARQPostRequest(ARQRequest* request, u32 owner, u32 type, u32 priority, u32 source, u32 dest, + u32 length, ARQCallback callback) +{ + BOOL enabled; + + request->next = NULL; + request->owner = owner; + request->type = type; + request->source = source; + request->dest = dest; + request->length = length; + + if (callback) + { + request->callback = callback; + } + else + { + request->callback = (ARQCallback)&__ARQCallbackHack; + } + + enabled = OSDisableInterrupts(); + + switch (priority) + { + case ARQ_PRIORITY_LOW: + + if (__ARQRequestQueueLo) + { + __ARQRequestTailLo->next = request; + } + else + { + __ARQRequestQueueLo = request; + } + __ARQRequestTailLo = request; + + break; + + case ARQ_PRIORITY_HIGH: + + if (__ARQRequestQueueHi) + { + __ARQRequestTailHi->next = request; + } + else + { + __ARQRequestQueueHi = request; + } + + __ARQRequestTailHi = request; + + break; + } + + if ((__ARQRequestPendingHi == NULL) && (__ARQRequestPendingLo == NULL)) + { + if (__ARQRequestQueueHi) + { + if (__ARQRequestQueueHi->type == 0) + { + ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->source, + __ARQRequestQueueHi->dest, __ARQRequestQueueHi->length); + } + else + { + ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->dest, + __ARQRequestQueueHi->source, __ARQRequestQueueHi->length); + } + __ARQCallbackHi = __ARQRequestQueueHi->callback; + __ARQRequestPendingHi = __ARQRequestQueueHi; + __ARQRequestQueueHi = __ARQRequestQueueHi->next; + } + + if (__ARQRequestPendingHi == NULL) + { + __ARQServiceQueueLo(); + } + } + + OSRestoreInterrupts(enabled); +} + +void ARQRemoveRequest(ARQRequest* request) +{ + ARQRequest* thisRequest; + BOOL level; + + level = OSDisableInterrupts(); + __ARQRequestQueueTemp = NULL; + __ARQRequestTailTemp = NULL; + for (thisRequest = __ARQRequestQueueHi; thisRequest; thisRequest = thisRequest->next) + { + if (thisRequest != request) + { + if (!__ARQRequestQueueTemp) + { + __ARQRequestQueueTemp = thisRequest; + __ARQRequestTailTemp = thisRequest; + } + else + { + __ARQRequestTailTemp->next = thisRequest; + __ARQRequestTailTemp = thisRequest; + } + } + } + + __ARQRequestQueueHi = __ARQRequestQueueTemp; + __ARQRequestTailHi = __ARQRequestTailTemp; + __ARQRequestQueueTemp = NULL; + __ARQRequestTailTemp = NULL; + for (thisRequest = __ARQRequestQueueLo; thisRequest; thisRequest = thisRequest->next) + { + if (thisRequest != request) + { + if (!__ARQRequestQueueTemp) + { + __ARQRequestQueueTemp = thisRequest; + __ARQRequestTailTemp = thisRequest; + } + else + { + __ARQRequestTailTemp->next = thisRequest; + __ARQRequestTailTemp = thisRequest; + } + } + } + + __ARQRequestQueueLo = __ARQRequestQueueTemp; + __ARQRequestTailLo = __ARQRequestTailTemp; + OSRestoreInterrupts(level); +} + +void ARQFlushQueue(void) +{ + BOOL level; + + level = OSDisableInterrupts(); + __ARQRequestQueueHi = NULL; + __ARQRequestTailHi = NULL; + __ARQRequestQueueLo = NULL; + __ARQRequestTailLo = NULL; + + OSRestoreInterrupts(level); +} diff --git a/libs/dolphin/ax/AX.c b/libs/dolphin/ax/AX.c new file mode 100644 index 000000000..ab015fffc --- /dev/null +++ b/libs/dolphin/ax/AX.c @@ -0,0 +1,43 @@ +#include +#include + +#include "dolphin/ax/__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 17 2003 12:33:57 (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/libs/dolphin/ax/AXAlloc.c b/libs/dolphin/ax/AXAlloc.c new file mode 100644 index 000000000..8c7d0ef74 --- /dev/null +++ b/libs/dolphin/ax/AXAlloc.c @@ -0,0 +1,256 @@ +#include +#include + +#include "dolphin/ax/__ax.h" + +static AXVPB* __AXStackHead[AX_PRIORITY_STACKS]; +static AXVPB* __AXStackTail[AX_PRIORITY_STACKS]; + +static AXVPB* __AXCallbackStack; + +AXVPB* __AXGetStackHead(u32 priority) +{ + 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 __AXAllocInit(void) +{ +#ifdef DEBUG + OSReport("Initializing AXAlloc code module\n"); +#endif + u32 i; + + __AXCallbackStack = NULL; + for (i = 0; i < AX_PRIORITY_STACKS; i++) + { + __AXStackHead[i] = __AXStackTail[i] = 0; + } +} + +void __AXAllocQuit(void) +{ +#ifdef DEBUG + OSReport("Shutting down AXAlloc code module\n"); +#endif + u32 i; + + __AXCallbackStack = NULL; + for (i = 0; i < AX_PRIORITY_STACKS; i++) + { + __AXStackHead[i] = __AXStackTail[i] = 0; + } +} + +void __AXPushFreeStack(AXVPB* p) +{ + 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; + + 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) +// { +// 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; + +// 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) +{ + int old; + + old = OSDisableInterrupts(); + __AXRemoveFromStack(p); + if (p->pb.state == 1) + { + p->depop = 1; + } + __AXSetPBDefault(p); + __AXPushFreeStack(p); + OSRestoreInterrupts(old); +} + +AXVPB* AXAcquireVoice(u32 priority, void (*callback)(void*), u32 userContext) +{ + // priority r25 + // userContext r 28 + // AXStackHead r26 + int old; // r31 + AXVPB* p; // r30 + u32 i; // r29 + + old = OSDisableInterrupts(); + p = (void*)(u32)&__AXStackHead[0]->next; + if (p != 0) + { + __AXStackHead[0] = __AXStackHead[0]->next; + } + + if (p == 0) + { + for (i = 1; i < priority; i++) + { + p = NULL; + if (__AXStackHead[i]) + { + if (__AXStackHead[i] == __AXStackTail[i]) + { + p = __AXStackHead[i]; + __AXStackHead[i] = __AXStackTail[i] = 0; + } + else if (__AXStackTail[i]) + { + p = __AXStackTail[i]; + __AXStackTail[i] = p->prev; + __AXStackTail[i]->next = 0; + } + } + if (p) + { + if (p->pb.state == 1) + { + p->depop = 1; + } + if (p->callback != 0) + { + p->callback(p); + } + break; + } + } + } + if (p) + { + p->next = __AXStackHead[i]; + p->prev = 0; + if (p->next) + { + __AXStackHead[i]->prev = p; + __AXStackHead[i] = p; + } + else + { + __AXStackTail[i] = p; + __AXStackHead[i] = p; + } + p->priority = i; + p->callback = callback; + p->userContext = userContext; + __AXSetPBDefault(p); + } + OSRestoreInterrupts(old); + return p; +} diff --git a/libs/dolphin/ax/AXAux.c b/libs/dolphin/ax/AXAux.c new file mode 100644 index 000000000..25af19bf0 --- /dev/null +++ b/libs/dolphin/ax/AXAux.c @@ -0,0 +1,184 @@ +#include +#include + +#include "dolphin/ax/__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; +} diff --git a/libs/dolphin/ax/AXCL.c b/libs/dolphin/ax/AXCL.c new file mode 100644 index 000000000..4487e3cb8 --- /dev/null +++ b/libs/dolphin/ax/AXCL.c @@ -0,0 +1,226 @@ +#include +#include + +#include "dolphin/ax/__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(); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 0x2E44; + + switch (__AXClMode) + { + case 0: + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 0x546; + break; + case 1: + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 0x5E6; + break; + case 2: + break; + default: + ASSERTMSGLINE(193, 0, "Unknown AX mode!"); + } + + data = (u32)__AXGetPBs(); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + + if (__AXClMode == 2) + { + __AXGetAuxAInput(&data); + if (data != 0) + { + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXGetAuxAInputDpl2(&data); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXGetAuxAOutput(&data); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXGetAuxAOutputDpl2R(&data); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXGetAuxAOutputDpl2Ls(&data); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXGetAuxAOutputDpl2Rs(&data); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 0xDED; + } + *__AXClWrite = data; + __AXClWrite++; + __AXGetAuxBForDPL2(&data); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXGetAuxBOutputDPL2(&data); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 0xDED; + } + else + { + __AXGetAuxAInput(&data); + + if (data != 0) + { + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXGetAuxAOutput(&data); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 0xDED; + } + + __AXGetAuxBInput(&data); + if (data != 0) + { + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 0xDED; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXGetAuxBOutput(&data); + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + } + } + + if (__AXCompressor) + { + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 0xBB8; + } + + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 0x2710; + *__AXClWrite = data; + __AXClWrite++; + __AXCommandListCycles += 2; + DCFlushRange(pCommandList, 0x300); +} + +void __AXClInit(void) +{ +#ifdef DEBUG + OSReport("Initializing AXCL code module\n"); +#endif + __AXClMode = 0; + __AXCommandListPosition = 0; + __AXClWrite = (void*)&__AXCommandList; + __AXCompressor = 1; +} + +void __AXClQuit(void) +{ +#ifdef DEBUG + OSReport("Shutting down AXCL code module\n"); +#endif +} diff --git a/libs/dolphin/ax/AXComp.c b/libs/dolphin/ax/AXComp.c new file mode 100644 index 000000000..af66e256f --- /dev/null +++ b/libs/dolphin/ax/AXComp.c @@ -0,0 +1,287 @@ +#include +#include + +#include "dolphin/ax/__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/libs/dolphin/ax/AXOut.c b/libs/dolphin/ax/AXOut.c new file mode 100644 index 000000000..7ead2b859 --- /dev/null +++ b/libs/dolphin/ax/AXOut.c @@ -0,0 +1,243 @@ +#include +#include +#include + +#include "dolphin/ax/__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; +} + +static void __AXDSPResumeCallback(void* task) +{ + if (__AXOutDspReady == 2) + { + __AXOutDspReady = 0; + __AXOutNewFrame((u32)(OSGetTime() - __AXOsTime) / 4); + return; + } + __AXOutDspReady = 1U; +} + +static void __AXDSPDoneCallback(void* task) +{ + __AXDSPDoneFlag = 1; + OSWakeupThread(&__AXOutThreadQueue); +} + +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(void (*callback)()) +{ + __AXUserFrameCallback = callback; +} diff --git a/libs/dolphin/ax/AXProf.c b/libs/dolphin/ax/AXProf.c new file mode 100644 index 000000000..2bd94b928 --- /dev/null +++ b/libs/dolphin/ax/AXProf.c @@ -0,0 +1,24 @@ +#include +#include + +#include "dolphin/ax/__ax.h" + +// .sbss +static AXPROFILE* __AXProfile; +static u32 __AXMaxProfiles; +static u32 __AXCurrentProfile; +static u32 __AXProfileInitialized; + +AXPROFILE* __AXGetCurrentProfile(void) +{ + AXPROFILE* profile; + + if (__AXProfileInitialized != 0U) + { + profile = &__AXProfile[__AXCurrentProfile]; + __AXCurrentProfile += 1; + __AXCurrentProfile %= __AXMaxProfiles; + return profile; + } + return 0; +} diff --git a/libs/dolphin/ax/AXSPB.c b/libs/dolphin/ax/AXSPB.c new file mode 100644 index 000000000..9a22f943c --- /dev/null +++ b/libs/dolphin/ax/AXSPB.c @@ -0,0 +1,94 @@ +#include +#include + +#include "dolphin/ax/__ax.h" + +// .bss +static struct _AXSPB __AXStudio ATTRIBUTE_ALIGN(32); + +// .sbss +static long __AXSpbAL; +static long __AXSpbAR; +static long __AXSpbAS; +static long __AXSpbAAL; +static long __AXSpbAAR; +static long __AXSpbAAS; +static long __AXSpbABL; +static long __AXSpbABR; +static long __AXSpbABS; + +u32 __AXGetStudio(void) +{ + return (u32)&__AXStudio; +} + +void __AXDepopFade(long* hostSum, long* dspVolume, s16* dspDelta) +{ + int frames; + long 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/libs/dolphin/ax/AXVPB.c b/libs/dolphin/ax/AXVPB.c new file mode 100644 index 000000000..b91ad2e30 --- /dev/null +++ b/libs/dolphin/ax/AXVPB.c @@ -0,0 +1,1299 @@ +#include +#include + +#include "dolphin/ax/__ax.h" + +static unsigned long __AXSrcCycles[5] = { 0x00000DF8, 0x00000F78, 0x000014B8, 0x000019F8, + 0x000019F8 }; + +static unsigned long __AXMixCycles[32] = { + 0x000005BE, 0x00000B7C, 0x00000B7C, 0x0000113A, 0x000008B6, 0x00000E74, 0x00000E74, 0x00001432, + 0x000009A6, 0x0000134C, 0x0000134C, 0x00001CF2, 0x00000E97, 0x0000183D, 0x0000183D, 0x000021E3, + 0x00000B7C, 0x00001432, 0x00000B7C, 0x00001432, 0x00000B7C, 0x00000B7C, 0x00000B7C, 0x00000B7C, + 0x0000134C, 0x000021E3, 0x0000134C, 0x000021E3, 0x0000134C, 0x000021E3, 0x0000134C, 0x000021E3 +}; + +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(0xA1, (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: 0xC0) + 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); + 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_ = 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 = (u16*)&ppbDsp->dpop; + src = (u16*)&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 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); + } + 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); + } +} + +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 lessDspCycles) +{ + u32 cycles; + u32 i; + AXVPB* pvpb; + + __AXNumVoices = 0; + DCInvalidateRange(__AXPB, sizeof(__AXPB)); + DCInvalidateRange(__AXITD, sizeof(__AXITD)); + cycles = (__AXGetCommandListCycles() + 0x10000) - 0x55F0 + lessDspCycles; + for (i = 31; i; i--) + { + for (pvpb = __AXGetStackHead(i); pvpb; pvpb = pvpb->next) + { + if (pvpb->depop != 0U) + { + __AXDepopVoice(&__AXPB[pvpb->index]); + } + if ((pvpb->pb.state == 1) || (pvpb->updateCounter != 0U)) + { + cycles = __AXSrcCycles[pvpb->pb.src.ratioHi] + __AXMixCycles[pvpb->pb.mixerCtrl] + + 0x8C + cycles; + 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 != 0U) + { + __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 = 0xA4; + 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; +} + +void __AXVPBInit(void) +{ + u32 i; + AXPB* ppb; + AXPBITDBUFFER* ppbi; + AXPBU* ppbu; + AXVPB* pvpb; + +#ifdef DEBUG + OSReport("Initializing AXVPB code module\n"); +#endif + __AXMaxDspCycles = OS_BUS_CLOCK / 400; + __AXRecDspCycles = 0U; + memset(__AXPB, 0, sizeof(__AXPB)); + memset(__AXITD, 0, sizeof(__AXITD)); + memset(__AXVPB, 0, sizeof(__AXVPB)); + for (i = 0; i < AX_MAX_VOICES; i++) + { + ppb = &__AXPB[i]; + ppbi = &__AXITD[i]; + ppbu = &__AXUpdates[i]; + pvpb = &__AXVPB[i]; + ASSERTLINE(0x2F6, (u32)ppb ^ 0x1F); + ASSERTLINE(0x2F7, (u32)ppbi ^ 0x1F); + ASSERTLINE(0x2F8, (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 + 0xC0) >> 16); + pvpb->pb.nextLo = (u16)((u32)((char*)ppb + 0xC0)); + ppb->nextHi = (u16)((u32)((char*)ppb + 0xC0) >> 16); + ppb->nextLo = (u16)((u32)((char*)ppb + 0xC0)); + } + 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); + __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) +{ + int old; + AXPB* ppb; + + ASSERTLINE(0x35E, p); + ASSERTLINE(0x35F, 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) +{ + int 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) +{ + int old; + + old = OSDisableInterrupts(); + p->pb.type = type; + p->sync |= AX_SYNC_FLAG_COPYTYPE; + OSRestoreInterrupts(old); +} + +void AXSetVoiceMix(AXVPB* p, AXPBMIX* mix) +{ + int old; + u16 mixerCtrl; + u16* dst; + u16* src; + + src = + (u16*)&mix; //! @bug? This is a pointer (to) a pointer and is not what you want if you want to copy the information, no? + dst = (u16*)&p->pb.mix; + + 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; + *(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; + } + mixerCtrl = 0; + if (__AXClMode == 4) + { + if ((mix->vAuxAL != 0) || (mix->vAuxAR != 0)) + { + mixerCtrl |= 1; + } + if ((mix->vAuxBL != 0) || (mix->vAuxBR != 0)) + { + mixerCtrl |= 16; + } + if ((mix->vDeltaL != 0) || (mix->vDeltaR != 0) || (mix->vDeltaAuxAL != 0) || + (mix->vDeltaAuxAR != 0) || (mix->vDeltaAuxAS != 0) || (mix->vDeltaAuxBL != 0) || + (mix->vDeltaAuxBR != 0)) + { + mixerCtrl |= 8; + } + } + else + { + if ((mix->vAuxAL != 0) || (mix->vAuxAR != 0)) + { + mixerCtrl |= 1; + } + if ((mix->vAuxBL != 0) || (mix->vAuxBR != 0)) + { + mixerCtrl |= 2; + } + if ((mix->vS != 0) || (mix->vAuxAS != 0) || (mix->vAuxBS != 0)) + { + mixerCtrl |= 4; + } + if ((mix->vDeltaL != 0) || (mix->vDeltaR != 0) || (mix->vDeltaS != 0) || + (mix->vDeltaAuxAL != 0) || (mix->vDeltaAuxAR != 0) || (mix->vDeltaAuxAS != 0) || + (mix->vDeltaAuxBL != 0) || (mix->vDeltaAuxBR != 0) || (mix->vDeltaAuxBS != 0)) + { + mixerCtrl |= 8; + } + } + p->pb.mixerCtrl = mixerCtrl; + p->sync |= (AX_SYNC_FLAG_COPYAXPBMIX | AX_SYNC_FLAG_COPYMXRCTRL); + OSRestoreInterrupts(old); +} + +void AXSetVoiceItdOn(AXVPB* p) +{ + int 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) +{ + int 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) +{ + int old; + + old = OSDisableInterrupts(); + p->updateMS++; + p->sync |= AX_SYNC_FLAG_COPYUPDATE; + ASSERTMSGLINE(0x431, p->updateMS <= 4, "PB updates cannot exceed 5ms\n"); + OSRestoreInterrupts(old); +} + +void AXSetVoiceUpdateWrite(AXVPB* p, u16 param, u16 data) +{ + int old; + + old = OSDisableInterrupts(); + p->updateCounter += 2; + ASSERTMSGLINE(0x43F, 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) +{ + int 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) +{ + int 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) +{ + int old; + + old = OSDisableInterrupts(); + p->pb.ve.currentDelta = delta; + p->sync |= AX_SYNC_FLAG_SWAPVOL; + OSRestoreInterrupts(old); +} + +void AXSetVoiceFir(AXVPB* p, AXPBFIR* fir) +{ + int 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) +{ + int 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(0x4BA, (addr->loopAddressLo & 0xF) > 1, + "*** loop address on ADPCM frame header! ***\n"); + ASSERTMSGLINE(0x4BF, (addr->endAddressLo & 0xF) > 1, + "*** end address on ADPCM frame header! ***\n"); + ASSERTMSGLINE(0x4C4, (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(0x4F0, 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) +{ + int old; + + old = OSDisableInterrupts(); + p->pb.addr.loopFlag = loop; + p->sync |= AX_SYNC_FLAG_COPYLOOP; + OSRestoreInterrupts(old); +} + +void AXSetVoiceLoopAddr(AXVPB* p, u32 addr) +{ + int old; + + old = OSDisableInterrupts(); + p->pb.addr.loopAddressHi = (addr >> 0x10U); + p->pb.addr.loopAddressLo = (addr); + p->sync |= AX_SYNC_FLAG_COPYLOOPADDR; + OSRestoreInterrupts(old); +} + +void AXSetVoiceEndAddr(AXVPB* p, u32 addr) +{ + int old; + + old = OSDisableInterrupts(); + p->pb.addr.endAddressHi = (addr >> 0x10U); + p->pb.addr.endAddressLo = (addr); + p->sync |= AX_SYNC_FLAG_COPYENDADDR; + OSRestoreInterrupts(old); +} + +void AXSetVoiceCurrentAddr(AXVPB* p, u32 addr) +{ + int old; + + old = OSDisableInterrupts(); + p->pb.addr.currentAddressHi = (addr >> 0x10U); + p->pb.addr.currentAddressLo = (addr); + p->sync |= AX_SYNC_FLAG_COPYCURADDR; + OSRestoreInterrupts(old); +} + +void AXSetVoiceAdpcm(AXVPB* p, AXPBADPCM* adpcm) +{ + int 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_) +{ + int 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; + int 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) +{ + int 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 AXSetMaxDspCycles(u32 cycles) +{ + __AXMaxDspCycles = cycles; +} + +u32 AXGetMaxDspCycles(void) +{ + return __AXMaxDspCycles; +} + +u32 AXGetDspCycles(void) +{ + return __AXRecDspCycles; +} diff --git a/libs/dolphin/ax/DSPCode.c b/libs/dolphin/ax/DSPCode.c new file mode 100644 index 000000000..c13f4c0ec --- /dev/null +++ b/libs/dolphin/ax/DSPCode.c @@ -0,0 +1,211 @@ +#include +#include + +u16 axDspSlaveLength = (AX_DSP_SLAVE_LENGTH*2); + +u16 axDspSlave[AX_DSP_SLAVE_LENGTH] ATTRIBUTE_ALIGN(32) = { + 0x0000, 0x0000, 0x029F, 0x0BDB, 0x029F, 0x0BEA, 0x029F, 0x0C06, 0x029F, 0x0C15, 0x029F, 0x0C1B, 0x029F, 0x0C47, 0x029F, 0x0C4D, + 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, 0x055C, 0x0080, 0x0C00, 0x8E00, 0x8100, 0x8970, 0xB100, 0x0291, 0x007E, 0x0A11, 0xC100, + 0x0292, 0x007E, 0x009F, 0x0ACB, 0x4C00, 0x1C7E, 0x0213, 0x1C7E, 0x176F, 0x16FC, 0xFBAD, 0x16FD, 0x8080, 0x0021, 0x16FC, 0xBAAD, + 0x2EFD, 0x0021, 0x8100, 0x8970, 0x8E78, 0x2ECE, 0x2FCF, 0x009E, 0x0E44, 0x2ECD, 0x0E00, 0x2EC9, 0x009E, 0x0040, 0x2ECB, 0x0081, + 0x0E44, 0x0082, 0x0000, 0x009B, 0x009F, 0x009A, 0x0140, 0x8100, 0x8900, 0x8F00, 0x02BF, 0x055C, 0x193E, 0x193C, 0xB100, 0x193F, + 0x0294, 0x00A6, 0x005A, 0x1B5E, 0x029F, 0x00AE, 0x9900, 0x1B5E, 0x1B5C, 0x007B, 0x00AD, 0x4C00, 0x1B5E, 0x1B5C, 0x193E, 0x193C, + 0xB100, 0x193F, 0x0294, 0x00B8, 0x005A, 0x1B5E, 0x029F, 0x00C0, 0x9900, 0x1B5E, 0x1B5C, 0x007B, 0x00BF, 0x4C00, 0x1B5E, 0x1B5C, + 0x193E, 0x193C, 0xB100, 0x193F, 0x0294, 0x00CA, 0x005A, 0x1B5E, 0x029F, 0x00D2, 0x9900, 0x1B5E, 0x1B5C, 0x007B, 0x00D1, 0x4C00, + 0x1B5E, 0x1B5C, 0x0082, 0x0400, 0x193E, 0x193C, 0xB179, 0x0294, 0x00DD, 0x005A, 0x1B5E, 0x029F, 0x00E5, 0x9900, 0x1B5E, 0x1B5C, + 0x007B, 0x00E4, 0x4C00, 0x1B5E, 0x1B5C, 0x193E, 0x193C, 0xB179, 0x0294, 0x00EE, 0x005A, 0x1B5E, 0x029F, 0x00F6, 0x9900, 0x1B5E, + 0x1B5C, 0x007B, 0x00F5, 0x4C00, 0x1B5E, 0x1B5C, 0x193E, 0x193C, 0xB179, 0x0294, 0x00FF, 0x005A, 0x1B5E, 0x029F, 0x0107, 0x9900, + 0x1B5E, 0x1B5C, 0x007B, 0x0106, 0x4C00, 0x1B5E, 0x1B5C, 0x0082, 0x07C0, 0x193E, 0x193C, 0xB179, 0x0294, 0x0112, 0x005A, 0x1B5E, + 0x029F, 0x011A, 0x9900, 0x1B5E, 0x1B5C, 0x007B, 0x0119, 0x4C00, 0x1B5E, 0x1B5C, 0x193E, 0x193C, 0xB179, 0x0294, 0x0123, 0x005A, + 0x1B5E, 0x029F, 0x012B, 0x9900, 0x1B5E, 0x1B5C, 0x007B, 0x012A, 0x4C00, 0x1B5E, 0x1B5C, 0x193E, 0x193C, 0xB179, 0x0294, 0x0134, + 0x005A, 0x1B5E, 0x029F, 0x013C, 0x9900, 0x1B5E, 0x1B5C, 0x007B, 0x013B, 0x4C00, 0x1B5E, 0x1B5C, 0x029F, 0x0068, 0x0085, 0xFFFF, + 0x8150, 0x8940, 0x8E48, 0x00FA, 0x0E17, 0x00F8, 0x0E18, 0x0081, 0x0000, 0x02BF, 0x04F1, 0x00DA, 0x0E17, 0x00D8, 0x0E18, 0x8948, + 0x0081, 0x0400, 0x02BF, 0x04F1, 0x00DA, 0x0E17, 0x00D8, 0x0E18, 0x8948, 0x0081, 0x07C0, 0x02BF, 0x04F1, 0x029F, 0x0068, 0x0086, + 0x07C0, 0x02BF, 0x0484, 0x029F, 0x0068, 0x8100, 0x8E00, 0x191E, 0x191C, 0x2ECE, 0x2CCF, 0x16CD, 0x0000, 0x16C9, 0x0001, 0x16CB, + 0x0780, 0x02BF, 0x055C, 0x029F, 0x0068, 0x8100, 0x8970, 0x8E60, 0x2ECE, 0x2CCF, 0x16CD, 0x0E44, 0x16C9, 0x0000, 0x8900, 0x0D20, + 0x2DCB, 0x4C00, 0x1C80, 0x0080, 0x0280, 0x0081, 0x0000, 0x0082, 0x0140, 0x0083, 0x0E44, 0x0A00, 0x27C9, 0x03A0, 0x0004, 0x029C, + 0x018C, 0x2ECE, 0x2CCF, 0x16CD, 0x0E54, 0x16C9, 0x0000, 0x16CB, 0x0260, 0x009F, 0x00A0, 0x8F00, 0x007F, 0x01A6, 0x197E, 0x1B1A, + 0x197C, 0x1B1A, 0x1B5E, 0x1B5C, 0x7C00, 0x1B3E, 0x1B3C, 0x1C04, 0x029F, 0x0068, 0x8E70, 0x8960, 0x191F, 0x2ECE, 0x2CCF, 0x16CD, + 0x0C00, 0x16C9, 0x0000, 0x0503, 0x0340, 0xFFF0, 0x2FCB, 0x02BF, 0x055C, 0x0080, 0x0C00, 0x029F, 0x0068, 0x8100, 0x8970, 0x8E78, + 0x2ECE, 0x2FCF, 0x16CD, 0x0B80, 0x16C9, 0x0000, 0x16CB, 0x00C0, 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, 0x055C, 0x00DE, 0x0BA7, 0x00DF, 0x0BA8, 0x2ECE, 0x2FCF, 0x16CD, 0x03C0, 0x16C9, + 0x0000, 0x16CB, 0x0080, 0x8100, 0x8900, 0x00DE, 0x0B84, 0x009F, 0x0AFC, 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E15, 0x00DE, 0x0B85, + 0x009F, 0x0AFF, 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E16, 0x00DE, 0x0B86, 0x009F, 0x0ADC, 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E14, + 0x8100, 0x00DE, 0x0B9B, 0xB100, 0x0295, 0x023B, 0x8900, 0x00DF, 0x0B9E, 0x0300, 0x0CC0, 0x00FF, 0x0E40, 0x00DF, 0x0B9F, 0x0300, + 0x0CC0, 0x00FF, 0x0E41, 0x009F, 0x0CE0, 0x00FF, 0x0E42, 0x00FF, 0x0E43, 0x02BF, 0x055C, 0x00DE, 0x0B9C, 0x2ECE, 0x00DE, 0x0B9D, + 0x2ECF, 0x16CD, 0x0CC0, 0x16C9, 0x0000, 0x16CB, 0x0040, 0x02BF, 0x055C, 0x029F, 0x0068, 0x009F, 0x0CE0, 0x00FF, 0x0E42, 0x00FF, + 0x0E40, 0x00FF, 0x0E41, 0x00FF, 0x0E43, 0x02BF, 0x055C, 0x029F, 0x0068, 0x8E00, 0x00E0, 0x0E07, 0x0080, 0x0BA2, 0x0081, 0x03C0, + 0x0E05, 0x00FE, 0x0E04, 0x8900, 0x8150, 0x009F, 0x0B80, 0x007A, 0x025C, 0x193E, 0x4C49, 0x1C5E, 0x1A59, 0x0083, 0x0E05, 0x1B61, + 0x1B60, 0x00DE, 0x0B87, 0x0601, 0x0295, 0x0268, 0x029F, 0x0332, 0x00DE, 0x0E42, 0x00FE, 0x0E1C, 0x00C3, 0x0E15, 0x177F, 0x8F00, + 0x8A00, 0x8100, 0x8900, 0x00DE, 0x0BB3, 0x00DF, 0x0BB2, 0x1F1F, 0x4D00, 0x1481, 0x8D1E, 0x1FD8, 0x0098, 0x8000, 0x0080, 0x0E44, + 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, 0x0080, 0x0E44, 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, 0x00C3, 0x0E14, 0x8F00, 0x8D00, 0x8A00, 0x177F, + 0x8100, 0x00DE, 0x0B9B, 0xB100, 0x0295, 0x032A, 0x00DE, 0x0E42, 0x00FE, 0x0E43, 0x8100, 0x8900, 0x00DE, 0x0B9E, 0x00DF, 0x0BA0, + 0x8200, 0x0293, 0x0306, 0x7800, 0x029F, 0x0309, 0x0295, 0x0309, 0x7400, 0x00FE, 0x0B9E, 0x00DF, 0x0E43, 0x05E0, 0x4C00, 0x00FE, + 0x0E40, 0x8100, 0x8900, 0x00DE, 0x0B9F, 0x00DF, 0x0BA1, 0x8200, 0x0293, 0x031D, 0x7800, 0x029F, 0x0320, 0x0295, 0x0320, 0x7400, + 0x00FE, 0x0B9F, 0x00DF, 0x0E43, 0x05E0, 0x4C00, 0x00FE, 0x0E41, 0x029F, 0x0332, 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, 0x0254, 0x8E00, 0x8100, 0x00DE, 0x0B9B, 0xB100, 0x0295, 0x036A, 0x00DE, 0x0B9C, 0x00DC, 0x0B9D, 0x2ECE, 0x2CCF, + 0x8100, 0x00DE, 0x0E1C, 0x2ECD, 0x16C9, 0x0001, 0x16CB, 0x0040, 0x02BF, 0x055C, 0x8100, 0x8900, 0x00DE, 0x0B82, 0x00DF, 0x0B83, + 0x2ECE, 0x2FCF, 0x16CD, 0x0B80, 0x16C9, 0x0001, 0x16CB, 0x00C0, 0x02BF, 0x055C, 0x8100, 0x00DE, 0x0B80, 0x00DC, 0x0B81, 0xB100, + 0x0294, 0x0386, 0x00C0, 0x0E07, 0x029F, 0x0068, 0x2ECE, 0x2CCF, 0x16CD, 0x0B80, 0x16C9, 0x0000, 0x16CB, 0x00C0, 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, 0x055C, 0x00DE, 0x0BA7, 0x00DF, + 0x0BA8, 0x2ECE, 0x2FCF, 0x16CD, 0x03C0, 0x16C9, 0x0000, 0x16CB, 0x0080, 0x8100, 0x8900, 0x00DE, 0x0B84, 0x009F, 0x0AFC, 0x4C00, + 0x1C7E, 0x0213, 0x00FE, 0x0E15, 0x00DE, 0x0B85, 0x009F, 0x0AFF, 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E16, 0x00DE, 0x0B86, 0x009F, + 0x0ADC, 0x4C00, 0x1C7E, 0x0213, 0x00FE, 0x0E14, 0x8100, 0x00DE, 0x0B9B, 0xB100, 0x0295, 0x0403, 0x8900, 0x00DF, 0x0B9E, 0x0300, + 0x0CC0, 0x00FF, 0x0E40, 0x00DF, 0x0B9F, 0x0300, 0x0CC0, 0x00FF, 0x0E41, 0x009F, 0x0CE0, 0x00FF, 0x0E42, 0x00FF, 0x0E43, 0x02BF, + 0x055C, 0x00DE, 0x0B9C, 0x2ECE, 0x00DE, 0x0B9D, 0x2ECF, 0x16CD, 0x0CC0, 0x16C9, 0x0000, 0x16CB, 0x0040, 0x02BF, 0x055C, 0x00C0, + 0x0E07, 0x029F, 0x0249, 0x009F, 0x0CE0, 0x00FF, 0x0E42, 0x00FF, 0x0E40, 0x00FF, 0x0E41, 0x00FF, 0x0E43, 0x02BF, 0x055C, 0x00C0, + 0x0E07, 0x029F, 0x0249, 0x8E00, 0x0086, 0x0400, 0x8100, 0x8970, 0x191C, 0x2ECE, 0x2CCF, 0x1FC6, 0x2ECD, 0x16C9, 0x0001, 0x16CB, + 0x0780, 0x02BF, 0x055C, 0x02BF, 0x0484, 0x029F, 0x0068, 0x8E00, 0x0086, 0x07C0, 0x8100, 0x8970, 0x191C, 0x2ECE, 0x2CCF, 0x1FC6, + 0x2ECD, 0x16C9, 0x0001, 0x16CB, 0x0780, 0x02BF, 0x055C, 0x02BF, 0x0484, 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, 0x055C, 0x1105, 0x046C, 0x1F61, 0x1120, 0x045E, 0x8972, 0x195C, 0xF07B, 0x197D, 0xF131, 0x8139, 0x8900, + 0x6800, 0x2ECE, 0x2CCF, 0x1FFB, 0x2FCD, 0x0F01, 0x2FC9, 0x1FF9, 0x2FCB, 0x7200, 0x1F5E, 0x1F1C, 0x8100, 0x26C9, 0x02A0, 0x0004, + 0x029C, 0x046D, 0x029F, 0x0068, 0x029F, 0x0068, 0x029F, 0x0068, 0x029F, 0x0068, 0x16FC, 0xDCD1, 0x16FD, 0x0002, 0x16FB, 0x0001, + 0x029F, 0x0C56, 0x029F, 0x0045, 0x8E00, 0x191F, 0x191D, 0x1F5F, 0x1F1D, 0x2FCE, 0x2DCF, 0x8900, 0x1FA6, 0x2DCD, 0x0E00, 0x2EC9, + 0x8100, 0x009C, 0x00C0, 0x2CCB, 0x1CA0, 0x0081, 0x0E44, 0x4800, 0x1B3E, 0x1B3C, 0x0B00, 0x0099, 0x0060, 0x4B00, 0x1B3D, 0x0081, + 0x0E44, 0x1C06, 0x0083, 0x0000, 0x1C43, 0x27C9, 0x03A0, 0x0004, 0x029C, 0x04A5, 0x1109, 0x04DA, 0x8E00, 0x193A, 0x1938, 0x6900, + 0x2FCE, 0x2DCF, 0x8900, 0x193D, 0x2DCD, 0x16C9, 0x0000, 0x8100, 0x009C, 0x00C0, 0x2CCB, 0x0081, 0x0E44, 0x4800, 0x1B3E, 0x1B3C, + 0x0B00, 0x0960, 0x4B00, 0x1B3D, 0x0081, 0x0E44, 0x8F00, 0x80F0, 0x80C0, 0x6A00, 0x4800, 0x1117, 0x04D4, 0x80F0, 0x80C0, 0x6B32, + 0x4922, 0x80F0, 0x80C0, 0x6A3A, 0x482A, 0x80F0, 0x80C0, 0x6B32, 0x4922, 0x1B5F, 0x1B5D, 0x80F0, 0x80C0, 0x6A00, 0x4800, 0x1117, + 0x04E8, 0x80F0, 0x80C0, 0x6B32, 0x4922, 0x80F0, 0x80C0, 0x6A3A, 0x482A, 0x80F0, 0x80C0, 0x6B32, 0x4922, 0x1B5F, 0x1B5D, 0x1C05, + 0x02DF, 0x8E00, 0x009B, 0x0E44, 0x009D, 0x00C0, 0x02BF, 0x0541, 0x4900, 0x00FF, 0x0E1D, 0x00FD, 0x0E1E, 0x8900, 0x02BF, 0x055C, + 0x1104, 0x052C, 0x00DA, 0x0E1D, 0x00D8, 0x0E1E, 0x009B, 0x0EA4, 0x009D, 0x00C0, 0x02BF, 0x0541, 0x4900, 0x00FF, 0x0E1D, 0x00FD, + 0x0E1E, 0x0083, 0x0E44, 0x02BF, 0x054C, 0x8900, 0x00DA, 0x0E1D, 0x00D8, 0x0E1E, 0x009B, 0x0E44, 0x009D, 0x00C0, 0x02BF, 0x0541, + 0x4900, 0x00FF, 0x0E1D, 0x00FD, 0x0E1E, 0x0083, 0x0EA4, 0x02BF, 0x054C, 0x0000, 0x0000, 0x8E00, 0x8900, 0x00DA, 0x0E1D, 0x00D8, + 0x0E1E, 0x009B, 0x0EA4, 0x009D, 0x00C0, 0x02BF, 0x0541, 0x4900, 0x0083, 0x0E44, 0x02BF, 0x054C, 0x0083, 0x0EA4, 0x02BF, 0x054C, + 0x02DF, 0x8E00, 0x00FA, 0xFFCE, 0x00F8, 0xFFCF, 0x00FB, 0xFFCD, 0x16C9, 0x0000, 0x2DCB, 0x02DF, 0x8F00, 0x8D00, 0x8A00, 0x197A, + 0x1978, 0xA000, 0xB600, 0x1130, 0x055A, 0x9179, 0x4E6D, 0x197A, 0x4D43, 0xA039, 0xB629, 0x02DF, 0x26C9, 0x02A0, 0x0004, 0x029C, + 0x055C, 0x02DF, 0x26FE, 0x02C0, 0x8000, 0x029C, 0x0562, 0x02DF, 0x26FC, 0x02A0, 0x8000, 0x029C, 0x0568, 0x02DF, 0x26FC, 0x02A0, + 0x8000, 0x029C, 0x056E, 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, 0x8E00, 0x00D8, + 0x0E16, 0x195B, 0x1959, 0x8100, 0x195C, 0x0080, 0x0E44, 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, + 0x0E44, 0x0081, 0xFFDD, 0x0083, 0x0D80, 0x0064, 0x05E6, 0x1827, 0x1B07, 0x4A00, 0x1FFC, 0x1827, 0x1B07, 0x1579, 0x3500, 0x1827, + 0x1B07, 0x4100, 0x1B7E, 0x1827, 0x1B07, 0x1B7F, 0x0000, 0x0065, 0x05EC, 0x1827, 0x1B07, 0x0000, 0x0000, 0x0007, 0x187F, 0x0066, + 0x05F5, 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, 0x0620, 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, 0x8E00, 0x195B, 0x1959, 0x8100, 0x195C, 0x0080, 0x0E44, 0x195F, 0x195F, 0x195F, 0x1B1F, 0x185F, 0x1B1F, + 0x6B00, 0x1505, 0x4D00, 0x157E, 0x1C9F, 0x1CBD, 0x05E0, 0x9900, 0x7D00, 0x1CDD, 0x8900, 0x1FA5, 0x1502, 0x1CBF, 0x009A, 0x01FC, + 0x009E, 0x0E45, 0x0081, 0xFFDD, 0x0083, 0x0D80, 0x0064, 0x0697, 0x1827, 0x1B07, 0x4A00, 0x1B7E, 0x1827, 0x1B07, 0x1B7C, 0x0000, + 0x1827, 0x1B07, 0x0000, 0x0000, 0x1827, 0x1B07, 0x0000, 0x0000, 0x0065, 0x069D, 0x1827, 0x1B07, 0x0000, 0x0000, 0x0066, 0x06A2, + 0x4A00, 0x1B7E, 0x1B7C, 0x0004, 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, 0x00C1, 0x0E42, + 0x0082, 0x0D80, 0x8100, 0x1120, 0x06CF, 0x8900, 0x1940, 0x189E, 0x181B, 0x199A, 0x5400, 0x1F5E, 0x1959, 0xB000, 0xFB00, 0x8139, + 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, 0x00C0, 0x0E42, 0x0081, 0xFFDD, 0x1120, + 0x0714, 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, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, + 0x80E7, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x1C62, 0x00C4, 0x0E41, 0x00C5, + 0x0E09, 0x02BF, 0x80E7, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x1C62, 0x00C4, 0x0E41, + 0x00C5, 0x0E0C, 0x02BF, 0x80E7, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x1C62, + 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x80E7, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, 0x0081, 0x0B91, 0x00C2, 0x0E0E, + 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E0F, 0x02BF, 0x80E7, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, + 0x00C2, 0x0E08, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x80E7, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, 0x0081, + 0x0B8D, 0x00C2, 0x0E0B, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E0C, 0x02BF, 0x80E7, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, 0x00C0, 0x0E40, + 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E0F, 0x02BF, 0x80E7, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 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, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x80E7, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, + 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E0C, 0x02BF, 0x80E7, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, 0x00C0, + 0x0E43, 0x0081, 0x0B97, 0x00C2, 0x0E0A, 0x1C62, 0x1C80, 0x00C5, 0x0E0D, 0x02BF, 0x80E7, 0x00F8, 0x0BAF, 0x00FB, 0x0BB0, 0x02DF, + 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x80E7, 0x00F8, 0x0BA9, 0x00FB, + 0x0BAC, 0x00C0, 0x0E40, 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E0F, 0x02BF, 0x80E7, 0x00F8, 0x0BAB, + 0x00FB, 0x0BAE, 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x1C62, 0x1C80, 0x00C5, 0x0E0A, 0x02BF, 0x80E7, 0x00F8, 0x0BB1, + 0x00FB, 0x0BAF, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x80E7, + 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E0C, 0x02BF, + 0x80E7, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, 0x00C0, 0x0E40, 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E0F, + 0x02BF, 0x80E7, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x00C0, 0x0E43, 0x0081, 0x0B97, 0x00C2, 0x0E0A, 0x1C62, 0x1C80, 0x00C5, 0x0E0D, + 0x02BF, 0x80E7, 0x00F8, 0x0BAF, 0x00FB, 0x0BB0, 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x1C62, 0x02BF, 0x81F9, 0x00F8, + 0x0BB1, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x8282, + 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, + 0x0E09, 0x02BF, 0x8282, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x0083, 0x0E44, 0x00C4, + 0x0E41, 0x00C5, 0x0E0C, 0x02BF, 0x8282, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, + 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x8282, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, 0x0081, 0x0B91, + 0x00C2, 0x0E0E, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E0F, 0x02BF, 0x8282, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x02DF, 0x00C0, + 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x8282, 0x00F8, 0x0BA9, 0x00FB, + 0x0BAC, 0x00C0, 0x0E40, 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E0C, 0x02BF, 0x8282, 0x00F8, + 0x0BAA, 0x00FB, 0x0BAD, 0x00C0, 0x0E40, 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E0F, 0x02BF, + 0x8282, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E44, 0x00C4, 0x0E41, + 0x00C5, 0x0E09, 0x02BF, 0x8282, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E43, 0x0081, 0x0B97, 0x00C2, 0x0E0A, 0x0083, 0x0E44, + 0x02BF, 0x845D, 0x00F8, 0x0BAF, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, + 0x0E09, 0x02BF, 0x8282, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x0083, 0x0E44, 0x00C4, + 0x0E41, 0x00C5, 0x0E0C, 0x02BF, 0x8282, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, 0x00C0, 0x0E43, 0x0081, 0x0B97, 0x00C2, 0x0E0A, 0x0083, + 0x0E44, 0x1C80, 0x00C5, 0x0E0D, 0x02BF, 0x8282, 0x00F8, 0x0BAF, 0x00FB, 0x0BB0, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, + 0x0E08, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x8282, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, 0x0081, + 0x0B91, 0x00C2, 0x0E0E, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E0F, 0x02BF, 0x8282, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x00C0, + 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x0083, 0x0E44, 0x1C80, 0x00C5, 0x0E0A, 0x02BF, 0x8282, 0x00F8, 0x0BB1, 0x00FB, 0x0BAF, + 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x8282, 0x00F8, + 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E40, 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x0083, 0x0E44, 0x00C0, 0x0E41, 0x00C5, 0x0E0C, 0x02BF, + 0x8282, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, 0x00C0, 0x0E40, 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, + 0x0E0F, 0x02BF, 0x8282, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x00C0, 0x0E43, 0x0081, 0x0B97, 0x00C2, 0x0E0A, 0x0083, 0x0E44, 0x1C80, + 0x00C5, 0x0E0D, 0x02BF, 0x8282, 0x00F8, 0x0BAF, 0x00FB, 0x0BB0, 0x00C0, 0x0E43, 0x0081, 0x0B95, 0x00C2, 0x0E10, 0x0083, 0x0E44, + 0x02BF, 0x845D, 0x00F8, 0x0BB1, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x1C62, 0x00C4, 0x0E41, 0x00C5, 0x0E09, + 0x02BF, 0x80E7, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E43, 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x1C62, 0x1C80, 0x00C5, 0x0E0F, + 0x02BF, 0x80E7, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x1C62, 0x00C4, 0x0E41, + 0x00C5, 0x0E09, 0x02BF, 0x80E7, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E43, 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x1C62, 0x1C80, + 0x00C5, 0x0E0F, 0x02BF, 0x80E7, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x00C0, 0x0E40, 0x0081, 0x0B8D, 0x00C2, 0x0E0B, 0x1C62, 0x00C4, + 0x0E41, 0x00C5, 0x0E0C, 0x02BF, 0x80E7, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, 0x00C0, 0x0E43, 0x0081, 0x0B99, 0x00C2, 0x0E0D, 0x1C62, + 0x02BF, 0x81F9, 0x00F8, 0x0BB0, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, + 0x0E09, 0x02BF, 0x8282, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E43, 0x0081, 0x0B91, 0x00C2, 0x0E0E, 0x0083, 0x0E44, 0x1C80, + 0x00C5, 0x0E0F, 0x02BF, 0x8282, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x02DF, 0x00C0, 0x0E40, 0x0081, 0x0B89, 0x00C2, 0x0E08, 0x0083, + 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E09, 0x02BF, 0x8282, 0x00F8, 0x0BA9, 0x00FB, 0x0BAC, 0x00C0, 0x0E43, 0x0081, 0x0B91, 0x00C2, + 0x0E0E, 0x0083, 0x0E44, 0x1C80, 0x00C5, 0x0E0F, 0x02BF, 0x8282, 0x00F8, 0x0BAB, 0x00FB, 0x0BAE, 0x00C0, 0x0E40, 0x0081, 0x0B8D, + 0x00C2, 0x0E0B, 0x0083, 0x0E44, 0x00C4, 0x0E41, 0x00C5, 0x0E0C, 0x02BF, 0x8282, 0x00F8, 0x0BAA, 0x00FB, 0x0BAD, 0x00C0, 0x0E43, + 0x0081, 0x0B99, 0x00C2, 0x0E0D, 0x0083, 0x0E44, 0x02BF, 0x845D, 0x00F8, 0x0BB0, 0x02DF, 0x0082, 0x013E, 0x01BD, 0x0249, 0x0413, + 0x0427, 0x0165, 0x0175, 0x0B02, 0x015F, 0x0478, 0x0474, 0x0476, 0x01AA, 0x043B, 0x047A, 0x0B7C, 0x0734, 0x0746, 0x0769, 0x078C, + 0x07C0, 0x07DD, 0x0810, 0x0843, 0x0892, 0x08A5, 0x08CA, 0x08EF, 0x0926, 0x0945, 0x097B, 0x09B1, 0x0A05, 0x0A27, 0x0734, 0x0734, + 0x0734, 0x0734, 0x0734, 0x0734, 0x0A65, 0x0A89, 0x0734, 0x0734, 0x0734, 0x0734, 0x0734, 0x0734, 0x0574, 0x0629, 0x06D3, 0x1000, + 0x1200, 0x1400, 0x8E00, 0x8100, 0x8970, 0x191C, 0x2ECE, 0x2CCF, 0x16CD, 0x0E80, 0x16C9, 0x0000, 0x16CB, 0x0100, 0x1F7E, 0x1F3C, + 0x8100, 0x26C9, 0x02A0, 0x0004, 0x029C, 0x0B11, 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, 0x0B2F, 0x8F00, 0x8A78, 0x8C68, 0xF100, 0x1A3F, 0x84E3, 0x107E, 0xF2E3, 0xF2E7, 0xF278, 0x6E68, 0xF132, + 0x1A3F, 0x119E, 0x0B4B, 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, 0x0B6B, 0x197F, 0x9930, 0x1B1E, 0x1B3F, 0x7D29, 0x1B5F, 0x1B5D, 0x8E00, 0x1FDB, 0x1F99, 0x2ECE, + 0x2CCF, 0x16CD, 0x0E80, 0x16C9, 0x0001, 0x16CB, 0x0100, 0x02BF, 0x055C, 0x1C04, 0x029F, 0x0068, 0x8E00, 0x8100, 0x8970, 0x191C, + 0x2ECE, 0x2CCF, 0x16CD, 0x07C0, 0x16C9, 0x0001, 0x16CB, 0x0500, 0x02BF, 0x055C, 0x8100, 0x8970, 0x191C, 0x2ECE, 0x2CCF, 0x16CD, + 0x07C0, 0x16C9, 0x0000, 0x8900, 0x0D20, 0x2DCB, 0x4C00, 0x1C80, 0x0080, 0x07C0, 0x0083, 0x0000, 0x1C43, 0x0A00, 0x27C9, 0x03A0, + 0x0004, 0x029C, 0x0B9E, 0x2ECE, 0x2CCF, 0x16CD, 0x07D0, 0x16C9, 0x0000, 0x16CB, 0x04E0, 0x8F00, 0x80F0, 0x80C0, 0x6A00, 0x4800, + 0x114F, 0x0BB9, 0x80F0, 0x80C0, 0x6B32, 0x4922, 0x80F0, 0x80C0, 0x6A3A, 0x482A, 0x80F0, 0x80C0, 0x6B32, 0x4922, 0x1B5F, 0x1B5D, + 0x80F0, 0x80C0, 0x6800, 0x7C00, 0x4A00, 0x114F, 0x0BD0, 0x80F0, 0x80C0, 0x6932, 0x7D00, 0x4B22, 0x80F0, 0x80C0, 0x683A, 0x7C00, + 0x4A2A, 0x80F0, 0x80C0, 0x6932, 0x7D00, 0x4B22, 0x1B5F, 0x1B5D, 0x1C04, 0x029F, 0x0068, 0x8E00, 0x16FC, 0xECC0, 0x1FCC, 0x1D9E, + 0x2EFD, 0x26FC, 0x02A0, 0x8000, 0x029C, 0x0BE1, 0x0000, 0x0000, 0x0000, 0x02FF, 0x8E00, 0x00F0, 0x0E17, 0x00FE, 0x0E18, 0x00FC, + 0x0E19, 0x1FCC, 0x1D9E, 0x16FC, 0xFEED, 0x2EFD, 0x26FC, 0x02A0, 0x8000, 0x029C, 0x0BF6, 0x00D0, 0x0E17, 0x00DE, 0x0E18, 0x00DC, + 0x0E19, 0x0000, 0x0000, 0x0000, 0x0000, 0x02FF, 0x8E00, 0x1DBC, 0x1DBE, 0x8100, 0x00DE, 0x0BB7, 0x0601, 0x0295, 0x0C12, 0x0E00, + 0x00FE, 0x0B87, 0x1FCD, 0x1F8D, 0x02FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x02FF, 0x8E00, 0x1DBC, 0x1DBE, 0x8100, 0x00DE, + 0x0BB7, 0x0601, 0x0295, 0x0C2A, 0x0E00, 0x00FE, 0x0B87, 0x1FCD, 0x1F8D, 0x02FF, 0x8100, 0x00DE, 0x0B88, 0x0601, 0x0295, 0x0C3C, + 0x00DE, 0x0BDA, 0x2EDA, 0x00DE, 0x0BDB, 0x2EDB, 0x00DE, 0x0BDC, 0x2EDC, 0x1FCD, 0x1F8D, 0x02FF, 0x00DE, 0x0BDA, 0x2EDA, 0x26DB, + 0x2EDB, 0x26DC, 0x2EDC, 0x8100, 0x1FCD, 0x1F8D, 0x02FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x02FF, 0x0000, 0x0000, 0x0000, + 0x0000, 0x02FF, 0x0C64, 0x0C67, 0x0C9F, 0x0CA2, 0x8E00, 0x8100, 0x8900, 0x02BF, 0x0CA5, 0x27FF, 0x009E, 0x0C52, 0x4C00, 0x1C7E, + 0x0313, 0x1C7F, 0x176F, 0x0021, 0x029F, 0x0030, 0x0021, 0x8100, 0x8900, 0x02BF, 0x0CA5, 0x24FF, 0x02BF, 0x0CAB, 0x25FF, 0x02BF, + 0x0CAB, 0x27FF, 0x2ECE, 0x2CCF, 0x16C9, 0x0001, 0x2FCD, 0x2DCB, 0x8100, 0x8900, 0x02BF, 0x0CA5, 0x24FF, 0x1C9E, 0x1CBC, 0x02BF, + 0x0CAB, 0x25FF, 0x02BF, 0x0CAB, 0x27FF, 0x1CDF, 0x1CFD, 0x8100, 0x02BF, 0x0CA5, 0x26FF, 0x1C1E, 0x8900, 0x02BF, 0x0CAB, 0x20FF, + 0x1F5F, 0x02BF, 0x0CA5, 0x21FF, 0x02BF, 0x0CA5, 0x23FF, 0x26C9, 0x02A0, 0x0004, 0x029C, 0x0C97, 0x029F, 0x80B5, 0x0021, 0x029F, + 0x8000, 0x0021, 0x029F, 0x0045, 0x0021, 0x26FE, 0x02C0, 0x8000, 0x029C, 0x0CA5, 0x02DF, 0x27FE, 0x03C0, 0x8000, 0x029C, 0x0CAB, + 0x02DF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 +}; diff --git a/libs/dolphin/ax/__ax.h b/libs/dolphin/ax/__ax.h new file mode 100644 index 000000000..1fb0fb8d2 --- /dev/null +++ b/libs/dolphin/ax/__ax.h @@ -0,0 +1,67 @@ +#ifndef _DOLPHIN_AX_INTERNAL_H_ +#define _DOLPHIN_AX_INTERNAL_H_ + +#include + +// AXAlloc.c +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.c +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); + +// AXCL.c +extern u32 __AXClMode; + +u32 __AXGetCommandListCycles(void); +u32 __AXGetCommandListAddress(void); +void __AXWriteToCommandList(u16 data); +void __AXNextFrame(void* sbuffer, void* buffer); +void __AXClInit(void); +void __AXClQuit(void); + +// AXOut.c +void __AXOutNewFrame(u32 lessDspCycles); +void __AXOutAiCallback(void); +void __AXOutInitDSP(void); +void __AXOutInit(u32); +void __AXOutQuit(void); + +// AXProf.c +AXPROFILE* __AXGetCurrentProfile(void); + +// AXSPB.c +u32 __AXGetStudio(void); +void __AXDepopFade(long* hostSum, long* dspVolume, s16* dspDelta); +void __AXPrintStudio(void); +void __AXSPBInit(void); +void __AXSPBQuit(void); +void __AXDepopVoice(AXPB* p); + +// AXVPB.c +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); + +#endif // _DOLPHIN_AX_INTERNAL_H_ diff --git a/libs/dolphin/base/PPCArch.c b/libs/dolphin/base/PPCArch.c new file mode 100644 index 000000000..33dc03e67 --- /dev/null +++ b/libs/dolphin/base/PPCArch.c @@ -0,0 +1,263 @@ +#include +#include +#include + +union FpscrUnion +{ + f64 f; + struct + { + u32 fpscr_pad; + u32 fpscr; + } u; +}; + +void PPCMthid0(u32 newHID0); + +asm u32 PPCMfmsr(void) +{ + nofralloc mfmsr r3 blr +} + +asm void PPCMtmsr(register u32 newMSR) +{ + nofralloc mtmsr newMSR blr +} + +void PPCOrMsr(void) +{ + // UNUSED FUNCTION +} + +void PPCAndMsr(void) +{ + // UNUSED FUNCTION +} + +void PPCAndCMsr(void) +{ + // UNUSED FUNCTION +} + +asm u32 PPCMfhid0(void) +{ + nofralloc mfspr r3, HID0 blr +} + +asm void PPCMthid0(register u32 newHID0) +{ + nofralloc mtspr HID0, newHID0 blr +} + +void PPCMfhid1(void) +{ + // UNUSED FUNCTION +} + +asm u32 PPCMfl2cr(void) +{ + nofralloc mfspr r3, L2CR blr +} + +asm void PPCMtl2cr(register u32 newL2cr) +{ + nofralloc mtspr L2CR, newL2cr blr +} + +__declspec(weak) asm void PPCMtdec(register u32 newDec) +{ + nofralloc mtdec newDec blr +} + +void PPCMfdec(void) +{ + // UNUSED FUNCTION +} + +asm void PPCSync(void) +{ + nofralloc sc blr +} + +asm void PPCEieio(void) +{ + nofralloc mfmsr r5 rlwinm r6, r5, 0, 0x11, 0xf mtmsr r6 mfspr r3, hid0 ori r4, r3, 8 mtspr hid0, + r4 isync eieio isync + + mtspr hid0, + r3 mtmsr r5 isync + + blr +} + +__declspec(weak) asm void PPCHalt(void) //spins infinitely +{ + nofralloc + + sync + + _spin : nop li r3, + 0 nop b _spin + + // NEVER REACHED +} + +asm void PPCMfmmcr0(void) +{ + nofralloc mfspr r3, MMCR0 blr +} + +asm void PPCMtmmcr0(register u32 newMmcr0) +{ + nofralloc mtspr MMCR0, newMmcr0 blr +} + +asm void PPCMfmmcr1(void) +{ + nofralloc mfspr r3, MMCR1 blr +} + +asm void PPCMtmmcr1(register u32 newMmcr1) +{ + nofralloc mtspr MMCR1, newMmcr1 blr +} + +asm void PPCMfpmc1(void) +{ + nofralloc mfspr r3, PMC1 blr +} + +asm void PPCMtpmc1(register u32 newPmc1) +{ + nofralloc mtspr PMC1, newPmc1 blr +} + +asm void PPCMfpmc2(void) +{ + nofralloc mfspr r3, PMC2 blr +} + +asm void PPCMtpmc2(register u32 newPmc2) +{ + nofralloc mtspr PMC2, newPmc2 blr +} + +asm void PPCMfpmc3(void) +{ + nofralloc mfspr r3, PMC2 blr +} + +asm void PPCMtpmc3(register u32 newPmc3) +{ + nofralloc mtspr PMC3, newPmc3 blr +} + +asm void PPCMfpmc4(void) +{ + nofralloc mfspr r3, PMC4 blr +} + +asm void PPCMtpmc4(register u32 newPmc4) +{ + nofralloc mtspr PMC4, newPmc4 blr +} + +asm void PPCMfsia(void) +{ + nofralloc mfspr r3, SIA blr +} + +asm void PPCMtsia(register u32 newSia){ nofralloc mtspr SIA, newSia blr } + +u32 PPCMffpscr(void) +{ + union FpscrUnion m; + + asm + { + mffs f31 + stfd f31, m.f; + } + + return m.u.fpscr; +} + +void PPCMtfpscr(register u32 newFPSCR) +{ + union FpscrUnion m; + + asm + { + li r4, 0 + stw r4, m.u.fpscr_pad; + stw newFPSCR, m.u.fpscr + lfd f31, m.f + mtfsf 0xff, f31 + } +} + +asm u32 PPCMfhid2(void) +{ + nofralloc mfspr r3, 0x398 blr +} + +asm void PPCMthid2(register u32 newhid2) +{ + nofralloc mtspr 0x398, newhid2 blr +} + +asm u32 PPCMfwpar(void) +{ + nofralloc sync mfspr r3, WPAR blr +} + +asm void PPCMtwpar(register u32 newwpar) +{ + nofralloc mtspr WPAR, newwpar blr +} + +asm void PPCMfdmaU(void) +{ + nofralloc mfspr r3, DMA_U blr +} + +asm void PPCMfdmaL(void) +{ + nofralloc mfspr r3, DMA_L blr +} + +void PPCMtdmaU(void) +{ + // UNUSED FUNCTION +} + +void PPCMtdmaL(void) +{ + // UNUSED FUNCTION +} + +void PPCMfpvr(void) +{ + // UNUSED FUNCTION +} + +void PPCEnableSpeculation(void) +{ + // UNUSED FUNCTION +} + +void PPCDisableSpeculation(void) +{ + PPCMthid0(PPCMfhid0() | HID0_SPD); +} + +asm void PPCSetFpIEEEMode(void) +{ + nofralloc mtfsb0 4 * 7 + 1 blr +} + +asm void PPCSetFpNonIEEEMode(void) +{ + nofralloc mtfsb1 29 blr +} +// clang-format on \ No newline at end of file diff --git a/libs/dolphin/card/CARDBios.c b/libs/dolphin/card/CARDBios.c new file mode 100644 index 000000000..8988eac3c --- /dev/null +++ b/libs/dolphin/card/CARDBios.c @@ -0,0 +1,722 @@ +#include + +const char* __CARDVersion = + "<< Dolphin SDK - CARD\trelease build: Apr 17 2003 12:34:19 (0x2301) >>"; + +CARDControl __CARDBlock[2]; +DVDDiskID __CARDDiskNone; + +static u16 __CARDEncode; + +s32 __CARDReadStatus(s32 chan, u8* status); +s32 __CARDClearStatus(s32 chan); +void __CARDSetDiskID(const DVDDiskID* id); +static s32 Retry(s32 chan); +static BOOL OnReset(BOOL f); + +static OSResetFunctionInfo ResetFunctionInfo = { OnReset, 127 }; + +void __CARDDefaultApiCallback(s32 chan, s32 result) +{ +} + +void __CARDSyncCallback(s32 channel, s32 result) +{ + OSWakeupThread(&__CARDBlock[channel].threadQueue); +} + +void __CARDExtHandler(s32 chan, OSContext* context) +{ + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + if (card->attached) + { + card->attached = FALSE; + EXISetExiCallback(chan, 0); + OSCancelAlarm(&card->alarm); + callback = card->exiCallback; + + if (callback) + { + card->exiCallback = 0; + callback(chan, CARD_RESULT_NOCARD); + } + + if (card->result != CARD_RESULT_BUSY) + { + card->result = CARD_RESULT_NOCARD; + } + + callback = card->extCallback; + if (callback && CARD_MAX_MOUNT_STEP <= card->mountStep) + { + card->extCallback = 0; + callback(chan, CARD_RESULT_NOCARD); + } + } +} + +void __CARDExiHandler(s32 chan, OSContext* context) +{ + CARDControl* card; + CARDCallback callback; + u8 status; + s32 result; + + card = &__CARDBlock[chan]; + + OSCancelAlarm(&card->alarm); + + if (!card->attached) + { + return; + } + + if (!EXILock(chan, 0, 0)) + { + result = CARD_RESULT_FATAL_ERROR; + goto fatal; + } + + if ((result = __CARDReadStatus(chan, &status)) < 0 || (result = __CARDClearStatus(chan)) < 0) + { + goto error; + } + + if ((result = (status & 0x18) ? CARD_RESULT_IOERROR : CARD_RESULT_READY) == + CARD_RESULT_IOERROR && + --card->retry > 0) + { + result = Retry(chan); + if (result >= 0) + { + return; + } + goto fatal; + } + +error: + EXIUnlock(chan); + +fatal: + callback = card->exiCallback; + if (callback) + { + card->exiCallback = 0; + callback(chan, result); + } +} + +void __CARDTxHandler(s32 chan, OSContext* context) +{ + CARDControl* card; + CARDCallback callback; + BOOL err; + + card = &__CARDBlock[chan]; + err = !EXIDeselect(chan); + EXIUnlock(chan); + callback = card->txCallback; + if (callback) + { + card->txCallback = 0; + callback(chan, (!err && EXIProbe(chan)) ? CARD_RESULT_READY : CARD_RESULT_NOCARD); + } +} + +void __CARDUnlockedHandler(s32 chan, OSContext* context) +{ + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + callback = card->unlockCallback; + if (callback) + { + card->unlockCallback = 0; + callback(chan, EXIProbe(chan) ? CARD_RESULT_UNLOCKED : CARD_RESULT_NOCARD); + } +} + +s32 __CARDEnableInterrupt(s32 chan, BOOL enable) +{ + BOOL err; + u32 cmd; + + if (!EXISelect(chan, 0, 4)) + { + return CARD_RESULT_NOCARD; + } + + cmd = enable ? 0x81010000 : 0x81000000; + err = FALSE; + err |= !EXIImm(chan, &cmd, 2, 1, NULL); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; +} + +s32 __CARDReadStatus(s32 chan, u8* status) +{ + BOOL err; + u32 cmd; + + if (!EXISelect(chan, 0, 4)) + { + return CARD_RESULT_NOCARD; + } + + cmd = 0x83000000; + err = FALSE; + err |= !EXIImm(chan, &cmd, 2, 1, NULL); + err |= !EXISync(chan); + err |= !EXIImm(chan, status, 1, 0, NULL); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; +} + +s32 __CARDClearStatus(s32 chan) +{ + BOOL err; + u32 cmd; + + if (!EXISelect(chan, 0, 4)) + { + return CARD_RESULT_NOCARD; + } + + cmd = 0x89000000; + err = FALSE; + err |= !EXIImm(chan, &cmd, 1, 1, 0); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + + return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; +} + +static void TimeoutHandler(OSAlarm* alarm, OSContext* context) +{ + s32 chan; + CARDControl* card; + CARDCallback callback; + for (chan = 0; chan < 2; ++chan) + { + card = &__CARDBlock[chan]; + if (alarm == &card->alarm) + { + break; + } + } + + if (!card->attached) + { + return; + } + + EXISetExiCallback(chan, NULL); + callback = card->exiCallback; + if (callback) + { + card->exiCallback = 0; + callback(chan, CARD_RESULT_IOERROR); + } +} + +static s32 Retry(s32 chan) +{ + CARDControl* card; + card = &__CARDBlock[chan]; + + if (!EXISelect(chan, 0, 4)) + { + EXIUnlock(chan); + return CARD_RESULT_NOCARD; + } + + OSCancelAlarm(&card->alarm); + switch (card->cmd[0]) + { + case 0xF2: + OSSetAlarm(&card->alarm, OSMillisecondsToTicks(100), TimeoutHandler); + break; + case 0xF3: + break; + case 0xF4: + case 0xF1: + OSSetAlarm(&card->alarm, OSSecondsToTicks((OSTime)2) * (card->sectorSize / 0x2000), + TimeoutHandler); + break; + } + + if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1)) + { + EXIDeselect(chan); + EXIUnlock(chan); + return CARD_RESULT_NOCARD; + } + + if (card->cmd[0] == 0x52 && + !EXIImmEx(chan, (u8*)card->workArea + sizeof(CARDID), card->latency, 1)) + { + EXIDeselect(chan); + EXIUnlock(chan); + return CARD_RESULT_NOCARD; + } + + if (card->mode == 0xffffffff) + { + EXIDeselect(chan); + EXIUnlock(chan); + return CARD_RESULT_READY; + } + + if (!EXIDma(chan, card->buffer, (s32)((card->cmd[0] == 0x52) ? 512 : 128), card->mode, + __CARDTxHandler)) + { + EXIDeselect(chan); + EXIUnlock(chan); + return CARD_RESULT_NOCARD; + } + + return CARD_RESULT_READY; +} + +static void UnlockedCallback(s32 chan, s32 result) +{ + CARDCallback callback; + CARDControl* card; + + card = &__CARDBlock[chan]; + if (result >= 0) + { + card->unlockCallback = UnlockedCallback; + if (!EXILock(chan, 0, __CARDUnlockedHandler)) + { + result = CARD_RESULT_READY; + } + else + { + card->unlockCallback = 0; + result = Retry(chan); + } + } + + if (result < 0) + { + switch (card->cmd[0]) + { + case 0x52: + callback = card->txCallback; + if (callback) + { + card->txCallback = 0; + callback(chan, result); + } + + break; + case 0xF2: + case 0xF4: + case 0xF1: + callback = card->exiCallback; + if (callback) + { + card->exiCallback = 0; + callback(chan, result); + } + break; + } + } +} + +static s32 __CARDStart(s32 chan, CARDCallback txCallback, CARDCallback exiCallback) +{ + BOOL enabled; + CARDControl* card; + s32 result; + + enabled = OSDisableInterrupts(); + + card = &__CARDBlock[chan]; + if (!card->attached) + { + result = CARD_RESULT_NOCARD; + } + else + { + if (txCallback) + { + card->txCallback = txCallback; + } + if (exiCallback) + { + card->exiCallback = exiCallback; + } + card->unlockCallback = UnlockedCallback; + if (!EXILock(chan, 0, __CARDUnlockedHandler)) + { + result = CARD_RESULT_BUSY; + } + else + { + card->unlockCallback = 0; + + if (!EXISelect(chan, 0, 4)) + { + EXIUnlock(chan); + result = CARD_RESULT_NOCARD; + } + else + { + OSCancelAlarm(&card->alarm); + switch (card->cmd[0]) + { + case 0xF2: + OSSetAlarm(&card->alarm, OSMillisecondsToTicks(100), TimeoutHandler); + break; + case 0xF3: + break; + case 0xF4: + case 0xF1: + OSSetAlarm(&card->alarm, + OSSecondsToTicks((OSTime)2) * (card->sectorSize / 0x2000), + TimeoutHandler); + break; + } + result = CARD_RESULT_READY; + } + } + } + + OSRestoreInterrupts(enabled); + return result; +} + +#define AD1(x) ((u8)(((x) >> 17) & 0x7f)) +#define AD1EX(x) ((u8)(AD1(x) | 0x80)); +#define AD2(x) ((u8)(((x) >> 9) & 0xff)) +#define AD3(x) ((u8)(((x) >> 7) & 0x03)) +#define BA(x) ((u8)((x)&0x7f)) + +s32 __CARDReadSegment(s32 chan, CARDCallback callback) +{ + CARDControl* card; + s32 result; + + card = &__CARDBlock[chan]; + card->cmd[0] = 0x52; + card->cmd[1] = AD1(card->addr); + card->cmd[2] = AD2(card->addr); + card->cmd[3] = AD3(card->addr); + card->cmd[4] = BA(card->addr); + card->cmdlen = 5; + card->mode = 0; + card->retry = 0; + + result = __CARDStart(chan, callback, 0); + if (result == CARD_RESULT_BUSY) + { + result = CARD_RESULT_READY; + } + else if (result >= 0) + { + if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1) || + !EXIImmEx(chan, (u8*)card->workArea + sizeof(CARDID), card->latency, + 1) || // XXX use DMA if possible + !EXIDma(chan, card->buffer, 512, card->mode, __CARDTxHandler)) + { + card->txCallback = 0; + EXIDeselect(chan); + EXIUnlock(chan); + result = CARD_RESULT_NOCARD; + } + else + { + result = CARD_RESULT_READY; + } + } + return result; +} + +s32 __CARDWritePage(s32 chan, CARDCallback callback) +{ + CARDControl* card; + s32 result; + + card = &__CARDBlock[chan]; + card->cmd[0] = 0xF2; + card->cmd[1] = AD1(card->addr); + card->cmd[2] = AD2(card->addr); + card->cmd[3] = AD3(card->addr); + card->cmd[4] = BA(card->addr); + card->cmdlen = 5; + card->mode = 1; + card->retry = 3; + + result = __CARDStart(chan, 0, callback); + if (result == CARD_RESULT_BUSY) + { + result = CARD_RESULT_READY; + } + else if (result >= 0) + { + if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1) || + !EXIDma(chan, card->buffer, 128, card->mode, __CARDTxHandler)) + { + card->exiCallback = 0; + EXIDeselect(chan); + EXIUnlock(chan); + result = CARD_RESULT_NOCARD; + } + else + { + result = CARD_RESULT_READY; + } + } + return result; +} + +s32 __CARDEraseSector(s32 chan, u32 addr, CARDCallback callback) +{ + CARDControl* card; + s32 result; + + card = &__CARDBlock[chan]; + card->cmd[0] = 0xF1; + card->cmd[1] = AD1(addr); + card->cmd[2] = AD2(addr); + card->cmdlen = 3; + card->mode = -1; + card->retry = 3; + + result = __CARDStart(chan, 0, callback); + + if (result == CARD_RESULT_BUSY) + { + result = CARD_RESULT_READY; + } + else if (result >= 0) + { + if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1)) + { + card->exiCallback = NULL; + result = CARD_RESULT_NOCARD; + } + else + { + result = CARD_RESULT_READY; + } + + EXIDeselect(chan); + EXIUnlock(chan); + } + return result; +} + +void CARDInit(void) +{ + int chan; + + if (__CARDBlock[0].diskID && __CARDBlock[1].diskID) + { + return; + } + + __CARDEncode = OSGetFontEncode(); + + OSRegisterVersion(__CARDVersion); + + DSPInit(); + OSInitAlarm(); + + for (chan = 0; chan < 2; ++chan) + { + CARDControl* card = &__CARDBlock[chan]; + + card->result = CARD_RESULT_NOCARD; + OSInitThreadQueue(&card->threadQueue); + OSCreateAlarm(&card->alarm); + } + __CARDSetDiskID((DVDDiskID*)OSPhysicalToCached(0x0)); + + OSRegisterResetFunction(&ResetFunctionInfo); +} + +u16 __CARDGetFontEncode() +{ + return __CARDEncode; +} + +void __CARDSetDiskID(const DVDDiskID* id) +{ + __CARDBlock[0].diskID = id ? id : &__CARDDiskNone; + __CARDBlock[1].diskID = id ? id : &__CARDDiskNone; +} + +s32 __CARDGetControlBlock(s32 chan, CARDControl** pcard) +{ + BOOL enabled; + s32 result; + CARDControl* card; + + card = &__CARDBlock[chan]; + if (chan < 0 || chan >= 2 || card->diskID == NULL) + { + return CARD_RESULT_FATAL_ERROR; + } + + enabled = OSDisableInterrupts(); + if (!card->attached) + { + result = CARD_RESULT_NOCARD; + } + else if (card->result == CARD_RESULT_BUSY) + { + result = CARD_RESULT_BUSY; + } + else + { + card->result = CARD_RESULT_BUSY; + result = CARD_RESULT_READY; + card->apiCallback = 0; + *pcard = card; + } + OSRestoreInterrupts(enabled); + return result; +} + +s32 __CARDPutControlBlock(CARDControl* card, s32 result) +{ + BOOL enabled; + + enabled = OSDisableInterrupts(); + if (card->attached) + { + card->result = result; + } + else if (card->result == CARD_RESULT_BUSY) + { + card->result = result; + } + OSRestoreInterrupts(enabled); + return result; +} + +s32 CARDGetResultCode(s32 chan) +{ + CARDControl* card; + if (chan < 0 || chan >= 2) + { + return CARD_RESULT_FATAL_ERROR; + } + card = &__CARDBlock[chan]; + return card->result; +} + +s32 CARDFreeBlocks(s32 chan, s32* byteNotUsed, s32* filesNotUsed) +{ + CARDControl* card; + s32 result; + u16* fat; + CARDDir* dir; + CARDDir* ent; + u16 fileNo; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + { + return result; + } + + fat = __CARDGetFatBlock(card); + dir = __CARDGetDirBlock(card); + if (fat == 0 || dir == 0) + { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + + if (byteNotUsed) + { + *byteNotUsed = (s32)(card->sectorSize * fat[CARD_FAT_FREEBLOCKS]); + } + + if (filesNotUsed) + { + *filesNotUsed = 0; + for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) + { + ent = &dir[fileNo]; + if (ent->fileName[0] == 0xff) + { + ++*filesNotUsed; + } + } + } + + return __CARDPutControlBlock(card, CARD_RESULT_READY); +} + +s32 CARDGetEncoding(s32 chan, u16* encode) +{ + CARDControl* card; + CARDID* id; + s32 result; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + { + return result; + } + + id = card->workArea; + *encode = id->encode; + 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); +} + +s32 __CARDSync(s32 channel) +{ + CARDControl* card; + s32 result; + BOOL enabled; + + card = &__CARDBlock[channel]; + enabled = OSDisableInterrupts(); + + while ((result = CARDGetResultCode(channel)) == CARD_RESULT_BUSY) + { + OSSleepThread(&card->threadQueue); + } + + OSRestoreInterrupts(enabled); + return result; +} + +static BOOL OnReset(BOOL f) +{ + if (!f) + { + if (CARDUnmount(0) == CARD_RESULT_BUSY || CARDUnmount(1) == CARD_RESULT_BUSY) + { + return FALSE; + } + } + + return TRUE; +} \ No newline at end of file diff --git a/libs/dolphin/card/CARDBlock.c b/libs/dolphin/card/CARDBlock.c new file mode 100644 index 000000000..b6305f129 --- /dev/null +++ b/libs/dolphin/card/CARDBlock.c @@ -0,0 +1,159 @@ +#include +#include +#include +#include + +#include + +u16* __CARDGetFatBlock(CARDControl* card) { return card->currentFat; } + +static void WriteCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + u16* fat; + u16* fatBack; + + card = &__CARDBlock[chan]; + + if (result >= 0) { + fat = (u16*)((u8*)card->workArea + 0x6000); + fatBack = (u16*)((u8*)card->workArea + 0x8000); + + if (card->currentFat == fat) { + card->currentFat = fatBack; + memcpy(fatBack, fat, 0x2000); + } else { + card->currentFat = fat; + memcpy(fat, fatBack, 0x2000); + } + } + + if (card->apiCallback == NULL) { + __CARDPutControlBlock(card, result); + } + + callback = card->eraseCallback; + if (callback) { + card->eraseCallback = NULL; + callback(chan, result); + } +} + +static void EraseCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + u32 temp[2]; /* this compiler sucks */ + u16* fat; + u32 addr; + + card = &__CARDBlock[chan]; + if (result < 0) { + goto error; + } + + fat = __CARDGetFatBlock(card); + addr = ((u32)fat - (u32)card->workArea) / CARD_SYSTEM_BLOCK_SIZE * card->sectorSize; + result = __CARDWrite(chan, addr, CARD_SYSTEM_BLOCK_SIZE, fat, WriteCallback); + if (result < 0) { + goto error; + } + + return; + +error: + if (card->apiCallback == NULL) { + __CARDPutControlBlock(card, result); + } + callback = card->eraseCallback; + if (callback) { + card->eraseCallback = NULL; + callback(chan, result); + } +} + +s32 __CARDAllocBlock(s32 chan, u32 cBlock, CARDCallback callback) { + CARDControl* card; + u16* fat; + u16 iBlock; + u16 startBlock; + u16 prevBlock; + u16 count; + + card = &__CARDBlock[chan]; + if (!card->attached) { + return CARD_RESULT_NOCARD; + } + + fat = __CARDGetFatBlock(card); + if (fat[3] < cBlock) { + return CARD_RESULT_INSSPACE; + } + + fat[3] -= cBlock; + startBlock = 0xFFFF; + iBlock = fat[4]; + count = 0; + while (0 < cBlock) { + if (card->cBlock - 5 < ++count) { + return CARD_RESULT_BROKEN; + } + + iBlock++; + if (!CARDIsValidBlockNo(card, iBlock)) { + iBlock = 5; + } + + if (fat[iBlock] == 0x0000u) { + if (startBlock == 0xFFFF) { + startBlock = iBlock; + } else { + fat[prevBlock] = iBlock; + } + prevBlock = iBlock; + fat[iBlock] = 0xFFFF; + --cBlock; + } + } + fat[4] = iBlock; + card->startBlock = startBlock; + + return __CARDUpdateFatBlock(chan, fat, callback); +} + +s32 __CARDFreeBlock(s32 chan, u16 nBlock, CARDCallback callback) { + CARDControl* card; + u16* fat; + u16 nextBlock; + + card = card = &__CARDBlock[chan]; + if (!card->attached) { + return CARD_RESULT_NOCARD; + } + + fat = __CARDGetFatBlock(card); + while (nBlock != 0xFFFF) { + if (!CARDIsValidBlockNo(card, nBlock)) { + return CARD_RESULT_BROKEN; + } + + nextBlock = fat[nBlock]; + fat[nBlock] = 0; + nBlock = nextBlock; + ++fat[3]; + } + + return __CARDUpdateFatBlock(chan, fat, callback); +} + +s32 __CARDUpdateFatBlock(s32 chan, u16* fat, CARDCallback callback) { + CARDControl* card; + + card = &__CARDBlock[chan]; + ++fat[2]; + __CARDCheckSum(fat + 2, 0x1FFC, fat, fat + 1); + DCStoreRange(fat, 0x2000); + card->eraseCallback = callback; + + return __CARDEraseSector(chan, (((u32)fat - (u32)card->workArea) / 8192u) * card->sectorSize, + EraseCallback); +} diff --git a/libs/dolphin/card/CARDCheck.c b/libs/dolphin/card/CARDCheck.c new file mode 100644 index 000000000..9d0771cc9 --- /dev/null +++ b/libs/dolphin/card/CARDCheck.c @@ -0,0 +1,406 @@ +#include +#include +#include +#include + +#include +#include + +#include "string.h" + +#define __CARDGetDirCheck(dir) ((CARDDirCheck*)&(dir)[CARD_MAX_FILE]) + +void __CARDCheckSum(void* ptr, int length, u16* checksum, u16* checksumInv) +{ + u16* p; + int i; + + length /= sizeof(u16); + *checksum = *checksumInv = 0; + for (i = 0, p = ptr; i < length; i++, p++) + { + *checksum += *p; + *checksumInv += ~*p; + } + if (*checksum == 0xffff) + { + *checksum = 0; + } + if (*checksumInv == 0xffff) + { + *checksumInv = 0; + } +} + +static s32 VerifyID(CARDControl* card) +{ + CARDID* id; + u16 checksum; + u16 checksumInv; + OSSramEx* sramEx; + OSTime rand; + int i; + + id = card->workArea; + + if (id->deviceID != 0 || id->size != card->size) + { + return CARD_RESULT_BROKEN; + } + + __CARDCheckSum(id, sizeof(CARDID) - sizeof(u32), &checksum, &checksumInv); + if (id->checkSum != checksum || id->checkSumInv != checksumInv) + { + return CARD_RESULT_BROKEN; + } + + rand = *(OSTime*)&id->serial[12]; + sramEx = __OSLockSramEx(); + + for (i = 0; i < 12; i++) + { + rand = (rand * 1103515245 + 12345) >> 16; + if (id->serial[i] != (u8)(sramEx->flashID[card - __CARDBlock][i] + rand)) + { + __OSUnlockSramEx(FALSE); + return CARD_RESULT_BROKEN; + } + rand = ((rand * 1103515245 + 12345) >> 16) & 0x7FFF; + } + + __OSUnlockSramEx(FALSE); + if (id->encode != __CARDGetFontEncode()) + { + return CARD_RESULT_ENCODING; + } + + return CARD_RESULT_READY; +} + +static s32 VerifyDir(CARDControl* card, int* outCurrent) +{ + CARDDir* dir[2]; + CARDDirCheck* check[2]; + u16 checkSum; + u16 checkSumInv; + int i; + int errors; + int current; + + current = errors = 0; + for (i = 0; i < 2; i++) + { + dir[i] = (CARDDir*)((u8*)card->workArea + (1 + i) * CARD_SYSTEM_BLOCK_SIZE); + check[i] = __CARDGetDirCheck(dir[i]); + __CARDCheckSum(dir[i], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &checkSum, &checkSumInv); + if (check[i]->checkSum != checkSum || check[i]->checkSumInv != checkSumInv) + { + ++errors; + current = i; + card->currentDir = 0; + } + } + + if (0 == errors) + { + if (card->currentDir == 0) + { + if ((check[0]->checkCode - check[1]->checkCode) < 0) + { + current = 0; + } + else + { + current = 1; + } + card->currentDir = dir[current]; + memcpy(dir[current], dir[current ^ 1], CARD_SYSTEM_BLOCK_SIZE); + } + else + { + current = (card->currentDir == dir[0]) ? 0 : 1; + } + } + if (outCurrent) + { + *outCurrent = current; + } + return errors; +} + +static s32 VerifyFAT(CARDControl* card, int* outCurrent) +{ + u16* fat[2]; + u16* fatp; + u16 nBlock; + u16 cFree; + int i; + u16 checkSum; + u16 checkSumInv; + int errors; + int current; + + current = errors = 0; + for (i = 0; i < 2; i++) + { + fatp = fat[i] = (u16*)((u8*)card->workArea + (3 + i) * CARD_SYSTEM_BLOCK_SIZE); + + __CARDCheckSum(&fatp[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &checkSum, + &checkSumInv); + if (fatp[CARD_FAT_CHECKSUM] != checkSum || fatp[CARD_FAT_CHECKSUMINV] != checkSumInv) + { + ++errors; + current = i; + card->currentFat = 0; + continue; + } + + cFree = 0; + for (nBlock = CARD_NUM_SYSTEM_BLOCK; nBlock < card->cBlock; nBlock++) + { + if (fatp[nBlock] == CARD_FAT_AVAIL) + { + cFree++; + } + } + if (cFree != fatp[CARD_FAT_FREEBLOCKS]) + { + ++errors; + current = i; + card->currentFat = 0; + continue; + } + } + + if (0 == errors) + { + if (card->currentFat == 0) + { + if (((s16)fat[0][CARD_FAT_CHECKCODE] - (s16)fat[1][CARD_FAT_CHECKCODE]) < 0) + { + current = 0; + } + else + { + current = 1; + } + card->currentFat = fat[current]; + memcpy(fat[current], fat[current ^ 1], CARD_SYSTEM_BLOCK_SIZE); + } + else + { + current = (card->currentFat == fat[0]) ? 0 : 1; + } + } + if (outCurrent) + { + *outCurrent = current; + } + return errors; +} + +s32 __CARDVerify(CARDControl* card) +{ + s32 result; + int errors; + + result = VerifyID(card); + if (result < 0) + { + return result; + } + + errors = VerifyDir(card, NULL); + errors += VerifyFAT(card, NULL); + switch (errors) + { + case 0: + return CARD_RESULT_READY; + case 1: + return CARD_RESULT_BROKEN; + default: + return CARD_RESULT_BROKEN; + } +} + +s32 CARDCheckExAsync(s32 chan, s32* xferBytes, CARDCallback callback) +{ + CARDControl* card; + CARDDir* dir[2]; + u16* fat[2]; + u16* map; + s32 result; + int errors; + int currentFat; + int currentDir; + s32 fileNo; + u16 iBlock; + u16 cBlock; + u16 cFree; + BOOL updateFat = FALSE; + BOOL updateDir = FALSE; + BOOL updateOrphan = FALSE; + + if (xferBytes) + { + *xferBytes = 0; + } + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + { + return result; + } + + result = VerifyID(card); + if (result < 0) + { + return __CARDPutControlBlock(card, result); + } + + errors = VerifyDir(card, ¤tDir); + errors += VerifyFAT(card, ¤tFat); + if (1 < errors) + { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + + dir[0] = (CARDDir*)((u8*)card->workArea + (1 + 0) * CARD_SYSTEM_BLOCK_SIZE); + dir[1] = (CARDDir*)((u8*)card->workArea + (1 + 1) * CARD_SYSTEM_BLOCK_SIZE); + fat[0] = (u16*)((u8*)card->workArea + (3 + 0) * CARD_SYSTEM_BLOCK_SIZE); + fat[1] = (u16*)((u8*)card->workArea + (3 + 1) * CARD_SYSTEM_BLOCK_SIZE); + + switch (errors) + { + case 0: + break; + case 1: + if (!card->currentDir) + { + card->currentDir = dir[currentDir]; + memcpy(dir[currentDir], dir[currentDir ^ 1], CARD_SYSTEM_BLOCK_SIZE); + updateDir = TRUE; + } + else + { + card->currentFat = fat[currentFat]; + memcpy(fat[currentFat], fat[currentFat ^ 1], CARD_SYSTEM_BLOCK_SIZE); + updateFat = TRUE; + } + break; + } + + map = fat[currentFat ^ 1]; + memset(map, 0, CARD_SYSTEM_BLOCK_SIZE); + + for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) + { + CARDDir* ent; + + ent = &card->currentDir[fileNo]; + if (ent->gameName[0] == 0xff) + { + continue; + } + + for (iBlock = ent->startBlock, cBlock = 0; iBlock != 0xFFFF && cBlock < ent->length; + iBlock = card->currentFat[iBlock], ++cBlock) + { + if (!CARDIsValidBlockNo(card, iBlock) || 1 < ++map[iBlock]) + { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + } + if (cBlock != ent->length || iBlock != 0xFFFF) + { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + } + + cFree = 0; + for (iBlock = CARD_NUM_SYSTEM_BLOCK; iBlock < card->cBlock; iBlock++) + { + u16 nextBlock; + + nextBlock = card->currentFat[iBlock]; + if (map[iBlock] == 0) + { + if (nextBlock != CARD_FAT_AVAIL) + { + card->currentFat[iBlock] = CARD_FAT_AVAIL; + updateOrphan = TRUE; + } + cFree++; + } + else if (!CARDIsValidBlockNo(card, nextBlock) && nextBlock != 0xFFFF) + { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + } + if (cFree != card->currentFat[CARD_FAT_FREEBLOCKS]) + { + card->currentFat[CARD_FAT_FREEBLOCKS] = cFree; + updateOrphan = TRUE; + } + if (updateOrphan) + { + __CARDCheckSum(&card->currentFat[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), + &card->currentFat[CARD_FAT_CHECKSUM], + &card->currentFat[CARD_FAT_CHECKSUMINV]); + } + + memcpy(fat[currentFat ^ 1], fat[currentFat], CARD_SYSTEM_BLOCK_SIZE); + + if (updateDir) + { + if (xferBytes) + { + *xferBytes = CARD_SYSTEM_BLOCK_SIZE; + } + return __CARDUpdateDir(chan, callback); + } + + if (updateFat | updateOrphan) + { + if (xferBytes) + { + *xferBytes = CARD_SYSTEM_BLOCK_SIZE; + } + return __CARDUpdateFatBlock(chan, card->currentFat, callback); + } + + __CARDPutControlBlock(card, CARD_RESULT_READY); + if (callback) + { + BOOL enabled = OSDisableInterrupts(); + callback(chan, CARD_RESULT_READY); + OSRestoreInterrupts(enabled); + } + return CARD_RESULT_READY; +} + +s32 CARDCheckEx(s32 chan, s32* xferBytes) +{ + s32 result = CARDCheckExAsync(chan, xferBytes, __CARDSyncCallback); + if (result < 0 || xferBytes == 0) + { + return result; + } + + return __CARDSync(chan); +} + +s32 CARDCheck(s32 channel) +{ + s32 result; + s32 xferBytes; + + result = CARDCheckExAsync(channel, &xferBytes, __CARDSyncCallback); + + if (result < 0 || &xferBytes == nullptr) + { + return result; + } + + return __CARDSync(channel); +} \ No newline at end of file diff --git a/libs/dolphin/card/CARDCreate.c b/libs/dolphin/card/CARDCreate.c new file mode 100644 index 000000000..06132d90f --- /dev/null +++ b/libs/dolphin/card/CARDCreate.c @@ -0,0 +1,141 @@ +#include +#include +#include +#include + +#include + +static void CreateCallbackFat(s32 chan, s32 result) +{ + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + CARDCallback callback; + + card = &__CARDBlock[chan]; + callback = card->apiCallback; + card->apiCallback = 0; + if (result < 0) + { + goto error; + } + + dir = __CARDGetDirBlock(card); + ent = &dir[card->freeNo]; + memcpy(ent->gameName, card->diskID->gameName, sizeof(ent->gameName)); + memcpy(ent->company, card->diskID->company, sizeof(ent->company)); + ent->permission = CARD_ATTR_PUBLIC; + ent->copyTimes = 0; + ent->startBlock = card->startBlock; + + ent->bannerFormat = 0; + ent->iconAddr = 0xffffffff; + ent->iconFormat = 0; + ent->iconSpeed = 0; + ent->commentAddr = 0xffffffff; + + CARDSetIconSpeed(ent, 0, CARD_STAT_SPEED_FAST); + + card->fileInfo->offset = 0; + card->fileInfo->iBlock = ent->startBlock; + + ent->time = (u32)OSTicksToSeconds(OSGetTime()); + result = __CARDUpdateDir(chan, callback); + if (result < 0) + { + goto error; + } + return; + +error: + __CARDPutControlBlock(card, result); + if (callback) + { + callback(chan, result); + } +} + +s32 CARDCreateAsync(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo, + CARDCallback callback) +{ + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + u16 fileNo; + u16 freeNo; + u16* fat; + + if (strlen(fileName) > (u32)CARD_FILENAME_MAX) + { + return CARD_RESULT_NAMETOOLONG; + } + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + { + return result; + } + + if (size <= 0 || (size % card->sectorSize) != 0) + { + return CARD_RESULT_FATAL_ERROR; + } + + freeNo = (u16)-1; + dir = __CARDGetDirBlock(card); + for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) + { + ent = &dir[fileNo]; + if (ent->gameName[0] == 0xff) + { + if (freeNo == (u16)-1) + { + freeNo = fileNo; + } + } + else if (memcmp(ent->gameName, card->diskID->gameName, sizeof(ent->gameName)) == 0 && + memcmp(ent->company, card->diskID->company, sizeof(ent->company)) == 0 && + __CARDCompareFileName(ent, fileName)) + { + return __CARDPutControlBlock(card, CARD_RESULT_EXIST); + } + } + if (freeNo == (u16)-1) + { + return __CARDPutControlBlock(card, CARD_RESULT_NOENT); + } + + fat = __CARDGetFatBlock(card); + if (card->sectorSize * fat[CARD_FAT_FREEBLOCKS] < size) + { + return __CARDPutControlBlock(card, CARD_RESULT_INSSPACE); + } + + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + card->freeNo = freeNo; + ent = &dir[freeNo]; + ent->length = (u16)(size / card->sectorSize); + strncpy(ent->fileName, fileName, CARD_FILENAME_MAX); + + card->fileInfo = fileInfo; + fileInfo->chan = chan; + fileInfo->fileNo = freeNo; + + result = __CARDAllocBlock(chan, size / card->sectorSize, CreateCallbackFat); + if (result < 0) + { + return __CARDPutControlBlock(card, result); + } + return result; +} + +s32 CARDCreate(s32 channel, const char* fileName, u32 size, CARDFileInfo* fileInfo) +{ + s32 result = CARDCreateAsync(channel, fileName, size, fileInfo, __CARDSyncCallback); + if (result < 0) + { + return result; + } + return __CARDSync(channel); +} \ No newline at end of file diff --git a/libs/dolphin/card/CARDDelete.c b/libs/dolphin/card/CARDDelete.c new file mode 100644 index 000000000..2286e205e --- /dev/null +++ b/libs/dolphin/card/CARDDelete.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include + +#include + +static void DeleteCallback(s32 chan, s32 result) +{ + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + callback = card->apiCallback; + card->apiCallback = 0; + + if (result < 0) + { + goto error; + } + + result = __CARDFreeBlock(chan, card->startBlock, callback); + if (result < 0) + { + goto error; + } + return; + +error: + __CARDPutControlBlock(card, result); + if (callback) + { + callback(chan, result); + } +} + +s32 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; + + result = CARDDeleteAsync(chan, fileName, __CARDSyncCallback); + + if (result < 0) + { + return result; + } + return __CARDSync(chan); +} \ No newline at end of file diff --git a/libs/dolphin/card/CARDDir.c b/libs/dolphin/card/CARDDir.c new file mode 100644 index 000000000..1daecf8ef --- /dev/null +++ b/libs/dolphin/card/CARDDir.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include + +#include + +CARDDir* __CARDGetDirBlock(CARDControl* card) { return card->currentDir; } + +static void WriteCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + if (0 <= result) { + CARDDir* dir0 = (CARDDir*)((u8*)card->workArea + 0x2000); + CARDDir* dir1 = (CARDDir*)((u8*)card->workArea + 0x4000); + + if (card->currentDir == dir0) { + card->currentDir = dir1; + memcpy(dir1, dir0, 0x2000); + } else { + card->currentDir = dir0; + memcpy(dir0, dir1, 0x2000); + } + } + +error: + if (card->apiCallback == 0) { + __CARDPutControlBlock(card, result); + } + callback = card->eraseCallback; + if (callback) { + card->eraseCallback = 0; + callback(chan, result); + } +} + +static void EraseCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + CARDDir* dir; + u32 tmp[2]; + u32 addr; + + card = &__CARDBlock[chan]; + if (result < 0) { + goto error; + } + + dir = __CARDGetDirBlock(card); + addr = ((u32)dir - (u32)card->workArea) / 0x2000 * card->sectorSize; + result = __CARDWrite(chan, addr, 0x2000, dir, WriteCallback); + if (result < 0) { + goto error; + } + + return; + +error: + if (card->apiCallback == 0) { + __CARDPutControlBlock(card, result); + } + callback = card->eraseCallback; + if (callback) { + card->eraseCallback = 0; + callback(chan, result); + } +} + +s32 __CARDUpdateDir(s32 chan, CARDCallback callback) { + CARDControl* card; + CARDDirCheck* check; + u32 tmp[2]; + u32 addr; + CARDDir* dir; + + card = &__CARDBlock[chan]; + if (!card->attached) { + return CARD_RESULT_NOCARD; + } + + dir = __CARDGetDirBlock(card); + check = __CARDGetDirCheck(dir); + ++check->checkCode; + __CARDCheckSum(dir, 0x2000 - sizeof(u32), &check->checkSum, &check->checkSumInv); + DCStoreRange(dir, 0x2000); + + card->eraseCallback = callback; + addr = ((u32)dir - (u32)card->workArea) / 0x2000 * card->sectorSize; + return __CARDEraseSector(chan, addr, EraseCallback); +} diff --git a/libs/dolphin/card/CARDFormat.c b/libs/dolphin/card/CARDFormat.c new file mode 100644 index 000000000..a29eb05bb --- /dev/null +++ b/libs/dolphin/card/CARDFormat.c @@ -0,0 +1,138 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +static void FormatCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + if (result < 0) { + goto error; + } + + ++card->formatStep; + if (card->formatStep < CARD_NUM_SYSTEM_BLOCK) { + result = __CARDEraseSector(chan, (u32)card->sectorSize * card->formatStep, FormatCallback); + if (0 <= result) { + return; + } + } else if (card->formatStep < 2 * CARD_NUM_SYSTEM_BLOCK) { + int step = card->formatStep - CARD_NUM_SYSTEM_BLOCK; + result = __CARDWrite(chan, (u32)card->sectorSize * step, CARD_SYSTEM_BLOCK_SIZE, + (u8*)card->workArea + (CARD_SYSTEM_BLOCK_SIZE * step), FormatCallback); + if (result >= 0) { + return; + } + } else { + card->currentDir = (CARDDir*)((u8*)card->workArea + (1 + 0) * CARD_SYSTEM_BLOCK_SIZE); + memcpy(card->currentDir, (u8*)card->workArea + (1 + 1) * CARD_SYSTEM_BLOCK_SIZE, + CARD_SYSTEM_BLOCK_SIZE); + card->currentFat = (u16*)((u8*)card->workArea + (3 + 0) * CARD_SYSTEM_BLOCK_SIZE); + memcpy(card->currentFat, (u8*)card->workArea + (3 + 1) * CARD_SYSTEM_BLOCK_SIZE, + CARD_SYSTEM_BLOCK_SIZE); + } + +error: + callback = card->apiCallback; + card->apiCallback = 0; + __CARDPutControlBlock(card, result); + callback(chan, result); +} + +s32 __CARDFormatRegionAsync(s32 chan, u16 encode, CARDCallback callback) { + CARDControl* card; + CARDID* id; + CARDDir* dir; + u16* fat; + s16 i; + s32 result; + OSSram* sram; + OSSramEx* sramEx; + u16 viDTVStatus; + OSTime time; + OSTime rand; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + id = (CARDID*)card->workArea; + memset(id, 0xff, CARD_SYSTEM_BLOCK_SIZE); + viDTVStatus = __VIRegs[55]; + + id->encode = encode; + + sram = __OSLockSram(); + *(u32*)&id->serial[20] = sram->counterBias; + *(u32*)&id->serial[24] = sram->language; + __OSUnlockSram(FALSE); + + rand = time = OSGetTime(); + + sramEx = __OSLockSramEx(); + for (i = 0; i < 12; i++) { + rand = (rand * 1103515245 + 12345) >> 16; + id->serial[i] = (u8)(sramEx->flashID[chan][i] + rand); + rand = ((rand * 1103515245 + 12345) >> 16) & 0x7FFF; + } + __OSUnlockSramEx(FALSE); + + *(u32*)&id->serial[28] = viDTVStatus; + *(OSTime*)&id->serial[12] = time; + + id->deviceID = 0; + id->size = card->size; + __CARDCheckSum(id, sizeof(CARDID) - sizeof(u32), &id->checkSum, &id->checkSumInv); + + for (i = 0; i < 2; i++) { + CARDDirCheck* check; + + dir = (CARDDir*)((u8*)card->workArea + (1 + i) * CARD_SYSTEM_BLOCK_SIZE); + memset(dir, 0xff, CARD_SYSTEM_BLOCK_SIZE); + check = __CARDGetDirCheck(dir); + check->checkCode = i; + __CARDCheckSum(dir, CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &check->checkSum, + &check->checkSumInv); + } + for (i = 0; i < 2; i++) { + fat = (u16*)((u8*)card->workArea + (3 + i) * CARD_SYSTEM_BLOCK_SIZE); + memset(fat, 0x00, CARD_SYSTEM_BLOCK_SIZE); + fat[CARD_FAT_CHECKCODE] = (u16)i; + fat[CARD_FAT_FREEBLOCKS] = (u16)(card->cBlock - CARD_NUM_SYSTEM_BLOCK); + fat[CARD_FAT_LASTSLOT] = CARD_NUM_SYSTEM_BLOCK - 1; + __CARDCheckSum(&fat[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), + &fat[CARD_FAT_CHECKSUM], &fat[CARD_FAT_CHECKSUMINV]); + } + + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + DCStoreRange(card->workArea, CARD_WORKAREA_SIZE); + + card->formatStep = 0; + result = __CARDEraseSector(chan, (u32)card->sectorSize * card->formatStep, FormatCallback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + return result; +} + +s32 CARDFormatAsync(s32 chan, CARDCallback callback) { + return __CARDFormatRegionAsync(chan, __CARDGetFontEncode(), callback); +} + +s32 CARDFormat(s32 channel) +{ + s32 result = __CARDFormatRegionAsync(channel, __CARDGetFontEncode(), __CARDSyncCallback); + if (result < 0) + { + return result; + } + return __CARDSync(channel); +} \ No newline at end of file diff --git a/libs/dolphin/card/CARDMount.c b/libs/dolphin/card/CARDMount.c new file mode 100644 index 000000000..ee5dbb1a4 --- /dev/null +++ b/libs/dolphin/card/CARDMount.c @@ -0,0 +1,366 @@ +#include +#include +#include +#include + +#include +#include + +u8 GameChoice : (OS_BASE_CACHED | 0x000030E3); + +static u32 SectorSizeTable[8] = { + 8 * 1024, 16 * 1024, 32 * 1024, 64 * 1024, 128 * 1024, 256 * 1024, 0, 0, +}; + +static u32 LatencyTable[8] = { + 4, 8, 16, 32, 64, 128, 256, 512, +}; + +void __CARDMountCallback(s32 chan, s32 result); +static void DoUnmount(s32 chan, s32 result); + +static BOOL IsCard(u32 id) { + u32 size; + s32 sectorSize; + if (id & (0xFFFF0000) && (id != 0x80000004 || __CARDVendorID == 0xFFFF)) { + return FALSE; + } + + if ((id & 3) != 0) { + return FALSE; + } + + size = id & 0xfc; + switch (size) { + case 4: + case 8: + case 16: + case 32: + case 64: + case 128: + break; + default: + return FALSE; + break; + } + + sectorSize = SectorSizeTable[(id & 0x00003800) >> 11]; + if (sectorSize == 0) { + return FALSE; + } + + if ((size * 1024 * 1024 / 8) / sectorSize < 8) { + return FALSE; + } + + return TRUE; +} + +s32 CARDProbeEx(s32 chan, s32* memSize, s32* sectorSize) { + u32 id; + CARDControl* card; + BOOL enabled; + s32 result; + int probe; + + if (chan < 0 || 2 <= chan) { + return CARD_RESULT_FATAL_ERROR; + } + + if (GameChoice & 0x80) { + return CARD_RESULT_NOCARD; + } + + card = &__CARDBlock[chan]; + enabled = OSDisableInterrupts(); + + probe = EXIProbeEx(chan); + if (probe == -1) { + result = CARD_RESULT_NOCARD; + } else if (probe == 0) { + result = CARD_RESULT_BUSY; + } else if (card->attached) { + if (card->mountStep < 1) { + result = CARD_RESULT_BUSY; + } else { + if (memSize) { + *memSize = card->size; + } + if (sectorSize) { + *sectorSize = card->sectorSize; + } + result = CARD_RESULT_READY; + } + } else if ((EXIGetState(chan) & 8)) { + result = CARD_RESULT_WRONGDEVICE; + } else if (!EXIGetID(chan, 0, &id)) { + result = CARD_RESULT_BUSY; + } else if (IsCard(id)) { + if (memSize) { + *memSize = (s32)(id & 0xfc); + } + if (sectorSize) { + *sectorSize = SectorSizeTable[(id & 0x00003800) >> 11]; + } + result = CARD_RESULT_READY; + } else { + result = CARD_RESULT_WRONGDEVICE; + } + + OSRestoreInterrupts(enabled); + return result; +} + +static s32 DoMount(s32 chan) { + CARDControl* card; + u32 id; + u8 status; + s32 result; + OSSramEx* sram; + int i; + u8 checkSum; + int step; + + card = &__CARDBlock[chan]; + + if (card->mountStep == 0) { + if (EXIGetID(chan, 0, &id) == 0) { + result = CARD_RESULT_NOCARD; + } else if (IsCard(id)) { + result = CARD_RESULT_READY; + } else { + result = CARD_RESULT_WRONGDEVICE; + } + if (result < 0) { + goto error; + } + + card->cid = id; + + card->size = (u16)(id & 0xFC); + card->sectorSize = SectorSizeTable[(id & 0x00003800) >> 11]; + card->cBlock = (u16)((card->size * 1024 * 1024 / 8) / card->sectorSize); + card->latency = LatencyTable[(id & 0x00000700) >> 8]; + + result = __CARDClearStatus(chan); + if (result < 0) { + goto error; + } + result = __CARDReadStatus(chan, &status); + if (result < 0) { + goto error; + } + + if (!EXIProbe(chan)) { + result = CARD_RESULT_NOCARD; + goto error; + } + + if (!(status & 0x40)) { + result = __CARDUnlock(chan, card->id); + if (result < 0) { + goto error; + } + + checkSum = 0; + sram = __OSLockSramEx(); + for (i = 0; i < 12; i++) { + sram->flashID[chan][i] = card->id[i]; + checkSum += card->id[i]; + } + sram->flashIDCheckSum[chan] = (u8)~checkSum; + __OSUnlockSramEx(TRUE); + + return result; + } else { + card->mountStep = 1; + + checkSum = 0; + sram = __OSLockSramEx(); + for (i = 0; i < 12; i++) { + checkSum += sram->flashID[chan][i]; + } + __OSUnlockSramEx(FALSE); + if (sram->flashIDCheckSum[chan] != (u8)~checkSum) { + result = CARD_RESULT_IOERROR; + goto error; + } + } + } + + if (card->mountStep == 1) { + if (card->cid == 0x80000004) { + u16 vendorID; + + sram = __OSLockSramEx(); + vendorID = *(u16*)sram->flashID[chan]; + __OSUnlockSramEx(FALSE); + + if (__CARDVendorID == 0xffff || vendorID != __CARDVendorID) { + result = CARD_RESULT_WRONGDEVICE; + goto error; + } + } + + card->mountStep = 2; + + result = __CARDEnableInterrupt(chan, TRUE); + if (result < 0) { + goto error; + } + + EXISetExiCallback(chan, __CARDExiHandler); + EXIUnlock(chan); + DCInvalidateRange(card->workArea, CARD_WORKAREA_SIZE); + } + + step = card->mountStep - 2; + result = __CARDRead(chan, (u32)card->sectorSize * step, CARD_SYSTEM_BLOCK_SIZE, + (u8*)card->workArea + (CARD_SYSTEM_BLOCK_SIZE * step), __CARDMountCallback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + return result; + +error: + EXIUnlock(chan); + DoUnmount(chan, result); + return result; +} + +void __CARDMountCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + + switch (result) { + case CARD_RESULT_READY: + if (++card->mountStep < CARD_MAX_MOUNT_STEP) { + result = DoMount(chan); + if (0 <= result) { + return; + } + } else { + result = __CARDVerify(card); + } + break; + case CARD_RESULT_UNLOCKED: + card->unlockCallback = __CARDMountCallback; + if (!EXILock(chan, 0, __CARDUnlockedHandler)) { + return; + } + card->unlockCallback = 0; + + result = DoMount(chan); + if (0 <= result) { + return; + } + break; + case CARD_RESULT_IOERROR: + case CARD_RESULT_NOCARD: + DoUnmount(chan, result); + break; + } + + callback = card->apiCallback; + card->apiCallback = 0; + __CARDPutControlBlock(card, result); + callback(chan, result); +} + +s32 CARDMountAsync(s32 chan, void *workArea, CARDCallback detachCallback, + CARDCallback attachCallback) +{ + CARDControl* card; + BOOL enabled; + + if (chan < 0 || 2 <= chan) { + return CARD_RESULT_FATAL_ERROR; + } + if (GameChoice & 0x80) { + return CARD_RESULT_NOCARD; + } + card = &__CARDBlock[chan]; + + enabled = OSDisableInterrupts(); + if (card->result == CARD_RESULT_BUSY) { + OSRestoreInterrupts(enabled); + return CARD_RESULT_BUSY; + } + + if (!card->attached && (EXIGetState(chan) & 0x08)) { + OSRestoreInterrupts(enabled); + return CARD_RESULT_WRONGDEVICE; + } + + card->result = CARD_RESULT_BUSY; + card->workArea = workArea; + card->extCallback = detachCallback; + card->apiCallback = attachCallback ? attachCallback : __CARDDefaultApiCallback; + card->exiCallback = 0; + + if (!card->attached && !EXIAttach(chan, __CARDExtHandler)) { + card->result = CARD_RESULT_NOCARD; + OSRestoreInterrupts(enabled); + return CARD_RESULT_NOCARD; + } + + card->mountStep = 0; + card->attached = TRUE; + EXISetExiCallback(chan, 0); + OSCancelAlarm(&card->alarm); + + card->currentDir = 0; + card->currentFat = 0; + + OSRestoreInterrupts(enabled); + + card->unlockCallback = __CARDMountCallback; + if (!EXILock(chan, 0, __CARDUnlockedHandler)) { + return CARD_RESULT_READY; + } + card->unlockCallback = 0; + + return DoMount(chan); +} + +s32 CARDMount(s32 channel, void *workArea, CARDCallback detachCallback) +{ + s32 result = CARDMountAsync(channel, workArea, detachCallback, __CARDSyncCallback); + if (result < 0) + { + return result; + } + + return __CARDSync(channel); +} + +static void DoUnmount(s32 chan, s32 result) { + CARDControl* card; + BOOL enabled; + + card = &__CARDBlock[chan]; + enabled = OSDisableInterrupts(); + if (card->attached) { + EXISetExiCallback(chan, 0); + EXIDetach(chan); + OSCancelAlarm(&card->alarm); + card->attached = FALSE; + card->result = result; + card->mountStep = 0; + } + OSRestoreInterrupts(enabled); +} + +s32 CARDUnmount(s32 chan) { + CARDControl* card; + s32 result; + + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + DoUnmount(chan, CARD_RESULT_NOCARD); + return CARD_RESULT_READY; +} diff --git a/libs/dolphin/card/CARDNet.c b/libs/dolphin/card/CARDNet.c new file mode 100644 index 000000000..17d61f429 --- /dev/null +++ b/libs/dolphin/card/CARDNet.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include + +#include + +u16 __CARDVendorID = 0xFFFF; +u8 __CARDPermMask = 28; + +// 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); +} diff --git a/libs/dolphin/card/CARDOpen.c b/libs/dolphin/card/CARDOpen.c new file mode 100644 index 000000000..fc305321e --- /dev/null +++ b/libs/dolphin/card/CARDOpen.c @@ -0,0 +1,209 @@ +#include +#include +#include +#include + +#include + +BOOL __CARDCompareFileName(CARDDir *ent, const char *fileName) +{ + char *entName; + char c1; + char c2; + int n; + + entName = (char *)ent->fileName; + n = CARD_FILENAME_MAX; + while (0 <= --n) + { + if ((c1 = *entName++) != (c2 = *fileName++)) + { + return FALSE; + } + else if (c2 == '\0') + { + return TRUE; + } + } + + if (*fileName == '\0') + { + return TRUE; + } + + return FALSE; +} + +s32 __CARDAccess(CARDControl *card, CARDDir *ent) +{ + const DVDDiskID *diskID = card->diskID; + if (ent->gameName[0] == 0xFF) + { + return CARD_RESULT_NOFILE; + } + + if (diskID == &__CARDDiskNone || (memcmp(ent->gameName, diskID->gameName, 4) == 0 && + memcmp(ent->company, diskID->company, 2) == 0)) + { + return CARD_RESULT_READY; + } + + return CARD_RESULT_NOPERM; +} + +s32 __CARDIsWritable(CARDControl *card, CARDDir *entry) +{ + const DVDDiskID *diskID = card->diskID; + s32 result; + u8 perm; + + result = __CARDAccess(card, entry); + if (result == CARD_RESULT_NOPERM) + { + perm = (u8)(entry->permission & __CARDPermMask); + + if ((perm & 0x20) && (memcmp(entry->gameName, __CARDDiskNone.gameName, 4) == 0 && memcmp(entry->company, __CARDDiskNone.company, 2) == 0)) + { + return CARD_RESULT_READY; + } + + if ((perm & 0x40) && (memcmp(entry->gameName, __CARDDiskNone.gameName, 4) == 0 && memcmp(entry->company, diskID->company, 2) == 0)) + { + return CARD_RESULT_READY; + } + } + return result; +} + +s32 __CARDIsReadable(CARDControl* card, CARDDir* entry) +{ + s32 result = __CARDIsWritable(card, entry); + + if (result == CARD_RESULT_NOPERM && (entry->permission & 0x4)) { + return CARD_RESULT_READY; + } + + return result; +} + +s32 __CARDGetFileNo(CARDControl *card, const char *fileName, s32 *pfileNo) +{ + CARDDir *dir; + CARDDir *ent; + s32 fileNo; + s32 result; + + if (!card->attached) + { + return CARD_RESULT_NOCARD; + } + + dir = __CARDGetDirBlock(card); + for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) + { + ent = &dir[fileNo]; + result = __CARDAccess(card, ent); + if (result < 0) + { + continue; + } + if (__CARDCompareFileName(ent, fileName)) + { + *pfileNo = fileNo; + return CARD_RESULT_READY; + } + } + + return CARD_RESULT_NOFILE; +} + +s32 CARDFastOpen(s32 chan, s32 fileno, CARDFileInfo *fileinfo) +{ + CARDControl *card; + CARDDir *dir; + CARDDir *ent; + s32 result; + + if (fileno < 0 || fileno >= 127) + { + return CARD_RESULT_FATAL_ERROR; + } + fileinfo->chan = -1; + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + { + return result; + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileno]; + result = __CARDIsReadable(card, ent); + + if (0 <= result) + { + 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 CARDOpen(s32 chan, const char *fileName, CARDFileInfo *fileInfo) +{ + CARDControl *card; + CARDDir *dir; + CARDDir *ent; + s32 result; + s32 fileNo; + + fileInfo->chan = -1; + result = __CARDGetControlBlock(chan, &card); + if (result < 0) + { + return result; + } + result = __CARDGetFileNo(card, fileName, &fileNo); + if (0 <= result) + { + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + if (!CARDIsValidBlockNo(card, ent->startBlock)) + { + result = CARD_RESULT_BROKEN; + } + else + { + fileInfo->chan = chan; + fileInfo->fileNo = fileNo; + fileInfo->offset = 0; + fileInfo->iBlock = ent->startBlock; + } + } + return __CARDPutControlBlock(card, result); +} + +s32 CARDClose(CARDFileInfo *fileInfo) +{ + CARDControl *card; + s32 result; + + result = __CARDGetControlBlock(fileInfo->chan, &card); + if (result < 0) + { + return result; + } + + fileInfo->chan = -1; + return __CARDPutControlBlock(card, CARD_RESULT_READY); +} + +BOOL __CARDIsOpened(CARDControl *card, s32 fileNo) { return FALSE; } diff --git a/libs/dolphin/card/CARDRdwr.c b/libs/dolphin/card/CARDRdwr.c new file mode 100644 index 000000000..1bf19a08b --- /dev/null +++ b/libs/dolphin/card/CARDRdwr.c @@ -0,0 +1,125 @@ +#include +#include +#include +#include + +#include + +static void BlockReadCallback(s32 chan, s32 result) +{ + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + if (result < 0) + { + goto error; + } + + card->xferred += CARD_SEG_SIZE; + + card->addr += CARD_SEG_SIZE; + (u8*)card->buffer += CARD_SEG_SIZE; + if (--card->repeat <= 0) + { + goto error; + } + + result = __CARDReadSegment(chan, BlockReadCallback); + if (result < 0) + { + goto error; + } + return; + +error: + if (card->apiCallback == 0) + { + __CARDPutControlBlock(card, result); + } + callback = card->xferCallback; + if (callback) + { + card->xferCallback = 0; + callback(chan, result); + } +} + +s32 __CARDRead(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback) +{ + CARDControl* card; + card = &__CARDBlock[chan]; + if (!card->attached) + { + return CARD_RESULT_NOCARD; + } + + card->xferCallback = callback; + card->repeat = (int)(length / CARD_SEG_SIZE); + card->addr = addr; + card->buffer = dst; + + return __CARDReadSegment(chan, BlockReadCallback); +} + +static void BlockWriteCallback(s32 chan, s32 result) +{ + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + if (result < 0) + { + goto error; + } + + card->xferred += CARD_PAGE_SIZE; + + card->addr += CARD_PAGE_SIZE; + (u8*)card->buffer += CARD_PAGE_SIZE; + if (--card->repeat <= 0) + { + goto error; + } + + result = __CARDWritePage(chan, BlockWriteCallback); + if (result < 0) + { + goto error; + } + return; + +error: + if (card->apiCallback == 0) + { + __CARDPutControlBlock(card, result); + } + callback = card->xferCallback; + if (callback) + { + card->xferCallback = 0; + callback(chan, result); + } +} + +s32 __CARDWrite(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback) +{ + CARDControl* card; + card = &__CARDBlock[chan]; + if (!card->attached) + { + return CARD_RESULT_NOCARD; + } + + card->xferCallback = callback; + card->repeat = (int)(length / CARD_PAGE_SIZE); + card->addr = addr; + card->buffer = dst; + + return __CARDWritePage(chan, BlockWriteCallback); +} + +s32 CARDGetXferredBytes(s32 chan) +{ + return __CARDBlock[chan].xferred; +} diff --git a/libs/dolphin/card/CARDRead.c b/libs/dolphin/card/CARDRead.c new file mode 100644 index 000000000..4ec0e21d8 --- /dev/null +++ b/libs/dolphin/card/CARDRead.c @@ -0,0 +1,151 @@ +#include +#include +#include +#include + +#include + +s32 __CARDSeek(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDControl** pcard) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + u16* fat; + + result = __CARDGetControlBlock(fileInfo->chan, &card); + if (result < 0) { + return result; + } + + if (!CARDIsValidBlockNo(card, fileInfo->iBlock) || + card->cBlock * card->sectorSize <= fileInfo->offset) { + return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR); + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileInfo->fileNo]; + if (ent->length * card->sectorSize <= offset || + ent->length * card->sectorSize < offset + length) { + return __CARDPutControlBlock(card, CARD_RESULT_LIMIT); + } + + card->fileInfo = fileInfo; + fileInfo->length = length; + if (offset < fileInfo->offset) { + fileInfo->offset = 0; + fileInfo->iBlock = ent->startBlock; + if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + } + fat = __CARDGetFatBlock(card); + while (fileInfo->offset < TRUNC(offset, card->sectorSize)) { + fileInfo->offset += card->sectorSize; + fileInfo->iBlock = fat[fileInfo->iBlock]; + if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) { + return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); + } + } + + fileInfo->offset = offset; + + *pcard = card; + return CARD_RESULT_READY; +} + +static void ReadCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + u16* fat; + CARDFileInfo* fileInfo; + s32 length; + + card = &__CARDBlock[chan]; + if (result < 0) { + goto error; + } + + fileInfo = card->fileInfo; + if (fileInfo->length < 0) { + result = CARD_RESULT_CANCELED; + goto error; + } + + length = (s32)TRUNC(fileInfo->offset + card->sectorSize, card->sectorSize) - fileInfo->offset; + fileInfo->length -= length; + if (fileInfo->length <= 0) { + goto error; + } + + fat = __CARDGetFatBlock(card); + fileInfo->offset += length; + fileInfo->iBlock = fat[fileInfo->iBlock]; + if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) { + result = CARD_RESULT_BROKEN; + goto error; + } + + result = __CARDRead(chan, card->sectorSize * (u32)fileInfo->iBlock, + (fileInfo->length < card->sectorSize) ? fileInfo->length : card->sectorSize, + card->buffer, ReadCallback); + if (result < 0) { + goto error; + } + + return; + +error: + callback = card->apiCallback; + card->apiCallback = 0; + __CARDPutControlBlock(card, result); + callback(chan, result); +} + +s32 CARDReadAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, + CARDCallback callback) { + CARDControl* card; + s32 result; + CARDDir* dir; + CARDDir* ent; + + if (OFFSET(offset, CARD_SEG_SIZE) != 0 || OFFSET(length, CARD_SEG_SIZE) != 0) { + return CARD_RESULT_FATAL_ERROR; + } + result = __CARDSeek(fileInfo, length, offset, &card); + if (result < 0) { + return result; + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileInfo->fileNo]; + result = __CARDIsReadable(card, ent); + + if (result < 0) + { + return __CARDPutControlBlock(card, result); + } + + DCInvalidateRange(buf, (u32)length); + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + + offset = (s32)OFFSET(fileInfo->offset, card->sectorSize); + length = (length < card->sectorSize - offset) ? length : card->sectorSize - offset; + result = __CARDRead(fileInfo->chan, card->sectorSize * (u32)fileInfo->iBlock + offset, length, + buf, ReadCallback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + return result; +} + +s32 CARDRead(CARDFileInfo *fileInfo, void *buffer, s32 length, s32 offset) +{ + s32 result = CARDReadAsync(fileInfo, buffer, length, offset, __CARDSyncCallback); + + if (result < 0) + { + return result; + } + + return __CARDSync(fileInfo->chan); +} \ No newline at end of file diff --git a/libs/dolphin/card/CARDRename.c b/libs/dolphin/card/CARDRename.c new file mode 100644 index 000000000..65205f062 --- /dev/null +++ b/libs/dolphin/card/CARDRename.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include + +#include + +s32 CARDRenameAsync(s32 chan, const char* old, const char* new, CARDCallback callback) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + int fileNo; + int newNo; + int oldNo; + + if (*old == 0xff || *new == 0xff || *old == 0x00 || *new == 0x00) { + return CARD_RESULT_FATAL_ERROR; + } + if (CARD_FILENAME_MAX < (u32)strlen(old) || CARD_FILENAME_MAX < (u32)strlen(new)) { + return CARD_RESULT_NAMETOOLONG; + } + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + newNo = oldNo = -1; + dir = __CARDGetDirBlock(card); + for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) { + ent = &dir[fileNo]; + if (ent->gameName[0] == 0xff) { + continue; + } + + if (memcmp(ent->gameName, card->diskID->gameName, sizeof(ent->gameName)) != 0 || + memcmp(ent->company, card->diskID->company, sizeof(ent->company)) != 0) { + continue; + } + + if (__CARDCompareFileName(ent, old)) { + oldNo = fileNo; + } + if (__CARDCompareFileName(ent, new)) { + newNo = fileNo; + } + } + + if (oldNo == -1) { + return __CARDPutControlBlock(card, CARD_RESULT_NOFILE); + } + if (newNo != -1) { + return __CARDPutControlBlock(card, CARD_RESULT_EXIST); + } + + ent = &dir[oldNo]; + result = __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; + + result = CARDRenameAsync(chan, old, new, __CARDSyncCallback); + + if (result < 0) + { + return result; + } + return __CARDSync(chan); +} \ No newline at end of file diff --git a/libs/dolphin/card/CARDStat.c b/libs/dolphin/card/CARDStat.c new file mode 100644 index 000000000..cca9c3d3e --- /dev/null +++ b/libs/dolphin/card/CARDStat.c @@ -0,0 +1,152 @@ +#include +#include +#include +#include + +#include + +static void UpdateIconOffsets(CARDDir* ent, CARDStat* stat) { + u32 offset; + BOOL iconTlut; + int i; + + offset = ent->iconAddr; + if (offset == 0xffffffff) { + stat->bannerFormat = 0; + stat->iconFormat = 0; + stat->iconSpeed = 0; + offset = 0; + } + + iconTlut = FALSE; + switch (CARDGetBannerFormat(ent)) { + case CARD_STAT_BANNER_C8: + stat->offsetBanner = offset; + offset += CARD_BANNER_WIDTH * CARD_BANNER_HEIGHT; + stat->offsetBannerTlut = offset; + offset += 2 * 256; + break; + case CARD_STAT_BANNER_RGB5A3: + stat->offsetBanner = offset; + offset += 2 * CARD_BANNER_WIDTH * CARD_BANNER_HEIGHT; + stat->offsetBannerTlut = 0xffffffff; + break; + default: + stat->offsetBanner = 0xffffffff; + stat->offsetBannerTlut = 0xffffffff; + break; + } + for (i = 0; i < CARD_ICON_MAX; ++i) { + switch (CARDGetIconFormat(ent, i)) { + case CARD_STAT_ICON_C8: + stat->offsetIcon[i] = offset; + offset += CARD_ICON_WIDTH * CARD_ICON_HEIGHT; + iconTlut = TRUE; + break; + case CARD_STAT_ICON_RGB5A3: + stat->offsetIcon[i] = offset; + offset += 2 * CARD_ICON_WIDTH * CARD_ICON_HEIGHT; + break; + default: + stat->offsetIcon[i] = 0xffffffff; + break; + } + } + if (iconTlut) { + stat->offsetIconTlut = offset; + offset += 2 * 256; + } else { + stat->offsetIconTlut = 0xffffffff; + } + stat->offsetData = offset; +} + +s32 CARDGetStatus(s32 chan, s32 fileNo, CARDStat* stat) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + + if (fileNo < 0 || CARD_MAX_FILE <= fileNo) { + return CARD_RESULT_FATAL_ERROR; + } + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + result = __CARDIsReadable(card, ent); + + if (result >= 0) { + memcpy(stat->gameName, ent->gameName, sizeof(stat->gameName)); + memcpy(stat->company, ent->company, sizeof(stat->company)); + stat->length = (u32)ent->length * card->sectorSize; + memcpy(stat->fileName, ent->fileName, CARD_FILENAME_MAX); + stat->time = ent->time; + + stat->bannerFormat = ent->bannerFormat; + stat->iconAddr = ent->iconAddr; + stat->iconFormat = ent->iconFormat; + stat->iconSpeed = ent->iconSpeed; + stat->commentAddr = ent->commentAddr; + + UpdateIconOffsets(ent, stat); + } + return __CARDPutControlBlock(card, result); +} + +s32 CARDSetStatusAsync(s32 chan, s32 fileNo, CARDStat* stat, CARDCallback callback) { + CARDControl* card; + CARDDir* dir; + CARDDir* ent; + s32 result; + + if (fileNo < 0 || CARD_MAX_FILE <= fileNo || + (stat->iconAddr != 0xffffffff && CARD_READ_SIZE <= stat->iconAddr) || + (stat->commentAddr != 0xffffffff && + CARD_SYSTEM_BLOCK_SIZE - CARD_COMMENT_SIZE < stat->commentAddr % CARD_SYSTEM_BLOCK_SIZE)) { + return CARD_RESULT_FATAL_ERROR; + } + result = __CARDGetControlBlock(chan, &card); + if (result < 0) { + return result; + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileNo]; + result = __CARDIsWritable(card, ent); + if (result < 0) { + return __CARDPutControlBlock(card, result); + } + + ent->bannerFormat = stat->bannerFormat; + ent->iconAddr = stat->iconAddr; + ent->iconFormat = stat->iconFormat; + ent->iconSpeed = stat->iconSpeed; + ent->commentAddr = stat->commentAddr; + UpdateIconOffsets(ent, stat); + + if (ent->iconAddr == 0xffffffff) { + CARDSetIconSpeed(ent, 0, CARD_STAT_SPEED_FAST); + } + + ent->time = (u32)OSTicksToSeconds(OSGetTime()); + result = __CARDUpdateDir(chan, callback); + if (result < 0) { + __CARDPutControlBlock(card, result); + } + return result; +} + +s32 CARDSetStatus(s32 channel, s32 fileNo, CARDStat *state) +{ + s32 result = CARDSetStatusAsync(channel, fileNo, state, __CARDSyncCallback); + if (result < 0) + { + return result; + } + + return __CARDSync(channel); +} diff --git a/libs/dolphin/card/CARDStatEx.c b/libs/dolphin/card/CARDStatEx.c new file mode 100644 index 000000000..681ab52e3 --- /dev/null +++ b/libs/dolphin/card/CARDStatEx.c @@ -0,0 +1,125 @@ +#include +#include +#include + +s32 __CARDGetStatusEx(s32 chan, s32 fileNo, CARDDir* dirent) +{ + 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; + + 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; +} diff --git a/libs/dolphin/card/CARDUnlock.c b/libs/dolphin/card/CARDUnlock.c new file mode 100644 index 000000000..a2fbb50c7 --- /dev/null +++ b/libs/dolphin/card/CARDUnlock.c @@ -0,0 +1,419 @@ +#include + +static void InitCallback(void* task); +static void DoneCallback(void* task); + +static u8 CardData[] ALIGN(32) = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x02, 0xFF, 0x00, 0x21, + 0x13, 0x06, 0x12, 0x03, 0x12, 0x04, 0x13, 0x05, 0x00, 0x92, 0x00, 0xFF, 0x00, 0x88, 0xFF, 0xFF, + 0x00, 0x89, 0xFF, 0xFF, 0x00, 0x8A, 0xFF, 0xFF, 0x00, 0x8B, 0xFF, 0xFF, 0x8F, 0x00, 0x02, 0xBF, + 0x00, 0x88, 0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x00, 0x16, 0xFB, 0x00, 0x01, 0x02, 0xBF, + 0x00, 0x8E, 0x25, 0xFF, 0x03, 0x80, 0xFF, 0x00, 0x02, 0x94, 0x00, 0x27, 0x02, 0xBF, 0x00, 0x8E, + 0x1F, 0xDF, 0x24, 0xFF, 0x02, 0x40, 0x0F, 0xFF, 0x00, 0x98, 0x04, 0x00, 0x00, 0x9A, 0x00, 0x10, + 0x00, 0x99, 0x00, 0x00, 0x8E, 0x00, 0x02, 0xBF, 0x00, 0x94, 0x02, 0xBF, 0x86, 0x44, 0x02, 0xBF, + 0x00, 0x88, 0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x03, 0x16, 0xFB, 0x00, 0x01, 0x8F, 0x00, + 0x02, 0xBF, 0x00, 0x8E, 0x03, 0x80, 0xCD, 0xD1, 0x02, 0x94, 0x00, 0x48, 0x27, 0xFF, 0x03, 0x80, + 0x00, 0x01, 0x02, 0x95, 0x00, 0x5A, 0x03, 0x80, 0x00, 0x02, 0x02, 0x95, 0x80, 0x00, 0x02, 0x9F, + 0x00, 0x48, 0x00, 0x21, 0x8E, 0x00, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, + 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC5, 0xFF, 0xFF, + 0x03, 0x40, 0x0F, 0xFF, 0x1C, 0x9F, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC7, 0xFF, 0xFF, 0x02, 0xBF, + 0x00, 0x8E, 0x00, 0xC6, 0xFF, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC0, 0xFF, 0xFF, 0x02, 0xBF, + 0x00, 0x8E, 0x20, 0xFF, 0x03, 0x40, 0x0F, 0xFF, 0x1F, 0x5F, 0x02, 0xBF, 0x00, 0x8E, 0x21, 0xFF, + 0x02, 0xBF, 0x00, 0x8E, 0x23, 0xFF, 0x12, 0x05, 0x12, 0x06, 0x02, 0x9F, 0x80, 0xB5, 0x00, 0x21, + 0x27, 0xFC, 0x03, 0xC0, 0x80, 0x00, 0x02, 0x9D, 0x00, 0x88, 0x02, 0xDF, 0x27, 0xFE, 0x03, 0xC0, + 0x80, 0x00, 0x02, 0x9C, 0x00, 0x8E, 0x02, 0xDF, 0x2E, 0xCE, 0x2C, 0xCF, 0x00, 0xF8, 0xFF, 0xCD, + 0x00, 0xF9, 0xFF, 0xC9, 0x00, 0xFA, 0xFF, 0xCB, 0x26, 0xC9, 0x02, 0xC0, 0x00, 0x04, 0x02, 0x9D, + 0x00, 0x9C, 0x02, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +typedef struct DecodeParameters +{ + u8* inputAddr; + u32 inputLength; + u32 aramAddr; + u8* outputAddr; +} DecodeParameters; + +static unsigned long int next = 1; + +static int CARDRand(void) +{ + next = next * 1103515245 + 12345; + return (int)((unsigned int)(next / 65536) % 32768); +} + +static u32 GetInitVal(void) +{ + u32 tmp = 0; + u32 tick; + + tick = OSGetTick(); + next = tmp; + tmp = 0x7fec8000; + tmp |= CARDRand(); + tmp &= 0xfffff000; + return tmp; +} + +static u32 exnor(u32 data, u32 lshift) +{ + u32 wk; + u32 w; + u32 i; + + w = data; + for (i = 0; i < lshift; i++) + { + // 1bit Left Shift + wk = ~(w ^ (w << 7) ^ (w << 15) ^ (w << 23)); + w = (w << 1) | ((wk >> 30) & 0x00000002); + // printf("i=%d, w=%8x\n", i, w); + } + return w; +} + +static u32 bitrev(u32 data) +{ + u32 wk; + u32 i; + u32 k = 0; + u32 j = 1; + + wk = 0; + for (i = 0; i < 32; i++) + { + if (i > 15) + { + if (i == 31) + { + wk |= (((data & (0x01 << 31)) >> 31) & 0x01); + } + else + { + wk |= ((data & (0x01 << i)) >> j); + j += 2; + } + } + else + { + wk |= ((data & (0x01 << i)) << (31 - i - k)); + k++; + } + } + return wk; +} + +#define SEC_AD1(x) ((u8)(((x) >> 29) & 0x03)) +#define SEC_AD2(x) ((u8)(((x) >> 21) & 0xff)) +#define SEC_AD3(x) ((u8)(((x) >> 19) & 0x03)) +#define SEC_BA(x) ((u8)(((x) >> 12) & 0x7f)) + +static s32 ReadArrayUnlock(s32 chan, u32 data, void* rbuf, s32 rlen, s32 mode) +{ + CARDControl* card; + BOOL err; + u8 cmd[5]; + + card = &__CARDBlock[chan]; + if (!EXISelect(chan, 0, 4)) + { + return CARD_RESULT_NOCARD; + } + + data &= 0xfffff000; + memset(cmd, 0, 5); + cmd[0] = 0x52; + if (mode == 0) + { + cmd[1] = SEC_AD1(data); + cmd[2] = SEC_AD2(data); + cmd[3] = SEC_AD3(data); + cmd[4] = SEC_BA(data); + } + else + { + cmd[1] = (u8)((data & 0xff000000) >> 24); + cmd[2] = (u8)((data & 0x00ff0000) >> 16); + } + + err = FALSE; + err |= !EXIImmEx(chan, cmd, 5, 1); + err |= !EXIImmEx(chan, (u8*)card->workArea + (u32)sizeof(CARDID), card->latency, 1); + err |= !EXIImmEx(chan, rbuf, rlen, 0); + err |= !EXIDeselect(chan); + + return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY; +} + +// Calculate Dummy Read Length, 4-32Bytes +static s32 DummyLen(void) +{ + u32 tick; + u32 wk; + s32 tmp; + u32 max; + + wk = 1; + max = 0; + tick = OSGetTick(); + next = tick; + + tmp = CARDRand(); + tmp &= 0x0000001f; + tmp += 1; + while ((tmp < 4) && (max < 10)) + { + tick = OSGetTick(); + tmp = (s32)(tick << wk); + wk++; + if (wk > 16) + { + wk = 1; + } + next = tmp; + tmp = CARDRand(); + tmp &= 0x0000001f; + tmp += 1; + max++; + } + if (tmp < 4) + { + tmp = 4; + } + + return tmp; +} + +s32 __CARDUnlock(s32 chan, u8 flashID[12]) +{ + u32 init_val; + u32 data = 0; + + s32 dummy; + s32 rlen; + u32 rshift; + + u8 fsts; + u32 wk, wk1; + u32 w; + u32 i; + u32 Ans1 = 0; + u32 Ans2 = 0; + u32* dp; + u8 rbuf[64]; + u32 para1A = 0; + u32 para1B = 0; + u32 para2A = 0; + u32 para2B = 0; + + CARDControl* card; + DSPTaskInfo* task; + DecodeParameters* param; + u8* input; + u8* output; + + card = &__CARDBlock[chan]; + task = &card->task; + param = (DecodeParameters*)card->workArea; + input = (u8*)((u8*)param + sizeof(DecodeParameters)); + input = (u8*)OSRoundUp32B(input); + output = input + 32; + + fsts = 0; + init_val = GetInitVal(); + + dummy = DummyLen(); + rlen = dummy; + if (ReadArrayUnlock(chan, init_val, rbuf, rlen, 0) < 0) + { + return CARD_RESULT_NOCARD; + } + + rshift = (u32)(dummy * 8 + 1); + wk = data; + for (i = 0; i < rshift; i++) + { + wk = ~(w ^ (w >> 7) ^ (w >> 15) ^ (w >> 23)); + w = (w >> 1) | ((wk << 30) & 0x40000000); + } + + wk1 = ~(wk ^ (wk >> 7) ^ (wk >> 15) ^ (wk >> 23)); + card->scramble = (wk | ((wk1 << 31) & 0x80000000)); + card->scramble = bitrev(card->scramble); + dummy = DummyLen(); + rlen = 20 + dummy; + data = 0; + if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) + { + return CARD_RESULT_NOCARD; + } + dp = (u32*)rbuf; + para1A = *dp++; + para1B = *dp++; + Ans1 = *dp++; + para2A = *dp++; + para2B = *dp++; + para1A = (para1A ^ card->scramble); + rshift = 32; + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + para1B = (para1B ^ card->scramble); + rshift = 32; + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + Ans1 ^= card->scramble; + rshift = 32; + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + para2A = (para2A ^ card->scramble); + rshift = 32; + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + para2B = (para2B ^ card->scramble); + rshift = (u32)(dummy * 8); + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + rshift = 32 + 1; + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + + *(u32*)&input[0] = para2A; + *(u32*)&input[4] = para2B; + + param->inputAddr = input; + param->inputLength = 8; + param->outputAddr = output; + param->aramAddr = 0; + + DCFlushRange(input, 8); + DCInvalidateRange(output, 4); + DCFlushRange(param, sizeof(DecodeParameters)); + + task->priority = 255; + task->iram_mmem_addr = (u16*)OSPhysicalToCached(CardData); + task->iram_length = 0x160; + task->iram_addr = 0; + task->dsp_init_vector = 0x10; + task->init_cb = InitCallback; + task->res_cb = NULL; + task->done_cb = DoneCallback; + task->req_cb = NULL; + DSPAddTask(task); + + dp = (u32*)flashID; + *dp++ = para1A; + *dp++ = para1B; + *dp = Ans1; + + return CARD_RESULT_READY; +} + +static void InitCallback(void* _task) +{ + s32 chan; + CARDControl* card; + DSPTaskInfo* task; + DecodeParameters* param; + + task = _task; + for (chan = 0; chan < 2; ++chan) + { + card = &__CARDBlock[chan]; + if ((DSPTaskInfo*)&card->task == task) + { + break; + } + } + param = (DecodeParameters*)card->workArea; + + DSPSendMailToDSP(0xff000000); + while (DSPCheckMailToDSP()) + ; + + DSPSendMailToDSP((u32)param); + while (DSPCheckMailToDSP()) + ; +} + +static void DoneCallback(void* _task) +{ + u8 rbuf[64]; + u32 data; + s32 dummy; + s32 rlen; + u32 rshift; + + u8 unk; + u32 wk, wk1; + u32 Ans2; + + s32 chan; + CARDControl* card; + s32 result; + DSPTaskInfo* task; + DecodeParameters* param; + + u8* input; + u8* output; + task = _task; + for (chan = 0; chan < 2; ++chan) + { + card = &__CARDBlock[chan]; + if ((DSPTaskInfo*)&card->task == task) + { + break; + } + } + + param = (DecodeParameters*)card->workArea; + input = (u8*)((u8*)param + sizeof(DecodeParameters)); + input = (u8*)OSRoundUp32B(input); + output = input + 32; + + Ans2 = *(u32*)output; + dummy = DummyLen(); + rlen = dummy; + data = ((Ans2 ^ card->scramble) & 0xffff0000); + if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) + { + EXIUnlock(chan); + __CARDMountCallback(chan, CARD_RESULT_NOCARD); + return; + } + + rshift = (u32)((dummy + 4 + card->latency) * 8 + 1); + wk = exnor(card->scramble, rshift); + wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23)); + card->scramble = (wk | ((wk1 >> 31) & 0x00000001)); + + dummy = DummyLen(); + rlen = dummy; + data = (((Ans2 << 16) ^ card->scramble) & 0xffff0000); + if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) + { + EXIUnlock(chan); + __CARDMountCallback(chan, CARD_RESULT_NOCARD); + return; + } + result = __CARDReadStatus(chan, &unk); + if (!EXIProbe(chan)) + { + EXIUnlock(chan); + __CARDMountCallback(chan, CARD_RESULT_NOCARD); + return; + } + if (result == CARD_RESULT_READY && !(unk & 0x40)) + { + EXIUnlock(chan); + result = CARD_RESULT_IOERROR; + } + __CARDMountCallback(chan, result); +} \ No newline at end of file diff --git a/libs/dolphin/card/CARDWrite.c b/libs/dolphin/card/CARDWrite.c new file mode 100644 index 000000000..a077a9621 --- /dev/null +++ b/libs/dolphin/card/CARDWrite.c @@ -0,0 +1,128 @@ +#include + +static void EraseCallback(s32 chan, s32 result); + +static void WriteCallback(s32 chan, s32 result) +{ + CARDControl* card; + CARDCallback callback; + u16* fat; + CARDDir* dir; + CARDDir* ent; + CARDFileInfo* fileInfo; + + card = &__CARDBlock[chan]; + if (result < 0) + { + goto error; + } + + fileInfo = card->fileInfo; + if (fileInfo->length < 0) + { + result = CARD_RESULT_CANCELED; + goto error; + } + + fileInfo->length -= card->sectorSize; + if (fileInfo->length <= 0) + { + dir = __CARDGetDirBlock(card); + ent = &dir[fileInfo->fileNo]; + ent->time = (u32)OSTicksToSeconds(OSGetTime()); + callback = card->apiCallback; + card->apiCallback = 0; + result = __CARDUpdateDir(chan, callback); + } + else + { + fat = __CARDGetFatBlock(card); + fileInfo->offset += card->sectorSize; + fileInfo->iBlock = fat[fileInfo->iBlock]; + if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) + { + result = CARD_RESULT_BROKEN; + goto error; + } + result = __CARDEraseSector(chan, card->sectorSize * (u32)fileInfo->iBlock, EraseCallback); + } + + if (result < 0) + { + goto error; + } + return; + +error: + callback = card->apiCallback; + card->apiCallback = 0; + __CARDPutControlBlock(card, result); + callback(chan, result); +} + +static void EraseCallback(s32 chan, s32 result) +{ + CARDControl* card; + CARDCallback callback; + CARDFileInfo* fileInfo; + + card = &__CARDBlock[chan]; + if (result < 0) + { + goto error; + } + + fileInfo = card->fileInfo; + result = __CARDWrite(chan, card->sectorSize * (u32)fileInfo->iBlock, card->sectorSize, + card->buffer, WriteCallback); + if (result < 0) + { + goto error; + } + return; + +error: + callback = card->apiCallback; + card->apiCallback = 0; + __CARDPutControlBlock(card, result); + callback(chan, result); +} + +s32 CARDWriteAsync(CARDFileInfo* fileInfo, const void* buf, s32 length, s32 offset, + CARDCallback callback) +{ + CARDControl* card; + s32 result; + CARDDir* dir; + CARDDir* ent; + + result = __CARDSeek(fileInfo, length, offset, &card); + if (result < 0) + { + return result; + } + + if (OFFSET(offset, card->sectorSize) != 0 || OFFSET(length, card->sectorSize) != 0) + { + return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR); + } + + dir = __CARDGetDirBlock(card); + ent = &dir[fileInfo->fileNo]; + result = __CARDIsWritable(card, ent); + if (result < 0) + { + return __CARDPutControlBlock(card, result); + } + + DCStoreRange((void*)buf, (u32)length); + card->apiCallback = callback ? callback : __CARDDefaultApiCallback; + card->buffer = (void*)buf; + result = + __CARDEraseSector(fileInfo->chan, card->sectorSize * (u32)fileInfo->iBlock, EraseCallback); + if (result < 0) + { + __CARDPutControlBlock(card, result); + } + return result; +} diff --git a/libs/dolphin/card/__card.h b/libs/dolphin/card/__card.h new file mode 100644 index 000000000..f4e4de2f0 --- /dev/null +++ b/libs/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/libs/dolphin/db/db.c b/libs/dolphin/db/db.c new file mode 100644 index 000000000..7ce0322f3 --- /dev/null +++ b/libs/dolphin/db/db.c @@ -0,0 +1,46 @@ +#include +#include + +DBInterface *__DBInterface = NULL; +int DBVerbose; + +extern void __DBExceptionStart(); +extern void __DBExceptionEnd(); +extern void __DBExceptionSetNumber(); + +void DBInit(void) +{ + __DBInterface = (DBInterface *)OSPhysicalToCached(OS_DBINTERFACE_ADDR); + __DBInterface->ExceptionDestination = (void (*)())OSCachedToPhysical(__DBExceptionDestination); + DBVerbose = TRUE; +} + +void __DBExceptionDestinationAux(void) +{ + u32 *contextAddr = (void *)0x00C0; + OSContext *context = (OSContext *)OSPhysicalToCached(*contextAddr); + + OSReport("DBExceptionDestination\n"); + OSDumpContext(context); + PPCHalt(); +} + +/* clang-format off */ +asm void __DBExceptionDestination(void) { + nofralloc + mfmsr r3 + ori r3, r3, 0x10|0x20 + mtmsr r3 + + b __DBExceptionDestinationAux +} +/* clang-format on */ + +BOOL __DBIsExceptionMarked(__OSException exception) +{ + u32 mask = 1 << exception; + + return (BOOL)(__DBInterface->exceptionMask & mask); +} + +void DBPrintf(char *format, ...) {} \ No newline at end of file diff --git a/libs/dolphin/dsp/dsp.c b/libs/dolphin/dsp/dsp.c new file mode 100644 index 000000000..7459587bb --- /dev/null +++ b/libs/dolphin/dsp/dsp.c @@ -0,0 +1,115 @@ +#include "dolphin/dsp.h" +#include "dolphin/os.h" + +#include "dolphin/hw_regs.h" + +#ifdef __cplusplus +extern "C" { +#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 17 2003 12:34:16 (0x2301) >>"; +#endif + +static s32 __DSP_init_flag = 0; +extern DSPTaskInfo* __DSP_tmp_task; +extern DSPTaskInfo* __DSP_last_task; +extern DSPTaskInfo* __DSP_first_task; +extern DSPTaskInfo* __DSP_curr_task; + +extern void __DSPHandler(__OSInterrupt, OSContext*); +extern void __DSP_debug_printf(const char* fmt, ...); +extern void __DSP_boot_task(DSPTaskInfo* task); + +u32 DSPCheckMailToDSP(void) +{ + return (__DSPRegs[0] >> 0xF) & 1; +} + +u32 DSPCheckMailFromDSP(void) +{ + return (__DSPRegs[2] >> 0xF) & 1; +} + +u32 DSPReadMailFromDSP() +{ + u16 reg1; + u16 reg2; + reg1 = __DSPRegs[2]; + reg2 = __DSPRegs[3]; + return reg1 << 16 | reg2; +} + +void DSPSendMailToDSP(u32 mail) +{ + __DSPRegs[0] = mail >> 16; + __DSPRegs[1] = mail; +} + +void DSPInit(void) +{ + u32 oldInt; + u16 reg; + __DSP_debug_printf("DSPInit(): Build Date: %s %s\n", "Apr 17 2003", "12:34:16"); + + if (__DSP_init_flag == 1) + { + return; + } + OSRegisterVersion(__DSPVersion); + oldInt = OSDisableInterrupts(); + __OSSetInterruptHandler(7, __DSPHandler); + __OSUnmaskInterrupts(0x1000000); + reg = __DSPRegs[5]; + reg = (reg & ~0xA8) | 0x800; + __DSPRegs[5] = reg; + reg = __DSPRegs[5]; + reg = reg & ~0xAC; + __DSPRegs[5] = reg; + __DSP_tmp_task = 0; + __DSP_curr_task = 0; + __DSP_last_task = 0; + __DSP_first_task = 0; + __DSP_init_flag = 1; + OSRestoreInterrupts(oldInt); +} + +int DSPCheckInit() +{ + return __DSP_init_flag; +} + +// it's possible to override this function but it wasn't done with DECL_WEAK(according to the symbol map) +DECL_WEAK DSPTaskInfo* DSPAddTask(DSPTaskInfo* task) +{ + u32 oldInt; + oldInt = OSDisableInterrupts(); + __DSP_insert_task(task); + task->state = 0; + task->flags = 1; + OSRestoreInterrupts(oldInt); + if (task == __DSP_first_task) + { + __DSP_boot_task(task); + } + + return task; +} + +DSPTaskInfo* DSPCancelTask(DSPTaskInfo* task) +{ + BOOL old; + + old = OSDisableInterrupts(); + + task->flags |= 2; + + OSRestoreInterrupts(old); + return task; +} + +#ifdef __cplusplus +} +#endif diff --git a/libs/dolphin/dsp/dsp_debug.c b/libs/dolphin/dsp/dsp_debug.c new file mode 100644 index 000000000..4559926db --- /dev/null +++ b/libs/dolphin/dsp/dsp_debug.c @@ -0,0 +1,6 @@ +#include "types.h" + +void __DSP_debug_printf(const char *fmt, ...) +{ + // UNUSED(fmt); +} \ No newline at end of file diff --git a/libs/dolphin/dsp/dsp_task.c b/libs/dolphin/dsp/dsp_task.c new file mode 100644 index 000000000..69a54084d --- /dev/null +++ b/libs/dolphin/dsp/dsp_task.c @@ -0,0 +1,426 @@ +#include "dolphin/dsp.h" +#include "dolphin/hw_regs.h" + +DSPTaskInfo* __DSP_curr_task; +DSPTaskInfo* __DSP_first_task; +DSPTaskInfo* __DSP_last_task; +DSPTaskInfo* __DSP_tmp_task; +DSPTaskInfo* __DSP_rude_task; + +BOOL __DSP_rude_task_pending; + +DECL_WEAK void __DSPHandler(__OSInterrupt, OSContext* context) +{ + DSPTaskInfo* tmp_task; + OSContext exceptionContext; + u16 tmp; + u32 mail; + + tmp = __DSPRegs[5]; + tmp = (u16)(tmp & ~0x28) | 0x80; + __DSPRegs[5] = tmp; + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + while (!DSPCheckMailFromDSP()) + ; + mail = DSPReadMailFromDSP(); + + if ((__DSP_curr_task->flags & DSP_TASK_FLAG_CANCEL) && (mail == 0xDCD10002)) + { + mail = 0xDCD10003; + } + + switch (mail) + { + case 0xDCD10000: + __DSP_curr_task->state = DSP_TASK_STATE_RUN; + + if (__DSP_curr_task->init_cb) + { + (*(__DSP_curr_task->init_cb))((void*)(__DSP_curr_task)); + } + break; + case 0xDCD10001: + __DSP_curr_task->state = DSP_TASK_STATE_RUN; + if (__DSP_curr_task->res_cb) + { + (*(__DSP_curr_task->res_cb))((void*)(__DSP_curr_task)); + } + break; + case 0xDCD10002: + if (__DSP_rude_task_pending) + { + if (__DSP_curr_task == __DSP_rude_task) + { + DSPSendMailToDSP(0xCDD10003); + while (DSPCheckMailToDSP()) + { + } + + __DSP_rude_task = NULL; + __DSP_rude_task_pending = FALSE; + + if (__DSP_curr_task->res_cb) + { + (*(__DSP_curr_task->res_cb))((void*)(__DSP_curr_task)); + } + + break; + } + else + { + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP()) + ; + __DSP_exec_task(__DSP_curr_task, __DSP_rude_task); + + __DSP_curr_task->state = DSP_TASK_STATE_YIELD; + __DSP_curr_task = __DSP_rude_task; + + __DSP_rude_task = NULL; + __DSP_rude_task_pending = FALSE; + + break; + } + } + + if (__DSP_curr_task->next == NULL) + { + if (__DSP_curr_task == __DSP_first_task) + { + DSPSendMailToDSP(0xCDD10003); + while (DSPCheckMailToDSP()) + ; + + if (__DSP_curr_task->res_cb) + { + (*(__DSP_curr_task->res_cb))((void*)(__DSP_curr_task)); + } + } + else + { + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP()) + { + } + + __DSP_exec_task(__DSP_curr_task, __DSP_first_task); + + __DSP_curr_task->state = DSP_TASK_STATE_YIELD; + __DSP_curr_task = __DSP_first_task; + } + } + else + { + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP()) + { + } + + __DSP_exec_task(__DSP_curr_task, __DSP_curr_task->next); + + __DSP_curr_task->state = DSP_TASK_STATE_YIELD; + __DSP_curr_task = __DSP_curr_task->next; + } + break; + case 0xDCD10003: + if (__DSP_rude_task_pending) + { + if (__DSP_curr_task->done_cb) + { + (*(__DSP_curr_task->done_cb))((void*)(__DSP_curr_task)); + } + + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP()) + ; + + __DSP_exec_task(NULL, __DSP_rude_task); + + __DSP_remove_task(__DSP_curr_task); + __DSP_curr_task = __DSP_rude_task; + + __DSP_rude_task = NULL; + __DSP_rude_task_pending = FALSE; + + break; + } + + if (__DSP_curr_task->next == NULL) + { + if (__DSP_curr_task == __DSP_first_task) + { + if (__DSP_curr_task->done_cb) + { + (*(__DSP_curr_task->done_cb))((void*)(__DSP_curr_task)); + } + + DSPSendMailToDSP(0xCDD10002); + while (DSPCheckMailToDSP()) + ; + + __DSP_curr_task->state = DSP_TASK_STATE_DONE; + + __DSP_remove_task(__DSP_curr_task); + } + else + { + if (__DSP_curr_task->done_cb) + { + (*(__DSP_curr_task->done_cb))((void*)(__DSP_curr_task)); + } + + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP()) + ; + + __DSP_curr_task->state = DSP_TASK_STATE_DONE; + __DSP_exec_task(NULL, __DSP_first_task); + + __DSP_curr_task = __DSP_first_task; + __DSP_remove_task(__DSP_last_task); + } + } + else + { + if (__DSP_curr_task->done_cb) + { + (*(__DSP_curr_task->done_cb))((void*)(__DSP_curr_task)); + } + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP()) + ; + + __DSP_curr_task->state = DSP_TASK_STATE_DONE; + __DSP_exec_task(NULL, __DSP_curr_task->next); + + __DSP_curr_task = __DSP_curr_task->next; + __DSP_remove_task(__DSP_curr_task->prev); + } + break; + + case 0xDCD10004: + + if (__DSP_curr_task->req_cb) + { + (*(__DSP_curr_task->req_cb))((void*)(__DSP_curr_task)); + } + break; + default: + break; + } + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +void __DSP_exec_task(DSPTaskInfo* curr, DSPTaskInfo* next) +{ + if (curr) + { + DSPSendMailToDSP((u32)(curr->dram_mmem_addr)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(curr->dram_length)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(curr->dram_addr)); + while (DSPCheckMailToDSP()) + ; + } + else + { + DSPSendMailToDSP((u32)(0)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(0)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(0)); + while (DSPCheckMailToDSP()) + ; + } + + DSPSendMailToDSP((u32)(next->iram_mmem_addr)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(next->iram_length)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(next->iram_addr)); + while (DSPCheckMailToDSP()) + ; + + if (DSP_TASK_STATE_INIT == next->state) + { + DSPSendMailToDSP((u32)(next->dsp_init_vector)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(0)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(0)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(0)); + while (DSPCheckMailToDSP()) + ; + } + else + { + DSPSendMailToDSP((u32)(next->dsp_resume_vector)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(next->dram_mmem_addr)); + while (DSPCheckMailToDSP()) + ; + + DSPSendMailToDSP((u32)(next->dram_length)); + while (DSPCheckMailToDSP()) + ; + + DSPSendMailToDSP((u32)(next->dram_addr)); + while (DSPCheckMailToDSP()) + ; + } +} + +#define MSG_BASE 0x80F30000 +void __DSP_boot_task(DSPTaskInfo* task) +{ + volatile u32 mail; + + while (!DSPCheckMailFromDSP()) + ; + + mail = DSPReadMailFromDSP(); + + DSPSendMailToDSP(MSG_BASE | 0xA001); + while (DSPCheckMailToDSP()) + { + } + DSPSendMailToDSP((u32)(task->iram_mmem_addr)); + while (DSPCheckMailToDSP()) + { + } + + DSPSendMailToDSP(MSG_BASE | 0xC002); + while (DSPCheckMailToDSP()) + { + } + DSPSendMailToDSP((u32)(task->iram_addr & 0xffff)); + while (DSPCheckMailToDSP()) + { + } + + DSPSendMailToDSP(MSG_BASE | 0xA002); + while (DSPCheckMailToDSP()) + { + } + DSPSendMailToDSP(task->iram_length); + while (DSPCheckMailToDSP()) + { + } + + DSPSendMailToDSP(MSG_BASE | 0xB002); + while (DSPCheckMailToDSP()) + { + } + DSPSendMailToDSP(0x00000000); + while (DSPCheckMailToDSP()) + { + } + + DSPSendMailToDSP(MSG_BASE | 0xD001); + while (DSPCheckMailToDSP()) + { + } + DSPSendMailToDSP((u32)(0xffff & task->dsp_init_vector)); + while (DSPCheckMailToDSP()) + { + } + + __DSP_debug_printf("DSP is booting task: 0x%08X\n", task); + __DSP_debug_printf("__DSP_boot_task() : IRAM MMEM ADDR: 0x%08X\n", + (u32)(task->iram_mmem_addr)); + __DSP_debug_printf("__DSP_boot_task() : IRAM DSP ADDR : 0x%08X\n", (u32)(task->iram_addr)); + __DSP_debug_printf("__DSP_boot_task() : IRAM LENGTH : 0x%08X\n", (u32)(task->iram_length)); + __DSP_debug_printf("__DSP_boot_task() : DRAM MMEM ADDR: 0x%08X\n", (u32)(task->dram_length)); + __DSP_debug_printf("__DSP_boot_task() : Start Vector : 0x%08X\n", + (u32)(task->dsp_init_vector)); +} + +void __DSP_insert_task(DSPTaskInfo* task) +{ + DSPTaskInfo* temp; + + if (__DSP_first_task == NULL) + { + __DSP_first_task = __DSP_last_task = __DSP_curr_task = task; + task->next = task->prev = NULL; + } + else + { + temp = __DSP_first_task; + + while (temp) + { + if (task->priority < temp->priority) + { + task->prev = temp->prev; + temp->prev = task; + task->next = temp; + if (task->prev == NULL) + { + __DSP_first_task = task; + } + else + { + (task->prev)->next = task; + } + break; + } + temp = temp->next; + } + + if (temp == NULL) + { + __DSP_last_task->next = task; + task->next = NULL; + task->prev = __DSP_last_task; + __DSP_last_task = task; + } + } +} + +void __DSP_remove_task(DSPTaskInfo* task) +{ + task->flags = DSP_TASK_FLAG_CLEARALL; + task->state = DSP_TASK_STATE_DONE; + + if (__DSP_first_task == task) + { + if (task->next) + { + __DSP_first_task = (task->next); + task->next->prev = NULL; + } + else + { + __DSP_first_task = __DSP_last_task = __DSP_curr_task = NULL; + } + } + else if (__DSP_last_task == task) + { + __DSP_last_task = (task->prev); + task->prev->next = NULL; + __DSP_curr_task = __DSP_first_task; + } + else + { + __DSP_curr_task = task->next; + task->prev->next = task->next; + task->next->prev = task->prev; + } +} \ No newline at end of file diff --git a/libs/dolphin/dvd/dvd.c b/libs/dolphin/dvd/dvd.c new file mode 100644 index 000000000..30b70e61e --- /dev/null +++ b/libs/dolphin/dvd/dvd.c @@ -0,0 +1,1664 @@ +#include +#include +#include +#include +#include + +const char* __DVDVersion = "<< Dolphin SDK - DVD\trelease build: Jul 23 2003 11:27:57 (0x2301) >>"; +// need to be "<< Dolphin SDK - DSP\trelease build: Apr 17 2003 12:34:16 (0x2301) >>" + +typedef void (*stateFunc)(DVDCommandBlock* block); +stateFunc LastState; + +static DVDBB2 BB2 ALIGN(32); +static DVDDiskID CurrDiskID ALIGN(32); +static DVDCommandBlock* executing; +static DVDDiskID* IDShouldBe; +static OSBootInfo* bootInfo; +static BOOL autoInvalidation = TRUE; +static volatile BOOL PauseFlag = FALSE; +static volatile BOOL PausingFlag = FALSE; +static volatile BOOL AutoFinishing = FALSE; +static volatile BOOL FatalErrorFlag = FALSE; +static vu32 CurrCommand; +static vu32 Canceling = FALSE; +static DVDCBCallback CancelCallback; +static vu32 ResumeFromHere = 0; +static vu32 CancelLastError; +static vu32 LastError; +static vs32 NumInternalRetry = 0; +static volatile BOOL ResetRequired; +static volatile BOOL CancelAllSyncComplete = FALSE; +static volatile BOOL FirstTimeInBootrom = FALSE; + +static DVDCommandBlock DummyCommandBlock; +static OSAlarm ResetAlarm; + +static BOOL DVDInitialized = FALSE; + +/* States */ +static void stateReadingFST(); +static void stateTimeout(); +static void stateGettingError(); +static void stateGoToRetry(); +static void stateCheckID(); +static void stateCheckID3(); +static void stateCheckID2a(); +static void stateCheckID2(); +static void stateCoverClosed(); +static void stateCoverClosed_CMD(); +static void stateCoverOpen(); +static void stateMotorStopped(); +static void stateReady(); +static void stateBusy(); + +/* Callbacks */ +static void cbForStateReadingFST(u32 intType); +static void cbForStateError(u32 intType); +static void cbForStateGettingError(u32 intType); +static void cbForUnrecoveredError(u32 intType); +static void cbForUnrecoveredErrorRetry(u32 intType); +static void cbForStateGoToRetry(u32 intType); +static void cbForStateCheckID2a(u32 intType); +static void cbForStateCheckID1(u32 intType); +static void cbForStateCheckID2(u32 intType); +static void cbForStateCheckID3(u32 intType); +static void cbForStateCoverClosed(u32 intType); +static void cbForStateMotorStopped(u32 intType); +static void cbForStateBusy(u32 intType); +static void cbForCancelStreamSync(s32 result, DVDCommandBlock* block); +static void cbForCancelSync(s32 result, DVDCommandBlock* block); +static void cbForCancelAllSync(s32 result, DVDCommandBlock* block); + +static void defaultOptionalCommandChecker(DVDCommandBlock* block, DVDLowCallback cb); + +static DVDOptionalCommandChecker checkOptionalCommand = defaultOptionalCommandChecker; + +static void defaultOptionalCommandChecker(DVDCommandBlock* block, DVDLowCallback cb) +{ +} + +void DVDInit() +{ + if (DVDInitialized) + { + return; + } + + OSRegisterVersion(__DVDVersion); + DVDInitialized = TRUE; + __DVDFSInit(); + __DVDClearWaitingQueue(); + __DVDInitWA(); + bootInfo = (OSBootInfo*)OSPhysicalToCached(0x0000); + IDShouldBe = &(bootInfo->DVDDiskID); + __OSSetInterruptHandler(21, __DVDInterruptHandler); + __OSUnmaskInterrupts(0x400); + OSInitThreadQueue(&__DVDThreadQueue); + __DIRegs[0] = 0x2a; + __DIRegs[1] = 0; + if (bootInfo->magic == 0xE5207C22) + { + OSReport("load fst\n"); + __fstLoad(); + } + else if (bootInfo->magic != 0xD15EA5E) + { + FirstTimeInBootrom = TRUE; + } +} + +static void stateReadingFST() +{ + LastState = (stateFunc)stateReadingFST; + + if (bootInfo->FSTMaxLength < BB2.FSTLength) + { +#line 650 + OSHalt("DVDChangeDisk(): FST in the new disc is too big. "); + } + + DVDLowRead(bootInfo->FSTLocation, OSRoundUp32B(BB2.FSTLength), BB2.FSTPosition, + cbForStateReadingFST); +} + +static void cbForStateReadingFST(u32 intType) +{ + DVDCommandBlock* finished; + + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if (intType & 1) + { + NumInternalRetry = 0; + __DVDFSInit(); + finished = executing; + executing = &DummyCommandBlock; + finished->state = 0; + if (finished->callback) + { + (finished->callback)(0, finished); + } + + stateReady(); + } + else + { + stateGettingError(); + } +} + +inline static void stateError(u32 error) +{ + __DVDStoreErrorCode(error); + DVDLowStopMotor(cbForStateError); +} + +static void cbForStateError(u32 intType) +{ + DVDCommandBlock* finished; + + if (intType == 16) + { + executing->state = -1; + 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(); + + return; +} + +static void stateTimeout() +{ + __DVDStoreErrorCode(0x1234568); + DVDReset(); + cbForStateError(0); +} + +static void stateGettingError() +{ + DVDLowRequestError(cbForStateGettingError); +} + +static u32 CategorizeError(u32 error) +{ + if (error == 0x20400) + { + LastError = error; + return 1; + } + + error &= 0xffffff; + + if ((error == 0x62800) || (error == 0x23a00) || (error == 0xb5a01)) + { + return 0; + } + + ++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; + } + } +} + +inline static BOOL CheckCancel(u32 resume) +{ + DVDCommandBlock* finished; + + if (Canceling) + { + ResumeFromHere = resume; + Canceling = FALSE; + + finished = executing; + executing = &DummyCommandBlock; + + finished->state = 10; + if (finished->callback) + (*finished->callback)(-3, finished); + if (CancelCallback) + (CancelCallback)(0, finished); + stateReady(); + return TRUE; + } + return FALSE; +} + +static void cbForStateGettingError(u32 intType) +{ + u32 error; + u32 status; + u32 errorCategory; + u32 resume; + + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if (intType & 2) + { + executing->state = -1; + stateError(0x1234567); + return; + } + + error = __DIRegs[8]; + status = error & 0xff000000; + + errorCategory = CategorizeError(error); + + if (errorCategory == 1) + { + executing->state = -1; + stateError(error); + 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 (CheckCancel(resume)) + return; + + if (errorCategory == 2) + { + __DVDStoreErrorCode(error); + stateGoToRetry(); + 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 + { + executing->state = -1; + stateError(0x1234567); + return; + } +} + +static void cbForUnrecoveredError(u32 intType) +{ + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if (intType & 1) + { + stateGoToRetry(); + return; + } + + DVDLowRequestError(cbForUnrecoveredErrorRetry); +} + +static void cbForUnrecoveredErrorRetry(u32 intType) +{ + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + executing->state = -1; + + if (intType & 2) + { + __DVDStoreErrorCode(0x1234567); + DVDLowStopMotor(cbForStateError); + return; + } + + __DVDStoreErrorCode(__DIRegs[8]); + DVDLowStopMotor(cbForStateError); +} + +static void stateGoToRetry() +{ + DVDLowStopMotor(cbForStateGoToRetry); +} + +static void cbForStateGoToRetry(u32 intType) +{ + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if (intType & 2) + { + executing->state = -1; + stateError(0x1234567); + return; + } + + NumInternalRetry = 0; + + if ((CurrCommand == 4) || (CurrCommand == 5) || (CurrCommand == 13) || (CurrCommand == 15)) + { + ResetRequired = TRUE; + } + + if (!CheckCancel(2)) + { + executing->state = 11; + stateMotorStopped(); + } +} + +static void stateCheckID() +{ + switch (CurrCommand) + { + case 3: + if (DVDCompareDiskID(&CurrDiskID, executing->id)) + { + memcpy(IDShouldBe, &CurrDiskID, sizeof(DVDDiskID)); + + executing->state = 1; + DCInvalidateRange(&BB2, sizeof(DVDBB2)); + LastState = stateCheckID2a; + stateCheckID2a(executing); + return; + } + else + { + DVDLowStopMotor(cbForStateCheckID1); + } + break; + + default: + if (memcmp(&CurrDiskID, IDShouldBe, sizeof(DVDDiskID))) + { + DVDLowStopMotor(cbForStateCheckID1); + } + else + { + LastState = stateCheckID3; + stateCheckID3(executing); + } + break; + } +} + +static void stateCheckID3() +{ + DVDLowAudioBufferConfig(IDShouldBe->streaming, 10, cbForStateCheckID3); +} + +static void stateCheckID2a() +{ + DVDLowAudioBufferConfig(IDShouldBe->streaming, 10, cbForStateCheckID2a); +} + +static void cbForStateCheckID2a(u32 intType) +{ + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if (intType & 1) + { + NumInternalRetry = 0; + stateCheckID2(executing); + return; + } + + DVDLowRequestError(cbForStateGettingError); +} + +static void stateCheckID2() +{ + DVDLowRead(&BB2, OSRoundUp32B(sizeof(BB2)), 0x420, cbForStateCheckID2); +} + +static void cbForStateCheckID1(u32 intType) +{ + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if (intType & 2) + { + executing->state = -1; + stateError(0x1234567); + return; + } + + NumInternalRetry = 0; + + if (!CheckCancel(1)) + { + executing->state = 6; + stateMotorStopped(); + } +} + +static void cbForStateCheckID2(u32 intType) +{ + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if (intType & 1) + { + NumInternalRetry = 0; + + stateReadingFST(); + } + else + { + stateGettingError(); + } +} + +static void cbForStateCheckID3(u32 intType) +{ + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if (intType & 1) + { + NumInternalRetry = 0; + + if (!CheckCancel(0)) + { + executing->state = 1; + stateBusy(executing); + } + } + else + { + stateGettingError(); + } +} + +static void AlarmHandler(OSAlarm* alarm, OSContext* context) +{ + DVDReset(); + DCInvalidateRange(&CurrDiskID, sizeof(DVDDiskID)); + LastState = stateCoverClosed_CMD; + stateCoverClosed_CMD(executing); +} + +static void stateCoverClosed() +{ + DVDCommandBlock* finished; + + switch (CurrCommand) + { + case 5: + case 4: + case 13: + case 15: + __DVDClearWaitingQueue(); + finished = executing; + executing = &DummyCommandBlock; + if (finished->callback) + { + (finished->callback)(-4, finished); + } + stateReady(); + break; + + default: + DVDReset(); + OSCreateAlarm(&ResetAlarm); + OSSetAlarm(&ResetAlarm, OSMillisecondsToTicks(1150), AlarmHandler); + break; + } +} + +static void stateCoverClosed_CMD(DVDCommandBlock* block) +{ + DVDLowReadDiskID(&CurrDiskID, cbForStateCoverClosed); +} + +static void cbForStateCoverClosed(u32 intType) +{ + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if (intType & 1) + { + NumInternalRetry = 0; + stateCheckID(); + } + else + { + stateGettingError(); + } +} + +static void stateMotorStopped(void) +{ + DVDLowWaitCoverClose(cbForStateMotorStopped); +} + +static void cbForStateMotorStopped(u32 intType) +{ + __DIRegs[1] = 0; + executing->state = 3; + stateCoverClosed(); +} + +static void stateReady() +{ + DVDCommandBlock* finished; + + if (!__DVDCheckWaitingQueue()) + { + executing = (DVDCommandBlock*)NULL; + return; + } + + if (PauseFlag) + { + PausingFlag = TRUE; + executing = (DVDCommandBlock*)NULL; + return; + } + + executing = __DVDPopWaitingQueue(); + + if (FatalErrorFlag) + { + executing->state = -1; + finished = executing; + executing = &DummyCommandBlock; + if (finished->callback) + { + (finished->callback)(-1, finished); + } + stateReady(); + return; + } + + CurrCommand = executing->command; + + if (ResumeFromHere) + { + switch (ResumeFromHere) + { + case 2: + executing->state = 11; + stateMotorStopped(); + break; + case 3: + executing->state = 4; + stateMotorStopped(); + break; + + case 4: + executing->state = 5; + stateMotorStopped(); + break; + case 1: + case 7: + case 6: + executing->state = 3; + stateCoverClosed(); + break; + + case 5: + executing->state = -1; + stateError(CancelLastError); + break; + } + + ResumeFromHere = 0; + } + else + { + executing->state = 1; + stateBusy(executing); + } +} + +static void stateBusy(DVDCommandBlock* block) +{ + DVDCommandBlock* finished; + LastState = stateBusy; + switch (block->command) + { + case 5: + __DIRegs[1] = __DIRegs[1]; + block->currTransferSize = sizeof(DVDDiskID); + DVDLowReadDiskID(block->addr, cbForStateBusy); + break; + case 1: + case 4: + if (!block->length) + { + finished = executing; + executing = &DummyCommandBlock; + finished->state = 0; + if (finished->callback) + { + finished->callback(0, finished); + } + stateReady(); + } + else + { + __DIRegs[1] = __DIRegs[1]; + block->currTransferSize = block->length - block->transferredSize > 0x80000 ? + 0x80000 : + block->length - block->transferredSize; + DVDLowRead((void*)((u8*)block->addr + block->transferredSize), block->currTransferSize, + block->offset + block->transferredSize, cbForStateBusy); + } + break; + case 2: + __DIRegs[1] = __DIRegs[1]; + DVDLowSeek(block->offset, cbForStateBusy); + break; + case 3: + DVDLowStopMotor(cbForStateBusy); + break; + case 15: + DVDLowStopMotor(cbForStateBusy); + break; + case 6: + __DIRegs[1] = __DIRegs[1]; + if (AutoFinishing) + { + executing->currTransferSize = 0; + DVDLowRequestAudioStatus(0, cbForStateBusy); + } + else + { + executing->currTransferSize = 1; + DVDLowAudioStream(0, block->length, block->offset, cbForStateBusy); + } + break; + case 7: + __DIRegs[1] = __DIRegs[1]; + DVDLowAudioStream(0x10000, 0, 0, cbForStateBusy); + break; + case 8: + __DIRegs[1] = __DIRegs[1]; + AutoFinishing = TRUE; + DVDLowAudioStream(0, 0, 0, cbForStateBusy); + break; + case 9: + __DIRegs[1] = __DIRegs[1]; + DVDLowRequestAudioStatus(0, cbForStateBusy); + break; + case 10: + __DIRegs[1] = __DIRegs[1]; + DVDLowRequestAudioStatus(0x10000, cbForStateBusy); + break; + case 11: + __DIRegs[1] = __DIRegs[1]; + DVDLowRequestAudioStatus(0x20000, cbForStateBusy); + break; + case 12: + __DIRegs[1] = __DIRegs[1]; + DVDLowRequestAudioStatus(0x30000, cbForStateBusy); + break; + case 13: + __DIRegs[1] = __DIRegs[1]; + DVDLowAudioBufferConfig(block->offset, block->length, cbForStateBusy); + break; + case 14: + __DIRegs[1] = __DIRegs[1]; + block->currTransferSize = sizeof(DVDDriveInfo); + DVDLowInquiry(block->addr, cbForStateBusy); + break; + default: + checkOptionalCommand(block, cbForStateBusy); + break; + } +} + +static u32 ImmCommand[] = { 0xffffffff, 0xffffffff, 0xffffffff }; +/* Somehow this got included even though the function is stripped? O.o */ +static char string_DVDChangeDiskAsyncMsg[] = + "DVDChangeDiskAsync(): You can't specify NULL to company name. \n"; +static u32 DmaCommand[] = { 0xffffffff }; + +inline static BOOL IsImmCommandWithResult(u32 command) +{ + u32 i; + + if (command == 9 || command == 10 || command == 11 || command == 12) + { + return TRUE; + } + + for (i = 0; i < sizeof(ImmCommand) / sizeof(ImmCommand[0]); i++) + { + if (command == ImmCommand[i]) + return TRUE; + } + + return FALSE; +} + +inline static BOOL IsDmaCommand(u32 command) +{ + u32 i; + + if (command == 1 || command == 4 || command == 5 || command == 14) + return TRUE; + + for (i = 0; i < sizeof(DmaCommand) / sizeof(DmaCommand[0]); i++) + { + if (command == DmaCommand[i]) + return TRUE; + } + + return FALSE; +} + +static void cbForStateBusy(u32 intType) +{ + DVDCommandBlock* finished; + + if (intType == 16) + { + executing->state = -1; + stateTimeout(); + return; + } + + if ((CurrCommand == 3) || (CurrCommand == 15)) + { + if (intType & 2) + { + executing->state = -1; + stateError(0x1234567); + return; + } + + NumInternalRetry = 0; + + if (CurrCommand == 15) + { + ResetRequired = TRUE; + } + + if (CheckCancel(7)) + { + return; + } + + executing->state = 7; + stateMotorStopped(); + return; + } + + if (IsDmaCommand(CurrCommand)) + { + executing->transferredSize += executing->currTransferSize - __DIRegs[6]; + } + + if (intType & 8) + { + Canceling = FALSE; + finished = executing; + executing = &DummyCommandBlock; + + finished->state = 10; + if (finished->callback) + (*finished->callback)(-3, finished); + if (CancelCallback) + (CancelCallback)(0, finished); + stateReady(); + + return; + } + + if (intType & 1) + { + NumInternalRetry = 0; + + if (CheckCancel(0)) + return; + + if (IsDmaCommand(CurrCommand)) + { + if (executing->transferredSize != executing->length) + { + stateBusy(executing); + return; + } + + finished = executing; + executing = &DummyCommandBlock; + + finished->state = 0; + if (finished->callback) + { + (finished->callback)((s32)finished->transferredSize, finished); + } + stateReady(); + } + else if (IsImmCommandWithResult(CurrCommand)) + { + s32 result; + + if ((CurrCommand == 11) || (CurrCommand == 10)) + { + result = (s32)(__DIRegs[8] << 2); + } + else + { + result = (s32)__DIRegs[8]; + } + finished = executing; + executing = &DummyCommandBlock; + + finished->state = 0; + if (finished->callback) + { + (finished->callback)(result, finished); + } + stateReady(); + } + else if (CurrCommand == 6) + { + if (executing->currTransferSize == 0) + { + if (__DIRegs[8] & 1) + { + finished = executing; + executing = &DummyCommandBlock; + + finished->state = 9; + if (finished->callback) + { + (finished->callback)(-2, finished); + } + stateReady(); + } + else + { + AutoFinishing = FALSE; + executing->currTransferSize = 1; + DVDLowAudioStream(0, executing->length, executing->offset, cbForStateBusy); + } + } + else + { + finished = executing; + executing = &DummyCommandBlock; + + finished->state = 0; + if (finished->callback) + { + (finished->callback)(0, finished); + } + stateReady(); + } + } + else + { + finished = executing; + executing = &DummyCommandBlock; + + finished->state = 0; + if (finished->callback) + { + (finished->callback)(0, finished); + } + stateReady(); + } + } + else + { + if (CurrCommand == 14) + { + executing->state = -1; + stateError(0x01234567); + return; + } + + if ((CurrCommand == 1 || CurrCommand == 4 || CurrCommand == 5 || CurrCommand == 14) && + (executing->transferredSize == executing->length)) + { + if (CheckCancel(0)) + { + return; + } + finished = executing; + executing = &DummyCommandBlock; + + finished->state = 0; + if (finished->callback) + { + (finished->callback)((s32)finished->transferredSize, finished); + } + stateReady(); + return; + } + + stateGettingError(); + } +} + +static BOOL issueCommand(s32 prio, DVDCommandBlock* block) +{ + BOOL level; + BOOL result; + + if (autoInvalidation && + (block->command == 1 || block->command == 4 || block->command == 5 || block->command == 14)) + { + DCInvalidateRange(block->addr, block->length); + } + + level = OSDisableInterrupts(); + + block->state = 2; + result = __DVDPushWaitingQueue(prio, block); + + if ((executing == (DVDCommandBlock*)NULL) && (PauseFlag == FALSE)) + { + stateReady(); + } + + OSRestoreInterrupts(level); + + return result; +} + +BOOL DVDReadAbsAsyncPrio(DVDCommandBlock* block, void* addr, s32 length, s32 offset, + DVDCBCallback callback, s32 prio) +{ + BOOL idle; + block->command = 1; + block->addr = addr; + block->length = length; + block->offset = offset; + block->transferredSize = 0; + block->callback = callback; + + idle = issueCommand(prio, block); + return idle; +} + +BOOL DVDReadAbsAsyncForBS(DVDCommandBlock* block, void* addr, s32 length, s32 offset, + DVDCBCallback callback) +{ + BOOL idle; + block->command = 4; + block->addr = addr; + block->length = length; + block->offset = offset; + block->transferredSize = 0; + block->callback = callback; + + idle = issueCommand(2, block); + return idle; +} + +BOOL DVDReadDiskID(DVDCommandBlock* block, DVDDiskID* diskID, DVDCBCallback callback) +{ + BOOL idle; + block->command = 5; + block->addr = diskID; + block->length = sizeof(DVDDiskID); + ; + block->offset = 0; + block->transferredSize = 0; + block->callback = callback; + + idle = issueCommand(2, block); + return idle; +} + +BOOL DVDPrepareStreamAbsAsync(DVDCommandBlock* block, u32 length, u32 offset, + DVDCBCallback callback) +{ + BOOL idle; + block->command = 6; + block->length = length; + block->offset = offset; + block->callback = callback; + + idle = issueCommand(1, block); + return idle; +} + +BOOL DVDCancelStreamAsync(DVDCommandBlock* block, DVDCBCallback callback) +{ + BOOL idle; + block->command = 7; + block->callback = callback; + idle = issueCommand(1, block); + return idle; +} + +s32 DVDCancelStream(DVDCommandBlock* block) +{ + BOOL result; + s32 state; + BOOL enabled; + s32 retVal; + + result = DVDCancelStreamAsync(block, cbForCancelStreamSync); + + if (result == FALSE) + { + return -1; + } + + enabled = OSDisableInterrupts(); + + while (TRUE) + { + state = ((volatile DVDCommandBlock*)block)->state; + + if (state == 0 || state == -1 || state == 10) + { + retVal = (s32)block->transferredSize; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} +static void cbForCancelStreamSync(s32 result, DVDCommandBlock* block) +{ + block->transferredSize = (u32)result; + OSWakeupThread(&__DVDThreadQueue); +} +BOOL DVDStopStreamAtEndAsync(DVDCommandBlock* block, DVDCBCallback callback) +{ + BOOL idle; + + block->command = 8; + block->callback = callback; + + idle = issueCommand(1, block); + + return idle; +} +BOOL DVDGetStreamErrorStatusAsync(DVDCommandBlock* block, DVDCBCallback callback) +{ + BOOL idle; + + block->command = 9; + block->callback = callback; + + idle = issueCommand(1, block); + + return idle; +} +BOOL DVDGetStreamPlayAddrAsync(DVDCommandBlock* block, DVDCBCallback callback) +{ + BOOL idle; + + block->command = 10; + block->callback = callback; + + idle = issueCommand(1, block); + + return idle; +} +BOOL DVDInquiryAsync(DVDCommandBlock* block, DVDDriveInfo* info, DVDCBCallback callback) +{ + BOOL idle; + + block->command = 14; + block->addr = (void*)info; + block->length = sizeof(DVDDriveInfo); + block->transferredSize = 0; + block->callback = callback; + + idle = issueCommand(2, block); + + return idle; +} + +void DVDReset(void) +{ + DVDLowReset(); + __DIRegs[0] = 0x2a; + __DIRegs[1] = __DIRegs[1]; + ResetRequired = FALSE; + ResumeFromHere = 0; +} + +s32 DVDGetCommandBlockStatus(const DVDCommandBlock* block) +{ + BOOL enabled; + s32 retVal; + + enabled = OSDisableInterrupts(); + + if (block->state == 3) + { + retVal = 1; + } + else + { + retVal = block->state; + } + + OSRestoreInterrupts(enabled); + + return retVal; +} + +s32 DVDGetDriveStatus() +{ + BOOL enabled; + s32 retVal; + + enabled = OSDisableInterrupts(); + + if (FatalErrorFlag) + { + retVal = -1; + } + else if (PausingFlag) + { + retVal = 8; + } + else + { + if (executing == (DVDCommandBlock*)NULL) + { + retVal = 0; + } + else if (executing == &DummyCommandBlock) + { + retVal = 0; + } + else + { + retVal = DVDGetCommandBlockStatus(executing); + } + } + + OSRestoreInterrupts(enabled); + + return retVal; +} + +BOOL DVDSetAutoInvalidation(BOOL autoInval) +{ + BOOL prev; + prev = autoInvalidation; + autoInvalidation = autoInval; + return prev; +} + +void DVDPause(void) +{ + BOOL level; + level = OSDisableInterrupts(); + PauseFlag = TRUE; + if (executing == (DVDCommandBlock*)NULL) + { + PausingFlag = TRUE; + } + OSRestoreInterrupts(level); +} + +void DVDResume(void) +{ + BOOL level; + level = OSDisableInterrupts(); + PauseFlag = FALSE; + if (PausingFlag) + { + PausingFlag = FALSE; + stateReady(); + } + OSRestoreInterrupts(level); +} + +BOOL DVDCancelAsync(DVDCommandBlock* block, DVDCBCallback callback) +{ + BOOL enabled; + DVDLowCallback old; + DVDCommandBlock* + finished; // needed for stack? maybe it actually gets used but not bothered to figure that out + + enabled = OSDisableInterrupts(); + + switch (block->state) + { + case -1: + case 0: + case 10: + if (callback) + (*callback)(0, block); + break; + + case 1: + if (Canceling) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + + Canceling = TRUE; + CancelCallback = callback; + if (block->command == 4 || block->command == 1) + { + DVDLowBreak(); + } + break; + + case 2: + __DVDDequeueWaitingQueue(block); + block->state = 10; + if (block->callback) + (block->callback)(-3, block); + if (callback) + (*callback)(0, block); + break; + + case 3: + switch (block->command) + { + case 5: + case 4: + case 13: + case 15: + if (callback) + (*callback)(0, block); + break; + + 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; + + executing = &DummyCommandBlock; + + block->state = 10; + if (block->callback) + { + (block->callback)(-3, block); + } + if (callback) + { + (callback)(0, block); + } + stateReady(); + break; + } + + OSRestoreInterrupts(enabled); + return TRUE; +} + +s32 DVDCancel(DVDCommandBlock* block) +{ + BOOL result; + s32 state; + u32 command; + BOOL enabled; + + result = DVDCancelAsync(block, cbForCancelSync); + + if (result == FALSE) + { + return -1; + } + + enabled = OSDisableInterrupts(); + + for (;;) + { + state = ((volatile DVDCommandBlock*)block)->state; + + if ((state == 0) || (state == -1) || (state == 10)) + { + break; + } + + if (state == 3) + { + command = ((volatile DVDCommandBlock*)block)->command; + + if ((command == 4) || (command == 5) || (command == 13) || (command == 15)) + { + break; + } + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return 0; +} + +static void cbForCancelSync(s32 result, DVDCommandBlock* block) +{ + OSWakeupThread(&__DVDThreadQueue); +} + +inline BOOL DVDCancelAllAsync(DVDCBCallback callback) +{ + BOOL enabled; + DVDCommandBlock* p; + BOOL retVal; + + enabled = OSDisableInterrupts(); + DVDPause(); + + while ((p = __DVDPopWaitingQueue()) != 0) + { + DVDCancelAsync(p, NULL); + } + + if (executing) + retVal = DVDCancelAsync(executing, callback); + else + { + retVal = TRUE; + if (callback) + (*callback)(0, NULL); + } + + DVDResume(); + OSRestoreInterrupts(enabled); + return retVal; +} + +s32 DVDCancelAll(void) +{ + BOOL result; + BOOL enabled; + + enabled = OSDisableInterrupts(); + CancelAllSyncComplete = FALSE; + + result = DVDCancelAllAsync(cbForCancelAllSync); + + if (result == FALSE) + { + OSRestoreInterrupts(enabled); + return -1; + } + + for (;;) + { + if (CancelAllSyncComplete) + break; + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return 0; +} + +static void cbForCancelAllSync(s32 result, DVDCommandBlock* block) +{ + CancelAllSyncComplete = TRUE; + OSWakeupThread(&__DVDThreadQueue); +} + +DVDDiskID* DVDGetCurrentDiskID(void) +{ + return (DVDDiskID*)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 == (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 = 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); +} + +BOOL __DVDTestAlarm(OSAlarm* alarm) +{ + BOOL ret; + if (alarm == &ResetAlarm) + { + ret = TRUE; + } + else + { + ret = __DVDLowTestAlarm(alarm); + } + return ret; +} \ No newline at end of file diff --git a/libs/dolphin/dvd/dvdFatal.c b/libs/dolphin/dvd/dvdFatal.c new file mode 100644 index 000000000..43359a1a4 --- /dev/null +++ b/libs/dolphin/dvd/dvdFatal.c @@ -0,0 +1,112 @@ +#include "dolphin/dvd.h" +#include "dolphin/gx/GXStruct.h" +#include "dolphin/os.h" +#include "dolphin/vi.h" + +void __DVDPrintFatalMessage(void); + +static void (*FatalFunc)(void) = NULL; + +const char *Japanese = "\n\n\nエラーが発生しました。" + "\n\n本体のパワーボタンを押して電源をOFFにし、" + "\n本体の取扱説明書の指示に従ってください。"; + +const char *English = "\n\n\nAn error has occurred." + "\nTurn the power off and refer to the" + "\nNintendo GameCube Instruction Booklet" + "\nfor further instructions."; + +const char *const Europe[] = { + // English + "\n\n\nAn error has occurred." + "\nTurn the power off and refer to the" + "\nNintendo GameCube" + "\x99" + " Instruction Booklet" + "\nfor further instructions.", + + // German + "\n\n\nEin Fehler ist aufgetreten." + "\nBitte schalten Sie den NINTENDO GAMECUBE" + "\naus und lesen Sie die Bedienungsanleitung," + "\num weitere Informationen zu erhalten.", + + // French + "\n\n\nUne erreur est survenue." + "\nEteignez la console et r" + "\xe9" + "f" + "\xe9" + "rez-vous au" + "\nmanuel d'instructions NINTENDO GAMECUBE" + "\npour de plus amples informations.", + + // Spanish + "\n\n\nSe ha producido un error." + "\nApaga la consola y consulta el manual" + "\nde instrucciones de NINTENDO GAMECUBE" + "\npara obtener m" + "\xe1" + "s informaci" + "\xf3" + "n.", + + // Italian + "\n\n\nSi \xe8 verificato un errore." + "\nSpegni (OFF) e controlla il manuale" + "\nd'istruzioni del NINTENDO GAMECUBE" + "\nper ulteriori indicazioni.", + + // Dutch + "\n\n\nEr is een fout opgetreden." + "\nZet de NINTENDO GAMECUBE uit en" + "\nraadpleeg de handleiding van de" + "\nNintendo GameCube voor nadere" + "\ninstructies.", +}; + +static void ShowMessage(void) +{ + const char *message; + GXColor bg = {0, 0, 0, 0}; + GXColor fg = {255, 255, 255, 0}; + + if (VIGetTvFormat() == VI_NTSC) + { + if (OSGetFontEncode() == OS_FONT_ENCODE_SJIS) + { + message = Japanese; + } + else + { + message = English; + } + } + else + { + message = Europe[OSGetLanguage()]; + } + + OSFatal(fg, bg, message); +} + +BOOL DVDSetAutoFatalMessaging(BOOL enable) +{ + BOOL enabled; + BOOL prev; + + enabled = OSDisableInterrupts(); + prev = FatalFunc ? TRUE : FALSE; + FatalFunc = enable ? ShowMessage : NULL; + OSRestoreInterrupts(enabled); + return prev; +} + +void __DVDPrintFatalMessage(void) +{ + if (!FatalFunc) + { + return; + } + FatalFunc(); +} \ No newline at end of file diff --git a/libs/dolphin/dvd/dvderror.c b/libs/dolphin/dvd/dvderror.c new file mode 100644 index 000000000..a2f294393 --- /dev/null +++ b/libs/dolphin/dvd/dvderror.c @@ -0,0 +1,77 @@ +#include "dolphin/dvd.h" +#include "dolphin/OSRtcPriv.h" + +static u32 ErrorTable[] = { + 0, + 0x00023A00, + 0x00062800, + 0x00030200, + 0x00031100, + 0x00052000, + 0x00052001, + 0x00052100, + 0x00052400, + 0x00052401, + 0x00052402, + 0x000B5A01, + 0x00056300, + 0x00020401, + 0x00020400, + 0x00040800, + 0x00100007, + 0, +}; + +static u8 ErrorCode2Num(u32 errorCode) +{ + u32 i; + + for (i = 0; i < sizeof(ErrorTable) / sizeof(ErrorTable[0]); i++) + { + if (ErrorTable[i] == errorCode) + { + return (u8)i; + } + } + + if ((errorCode >= 0x00100000) && (errorCode <= 0x00100008)) + { + return 17; + } + + return 29; +} + +static u8 Convert(u32 error) +{ + u32 statusCode; + u32 errorCode; + u8 errorNum; + + if (error == 0x01234567) + return 255; + + if (error == 0x01234568) + return 254; + + statusCode = (error & 0xff000000) >> 24; + errorCode = error & 0x00ffffff; + + errorNum = ErrorCode2Num(errorCode); + if (statusCode >= 6) + statusCode = 6; + + return (u8)(statusCode * 30 + errorNum); +} + +void __DVDStoreErrorCode(u32 error) +{ + OSSramEx *sram; + u8 num; + + num = Convert(error); + + sram = __OSLockSramEx(); + sram->dvdErrorCode = num; + __OSUnlockSramEx(TRUE); +} \ No newline at end of file diff --git a/libs/dolphin/dvd/dvdfs.c b/libs/dolphin/dvd/dvdfs.c new file mode 100644 index 000000000..7b688f415 --- /dev/null +++ b/libs/dolphin/dvd/dvdfs.c @@ -0,0 +1,739 @@ +#include "dolphin/dvd.h" +#include "dolphin/os.h" +#include "dolphin/os/OSBootInfo.h" + +typedef struct FSTEntry FSTEntry; + +struct FSTEntry +{ + unsigned int isDirAndStringOff; + unsigned int parentOrPosition; + unsigned int nextEntryOrLength; +}; + +static OSBootInfo *BootInfo; +static FSTEntry *FstStart; +static char *FstStringStart; +static u32 MaxEntryNum; +static u32 currentDirectory = 0; +OSThreadQueue __DVDThreadQueue; +u32 __DVDLongFileNameFlag = 0; + +static void cbForReadAsync(s32 result, DVDCommandBlock *block); +static void cbForReadSync(s32 result, DVDCommandBlock *block); +static void cbForSeekAsync(s32 result, DVDCommandBlock *block); +static void cbForSeekSync(s32 result, DVDCommandBlock *block); +static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock *block); +static void cbForPrepareStreamSync(s32 result, DVDCommandBlock *block); + +void __DVDFSInit() +{ + BootInfo = (OSBootInfo *)OSPhysicalToCached(0); + FstStart = (FSTEntry *)BootInfo->FSTLocation; + + if (FstStart) + { + MaxEntryNum = FstStart[0].nextEntryOrLength; + FstStringStart = (char *)&(FstStart[MaxEntryNum]); + } +} + +/* For convenience */ +#define entryIsDir(i) (((FstStart[i].isDirAndStringOff & 0xff000000) == 0) ? FALSE : TRUE) +#define stringOff(i) (FstStart[i].isDirAndStringOff & ~0xff000000) +#define parentDir(i) (FstStart[i].parentOrPosition) +#define nextDir(i) (FstStart[i].nextEntryOrLength) +#define filePosition(i) (FstStart[i].parentOrPosition) +#define fileLength(i) (FstStart[i].nextEntryOrLength) + +static BOOL isSame(const char *path, const char *string) +{ + while (*string != '\0') + { + if (tolower(*path++) != tolower(*string++)) + { + return FALSE; + } + } + + if ((*path == '/') || (*path == '\0')) + { + return TRUE; + } + + return FALSE; +} + +s32 DVDConvertPathToEntrynum(const char *pathPtr) +{ + const char *ptr; + char *stringPtr; + BOOL isDir; + u32 length; + u32 dirLookAt; + u32 i; + const char *origPathPtr = pathPtr; + const char *extentionStart; + BOOL illegal; + BOOL extention; + + dirLookAt = currentDirectory; + + while (1) + { + + if (*pathPtr == '\0') + { + return (s32)dirLookAt; + } + else if (*pathPtr == '/') + { + dirLookAt = 0; + pathPtr++; + continue; + } + else if (*pathPtr == '.') + { + if (*(pathPtr + 1) == '.') + { + if (*(pathPtr + 2) == '/') + { + dirLookAt = parentDir(dirLookAt); + pathPtr += 3; + continue; + } + else if (*(pathPtr + 2) == '\0') + { + return (s32)parentDir(dirLookAt); + } + } + else if (*(pathPtr + 1) == '/') + { + pathPtr += 2; + continue; + } + else if (*(pathPtr + 1) == '\0') + { + return (s32)dirLookAt; + } + } + + if (__DVDLongFileNameFlag == 0) + { + extention = FALSE; + illegal = FALSE; + + for (ptr = pathPtr; (*ptr != '\0') && (*ptr != '/'); ptr++) + { + if (*ptr == '.') + { + if ((ptr - pathPtr > 8) || (extention == TRUE)) + { + illegal = TRUE; + break; + } + extention = TRUE; + extentionStart = ptr + 1; + } + else if (*ptr == ' ') + illegal = TRUE; + } + + if ((extention == TRUE) && (ptr - extentionStart > 3)) + illegal = TRUE; + + if (illegal) { + OSPanic(__FILE__, 383, + "DVDConvertEntrynumToPath(possibly DVDOpen or DVDChangeDir or DVDOpenDir): " + "specified directory or file (%s) doesn't match standard 8.3 format. This is a " + "temporary restriction and will be removed soon\n", + origPathPtr); + } + } + + else + { + for (ptr = pathPtr; (*ptr != '\0') && (*ptr != '/'); ptr++) + ; + } + + isDir = (*ptr == '\0') ? FALSE : TRUE; + length = (u32)(ptr - pathPtr); + + ptr = pathPtr; + + for (i = dirLookAt + 1; i < nextDir(dirLookAt); i = entryIsDir(i) ? nextDir(i) : (i + 1)) + { + if ((entryIsDir(i) == FALSE) && (isDir == TRUE)) + { + continue; + } + + stringPtr = FstStringStart + stringOff(i); + + if (isSame(ptr, stringPtr) == TRUE) + { + goto next_hier; + } + } + + return -1; + + next_hier: + if (!isDir) + { + return (s32)i; + } + + dirLookAt = i; + pathPtr += length + 1; + } +} + +BOOL DVDFastOpen(s32 entrynum, DVDFileInfo *fileInfo) +{ + if ((entrynum < 0) || (entrynum >= MaxEntryNum) || entryIsDir(entrynum)) + { + return FALSE; + } + + fileInfo->startAddr = filePosition(entrynum); + fileInfo->length = fileLength(entrynum); + fileInfo->callback = (DVDCallback)NULL; + fileInfo->cb.state = DVD_STATE_END; + + return TRUE; +} + +BOOL DVDOpen(const char *fileName, DVDFileInfo *fileInfo) +{ + s32 entry; + char currentDir[128]; + + entry = DVDConvertPathToEntrynum(fileName); + + if (0 > entry) + { + DVDGetCurrentDir(currentDir, 128); + OSReport("Warning: DVDOpen(): file '%s' was not found under %s.\n", fileName, currentDir); + return FALSE; + } + + if (entryIsDir(entry)) + { + return FALSE; + } + + fileInfo->startAddr = filePosition(entry); + fileInfo->length = fileLength(entry); + fileInfo->callback = (DVDCallback)NULL; + fileInfo->cb.state = DVD_STATE_END; + + return TRUE; +} + +BOOL DVDClose(DVDFileInfo *fileInfo) +{ + DVDCancel(&(fileInfo->cb)); + return TRUE; +} + +static u32 myStrncpy(char *dest, char *src, u32 maxlen) +{ + u32 i = maxlen; + + while ((i > 0) && (*src != 0)) + { + *dest++ = *src++; + i--; + } + + return (maxlen - i); +} + +static u32 entryToPath(u32 entry, char *path, u32 maxlen) +{ + char *name; + u32 loc; + + if (entry == 0) + { + return 0; + } + + name = FstStringStart + stringOff(entry); + + loc = entryToPath(parentDir(entry), path, maxlen); + + if (loc == maxlen) + { + return loc; + } + + *(path + loc++) = '/'; + + loc += myStrncpy(path + loc, name, maxlen - loc); + + return loc; +} + +static BOOL DVDConvertEntrynumToPath(s32 entrynum, char *path, u32 maxlen) +{ + u32 loc; + + loc = entryToPath((u32)entrynum, path, maxlen); + + if (loc == maxlen) + { + path[maxlen - 1] = '\0'; + return FALSE; + } + + if (entryIsDir(entrynum)) + { + if (loc == maxlen - 1) + { + path[loc] = '\0'; + return FALSE; + } + + path[loc++] = '/'; + } + + path[loc] = '\0'; + return TRUE; +} + +BOOL DVDGetCurrentDir(char *path, u32 maxlen) +{ + return DVDConvertEntrynumToPath((s32)currentDirectory, path, maxlen); +} + +BOOL DVDChangeDir(char *dirName) +{ + s32 entry; + entry = DVDConvertPathToEntrynum(dirName); + if ((entry < 0) || (entryIsDir(entry) == FALSE)) + { + return FALSE; + } + + currentDirectory = (u32)entry; + + return TRUE; +} + +BOOL DVDReadAsyncPrio(DVDFileInfo *fileInfo, void *addr, s32 length, s32 offset, + DVDCallback callback, s32 prio) +{ + + if (!((0 <= offset) && (offset < fileInfo->length))) + { +#line 746 + OSHalt("DVDReadAsync(): specified area is out of the file "); + } + + if (!((0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE))) + { +#line 752 + OSHalt("DVDReadAsync(): specified area is out of the file "); + } + + fileInfo->callback = callback; + DVDReadAbsAsyncPrio(&(fileInfo->cb), addr, length, (s32)(fileInfo->startAddr + offset), + cbForReadAsync, prio); + + return TRUE; +} +#ifndef offsetof +#define offsetof(type, memb) ((u32) & ((type *)0)->memb) +#endif + +static void cbForReadAsync(s32 result, DVDCommandBlock *block) +{ + DVDFileInfo *fileInfo; + + fileInfo = (DVDFileInfo *)((char *)block - offsetof(DVDFileInfo, cb)); + if (fileInfo->callback) + { + (fileInfo->callback)(result, fileInfo); + } +} + +s32 DVDReadPrio(DVDFileInfo *fileInfo, void *addr, s32 length, s32 offset, s32 prio) +{ + BOOL result; + DVDCommandBlock *block; + s32 state; + BOOL enabled; + s32 retVal; + + if (!((0 <= offset) && (offset < fileInfo->length))) + { +#line 816 + OSHalt("DVDRead(): specified area is out of the file "); + } + + if (!((0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE))) + { +#line 822 + OSHalt("DVDRead(): specified area is out of the file "); + } + + block = &(fileInfo->cb); + + result = DVDReadAbsAsyncPrio(block, addr, length, (s32)(fileInfo->startAddr + offset), + cbForReadSync, prio); + + if (result == FALSE) + { + return -1; + } + + enabled = OSDisableInterrupts(); + + while (1) + { + state = ((volatile DVDCommandBlock *)block)->state; + + if (state == DVD_STATE_END) + { + retVal = (s32)block->transferredSize; + break; + } + if (state == DVD_STATE_FATAL_ERROR) + { + retVal = DVD_RESULT_FATAL_ERROR; + break; + } + if (state == DVD_STATE_CANCELED) + { + retVal = DVD_RESULT_CANCELED; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +/* This is based on the revolution SDK, these may not match in all cases */ +static void cbForReadSync(s32 result, DVDCommandBlock *block) { OSWakeupThread(&__DVDThreadQueue); } +/* This is based on the revolution SDK, these may not match in all cases */ +BOOL DVDSeekAsyncPrio(DVDFileInfo *fileInfo, s32 offset, DVDCallback callback, s32 prio) +{ + if (!((0 <= offset) && (offset <= fileInfo->length))) + { + OSPanic(__FILE__, 0, "DVDSeek(): offset is out of the file "); + } + + fileInfo->callback = callback; + DVDSeekAbsAsyncPrio(&(fileInfo->cb), (s32)(fileInfo->startAddr + offset), cbForSeekAsync, + prio); + + return TRUE; +} +/* This is based on the revolution SDK, these may not match in all cases */ +static void cbForSeekAsync(s32 result, DVDCommandBlock *block) +{ + DVDFileInfo *fileInfo; + + fileInfo = (DVDFileInfo *)((char *)block - offsetof(DVDFileInfo, cb)); + + if (fileInfo->callback) + { + (fileInfo->callback)(result, fileInfo); + } +} +/* This is based on the revolution SDK, these may not match in all cases */ +s32 DVDSeekPrio(DVDFileInfo *fileInfo, s32 offset, s32 prio) +{ + BOOL result; + DVDCommandBlock *block; + s32 state; + BOOL enabled; + s32 retVal; + + block = &(fileInfo->cb); + + result = + DVDSeekAbsAsyncPrio(block, (s32)(fileInfo->startAddr + offset), cbForSeekSync, prio); + + 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 = DVD_RESULT_CANCELED; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} +/* This is based on the revolution SDK, these may not match in all cases */ +static void cbForSeekSync(s32 result, DVDCommandBlock *block) { OSWakeupThread(&__DVDThreadQueue); } + +/* This is based on the revolution SDK, these may not match in all cases */ +s32 DVDGetFileInfoStatus(DVDFileInfo *fileInfo) +{ + return DVDGetCommandBlockStatus(&fileInfo->cb); +} + +/* This is based on the revolution SDK, these may not match in all cases */ +BOOL DVDFastOpenDir(s32 entrynum, DVDDir *dir) +{ + + if ((entrynum < 0) || (entrynum >= MaxEntryNum) || !entryIsDir(entrynum)) + { + return FALSE; + } + + dir->entryNum = (u32)entrynum; + dir->location = (u32)entrynum + 1; + dir->next = nextDir(entrynum); + + return TRUE; +} + +/* This is based on the revolution SDK, these may not match in all cases */ +BOOL DVDOpenDir(char *dirName, DVDDir *dir) +{ + s32 entry; + char currentDir[128]; + entry = DVDConvertPathToEntrynum(dirName); + + if (entry < 0) + { + DVDGetCurrentDir(currentDir, 128); + OSReport("Warning: DVDOpenDir(): file '%s' was not found under %s.\n", dirName, currentDir); + return FALSE; + } + + if (!entryIsDir(entry)) + { + return FALSE; + } + + dir->entryNum = (u32)entry; + dir->location = (u32)entry + 1; + dir->next = nextDir(entry); + + return TRUE; +} + +BOOL DVDReadDir(DVDDir *dir, DVDDirEntry *dirent) +{ + u32 loc = dir->location; + if ((loc <= dir->entryNum) || (dir->next <= loc)) + return FALSE; + + dirent->entryNum = loc; + dirent->isDir = entryIsDir(loc); + dirent->name = FstStringStart + stringOff(loc); + + dir->location = entryIsDir(loc) ? nextDir(loc) : (loc + 1); + + return TRUE; +} + +/* This is based on the revolution SDK, these may not match in all cases */ +BOOL DVDCloseDir(DVDDir *dir) { return TRUE; } + +/* This is based on the revolution SDK, these may not match in all cases */ +void DVDRewindDir(DVDDir *dir) { dir->location = dir->entryNum + 1; } + +/* This is based on the revolution SDK, these may not match in all cases */ +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; + + start = fileInfo->startAddr + offset; + + if (!Is32KBAligned(start)) + { + OSPanic(__FILE__, 1189, + "DVDPrepareStreamAsync(): Specified start address (filestart(0x%x) + offset(0x%x)) is " + "not 32KB aligned", + fileInfo->startAddr, offset); + } + + if (length == 0) + length = fileInfo->length - offset; + + if (!Is32KBAligned(length)) + { + OSPanic(__FILE__, 1199, + "DVDPrepareStreamAsync(): Specified length (0x%x) is not a multiple of 32768(32*1024)", + length); + } + + if (!((offset < fileInfo->length) && (offset + length <= fileInfo->length))) + { + OSPanic(__FILE__, 1207, + "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)); + + if (fileInfo->callback) + { + (fileInfo->callback)(result, fileInfo); + } +} + +/* This is based on the revolution SDK, these may not match in all cases */ +s32 DVDPrepareStream(DVDFileInfo *fileInfo, u32 length, u32 offset) +{ + BOOL result; + DVDCommandBlock *block; + s32 state; + BOOL enabled; + s32 retVal; + u32 start; + start = fileInfo->startAddr + offset; + + if (!Is32KBAligned(start)) + { + OSPanic(__FILE__, 0, + "DVDPrepareStream(): Specified start address (filestart(0x%x) + offset(0x%x)) is not " + "32KB aligned", + fileInfo->startAddr, offset); + } + + if (length == 0) + length = fileInfo->length - offset; + + if (!Is32KBAligned(length)) + { + OSPanic(__FILE__, 0, + "DVDPrepareStream(): Specified length (0x%x) is not a multiple of 32768(32*1024)", + length); + } + + if (!((offset <= fileInfo->length) && (offset + length <= fileInfo->length))) + { + OSPanic( + __FILE__, 0, + "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 = DVD_RESULT_CANCELED; + break; + } + + OSSleepThread(&__DVDThreadQueue); + } + + OSRestoreInterrupts(enabled); + return retVal; +} + +/* This is based on the revolution SDK, these may not match in all cases */ +static void cbForPrepareStreamSync(s32 result, DVDCommandBlock *block) +{ + OSWakeupThread(&__DVDThreadQueue); +} + +/* This is based on the revolution SDK, these may not match in all cases */ +s32 DVDGetTransferredSize(DVDFileInfo *fileinfo) +{ + s32 bytes; + DVDCommandBlock *cb; + + cb = &(fileinfo->cb); + + switch (cb->state) + { + case DVD_STATE_END: + 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: + bytes = (s32)cb->transferredSize; + break; + + case DVD_STATE_WAITING: + bytes = 0; + break; + + case DVD_STATE_BUSY: + bytes = (s32)(cb->transferredSize + (cb->currTransferSize - DVDLowGetLength())); + break; + + default: + break; + } + + return bytes; +} \ No newline at end of file diff --git a/libs/dolphin/dvd/dvdidutils.c b/libs/dolphin/dvd/dvdidutils.c new file mode 100644 index 000000000..f4cbe4118 --- /dev/null +++ b/libs/dolphin/dvd/dvdidutils.c @@ -0,0 +1,31 @@ +#include +#include + +#include + +BOOL DVDCompareDiskID(DVDDiskID *id1, DVDDiskID *id2) +{ + + if (id1->gameName[0] && id2->gameName[0] && strncmp(&id1->gameName[0], &id2->gameName[0], 4)) + { + return FALSE; + } + + if (!id1->company[0] || !id2->company[0] || strncmp(&id1->company[0], &id2->company[0], 2)) + { + return FALSE; + } + + if (id1->diskNumber != 0xff && id2->diskNumber != 0xff && id1->diskNumber != id2->diskNumber) + { + return FALSE; + } + + if (id1->gameVersion != 0xff && id2->gameVersion != 0xff && + id1->gameVersion != id2->gameVersion) + { + return FALSE; + } + + return TRUE; +} \ No newline at end of file diff --git a/libs/dolphin/dvd/dvdlow.c b/libs/dolphin/dvd/dvdlow.c new file mode 100644 index 000000000..c09c54eb9 --- /dev/null +++ b/libs/dolphin/dvd/dvdlow.c @@ -0,0 +1,515 @@ +#include "dolphin/dvd.h" +#include "dolphin/os.h" + +static BOOL FirstRead = TRUE; +static volatile BOOL StopAtNextInt = FALSE; +static u32 LastLength = 0; +static DVDLowCallback Callback = NULL; +static DVDLowCallback ResetCoverCallback = NULL; +static volatile OSTime LastResetEnd = 0; +static volatile u32 ResetOccurred = FALSE; +static volatile BOOL WaitingCoverClose = FALSE; +static BOOL Breaking = FALSE; +static volatile u32 WorkAroundType = 0; +static u32 WorkAroundSeekLocation = 0; +static volatile OSTime LastReadFinished = 0; +static OSTime LastReadIssued = 0; +static volatile BOOL LastCommandWasRead = FALSE; +static vu32 NextCommandNumber = 0; + +typedef struct DVDBuffer +{ + void *addr; + u32 length; + u32 offset; +} DVDBuffer; + +typedef struct DVDCommand +{ + s32 cmd; + void *addr; + u32 length; + u32 offset; + DVDLowCallback callback; +} DVDCommand; + +static DVDCommand CommandList[3]; +static OSAlarm AlarmForWA; +static OSAlarm AlarmForTimeout; +static OSAlarm AlarmForBreak; +static DVDBuffer Prev; +static DVDBuffer Curr; + +void __DVDInitWA() +{ + NextCommandNumber = 0; + CommandList[0].cmd = -1; + __DVDLowSetWAType(0, 0); + OSInitAlarm(); +} + +static void Read(void *addr, u32 length, u32 offset, DVDLowCallback callback); + +static BOOL ProcessNextCommand() +{ + s32 n = NextCommandNumber; + ASSERT(n < 3); + + if (CommandList[n].cmd == 1) + { + ++NextCommandNumber; + Read(CommandList[n].addr, CommandList[n].length, CommandList[n].offset, + CommandList[n].callback); + return TRUE; + } + else if (CommandList[n].cmd == 2) + { + ++NextCommandNumber; + DVDLowSeek(CommandList[n].offset, CommandList[n].callback); + return TRUE; + } + + return FALSE; +} + +void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext *context) +{ + DVDLowCallback cb; + OSContext exceptionContext; + u32 cause = 0; + u32 reg; + u32 intr; + u32 mask; + + 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].cmd = -1; + NextCommandNumber = 0; + } + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + if (cause) + { + cb = Callback; + Callback = NULL; + if (cb) + { + cb(cause); + } + + Breaking = FALSE; + } + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +static void AlarmHandler(OSAlarm *alarm, OSContext *context) +{ + BOOL error = ProcessNextCommand(); + ASSERTMSG(error != FALSE, "Failed assertion processed"); +} + +static void AlarmHandlerForTimeout(OSAlarm *alarm, OSContext *context) +{ + OSContext tmpContext; + DVDLowCallback callback; + __OSMaskInterrupts(0x400); + OSClearContext(&tmpContext); + OSSetCurrentContext(&tmpContext); + callback = Callback; + Callback = NULL; + if (callback != NULL) + { + callback(0x10); + } + OSClearContext(&tmpContext); + OSSetCurrentContext(context); +} + +static void SetTimeoutAlarm(OSTime timeout) +{ + OSCreateAlarm(&AlarmForTimeout); + OSSetAlarm(&AlarmForTimeout, timeout, AlarmHandlerForTimeout); +} + +static void Read(void *addr, u32 length, u32 offset, DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + LastCommandWasRead = TRUE; + Callback = callback; + LastReadIssued = __OSGetSystemTime(); + + __DIRegs[2] = 0xa8000000; + __DIRegs[3] = offset / 4; + __DIRegs[4] = length; + __DIRegs[5] = (u32)addr; + __DIRegs[6] = length; + LastLength = length; + __DIRegs[7] = 3; + + if (length > 0xa00000) + { + SetTimeoutAlarm(OSSecondsToTicks(20)); + } + else + { + SetTimeoutAlarm(OSSecondsToTicks(10)); + } +} + +BOOL HitCache(DVDBuffer *cur, DVDBuffer *prev) +{ + u32 uVar1 = (prev->offset + prev->length - 1) >> 15; + u32 uVar2 = (cur->offset >> 15); + u32 iVar3 = (DVDGetCurrentDiskID()->streaming ? TRUE : FALSE) ? 5 : 15; + + if ((uVar2 > uVar1 - 2) || (uVar2 < uVar1 + iVar3 + 3)) + { + return TRUE; + } + return FALSE; +} + +static void DoJustRead(void *addr, u32 length, u32 offset, DVDLowCallback callback) +{ + CommandList[0].cmd = -1; + NextCommandNumber = 0; + Read(addr, length, offset, callback); +} + +static void SeekTwiceBeforeRead(void *addr, u32 length, u32 offset, DVDLowCallback callback) +{ + u32 newOffset = offset & ~0x7FFF; + if (!newOffset) + { + newOffset = 0; + } + else + { + newOffset += WorkAroundSeekLocation; + } + CommandList[0].cmd = 2; + CommandList[0].offset = newOffset; + CommandList[0].callback = callback; + CommandList[1].cmd = 1; + CommandList[1].addr = addr; + CommandList[1].length = length; + CommandList[1].offset = offset; + CommandList[1].callback = callback; + CommandList[2].cmd = -1; + NextCommandNumber = 0; + DVDLowSeek(newOffset, callback); +} + +static void WaitBeforeRead(void *addr, u32 length, u32 offset, DVDLowCallback callback, + OSTime timeout) +{ + CommandList[0].cmd = 1; + CommandList[0].addr = addr; + CommandList[0].length = length; + CommandList[0].offset = offset; + CommandList[0].callback = callback; + CommandList[1].cmd = -1; + NextCommandNumber = 0; + OSCreateAlarm(&AlarmForWA); + OSSetAlarm(&AlarmForWA, timeout, AlarmHandler); +} + +BOOL DVDLowRead(void *addr, u32 length, u32 offset, DVDLowCallback callback) +{ + OSTime diff; + u32 prev; + + __DIRegs[6] = length; + Curr.addr = addr; + Curr.length = length; + Curr.offset = offset; + + if (WorkAroundType == 0) + { + DoJustRead(addr, length, offset, callback); + } + else if (WorkAroundType == 1) + { + if (FirstRead) + { + SeekTwiceBeforeRead(addr, length, offset, callback); + } + else + { + if (!HitCache(&Curr, &Prev)) + { + DoJustRead(addr, length, offset, callback); + } + else + { + prev = (Prev.offset + Prev.length - 1) >> 15; + if (prev == Curr.offset >> 15 || prev + 1 == Curr.offset >> 15) + { + diff = __OSGetSystemTime() - LastReadFinished; + if (OSMillisecondsToTicks(5) < diff) + { + DoJustRead(addr, length, offset, callback); + } + else + { + WaitBeforeRead(addr, length, offset, callback, + OSMillisecondsToTicks(5) - diff + OSMicrosecondsToTicks(500)); + } + } + else + { + SeekTwiceBeforeRead(addr, length, offset, callback); + } + } + } + } + return TRUE; +} + +BOOL DVDLowSeek(u32 offset, DVDLowCallback callback) +{ + ASSERTMSG(offset & 3, "DVDLowSeek(): offset must be a multiple of 4."); + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = 0xab000000; + __DIRegs[3] = offset / 4; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowWaitCoverClose(DVDLowCallback callback) +{ + Callback = callback; + WaitingCoverClose = TRUE; + StopAtNextInt = FALSE; + __DIRegs[1] = 2; + return TRUE; +} + +BOOL DVDLowReadDiskID(DVDDiskID *diskID, DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = 0xa8000040; + __DIRegs[3] = 0; + __DIRegs[4] = sizeof(DVDDiskID); + __DIRegs[5] = (u32)diskID; + __DIRegs[6] = sizeof(DVDDiskID); + __DIRegs[7] = 3; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowStopMotor(DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = 0xe3000000; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowRequestError(DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = 0xe0000000; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowInquiry(DVDDriveInfo *info, DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = 0x12000000; + __DIRegs[4] = sizeof(DVDDriveInfo); + __DIRegs[5] = (u32)info; + __DIRegs[6] = sizeof(DVDDriveInfo); + __DIRegs[7] = 3; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowAudioStream(u32 subcmd, u32 length, u32 offset, DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = subcmd | 0xe1000000; + __DIRegs[3] = offset >> 2; + __DIRegs[4] = length; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowRequestAudioStatus(u32 subcmd, DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = subcmd | 0xe2000000; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +BOOL DVDLowAudioBufferConfig(BOOL enable, u32 size, DVDLowCallback callback) +{ + StopAtNextInt = FALSE; + Callback = callback; + __DIRegs[2] = 0xe4000000 | (enable != 0 ? 0x10000 : 0) | size; + __DIRegs[7] = 1; + SetTimeoutAlarm(OSSecondsToTicks(10)); + return TRUE; +} + +void DVDLowReset() +{ + u32 reg; + OSTime resetStart; + + __DIRegs[1] = 2; + reg = __PIRegs[9]; + __PIRegs[9] = (reg & ~4) | 1; + + resetStart = __OSGetSystemTime(); + while ((__OSGetSystemTime() - resetStart) < OSMicrosecondsToTicks(12)) + ; + + __PIRegs[9] = reg | 5; + ResetOccurred = TRUE; + LastResetEnd = __OSGetSystemTime(); +} + +BOOL DVDLowBreak() +{ + StopAtNextInt = TRUE; + Breaking = TRUE; + return TRUE; +} + +DVDLowCallback DVDLowClearCallback() +{ + DVDLowCallback old; + __DIRegs[1] = 0; + old = Callback; + WaitingCoverClose = FALSE; + Callback = NULL; + return old; +} + +void __DVDLowSetWAType(u32 type, u32 location) +{ + BOOL enabled; + enabled = OSDisableInterrupts(); + WorkAroundType = type; + WorkAroundSeekLocation = location; + OSRestoreInterrupts(enabled); +} + +BOOL __DVDLowTestAlarm(OSAlarm *alarm) { + if(alarm == &AlarmForBreak) { + return TRUE; + } + if(alarm == &AlarmForTimeout) { + return TRUE; + } + + return FALSE; +} \ No newline at end of file diff --git a/libs/dolphin/dvd/dvdqueue.c b/libs/dolphin/dvd/dvdqueue.c new file mode 100644 index 000000000..54851a3c3 --- /dev/null +++ b/libs/dolphin/dvd/dvdqueue.c @@ -0,0 +1,159 @@ +#include "dolphin/dvd.h" + +#define MAX_QUEUES 4 +typedef struct +{ + DVDCommandBlock *next; + DVDCommandBlock *prev; +} DVDQueue; + +static DVDQueue WaitingQueue[MAX_QUEUES]; + +void __DVDClearWaitingQueue(void) +{ + u32 i; + + for (i = 0; i < MAX_QUEUES; i++) + { + DVDCommandBlock *q; + + q = (DVDCommandBlock *)&(WaitingQueue[i]); + q->next = q; + q->prev = q; + } +} + +BOOL __DVDPushWaitingQueue(s32 prio, DVDCommandBlock *block) +{ + BOOL enabled; + DVDCommandBlock *q; + + enabled = OSDisableInterrupts(); + + q = (DVDCommandBlock *)&(WaitingQueue[prio]); + + q->prev->next = block; + block->prev = q->prev; + block->next = q; + q->prev = block; + + OSRestoreInterrupts(enabled); + + return TRUE; +} + +static DVDCommandBlock *PopWaitingQueuePrio(s32 prio) +{ + DVDCommandBlock *tmp; + BOOL enabled; + DVDCommandBlock *q; + + enabled = OSDisableInterrupts(); + + q = (DVDCommandBlock *)&(WaitingQueue[prio]); + + tmp = q->next; + q->next = tmp->next; + tmp->next->prev = q; + + OSRestoreInterrupts(enabled); + + tmp->next = (DVDCommandBlock *)NULL; + tmp->prev = (DVDCommandBlock *)NULL; + + return tmp; +} + +DVDCommandBlock *__DVDPopWaitingQueue(void) +{ + u32 i; + BOOL enabled; + DVDCommandBlock *q; + + enabled = OSDisableInterrupts(); + + for (i = 0; i < MAX_QUEUES; i++) + { + q = (DVDCommandBlock *)&(WaitingQueue[i]); + if (q->next != q) + { + OSRestoreInterrupts(enabled); + return PopWaitingQueuePrio((s32)i); + } + } + + OSRestoreInterrupts(enabled); + + return (DVDCommandBlock *)NULL; +} + +BOOL __DVDCheckWaitingQueue(void) +{ + u32 i; + BOOL enabled; + DVDCommandBlock *q; + + enabled = OSDisableInterrupts(); + + for (i = 0; i < MAX_QUEUES; i++) + { + q = (DVDCommandBlock *)&(WaitingQueue[i]); + if (q->next != q) + { + OSRestoreInterrupts(enabled); + return TRUE; + } + } + + OSRestoreInterrupts(enabled); + + return FALSE; +} + +BOOL __DVDDequeueWaitingQueue(DVDCommandBlock *block) +{ + BOOL enabled; + DVDCommandBlock *prev; + DVDCommandBlock *next; + + enabled = OSDisableInterrupts(); + + prev = block->prev; + next = block->next; + + if ((prev == (DVDCommandBlock *)NULL) || (next == (DVDCommandBlock *)NULL)) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + + prev->next = next; + next->prev = prev; + + OSRestoreInterrupts(enabled); + + return TRUE; +} + +BOOL __DVDIsBlockInWaitingQueue(DVDCommandBlock *block) +{ + u32 i; + DVDCommandBlock *start; + DVDCommandBlock *q; + + for (i = 0; i < MAX_QUEUES; i++) + { + start = (DVDCommandBlock *)&(WaitingQueue[i]); + + if (start->next != start) + { + for (q = start->next; q != start; q = q->next) + { + if (q == block) + return TRUE; + } + } + } + + return FALSE; +} \ No newline at end of file diff --git a/libs/dolphin/dvd/emu_level2/fstload.c b/libs/dolphin/dvd/emu_level2/fstload.c new file mode 100644 index 000000000..14142137c --- /dev/null +++ b/libs/dolphin/dvd/emu_level2/fstload.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include + +static s32 status = 0; + +static u8 bb2Buf[OSRoundUp32B(sizeof(DVDBB2)) + 31]; +static DVDBB2 *bb2 = 0; +static DVDDiskID *idTmp = NULL; + +static void cb(s32 result, DVDCommandBlock *block) +{ + if (result > 0) + { + switch (status) + { + case 0: + status = 1; + DVDReadAbsAsyncForBS(block, bb2, OSRoundUp32B(sizeof(bb2)), 0x420, cb); + break; + case 1: + status = 2; + DVDReadAbsAsyncForBS(block, bb2->FSTAddress, OSRoundUp32B(bb2->FSTLength), bb2->FSTPosition, + cb); + } + } + else if (result == -1) + { + } + else if (result == -4) + { + status = 0; + DVDReset(); + DVDReadDiskID(block, idTmp, cb); + } +} + +void __fstLoad() +{ + OSBootInfo *bootInfo; + DVDDiskID *id; + u8 idTmpBuf[sizeof(DVDDiskID) + 31]; + static DVDCommandBlock block; + void *arenaHi; + + arenaHi = OSGetArenaHi(); + bootInfo = (OSBootInfo *)OSPhysicalToCached(0); + + idTmp = (DVDDiskID *)(OSRoundUp32B(idTmpBuf)); + bb2 = (DVDBB2 *)(OSRoundUp32B(bb2Buf)); + + DVDReset(); + DVDReadDiskID(&block, idTmp, cb); + while (DVDGetDriveStatus() != 0) + ; + + bootInfo->FSTLocation = bb2->FSTAddress; + bootInfo->FSTMaxLength = bb2->FSTMaxLength; + + id = &bootInfo->DVDDiskID; + + memcpy(id, idTmp, sizeof(DVDDiskID)); + OSReport("\n"); + OSReport(" Game Name ... %c%c%c%c\n", id->gameName[0], id->gameName[1], id->gameName[2], + id->gameName[3]); + OSReport(" Company ..... %c%c\n", id->company[0], id->company[1]); + OSReport(" Disk # ...... %d\n", id->diskNumber); + OSReport(" Game ver .... %d\n", id->gameVersion); + OSReport(" Streaming ... %s\n", (id->streaming == 0) ? "OFF" : "ON"); + OSReport("\n"); + OSSetArenaHi(bb2->FSTAddress); +} \ No newline at end of file diff --git a/libs/dolphin/eth/base64.c b/libs/dolphin/eth/base64.c new file mode 100644 index 000000000..a2c6b0053 --- /dev/null +++ b/libs/dolphin/eth/base64.c @@ -0,0 +1,70 @@ +#include + +static const char Base64[] = { + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" +}; + +char *__IPEncodeToBase64(void *_src, s32 len , char *dst) { + const u8 *src; + int i; + char *p; + + src = _src; + p = dst; + for (i = 0; i < len - len % 3; i += 3) { + *p++ = Base64[(src[i+0] >> 2) & 0x3f]; + *p++ = Base64[((src[i+0] & 0x3) << 4) | ((src[i+1] >> 4) & 0xf)]; + *p++ = Base64[((src[i+1] & 0xf) << 2) | ((src[i+2] >> 6) & 0x3)]; + *p++ = Base64[src[i+2] & 0x3f]; + } + + i = len - len % 3; + // Encode remaining characters + switch (len % 3) { + case 2: { + *p++ = Base64[(src[i+0] >> 2) & 0x3f]; + *p++ = Base64[((src[i+0] & 0x3) << 4) | ((src[i+1] >> 4) & 0xf)]; + *p++ = Base64[((src[i+1] & 0xf) << 2)]; + *p++ = '='; + break; + } + case 1: { + *p++ = Base64[(src[i+0] >> 2) & 0x3f]; + *p++ = Base64[((src[i+0] & 0x3) << 4)]; + *p++ = '='; + *p++ = '='; + break; + } + } + + return p; +} + +void *__IPDecodeFromBase64(const char *src, long len , void *_dst) { + u8 *dst; + int i; + u8 *p; + + dst = _dst; + p = dst; + for (i = 0; i < len; i += 4) { + int n0; + int n1; + int n2; + int n3; + n0 = strchr(Base64, src[i+0]) - Base64; + n1 = strchr(Base64, src[i+1]) - Base64; + *p++ = (n0 << 2) | (n1 >> 4) & 0x3; + + if (src[i+2] == '=') break; + + n2 = strchr(Base64, src[i+2]) - Base64; + *p++ = ((n1 << 4) & 0xff) | (n2 >> 2) & 0xf; + + if (src[i+3] == '=') break; + + n3 = strchr(Base64, src[i+3]) - Base64; + *p++ = ((n2 << 6) & 0xff) | (n3 & 0x3f); + } + return p; +} diff --git a/libs/dolphin/eth/eth.c b/libs/dolphin/eth/eth.c new file mode 100644 index 000000000..871352662 --- /dev/null +++ b/libs/dolphin/eth/eth.c @@ -0,0 +1,1031 @@ +#include + +#include +#include +#include +#include + +#include "types.h" + +#ifdef DEBUG +const char* __ETHVersion = "<< Dolphin SDK - ETH\tdebug build: Aug 5 2003 17:18:42 (0x2301) >>"; +#else +const char* __ETHVersion = "<< Dolphin SDK - ETH\trelease build: Aug 5 2003 17:18:42 (0x2301) >>"; +#endif + +static u8 broadcastheader[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +static u8 private_macaddr[6]; +static u8 __revid = 0; +static u16 __devid = 0xD107; +static u8 __acstart = 0x4E; +static OSThreadQueue threadQ; +static BOOL lockUpdate = FALSE; +static BOOL __sendbusy = FALSE; +static BOOL sendUpdate = FALSE; +static ETHStat ethstat; +static u16* protoarray = NULL; +static s32 protonum = 0; +static void* (*recvcallback0)(u16, s32, u8) = NULL; +static void (*recvcallback1)(u8*, s32) = NULL; +static BOOL recvcallbackUpdate = FALSE; +static void (*__sendcallback)(u8) = NULL; +static BOOL __recvpriorityflag = FALSE; +static u8* __sendadr = NULL; +static s32 __sendlen = 0; +static s32 __senddmalen = 0; +static s32 __sendimmlen = 0; +static u8 tmppool0[1536] ATTRIBUTE_ALIGN(32); +static u8 tmppool1[1536] ATTRIBUTE_ALIGN(32); +static u32 recvlen0 = 0; +static u32 recvlen1 = 0; + +typedef struct Descriptor { + u8 nextpacketL; + u8 packetlengthL : 4; + u8 nextpacketH : 4; + u8 packetLengthH; + u8 status; +} Descriptor; + +typedef struct Descriptor2 { + u16 nextpacket; + u16 packetlength; + u8 status; +} Descriptor2; + +static Descriptor2 d2; + +static u8* recvaddr = NULL; +static u16 rwp = 0; +static u16 rrp = 0; +static u8 mcastmap[8]; +static BOOL mcastUpdate = FALSE; + + +static BOOL lock(void); +static void unlock(void); + +static void recvsub0(void); +static void recvsub1(void); + +static void sendsub0(void); +static void sendsub1(s32 chan, OSContext* context); + +static void readbuffer0(u16 cmd); +static void readbuffer1(s32 chan, OSContext* context); +static void readbuffersub(s32 chan, OSContext* context); + +static void exiinthandler(s32 chan, OSContext* context); + +static inline u16 swap16(u16 val) { + u16 ret = __lhbrx(&val, 0); + return ret; +} + +static inline u8 higher(u16 val) { + return (val >> 8) & 0xff; +} + +static inline u8 lower(u16 val) { + return val & 0xff; +} + +static void waitexilock(void) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + while (TRUE) { + if (lock() != FALSE) { + OSRestoreInterrupts(enabled); + return; + } + + lockUpdate = TRUE; + OSSleepThread(&threadQ); + OSRestoreInterrupts(enabled); + } +} + +static void waitmicro(s32 usec) { + OSTick start; + OSTick interval; + + start = OSGetTick(); + interval = OSMicrosecondsToTicks(usec); + + while (TRUE) { + if (OSGetTick() - start >= interval) { + break; + } + } +} + +static u8 readEXIcmd(u8 cmd) { + u16 ethcmd; + u8 rdata; + + ethcmd = 0x0000 | (cmd << 8); + EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImm(0, &rdata, sizeof(rdata), EXI_READ, NULL); + EXISync(0); + EXIDeselect(0); + return rdata; +} + +static u8 readEXIcmdWait200Micro(u8 cmd) { + u16 ethcmd; + u8 rdata; + + ethcmd = 0x0000 | (cmd << 8); + EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImm(0, &rdata, sizeof(rdata), EXI_READ, NULL); + EXISync(0); + waitmicro(200); + EXIDeselect(0); + return rdata; +} + +static void writeEXIcmd(u8 cmd, u8 imr) { + BOOL ret; + u16 ethcmd; + + ethcmd = 0x4000 | (cmd << 8); + ret = EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImm(0, &imr, sizeof(imr), EXI_WRITE, NULL); + EXISync(0); + EXIDeselect(0); +} + +static void readEXIcmdLong(u8 cmd, void* address, s32 length) { + u16 ethcmd; + + ethcmd = cmd << 8; + EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImmEx(0, address, length, EXI_READ); + EXIDeselect(0); +} + +static void writeEXIcmdLong(u8 cmd, void* address, s32 length) { + BOOL ret; + u16 ethcmd; + + ethcmd = 0x4000 | (cmd << 8); + ret = EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImmEx(0, address, length, EXI_WRITE); + EXIDeselect(0); +} + +static void readcmdLong(u16 cmd, void* addr, s32 length) { + u32 ethcmd; + + ethcmd = 0x80000000 | (cmd << 8); + EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImmEx(0, addr, length, EXI_READ); + EXIDeselect(0); +} + +static void writecmdLong(u16 cmd, void* addr, s32 length) { + u32 ethcmd = 0xC0000000 | (cmd << 8); + EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImmEx(0, addr, length, EXI_WRITE); + EXIDeselect(0); +} + +static u8 readcmd(u16 cmd) { + u8 val; + + readcmdLong(cmd, &val, sizeof(val)); + return val; +} + +static void writecmd(u16 cmd, u8 val) { + writecmdLong(cmd, &val, sizeof(val)); +} + +static void StaOutput(unsigned int bit) { + writecmd(0x0060, bit * 2); + writecmd(0x0060, 8 + bit * 2); + writecmd(0x0060, 8 + bit * 2); + writecmd(0x0060, bit * 2); +} + +static u8 StaInput(void) { + unsigned char bit; + + writecmd(0x0060, 0x0C); + bit = readcmd(0x0060); + bit &= 1; + writecmd(0x0060, 0x04); + writecmd(0x0060, 0x04); + return bit; +} + +static u16 PhyRead(unsigned int regNo) { + int i; + u16 value; + + /* Clear command */ + for (i = 0; i < 32; i++) { + StaOutput(1); + } + + /* Enter read mode */ + StaOutput(0); + StaOutput(1); + StaOutput(1); + StaOutput(0); + StaOutput(0); + StaOutput(0); + StaOutput(0); + StaOutput(0); + StaOutput(0); + + /* Set register */ + StaOutput((regNo >> 4) & 1); + StaOutput((regNo >> 3) & 1); + StaOutput((regNo >> 2) & 1); + StaOutput((regNo >> 1) & 1); + StaOutput((regNo >> 0) & 1); + writecmd(0x0060, 4); + value = StaInput(); + value = StaInput(); + + /* Read value */ + value = 0; + for (i = 0; i < 16; i++) { + value = value + (StaInput() << (15 - i)); + } + + /* Clear command */ + for (i = 0; i < 32; i++) { + StaOutput(1); + } + + return value; +} + +static void PhyWrite(unsigned int regNo, u16 value) { + int i; + + /* Clear command */ + for (i = 0; i < 32; i++) { + StaOutput(1); + } + + /* Enter write mode */ + StaOutput(0); + StaOutput(1); + StaOutput(0); + StaOutput(1); + StaOutput(0); + StaOutput(0); + StaOutput(0); + StaOutput(0); + StaOutput(0); + + /* Set register */ + StaOutput((regNo >> 4) & 1); + StaOutput((regNo >> 3) & 1); + StaOutput((regNo >> 2) & 1); + StaOutput((regNo >> 1) & 1); + StaOutput((regNo >> 0) & 1); + + StaOutput(1); + StaOutput(0); + + /* Write value */ + for (i = 0; i < 16; i++) { + StaOutput((u8)((value >> (15 - i)) & 1)); + } + + /* Clear command */ + for (i = 0; i < 32; i++) { + StaOutput(1); + } +} + +static void reset(void) { + writecmd(0x0060, 0); + waitmicro(10000); + readEXIcmdWait200Micro(0x0F); + waitmicro(10000); + writecmd(0x0000, 1); + writecmd(0x0000, 0); +} + +static void recvinit(void) { + u8 ncrb; + u16 swapped; + + swapped = higher(0x0001) | (lower(0x0001) << 8); + writecmdLong(0x000A, &swapped, sizeof(swapped)); + writecmdLong(0x0016, &swapped, sizeof(swapped)); + writecmdLong(0x0018, &swapped, sizeof(swapped)); + + swapped = higher(0x000F) | (lower(0x000F) << 8); + writecmdLong(0x001A, &swapped, sizeof(swapped)); + + ncrb = readcmd(0x0001); + ncrb &= ~0b00000011; // ~3 + ncrb |= 0b00010000; // | 0x10 + writecmd(0x0001, ncrb); + writecmd(0x0000, 0x08); + writecmd(0x0032, 0x08); +} + +static void getdescriptor(u16 address) { + Descriptor d; + + readcmdLong(address, &d, sizeof(d)); + d2.nextpacket = (d.nextpacketH << 8) | d.nextpacketL; + d2.packetlength = (d.packetLengthH << 4) | d.packetlengthL; + d2.status = d.status; +} + +static u16 readcmd16(u8 cmd) { + u16 tmp16; + + readcmdLong(cmd, &tmp16, sizeof(tmp16)); + + return swap16(tmp16); +} + +static void writecmd16(u8 cmd, u16 val) { + u16 tmp16; + + tmp16 = swap16(val); + writecmdLong(cmd, &tmp16, sizeof(tmp16)); +} + +static void recvsub0(void) { + rwp = readcmd16(0x16); + rrp = readcmd16(0x18); + recvsub1(); +} + +static void recvsub1(void) { + u16 packettype; + s32 i; + u8 lrps; + u16 address; + + recvlen0 = recvlen1 = 0; + do { + while (rrp != rwp) { + address = (rrp & 0xFF) << 8; + getdescriptor(address); + readcmdLong(address + 0x10U, &packettype, sizeof(packettype)); + + if (protonum > 0) { + for (i = 0; i < protonum; i++) { + if (packettype == protoarray[i]) { + break; + } + } + + if (i == protonum) { + goto update_pointers; + } + } + + if (recvcallback0) { + lrps = d2.status; + recvaddr = (*recvcallback0)(packettype, d2.packetlength, lrps); + + if (recvaddr != NULL) { + if (address + 4U + d2.packetlength > 0x1000U) { + recvlen1 = address - 0x0FFCU + d2.packetlength; + recvlen0 = d2.packetlength - recvlen1; + } else { + recvlen0 = d2.packetlength; + recvlen1 = 0; + } + + readbuffer0(address + 4U); + return; + } + } + +update_pointers: + rrp = d2.nextpacket; + rwp = readcmd16(0x16); + } + + writecmd16(0x18, rwp); + writecmd(0x0009, 0x02); + rwp = readcmd16(0x16); + rrp = readcmd16(0x18); + } while (rwp != rrp); + + writeEXIcmd(0x02, 0xF8); + unlock(); +} + +static void readbuffer0(u16 cmd) { + u32 etcmd; + u32 length; + + length = OSRoundUp32B(recvlen0); + etcmd = 0x80000000 | (cmd << 8); + + EXISelect(0, 2, 5); + EXIImm(0, &etcmd, sizeof(etcmd), EXI_WRITE, NULL); + EXISync(0); + EXIDma(0, tmppool0, length, EXI_READ, recvlen1 != 0 ? &readbuffersub : &readbuffer1); +} + +static void readbuffersub(s32 chan, OSContext* context) { + u32 etcmd; + u32 length; + + length = OSRoundUp32B(recvlen1); + EXIDeselect(0); + + etcmd = 0x80000000 | (0x0100 << 8); + EXISelect(0, 2, 5); + EXIImm(0, &etcmd, sizeof(etcmd), EXI_WRITE, NULL); + EXISync(0); + EXIDma(0, tmppool1, length, EXI_READ, readbuffer1); + __ETHInterruptTime = OSGetTime() - __OSLastInterruptTime; +} + +static void readbuffer1(s32 chan, OSContext* context) { + EXIDeselect(0); + + DCInvalidateRange(tmppool0, OSRoundUp32B(recvlen0)); + if (recvlen1 != 0) { + DCInvalidateRange(tmppool1, OSRoundUp32B(recvlen1)); + } + + if (recvcallback1) { + memcpy(recvaddr, tmppool0, recvlen0); + if (recvlen1 != 0) { + memcpy(recvaddr + recvlen0, tmppool1, recvlen1); + } + __ETHFilter(recvaddr, d2.packetlength); + (*recvcallback1)(recvaddr, d2.packetlength); + } + + rrp = d2.nextpacket; + rwp = readcmd16(0x16); + recvsub1(); + __ETHInterruptTime = OSGetTime() - __OSLastInterruptTime; +} + +#include + +static void patchthru(void) { + u32 rnda; + u32 fa; + + writeEXIcmd(0x05, __acstart); + readEXIcmdLong(0x08, &rnda, sizeof(rnda)); + fa = hashfunc(rnda); + writeEXIcmdLong(0x09, &fa, sizeof(fa)); +} + +static void exiinthandler(s32 chan, OSContext* context) { + u8 ir; + u8 exiisr; + BOOL ret; + BOOL sendcbflag; + u8 ltps; + u8 lrps; + u8 result; + void (*callback)(u8); + + sendcbflag = FALSE; + ret = EXILock(0, 2, &exiinthandler); + if (ret != FALSE) { + exiisr = readEXIcmd(0x03); + writeEXIcmd(0x02, 0x00); + + switch (__cntlzw(exiisr)) { + case 0x18: { + writeEXIcmd(0x03, 0x80); + break; + } + + case 0x1A: { + writeEXIcmd(0x03, 0x20); + writeEXIcmd(0x02, 0xF8); + unlock(); + #ifdef DEBUG + OSPanic(__FILE__, 765, "exi cmderr\n"); + #endif + return; + } + + case 0x19: { + writeEXIcmd(0x03, 0x40); + writeEXIcmd(0x02, 0xF8); + unlock(); + return; + } + + case 0x1B: { + patchthru(); + writeEXIcmd(0x03, 0x10); + writeEXIcmd(0x02, 0xF8); + unlock(); + return; + } + + case 0x1C: { + result = readEXIcmd(0x0B); + writeEXIcmd(0x03, 0x08); + writeEXIcmd(0x02, 0xF8); + unlock(); + + if (result != 1) { + #ifdef DEBUG + OSPanic(__FILE__, 785, "ETHLIB: hash func error\n"); + #endif + } + + return; + } + } + + ir = readcmd(0x0009); + if (__recvpriorityflag == TRUE && (ir & 2) != 0) { + ethstat.rcvcount++; + recvsub0(); + __ETHInterruptTime = OSGetTime() - __OSLastInterruptTime; + } else { + switch (__cntlzw(ir)) { + case 0x18: { + ethstat.rbf++; + writecmd(0x0009, 0x80); + break; + } + + case 0x19: { + writecmd(0x0009, 0x40); + break; + } + + case 0x1A: { + ethstat.fifoe++; + writecmd(0x0009, 0x20); + break; + } + + case 0x1B: { + ethstat.te++; + //ASSERTLINE(816, __sendbusy); + __sendbusy = FALSE; + ltps = readcmd(0x0004); + + if ((ltps & 0x10) != 0) { + ethstat.tx_crs++; + } + + if ((ltps & 0x20) != 0) { + ethstat.tx_uf++; + } + + if ((ltps & 0x40) != 0) { + ethstat.tx_owc++; + } + + sendcbflag = TRUE; + writecmd(0x0009, 0x10); + break; + } + + case 0x1C: { + ethstat.re++; + + lrps = readcmd(0x0005); + if ((lrps & 1) != 0) { + ethstat.rx_bf++; + } + + if ((lrps & 2) != 0) { + ethstat.rx_crc++; + } + + if ((lrps & 4) != 0) { + ethstat.rx_fae++; + } + + if ((lrps & 8) != 0) { + ethstat.rx_fo++; + } + + if ((lrps & 0x10) != 0) { + ethstat.rx_rw++; + } + + if ((lrps & 0x40) != 0) { + ethstat.rx_rf++; + } + + writecmd(0x0009, 0x08); + break; + } + + case 0x1D: { + //ASSERTLINE(868, __sendbusy); + ethstat.sendcount++; + __sendbusy = FALSE; + sendcbflag = TRUE; + ltps = readcmd(0x0004); + writecmd(0x0009, 0x04); + break; + } + + case 0x1E: { + ethstat.rcvcount++; + recvsub0(); + return; + } + + case 0x1F: { + ethstat.cntof++; + writecmd(0x0009, 0x01); + break; + } + } + + writeEXIcmd(0x02, 0xF8); + unlock(); + + if (sendcbflag) { + callback = __sendcallback; + __sendcallback = NULL; + __ETHPostSend(ltps, callback, __sendadr); + } + + __ETHInterruptTime = OSGetTime() - __OSLastInterruptTime; + } + } +} + +s32 ETHInit(s32 mode) { + static BOOL initialized = FALSE; + u32 cid; + u8 fcsr; + u8 phy0r; + + if (initialized == FALSE) { + initialized = TRUE; + OSRegisterVersion(__ETHVersion); + } + + OSInitThreadQueue(&threadQ); + __SIRegs[15] = __SIRegs[15] & ~0x80000000; // turn on 32MHz EXI clock setting allowance + waitexilock(); + __sendbusy = FALSE; + memset(ðstat, 0, sizeof(ethstat)); + protoarray = NULL; + protonum = 0; + recvcallback0 = NULL; + recvcallback1 = NULL; + + cid = 0; + EXIGetID(0, 2, &cid); + if (cid != EXI_ETHER) { + unlock(); + OSReport("cid = %08x\n", cid); + return -1; + } else { + reset(); + readcmdLong(0x0020, private_macaddr, sizeof(private_macaddr)); + __revid = readEXIcmd(0x01); + writeEXIcmdLong(0x04, &__devid, sizeof(__devid)); + writeEXIcmd(0x05, __acstart); + + fcsr = readcmd(0x005B); + fcsr &= ~0x80; + writecmd(0x005B, fcsr); + writecmd(0x005E, 0x01); + + phy0r = readcmd(0x005C); + phy0r |= 0x04; + writecmd(0x005C, phy0r); + + writecmd(0x0001, 0x00); + writecmd(0x0003, 0x2E); + writecmd(0x0050, 0x80); + writecmd(0x0008, 0x00); + writeEXIcmd(0x02, 0xF8); + EXISetExiCallback(2, (EXICallback)&exiinthandler); + unlock(); + + return ETH_OK; + } +} + +void ETHSendAsync(void* addr, s32 length, void (*callback2)(u8)) { + BOOL disabled; + + //ASSERTLINE(985, !__sendbusy); + //ASSERTLINE(986, ((u32) addr % 32) == 0); + DCStoreRange(addr, length); + + disabled = OSDisableInterrupts(); + __sendbusy = TRUE; + __sendadr = addr; + __sendlen = length < 60 ? 60 : length; + __sendcallback = callback2; + sendUpdate = TRUE; + + if (lock()) { + unlock(); + } + + OSRestoreInterrupts(disabled); +} + +static void sendsub0(void) { + u32 etcmd; + + __senddmalen = OSRoundDown32B(__sendlen); + __sendimmlen = __sendlen - __senddmalen; + + etcmd = 0xC0000000 | (0x0048 << 8); + EXISelect(0, 2, 5); + EXIImm(0, &etcmd, sizeof(etcmd), EXI_WRITE, NULL); + EXISync(0); + EXIDma(0, __sendadr, __senddmalen, EXI_WRITE, &sendsub1); +} + +static void sendsub1(s32 chan, OSContext* context) { + u8 ncra; + + if (__sendimmlen != 0) { + EXIImmEx(0, __sendadr + __senddmalen, __sendimmlen, EXI_WRITE); + } + + EXIDeselect(0); + ncra = readcmd(0x0000); + //ASSERTLINE(1033, (ncra & ME_NCRA_TXFIFO) == 0); + ncra |= ME_NCRA_TXFIFO; + writecmd(0x0000, ncra); + unlock(); +} + +void ETHGetMACAddr(u8* macaddr) { + memcpy(macaddr, private_macaddr, sizeof(private_macaddr)); +} + +void ETHSetMACAddr(u8* macaddr) { + memcpy(private_macaddr, macaddr, sizeof(private_macaddr)); + waitexilock(); + writecmdLong(0x0020, private_macaddr, sizeof(private_macaddr)); + unlock(); +} + +void ETHSetRecvCallback(void* (*cb0)(u16, s32, u8), void (*cb1)(u8*, s32)) { + BOOL disabled; + + disabled = OSDisableInterrupts(); + recvcallback0 = cb0; + recvcallback1 = cb1; + recvcallbackUpdate = TRUE; + + if (lock()) { + unlock(); + } + + OSRestoreInterrupts(disabled); +} + +static BOOL linkState(void) { + u8 nways; + + nways = readcmd(0x0031); + if ((nways & 1) != 0 || (nways & 2) != 0) { + return TRUE; + } + + return FALSE; +} + +static BOOL ETHGetLinkState(void) { + BOOL ret; + + waitexilock(); + ret = linkState(); + unlock(); + return ret; +} + +static BOOL linkStateAsyncMain(BOOL* linkstateptr) { + if (EXILock(0, 2, NULL)) { + *linkstateptr = linkState(); + unlock(); + return TRUE; + } + + return FALSE; +} + +BOOL ETHGetLinkStateAsync(BOOL* status) { + //ASSERTLINE(1104, status); + return linkStateAsyncMain(status); +} + +s32 ETHGetNWAYMode(void) { + u8 nways; + + waitexilock(); + nways = readcmd(0x0031); + unlock(); + + if ((nways & 0x10) != 0) { + return 1; + } + + if ((nways & 0x20) != 0) { + return 2; + } + + if ((nways & 0x40) != 0) { + return 3; + } + + if ((nways & 0x80) != 0) { + return 4; + } + + return 5; +} + +void ETHSetProtoType(u16* array, s32 num) { + BOOL flag; + + //ASSERTLINE(1139, (num != 0 && array != NULL) || (num == 0 && array == NULL)); + flag = OSDisableInterrupts(); + protoarray = array; + protonum = num; + OSRestoreInterrupts(flag); +} + +void ETHGetStatus(ETHStat* stat) { + BOOL flag; + + //ASSERTLINE(1150, stat); + flag = OSDisableInterrupts(); + *stat = ethstat; + OSRestoreInterrupts(flag); +} + +s32 ETHGetLibraryVersion(void) { + return 0x506; +} + +s32 ETHGetBBAType(void) { + return 2; +} + +static u16 HashIndex(const u8* address) { + u32 crc; + u16 index; + u32 msb; + u8 byte; + s32 byteLen; + s32 bit; + s32 shift; + + crc = 0xFFFFFFFF; + index = 0; + + for (byteLen = 0; byteLen < 6; byteLen++, address++) { + byte = *address; + bit = 0; + for (bit = 0; bit < 8; bit++, byte >>= 1) { + msb = (crc >> 31) & 1; + crc = crc << 1; + + if (msb ^ (byte & 1)) { + crc ^= 0x04C11DB6; + crc |= 1; + } + } + } + + bit = 31; + for (shift = 5; shift >= 0; shift--, bit--) { + index |= ((crc >> bit) & 1) << shift; + } + + return index; +} + +void ETHAddMulticastAddress(const u8* macaddr) { + BOOL disabled; + u16 index; + u8 marNo; + u8 bitNo; + u8 ncrb; + + if (memcmp(macaddr, broadcastheader, sizeof(broadcastheader)) == 0) { + waitexilock(); + ncrb = readcmd(0x0001); + ncrb |= 4; + writecmd(0x0001, ncrb); + unlock(); + } else { + index = HashIndex(macaddr); + marNo = index / 8; + bitNo = index % 8; + disabled = OSDisableInterrupts(); + mcastmap[marNo] |= 1 << bitNo; + mcastUpdate = TRUE; + + if (lock()) { + unlock(); + } + + OSRestoreInterrupts(disabled); + } +} + +void ETHChangeIntPriority(BOOL flag) { + __recvpriorityflag = flag; +} + +u32 ETHGetREVID(void) { + u32 revid; + + waitexilock(); + revid = readEXIcmd(0x01); + unlock(); + return revid; +} + +void ETHClearMulticastAddresses(void) { + BOOL disabled; + + disabled = OSDisableInterrupts(); + memset(mcastmap, 0, sizeof(mcastmap)); + mcastUpdate = TRUE; + if (lock()) { + unlock(); + } + OSRestoreInterrupts(disabled); +} + +static void unlockcallback(s32 chan, OSContext* context) { + if (lock()) { + unlock(); + } +} + +static BOOL lock() { + return EXILock(0, 2, &unlockcallback); +} + +static void unlock(void) { + BOOL disabled; + + disabled = OSDisableInterrupts(); + + if (mcastUpdate) { + mcastUpdate = FALSE; + writecmdLong(0x0026, mcastmap, sizeof(mcastmap)); + } + + if (recvcallbackUpdate) { + recvcallbackUpdate = FALSE; + + if (recvcallback0 == NULL) { + writecmd(0x0000, 0x00); + writecmd(0x0008, 0x14); + } else { + //ASSERTLINE(1308, recvcallback0 != NULL && recvcallback1 != NULL); + writecmd(0x0008, 0xFF); + recvinit(); + } + } + + if (sendUpdate) { + sendUpdate = FALSE; + sendsub0(); + } else { + EXIUnlock(0); + if (lockUpdate) { + lockUpdate = FALSE; + OSWakeupThread(&threadQ); + } + } + + OSRestoreInterrupts(disabled); +} diff --git a/libs/dolphin/eth/ethsec.c b/libs/dolphin/eth/ethsec.c new file mode 100644 index 000000000..b86953b5e --- /dev/null +++ b/libs/dolphin/eth/ethsec.c @@ -0,0 +1,344 @@ +#include +#include +#include +#include +#include + +#include + +#define IP_MIN_HLEN (s32)sizeof(IPHeader) +#define TCP_MIN_HLEN (s32)sizeof(TCPHeader) + +static TCPResetInfo Ri; +static u8 SendBuf[82]; +static const u8 NintendoAddr[6] = { 0,9,191,0,0,0 }; + +extern u32 __OSGetDIConfig(void); +vu16 __OSDeviceCode : (OS_BASE_CACHED | 0x30E6); + +static inline BOOL CheckConsoleType() { + if (__OSGetDIConfig() == 0xFF) { + switch (__OSDeviceCode) { + case 0x8200: { + return TRUE; + } + case 0x8001: { + if (OSGetPhysicalMemSize() == 0x3000000) { + return TRUE; + } + return FALSE; + } + } + return FALSE; + } + + if ((OSGetConsoleType() & OS_CONSOLE_MASK) == 0) { + return FALSE; + } + + return TRUE; +} + +static s16 AT_IP4_IsMyAddrMask(u8 val) { return 0; } + +/*static inline BOOL IPIsLocalAddr(u32, const u8 *addr) { + return AT_IP4_IsMyAddrMask(*addr) != -1; +}*/ + +static u16 CalcIpCheckSum(IPHeader *ip) { + int len; + u32 sum; + u16 *p; + + sum = 0; + len = (ip->verlen & 0xf) << 2; + p = (u16*)ip; + + while (len > 0) { + sum += *p++; + len -= 2; + } + + sum = (sum & 0xffff) + (sum >> 16); + sum = ((sum & 0xffff) + (sum >> 16)); + return sum ^ 0xffff; +} + +static u16 CalcTcpCheckSum(IPHeader *ip, s32 len) { + s32 hlen; + u16 *p; + u32 sum = 0; + +#line 212 + ASSERT(IP_MIN_HLEN + TCP_MIN_HLEN <= len); +#line 215 + ASSERT(ip->proto == IP_PROTO_TCP); + + hlen = (ip->verlen & 0xf) << 2; + sum += ((u16*)ip->src)[0]; + sum += ((u16*)ip->src)[1]; + sum += ((u16*)ip->dst)[0]; + sum += ((u16*)ip->dst)[1]; + sum += 6; + sum += (u32)len - (u32)hlen; + + p = (u16*)((u32)ip+hlen); + len = len - hlen; + while (len > 1) { + sum += *p++; + len -= 2; + } + + if (len == 1) { + sum += *((u8*)p) * 0x100; + } + + sum = (sum & 0xffff) + (sum >> 16); + sum = (sum & 0xffff) + (sum >> 16); + return sum ^ 0xffff; +} + +static s32 GetTcpSegLen(IPHeader *ip, TCPHeader *tcp) { + s32 len = ip->len - ((ip->verlen & 0xf) << 2) - (s32)(((tcp->flag & 0xf000) >> 10)); + + if (tcp->flag & 2) { + len += 1; + } + + if (tcp->flag & 1) { + len += 1; + } + + return len; +} + +static BOOL VerifyPacket(IPHeader *ip) { + if(ip->verlen >> 4 != 4 || ip->len < ((ip->verlen & 0xf) << 2)) { + return TRUE; + } + + if (CalcIpCheckSum(ip) != 0) { + return TRUE; + } + + if ((ip->dst[0] & 0xf0) == 0xe0 || (ip->src[0] & 0xf0) == 0xe0 || + (ip->dst[0] & 0xf8) == 0xf0 || (ip->src[0] & 0xf8) == 0xf0) { + return TRUE; + } + + ASSERT(ip->proto == IP_PROTO_TCP); + if (CalcTcpCheckSum(ip, ip->len) != 0) { + return TRUE; + } + + return FALSE; +} + +static void CalcDigest(u8 *digest, TCPHeader *tcp) { + MD5Context context; + u64 secret; + + MD5Init(&context); + MD5Update(&context,(u8*)&tcp->seq,sizeof(tcp->seq)); + MD5Update(&context,(u8*)&tcp->ack,sizeof(tcp->ack)); + + secret = ((tcp->seq ^ tcp->ack) * 0x5DEECE66Dll + 0xb) % 0x1000000000000ll; + MD5Update(&context,(u8 *)&secret + 2, sizeof(secret) - 2); + MD5Final(digest,&context); +} + +BOOL __ETHFilter(u8 *buf, s32 len) { + ETHHeader *eh; + IPHeader *ip; + TCPHeader *tcp; + TCPResetInfo *ri; + u8 digest1[16]; + u8 digest2[16]; + + ri = &Ri; + if (CheckConsoleType()) { + return TRUE; + } + + eh = (ETHHeader *)buf; + if (eh->type != 0x800) { + return TRUE; + } + + if (memcmp(eh->src, NintendoAddr, 3) == 0) { + return TRUE; + } + + len = len - sizeof(ETHHeader); + ip = (IPHeader *)(eh + 1); + if (len < IP_MIN_HLEN || len < ip->len) { + return TRUE; + } + + if(ip->proto != IP_PROTO_TCP) { + return TRUE; + } + + tcp = (TCPHeader *)((u32)ip + ((ip->verlen & 0xf) << 2)); + if ((s32)(((tcp->flag & 0xf000) >> 10)) < TCP_MIN_HLEN) { + return TRUE; + } + + if (ip->len < ((ip->verlen & 0xf) << 2) + (s32)(((tcp->flag & 0xf000) >> 10))) { + return TRUE; + } + + if ((tcp->flag & 3) == 2) { + switch(tcp->src) { + case 0x76c: + case 0x35: + return TRUE; + } + + switch (tcp->dst) { + case 0x76c: + return TRUE; + } + + if (IPIsLocalAddr(0, ip->src) == FALSE) { + return TRUE; + } + + if (tcp->flag & 4) { + return TRUE; + } + + if (VerifyPacket(ip)) { + return TRUE; + } + + if (ri->flag == 0) { + memmove(ri->addr, eh->src, sizeof(ri->addr)); + memmove(ri->dstAddr, ip->dst, sizeof(ri->dstAddr)); + memmove(ri->srcAddr, ip->src, sizeof(ri->dstAddr)); + ri->dstPort = tcp->dst; + ri->srcPort = tcp->src; + + if ((tcp->flag & 0x10) == 0) { + ri->seq = 0; + ri->ack = tcp->seq + GetTcpSegLen(ip, tcp); + ri->flag = (0x10 | 0x2 | 0x1); + } + else { + ri->seq = tcp->ack; + ri->ack = 0; + ri->flag = (0x2 | 0x1); + } + ri->id = 0; + return TRUE; + } + ip->len = 0; + return FALSE; + } + + if ((tcp->flag & 3) == 3) { + if ((s32)(((tcp->flag & 0xf000) >> 10)) != TCP_MIN_HLEN) { + return TRUE; + } + + if (ip->len != 0x40) { + return TRUE; + } + + if (IPIsLocalAddr(0, ip->src) == FALSE) { + return TRUE; + } + + if (VerifyPacket(ip)) { + return TRUE; + } + + CalcDigest(digest1, tcp); + __IPDecodeFromBase64(tcp + 1, 0x18, digest2); + + if (memcmp(digest1, digest2, sizeof(digest1))) { + return TRUE; + } + ip->len = 0; + return FALSE; + } + return TRUE; +} + +BOOL __ETHPostSend(u8 ltps , void (*callback)(u8), void *prev) { + ETHHeader *eh; + IPHeader *ip; + TCPHeader *tcp; + TCPResetInfo *ri; + u8 digest[16]; + + ri = &Ri; + + if (ri->flag == 0) { + ri = NULL; + } + else if (prev != SendBuf) { + eh = prev; + ip = (IPHeader *)(eh + 1); + tcp = (TCPHeader *)(ip + 1); + if (*((u32*)ip->dst) == *((u32*)ri->srcAddr) && *((u32*)ip->src) == *((u32*)ri->dstAddr) + && tcp->src == ri->dstPort && tcp->dst == ri->srcPort) { + + if (tcp->flag & 4) { + ri->flag = 0; + ri = NULL; + } + else { + ri->seq = tcp->seq + GetTcpSegLen(ip, tcp); + ri->ack = tcp->ack; + ri->flag |= tcp->flag & 0x10; + + ri->id = ip->id - 0x4000; + if (ri->id == 0) { + ri->id = 1; + } + } + } + } + + if (ri != NULL && ri->id != 0) { + eh = (ETHHeader *)SendBuf; + ip = (IPHeader *)(eh + 1); + eh->type = 0x800; + memmove(SendBuf, ri, 6); + ETHGetMACAddr(eh->src); + + ip->verlen = 0x45; + ip->tos = 0; + ip->len = 0x40; + ip->id = ri->id; + ip->frag = 0x4000; + ip->ttl = 0xff; + ip->proto = IP_PROTO_TCP; + ip->sum = 0; + memmove(ip->dst, ri->srcAddr, sizeof(ip->dst)); + memmove(ip->src, ri->dstAddr, sizeof(ip->src)); + + + tcp = (TCPHeader *)((u32)ip + ((ip->verlen & 0xf) << 2)); + tcp->src = ri->dstPort; + tcp->dst = ri->srcPort; + tcp->seq = ri->seq; + tcp->ack = ri->ack; + tcp->flag = ri->flag & 0x3f | 0x5000; + tcp->win = 0; + tcp->sum = 0; + tcp->urg = 0; + + CalcDigest(digest, tcp); + __IPEncodeToBase64(digest, sizeof(digest), tcp + 1); + ip->sum = CalcIpCheckSum(ip); + tcp->sum = CalcTcpCheckSum(ip, ip->len); + ri->flag = 0; + ETHSendAsync(SendBuf, 0x4e, callback); + } + else if (callback) { + (*callback)(ltps); + } + return ETH_OK; +} diff --git a/libs/dolphin/eth/md5.c b/libs/dolphin/eth/md5.c new file mode 100644 index 000000000..11c6c616d --- /dev/null +++ b/libs/dolphin/eth/md5.c @@ -0,0 +1,285 @@ +/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + rights reserved. + + License to copy and use this software is granted provided that it + is identified as the "RSA Data Security, Inc. MD5 Message-Digest + Algorithm" in all material mentioning or referencing this software + or this function. + + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD5 Message-Digest Algorithm" in all material + mentioning or referencing the derived work. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + */ + +#include +#include + +/* Constants for MD5Transform routine. + */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +static void MD5Transform (u32 state[4], u8 block[64]); +static void Encode(u8* output, u32* input, u32 len); +static void Decode(u32* output, u8* input, u32 len); + +static u8 PADDING[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* F, G, H and I are basic MD5 functions. + */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. + */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +Rotation is separate from addition to prevent recomputation. + */ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (u32)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (u32)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (u32)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (u32)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +/* MD5 initialization. Begins an MD5 operation, writing a new context. + */ +void MD5Init(MD5_CTX *context) +/* context: context */ +{ + context->count[0] = context->count[1] = 0; + /* Load magic initialization constants. */ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* MD5 block update operation. Continues an MD5 message-digest + operation, processing another message block, and updating the + context. + */ +void MD5Update(MD5_CTX *context, u8 *input, u32 inputLen) +/* context: context */ +/* input: input block */ +/* inputlen: length of input block */ +{ + u32 i, index, partLen; + + /* Compute number of bytes mod 64 */ + index = (u32)((context->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + if ((context->count[0] += ((u32)inputLen << 3)) < ((u32)inputLen << 3)) + context->count[1]++; + context->count[1] += ((u32)inputLen >> 29); + partLen = 64 - index; + + /* Transform as many times as possible. */ + if (inputLen >= partLen) { + memcpy(&context->buffer[index], input, partLen); + MD5Transform(context->state, context->buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) { + MD5Transform (context->state, &input[i]); + } + + index = 0; + } else { + i = 0; + } + + /* Buffer remaining input */ + memcpy(&context->buffer[index], &input[i], inputLen - i); +} + +/* MD5 finalization. Ends an MD5 message-digest operation, writing the + the message digest and zeroizing the context. + */ +void MD5Final(u8 digest[16], MD5_CTX *context) +/* digest: message digest */ +/* context: context */ +{ + u8 bits[8]; + u32 index, padLen; + + /* Save number of bits */ + Encode (bits, context->count, 8); + + /* Pad out to 56 mod 64. */ + index = (u32)((context->count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + MD5Update (context, PADDING, padLen); + + /* Append length (before padding) */ + MD5Update (context, bits, 8); + + /* Store state in digest */ + Encode (digest, context->state, 16); + + /* Zeroize sensitive information. */ + memset(context, 0, sizeof(*context)); +} + +/* MD5 basic transformation. Transforms state based on block. + */ +static void MD5Transform (u32 state[4], u8 block[64]) +{ + u32 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode (x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information. */ + memset(x, 0, sizeof(x)); +} + +/* Encodes input (u32) into output (u8). Assumes len is + a multiple of 4. + */ +static void Encode(u8* output, u32* input, u32 len) +{ + u32 i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (u8)(input[i] & 0xff); + output[j+1] = (u8)((input[i] >> 8) & 0xff); + output[j+2] = (u8)((input[i] >> 16) & 0xff); + output[j+3] = (u8)((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (u8) into output (u32). Assumes len is + a multiple of 4. + */ +static void Decode(u32* output, u8* input, u32 len) +{ + u32 i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((u32)input[j]) | (((u32)input[j+1]) << 8) | + (((u32)input[j+2]) << 16) | (((u32)input[j+3]) << 24); +} diff --git a/libs/dolphin/exi/EXIBios.c b/libs/dolphin/exi/EXIBios.c new file mode 100644 index 000000000..66653a0a9 --- /dev/null +++ b/libs/dolphin/exi/EXIBios.c @@ -0,0 +1,854 @@ +#include "dolphin/os.h" +#include "dolphin/hw_regs.h" + +static const char *__EXIVersion = + "<< Dolphin SDK - EXI\trelease build: Apr 17 2003 12:33:17 (0x2301) >>"; + +#define MAX_DEV 3 +#define MAX_CHAN 3 + +#define REG_MAX 5 +#define REG(chan, idx) (__EXIRegs[((chan)*REG_MAX) + (idx)]) + +#define STATE_IDLE 0x00 +#define STATE_DMA 0x01 +#define STATE_IMM 0x02 +#define STATE_BUSY (STATE_DMA | STATE_IMM) +#define STATE_SELECTED 0x04 +#define STATE_ATTACHED 0x08 +#define STATE_LOCKED 0x10 + +#define EXI_0CR(tstart, dma, rw, tlen) \ + ((((u32)(tstart)) << 0) | (((u32)(dma)) << 1) | (((u32)(rw)) << 2) | (((u32)(tlen)) << 4)) + +#define CPR_CS(x) ((1u << (x)) << 7) +#define CPR_CLK(x) ((x) << 4) + +typedef struct EXIControl +{ + EXICallback exiCallback; + EXICallback tcCallback; + EXICallback extCallback; + vu32 state; + int immLen; + u8 *immBuf; + u32 dev; + u32 id; + s32 idTime; + int items; + struct + { + u32 dev; + EXICallback callback; + } queue[MAX_DEV]; +} EXIControl; + +static EXIControl Ecb[MAX_CHAN]; +static u32 IDSerialPort1; +s32 __EXIProbeStartTime[2] : (OS_BASE_CACHED | 0x30C0); + +#pragma scheduling off + +static void SetExiInterruptMask(s32 chan, EXIControl *exi) +{ + EXIControl *exi2; + + exi2 = &Ecb[2]; + switch (chan) + { + case 0: + if ((exi->exiCallback == 0 && exi2->exiCallback == 0) || (exi->state & STATE_LOCKED)) + { + __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_2_EXI); + } + else + { + __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_2_EXI); + } + break; + case 1: + if (exi->exiCallback == 0 || (exi->state & STATE_LOCKED)) + { + __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXI); + } + else + { + __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXI); + } + break; + case 2: + if (__OSGetInterruptHandler(__OS_INTERRUPT_PI_DEBUG) == 0 || (exi->state & STATE_LOCKED)) + { + __OSMaskInterrupts(OS_INTERRUPTMASK_PI_DEBUG); + } + else + { + __OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_DEBUG); + } + break; + } +} + +static void CompleteTransfer(s32 chan) +{ + EXIControl *exi = &Ecb[chan]; + u8 *buf; + u32 data; + int i; + int len; + + if (exi->state & STATE_BUSY) + { + if ((exi->state & STATE_IMM) && (len = exi->immLen)) + { + buf = exi->immBuf; + data = REG(chan, 4); + for (i = 0; i < len; i++) + { + *buf++ = (u8)((data >> ((3 - i) * 8)) & 0xff); + } + } + exi->state &= ~STATE_BUSY; + } +} + +BOOL EXIImm(s32 chan, void *buf, s32 len, u32 type, EXICallback callback) +{ + EXIControl *exi = &Ecb[chan]; + BOOL enabled; + + enabled = OSDisableInterrupts(); + if ((exi->state & STATE_BUSY) || !(exi->state & STATE_SELECTED)) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + + exi->tcCallback = callback; + if (exi->tcCallback) + { + EXIClearInterrupts(chan, FALSE, TRUE, FALSE); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_TC >> (3 * chan)); + } + + exi->state |= STATE_IMM; + + if (type != EXI_READ) + { + u32 data; + int i; + + data = 0; + for (i = 0; i < len; i++) + { + data |= ((u8 *)buf)[i] << ((3 - i) * 8); + } + REG(chan, 4) = data; + } + + exi->immBuf = buf; + exi->immLen = (type != EXI_WRITE) ? len : 0; + + REG(chan, 3) = EXI_0CR(1, 0, type, len - 1); + + OSRestoreInterrupts(enabled); + + return TRUE; +} + +BOOL EXIImmEx(s32 chan, void *buf, s32 len, u32 mode) +{ + s32 xLen; + + while (len) + { + xLen = (len < 4) ? len : 4; + if (!EXIImm(chan, buf, xLen, mode, NULL)) + { + return FALSE; + } + + if (!EXISync(chan)) + { + return FALSE; + } + + (u8 *)buf += xLen; + len -= xLen; + } + return TRUE; +} + +BOOL EXIDma(s32 chan, void *buf, s32 len, u32 type, EXICallback callback) +{ + EXIControl *exi = &Ecb[chan]; + BOOL enabled; + + enabled = OSDisableInterrupts(); + if ((exi->state & STATE_BUSY) || !(exi->state & STATE_SELECTED)) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + + exi->tcCallback = callback; + if (exi->tcCallback) + { + EXIClearInterrupts(chan, FALSE, TRUE, FALSE); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_TC >> (3 * chan)); + } + + exi->state |= STATE_DMA; + + REG(chan, 1) = (u32)buf & 0x3ffffe0; + REG(chan, 2) = (u32)len; + REG(chan, 3) = EXI_0CR(1, 1, type, 0); + + OSRestoreInterrupts(enabled); + + return TRUE; +} + +extern u32 __OSGetDIConfig(void); + +vu16 __OSDeviceCode : (OS_BASE_CACHED | 0x30E6); + +BOOL EXISync(s32 chan) +{ + EXIControl *exi = &Ecb[chan]; + BOOL rc = FALSE; + BOOL enabled; + + while (exi->state & STATE_SELECTED) + { + if (((REG(chan, 3) & 1) >> 0) == 0) + { + enabled = OSDisableInterrupts(); + if (exi->state & STATE_SELECTED) + { + CompleteTransfer(chan); + if (__OSGetDIConfig() != 0xff || ((OSGetConsoleType() & OS_CONSOLE_MASK) == OS_CONSOLE_TDEV) || exi->immLen != 4 || + (REG(chan, 0) & 0x00000070) != (EXI_FREQ_1M << 4) || + (REG(chan, 4) != EXI_USB_ADAPTER && REG(chan, 4) != EXI_IS_VIEWER && + REG(chan, 4) != 0x04220001) || + __OSDeviceCode == 0x8200) + { + rc = TRUE; + } + } + OSRestoreInterrupts(enabled); + break; + } + } + return rc; +} + +u32 EXIClearInterrupts(s32 chan, BOOL exi, BOOL tc, BOOL ext) +{ + u32 cpr; + u32 prev; + + prev = cpr = REG(chan, 0); + cpr &= 0x7f5; + if (exi) + cpr |= 2; + if (tc) + cpr |= 8; + if (ext) + cpr |= 0x800; + REG(chan, 0) = cpr; + return prev; +} + +EXICallback EXISetExiCallback(s32 chan, EXICallback exiCallback) +{ + EXIControl *exi = &Ecb[chan]; + EXICallback prev; + BOOL enabled; + + enabled = OSDisableInterrupts(); + prev = exi->exiCallback; + exi->exiCallback = exiCallback; + + if (chan != 2) + { + SetExiInterruptMask(chan, exi); + } + else + { + SetExiInterruptMask(0, &Ecb[0]); + } + + OSRestoreInterrupts(enabled); + return prev; +} + +void EXIProbeReset(void) +{ + __EXIProbeStartTime[0] = __EXIProbeStartTime[1] = 0; + Ecb[0].idTime = Ecb[1].idTime = 0; + __EXIProbe(0); + __EXIProbe(1); +} + +static BOOL __EXIProbe(s32 chan) +{ + EXIControl *exi = &Ecb[chan]; + BOOL enabled; + BOOL rc; + u32 cpr; + s32 t; + + if (chan == 2) + { + return TRUE; + } + + rc = TRUE; + enabled = OSDisableInterrupts(); + cpr = REG(chan, 0); + if (!(exi->state & EXI_STATE_ATTACHED)) + { + if (cpr & 0x00000800) + { + EXIClearInterrupts(chan, FALSE, FALSE, TRUE); + __EXIProbeStartTime[chan] = exi->idTime = 0; + } + + if (cpr & 0x00001000) + { + t = (s32)(OSTicksToMilliseconds(OSGetTime()) / 100) + 1; + if (__EXIProbeStartTime[chan] == 0) + { + __EXIProbeStartTime[chan] = t; + } + if (t - __EXIProbeStartTime[chan] < 300 / 100) + { + rc = FALSE; + } + } + else + { + __EXIProbeStartTime[chan] = exi->idTime = 0; + rc = FALSE; + } + } + else if (!(cpr & 0x00001000) || (cpr & 0x00000800)) + { + __EXIProbeStartTime[chan] = exi->idTime = 0; + rc = FALSE; + } + OSRestoreInterrupts(enabled); + + return rc; +} + +BOOL EXIProbe(s32 chan) +{ + EXIControl *exi = &Ecb[chan]; + BOOL rc; + u32 id; + + rc = __EXIProbe(chan); + if (rc && exi->idTime == 0) + { + rc = EXIGetID(chan, 0, &id) ? TRUE : FALSE; + } + return rc; +} + +s32 EXIProbeEx(s32 chan) +{ + if (EXIProbe(chan)) + { + return 1; + } + else if (__EXIProbeStartTime[chan] != 0) + { + return 0; + } + else + { + return -1; + } +} + +static BOOL __EXIAttach(s32 chan, EXICallback extCallback) +{ + EXIControl *exi = &Ecb[chan]; + BOOL enabled; + + enabled = OSDisableInterrupts(); + if ((exi->state & EXI_STATE_ATTACHED) || __EXIProbe(chan) == FALSE) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + + EXIClearInterrupts(chan, TRUE, FALSE, FALSE); + + exi->extCallback = extCallback; + __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT >> (3 * chan)); + exi->state |= STATE_ATTACHED; + OSRestoreInterrupts(enabled); + + return TRUE; +} + +BOOL EXIAttach(s32 chan, EXICallback extCallback) +{ + EXIControl *exi = &Ecb[chan]; + BOOL enabled; + BOOL rc; + + EXIProbe(chan); + + enabled = OSDisableInterrupts(); + if (exi->idTime == 0) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + rc = __EXIAttach(chan, extCallback); + OSRestoreInterrupts(enabled); + return rc; +} + +BOOL EXIDetach(s32 chan) +{ + EXIControl *exi = &Ecb[chan]; + BOOL enabled; + + enabled = OSDisableInterrupts(); + if (!(exi->state & STATE_ATTACHED)) + { + OSRestoreInterrupts(enabled); + return TRUE; + } + if ((exi->state & STATE_LOCKED) && exi->dev == 0) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + + exi->state &= ~STATE_ATTACHED; + __OSMaskInterrupts((OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_0_EXI) >> (3 * chan)); + OSRestoreInterrupts(enabled); + return TRUE; +} + +BOOL EXISelect(s32 chan, u32 dev, u32 freq) +{ + EXIControl *exi = &Ecb[chan]; + u32 cpr; + BOOL enabled; + + enabled = OSDisableInterrupts(); + if ((exi->state & STATE_SELECTED) || + chan != 2 && (dev == 0 && !(exi->state & STATE_ATTACHED) && !__EXIProbe(chan) || + !(exi->state & STATE_LOCKED) || (exi->dev != dev))) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + + exi->state |= STATE_SELECTED; + cpr = REG(chan, 0); + cpr &= 0x405; + cpr |= CPR_CS(dev) | CPR_CLK(freq); + REG(chan, 0) = cpr; + + if (exi->state & STATE_ATTACHED) + { + switch (chan) + { + case 0: + __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT); + break; + case 1: + __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXT); + break; + } + } + + OSRestoreInterrupts(enabled); + return TRUE; +} + +BOOL EXIDeselect(s32 chan) +{ + EXIControl *exi = &Ecb[chan]; + u32 cpr; + BOOL enabled; + + enabled = OSDisableInterrupts(); + if (!(exi->state & STATE_SELECTED)) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + exi->state &= ~STATE_SELECTED; + cpr = REG(chan, 0); + REG(chan, 0) = cpr & 0x405; + + if (exi->state & STATE_ATTACHED) + { + switch (chan) + { + case 0: + __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT); + break; + case 1: + __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXT); + break; + } + } + + OSRestoreInterrupts(enabled); + + if (chan != 2 && (cpr & CPR_CS(0))) + { + return __EXIProbe(chan) ? TRUE : FALSE; + } + + return TRUE; +} + +static void EXIIntrruptHandler(__OSInterrupt interrupt, OSContext *context) +{ + s32 chan; + EXIControl *exi; + EXICallback callback; + + chan = (interrupt - __OS_INTERRUPT_EXI_0_EXI) / 3; + exi = &Ecb[chan]; + EXIClearInterrupts(chan, TRUE, FALSE, FALSE); + callback = exi->exiCallback; + if (callback) + { + OSContext exceptionContext; + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + callback(chan, context); + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } +} + +static void TCIntrruptHandler(__OSInterrupt interrupt, OSContext *context) +{ + OSContext exceptionContext; + s32 chan; + EXIControl *exi; + EXICallback callback; + + chan = (interrupt - __OS_INTERRUPT_EXI_0_TC) / 3; + exi = &Ecb[chan]; + __OSMaskInterrupts(OS_INTERRUPTMASK(interrupt)); + EXIClearInterrupts(chan, FALSE, TRUE, FALSE); + callback = exi->tcCallback; + if (callback) + { + exi->tcCallback = 0; + CompleteTransfer(chan); + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + callback(chan, context); + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } +} + +static void EXTIntrruptHandler(__OSInterrupt interrupt, OSContext *context) +{ + s32 chan; + EXIControl *exi; + EXICallback callback; + + chan = (interrupt - __OS_INTERRUPT_EXI_0_EXT) / 3; + __OSMaskInterrupts((OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_0_EXI) >> (3 * chan)); + exi = &Ecb[chan]; + callback = exi->extCallback; + exi->state &= ~STATE_ATTACHED; + if (callback) + { + OSContext exceptionContext; + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + exi->extCallback = 0; + callback(chan, context); + + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } +} + +void EXIInit(void) +{ + u32 id; + while (((REG(0, 3) & 0x1) == 1) || ((REG(1, 3) & 0x1) == 1) || ((REG(2, 3) & 0x1) == 1)) { + continue; + } + + __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_0_TC | OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_1_EXI + | OS_INTERRUPTMASK_EXI_1_TC | OS_INTERRUPTMASK_EXI_1_EXT | OS_INTERRUPTMASK_EXI_2_EXI | OS_INTERRUPTMASK_EXI_2_TC); + + REG(0, 0) = 0; + REG(1, 0) = 0; + REG(2, 0) = 0; + + REG(0, 0) = 0x00002000; + + __OSSetInterruptHandler(__OS_INTERRUPT_EXI_0_EXI, EXIIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_EXI_0_TC, TCIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_EXI_0_EXT, EXTIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_EXI_1_EXI, EXIIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_EXI_1_TC, TCIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_EXI_1_EXT, EXTIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_EXI_2_EXI, EXIIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_EXI_2_TC, TCIntrruptHandler); + + 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, &id) && id == 0x07010000) { + __OSEnableBarnacle(1, 0); + } else if (EXIGetID(1, 0, &id) && id == 0x07010000) { + __OSEnableBarnacle(0, 2); + } + + OSRegisterVersion(__EXIVersion); +} + +BOOL EXILock(s32 chan, u32 dev, EXICallback unlockedCallback) +{ + EXIControl *exi = &Ecb[chan]; + BOOL enabled; + int i; + + enabled = OSDisableInterrupts(); + if (exi->state & STATE_LOCKED) + { + if (unlockedCallback) + { + for (i = 0; i < exi->items; i++) + { + if (exi->queue[i].dev == dev) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + } + exi->queue[exi->items].callback = unlockedCallback; + exi->queue[exi->items].dev = dev; + exi->items++; + } + OSRestoreInterrupts(enabled); + return FALSE; + } + + exi->state |= STATE_LOCKED; + exi->dev = dev; + SetExiInterruptMask(chan, exi); + + OSRestoreInterrupts(enabled); + return TRUE; +} + +BOOL EXIUnlock(s32 chan) +{ + EXIControl *exi = &Ecb[chan]; + BOOL enabled; + EXICallback unlockedCallback; + + enabled = OSDisableInterrupts(); + if (!(exi->state & STATE_LOCKED)) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + exi->state &= ~STATE_LOCKED; + SetExiInterruptMask(chan, exi); + + if (0 < exi->items) + { + unlockedCallback = exi->queue[0].callback; + if (0 < --exi->items) + { + memmove(&exi->queue[0], &exi->queue[1], sizeof(exi->queue[0]) * exi->items); + } + unlockedCallback(chan, 0); + } + + OSRestoreInterrupts(enabled); + return TRUE; +} + +u32 EXIGetState(s32 chan) +{ + EXIControl *exi = &Ecb[chan]; + + return (u32)exi->state; +} + +static void UnlockedHandler(s32 chan, OSContext *context) +{ + u32 id; + + EXIGetID(chan, 0, &id); +} + +s32 EXIGetID(s32 chan, u32 dev, u32* id) +{ + EXIControl* exi = &Ecb[chan]; + BOOL err; + u32 cmd; + s32 startTime; + BOOL enabled; + BOOL interrupt; + + if (chan == 0 && dev == 2 && IDSerialPort1) { + *id = IDSerialPort1; + return 1; + } + + if (chan < 2 && dev == 0) { + if (!__EXIProbe(chan)) { + return 0; + } + + if (exi->idTime == __EXIProbeStartTime[chan]) { + *id = exi->id; + return exi->idTime; + } + + if (!__EXIAttach(chan, NULL)) { + return 0; + } + startTime = __EXIProbeStartTime[chan]; + } + + interrupt = OSDisableInterrupts(); + err = !EXILock(chan, dev, (chan < 2 && dev == 0) ? UnlockedHandler : NULL); + if (!err) { + err = !EXISelect(chan, dev, EXI_FREQ_1M); + if (!err) { + cmd = 0; + err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, NULL); + err |= !EXISync(chan); + err |= !EXIImm(chan, id, 4, EXI_READ, NULL); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + } + EXIUnlock(chan); + } + OSRestoreInterrupts(interrupt); + + if (chan < 2 && dev == 0) { + EXIDetach(chan); + enabled = OSDisableInterrupts(); + err |= (startTime != __EXIProbeStartTime[chan]); + if (!err) { + exi->id = *id; + exi->idTime = startTime; + } + OSRestoreInterrupts(enabled); + + return err ? 0 : exi->idTime; + } + + return err ? 0 : !0; +} + +s32 EXIGetType(s32 chan, u32 dev, u32 *type) { + u32 _type; + s32 probe; + + probe = EXIGetID(chan, dev, &_type); + if(probe == 0) + return probe; + + switch(_type & 0xffffff00) + { + case 0x4020100: + case 0x4020200: + case 0x4020300: + case 0x4060000: + *type = _type & 0xffffff00; + return probe; + } + + switch(_type & 0xffff0000) + { + case 0: + { + if ((_type & 0x3803)) + break; + + switch (_type & 0xfc) + { + case 4: + case 8: + case 16: + case 32: + case 64: + case 128: + *type = _type & 0xfc; + return probe; + } + break; + } + case 0x5070000: + *type = 0x5070000; + return probe; + } + *type = _type; + return probe; +} + +char* EXIGetTypeString(u32 type) +{ + switch (type) { + case EXI_MEMORY_CARD_59: + return "Memory Card 59"; + case EXI_MEMORY_CARD_123: + return "Memory Card 123"; + case EXI_MEMORY_CARD_251: + return "Memory Card 251"; + case EXI_MEMORY_CARD_507: + return "Memory Card 507"; + case EXI_MEMORY_CARD_1019: + return "Memory Card 1019"; + case EXI_MEMORY_CARD_2043: + 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: + return "Net Card"; + case EXI_ETHER_VIEWER: + return "Artist Ether"; + case EXI_MODEM: + return "Broadband Adapter"; + case EXI_STREAM_HANGER: + return "Stream Hanger"; + case EXI_IS_VIEWER: + return "IS-DOL-VIEWER"; + } +} + +#pragma scheduling reset diff --git a/libs/dolphin/exi/EXIUart.c b/libs/dolphin/exi/EXIUart.c new file mode 100644 index 000000000..8e8734a1a --- /dev/null +++ b/libs/dolphin/exi/EXIUart.c @@ -0,0 +1,202 @@ +#include "dolphin/os.h" + +#define EXI_TX 0x800400u +#define EXI_MAGIC 0xa5ff005a + +static s32 Chan; +static u32 Dev; +static u32 Enabled = 0; +static u32 BarnacleEnabled = 0; + +static BOOL ProbeBarnacle(s32 chan, u32 dev, u32 *revision) +{ + BOOL err; + u32 cmd; + + if (chan != 2 && dev == 0 && !EXIAttach(chan, NULL)) + { + return FALSE; + } + + err = !EXILock(chan, dev, NULL); + if (!err) + { + err = !EXISelect(chan, dev, EXI_FREQ_1M); + if (!err) + { + cmd = 0x20011300; + err = FALSE; + err |= !EXIImm(chan, &cmd, 4, EXI_WRITE, NULL); + err |= !EXISync(chan); + err |= !EXIImm(chan, revision, 4, EXI_READ, NULL); + err |= !EXISync(chan); + err |= !EXIDeselect(chan); + } + EXIUnlock(chan); + } + + if (chan != 2 && dev == 0) + { + EXIDetach(chan); + } + + if (err) + { + return FALSE; + } + + return (*revision != 0xFFFFFFFF) ? TRUE : FALSE; +} + +void __OSEnableBarnacle(s32 chan, u32 dev) +{ + u32 id; + + if (EXIGetID(chan, dev, &id)) + { + switch (id) + { + case 0xffffffff: + case EXI_MEMORY_CARD_59: + case EXI_MEMORY_CARD_123: + case EXI_MEMORY_CARD_251: + case EXI_MEMORY_CARD_507: + case EXI_USB_ADAPTER: + case EXI_NPDP_GDEV: + case EXI_MODEM: + case EXI_MARLIN: + case 0x04220000: + case 0x04020100: + case 0x04020200: + case 0x04020300: + case 0x04040404: + case 0x04060000: + case 0x04120000: + case 0x04130000: + case 0x80000000 | EXI_MEMORY_CARD_59: + case 0x80000000 | EXI_MEMORY_CARD_123: + case 0x80000000 | EXI_MEMORY_CARD_251: + case 0x80000000 | EXI_MEMORY_CARD_507: + break; + default: + if (ProbeBarnacle(chan, dev, &id)) + { + Chan = chan; + Dev = dev; + Enabled = BarnacleEnabled = EXI_MAGIC; + } + break; + } + } +} + +u32 InitializeUART(u32 baudRate) +{ + if (BarnacleEnabled == EXI_MAGIC) + { + return 0; + } + + if (!(OSGetConsoleType() & OS_CONSOLE_DEVELOPMENT)) + { + Enabled = 0; + return 2; + } + else + { + Chan = 0; + Dev = 1; + Enabled = EXI_MAGIC; + return 0; + } +} + +u32 ReadUARTN(void *bytes, unsigned long length) { return 4; } + +static int QueueLength(void) +{ + u32 cmd; + + if (!EXISelect(Chan, Dev, EXI_FREQ_8M)) + return -1; + + cmd = EXI_TX << 6; + EXIImm(Chan, &cmd, 4, EXI_WRITE, NULL); + EXISync(Chan); + + EXIImm(Chan, &cmd, 1, EXI_READ, NULL); + EXISync(Chan); + EXIDeselect(Chan); + + return 16 - (int)((cmd >> 24) & 0xff); +} + +u32 WriteUARTN(const void *buf, unsigned long len) +{ + BOOL enabled; + u32 cmd; + int qLen; + long xLen; + char *ptr; + BOOL locked; + u32 error; + + if (Enabled != EXI_MAGIC) + return 2; + + enabled = OSDisableInterrupts(); + + locked = EXILock(Chan, Dev, 0); + if (!locked) + { + OSRestoreInterrupts(enabled); + return 0; + } + + for (ptr = (char *)buf; ptr - buf < len; ptr++) + { + if (*ptr == '\n') + *ptr = '\r'; + } + + error = 0; + cmd = (EXI_TX | 0x2000000) << 6; + while (len) + { + qLen = QueueLength(); + if (qLen < 0) + { + error = 3; + break; + } + + if (qLen < 12 && qLen < len) + continue; + + if (!EXISelect(Chan, Dev, EXI_FREQ_8M)) + { + error = 3; + break; + } + + EXIImm(Chan, &cmd, 4, EXI_WRITE, NULL); + EXISync(Chan); + + while (qLen && len) + { + if (qLen < 4 && qLen < len) + break; + xLen = (len < 4) ? (long)len : 4; + EXIImm(Chan, (void *)buf, xLen, EXI_WRITE, NULL); + (u8 *)buf += xLen; + len -= xLen; + qLen -= xLen; + EXISync(Chan); + } + EXIDeselect(Chan); + } + + EXIUnlock(Chan); + OSRestoreInterrupts(enabled); + return error; +} \ No newline at end of file diff --git a/libs/dolphin/gd/GDBase.c b/libs/dolphin/gd/GDBase.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gd/GDGeometry.c b/libs/dolphin/gd/GDGeometry.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXAttr.c b/libs/dolphin/gx/GXAttr.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXBump.c b/libs/dolphin/gx/GXBump.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXDisplayList.c b/libs/dolphin/gx/GXDisplayList.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXDraw.c b/libs/dolphin/gx/GXDraw.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXFifo.c b/libs/dolphin/gx/GXFifo.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXFrameBuf.c b/libs/dolphin/gx/GXFrameBuf.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXGeometry.c b/libs/dolphin/gx/GXGeometry.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXInit.c b/libs/dolphin/gx/GXInit.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXLight.c b/libs/dolphin/gx/GXLight.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXMisc.c b/libs/dolphin/gx/GXMisc.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXPerf.c b/libs/dolphin/gx/GXPerf.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXPixel.c b/libs/dolphin/gx/GXPixel.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXTev.c b/libs/dolphin/gx/GXTev.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXTexture.c b/libs/dolphin/gx/GXTexture.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gx/GXTransform.c b/libs/dolphin/gx/GXTransform.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/hio/hio.c b/libs/dolphin/hio/hio.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IFFifo.c b/libs/dolphin/ip/IFFifo.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IFRing.c b/libs/dolphin/ip/IFRing.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IP.c b/libs/dolphin/ip/IP.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPArp.c b/libs/dolphin/ip/IPArp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPChap.c b/libs/dolphin/ip/IPChap.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPDhcp.c b/libs/dolphin/ip/IPDhcp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPDns.c b/libs/dolphin/ip/IPDns.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPEther.c b/libs/dolphin/ip/IPEther.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPFrag.c b/libs/dolphin/ip/IPFrag.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPIcmp.c b/libs/dolphin/ip/IPIcmp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPIgmp.c b/libs/dolphin/ip/IPIgmp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPIpcp.c b/libs/dolphin/ip/IPIpcp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPLcp.c b/libs/dolphin/ip/IPLcp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPOpt.c b/libs/dolphin/ip/IPOpt.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPPPP.c b/libs/dolphin/ip/IPPPP.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPPPPoE.c b/libs/dolphin/ip/IPPPPoE.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPPap.c b/libs/dolphin/ip/IPPap.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPRoute.c b/libs/dolphin/ip/IPRoute.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPSocket.c b/libs/dolphin/ip/IPSocket.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPTcp.c b/libs/dolphin/ip/IPTcp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPTcpOutput.c b/libs/dolphin/ip/IPTcpOutput.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPTcpTimeWait.c b/libs/dolphin/ip/IPTcpTimeWait.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPTcpTimer.c b/libs/dolphin/ip/IPTcpTimer.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPTcpUser.c b/libs/dolphin/ip/IPTcpUser.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPUdp.c b/libs/dolphin/ip/IPUdp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPUuid.c b/libs/dolphin/ip/IPUuid.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPZero.c b/libs/dolphin/ip/IPZero.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/lg/allsrc.c b/libs/dolphin/lg/allsrc.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/mtx/mtx.c b/libs/dolphin/mtx/mtx.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/mtx/mtx44.c b/libs/dolphin/mtx/mtx44.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/mtx/mtx44vec.c b/libs/dolphin/mtx/mtx44vec.c new file mode 100644 index 000000000..2a12fbce9 --- /dev/null +++ b/libs/dolphin/mtx/mtx44vec.c @@ -0,0 +1,39 @@ +#include "dolphin/mtx.h" + +// TODO: cleanup, documentation, check other builds +void PSMTX44MultVec(register const Mtx44 m, register const Vec *src, register Vec *dst) +{ + // clang-format off + __asm { + psq_l f0, 0(src), 0, 0 + psq_l f2, 0x30(m), 0, 0 + psq_l f1, 8(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, 0(m), 0, 0 + ps_merge00 f13, f13, f13 + psq_l f5, 8(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, 0(dst), 0, 0 + ps_mul f3, f3, f13 + psq_st f3, 8(dst), 1, 0 + } + // clang-format on +} \ No newline at end of file diff --git a/libs/dolphin/mtx/mtxvec.c b/libs/dolphin/mtx/mtxvec.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/mtx/quat.c b/libs/dolphin/mtx/quat.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/mtx/vec.c b/libs/dolphin/mtx/vec.c new file mode 100644 index 000000000..17ba7c59e --- /dev/null +++ b/libs/dolphin/mtx/vec.c @@ -0,0 +1,262 @@ +#include "types.h" +#include "dolphin/mtx.h" + +#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 + +void C_VECAdd(void) +{ + // UNUSED FUNCTION +} + +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_VECSubtract(void) +{ + // UNUSED FUNCTION +} + +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 +} + +void C_VECScale(void) +{ + // UNUSED FUNCTION +} + +void PSVECScale(register const Vec *src, register Vec *dst, register f32 scale) +{ + // clang-format off + register f32 vxy, vz, rxy, rz; + __asm { + psq_l vxy, 0(src), 0, 0 + psq_l vz, 8(src), 1, 0 + ps_muls0 rxy, vxy, scale + psq_st rxy, 0(dst), 0, 0 + ps_muls0 rz, vz, scale + psq_st rz, 8(dst), 1, 0 + } + // clang-format on +} + +void C_VECNormalize(void) +{ + // UNUSED FUNCTION +} + +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 C_VECSquareMag(void) +{ + // UNUSED FUNCTION +} + +f32 PSVECSquareMag(const Vec *v) +{ + // UNUSED FUNCTION +} + +void C_VECMag(void) +{ + // UNUSED FUNCTION +} + +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; +} + +void C_VECDotProduct(void) +{ + // UNUSED FUNCTION +} + +ASM f32 PSVECDotProduct(register const Vec *a, register const Vec *b) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc; + psq_l f2, 4(a), 0, 0; + psq_l f3, 4(b), 0, 0; + ps_mul f2, f2, f3; + psq_l f5, 0(a), 0, 0; + psq_l f4, 0(b), 0, 0; + ps_madd f3, f5, f4, f2; + ps_sum0 R_RET, f3, f2, f2; + blr +#endif // clang-format on +} + +void C_VECCrossProduct(void) +{ + // UNUSED FUNCTION +} + +ASM void PSVECCrossProduct(const register Vec *vec1, const register Vec *vec2, register Vec *ret) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc; + psq_l fp1, 0(vec2), 0, 0 + lfs fp2, 8(vec1) + psq_l fp0, 0(vec1), 0, 0 + ps_merge10 fp6, fp1, fp1 + lfs fp3, 8(vec2) + ps_mul fp4, fp1, fp2 + ps_muls0 fp7, fp1, fp0 + ps_msub fp5, fp0, fp3, fp4 + ps_msub fp8, fp0, fp6, fp7 + ps_merge11 fp9, fp5, fp5 + ps_merge01 fp10, fp5, fp8 + psq_st fp9, 0(ret), 1, 0 + ps_neg fp10, fp10 + psq_st fp10, 4(ret), 0, 0 + blr; +#endif // clang-format on +} + +void C_VECHalfAngle(void) +{ + // UNUSED FUNCTION +} + +void C_VECReflect(void) +{ + // UNUSED FUNCTION +} + +void C_VECSquareDistance(void) +{ + // UNUSED FUNCTION +} + +f32 PSVECSquareDistance(const Vec *a, const Vec *b) +{ + // UNUSED FUNCTION +} + +void C_VECDistance(void) +{ + // UNUSED FUNCTION +} + +// TODO: cleanup? +ASM f32 PSVECDistance(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; + lfs f3, 0.5f; + + ps_madd f1, f0, f0, f2; + fsubs f0, f3, f3; + ps_sum0 f1, f1, f2, f2; + fcmpu cr0, f0, f1; + beq exit; + lfs f4, 3.0f; + frsqrte f0, f1; + fmuls f2, f0, f0; + fmuls f0, f0, f3; + fnmsubs f2, f2, f1, f4; + fmuls f0, f2, f0; + fmuls R_RET, f1, f0; +exit: + blr +#endif // clang-format on +} \ No newline at end of file diff --git a/libs/dolphin/odenotstub/odenotstub.c b/libs/dolphin/odenotstub/odenotstub.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/os/OS.c b/libs/dolphin/os/OS.c new file mode 100644 index 000000000..ca58c2c5b --- /dev/null +++ b/libs/dolphin/os/OS.c @@ -0,0 +1,678 @@ +#include "dolphin/os.h" +#include "dolphin/DVDPriv.h" +#include "dolphin/db.h" +#include "dolphin/os/OSBootInfo.h" +#include "macros.h" + +extern OSTime __OSGetSystemTime(); +static const char* __OSVersion = + "<< Dolphin SDK - OS\trelease build: Jul 23 2003 11:27:16 (0x2301) >>"; +// needs to be "<< Dolphin SDK - DSP\trelease build: Apr 17 2003 12:34:16 (0x2301) >>"? +extern char _db_stack_end[]; + +#define OS_BI2_DEBUG_ADDRESS 0x800000F4 +#define DEBUGFLAG_ADDR 0x800030E8 +#define OS_DEBUG_ADDRESS_2 0x800030E9 +#define OS_CURRENTCONTEXT_PADDR 0x00C0 + +extern char* __OSResetSWInterruptHandler[]; + +vu16 __OSDeviceCode : (OS_BASE_CACHED | 0x30E6); +static DVDDriveInfo DriveInfo ALIGN(32); +static DVDCommandBlock DriveBlock; + +static OSBootInfo* BootInfo; +static u32* BI2DebugFlag; +static u32* BI2DebugFlagHolder; +DECL_WEAK BOOL __OSIsGcam = FALSE; +static f64 ZeroF; +static f32 ZeroPS[2]; +static BOOL AreWeInitialized = FALSE; +static __OSExceptionHandler* OSExceptionTable; +OSTime __OSStartTime; +BOOL __OSInIPL; + +extern u8 __ArenaHi[]; +extern u8 __ArenaLo[]; +extern u32 __DVDLongFileNameFlag; +extern u32 __PADSpec; + +#define OS_EXCEPTIONTABLE_ADDR 0x3000 +#define OS_DBJUMPPOINT_ADDR 0x60 +// memory locations for important stuff +#define OS_CACHED_REGION_PREFIX 0x8000 +#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 MSR_RI_BIT 0x1E + +void OSDefaultExceptionHandler(__OSException exception, OSContext* context); +extern BOOL __DBIsExceptionMarked(__OSException); +static void OSExceptionInit(void); + +/* clang-format off */ +asm void __OSFPRInit(void) +{ + nofralloc + + mfmsr r3 + ori r3, r3, 0x2000 + mtmsr r3 + + mfspr r3, 0x398 + rlwinm. r3, r3, 3, 31, 31 + beq SkipPairedSingles + + lis r3, ZeroPS@ha + addi r3, r3, ZeroPS@l + psq_l fp0, 0(r3), 0, 0 + ps_mr fp1, fp0 + ps_mr fp2, fp0 + ps_mr fp3, fp0 + ps_mr fp4, fp0 + ps_mr fp5, fp0 + ps_mr fp6, fp0 + ps_mr fp7, fp0 + ps_mr fp8, fp0 + ps_mr fp9, fp0 + ps_mr fp10, fp0 + ps_mr fp11, fp0 + ps_mr fp12, fp0 + ps_mr fp13, fp0 + ps_mr fp14, fp0 + ps_mr fp15, fp0 + ps_mr fp16, fp0 + ps_mr fp17, fp0 + ps_mr fp18, fp0 + ps_mr fp19, fp0 + ps_mr fp20, fp0 + ps_mr fp21, fp0 + ps_mr fp22, fp0 + ps_mr fp23, fp0 + ps_mr fp24, fp0 + ps_mr fp25, fp0 + ps_mr fp26, fp0 + ps_mr fp27, fp0 + ps_mr fp28, fp0 + ps_mr fp29, fp0 + ps_mr fp30, fp0 + ps_mr fp31, fp0 + +SkipPairedSingles: + lfd fp0, ZeroF + fmr fp1, fp0 + fmr fp2, fp0 + fmr fp3, fp0 + fmr fp4, fp0 + fmr fp5, fp0 + fmr fp6, fp0 + fmr fp7, fp0 + fmr fp8, fp0 + fmr fp9, fp0 + fmr fp10, fp0 + fmr fp11, fp0 + fmr fp12, fp0 + fmr fp13, fp0 + fmr fp14, fp0 + fmr fp15, fp0 + fmr fp16, fp0 + fmr fp17, fp0 + fmr fp18, fp0 + fmr fp19, fp0 + fmr fp20, fp0 + fmr fp21, fp0 + fmr fp22, fp0 + fmr fp23, fp0 + fmr fp24, fp0 + fmr fp25, fp0 + fmr fp26, fp0 + fmr fp27, fp0 + fmr fp28, fp0 + fmr fp29, fp0 + fmr fp30, fp0 + fmr fp31, fp0 + + mtfsf 0xFF, fp0 + + blr +} +/* clang-format on */ + +u32 OSGetConsoleType() +{ + if (BootInfo == NULL || BootInfo->consoleType == 0) + { + return OS_CONSOLE_ARTHUR; + } + return BootInfo->consoleType; +} + +void* __OSSavedRegionStart; +void* __OSSavedRegionEnd; + +extern u32 BOOT_REGION_START : 0x812FDFF0; //(*(u32 *)0x812fdff0) +extern u32 BOOT_REGION_END : 0x812FDFEC; //(*(u32 *)0x812fdfec) + +void ClearArena(void) +{ + if ((u32)(OSGetResetCode() + 0x80000000) != 0U) + { + __OSSavedRegionStart = 0U; + __OSSavedRegionEnd = 0U; + memset(OSGetArenaLo(), 0U, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); + return; + } + __OSSavedRegionStart = (void*)BOOT_REGION_START; + __OSSavedRegionEnd = (void*)BOOT_REGION_END; + if (BOOT_REGION_START == 0U) + { + memset(OSGetArenaLo(), 0U, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); + return; + } + + if ((u32)OSGetArenaLo() < (u32)__OSSavedRegionStart) + { + if ((u32)OSGetArenaHi() <= (u32)__OSSavedRegionStart) + { + memset((u32)OSGetArenaLo(), 0U, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); + return; + } + memset(OSGetArenaLo(), 0U, (u32)__OSSavedRegionStart - (u32)OSGetArenaLo()); + if ((u32)OSGetArenaHi() > (u32)__OSSavedRegionEnd) + { + memset((u32)__OSSavedRegionEnd, 0, (u32)OSGetArenaHi() - (u32)__OSSavedRegionEnd); + } + } +} + +static void InquiryCallback(s32 result, DVDCommandBlock* block) +{ + switch (block->state) + { + case 0: + __OSDeviceCode = (u16)(0x8000 | DriveInfo.deviceCode); + break; + default: + __OSDeviceCode = 1; + break; + } +} + +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 + */ + // pretty sure this is the min(/max) amount of pointers etc for the stack to match + BI2Debug* DebugInfo; + void* debugArenaLo; + u32 inputConsoleType; + u32 tdev; + + // check if we've already done all this or not + if ((BOOL)AreWeInitialized == FALSE) + { // fantastic name + AreWeInitialized = TRUE; // flag to make sure we don't have to do this again + + // SYSTEM // + __OSStartTime = __OSGetSystemTime(); + OSDisableInterrupts(); + + // set some PPC things + PPCMtmmcr0(0); + PPCMtmmcr1(0); + PPCMtpmc1(0); + PPCMtpmc2(0); + PPCMtpmc3(0); + PPCMtpmc4(0); + PPCDisableSpeculation(); + PPCSetFpNonIEEEMode(); + + // DEBUG // + // load some DVD stuff + BI2DebugFlag = 0; // debug flag from the DVD BI2 header + BootInfo = (OSBootInfo*)OS_BASE_CACHED; // set pointer to BootInfo + + __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 the debug info address exists, grab some debug info + 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->arenaHi) + { // if the top of the heap is already set + 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 + } + + __DVDLongFileNameFlag = 1; // we made it through debug! + + // HEAP // + // set up bottom of heap (ArenaLo) + // grab address from BootInfo if it exists, otherwise use default __ArenaLo + OSSetArenaLo((BootInfo->arenaLo == NULL) ? __ArenaLo : BootInfo->arenaLo); + + // 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->arenaLo == NULL) && (BI2DebugFlag != 0) && (*BI2DebugFlag < 2)) + { + debugArenaLo = (char*)(((u32)_db_stack_end + 0x1f) & ~0x1f); + OSSetArenaLo(debugArenaLo); + } + + // set up top of heap (ArenaHi) + // grab address from BootInfo if it exists, otherwise use default __ArenaHi + OSSetArenaHi((BootInfo->arenaHi == NULL) ? __ArenaHi : BootInfo->arenaHi); + + // OS INIT AND REPORT // + // initialise a whole bunch of OS stuff + OSExceptionInit(); + __OSInitSystemCall(); + OSInitAlarm(); + __OSModuleInit(); + __OSInterruptInit(); + __OSSetInterruptHandler(__OS_INTERRUPT_PI_RSW, (void*)__OSResetSWInterruptHandler); + __OSContextInit(); + __OSCacheInit(); + EXIInit(); + SIInit(); + __OSInitSram(); + __OSThreadInit(); + __OSInitAudioSystem(); + PPCMthid2(PPCMfhid2() & 0xBFFFFFFF); + if ((BOOL)__OSInIPL == FALSE) + { + __OSInitMemoryProtection(); + } + + // begin OS reporting + OSReport("\nDolphin OS\n"); + OSReport("Kernel built : %s %s\n", "Jul 23 2003", "11:27:16"); + OSReport("Console Type : "); + + // this is a function in the same file, but it doesn't seem to match + // inputConsoleType = OSGetConsoleType(); + + // inputConsoleType = (BootInfo == NULL || (inputConsoleType = BootInfo->consoleType) == 0) ? 0x10000002 : BootInfo->consoleType; + if (BootInfo == NULL || (inputConsoleType = BootInfo->consoleType) == 0) + { + inputConsoleType = OS_CONSOLE_ARTHUR; // default console type + } + else + { + inputConsoleType = BootInfo->consoleType; + } + + // work out what console type this corresponds to and report it + // consoleTypeSwitchHi = inputConsoleType & 0xF0000000; + switch (inputConsoleType & 0xF0000000) + { // check "first" byte + case OS_CONSOLE_RETAIL: + OSReport("Retail %d\n", inputConsoleType); + break; + case OS_CONSOLE_DEVELOPMENT: + case OS_CONSOLE_TDEV: + // consoleTypeSwitchLo = (inputConsoleType & 0x0FFFFFFF); + switch (inputConsoleType & 0x0FFFFFFF) + { // if "first" byte is 2, check "the rest" + case OS_CONSOLE_EMULATOR: + OSReport("Mac Emulator\n"); + break; + case OS_CONSOLE_PC_EMULATOR: + OSReport("PC Emulator\n"); + break; + case OS_CONSOLE_ARTHUR: + OSReport("EPPC Arthur\n"); + break; + case OS_CONSOLE_MINNOW: + OSReport("EPPC Minnow\n"); + break; + default: // if none of the above, just report the info we have + tdev = (u32)inputConsoleType & 0x0FFFFFFF; + OSReport("Development HW%d (%08x)\n", tdev - 3, inputConsoleType); + break; + } + break; + default: // if none of the above, just report the info we have + OSReport("%08x\n", inputConsoleType); + break; + } + + // report memory size + OSReport("Memory %d MB\n", (u32)BootInfo->memorySize >> 0x14U); + // report heap bounds + OSReport("Arena : 0x%x - 0x%x\n", OSGetArenaLo(), OSGetArenaHi()); + // report OS version + OSRegisterVersion(__OSVersion); + + // if location of debug flag exists, and flag is >= 2, enable MetroTRKInterrupts + if (BI2DebugFlag && ((*BI2DebugFlag) >= 2)) + { + EnableMetroTRKInterrupts(); + } + + // free up memory and re-enable things + ClearArena(); + OSEnableInterrupts(); + + // check if we can load OS from IPL; if not, grab it from DVD (?) + if ((BOOL)__OSInIPL == FALSE) + { + DVDInit(); + if ((BOOL)__OSIsGcam) + { + __OSDeviceCode = 0x9000; + return; + } + DCInvalidateRange(&DriveInfo, sizeof(DriveInfo)); + DVDInquiryAsync(&DriveBlock, &DriveInfo, InquiryCallback); + } + } +} + +static u32 __OSExceptionLocations[] = { + 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 __OSEVEnd(void); +void __OSEVSetNumber(void); +void __OSExceptionVector(void); + +void __DBVECTOR(void); +void __OSDBINTSTART(void); +void __OSDBINTEND(void); +void __OSDBJUMPSTART(void); +void __OSDBJUMPEND(void); + +#define NOP 0x60000000 + +__OSExceptionHandler __OSSetExceptionHandler(__OSException exception, __OSExceptionHandler handler); + +/* + * --INFO-- + * Address: 800EB654 + * Size: 000280 + */ +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; + + // 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 + { + DBPrintf("Installing OSDBIntegrator\n"); + memcpy(destAddr, (void*)__OSDBINTSTART, (u32)__OSDBINTEND - (u32)__OSDBINTSTART); + DCFlushRangeNoSync(destAddr, (u32)__OSDBINTEND - (u32)__OSDBINTSTART); + __sync(); + ICInvalidateRange(destAddr, (u32)__OSDBINTEND - (u32)__OSDBINTSTART); + } + + // Copy the right vector into the table + 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); + } + 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); + DCFlushRangeNoSync(destAddr, handlerSize); + __sync(); + ICInvalidateRange(destAddr, handlerSize); + } + + // initialize pointer to exception table + OSExceptionTable = OSPhysicalToCached(OS_EXCEPTIONTABLE_ADDR); + + // install default exception handlers + 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"); +} + +static asm void __OSDBIntegrator(void) +{ + /* clang-format off */ + nofralloc +entry __OSDBINTSTART + 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 */ +} + +static asm void __OSDBJump(void){ + /* clang-format off */ + + nofralloc +entry __OSDBJUMPSTART + bla OS_DBJUMPPOINT_ADDR +entry __OSDBJUMPEND + /* clang-format on */ + +} + +__OSExceptionHandler __OSSetExceptionHandler(__OSException exception, __OSExceptionHandler handler) +{ + __OSExceptionHandler oldHandler; + oldHandler = OSExceptionTable[exception]; + OSExceptionTable[exception] = handler; + return oldHandler; +} + +__OSExceptionHandler __OSGetExceptionHandler(__OSException exception) +{ + return OSExceptionTable[exception]; +} + +static asm void OSExceptionVector(void) +{ + /* clang-format off */ + nofralloc + +entry __OSEVStart + // Save r4 into SPRG0 + mtsprg 0, r4 + + // Load current context physical address into r4 + 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) + + 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 + +entry __DBVECTOR + nop + + // Set SRR1[IR|DR] to turn on address + // translation at the next RFI + mfmsr r3 + ori r3, r3, 0x30 + mtsrr1 r3 + + // This lets us change the exception number based on the + // exception we're installing. +entry __OSEVSetNumber + addi r3, 0, 0x0000 + + // Load current context virtual address into r4 + lwz r4, 0xD4 + + // Check non-recoverable interrupt + rlwinm. r5, r5, 0, MSR_RI_BIT, MSR_RI_BIT + 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, 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 enalbed, not yet recoverable + + rfi + // NOT REACHED HERE + // The handler will restore state + +entry __OSEVEnd + nop + /* clang-format on */ +} + +void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar); +asm void OSDefaultExceptionHandler(register __OSException exception, register OSContext* context) +{ + /* clang-format off */ + nofralloc + OS_EXCEPTION_SAVE_GPRS(context) + mfdsisr r5 + mfdar r6 + + stwu r1,-8(r1) + b __OSUnhandledException + /* clang-foramt on */ +} + +void __OSPSInit(void) +{ + PPCMthid2(PPCMfhid2() | 0xA0000000); + ICFlashInvalidate(); + __sync(); + // clang-format off + 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 + } + // clang-format on +} + +#define DI_CONFIG_IDX 0x9 +#define DI_CONFIG_CONFIG_MASK 0xFF +u32 __OSGetDIConfig(void) +{ + return (__DIRegs[DI_CONFIG_IDX] & DI_CONFIG_CONFIG_MASK); +} + +void OSRegisterVersion(const char* id) +{ + OSReport("%s\n", id); +} diff --git a/libs/dolphin/os/OSAlarm.c b/libs/dolphin/os/OSAlarm.c new file mode 100644 index 000000000..c384f40b7 --- /dev/null +++ b/libs/dolphin/os/OSAlarm.c @@ -0,0 +1,254 @@ +#include "dolphin/base/PPCArch.h" +#include "dolphin/os/OSPriv.h" +#include "dolphin/os/OSReset.h" + +static struct OSAlarmQueue +{ + OSAlarm *head; + OSAlarm *tail; +} AlarmQueue; + +static void DecrementerExceptionHandler(__OSException exception, OSContext *context); +static BOOL OnReset(BOOL final); + +static OSResetFunctionInfo ResetFunctionInfo = {OnReset, 0xFFFFFFFF}; + +static void SetTimer(OSAlarm *alarm) +{ + OSTime delta; + + delta = alarm->fire - __OSGetSystemTime(); + if (delta < 0) + { + PPCMtdec(0); + } + else if (delta < 0x80000000) + { + PPCMtdec((u32)delta); + } + else + { + PPCMtdec(0x7fffffff); + } +} + +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) + { + OSTime time = __OSGetSystemTime(); + + fire = alarm->start; + if (alarm->start < time) + { + fire += alarm->period * ((time - alarm->start) / alarm->period + 1); + } + } + + alarm->handler = handler; + 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; + if (prev) + { + prev->next = alarm; + } + else + { + AlarmQueue.head = alarm; + SetTimer(alarm); + } + return; + } + alarm->next = 0; + prev = AlarmQueue.tail; + AlarmQueue.tail = alarm; + alarm->prev = prev; + if (prev) + { + prev->next = alarm; + } + else + { + AlarmQueue.head = AlarmQueue.tail = alarm; + SetTimer(alarm); + } +} + +void OSSetAlarm(OSAlarm *alarm, OSTime tick, OSAlarmHandler handler) +{ + BOOL enabled; + enabled = OSDisableInterrupts(); + alarm->period = 0; + InsertAlarm(alarm, __OSGetSystemTime() + tick, handler); + OSRestoreInterrupts(enabled); +} + +void OSSetPeriodicAlarm(OSAlarm *alarm, OSTime start, OSTime period, OSAlarmHandler handler) +{ + BOOL enabled; + enabled = OSDisableInterrupts(); + alarm->period = period; + alarm->start = __OSTimeToSystemTime(start); + InsertAlarm(alarm, 0, handler); + OSRestoreInterrupts(enabled); +} + +void OSCancelAlarm(OSAlarm *alarm) +{ + OSAlarm *next; + BOOL enabled; + + enabled = OSDisableInterrupts(); + + if (alarm->handler == 0) + { + OSRestoreInterrupts(enabled); + return; + } + + next = alarm->next; + if (next == 0) + { + AlarmQueue.tail = alarm->prev; + } + else + { + next->prev = alarm->prev; + } + if (alarm->prev) + { + alarm->prev->next = next; + } + else + { + AlarmQueue.head = next; + if (next) + { + SetTimer(next); + } + } + alarm->handler = 0; + + OSRestoreInterrupts(enabled); +} + +static void DecrementerExceptionCallback(register __OSException exception, + register OSContext *context) +{ + OSAlarm *alarm; + OSAlarm *next; + OSAlarmHandler handler; + OSTime time; + OSContext exceptionContext; + time = __OSGetSystemTime(); + alarm = AlarmQueue.head; + if (alarm == 0) + { + OSLoadContext(context); + } + + if (time < alarm->fire) + { + SetTimer(alarm); + OSLoadContext(context); + } + + next = alarm->next; + AlarmQueue.head = next; + if (next == 0) + { + AlarmQueue.tail = 0; + } + else + { + next->prev = 0; + } + + handler = alarm->handler; + alarm->handler = 0; + if (0 < alarm->period) + { + InsertAlarm(alarm, 0, handler); + } + + if (AlarmQueue.head) + { + SetTimer(AlarmQueue.head); + } + + OSDisableScheduler(); + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + handler(alarm, context); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + OSEnableScheduler(); + __OSReschedule(); + OSLoadContext(context); +} + +static asm void DecrementerExceptionHandler(register __OSException exception, + register OSContext *context) +{ + // clang-format off + nofralloc + OS_EXCEPTION_SAVE_GPRS(context) + stwu r1, -8(r1) + b DecrementerExceptionCallback + // clang-format on +} + +static BOOL OnReset(BOOL final) +{ + OSAlarm *alarm; + OSAlarm *next; + + if (final) + { + alarm = AlarmQueue.head; + next = (alarm) ? alarm->next : NULL; + + while (alarm != NULL) + { + if (__DVDTestAlarm(alarm) == FALSE) + { + OSCancelAlarm(alarm); + } + + alarm = next; + next = (alarm) ? alarm->next : NULL; + } + } + + return TRUE; +} diff --git a/libs/dolphin/os/OSAlloc.c b/libs/dolphin/os/OSAlloc.c new file mode 100644 index 000000000..bb2898e7a --- /dev/null +++ b/libs/dolphin/os/OSAlloc.c @@ -0,0 +1,228 @@ +#include "types.h" +#include + +typedef struct HeapCell +{ + struct HeapCell *prev; + struct HeapCell *next; + u32 size; +} HeapCell; + +typedef struct Heap +{ + s32 size; + struct HeapCell *free; // linked list of free cells + struct HeapCell *allocated; // linked list of allocated cells +} Heap; + +void *ArenaEnd; +void *ArenaStart; +int NumHeaps; +struct Heap *HeapArray; +volatile OSHeapHandle __OSCurrHeap = -1; + +#define InRange(addr, start, end) ((u8 *)(start) <= (u8 *)(addr) && (u8 *)(addr) < (u8 *)(end)) +#define OFFSET(addr, align) (((u32)(addr) & ((align)-1))) + +#define ALIGNMENT 32 +#define MINOBJSIZE 64 + +static inline void *DLAddFront(struct HeapCell *neighbor, struct HeapCell *cell) +{ + cell->next = neighbor; + cell->prev = NULL; + if (neighbor != NULL) + neighbor->prev = cell; + return cell; +} + +void DLLookup(void) +{ + // UNUSED FUNCTION +} + +// removes 'cell' from 'list' and returns 'list' +static inline HeapCell *DLExtract(struct HeapCell *list, struct HeapCell *cell) +{ + if (cell->next != NULL) + cell->next->prev = cell->prev; + if (cell->prev == NULL) + list = cell->next; + else + cell->prev->next = cell->next; + return list; +} + +static HeapCell *DLInsert(HeapCell *list, HeapCell *cell, void *unused /* needed to match OSFreeToHeap */) +{ + HeapCell *before = NULL; + HeapCell *after = list; + + while (after != NULL) + { + if (cell <= after) + break; + before = after; + after = after->next; + } + cell->next = after; + cell->prev = before; + if (after != NULL) + { + after->prev = cell; + if ((u8 *)cell + cell->size == (u8 *)after) + { + cell->size += after->size; + after = after->next; + cell->next = after; + if (after != NULL) + after->prev = cell; + } + } + if (before != NULL) + { + before->next = cell; + if ((u8 *)before + before->size == (u8 *)cell) + { + before->size += cell->size; + before->next = after; + if (after != NULL) + after->prev = before; + } + return list; + } + return cell; +} + +void DLOverlap(void) +{ + // UNUSED FUNCTION +} + +void DLSize(void) +{ + // UNUSED FUNCTION +} + +void *OSAllocFromHeap(OSHeapHandle heap, u32 size) +{ + struct Heap *hd = &HeapArray[heap]; + s32 sizeAligned = OSRoundUp32B(ALIGNMENT + size); + struct HeapCell *cell; + struct HeapCell *oldTail; + u32 leftoverSpace; + + // find first cell with enough capacity + for (cell = hd->free; cell != NULL; cell = cell->next) + { + if (sizeAligned <= (s32)cell->size) + break; + } + if (cell == NULL) + return NULL; + + leftoverSpace = cell->size - sizeAligned; + if (leftoverSpace < MINOBJSIZE) + { + // remove this cell from the free list + hd->free = DLExtract(hd->free, cell); + } + else + { + // remove this cell from the free list and make a new cell out of the + // remaining space + struct HeapCell *newcell = (void *)((u8 *)cell + sizeAligned); + cell->size = sizeAligned; + newcell->size = leftoverSpace; + 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 + hd->free = newcell; + } + + // add the cell to the beginning of the allocated list + hd->allocated = DLAddFront(hd->allocated, cell); + + return (u8 *)cell + ALIGNMENT; +} + +void OSFreeToHeap(OSHeapHandle heap, void *ptr) +{ + HeapCell *cell = (void *)((u8 *)ptr - ALIGNMENT); + Heap *hd = &HeapArray[heap]; + HeapCell *list = hd->allocated; + + // remove cell from the allocated list + // hd->allocated = DLExtract(hd->allocated, cell); + if (cell->next != NULL) + cell->next->prev = cell->prev; + if (cell->prev == NULL) + list = cell->next; + else + cell->prev->next = cell->next; + hd->allocated = list; + hd->free = DLInsert(hd->free, cell, list); +} + +OSHeapHandle OSSetCurrentHeap(OSHeapHandle heap) +{ + OSHeapHandle old = __OSCurrHeap; + + __OSCurrHeap = heap; + return old; +} + +void *OSInitAlloc(void *arenaStart, void *arenaEnd, int maxHeaps) +{ + u32 totalSize = maxHeaps * sizeof(struct Heap); + int i; + + HeapArray = arenaStart; + NumHeaps = maxHeaps; + + for (i = 0; i < NumHeaps; i++) + { + Heap *heap = &HeapArray[i]; + + heap->size = -1; + heap->free = heap->allocated = NULL; + } + + __OSCurrHeap = -1; + + arenaStart = (u8 *)HeapArray + totalSize; + arenaStart = (void *)OSRoundUp32B(arenaStart); + + ArenaStart = arenaStart; + ArenaEnd = (void *)OSRoundDown32B(arenaEnd); + + return arenaStart; +} + +OSHeapHandle OSCreateHeap(void *start, void *end) +{ + int i; + HeapCell *cell = (void *)OSRoundUp32B(start); + + end = (void *)OSRoundDown32B(end); + for (i = 0; i < NumHeaps; i++) + { + Heap *hd = &HeapArray[i]; + + if (hd->size < 0) + { + hd->size = (u8 *)end - (u8 *)cell; + cell->prev = NULL; + cell->next = NULL; + cell->size = hd->size; + hd->free = cell; + hd->allocated = NULL; + return i; + } + } + return -1; +} diff --git a/libs/dolphin/os/OSArena.c b/libs/dolphin/os/OSArena.c new file mode 100644 index 000000000..97e7ede95 --- /dev/null +++ b/libs/dolphin/os/OSArena.c @@ -0,0 +1,41 @@ +#include + +#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) +#define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) + +void *__OSArenaHi; +void *__OSArenaLo = (void *)-1; + +void *OSGetArenaHi(void) { return __OSArenaHi; } + +void *OSGetArenaLo(void) { return __OSArenaLo; } + +void OSSetArenaHi(void *addr) { __OSArenaHi = addr; } + +void OSSetArenaLo(void *addr) { __OSArenaLo = addr; } + +void *OSAllocFromArenaLo(u32 size, u32 align) +{ + void *ptr; + u8 *arenaLo; + + 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; +} \ No newline at end of file diff --git a/libs/dolphin/os/OSAudioSystem.c b/libs/dolphin/os/OSAudioSystem.c new file mode 100644 index 000000000..c88cfa1c3 --- /dev/null +++ b/libs/dolphin/os/OSAudioSystem.c @@ -0,0 +1,114 @@ +#include "types.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static u8 DSPInitCode[128] = { + // clang-format off + 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, + 0x12, 0x06, 0x12, 0x03, 0x12, 0x04, 0x12, 0x05, 0x00, 0x80, 0x80, 0x00, 0x00, 0x88, 0xFF, 0xFF, + 0x00, 0x84, 0x10, 0x00, 0x00, 0x64, 0x00, 0x1D, 0x02, 0x18, 0x00, 0x00, 0x81, 0x00, 0x1C, 0x1E, + 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, + // clang-format on +}; + +#define __DSPWorkBuffer (void*)0x81000000 + +void __OSInitAudioSystem(void) { + u32 r28; + u16 r3; + + u32 padding; + + memcpy((void*)((u8*)OSGetArenaHi() - 128), __DSPWorkBuffer, 128); + memcpy(__DSPWorkBuffer, (void*)DSPInitCode, 128); + + DCFlushRange(__DSPWorkBuffer, 128); + + __DSPRegs[9] = 0x43; + __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; + + r28 = OSGetTick(); + while ((s32)(OSGetTick() - r28) < 0x892) + ; + + *(u32*)&__DSPRegs[16] = 0x1000000; + *(u32*)&__DSPRegs[18] = 0; + *(u32*)&__DSPRegs[20] = 0x20; + + r3 = __DSPRegs[5]; + while (!(r3 & 0x20)) + r3 = __DSPRegs[5]; + __DSPRegs[5] = r3; + + __DSPRegs[5] &= ~0x800; + while ((__DSPRegs[5]) & 0x400) + ; + __DSPRegs[5] &= ~4; + + r3 = __DSPRegs[2]; + + while (!(r3 & 0x8000)) + r3 = __DSPRegs[2]; + + (void)__DSPRegs[3]; + r3 != 42069; + __DSPRegs[5] |= 4; + __DSPRegs[5] = 0x8AC; + __DSPRegs[5] |= 1; + while (__DSPRegs[5] & 1) + ; + memcpy(__DSPWorkBuffer, (void*)((u8*)OSGetArenaHi() - 128), 128); +} + +void __OSStopAudioSystem(void) { + u32 r28; + +#define waitUntil(load, mask) \ + r28 = (load); \ + while (r28 & (mask)) { \ + r28 = (load); \ + } + + __DSPRegs[5] = 0x804; + r28 = __DSPRegs[27]; + __DSPRegs[27] = r28 & ~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; + waitUntil(__DSPRegs[5], 0x001); + +#undef waitUntil +} + +#ifdef __cplusplus +} +#endif diff --git a/libs/dolphin/os/OSCache.c b/libs/dolphin/os/OSCache.c new file mode 100644 index 000000000..2cec4d3dd --- /dev/null +++ b/libs/dolphin/os/OSCache.c @@ -0,0 +1,426 @@ +#include "dolphin/base/PPCArch.h" +#include "dolphin/os.h" + +// Can't use this due to weird condition register issues +//#include "asm_types.h" +#define HID2 920 + +#include "dolphin/db.h" + +/* clang-format off */ +asm void DCEnable() { + nofralloc + sync + mfspr r3, HID0 + ori r3, r3, 0x4000 + mtspr HID0, r3 + 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 + +@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, 31 + srwi nBytes, nBytes, 5 + mtctr nBytes + +@1 + dcbf r0, addr + addi addr, addr, 32 + bdnz @1 + sc + blr +} + +asm void DCStoreRange(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 + sc + + blr +} + +asm void DCFlushRangeNoSync(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 + 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 +} + +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 ICInvalidateRange(register void* addr, register u32 nBytes) { + nofralloc + nofralloc + cmplwi nBytes, 0 + blelr + clrlwi r5, addr, 27 + add nBytes, nBytes, r5 + addi nBytes, nBytes, 31 + srwi nBytes, nBytes, 5 + mtctr nBytes + +@1 + icbi r0, addr + addi addr, addr, 32 + bdnz @1 + sync + isync + + blr +} + + +asm void ICFlashInvalidate() { + nofralloc + mfspr r3, HID0 + ori r3, r3, 0x800 + mtspr HID0, r3 + blr +} + +asm void ICEnable() { + nofralloc + isync + mfspr r3, HID0 + ori r3, r3, 0x8000 + mtspr HID0, r3 + blr +} + +#define LC_LINES 512 +#define CACHE_LINES 1024 + +asm void __LCEnable() { + 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 + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + blr +} + +void LCEnable() { + BOOL enabled; + + enabled = OSDisableInterrupts(); + __LCEnable(); + OSRestoreInterrupts(enabled); +} + + +asm void LCDisable() { + nofralloc + lis r3, LC_BASE_PREFIX + li r4, LC_LINES + mtctr r4 +@1 + dcbi r0, r3 + addi r3, r3, 32 + bdnz @1 + mfspr r4, HID2 + rlwinm r4, r4, 0, 4, 2 + mtspr HID2, r4 + 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 +} + +/* clang-format on */ + +u32 LCLoadData(register void* destAddr, register void* srcAddr, register u32 nBytes) { + u32 numBlocks = (nBytes + 31) / 32; + u32 numTransactions = (numBlocks + 128 - 1) / 128; + + while (numBlocks > 0) { + if (numBlocks < 128) { + LCLoadBlocks(destAddr, srcAddr, numBlocks); + numBlocks = 0; + } else { + LCLoadBlocks(destAddr, srcAddr, 0); + numBlocks -= 128; + destAddr = (void*)((u32)destAddr + 4096); + srcAddr = (void*)((u32)srcAddr + 4096); + } + } + + return numTransactions; +} +u32 LCStoreData(void* destAddr, void* srcAddr, u32 nBytes) { + u32 numBlocks = (nBytes + 31) / 32; + u32 numTransactions = (numBlocks + 128 - 1) / 128; + + 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; +} + +/* clang-format off */ +asm u32 LCQueueLength() { + nofralloc + mfspr r4, HID2 + rlwinm r3, r4, 8, 28, 31 + blr +} + +asm void LCQueueWait(register u32 len) { + nofralloc +wait: + mfspr r4, HID2 + rlwinm r4, r4, 8, 28, 31 + cmpw r4, r3 + bgt wait + blr +} + +/* clang-format on */ +static void L2Disable(void) { + __sync(); + PPCMtl2cr(PPCMfl2cr() & ~0x80000000); + __sync(); +} + +void L2GlobalInvalidate(void) { + L2Disable(); + PPCMtl2cr(PPCMfl2cr() | 0x00200000); + while (PPCMfl2cr() & 0x00000001u) + ; + PPCMtl2cr(PPCMfl2cr() & ~0x00200000); + while (PPCMfl2cr() & 0x00000001u) { + DBPrintf(">>> L2 INVALIDATE : SHOULD NEVER HAPPEN\n"); + } +} + +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 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)) { + OSReport("Machine check was not DMA/locked cache related\n"); + OSDumpContext(context); + PPCHalt(); + } + + OSReport("DMAErrorHandler(): An error occurred while processing DMA.\n"); + OSReport("The following errors have been detected and cleared :\n"); + + if (hid2 & HID2_DCHERR) { + OSReport("\t- Requested a locked cache tag that was already in the cache\n"); + } + + if (hid2 & HID2_DNCERR) { + OSReport("\t- DMA attempted to access normal cache\n"); + } + + if (hid2 & HID2_DCMERR) { + OSReport("\t- DMA missed in data cache\n"); + } + + if (hid2 & HID2_DQOERR) { + OSReport("\t- DMA queue overflowed\n"); + } + + // write hid2 back to clear the error bits + PPCMthid2(hid2); +} + +void __OSCacheInit() { + if (!(PPCMfhid0() & HID0_ICE)) { + ICEnable(); + DBPrintf("L1 i-caches initialized\n"); + } + if (!(PPCMfhid0() & HID0_DCE)) { + DCEnable(); + DBPrintf("L1 d-caches initialized\n"); + } + + if (!(PPCMfl2cr() & L2CR_L2E)) { + L2Init(); + L2Enable(); + DBPrintf("L2 cache initialized\n"); + } + + OSSetErrorHandler(OS_ERROR_MACHINE_CHECK, DMAErrorHandler); + DBPrintf("Locked cache machine check handler installed\n"); +} diff --git a/libs/dolphin/os/OSContext.c b/libs/dolphin/os/OSContext.c new file mode 100644 index 000000000..f8aae0446 --- /dev/null +++ b/libs/dolphin/os/OSContext.c @@ -0,0 +1,637 @@ +#include +#include + +#define HID2 920 + +volatile OSContext* __OSCurrentContext : (OS_BASE_CACHED | 0x00D4); +volatile OSContext* __OSFPUContext : (OS_BASE_CACHED | 0x00D8); + +static asm void __OSLoadFPUContext(register u32, register OSContext* fpuContext) { + // clang-format off + nofralloc + lhz r5, fpuContext->state; + clrlwi. r5, r5, 31 + beq _return + + lfd fp0, OS_CONTEXT_FPSCR(fpuContext) + mtfsf 0xFF, fp0 + mfspr r5, HID2 + rlwinm. r5, r5, 3, 31, 31 + beq _regular_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 + +_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 +} + +static asm void __OSSaveFPUContext(register u32, register u32, register OSContext* fpuContext) { + // clang-format off + nofralloc + + lhz r3, fpuContext->state + ori r3, r3, 1 + sth r3, fpuContext->state + + 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 fp0 + stfd fp0, OS_CONTEXT_FPSCR(fpuContext) + + lfd fp0, fpuContext->fpr[0] + + 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 +} + +asm void OSLoadFPUContext(register OSContext* fpuContext) { + // clang-format off + nofralloc + addi r4, fpuContext, 0 + b __OSLoadFPUContext + // clang-format on +} + +asm void OSSaveFPUContext(register OSContext* fpuContext) { + // clang-format off + nofralloc + addi r5, fpuContext, 0 + b __OSSaveFPUContext + // clang-format on +} + +asm void OSSetCurrentContext(register OSContext* context){ + // clang-format off + nofralloc + + 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 + +_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 +} + +OSContext* OSGetCurrentContext(void) { + return (OSContext*)__OSCurrentContext; +} + +asm u32 OSSaveContext(register OSContext* context) { + // clang-format off + nofralloc + 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 +} + +extern void __RAS_OSDisableInterrupts_begin(); +extern void __RAS_OSDisableInterrupts_end(); + +asm void OSLoadContext(register OSContext* context) { + // clang-format off + nofralloc + + 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 +} + +asm u32 OSGetStackPointer() { + // clang-format off + nofralloc + mr r3, r1 + blr + // clang-format on +} + +asm u32 OSSwitchStack(register u32 newsp) { + // clang-format off + nofralloc + mr r5, r1 + mr r1, newsp + mr r3, r5 + blr + // clang-format on +} + +asm int OSSwitchFiber(register u32 pc, register u32 newsp) { + // clang-format off + 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 + // clang-format on +} + +void OSClearContext(register OSContext* context) { + context->mode = 0; + context->state = 0; + if (context == __OSFPUContext) + __OSFPUContext = NULL; +} + +asm void OSInitContext(register OSContext* context, register u32 pc, register u32 newsp) { + // clang-format off + 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 + // clang-format on +} + +void OSDumpContext(OSContext* context) { + u32 i; + u32* p; + + OSReport("------------------------- Context 0x%08x -------------------------\n", 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]); + } + + OSReport("LR = 0x%08x CR = 0x%08x\n", context->lr, context->cr); + OSReport("SRR0 = 0x%08x SRR1 = 0x%08x\n", context->srr0, context->srr1); + + 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]); + } + + if (context->state & OS_CONTEXT_STATE_FPSAVED) { + OSContext* currentContext; + OSContext fpuContext; + BOOL enabled; + + enabled = OSDisableInterrupts(); + 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]); + } + 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->psf[i], i + 1, + (u32)context->psf[i + 1]); + } + + OSClearContext(&fpuContext); + OSSetCurrentContext(currentContext); + OSRestoreInterrupts(enabled); + } + + OSReport("\nAddress: Back Chain LR Save\n"); + for (i = 0, p = (u32*)context->gpr[1]; p && (u32)p != 0xffffffff && i++ < 16; p = (u32*)*p) { + OSReport("0x%08x: 0x%08x 0x%08x\n", p, p[0], p[1]); + } +} + +static asm void OSSwitchFPUContext(register __OSException exception, register OSContext* context) { + // clang-format off + nofralloc + mfmsr r5 + ori r5, r5, 0x2000 + mtmsr r5 + isync + 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 +} + +void __OSContextInit(void) { + __OSSetExceptionHandler(__OS_EXCEPTION_FLOATING_POINT, OSSwitchFPUContext); + __OSFPUContext = NULL; + DBPrintf("FPU-unavailable handler installed\n"); +} + +asm void OSFillFPUContext(register OSContext *context) +{ + // clang-format off + nofralloc + mfmsr r5 + ori r5, r5, 0x2000 + mtmsr r5 + + isync + stfd f0, 0x90(r3) + stfd f1, 0x98(r3) + stfd f2, 0xA0(r3) + stfd f3, 0xA8(r3) + stfd f4, 0xB0(r3) + stfd f5, 0xB8(r3) + stfd f6, 0xC0(r3) + stfd f7, 0xC8(r3) + stfd f8, 0xD0(r3) + stfd f9, 0xD8(r3) + stfd f10, 0xE0(r3) + stfd f11, 0xE8(r3) + stfd f12, 0xF0(r3) + stfd f13, 0xF8(r3) + stfd f14, 0x100(r3) + stfd f15, 0x108(r3) + stfd f16, 0x110(r3) + stfd f17, 0x118(r3) + stfd f18, 0x120(r3) + stfd f19, 0x128(r3) + stfd f20, 0x130(r3) + stfd f21, 0x138(r3) + stfd f22, 0x140(r3) + stfd f23, 0x148(r3) + stfd f24, 0x150(r3) + stfd f25, 0x158(r3) + stfd f26, 0x160(r3) + stfd f27, 0x168(r3) + stfd f28, 0x170(r3) + stfd f29, 0x178(r3) + stfd f30, 0x180(r3) + stfd f31, 0x188(r3) + mffs f0 + stfd f0, 0x190(r3) + lfd f0, 0x90(r3) + + mfspr r5, 0x398 + rlwinm. r5,r5,3,31,31 + beq- _return + + psq_st f0,0x1C8(r3),0,0 + psq_st f1,0x1D0(r3),0,0 + psq_st f2,0x1D8(r3),0,0 + psq_st f3,0x1E0(r3),0,0 + psq_st f4,0x1E8(r3),0,0 + psq_st f5,0x1F0(r3),0,0 + psq_st f6,0x1F8(r3),0,0 + psq_st f7,0x200(r3),0,0 + psq_st f8,0x208(r3),0,0 + psq_st f9,0x210(r3),0,0 + psq_st f10,0x218(r3),0,0 + psq_st f11,0x220(r3),0,0 + psq_st f12,0x228(r3),0,0 + psq_st f13,0x230(r3),0,0 + psq_st f14,0x238(r3),0,0 + psq_st f15,0x240(r3),0,0 + psq_st f16,0x248(r3),0,0 + psq_st f17,0x250(r3),0,0 + psq_st f18,0x258(r3),0,0 + psq_st f19,0x260(r3),0,0 + psq_st f20,0x268(r3),0,0 + psq_st f21,0x270(r3),0,0 + psq_st f22,0x278(r3),0,0 + psq_st f23,0x280(r3),0,0 + psq_st f24,0x288(r3),0,0 + psq_st f25,0x290(r3),0,0 + psq_st f26,0x298(r3),0,0 + psq_st f27,0x2A0(r3),0,0 + psq_st f28,0x2A8(r3),0,0 + psq_st f29,0x2B0(r3),0,0 + psq_st f30,0x2B8(r3),0,0 + psq_st f31,0x2C0(r3),0,0 + +_return: + blr + // clang-format on +} \ No newline at end of file diff --git a/libs/dolphin/os/OSError.c b/libs/dolphin/os/OSError.c new file mode 100644 index 000000000..b7091c98f --- /dev/null +++ b/libs/dolphin/os/OSError.c @@ -0,0 +1,205 @@ +#include +#include +#include +#include + +OSThread* __OSCurrentThread : (OS_BASE_CACHED | 0x00E4); +OSThreadQueue __OSActiveThreadQueue : (OS_BASE_CACHED | 0x00DC); +volatile OSContext* __OSFPUContext : (OS_BASE_CACHED | 0x00D8); + +OSErrorHandler __OSErrorTable[OS_ERROR_MAX]; +#define FPSCR_ENABLE (FPSCR_VE | FPSCR_OE | FPSCR_UE | FPSCR_ZE | FPSCR_XE) +u32 __OSFpscrEnableBits = FPSCR_ENABLE; + +__declspec(weak) void OSReport(const char* msg, ...) { + va_list args; + va_start(args, msg); + vprintf(msg, args); + va_end(args); +} + +__declspec(weak) void OSVReport(const char* msg, va_list list) { vprintf(msg, list); } + +__declspec(weak) void OSPanic(const char* file, int line, const char* msg, ...) { + va_list marker; + u32 i; + u32* p; + + OSDisableInterrupts(); + va_start(marker, msg); + vprintf(msg, marker); + va_end(marker); + OSReport(" in \"%s\" on line %d.\n", file, line); + + OSReport("\nAddress: Back Chain LR Save\n"); + 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(); +} + +OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler) { + OSErrorHandler oldHandler; + BOOL enabled; + + enabled = OSDisableInterrupts(); + oldHandler = __OSErrorTable[error]; + __OSErrorTable[error] = handler; + + if (error == OS_ERROR_FPE) { + u32 msr; + u32 fpscr; + OSThread* thread; + + msr = PPCMfmsr(); + PPCMtmsr(msr | MSR_FP); + fpscr = PPCMffpscr(); + if (handler) { + for (thread = __OSActiveThreadQueue.head; thread; 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.psf[i] = (u64)0xffffffffffffffffLL; + } + thread->context.fpscr = FPSCR_NI; + } + thread->context.fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE; + thread->context.fpscr &= + ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | + FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | + FPSCR_OX | FPSCR_FX | FPSCR_FI); + } + fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE; + msr |= MSR_FE0 | MSR_FE1; + } else { + for (thread = __OSActiveThreadQueue.head; thread; thread = thread->linkActive.next) { + thread->context.srr1 &= ~(MSR_FE0 | MSR_FE1); + thread->context.fpscr &= ~FPSCR_ENABLE; + thread->context.fpscr &= + ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | + FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | + FPSCR_OX | FPSCR_FX | FPSCR_FI); + } + fpscr &= ~FPSCR_ENABLE; + msr &= ~(MSR_FE0 | MSR_FE1); + } + + fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | + FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | + FPSCR_OX | FPSCR_FX | FPSCR_FI); + + PPCMtfpscr(fpscr); + PPCMtmsr(msr); + } + + OSRestoreInterrupts(enabled); + return oldHandler; +} + +void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar) { + OSTime now; + + now = OSGetTime(); + + if (!(context->srr1 & MSR_RI)) { + OSReport("Non-recoverable Exception %d", exception); + } else { + if (exception == __OS_EXCEPTION_PROGRAM && (context->srr1 & (0x80000000 >> 11)) && + __OSErrorTable[OS_ERROR_FPE] != 0) { + u32 fpscr; + u32 msr; + + exception = OS_ERROR_FPE; + + msr = PPCMfmsr(); + PPCMtmsr(msr | MSR_FP); + + if (__OSFPUContext) { + OSSaveFPUContext((OSContext*)__OSFPUContext); + } + + fpscr = PPCMffpscr(); + fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | + FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | + FPSCR_OX | FPSCR_FX | FPSCR_FI); + PPCMtfpscr(fpscr); + + PPCMtmsr(msr); + + if (__OSFPUContext == context) { + OSDisableScheduler(); + __OSErrorTable[exception](exception, context, dsisr, dar); + context->srr1 &= ~MSR_FP; + __OSFPUContext = NULL; + + context->fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | + FPSCR_VXSNAN | FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | + FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI); + OSEnableScheduler(); + __OSReschedule(); + } else { + context->srr1 &= ~MSR_FP; + __OSFPUContext = NULL; + } + + OSLoadContext(context); + } + + if (__OSErrorTable[exception]) { + OSDisableScheduler(); + __OSErrorTable[exception](exception, context, dsisr, dar); + OSEnableScheduler(); + __OSReschedule(); + OSLoadContext(context); + } + + if (exception == OS_ERROR_DECREMENTER) { + OSLoadContext(context); + } + + OSReport("Unhandled Exception %d", exception); + } + + OSReport("\n"); + OSDumpContext(context); + OSReport("\nDSISR = 0x%08x DAR = 0x%08x\n", dsisr, dar); + OSReport("TB = 0x%016llx\n", now); + + 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); + break; + case __OS_EXCEPTION_ISI: + OSReport("\nAttempted to fetch instruction from invalid address 0x%x " + "(read from SRR0)\n", + context->srr0); + break; + 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); + break; + case __OS_EXCEPTION_PROGRAM: + OSReport("\nProgram exception : Possible illegal instruction/operation " + "at or around 0x%x (read from SRR0)\n", + context->srr0, dar); + break; + case OS_ERROR_PROTECTION: + OSReport("\n"); + OSReport("AI DMA Address = 0x%04x%04x\n", __DSPRegs[0x00000018], __DSPRegs[0x00000018 + 1]); + OSReport("ARAM DMA Address = 0x%04x%04x\n", __DSPRegs[0x00000010], __DSPRegs[0x00000010 + 1]); + OSReport("DI DMA Address = 0x%08x\n", __DIRegs[0x00000005]); + break; + } + + OSReport("\nLast interrupt (%d): SRR0 = 0x%08x TB = 0x%016llx\n", __OSLastInterrupt, + __OSLastInterruptSrr0, __OSLastInterruptTime); + + PPCHalt(); +} diff --git a/libs/dolphin/os/OSFont.c b/libs/dolphin/os/OSFont.c new file mode 100644 index 000000000..aa79fb6bc --- /dev/null +++ b/libs/dolphin/os/OSFont.c @@ -0,0 +1,32 @@ +#include +#include +#include + +// there shoudl be more in this file, however this is the only thing that gets used, i'm not gonna add 1000 lines of text that have no value here + +u16 OSGetFontEncode() +{ + static u16 fontEncode = OS_FONT_ENCODE_NULL; + + if (fontEncode <= 1) + { + return fontEncode; + } + + switch (__OSTVMode) + { + case VI_NTSC: + fontEncode = (__VIRegs[VI_DTV_STAT] & 2) ? OS_FONT_ENCODE_SJIS : OS_FONT_ENCODE_ANSI; + break; + + case VI_PAL: + case VI_MPAL: + case VI_DEBUG: + case VI_DEBUG_PAL: + case VI_EURGB60: + default: + fontEncode = OS_FONT_ENCODE_ANSI; + } + + return fontEncode; +} diff --git a/libs/dolphin/os/OSInterrupt.c b/libs/dolphin/os/OSInterrupt.c new file mode 100644 index 000000000..a7bed16a5 --- /dev/null +++ b/libs/dolphin/os/OSInterrupt.c @@ -0,0 +1,427 @@ +#include +#include + +static asm void ExternalInterruptHandler(register __OSException exception, + register OSContext* context); + +extern void __RAS_OSDisableInterrupts_begin(void); +extern void __RAS_OSDisableInterrupts_end(void); + +static __OSInterruptHandler* InterruptHandlerTable; + +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, +}; + +asm BOOL OSDisableInterrupts(void) { + // clang-format off + 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 + // clang-format on +} +asm BOOL OSEnableInterrupts(void) { + // clang-format off + nofralloc + + mfmsr r3 + ori r4, r3, 0x8000 + mtmsr r4 + rlwinm r3, r3, 17, 31, 31 + blr + // clang-format on +} + +asm BOOL OSRestoreInterrupts(register BOOL level){ + // clang-format off + + 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 + // clang-format on +} + +__OSInterruptHandler + __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler) { + __OSInterruptHandler oldHandler; + + oldHandler = InterruptHandlerTable[interrupt]; + InterruptHandlerTable[interrupt] = handler; + return oldHandler; +} + +__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt) { + return InterruptHandlerTable[interrupt]; +} + +void __OSInterruptInit(void) { + InterruptHandlerTable = 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); + + __OSSetExceptionHandler(4, ExternalInterruptHandler); +} + +u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current) { + u32 reg; + + switch (__cntlzw(mask)) { + 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; + if (!(current & OS_INTERRUPTMASK_MEM_1)) + reg |= 0x2; + if (!(current & OS_INTERRUPTMASK_MEM_2)) + reg |= 0x4; + if (!(current & OS_INTERRUPTMASK_MEM_3)) + reg |= 0x8; + if (!(current & OS_INTERRUPTMASK_MEM_ADDRESS)) + reg |= 0x10; + __MEMRegs[0x0000000e] = (u16)reg; + mask &= ~OS_INTERRUPTMASK_MEM; + break; + 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)) + reg |= 0x10; + if (!(current & OS_INTERRUPTMASK_DSP_ARAM)) + reg |= 0x40; + if (!(current & OS_INTERRUPTMASK_DSP_DSP)) + reg |= 0x100; + __DSPRegs[0x00000005] = (u16)reg; + mask &= ~OS_INTERRUPTMASK_DSP; + break; + case __OS_INTERRUPT_AI_AI: + reg = __AIRegs[0]; + reg &= ~0x2C; + if (!(current & OS_INTERRUPTMASK_AI_AI)) + reg |= 0x4; + __AIRegs[0] = reg; + mask &= ~OS_INTERRUPTMASK_AI; + break; + 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)) + reg |= 0x1; + if (!(current & OS_INTERRUPTMASK_EXI_0_TC)) + reg |= 0x4; + if (!(current & OS_INTERRUPTMASK_EXI_0_EXT)) + reg |= 0x400; + __EXIRegs[0] = reg; + mask &= ~OS_INTERRUPTMASK_EXI_0; + break; + case __OS_INTERRUPT_EXI_1_EXI: + case __OS_INTERRUPT_EXI_1_TC: + case __OS_INTERRUPT_EXI_1_EXT: + reg = __EXIRegs[5]; + reg &= ~0xC0F; + + if (!(current & OS_INTERRUPTMASK_EXI_1_EXI)) + reg |= 0x1; + if (!(current & OS_INTERRUPTMASK_EXI_1_TC)) + reg |= 0x4; + if (!(current & OS_INTERRUPTMASK_EXI_1_EXT)) + reg |= 0x400; + __EXIRegs[5] = reg; + mask &= ~OS_INTERRUPTMASK_EXI_1; + break; + case __OS_INTERRUPT_EXI_2_EXI: + case __OS_INTERRUPT_EXI_2_TC: + reg = __EXIRegs[10]; + reg &= ~0xF; + if (!(current & OS_INTERRUPTMASK_EXI_2_EXI)) + reg |= 0x1; + if (!(current & OS_INTERRUPTMASK_EXI_2_TC)) + reg |= 0x4; + + __EXIRegs[10] = reg; + mask &= ~OS_INTERRUPTMASK_EXI_2; + break; + 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)) { + reg |= 0x800; + } + if (!(current & OS_INTERRUPTMASK_PI_SI)) { + reg |= 0x8; + } + if (!(current & OS_INTERRUPTMASK_PI_DI)) { + reg |= 0x4; + } + if (!(current & OS_INTERRUPTMASK_PI_RSW)) { + reg |= 0x2; + } + if (!(current & OS_INTERRUPTMASK_PI_ERROR)) { + reg |= 0x1; + } + if (!(current & OS_INTERRUPTMASK_PI_VI)) { + reg |= 0x100; + } + if (!(current & OS_INTERRUPTMASK_PI_DEBUG)) { + reg |= 0x1000; + } + if (!(current & OS_INTERRUPTMASK_PI_PE_TOKEN)) { + reg |= 0x200; + } + if (!(current & OS_INTERRUPTMASK_PI_PE_FINISH)) { + reg |= 0x400; + } + if (!(current & OS_INTERRUPTMASK_PI_HSP)) { + reg |= 0x2000; + } + __PIRegs[1] = reg; + mask &= ~OS_INTERRUPTMASK_PI; + break; + default: + break; + } + return mask; +} + +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; + OSInterruptMask local; + OSInterruptMask mask; + + enabled = OSDisableInterrupts(); + prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4); + local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8); + mask = ~(prev | local) & global; + global |= prev; + *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global; + while (mask) { + mask = SetInterruptMask(mask, global | local); + } + OSRestoreInterrupts(enabled); + return prev; +} + +OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask global) { + BOOL enabled; + OSInterruptMask prev; + OSInterruptMask local; + OSInterruptMask mask; + + enabled = OSDisableInterrupts(); + prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4); + local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8); + mask = (prev | local) & global; + global = prev & ~global; + *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global; + while (mask) { + mask = SetInterruptMask(mask, global | local); + } + OSRestoreInterrupts(enabled); + return prev; +} + +volatile OSTime __OSLastInterruptTime; +volatile __OSInterrupt __OSLastInterrupt; +volatile u32 __OSLastInterruptSrr0; + +void __OSDispatchInterrupt(__OSException exception, OSContext* context) { + u32 intsr; + u32 reg; + OSInterruptMask cause; + OSInterruptMask unmasked; + OSInterruptMask* prio; + __OSInterrupt interrupt; + __OSInterruptHandler handler; + intsr = __PIRegs[0]; + intsr &= ~0x00010000; + + if (intsr == 0 || (intsr & __PIRegs[1]) == 0) { + OSLoadContext(context); + } + + cause = 0; + + if (intsr & 0x00000080) { + reg = __MEMRegs[15]; + if (reg & 0x1) + cause |= OS_INTERRUPTMASK_MEM_0; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_MEM_1; + if (reg & 0x4) + cause |= OS_INTERRUPTMASK_MEM_2; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_MEM_3; + if (reg & 0x10) + cause |= OS_INTERRUPTMASK_MEM_ADDRESS; + } + + if (intsr & 0x00000040) { + reg = __DSPRegs[5]; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_DSP_AI; + if (reg & 0x20) + cause |= OS_INTERRUPTMASK_DSP_ARAM; + if (reg & 0x80) + cause |= OS_INTERRUPTMASK_DSP_DSP; + } + + if (intsr & 0x00000020) { + reg = __AIRegs[0]; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_AI_AI; + } + + if (intsr & 0x00000010) { + reg = __EXIRegs[0]; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_EXI_0_EXI; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_EXI_0_TC; + if (reg & 0x800) + cause |= OS_INTERRUPTMASK_EXI_0_EXT; + reg = __EXIRegs[5]; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_EXI_1_EXI; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_EXI_1_TC; + if (reg & 0x800) + cause |= OS_INTERRUPTMASK_EXI_1_EXT; + reg = __EXIRegs[10]; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_EXI_2_EXI; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_EXI_2_TC; + } + + if (intsr & 0x00002000) + cause |= OS_INTERRUPTMASK_PI_HSP; + if (intsr & 0x00001000) + cause |= OS_INTERRUPTMASK_PI_DEBUG; + if (intsr & 0x00000400) + cause |= OS_INTERRUPTMASK_PI_PE_FINISH; + if (intsr & 0x00000200) + cause |= OS_INTERRUPTMASK_PI_PE_TOKEN; + if (intsr & 0x00000100) + cause |= OS_INTERRUPTMASK_PI_VI; + if (intsr & 0x00000008) + cause |= OS_INTERRUPTMASK_PI_SI; + if (intsr & 0x00000004) + cause |= OS_INTERRUPTMASK_PI_DI; + if (intsr & 0x00000002) + cause |= OS_INTERRUPTMASK_PI_RSW; + if (intsr & 0x00000800) + cause |= OS_INTERRUPTMASK_PI_CP; + if (intsr & 0x00000001) + cause |= OS_INTERRUPTMASK_PI_ERROR; + + unmasked = cause & ~(*(OSInterruptMask*)OSPhysicalToCached(0x00C4) | + *(OSInterruptMask*)OSPhysicalToCached(0x00C8)); + if (unmasked) { + for (prio = InterruptPrioTable;; ++prio) { + if (unmasked & *prio) { + interrupt = (__OSInterrupt)__cntlzw(unmasked & *prio); + break; + } + } + + handler = __OSGetInterruptHandler(interrupt); + if (handler) { + if (__OS_INTERRUPT_MEM_ADDRESS < interrupt) { + __OSLastInterrupt = interrupt; + __OSLastInterruptTime = OSGetTime(); + __OSLastInterruptSrr0 = context->srr0; + } + + OSDisableScheduler(); + handler(interrupt, context); + OSEnableScheduler(); + __OSReschedule(); + OSLoadContext(context); + } + } + + OSLoadContext(context); +} + +static asm void ExternalInterruptHandler(register __OSException exception, + register OSContext* context) { +#pragma unused(exception) + // clang-format off + nofralloc + OS_EXCEPTION_SAVE_GPRS(context) + + stwu r1, -8(r1) + b __OSDispatchInterrupt + // clang-format on +} diff --git a/libs/dolphin/os/OSLink.c b/libs/dolphin/os/OSLink.c new file mode 100644 index 000000000..d6f5a51d7 --- /dev/null +++ b/libs/dolphin/os/OSLink.c @@ -0,0 +1,556 @@ +#include + +#define SHN_UNDEF 0 +#define SHN_LORESERVE 0xff00 +#define SHN_LOPROC 0xff00 +#define SHN_HIPROC 0xff1f +#define SHN_ABS 0xfff1 +#define SHN_COMMON 0xfff2 +#define SHN_HIRESERVE 0xffff + +#define ELF32_R_SYM(i) ((i) >> 8) +#define ELF32_R_TYPE(i) ((unsigned char)(i)) +#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_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_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_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 + +OSModuleQueue __OSModuleInfoList : (OS_BASE_CACHED | 0x30C8); +const void* __OSStringTable : (OS_BASE_CACHED | 0x30D0); + +#pragma dont_inline on +__declspec(weak) void OSNotifyLink(OSModuleInfo* module) {} + +__declspec(weak) void OSNotifyUnlink(OSModuleInfo* module) {} + +#pragma dont_inline reset + +#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) + +#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) + +void OSSetStringTable(const void* stringTable) { __OSStringTable = stringTable; } + +static BOOL Relocate(OSModuleHeader* newModule, OSModuleHeader* module) { + OSModuleID idNew; + OSImportInfo* imp; + OSRel* rel; + OSSectionInfo* si; + OSSectionInfo* siFlush; + u32* p; + u32 offset; + u32 x; + + idNew = newModule ? newModule->info.id : 0; + for (imp = (OSImportInfo*)module->impOffset; + imp < (OSImportInfo*)(module->impOffset + module->impSize); imp++) { + if (imp->id == idNew) { + goto Found; + } + } + return FALSE; + +Found: + siFlush = 0; + for (rel = (OSRel*)imp->offset; rel->type != R_DOLPHIN_END; rel++) { + (u8*)p += rel->offset; + if (idNew) { + si = &OSGetSectionInfo(newModule)[rel->section]; + offset = OS_SECTIONINFO_OFFSET(si->offset); + } else { + offset = 0; + } + switch (rel->type) { + case R_PPC_NONE: + break; + case R_PPC_ADDR32: + x = offset + rel->addend; + *p = x; + break; + case R_PPC_ADDR24: + x = offset + rel->addend; + *p = (*p & ~0x03fffffc) | (x & 0x03fffffc); + break; + case R_PPC_ADDR16: + x = offset + rel->addend; + *(u16*)p = (u16)(x & 0xffff); + break; + case R_PPC_ADDR16_LO: + x = offset + rel->addend; + *(u16*)p = (u16)(x & 0xffff); + break; + case R_PPC_ADDR16_HI: + x = offset + rel->addend; + *(u16*)p = (u16)(((x >> 16) & 0xffff)); + break; + case R_PPC_ADDR16_HA: + x = offset + rel->addend; + *(u16*)p = (u16)(((x >> 16) + ((x & 0x8000) ? 1 : 0)) & 0xffff); + break; + case R_PPC_ADDR14: + case R_PPC_ADDR14_BRTAKEN: + case R_PPC_ADDR14_BRNTAKEN: + x = offset + rel->addend; + *p = (*p & ~0x0000fffc) | (x & 0x0000fffc); + break; + case R_PPC_REL24: + x = offset + rel->addend - (u32)p; + *p = (*p & ~0x03fffffc) | (x & 0x03fffffc); + break; + case R_PPC_REL14: + case R_PPC_REL14_BRTAKEN: + case R_PPC_REL14_BRNTAKEN: + x = offset + rel->addend - (u32)p; + *p = (*p & ~0x0000fffc) | (x & 0x0000fffc); + break; + case R_DOLPHIN_NOP: + break; + case R_DOLPHIN_SECTION: + si = &OSGetSectionInfo(module)[rel->section]; + p = (u32*)OS_SECTIONINFO_OFFSET(si->offset); + if (siFlush) { + offset = OS_SECTIONINFO_OFFSET(siFlush->offset); + DCFlushRange((void*)offset, siFlush->size); + ICInvalidateRange((void*)offset, siFlush->size); + } + siFlush = (si->offset & OS_SECTIONINFO_EXEC) ? si : 0; + break; + default: + OSReport("OSLink: unknown relocation type %3d\n", rel->type); + break; + } + } + + if (siFlush) { + offset = OS_SECTIONINFO_OFFSET(siFlush->offset); + DCFlushRange((void*)offset, siFlush->size); + ICInvalidateRange((void*)offset, siFlush->size); + } + + return TRUE; +} + +#if OS_MODULE_VERSION >= 3 +static BOOL Link(OSModuleInfo* newModule, void* bss, BOOL fixed) { + u32 i; + OSSectionInfo* si; + OSModuleHeader* moduleHeader; + OSModuleInfo* moduleInfo; + OSImportInfo* imp; + + moduleHeader = (OSModuleHeader*)newModule; + moduleHeader->bssSection = 0; + + if (OS_MODULE_VERSION < newModule->version || + 2 <= newModule->version && + (moduleHeader->align && (u32)newModule % moduleHeader->align != 0 || + moduleHeader->bssAlign && (u32)bss % moduleHeader->bssAlign != 0)) { + return FALSE; + } + + EnqueueTail(&__OSModuleInfoList, newModule, link); + newModule->sectionInfoOffset += (u32)moduleHeader; + moduleHeader->relOffset += (u32)moduleHeader; + moduleHeader->impOffset += (u32)moduleHeader; + if (3 <= newModule->version) { + moduleHeader->fixSize += (u32)moduleHeader; + } + for (i = 1; i < newModule->numSections; i++) { + si = &OSGetSectionInfo(newModule)[i]; + if (si->offset != 0) { + si->offset += (u32)moduleHeader; + } else if (si->size != 0) { + moduleHeader->bssSection = (u8)i; + si->offset = (u32)bss; + bss = (void*)((u32)bss + si->size); + } + } + for (imp = (OSImportInfo*)moduleHeader->impOffset; + imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) { + imp->offset += (u32)moduleHeader; + } + if (moduleHeader->prologSection != SHN_UNDEF) { + moduleHeader->prolog += + OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->prologSection].offset); + } + if (moduleHeader->epilogSection != SHN_UNDEF) { + moduleHeader->epilog += + OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->epilogSection].offset); + } + if (moduleHeader->unresolvedSection != SHN_UNDEF) { + moduleHeader->unresolved += + OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->unresolvedSection].offset); + } + if (__OSStringTable) { + newModule->nameOffset += (u32)__OSStringTable; + } + + Relocate(0, moduleHeader); + + for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) { + Relocate(moduleHeader, (OSModuleHeader*)moduleInfo); + if (moduleInfo != newModule) { + Relocate((OSModuleHeader*)moduleInfo, moduleHeader); + } + } + + if (fixed) { + for (imp = (OSImportInfo*)moduleHeader->impOffset; + imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) { + if (imp->id == 0 || imp->id == newModule->id) { + moduleHeader->impSize = (u32)((u8*)imp - (u8*)moduleHeader->impOffset); + break; + } + } + } + + memset(bss, 0, moduleHeader->bssSize); + + OSNotifyLink(newModule); + + return TRUE; +} + +BOOL OSLink(OSModuleInfo* newModule, void* bss) { return Link(newModule, bss, FALSE); } + +BOOL OSLinkFixed(OSModuleInfo* newModule, void* bss) { + if (OS_MODULE_VERSION < newModule->version || newModule->version < 3) { + return FALSE; + } + return Link(newModule, bss, TRUE); +} +#else +BOOL OSLink(OSModuleInfo* newModule, void* bss) { + u32 i; + OSSectionInfo* si; + OSModuleHeader* moduleHeader; + OSModuleInfo* moduleInfo; + OSImportInfo* imp; + + moduleHeader = (OSModuleHeader*)newModule; + moduleHeader->bssSection = 0; + + if (OS_MODULE_VERSION < newModule->version || + 2 <= newModule->version && + (moduleHeader->align && (u32)newModule % moduleHeader->align != 0 || + moduleHeader->bssAlign && (u32)bss % moduleHeader->bssAlign != 0)) { + return FALSE; + } + + EnqueueTail(&__OSModuleInfoList, newModule, link); + memset(bss, 0, moduleHeader->bssSize); + newModule->sectionInfoOffset += (u32)moduleHeader; + moduleHeader->relOffset += (u32)moduleHeader; + moduleHeader->impOffset += (u32)moduleHeader; + + for (i = 1; i < newModule->numSections; i++) { + si = &OSGetSectionInfo(newModule)[i]; + if (si->offset != 0) { + si->offset += (u32)moduleHeader; + } else if (si->size != 0) { + moduleHeader->bssSection = (u8)i; + si->offset = (u32)bss; + bss = (void*)((u32)bss + si->size); + } + } + for (imp = (OSImportInfo*)moduleHeader->impOffset; + imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) { + imp->offset += (u32)moduleHeader; + } + if (moduleHeader->prologSection != SHN_UNDEF) { + moduleHeader->prolog += + OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->prologSection].offset); + } + if (moduleHeader->epilogSection != SHN_UNDEF) { + moduleHeader->epilog += + OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->epilogSection].offset); + } + if (moduleHeader->unresolvedSection != SHN_UNDEF) { + moduleHeader->unresolved += + OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->unresolvedSection].offset); + } + if (__OSStringTable) { + newModule->nameOffset += (u32)__OSStringTable; + } + + Relocate(0, moduleHeader); + + for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) { + Relocate(moduleHeader, (OSModuleHeader*)moduleInfo); + if (moduleInfo != newModule) { + Relocate((OSModuleHeader*)moduleInfo, moduleHeader); + } + } + + OSNotifyLink(newModule); + + return TRUE; +} +#endif + +static BOOL Undo(OSModuleHeader* newModule, OSModuleHeader* module) { + OSModuleID idNew; + OSImportInfo* imp; + OSRel* rel; + OSSectionInfo* si; + OSSectionInfo* siFlush; + u32* p; + u32 offset; + u32 x; + + idNew = newModule->info.id; + for (imp = (OSImportInfo*)module->impOffset; + imp < (OSImportInfo*)(module->impOffset + module->impSize); imp++) { + if (imp->id == idNew) { + goto Found; + } + } + return FALSE; + +Found: + siFlush = 0; + for (rel = (OSRel*)imp->offset; rel->type != R_DOLPHIN_END; rel++) { + (u8*)p += rel->offset; + si = &OSGetSectionInfo(newModule)[rel->section]; + offset = OS_SECTIONINFO_OFFSET(si->offset); + x = 0; + switch (rel->type) { + case R_PPC_NONE: + break; + case R_PPC_ADDR32: + *p = x; + break; + case R_PPC_ADDR24: + *p = (*p & ~0x03fffffc) | (x & 0x03fffffc); + break; + case R_PPC_ADDR16: + *(u16*)p = (u16)(x & 0xffff); + break; + case R_PPC_ADDR16_LO: + *(u16*)p = (u16)(x & 0xffff); + break; + case R_PPC_ADDR16_HI: + *(u16*)p = (u16)(((x >> 16) & 0xffff)); + break; + case R_PPC_ADDR16_HA: + *(u16*)p = (u16)(((x >> 16) + ((x & 0x8000) ? 1 : 0)) & 0xffff); + break; + case R_PPC_ADDR14: + case R_PPC_ADDR14_BRTAKEN: + case R_PPC_ADDR14_BRNTAKEN: + *p = (*p & ~0x0000fffc) | (x & 0x0000fffc); + break; + case R_PPC_REL24: + if (module->unresolvedSection != SHN_UNDEF) { + x = (u32)module->unresolved - (u32)p; + } + *p = (*p & ~0x03fffffc) | (x & 0x03fffffc); + break; + case R_PPC_REL14: + case R_PPC_REL14_BRTAKEN: + case R_PPC_REL14_BRNTAKEN: + *p = (*p & ~0x0000fffc) | (x & 0x0000fffc); + break; + case R_DOLPHIN_NOP: + break; + case R_DOLPHIN_SECTION: + si = &OSGetSectionInfo(module)[rel->section]; + p = (u32*)OS_SECTIONINFO_OFFSET(si->offset); + if (siFlush) { + offset = OS_SECTIONINFO_OFFSET(siFlush->offset); + DCFlushRange((void*)offset, siFlush->size); + ICInvalidateRange((void*)offset, siFlush->size); + } + siFlush = (si->offset & OS_SECTIONINFO_EXEC) ? si : 0; + break; + default: + OSReport("OSUnlink: unknown relocation type %3d\n", rel->type); + break; + } + } + + if (siFlush) { + offset = OS_SECTIONINFO_OFFSET(siFlush->offset); + DCFlushRange((void*)offset, siFlush->size); + ICInvalidateRange((void*)offset, siFlush->size); + } + + return TRUE; +} + +BOOL OSUnlink(OSModuleInfo* oldModule) { + OSModuleHeader* moduleHeader; + OSModuleInfo* moduleInfo; + u32 i; + OSSectionInfo* si; + OSImportInfo* imp; + + moduleHeader = (OSModuleHeader*)oldModule; + + DequeueItem(&__OSModuleInfoList, oldModule, link); + + for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) { + Undo(moduleHeader, (OSModuleHeader*)moduleInfo); + } + + OSNotifyUnlink(oldModule); + + if (__OSStringTable) { + oldModule->nameOffset -= (u32)__OSStringTable; + } + if (moduleHeader->prologSection != SHN_UNDEF) { + moduleHeader->prolog -= + OS_SECTIONINFO_OFFSET(OSGetSectionInfo(oldModule)[moduleHeader->prologSection].offset); + } + if (moduleHeader->epilogSection != SHN_UNDEF) { + moduleHeader->epilog -= + OS_SECTIONINFO_OFFSET(OSGetSectionInfo(oldModule)[moduleHeader->epilogSection].offset); + } + if (moduleHeader->unresolvedSection != SHN_UNDEF) { + moduleHeader->unresolved -= + OS_SECTIONINFO_OFFSET(OSGetSectionInfo(oldModule)[moduleHeader->unresolvedSection].offset); + } + for (imp = (OSImportInfo*)moduleHeader->impOffset; + imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) { + imp->offset -= (u32)moduleHeader; + } + for (i = 1; i < oldModule->numSections; i++) { + si = &OSGetSectionInfo(oldModule)[i]; + if (i == moduleHeader->bssSection) { + moduleHeader->bssSection = 0; + si->offset = 0; + } else if (si->offset != 0) { + si->offset -= (u32)moduleHeader; + } + } + moduleHeader->relOffset -= (u32)moduleHeader; + moduleHeader->impOffset -= (u32)moduleHeader; + oldModule->sectionInfoOffset -= (u32)moduleHeader; + + return TRUE; +} + +void __OSModuleInit(void) { + __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; + } + + for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) { + sectionInfo = OSGetSectionInfo(moduleInfo); + for (i = 0; i < moduleInfo->numSections; ++i) { + if (sectionInfo->size) { + baseSection = OS_SECTIONINFO_OFFSET(sectionInfo->offset); + if (baseSection <= (u32)ptr && (u32)ptr < baseSection + sectionInfo->size) { + if (section) { + *section = i; + } + if (offset) { + *offset = (u32)ptr - baseSection; + } + return moduleInfo; + } + } + sectionInfo++; + } + } + + return NULL; +} diff --git a/libs/dolphin/os/OSMemory.c b/libs/dolphin/os/OSMemory.c new file mode 100644 index 000000000..71d3097af --- /dev/null +++ b/libs/dolphin/os/OSMemory.c @@ -0,0 +1,223 @@ +#include + +#define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) +#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) + +vu16 __MEMRegs[64] : 0xCC004000; + +static BOOL OnReset(BOOL final); + +static OSResetFunctionInfo ResetFunctionInfo = { + OnReset, + 127, +}; + +u32 OSGetPhysicalMemSize() { return *(u32 *)(OSPhysicalToCached(0x0028)); } + +u32 OSGetConsoleSimulatedMemSize() { return *(u32 *)(OSPhysicalToCached(0x00F0)); } + +static BOOL OnReset(BOOL final) { + if (final != FALSE) { + __MEMRegs[8] = 0xFF; + __OSMaskInterrupts(0xf0000000); + } + return TRUE; +} + +static void MEMIntrruptHandler(__OSInterrupt interrupt, OSContext* context) { + u32 addr; + u32 cause; + + cause = __MEMRegs[0xf]; + addr = (((u32)__MEMRegs[0x12] & 0x3ff) << 16) | __MEMRegs[0x11]; + __MEMRegs[0x10] = 0; + + if (__OSErrorTable[OS_ERROR_PROTECTION]) { + __OSErrorTable[OS_ERROR_PROTECTION](OS_ERROR_PROTECTION, context, cause, addr); + return; + } + + __OSUnhandledException(OS_ERROR_PROTECTION, context, cause, addr); +} + +void OSProtectRange(u32 chan, void* addr, u32 nBytes, u32 control) { + BOOL enabled; + u32 start; + u32 end; + u16 reg; + if (4 <= chan) { + return; + } + + control &= OS_PROTECT_CONTROL_RDWR; + + end = (u32)addr + nBytes; + start = TRUNC(addr, 1u << 10); + end = ROUND(end, 1u << 10); + + DCFlushRange((void*)start, end - start); + + enabled = OSDisableInterrupts(); + + __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 |= control << 2 * chan; + __MEMRegs[8] = reg; + + if (control != OS_PROTECT_CONTROL_RDWR) { + __OSUnmaskInterrupts(OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_0 + chan)); + } + + OSRestoreInterrupts(enabled); +} + +asm void Config24MB() { + // clang-format off + nofralloc + + addi r7,r0,0 + + addis r4,r0,0x00000002@ha + addi r4,r4,0x00000002@l + addis r3,r0,0x800001ff@ha + addi r3,r3,0x800001ff@l + + addis r6,r0,0x01000002@ha + addi r6,r6,0x01000002@l + addis r5,r0,0x810000ff@ha + addi r5,r5,0x810000ff@l + + isync + + mtspr dbat0u,r7 + mtspr dbat0l,r4 + mtspr dbat0u,r3 + isync + + mtspr ibat0u,r7 + mtspr ibat0l,r4 + mtspr ibat0u,r3 + isync + + mtspr dbat2u,r7 + mtspr dbat2l,r6 + mtspr dbat2u,r5 + isync + + mtspr ibat2u,r7 + mtspr ibat2l,r6 + mtspr ibat2u,r5 + isync + + mfmsr r3 + ori r3, r3, 0x30 + mtsrr1 r3 + + mflr r3 + mtsrr0 r3 + rfi + // clang-format on +} + +asm void Config48MB() { + // clang-format off + nofralloc + + addi r7,r0,0x0000 + + addis r4,r0,0x00000002@ha + addi r4,r4,0x00000002@l + addis r3,r0,0x800003ff@ha + addi r3,r3,0x800003ff@l + + addis r6,r0,0x02000002@ha + addi r6,r6,0x02000002@l + addis r5,r0,0x820001ff@ha + addi r5,r5,0x820001ff@l + + isync + + mtspr dbat0u,r7 + mtspr dbat0l,r4 + mtspr dbat0u,r3 + isync + + mtspr ibat0u,r7 + mtspr ibat0l,r4 + mtspr ibat0u,r3 + isync + + mtspr dbat2u,r7 + mtspr dbat2l,r6 + mtspr dbat2u,r5 + isync + + mtspr ibat2u,r7 + mtspr ibat2l,r6 + mtspr ibat2u,r5 + isync + + mfmsr r3 + ori r3, r3, 0x30 + mtsrr1 r3 + + mflr r3 + mtsrr0 r3 + rfi + // clang-format on +} + +asm void RealMode(register u32 addr) { + // clang-format off + nofralloc + clrlwi r3, r3, 2 + mtsrr0 r3 + mfmsr r3 + rlwinm r3, r3, 0, 28, 25 + mtsrr1 r3 + rfi + // clang-format on +} + +void __OSInitMemoryProtection() { + u32 padding[8]; + u32 simulatedSize; + BOOL enabled; + simulatedSize = OSGetConsoleSimulatedMemSize(); + enabled = OSDisableInterrupts(); + + __MEMRegs[16] = 0; + __MEMRegs[8] = 0xFF; + + __OSMaskInterrupts(OS_INTERRUPTMASK_MEM_0 | OS_INTERRUPTMASK_MEM_1 | OS_INTERRUPTMASK_MEM_2 | + OS_INTERRUPTMASK_MEM_3); + __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) { + DCInvalidateRange((void*)0x81800000, 0x1800000); + __MEMRegs[20] = 2; + } + + if (simulatedSize <= 0x1800000) + { + RealMode((u32)&Config24MB); + } + else if (simulatedSize <= 0x3000000) + { + RealMode((u32)&Config48MB); + } + + __OSUnmaskInterrupts(OS_INTERRUPTMASK_MEM_ADDRESS); + OSRestoreInterrupts(enabled); +} diff --git a/libs/dolphin/os/OSMessage.c b/libs/dolphin/os/OSMessage.c new file mode 100644 index 000000000..db4d2fdd2 --- /dev/null +++ b/libs/dolphin/os/OSMessage.c @@ -0,0 +1,86 @@ +#include + +void OSInitMessageQueue(OSMessageQueue* mq, OSMessage* msgArray, s32 msgCount) { + OSInitThreadQueue(&mq->queueSend); + OSInitThreadQueue(&mq->queueReceive); + mq->msgArray = msgArray; + mq->msgCount = msgCount; + mq->firstIndex = 0; + mq->usedCount = 0; +} + +BOOL OSSendMessage(OSMessageQueue* mq, OSMessage msg, s32 flags) { + BOOL enabled; + s32 lastIndex; + + enabled = OSDisableInterrupts(); + + while (mq->msgCount <= mq->usedCount) { + if (!(flags & OS_MESSAGE_BLOCK)) { + OSRestoreInterrupts(enabled); + return FALSE; + } else { + OSSleepThread(&mq->queueSend); + } + } + + lastIndex = (mq->firstIndex + mq->usedCount) % mq->msgCount; + mq->msgArray[lastIndex] = msg; + mq->usedCount++; + + OSWakeupThread(&mq->queueReceive); + + OSRestoreInterrupts(enabled); + return TRUE; +} + +BOOL OSReceiveMessage(OSMessageQueue* mq, OSMessage* msg, s32 flags) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + + while (mq->usedCount == 0) { + if (!(flags & OS_MESSAGE_BLOCK)) { + OSRestoreInterrupts(enabled); + return FALSE; + } else { + OSSleepThread(&mq->queueReceive); + } + } + + if (msg != NULL) { + *msg = mq->msgArray[mq->firstIndex]; + } + mq->firstIndex = (mq->firstIndex + 1) % mq->msgCount; + mq->usedCount--; + + OSWakeupThread(&mq->queueSend); + + OSRestoreInterrupts(enabled); + return TRUE; +} + +BOOL OSJamMessage(OSMessageQueue* mq, OSMessage msg, s32 flags) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + + while (mq->msgCount <= mq->usedCount) + { + if (!(flags & OS_MESSAGE_BLOCK)) { + OSRestoreInterrupts(enabled); + return FALSE; + } else { + OSSleepThread(&mq->queueSend); + } + } + + mq->firstIndex = (mq->firstIndex + mq->msgCount - 1) % mq->msgCount; + mq->msgArray[mq->firstIndex] = msg; + mq->usedCount++; + + OSWakeupThread(&mq->queueReceive); + + OSRestoreInterrupts(enabled); + return TRUE; +} diff --git a/libs/dolphin/os/OSMutex.c b/libs/dolphin/os/OSMutex.c new file mode 100644 index 000000000..f853729e0 --- /dev/null +++ b/libs/dolphin/os/OSMutex.c @@ -0,0 +1,223 @@ +#include "dolphin/os.h" + +#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) + +#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 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) + +void OSInitMutex(OSMutex* mutex) { + OSInitThreadQueue(&mutex->queue); + mutex->thread = 0; + mutex->count = 0; +} + +void OSLockMutex(OSMutex* mutex) { + BOOL enabled = OSDisableInterrupts(); + OSThread* currentThread = OSGetCurrentThread(); + OSThread* ownerThread; + + while (TRUE) { + ownerThread = ((OSMutex*)mutex)->thread; + if (ownerThread == 0) { + mutex->thread = currentThread; + mutex->count++; + PushTail(¤tThread->queueMutex, mutex, link); + break; + } else if (ownerThread == currentThread) { + mutex->count++; + break; + } else { + currentThread->mutex = mutex; + __OSPromoteThread(mutex->thread, currentThread->priority); + OSSleepThread(&mutex->queue); + currentThread->mutex = 0; + } + } + OSRestoreInterrupts(enabled); +} + +void OSUnlockMutex(OSMutex* mutex) { + BOOL enabled = OSDisableInterrupts(); + OSThread* currentThread = OSGetCurrentThread(); + + if (mutex->thread == currentThread && --mutex->count == 0) { + PopItem(¤tThread->queueMutex, mutex, link); + mutex->thread = NULL; + if (currentThread->priority < currentThread->base) { + currentThread->priority = __OSGetEffectivePriority(currentThread); + } + + OSWakeupThread(&mutex->queue); + } + OSRestoreInterrupts(enabled); +} + +void __OSUnlockAllMutex(OSThread* thread) { + OSMutex* mutex; + + while (thread->queueMutex.head) { + PopHead(&thread->queueMutex, mutex, link); + mutex->count = 0; + mutex->thread = NULL; + OSWakeupThread(&mutex->queue); + } +} + +BOOL OSTryLockMutex(OSMutex* mutex) { + BOOL enabled = OSDisableInterrupts(); + OSThread* currentThread = OSGetCurrentThread(); + BOOL locked; + if (mutex->thread == 0) { + mutex->thread = currentThread; + mutex->count++; + PushTail(¤tThread->queueMutex, mutex, link); + locked = TRUE; + } else if (mutex->thread == currentThread) { + mutex->count++; + locked = TRUE; + } else { + locked = FALSE; + } + OSRestoreInterrupts(enabled); + return locked; +} + +void OSInitCond(OSCond* cond) { OSInitThreadQueue(&cond->queue); } + +void OSWaitCond(OSCond* cond, OSMutex* mutex) { + BOOL enabled = OSDisableInterrupts(); + OSThread* currentThread = OSGetCurrentThread(); + s32 count; + + if (mutex->thread == currentThread) { + count = mutex->count; + mutex->count = 0; + PopItem(¤tThread->queueMutex, mutex, link); + mutex->thread = NULL; + + if (currentThread->priority < currentThread->base) { + currentThread->priority = __OSGetEffectivePriority(currentThread); + } + + OSDisableScheduler(); + OSWakeupThread(&mutex->queue); + OSEnableScheduler(); + OSSleepThread(&cond->queue); + OSLockMutex(mutex); + mutex->count = count; + } + + OSRestoreInterrupts(enabled); +} + +void OSSignalCond(OSCond* cond) { OSWakeupThread(&cond->queue); } + +static BOOL IsMember(OSMutexQueue* queue, OSMutex* mutex) { + OSMutex* member; + + for (member = queue->head; member; member = member->link.next) { + if (mutex == member) + return TRUE; + } + return FALSE; +} + +BOOL __OSCheckMutex(OSMutex* mutex) { + OSThread* thread; + OSThreadQueue* queue; + OSPriority 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->priority < priority) + return FALSE; + priority = thread->priority; + } + + if (mutex->thread) { + if (mutex->count <= 0) + return FALSE; + } else { + if (0 != mutex->count) + return FALSE; + } + + return TRUE; +} + +BOOL __OSCheckDeadLock(OSThread* thread) { + OSMutex* mutex; + + mutex = thread->mutex; + while (mutex && mutex->thread) { + if (mutex->thread == thread) + return TRUE; + mutex = mutex->thread->mutex; + } + return FALSE; +} + +BOOL __OSCheckMutexes(OSThread* thread) { + OSMutex* mutex; + + for (mutex = thread->queueMutex.head; mutex; mutex = mutex->link.next) { + if (mutex->thread != thread) + return FALSE; + if (!__OSCheckMutex(mutex)) + return FALSE; + } + return TRUE; +} diff --git a/libs/dolphin/os/OSReboot.c b/libs/dolphin/os/OSReboot.c new file mode 100644 index 000000000..4fd3bf22e --- /dev/null +++ b/libs/dolphin/os/OSReboot.c @@ -0,0 +1,119 @@ +#include "dolphin/dvd.h" +#include "dolphin/os.h" +#include "dolphin/os/OSBootInfo.h" +#include "dolphin/ai.h" + +// Struct for Apploader header (size 0x20). +typedef struct _ApploaderHeader { + char date[16]; // _00 + u32 entry; // _10 + u32 size; // _14 + u32 rebootSize; // _18 + u32 reserved2; // _1C +} ApploaderHeader; + +static ApploaderHeader Header ALIGN(32); + +extern void* __OSSavedRegionStart; +extern void* __OSSavedRegionEnd; + +static void* SaveStart = NULL; +static void* SaveEnd = NULL; + +extern u32 UNK_817FFFF8 AT_ADDRESS(0x817FFFF8); +extern u32 UNK_817FFFFC AT_ADDRESS(0x817FFFFC); +extern u32 BOOT_REGION_START AT_ADDRESS(0x812FDFF0); +extern u32 BOOT_REGION_END AT_ADDRESS(0x812FDFEC); +extern u32 OS_RESET_CODE AT_ADDRESS(0x800030F0); +extern u8 OS_REBOOT_BOOL AT_ADDRESS(0x800030E2); // unknown function, set to true by __OSReboot + +static BOOL Prepared = FALSE; + +void __OSDoHotReset(int); + +inline void ReadApploader(OSTime time1) { + if (DVDCheckDisk() == DVD_RESULT_GOOD || OSGetTime() - time1 > OS_TIMER_CLOCK) { + __OSDoHotReset(UNK_817FFFFC); + } +} + +ASM void Run() { +#ifdef __MWERKS__ // clang-format off + nofralloc + sync + isync + mtlr r3 + blr +#endif // clang-format on +} + +static void Callback() { Prepared = TRUE; } + +inline BOOL IsStreamEnabled(void) { + if (DVDGetCurrentDiskID()->streaming) { + return TRUE; + } + return FALSE; +} + +void __OSReboot(u32 resetCode, u32 bootDol) { + OSContext exceptionContext; + OSTime time; + DVDCommandBlock dvdCmd; + DVDCommandBlock dvdCmd2; + DVDCommandBlock dvdCmd3; + u32 numBytes; + u32 offset; + + OSDisableInterrupts(); + UNK_817FFFFC = 0; + UNK_817FFFF8 = 0; + OS_REBOOT_BOOL = TRUE; + BOOT_REGION_START = (u32)SaveStart; + BOOT_REGION_END = (u32)SaveEnd; + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + DVDInit(); + DVDSetAutoInvalidation(TRUE); + DVDResume(); + Prepared = FALSE; + __DVDPrepareResetAsync(Callback); + __OSMaskInterrupts(~0x1F); + __OSUnmaskInterrupts(0x400); + OSEnableInterrupts(); + + time = OSGetTime(); + while (Prepared != TRUE) { + ReadApploader(time); + } + + if (!__OSIsGcam && IsStreamEnabled()) { + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + DVDCancelStreamAsync(&dvdCmd, NULL); + time = OSGetTime(); + while (DVDGetCommandBlockStatus(&dvdCmd)) { + ReadApploader(time); + } + AISetStreamPlayState(0); + } + + DVDReadAbsAsyncPrio(&dvdCmd2, &Header, 32, 0x2440, NULL, 0); + time = OSGetTime(); + while (DVDGetCommandBlockStatus(&dvdCmd2)) { + ReadApploader(time); + } + + offset = Header.size + 0x20; + numBytes = OSRoundUp32B(Header.rebootSize); + DVDReadAbsAsyncPrio(&dvdCmd3, (void*)(OS_BOOTROM_ADDR), numBytes, offset + 0x2440, NULL, 0); + time = OSGetTime(); + while (DVDGetCommandBlockStatus(&dvdCmd3)) { + ReadApploader(time); + } + + ICInvalidateRange((void*)(OS_BOOTROM_ADDR), numBytes); + OSDisableInterrupts(); + ICFlashInvalidate(); + Run((void*)OS_BOOTROM_ADDR); +} \ No newline at end of file diff --git a/libs/dolphin/os/OSReset.c b/libs/dolphin/os/OSReset.c new file mode 100644 index 000000000..1194de004 --- /dev/null +++ b/libs/dolphin/os/OSReset.c @@ -0,0 +1,211 @@ +#include "dolphin/OSRtcPriv.h" +#include "dolphin/os.h" +#include "dolphin/vi.h" +#include "dolphin/hw_regs.h" + +volatile u8 DAT_800030e2 : 0x800030e2; +typedef struct Unk { + u8 pad[0x24]; + u32 resetCode; +} Unk; +volatile Unk DAT_cc003000 : 0xcc003000; + +typedef struct Unk2 { + u16 _0; + u16 _2; +} Unk2; + +volatile Unk2 DAT_cc002000 : 0xcc002000; + +typedef struct OSResetQueue { + OSResetFunctionInfo* first; + OSResetFunctionInfo* last; +} OSResetQueue; + +static OSResetQueue ResetFunctionQueue; +static u32 bootThisDol; + +void OSRegisterResetFunction(OSResetFunctionInfo* func) { + OSResetFunctionInfo* tmp; + OSResetFunctionInfo* iter; + + for (iter = ResetFunctionQueue.first; iter && iter->priority <= func->priority; iter = iter->next) + ; + + 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; + } + + func->next = iter; + tmp = iter->prev; + iter->prev = func; + func->prev = tmp; + if (tmp == NULL) { + ResetFunctionQueue.first = func; + return; + } + tmp->next = func; +} + +BOOL __OSCallResetFunctions(u32 arg0) { + OSResetFunctionInfo *info; + s32 err = 0; + + for (info = ResetFunctionQueue.first; info != NULL && err == 0; info = info->next) + { + err |= !info->func(arg0); + } + err |= !__OSSyncSram() ; + if (err) + { + return 0; + } + return 1; +} + +asm void Reset(register s32 resetCode) { + // clang-format off + nofralloc + b lbl_8038315C +lbl_80383140: + mfspr r8, HID0 + ori r8, r8, 8 + mtspr HID0, r8 + isync + sync + nop + b lbl_80383160 +lbl_8038315C: + b lbl_8038317C +lbl_80383160: + mftb r5, 268 +lbl_80383164: + mftb r6, 268 + subf r7, r5, r6 + cmplwi r7, 0x1124 + blt lbl_80383164 + nop + b lbl_80383180 +lbl_8038317C: + b lbl_8038319C +lbl_80383180: + lis r8, 0xCC003000@h + ori r8, r8, 0xCC003000@l + li r4, 3 + stw r4, 0x24(r8) + stw r3, 0x24(r8) + nop + b lbl_803831A0 +lbl_8038319C: + b lbl_803831A8 +lbl_803831A0: + nop + b lbl_803831A0 +lbl_803831A8: + b lbl_80383140 + // clang-format on +} + +OSThreadQueue __OSActiveThreadQueue : (OS_BASE_CACHED | 0x00DC); + +static void KillThreads(void) { + OSThread* thread; + OSThread* next; + + for (thread = __OSActiveThreadQueue.head; thread; thread = next) { + next = thread->linkActive.next; + switch (thread->state) { + case 1: + case 4: + OSCancelThread(thread); + break; + default: + break; + } + } +} + +void __OSDoHotReset(s32 arg0) { + OSDisableInterrupts(); + __VIRegs[1] = 0; + ICFlashInvalidate(); + Reset(arg0 * 8); +} + +void OSResetSystem(int reset, u32 resetCode, BOOL forceMenu) +{ + BOOL rc; + BOOL disableRecalibration; + u32 unk[3]; // dumb compiler + + OSDisableScheduler(); + __OSStopAudioSystem(); + + if (reset == OS_RESET_SHUTDOWN || (reset == OS_RESET_RESTART && bootThisDol != 0)) + { + disableRecalibration = __PADDisableRecalibration(TRUE); + } + + while (!__OSCallResetFunctions(FALSE)) + { + ; + } + + if (reset == OS_RESET_HOTRESET && forceMenu) + { + OSSram *sram; + + sram = __OSLockSram(); + sram->flags |= 0x40; + __OSUnlockSram(TRUE); + + while (!__OSSyncSram()) + { + ; + } + } + + OSDisableInterrupts(); + __OSCallResetFunctions(TRUE); + LCDisable(); + if (reset == OS_RESET_HOTRESET) + { + __OSDoHotReset(resetCode); + } + else if (reset == OS_RESET_RESTART) + { + if ((*(u32 *)OSPhysicalToCached(0x30EC) = bootThisDol) != 0) + { + __PADDisableRecalibration(disableRecalibration); + } + KillThreads(); + OSEnableScheduler(); + __OSReboot(resetCode, forceMenu); + } + + KillThreads(); + memset(OSPhysicalToCached(0x40), 0, 0xCC - 0x40); + memset(OSPhysicalToCached(0xD4), 0, 0xE8 - 0xD4); + memset(OSPhysicalToCached(0xF4), 0, 0xF8 - 0xF4); + memset(OSPhysicalToCached(0x3000), 0, 0xC0); + memset(OSPhysicalToCached(0x30C8), 0, 0xD4 - 0xC8); + memset(OSPhysicalToCached(0x30E2), 0, 1); + + __PADDisableRecalibration(disableRecalibration); +} + +u32 OSGetResetCode(void) { + if (DAT_800030e2 != 0) { + return 0x80000000; + } + return ((DAT_cc003000.resetCode & ~7) >> 3); +} diff --git a/libs/dolphin/os/OSResetSW.c b/libs/dolphin/os/OSResetSW.c new file mode 100644 index 000000000..24766fd35 --- /dev/null +++ b/libs/dolphin/os/OSResetSW.c @@ -0,0 +1,118 @@ +#include + +extern OSTime __OSGetSystemTime(); + +u8 GameChoice : (OS_BASE_CACHED | 0x30E3); + +vu32 __PIRegs[12] : 0xCC003000; + +extern OSTime __OSStartTime; + +static OSResetCallback ResetCallback; +static BOOL Down; +static BOOL LastState; +static OSTime HoldUp; +static OSTime HoldDown; + +void __OSResetSWInterruptHandler(__OSInterrupt interrupt, OSContext *context) +{ + OSResetCallback callback; + + HoldDown = __OSGetSystemTime(); + while (__OSGetSystemTime() - HoldDown < OSMicrosecondsToTicks(100) && + !(__PIRegs[0] & 0x00010000)) + { + ; + } + if (!(__PIRegs[0] & 0x00010000)) + { + LastState = Down = TRUE; + __OSMaskInterrupts(OS_INTERRUPTMASK_PI_RSW); + if (ResetCallback) + { + callback = ResetCallback; + ResetCallback = NULL; + callback(); + } + } + __PIRegs[0] = 2; +} + +BOOL OSGetResetButtonState(void) +{ + BOOL enabled; + BOOL state; + u32 reg; + OSTime now; + + enabled = OSDisableInterrupts(); + + now = __OSGetSystemTime(); + + reg = __PIRegs[0]; + if (!(reg & 0x00010000)) + { + if (!Down) + { + Down = TRUE; + state = HoldUp ? TRUE : FALSE; + HoldDown = now; + } + else + { + state = (HoldUp || (OSMicrosecondsToTicks(100) < now - HoldDown)) ? TRUE : FALSE; + } + } + else if (Down) + { + Down = FALSE; + state = LastState; + if (state) + { + HoldUp = now; + } + else + { + HoldUp = 0; + } + } + else if (HoldUp && (now - HoldUp < OSMillisecondsToTicks(40))) + { + state = TRUE; + } + else + { + state = FALSE; + HoldUp = 0; + } + + LastState = state; + + if (GameChoice & 0x1f) + { + OSTime fire = (GameChoice & 0x1f) * 60; + fire = __OSStartTime + OSSecondsToTicks(fire); + if (fire < now) + { + now -= fire; + now = OSTicksToSeconds(now) / 2; + if ((now & 1) == 0) + { + state = TRUE; + } + else + { + state = FALSE; + } + } + } + + OSRestoreInterrupts(enabled); + return state; +} + +#pragma dont_inline on + +BOOL OSGetResetSwitchState(void) { return OSGetResetButtonState(); } + +#pragma dont_inline reset diff --git a/libs/dolphin/os/OSRtc.c b/libs/dolphin/os/OSRtc.c new file mode 100644 index 000000000..b76bcdc21 --- /dev/null +++ b/libs/dolphin/os/OSRtc.c @@ -0,0 +1,399 @@ +#include "dolphin/OSRtcPriv.h" +#include "dolphin/os.h" + +#define RTC_CMD_READ 0x20000000 +#define RTC_CMD_WRITE 0xa0000000 + +#define RTC_SRAM_ADDR 0x00000100 +#define RTC_SRAM_SIZE 64 + +#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; + +static SramControlBlock Scb ALIGN(32); + +static BOOL GetRTC(u32* rtc) { + BOOL err; + u32 cmd; + + if (!EXILock(RTC_CHAN, RTC_DEV, 0)) { + return FALSE; + } + if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { + EXIUnlock(RTC_CHAN); + return FALSE; + } + + cmd = RTC_CMD_READ; + err = FALSE; + err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL); + err |= !EXISync(RTC_CHAN); + err |= !EXIImm(RTC_CHAN, &cmd, 4, 0, NULL); + err |= !EXISync(RTC_CHAN); + err |= !EXIDeselect(RTC_CHAN); + EXIUnlock(RTC_CHAN); + + *rtc = cmd; + + return !err; +} + +BOOL __OSGetRTC(u32* rtc) { + BOOL err; + u32 t0; + u32 t1; + int i; + + for (i = 0; i < 16; i++) { + err = FALSE; + err |= !GetRTC(&t0); + err |= !GetRTC(&t1); + if (err) { + break; + } + if (t0 == t1) { + *rtc = t0; + return TRUE; + } + } + return FALSE; +} + +BOOL __OSSetRTC(u32 rtc) { + BOOL err; + u32 cmd; + + if (!EXILock(RTC_CHAN, RTC_DEV, 0)) { + return FALSE; + } + if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { + EXIUnlock(RTC_CHAN); + return FALSE; + } + + cmd = RTC_CMD_WRITE; + err = FALSE; + err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL); + err |= !EXISync(RTC_CHAN); + err |= !EXIImm(RTC_CHAN, &rtc, 4, 1, NULL); + err |= !EXISync(RTC_CHAN); + err |= !EXIDeselect(RTC_CHAN); + EXIUnlock(RTC_CHAN); + + return !err; +} + +static BOOL ReadSram(void* buffer) { + BOOL err; + u32 cmd; + + DCInvalidateRange(buffer, RTC_SRAM_SIZE); + + if (!EXILock(RTC_CHAN, RTC_DEV, 0)) { + return FALSE; + } + if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { + EXIUnlock(RTC_CHAN); + return FALSE; + } + + 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); + + return !err; +} + +BOOL WriteSram(void* buffer, u32 offset, u32 size); +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; + } +} + +BOOL WriteSram(void* buffer, u32 offset, u32 size) { + BOOL err; + u32 cmd; + + if (!EXILock(RTC_CHAN, RTC_DEV, WriteSramCallback)) { + return FALSE; + } + if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { + EXIUnlock(RTC_CHAN); + return FALSE; + } + + 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); + + return !err; +} + +void __OSInitSram() { + Scb.locked = Scb.enabled = FALSE; + Scb.sync = ReadSram(Scb.sram); + Scb.offset = RTC_SRAM_SIZE; + + OSSetGbsMode(OSGetGbsMode()); +} + +static void* LockSram(u32 offset) { + BOOL enabled; + enabled = OSDisableInterrupts(); + + if (Scb.locked != FALSE) { + OSRestoreInterrupts(enabled); + return NULL; + } + + Scb.enabled = enabled; + Scb.locked = TRUE; + + return Scb.sram + offset; +} + +OSSram* __OSLockSram() { return LockSram(0); } + +OSSramEx* __OSLockSramEx() { return LockSram(sizeof(OSSram)); } + +static BOOL UnlockSram(BOOL commit, u32 offset) { + u16* p; + + if (commit) { + if (offset == 0) { + 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++) { + sram->checkSum += *p; + sram->checkSumInv += ~*p; + } + } + + if (offset < Scb.offset) { + Scb.offset = offset; + } + // this isn't in prime? + if (Scb.offset <= 20) + { + // this seems to work? esp. since we have GbsMode functions when prime doesn't + // wacky tho + OSSramEx *sramEx = (OSSramEx *)(&Scb.sram[20]); + if ((u32)(sramEx->gbs & 0x7C00) == 0x5000 || (u32)(sramEx->gbs & 0xC0) == 0xC0) + { + sramEx->gbs = 0; + } + } + + Scb.sync = WriteSram(Scb.sram + Scb.offset, Scb.offset, RTC_SRAM_SIZE - Scb.offset); + if (Scb.sync) { + Scb.offset = RTC_SRAM_SIZE; + } + } + Scb.locked = FALSE; + OSRestoreInterrupts(Scb.enabled); + return Scb.sync; +} + +BOOL __OSUnlockSram(BOOL commit) { return UnlockSram(commit, 0); } + +BOOL __OSUnlockSramEx(BOOL commit) { return UnlockSram(commit, sizeof(OSSram)); } + +BOOL __OSSyncSram() { return Scb.sync; } + +BOOL __OSReadROM(void* buffer, s32 length, s32 offset) { + BOOL err; + u32 cmd; + + DCInvalidateRange(buffer, (u32)length); + + if (!EXILock(RTC_CHAN, RTC_DEV, 0)) { + return FALSE; + } + if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { + EXIUnlock(RTC_CHAN); + return FALSE; + } + + cmd = (u32)(offset << 6); + err = FALSE; + err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL); + err |= !EXISync(RTC_CHAN); + err |= !EXIDma(RTC_CHAN, buffer, length, 0, NULL); + err |= !EXISync(RTC_CHAN); + err |= !EXIDeselect(RTC_CHAN); + EXIUnlock(RTC_CHAN); + + return !err; +} + +inline OSSram* __OSLockSramHACK() { return LockSram(0); } +u32 OSGetSoundMode() { + OSSram* sram; + u32 mode; + + sram = __OSLockSramHACK(); + mode = (sram->flags & 0x4) ? OS_SOUND_MODE_STEREO : OS_SOUND_MODE_MONO; + __OSUnlockSram(FALSE); + return mode; +} + +void OSSetSoundMode(u32 mode) { + OSSram* sram; + mode <<= 2; + mode &= 4; + + sram = __OSLockSramHACK(); + if (mode == (sram->flags & 4)) { + __OSUnlockSram(FALSE); + return; + } + + sram->flags &= ~4; + sram->flags |= mode; + __OSUnlockSram(TRUE); +} + +u32 OSGetProgressiveMode() { + OSSram* sram; + u32 mode; + + sram = __OSLockSramHACK(); + mode = (sram->flags & 0x80) >> 7; + __OSUnlockSram(FALSE); + return mode; +} + +void OSSetProgressiveMode(u32 mode) { + OSSram* sram; + mode <<= 7; + mode &= 0x80; + + sram = __OSLockSramHACK(); + if (mode == (sram->flags & 0x80)) { + __OSUnlockSram(FALSE); + return; + } + + sram->flags &= ~0x80; + sram->flags |= mode; + __OSUnlockSram(TRUE); +} + +u8 OSGetLanguage() { + OSSram* sram; + u8 language; + + sram = __OSLockSramHACK(); + language = sram->language; + __OSUnlockSram(FALSE); + return language; +} + +u32 OSGetEuRgb60Mode() { + OSSram *sram; + u32 on; + sram = __OSLockSramHACK(); + on = (sram->ntd >> 6) & 0x1; + __OSUnlockSram(FALSE); + return on; +} + +void OSSetEuRgb60Mode(u32 mode) +{ + OSSram *sram; + mode <<= 6; + mode &= 0x40; + + sram = __OSLockSramHACK(); + if (mode == (sram->ntd & 0x40)) + { + __OSUnlockSram(FALSE); + return; + } + + sram->ntd &= ~0x40; + sram->ntd |= mode; + __OSUnlockSram(TRUE); +} + +u16 OSGetWirelessID(s32 channel) { + OSSramEx* sram; + u16 id; + + sram = __OSLockSramEx(); + id = sram->wirelessPadID[channel]; + __OSUnlockSramEx(FALSE); + return id; +} + +void OSSetWirelessID(s32 channel, u16 id) { + OSSramEx* sram; + + sram = __OSLockSramEx(); + if (sram->wirelessPadID[channel] != id) { + sram->wirelessPadID[channel] = id; + __OSUnlockSramEx(TRUE); + return; + } + + __OSUnlockSramEx(FALSE); +} + +u16 OSGetGbsMode() +{ + OSSramEx *sram; + u16 id; + + sram = __OSLockSramEx(); + id = sram->gbs; + __OSUnlockSramEx(FALSE); + return id; +} + +void OSSetGbsMode(u16 mode) +{ + OSSramEx *sram; + + // same odd code as in UnlockSram? + if ((u32)(mode & 0x7C00) == 0x5000 || (u32)(mode & 0xC0) == 0xC0) + { + mode = 0; + } + + sram = __OSLockSramEx(); + if (mode == sram->gbs) + { + __OSUnlockSramEx(FALSE); + return; + } + + sram->gbs = mode; + __OSUnlockSramEx(TRUE); +} \ No newline at end of file diff --git a/libs/dolphin/os/OSSync.c b/libs/dolphin/os/OSSync.c new file mode 100644 index 000000000..5681518ed --- /dev/null +++ b/libs/dolphin/os/OSSync.c @@ -0,0 +1,29 @@ +#include +#include "dolphin/base/PPCArch.h" +#include "dolphin/os.h" + +void __OSSystemCallVectorStart(); +void __OSSystemCallVectorEnd(); +static asm void SystemCallVector() { + nofralloc +entry __OSSystemCallVectorStart + mfspr r9, HID0 + ori r10, r9, 8 + mtspr HID0, r10 + isync + sync + mtspr HID0, r9 + + rfi + +entry __OSSystemCallVectorEnd + nop +} + +void __OSInitSystemCall() { + void* addr = OSPhysicalToCached(0x00C00); + memcpy(addr, __OSSystemCallVectorStart, (size_t)__OSSystemCallVectorEnd - (size_t)__OSSystemCallVectorStart); + DCFlushRangeNoSync(addr, 0x100); + __sync(); + ICInvalidateRange(addr, 0x100); +} diff --git a/libs/dolphin/os/OSThread.c b/libs/dolphin/os/OSThread.c new file mode 100644 index 000000000..016bfd3bd --- /dev/null +++ b/libs/dolphin/os/OSThread.c @@ -0,0 +1,590 @@ +#include "dolphin/os/OSPriv.h" + +static vu32 RunQueueBits; +static volatile BOOL RunQueueHint; +static vs32 Reschedule; + +static OSThreadQueue RunQueue[32]; +static OSThread IdleThread; +static OSThread DefaultThread; +static OSContext IdleContext; +static void DefaultSwitchThreadCallback(OSThread* from, OSThread* to); +static OSSwitchThreadCallback SwitchThreadCallback = DefaultSwitchThreadCallback; + +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; + +static void DefaultSwitchThreadCallback(OSThread* from, OSThread* to) {} + +extern u8 _stack_addr[]; +extern u8 _stack_end[]; + +#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 AddPrio(queue, thread, link) \ + do { \ + OSThread *prev, *next; \ + \ + for (next = (queue)->head; next && next->priority <= thread->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 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 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) + +static inline void OSInitMutexQueue(OSMutexQueue* queue) { queue->head = queue->tail = NULL; } + +static inline void OSSetCurrentThread(OSThread* thread) { + SwitchThreadCallback(__OSCurrentThread, thread); + __OSCurrentThread = thread; +} + +void __OSThreadInit() { + OSThread* thread = &DefaultThread; + int prio; + + thread->state = OS_THREAD_STATE_RUNNING; + thread->attr = OS_THREAD_ATTR_DETACH; + thread->priority = thread->base = 16; + thread->suspend = 0; + thread->val = (void*)-1; + thread->mutex = NULL; + OSInitThreadQueue(&thread->queueJoin); + OSInitMutexQueue(&thread->queueMutex); + + __OSFPUContext = &thread->context; + + OSClearContext(&thread->context); + OSSetCurrentContext(&thread->context); + thread->stackBase = (void*)_stack_addr; + thread->stackEnd = (void*)_stack_end; + *(thread->stackEnd) = OS_THREAD_STACK_MAGIC; + + OSSetCurrentThread(thread); + OSClearStack(0); + + RunQueueBits = 0; + RunQueueHint = FALSE; + for (prio = OS_PRIORITY_MIN; prio <= OS_PRIORITY_MAX; ++prio) { + OSInitThreadQueue(&RunQueue[prio]); + } + + OSInitThreadQueue(&__OSActiveThreadQueue); + AddTail(&__OSActiveThreadQueue, thread, linkActive); + OSClearContext(&IdleContext); + Reschedule = 0; +} + +void OSInitThreadQueue(OSThreadQueue* queue) { queue->head = queue->tail = NULL; } + +OSThread* OSGetCurrentThread() { return __OSCurrentThread; } + +static void __OSSwitchThread(OSThread *nextThread) +{ + OSSetCurrentThread(nextThread); + OSSetCurrentContext(&nextThread->context); + OSLoadContext(&nextThread->context); +} + +BOOL OSIsThreadTerminated(OSThread *thread) +{ + return (thread->state == OS_THREAD_STATE_MORIBUND || thread->state == OS_THREAD_STATE_NULL) ? TRUE : FALSE; +} + +s32 OSDisableScheduler() { + BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + count = Reschedule++; + OSRestoreInterrupts(enabled); + return count; +} + +s32 OSEnableScheduler() { + BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + count = Reschedule--; + OSRestoreInterrupts(enabled); + return count; +} + +static void SetRun(OSThread* thread) { + thread->queue = &RunQueue[thread->priority]; + AddTail(thread->queue, thread, link); + RunQueueBits |= 1u << (OS_PRIORITY_MAX - thread->priority); + RunQueueHint = TRUE; +} +#pragma dont_inline on +static void UnsetRun(OSThread* thread) { + OSThreadQueue* queue; + queue = thread->queue; + RemoveItem(queue, thread, link); + if (queue->head == 0) + RunQueueBits &= ~(1u << (OS_PRIORITY_MAX - thread->priority)); + thread->queue = NULL; +} +#pragma dont_inline reset + +OSPriority __OSGetEffectivePriority(OSThread* thread) { + OSPriority priority; + OSMutex* mutex; + OSThread* blocked; + + priority = thread->base; + for (mutex = thread->queueMutex.head; mutex; mutex = mutex->link.next) { + blocked = mutex->queue.head; + if (blocked && blocked->priority < priority) { + priority = blocked->priority; + } + } + return priority; +} + +static OSThread* SetEffectivePriority(OSThread* thread, OSPriority priority) { + switch (thread->state) { + case OS_THREAD_STATE_READY: + UnsetRun(thread); + thread->priority = priority; + SetRun(thread); + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->priority = priority; + AddPrio(thread->queue, thread, link); + if (thread->mutex) { + return thread->mutex->thread; + } + break; + case OS_THREAD_STATE_RUNNING: + RunQueueHint = TRUE; + thread->priority = priority; + break; + } + return NULL; +} + +static void UpdatePriority(OSThread* thread) { + OSPriority priority; + + do { + if (0 < thread->suspend) { + break; + } + priority = __OSGetEffectivePriority(thread); + if (thread->priority == priority) { + break; + } + thread = SetEffectivePriority(thread, priority); + } while (thread); +} + +void __OSPromoteThread(OSThread *thread, OSPriority priority) +{ + do + { + if (thread->suspend > 0) + { + break; + } + if (thread->priority <= priority) + { + break; + } + + thread = SetEffectivePriority(thread, priority); + } while (thread); +} + +static OSThread *SelectThread(BOOL yield) +{ + OSContext *currentContext; + OSThread *currentThread; + OSThread *nextThread; + OSPriority priority; + OSThreadQueue *queue; + + if (0 < Reschedule) + { + return 0; + } + + currentContext = OSGetCurrentContext(); + currentThread = OSGetCurrentThread(); + if (currentContext != ¤tThread->context) + { + return 0; + } + + if (currentThread) + { + if (currentThread->state == OS_THREAD_STATE_RUNNING) + { + if (!yield) + { + priority = __cntlzw(RunQueueBits); + if (currentThread->priority <= priority) + { + return 0; + } + } + currentThread->state = OS_THREAD_STATE_READY; + SetRun(currentThread); + } + + if (!(currentThread->context.state & OS_CONTEXT_STATE_EXC) && OSSaveContext(¤tThread->context)) + { + return 0; + } + } + + if (RunQueueBits == 0) + { + SwitchThreadCallback(__OSCurrentThread, nullptr); + __OSCurrentThread = nullptr; + OSSetCurrentContext(&IdleContext); + do + { + OSEnableInterrupts(); + while (RunQueueBits == 0) + ; + OSDisableInterrupts(); + } while (RunQueueBits == 0); + + OSClearContext(&IdleContext); + } + + RunQueueHint = FALSE; + + priority = __cntlzw(RunQueueBits); + queue = &RunQueue[priority]; + RemoveHead(queue, nextThread, link); + if (queue->head == 0) + { + RunQueueBits &= ~(1u << (OS_PRIORITY_MAX - priority)); + } + nextThread->queue = NULL; + nextThread->state = OS_THREAD_STATE_RUNNING; + __OSSwitchThread(nextThread); + return nextThread; +} + +void __OSReschedule() { + if (!RunQueueHint) { + return; + } + + SelectThread(FALSE); +} + +void OSYieldThread(void) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + SelectThread(TRUE); + OSRestoreInterrupts(enabled); +} + +BOOL OSCreateThread(OSThread *thread, OSThreadStartFunction func, void *param, void *stack, u32 stackSize, OSPriority priority, u16 attr) +{ + BOOL enable; + u32 stackThing; + int i; + u32 tmp[2]; // DUMB compiler smfh. + + if (priority < OS_PRIORITY_MIN || priority > OS_PRIORITY_MAX) + { + return FALSE; + } + + stackThing = ((u32)stack & 0xFFFFFFF8); // ?? + thread->state = OS_THREAD_STATE_READY; + thread->attr = attr & OS_THREAD_ATTR_DETACH; + thread->base = priority; + thread->priority = priority; + thread->suspend = 1; + thread->val = (void *)-1; + thread->mutex = nullptr; + OSInitThreadQueue(&thread->queueJoin); + OSInitMutexQueue(&thread->queueMutex); + *(u32 *)(stackThing - 8) = 0; + *(u32 *)(stackThing - 4) = 0; + + OSInitContext(&thread->context, (u32)func, (u32)(stackThing - 8)); + + thread->context.lr = (u32)&OSExitThread; + thread->context.gpr[3] = (u32)param; + thread->stackBase = stack; + thread->stackEnd = (u32 *)((u32)stack - stackSize); + *(thread->stackEnd) = OS_THREAD_STACK_MAGIC; + thread->error = 0; + thread->specific[0] = nullptr; + thread->specific[1] = nullptr; + + enable = OSDisableInterrupts(); + + if (__OSErrorTable[OS_ERROR_FPE] != nullptr) + { + thread->context.srr1 |= 0x900; // ?? + thread->context.state |= OS_CONTEXT_STATE_FPSAVED; + thread->context.fpscr = (__OSFpscrEnableBits & 0xF8) | 0x4; // ?? + + for (i = 0; i < 32; i++) + { + *(u64 *)&thread->context.fpr[i] = -1; // ??????? + *(u64 *)&thread->context.psf[i] = -1; // ??????? + } + } + + AddTail(&__OSActiveThreadQueue, thread, linkActive); + OSRestoreInterrupts(enable); + return TRUE; +} + +void OSExitThread(void *val) +{ + OSThread *thread; + BOOL enable; + + enable = OSDisableInterrupts(); + thread = __OSCurrentThread; + OSClearContext(&thread->context); + + if (thread->attr & OS_THREAD_ATTR_DETACH) + { + RemoveItem(&__OSActiveThreadQueue, thread, linkActive); + thread->state = OS_THREAD_STATE_NULL; + } + else + { + thread->state = OS_THREAD_STATE_MORIBUND; + thread->val = val; + } + + __OSUnlockAllMutex(thread); + OSWakeupThread(&thread->queueJoin); + RunQueueHint = TRUE; + if (RunQueueHint != FALSE) + { + SelectThread(FALSE); + } + + OSRestoreInterrupts(enable); +} + +void OSCancelThread(OSThread* thread) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + + switch (thread->state) { + case OS_THREAD_STATE_READY: + if (!(0 < thread->suspend)) { + UnsetRun(thread); + } + break; + case OS_THREAD_STATE_RUNNING: + RunQueueHint = TRUE; + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->queue = NULL; + if (!(0 < thread->suspend) && thread->mutex) { + UpdatePriority(thread->mutex->thread); + } + break; + default: + OSRestoreInterrupts(enabled); + return; + } + + OSClearContext(&thread->context); + if (thread->attr & OS_THREAD_ATTR_DETACH) { + RemoveItem(&__OSActiveThreadQueue, thread, linkActive); + thread->state = 0; + } else { + thread->state = OS_THREAD_STATE_MORIBUND; + } + + __OSUnlockAllMutex(thread); + + OSWakeupThread(&thread->queueJoin); + + __OSReschedule(); + OSRestoreInterrupts(enabled); + + return; +} + +void OSDetachThread(OSThread *thread) +{ + BOOL enable; + + enable = OSDisableInterrupts(); + thread->attr |= OS_THREAD_ATTR_DETACH; + if (thread->state == OS_THREAD_STATE_MORIBUND) + { + RemoveItem(&__OSActiveThreadQueue, thread, linkActive); + thread->state = OS_THREAD_STATE_NULL; + } + + OSWakeupThread(&thread->queueJoin); + OSRestoreInterrupts(enable); +} + +s32 OSResumeThread(OSThread* thread) { + BOOL enabled; + s32 suspendCount; + + enabled = OSDisableInterrupts(); + suspendCount = thread->suspend--; + if (thread->suspend < 0) { + thread->suspend = 0; + } else if (thread->suspend == 0) { + switch (thread->state) { + case OS_THREAD_STATE_READY: + thread->priority = __OSGetEffectivePriority(thread); + SetRun(thread); + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->priority = __OSGetEffectivePriority(thread); + AddPrio(thread->queue, thread, link); + if (thread->mutex) { + UpdatePriority(thread->mutex->thread); + } + break; + } + __OSReschedule(); + } + OSRestoreInterrupts(enabled); + return suspendCount; +} + +s32 OSSuspendThread(OSThread* thread) { + BOOL enabled; + s32 suspendCount; + + enabled = OSDisableInterrupts(); + suspendCount = thread->suspend++; + if (suspendCount == 0) { + switch (thread->state) { + case OS_THREAD_STATE_RUNNING: + RunQueueHint = TRUE; + thread->state = OS_THREAD_STATE_READY; + break; + case OS_THREAD_STATE_READY: + UnsetRun(thread); + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->priority = 32; + AddTail(thread->queue, thread, link); + if (thread->mutex) { + UpdatePriority(thread->mutex->thread); + } + break; + } + + __OSReschedule(); + } + OSRestoreInterrupts(enabled); + return suspendCount; +} + +void OSSleepThread(OSThreadQueue* queue) { + BOOL enabled; + OSThread* currentThread; + + enabled = OSDisableInterrupts(); + currentThread = OSGetCurrentThread(); + + currentThread->state = OS_THREAD_STATE_WAITING; + currentThread->queue = queue; + AddPrio(queue, currentThread, link); + RunQueueHint = TRUE; + __OSReschedule(); + OSRestoreInterrupts(enabled); +} + +void OSWakeupThread(OSThreadQueue* queue) { + BOOL enabled; + OSThread* thread; + + enabled = OSDisableInterrupts(); + while (queue->head) { + RemoveHead(queue, thread, link); + thread->state = OS_THREAD_STATE_READY; + if (!(0 < thread->suspend)) { + SetRun(thread); + } + } + __OSReschedule(); + OSRestoreInterrupts(enabled); +} + +OSPriority OSGetThreadPriority(OSThread *thread) { return thread->base; } + +void OSClearStack(u8 val) { + register u32 sp; + register u32* p; + register u32 pattern; + + pattern = ((u32)val << 24) | ((u32)val << 16) | ((u32)val << 8) | (u32)val; + sp = OSGetStackPointer(); + for (p = __OSCurrentThread->stackEnd + 1; p < (u32*)sp; ++p) { + *p = pattern; + } +} diff --git a/libs/dolphin/os/OSTime.c b/libs/dolphin/os/OSTime.c new file mode 100644 index 000000000..803fe10bc --- /dev/null +++ b/libs/dolphin/os/OSTime.c @@ -0,0 +1,137 @@ +#include + +#define OS_TIME_MONTH_MAX 12 +#define OS_TIME_WEEK_DAY_MAX 7 +#define OS_TIME_YEAR_DAY_MAX 365 + +// End of each month in standard year +static s32 YearDays[OS_TIME_MONTH_MAX] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; +// End of each month in leap year +static s32 LeapYearDays[OS_TIME_MONTH_MAX] = {0, 31, 60, 91, 121, 152, + 182, 213, 244, 274, 305, 335}; + +asm OSTime OSGetTime(void) { + // clang-format off + nofralloc + + mftbu r3 + mftb r4 + + // Check for possible carry from TBL to TBU + mftbu r5 + cmpw r3, r5 + bne OSGetTime + + blr + // clang-format on +} + +asm OSTick OSGetTick(void){ + // clang-format off + nofralloc + + mftb r3 + blr + // clang-format on +} + +#define OS_SYSTEMTIME_BASE 0x30D8 + +OSTime __OSGetSystemTime(void) { + BOOL enabled; + OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE); + OSTime result; + + enabled = OSDisableInterrupts(); + result = *timeAdjustAddr + OSGetTime(); + OSRestoreInterrupts(enabled); + + return result; +} + +OSTime __OSTimeToSystemTime(OSTime time) { + BOOL enabled; + OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE); + OSTime result; + + enabled = OSDisableInterrupts(); + result = *timeAdjustAddr + time; + OSRestoreInterrupts(enabled); + + return result; +} + +static BOOL IsLeapYear(s32 year) { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); } + +static s32 GetYearDays(s32 year, s32 mon) { + return (IsLeapYear(year) ? LeapYearDays : YearDays)[mon]; +} + +static s32 GetLeapDays(s32 year) { + if (year < 1) { + return 0; + } + return (year + 3) / 4 - (year - 1) / 100 + (year - 1) / 400; +} + +static void GetDates(s32 days, OSCalendarTime* cal) { + s32 year; + s32 totalDays; + s32* p_days; + s32 month; + cal->wday = (days + 6) % OS_TIME_WEEK_DAY_MAX; + + for (year = days / OS_TIME_YEAR_DAY_MAX; + days < (totalDays = year * OS_TIME_YEAR_DAY_MAX + GetLeapDays(year));) { + year--; + } + + days -= totalDays; + cal->year = year; + cal->yday = days; + + p_days = IsLeapYear(year) ? LeapYearDays : YearDays; + month = OS_TIME_MONTH_MAX; + while (days < p_days[--month]) { + ; + } + cal->mon = month; + cal->mday = days - p_days[month] + 1; +} + +#define BIAS (2000 * 365 + (2000 + 3) / 4 - (2000 - 1) / 100 + (2000 - 1) / 400) + +#pragma push +#pragma dont_inline on +void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* td) { + int days; + int secs; + OSTime d; + + d = ticks % OSSecondsToTicks(1); + if (d < 0) { + d += OSSecondsToTicks(1); + } + td->usec = (int)(OSTicksToMicroseconds(d) % 1000); + td->msec = (int)(OSTicksToMilliseconds(d) % 1000); + + ticks -= d; + days = (int)(OSTicksToSeconds(ticks) / 86400 + BIAS); + secs = (int)(OSTicksToSeconds(ticks) % 86400); + if (secs < 0) { + days -= 1; + secs += 24 * 60 * 60; + } + + GetDates(days, td); + + td->hour = secs / 60 / 60; + td->min = (secs / 60) % 60; + td->sec = secs % 60; +} +#pragma dont_inline reset + +OSTime OSCalendarTimeToTicks(const OSCalendarTime* time) { + ; + ; +} diff --git a/libs/dolphin/os/init/__ppc_eabi_init.cpp b/libs/dolphin/os/init/__ppc_eabi_init.cpp new file mode 100644 index 000000000..ea0791dd2 --- /dev/null +++ b/libs/dolphin/os/init/__ppc_eabi_init.cpp @@ -0,0 +1,74 @@ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void __OSPSInit(); +void __OSFPRInit(); +void __OSCacheInit(); + +typedef void (*voidfunctionptr)(void); // pointer to function returning void +__declspec(section ".ctors") extern voidfunctionptr _ctors[]; +__declspec(section ".dtors") extern voidfunctionptr _dtors[]; + +static void __init_cpp(void); + +// clang-format off +__declspec(section ".init") asm void __init_hardware(void) { + nofralloc + mfmsr r0 + ori r0,r0,0x2000 + mtmsr r0 + mflr r31 + bl __OSPSInit + bl __OSFPRInit + bl __OSCacheInit + mtlr r31 + blr +} + +__declspec(section ".init") asm void __flush_cache(void) { + nofralloc + lis r5, 0xFFFFFFF1@h + ori r5, r5, 0xFFFFFFF1@l + and r5, r5, r3 + subf r3, r5, r3 + add r4, r4, r3 +loop: + dcbst 0, r5 + sync + icbi 0, r5 + addic r5, r5, 8 + addic. r4, r4, -8 + bge loop + isync + blr +} +// clang-format on + + +void __init_user(void) { __init_cpp(); } + +static void __init_cpp(void) +{ + voidfunctionptr* constructor; + /* + * call static initializers + */ + for (constructor = _ctors; *constructor; constructor++) { + (*constructor)(); + } +} + + +void __fini_cpp(void) +{ + // UNUSED FUNCTION +} + +void _ExitProcess(void) { PPCHalt(); } +#ifdef __cplusplus +} +#endif diff --git a/libs/dolphin/os/init/__start.c b/libs/dolphin/os/init/__start.c new file mode 100644 index 000000000..0fa8a9546 --- /dev/null +++ b/libs/dolphin/os/init/__start.c @@ -0,0 +1,223 @@ +#include "dolphin/os/init/__start.h" +#include "PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h" +#include "PowerPC_EABI_Support/MetroTRK/dolphin_trk.h" + +void __check_pad3(void) +{ + if ((Pad3Button & 0x0eef) == 0x0eef) + { + OSResetSystem(OS_RESET_RESTART, 0, FALSE); + } + return; +} + +void __set_debug_bba(void) +{ + Debug_BBA = 1; +} + +u8 __get_debug_bba(void) +{ + return Debug_BBA; +} + +__declspec(weak) asm void __start(void) +{ + // clang-format off + nofralloc + bl __init_registers + bl __init_hardware + li r0, -1 + stwu r1, -8(r1) + stw r0, 4(r1) + stw r0, 0(r1) + bl __init_data + li r0, 0 + lis r6, EXCEPTIONMASK_ADDR@ha + addi r6, r6, EXCEPTIONMASK_ADDR@l + stw r0, 0(r6) + lis r6, BOOTINFO2_ADDR@ha + addi r6, r6, BOOTINFO2_ADDR@l + lwz r6, 0(r6) + +_check_TRK: + cmplwi r6, 0 + beq _load_lomem_debug_flag + lwz r7, OS_BI2_DEBUGFLAG_OFFSET(r6) + b _check_debug_flag + +_load_lomem_debug_flag: + lis r5, ARENAHI_ADDR@ha + addi r5, r5, ARENAHI_ADDR@l + lwz r5, 0(r5) + cmplwi r5, 0 + beq _goto_main + lis r7, DEBUGFLAG_ADDR@ha + addi r7, r7, DEBUGFLAG_ADDR@l + lwz r7, 0(r7) + +_check_debug_flag: + li r5, 0 + cmplwi r7, 2 + beq _goto_inittrk + cmplwi r7, 3 + li r5, 1 + beq _goto_inittrk + cmplwi r7, 4 + bne _goto_main + li r5, 2 + bl __set_debug_bba + b _goto_main + +_goto_inittrk: + lis r6, InitMetroTRK@ha + addi r6, r6, InitMetroTRK@l + mtlr r6 + blrl + +_goto_main: + lis r6, BOOTINFO2_ADDR@ha + addi r6, r6, BOOTINFO2_ADDR@l + lwz r5, 0(r6) + cmplwi r5, 0 + beq+ _no_args + lwz r6, 8(r5) + cmplwi r6, 0 + beq+ _no_args + add r6, r5, r6 + lwz r14, 0(r6) + cmplwi r14, 0 + beq _no_args + addi r15, r6, 4 + mtctr r14 + +_loop: + addi r6, r6, 4 + lwz r7, 0(r6) + add r7, r7, r5 + stw r7, 0(r6) + bdnz _loop + lis r5, ARENAHI_ADDR@ha + addi r5, r5, ARENAHI_ADDR@l + rlwinm r7, r15, 0, 0, 0x1a + stw r7, 0(r5) + b _end_of_parseargs + +_no_args: + li r14, 0 + li r15, 0 + +_end_of_parseargs: + bl DBInit + bl OSInit + lis r4, DVD_DEVICECODE_ADDR@ha + addi r4, r4, DVD_DEVICECODE_ADDR@l + lhz r3, 0(r4) + andi. r5, r3, 0x8000 + beq _check_pad3 + andi. r3, r3, 0x7fff + cmplwi r3, 1 + bne _skip_crc + +_check_pad3: + bl __check_pad3 + +_skip_crc: + bl __get_debug_bba + cmplwi r3, 1 + bne _goto_skip_init_bba + bl InitMetroTRK_BBA + +_goto_skip_init_bba: + bl __init_user + mr r3, r14 + mr r4, r15 + bl main + b exit + // clang-format on +} + +__declspec(section ".init") static void __copy_rom_section(void* dst, const void* src, + unsigned long size) +{ + if (size && (dst != src)) + { + memcpy(dst, src, size); + __flush_cache(dst, size); + } +} + +__declspec(section ".init") static void __init_bss_section(void* dst, unsigned long size) +{ + if (size) + { + memset(dst, 0, size); + } +} + +asm static void __init_registers(void) +{ + // clang-format off + nofralloc + li r0, 0 + li r3, 0 + li r4, 0 + li r5, 0 + li r6, 0 + li r7, 0 + li r8, 0 + li r9, 0 + li r10, 0 + li r11, 0 + li r12, 0 + li r14, 0 + li r15, 0 + li r16, 0 + li r17, 0 + li r18, 0 + li r19, 0 + li r20, 0 + li r21, 0 + li r22, 0 + li r23, 0 + li r24, 0 + li r25, 0 + li r26, 0 + li r27, 0 + li r28, 0 + li r29, 0 + li r30, 0 + li r31, 0 + lis r1, _stack_addr@h + ori r1, r1, _stack_addr@l + lis r2, _SDA2_BASE_@h + ori r2, r2, _SDA2_BASE_@l + lis r13, _SDA_BASE_@h + ori r13, r13, _SDA_BASE_@l + blr + // clang-format on +} + +void __init_data(void) +{ + __rom_copy_info* dci; + __bss_init_info* bii; + + dci = _rom_copy_info; + while (TRUE) + { + if (dci->size == 0) + break; + __copy_rom_section(dci->addr, dci->rom, dci->size); + dci++; + } + + bii = _bss_init_info; + while (TRUE) + { + if (bii->size == 0) + break; + __init_bss_section(bii->addr, bii->size); + bii++; + } +} diff --git a/libs/dolphin/pad/Pad.c b/libs/dolphin/pad/Pad.c new file mode 100644 index 000000000..f648d1cb5 --- /dev/null +++ b/libs/dolphin/pad/Pad.c @@ -0,0 +1,901 @@ +#include +#include +#include + +const char* __PADVersion = "<< Dolphin SDK - PAD\trelease build: Aug 6 2003 04:30:02 (0x2301) >>"; + +u8 UnkVal : (OS_BASE_CACHED | 0x30E3); +u16 __OSWirelessPadFixMode : (OS_BASE_CACHED | 0x30E0); + +static void PADTypeAndStatusCallback(s32 chan, u32 type); +static void PADOriginCallback(s32 chan, u32 error, OSContext* context); +static void PADProbeCallback(s32 chan, u32 error, OSContext* context); +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 void PADTypeAndStatusCallback(s32 chan, u32 type); + +static void PADOriginCallback(s32 chan, u32 error, OSContext* context); +static void PADProbeCallback(s32 chan, u32 error, OSContext* context); + +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 Initialized; + +static u32 EnabledBits; +static u32 ResettingBits; +static s32 ResettingChan = 32; +static u32 RecalibrateBits; +static u32 WaitingBits; +static u32 CheckingBits; +static u32 PendingBits; +static u32 BarrelBits; + +static u32 XPatchBits = PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT; + +static u32 AnalogMode = 0x00000300u; + +u32 __PADSpec; +static u32 Spec = 5; +static void (*MakeStatus)(s32, PADStatus*, u32[2]) = SPEC2_MakeStatus; + +static u32 Type[SI_MAX_CHAN]; +static PADStatus Origin[SI_MAX_CHAN]; + +static u32 CmdReadOrigin = 0x41 << 24; +static u32 CmdCalibrate = 0x42 << 24; +static u32 CmdProbeDevice[SI_MAX_CHAN]; + +static BOOL OnReset(BOOL final); + +static OSResetFunctionInfo ResetFunctionInfo = { OnReset, 127 }; + +static void (*SamplingCallback)(void); + +static void PADEnable(s32 chan) +{ + u32 cmd; + u32 chanBit; + u32 data[2]; + + chanBit = PAD_CHAN0_BIT >> chan; + EnabledBits |= chanBit; + SIGetResponse(chan, data); + cmd = (0x40 << 16) | AnalogMode; + SISetCommand(chan, cmd); + SIEnablePolling(EnabledBits); +} + +static void PADDisable(s32 chan) +{ + BOOL enabled; + u32 chanBit; + + enabled = OSDisableInterrupts(); + + chanBit = PAD_CHAN0_BIT >> chan; + SIDisablePolling(chanBit); + EnabledBits &= ~chanBit; + WaitingBits &= ~chanBit; + CheckingBits &= ~chanBit; + PendingBits &= ~chanBit; + BarrelBits &= ~chanBit; + OSSetWirelessID(chan, 0); + + OSRestoreInterrupts(enabled); +} + +static void DoReset(void) +{ + u32 chanBit; + + ResettingChan = __cntlzw(ResettingBits); + if (ResettingChan == 32) + { + return; + } + + 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; + } + + 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) +{ + if (!(error & + (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) + { + UpdateOrigin(ResettingChan); + PADEnable(ResettingChan); + } + DoReset(); +} + +static void PADOriginUpdateCallback(s32 chan, u32 error, OSContext* context) +{ + 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); + } +} + +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))) + { + PADEnable(ResettingChan); + WaitingBits |= PAD_CHAN0_BIT >> ResettingChan; + } + DoReset(); +} + +static void PADTypeAndStatusCallback(s32 chan, u32 type) +{ + u32 chanBit; + u32 recalibrate; + BOOL rc = TRUE; + u32 error; + chanBit = PAD_CHAN0_BIT >> ResettingChan; + error = type & 0xFF; + recalibrate = RecalibrateBits & chanBit; + RecalibrateBits &= ~chanBit; + + 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)) + { + DoReset(); + return; + } + + if (Spec < PAD_SPEC_2) + { + PADEnable(ResettingChan); + DoReset(); + return; + } + + if (!(type & SI_GC_WIRELESS) || (type & SI_WIRELESS_IR)) + { + if (recalibrate) + { + rc = SITransfer(ResettingChan, &CmdCalibrate, 3, &Origin[ResettingChan], 10, + PADOriginCallback, 0); + } + else + { + rc = SITransfer(ResettingChan, &CmdReadOrigin, 1, &Origin[ResettingChan], 10, + PADOriginCallback, 0); + } + } + else if ((type & SI_WIRELESS_FIX_ID) && (type & SI_WIRELESS_CONT_MASK) == SI_WIRELESS_CONT && + !(type & SI_WIRELESS_LITE)) + { + if (type & SI_WIRELESS_RECEIVED) + { + rc = SITransfer(ResettingChan, &CmdReadOrigin, 1, &Origin[ResettingChan], 10, + PADOriginCallback, 0); + } + else + { + rc = SITransfer(ResettingChan, &CmdProbeDevice[ResettingChan], 3, + &Origin[ResettingChan], 8, PADProbeCallback, 0); + } + } + if (!rc) + { + PendingBits |= chanBit; + DoReset(); + return; + } +} + +static void PADReceiveCheckCallback(s32 chan, u32 type) +{ + u32 error; + u32 chanBit; + + chanBit = PAD_CHAN0_BIT >> chan; + if (!(EnabledBits & chanBit)) + { + return; + } + + error = type & 0xFF; + type &= ~0xFF; + + 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); + } +} + +#pragma push +#pragma auto_inline off // fakematch most likely + +BOOL PADReset(u32 mask) +{ + BOOL enabled; + u32 diableBits; + + enabled = OSDisableInterrupts(); + + mask |= PendingBits; + PendingBits = 0; + mask &= ~(WaitingBits | CheckingBits); + ResettingBits |= mask; + diableBits = ResettingBits & EnabledBits; + EnabledBits &= ~mask; + BarrelBits &= ~mask; + + if (Spec == PAD_SPEC_4) + { + RecalibrateBits |= mask; + } + + SIDisablePolling(diableBits); + + if (ResettingChan == 32) + { + DoReset(); + } + OSRestoreInterrupts(enabled); + return TRUE; +} + +BOOL PADRecalibrate(u32 mask) +{ + BOOL enabled; + u32 disableBits; + + enabled = OSDisableInterrupts(); + + mask |= PendingBits; + PendingBits = 0; + mask &= ~(WaitingBits | CheckingBits); + ResettingBits |= mask; + disableBits = ResettingBits & EnabledBits; + EnabledBits &= ~mask; + BarrelBits &= ~mask; + + if (!(UnkVal & 0x40)) + { + RecalibrateBits |= mask; + } + + SIDisablePolling(disableBits); + if (ResettingChan == 32) + { + DoReset(); + } + OSRestoreInterrupts(enabled); + return TRUE; +} + +BOOL PADInit() +{ + s32 chan; + if (Initialized) + { + return TRUE; + } + + OSRegisterVersion(__PADVersion); + + 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); + 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); + } + + SIRefreshSamplingRate(); + OSRegisterResetFunction(&ResetFunctionInfo); + + return PADReset((PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT)); +} + +#define offsetof(type, memb) ((u32) & ((type*)0)->memb) + +u32 PADRead(PADStatus* status) +{ + BOOL enabled; + s32 chan; + u32 data[2]; + u32 chanBit; + u32 sr; + int chanShift; + u32 motor; + + enabled = OSDisableInterrupts(); + + motor = 0; + for (chan = 0; chan < SI_MAX_CHAN; chan++, status++) + { + chanBit = PAD_CHAN0_BIT >> chan; + chanShift = 8 * (SI_MAX_CHAN - 1 - chan); + + if (PendingBits & chanBit) + { + PADReset(0); + status->err = PAD_ERR_NOT_READY; + memset(status, 0, offsetof(PADStatus, err)); + continue; + } + + if ((ResettingBits & chanBit) || ResettingChan == chan) + { + status->err = PAD_ERR_NOT_READY; + memset(status, 0, offsetof(PADStatus, err)); + continue; + } + + if (!(EnabledBits & chanBit)) + { + status->err = (s8)PAD_ERR_NO_CONTROLLER; + memset(status, 0, offsetof(PADStatus, err)); + continue; + } + + if (SIIsChanBusy(chan)) + { + status->err = PAD_ERR_TRANSFER; + memset(status, 0, offsetof(PADStatus, err)); + continue; + } + + sr = SIGetStatus(chan); + if (sr & SI_ERROR_NO_RESPONSE) + { + SIGetResponse(chan, data); + + if (WaitingBits & chanBit) + { + status->err = (s8)PAD_ERR_NONE; + memset(status, 0, offsetof(PADStatus, err)); + + if (!(CheckingBits & chanBit)) + { + CheckingBits |= chanBit; + SIGetTypeAsync(chan, PADReceiveCheckCallback); + } + continue; + } + + PADDisable(chan); + + status->err = (s8)PAD_ERR_NO_CONTROLLER; + memset(status, 0, offsetof(PADStatus, err)); + continue; + } + + if (!(SIGetType(chan) & SI_GC_NOMOTOR)) + { + motor |= chanBit; + } + + if (!SIGetResponse(chan, data)) + { + status->err = PAD_ERR_TRANSFER; + memset(status, 0, offsetof(PADStatus, err)); + continue; + } + + if (data[0] & 0x80000000) + { + status->err = PAD_ERR_TRANSFER; + memset(status, 0, offsetof(PADStatus, err)); + continue; + } + + 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); + continue; + } + + status->err = PAD_ERR_NONE; + + // Clear PAD_INTERFERE bit + status->button &= ~0x0080; + } + + OSRestoreInterrupts(enabled); + return motor; +} + +#pragma pop + +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) & SI_GC_NOMOTOR)) + { + command = *commandArray; + if (Spec < PAD_SPEC_2 && command == PAD_MOTOR_STOP_HARD) + { + command = PAD_MOTOR_STOP; + } + + if (UnkVal & 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; + + enabled = OSDisableInterrupts(); + chanBit = PAD_CHAN0_BIT >> chan; + if ((EnabledBits & chanBit) && !(SIGetType(chan) & SI_GC_NOMOTOR)) + { + if (Spec < PAD_SPEC_2 && command == PAD_MOTOR_STOP_HARD) + { + command = PAD_MOTOR_STOP; + } + + if (UnkVal & 0x20) + { + command = PAD_MOTOR_STOP; + } + + SISetCommand(chan, (0x40 << 16) | AnalogMode | (command & (0x00000001 | 0x00000002))); + SITransferCommands(); + } + OSRestoreInterrupts(enabled); +} + +void PADSetSpec(u32 spec) +{ + __PADSpec = 0; + switch (spec) + { + case PAD_SPEC_0: + MakeStatus = SPEC0_MakeStatus; + break; + case PAD_SPEC_1: + MakeStatus = SPEC1_MakeStatus; + break; + case PAD_SPEC_2: + case PAD_SPEC_3: + case PAD_SPEC_4: + case PAD_SPEC_5: + MakeStatus = SPEC2_MakeStatus; + break; + } + Spec = spec; +} + +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; + status->button |= ((data[0] >> 16) & 0x0020) ? PAD_BUTTON_B : 0; + 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->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->triggerRight) + { + status->button |= PAD_TRIGGER_R; + } + status->stickX -= 128; + status->stickY -= 128; + status->substickX -= 128; + status->substickY -= 128; +} + +static void SPEC1_MakeStatus(s32 chan, PADStatus* status, u32 data[2]) +{ + status->button = 0; + status->button |= ((data[0] >> 16) & 0x0080) ? PAD_BUTTON_A : 0; + status->button |= ((data[0] >> 16) & 0x0100) ? PAD_BUTTON_B : 0; + status->button |= ((data[0] >> 16) & 0x0020) ? PAD_BUTTON_X : 0; + status->button |= ((data[0] >> 16) & 0x0010) ? PAD_BUTTON_Y : 0; + status->button |= ((data[0] >> 16) & 0x0200) ? PAD_BUTTON_START : 0; + + 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->triggerRight) + { + status->button |= PAD_TRIGGER_R; + } + + status->stickX -= 128; + status->stickY -= 128; + status->substickX -= 128; + status->substickY -= 128; +} + +static s8 ClampS8(s8 var, s8 org) +{ + if (0 < org) + { + s8 min = (s8)(-128 + org); + if (var < min) + { + var = min; + } + } + else if (org < 0) + { + s8 max = (s8)(127 + org); + if (max < var) + { + var = max; + } + } + return 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) + +static void SPEC2_MakeStatus(s32 chan, PADStatus* status, u32 data[2]) +{ + PADStatus* origin; + + status->button = (u16)((data[0] >> 16) & PAD_ALL); + status->stickX = (s8)(data[0] >> 8); + status->stickY = (s8)(data[0]); + + switch (AnalogMode & 0x00000700) + { + case 0x00000000: + case 0x00000500: + case 0x00000600: + case 0x00000700: + 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->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->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->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->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->stickX -= 128; + status->stickY -= 128; + status->substickX -= 128; + status->substickY -= 128; + + if ((Type[chan] & 0xffff0000) == SI_GC_CONTROLLER && (((status->button) & 0x80) ^ 0x80)) + { + BarrelBits |= PAD_CHAN0_BIT >> chan; + status->stickX = 0; + status->stickY = 0; + status->substickX = 0; + status->substickY = 0; + } + else + { + BarrelBits &= ~(PAD_CHAN0_BIT >> chan); + origin = &Origin[chan]; + 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); + } +} + +BOOL PADGetType(s32 chan, u32* type) +{ + u32 chanBit; + + *type = SIGetType(chan); + chanBit = PAD_CHAN0_BIT >> chan; + if ((ResettingBits & chanBit) || ResettingChan == chan || !(EnabledBits & chanBit)) + { + return FALSE; + } + return TRUE; +} + +BOOL PADSync(void) +{ + return ResettingBits == 0 && ResettingChan == 32 && !SIBusy(); +} + +void PADSetAnalogMode(u32 mode) +{ + BOOL enabled; + u32 mask; + + enabled = OSDisableInterrupts(); + AnalogMode = mode << 8; + mask = EnabledBits; + + EnabledBits &= ~mask; + WaitingBits &= ~mask; + CheckingBits &= ~mask; + + SIDisablePolling(mask); + OSRestoreInterrupts(enabled); +} + +static BOOL OnReset(BOOL f) +{ + static BOOL recalibrated = FALSE; + BOOL sync; + + if (SamplingCallback) + { + PADSetSamplingCallback(NULL); + } + + if (!f) + { + sync = PADSync(); + if (!recalibrated && sync) + { + recalibrated = + PADRecalibrate(PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT); + return FALSE; + } + return sync; + } + else + { + recalibrated = FALSE; + } + + return TRUE; +} + +void __PADDisableXPatch(void) +{ + XPatchBits = 0; +} + +static void SamplingHandler(__OSInterrupt interrupt, OSContext* context) +{ + OSContext exceptionContext; + + if (SamplingCallback) + { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + SamplingCallback(); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } +} + +PADSamplingCallback PADSetSamplingCallback(PADSamplingCallback callback) +{ + PADSamplingCallback prev; + + prev = SamplingCallback; + SamplingCallback = callback; + if (callback) + { + SIRegisterPollingHandler(SamplingHandler); + } + else + { + SIUnregisterPollingHandler(SamplingHandler); + } + return prev; +} + +BOOL __PADDisableRecalibration(BOOL disable) +{ + BOOL enabled; + BOOL prev; + + enabled = OSDisableInterrupts(); + prev = (UnkVal & 0x40) ? TRUE : FALSE; + UnkVal &= ~0x40; + if (disable) + { + UnkVal |= 0x40; + } + OSRestoreInterrupts(enabled); + return prev; +} \ No newline at end of file diff --git a/libs/dolphin/pad/Padclamp.c b/libs/dolphin/pad/Padclamp.c new file mode 100644 index 000000000..89fbbfb8a --- /dev/null +++ b/libs/dolphin/pad/Padclamp.c @@ -0,0 +1,198 @@ +#include + +#include "std/math.h" + +s32 PAD_CHANMAX; + +static const PADClampRegion ClampRegion = { + // Triggers + 30, + 180, + + // Left stick + 15, + 72, + 40, + + // Right stick + 15, + 59, + 31, + + // Stick radii + 56, + 44, +}; + +static void ClampStick(s8* px, s8* py, s8 max, s8 xy, s8 min) +{ + int x = *px; + int y = *py; + int signX; + int signY; + int d; + + if (0 <= x) + { + signX = 1; + } + else + { + signX = -1; + x = -x; + } + + if (0 <= y) + { + signY = 1; + } + else + { + signY = -1; + y = -y; + } + + if (x <= min) + { + x = 0; + } + else + { + x -= min; + } + if (y <= min) + { + y = 0; + } + else + { + y -= min; + } + + if (x == 0 && y == 0) + { + *px = *py = 0; + return; + } + + if (xy * y <= xy * x) + { + d = xy * x + (max - xy) * y; + if (xy * max < d) + { + x = (s8)(xy * max * x / d); + y = (s8)(xy * max * y / d); + } + } + else + { + d = xy * y + (max - xy) * x; + if (xy * max < d) + { + x = (s8)(xy * max * x / d); + y = (s8)(xy * max * y / d); + } + } + + *px = (s8)(signX * x); + *py = (s8)(signY * y); +} + +static void ClampCircle(s8* px, s8* py, s8 radius, s8 min) +{ + int x = *px; + int y = *py; + int squared; + int length; + + if (-min < x && x < min) + { + x = 0; + } + else if (0 < x) + { + x -= min; + } + else + { + x += min; + } + + if (-min < y && y < min) + { + y = 0; + } + else if (0 < y) + { + y -= min; + } + else + { + y += min; + } + + squared = x * x + y * y; + if (radius * radius < squared) + { + length = sqrtf(squared); + x = (x * radius) / length; + y = (y * radius) / length; + } + + *px = x; + *py = y; +} + +static void ClampTrigger(u8* trigger, u8 min, u8 max) +{ + if (*trigger <= min) + { + *trigger = 0; + return; + } + else + { + if (max < *trigger) + { + *trigger = max; + } + *trigger -= min; + } +} + +void PADClamp(PADStatus* status) +{ + int i; + for (i = 0; i < PAD_CHANMAX; i++, status++) + { + if (status->err != PAD_ERR_NONE) + { + continue; + } + + 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); + } +} + +void PADClampCircle(PADStatus* status) +{ + int i; + for (i = 0; i < PAD_CHANMAX; ++i, status++) + { + if (status->err != PAD_ERR_NONE) + { + continue; + } + + 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); + } +} diff --git a/libs/dolphin/si/SIBios.c b/libs/dolphin/si/SIBios.c new file mode 100644 index 000000000..030b026e3 --- /dev/null +++ b/libs/dolphin/si/SIBios.c @@ -0,0 +1,902 @@ +#include +#include +#include +#include + +vu32 __SIRegs[64] : 0xCC006400; + +extern OSTime __OSGetSystemTime(); + +const char* __SIVersion = "<< Dolphin SDK - SI\trelease build: Apr 17 2003 12:33:19 (0x2301) >>"; + +static SIControl Si = { + -1, 0, 0, NULL, NULL, +}; + +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; + +static SIPacket Packet[SI_MAX_CHAN]; +static OSAlarm Alarm[SI_MAX_CHAN]; +static u32 Type[SI_MAX_CHAN] = { + SI_ERROR_NO_RESPONSE, + SI_ERROR_NO_RESPONSE, + SI_ERROR_NO_RESPONSE, + SI_ERROR_NO_RESPONSE, +}; + +static OSTime TypeTime[SI_MAX_CHAN]; +static OSTime XferTime[SI_MAX_CHAN]; + +static SITypeAndStatusCallback TypeCallback[SI_MAX_CHAN][4]; +static __OSInterruptHandler RDSTHandler[4]; + +u32 __PADFixBits; + +static BOOL __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, + SICallback callback); + +static BOOL InputBufferValid[SI_MAX_CHAN]; +static u32 InputBuffer[SI_MAX_CHAN][2]; +static vu32 InputBufferVcount[SI_MAX_CHAN]; + +static BOOL SIGetResponseRaw(s32 chan); +static void GetTypeCallback(s32 chan, u32 error, OSContext* context); + +BOOL SIBusy() +{ + return Si.chan != -1 ? TRUE : FALSE; +} + +BOOL SIIsChanBusy(s32 chan) +{ + return (Packet[chan].chan != -1 || Si.chan == chan); +} + +static void SIClearTCInterrupt() +{ + u32 reg; + + reg = __SIRegs[13]; + reg |= 0x80000000; + reg &= ~0x00000001; + __SIRegs[13] = reg; +} + +static u32 CompleteTransfer() +{ + u32 sr; + u32 i; + u32 rLen; + u8* input; + + sr = __SIRegs[14]; + + SIClearTCInterrupt(); + + if (Si.chan != -1) + { + XferTime[Si.chan] = __OSGetSystemTime(); + + input = Si.input; + + rLen = Si.inputBytes / 4; + for (i = 0; i < rLen; i++) + { + *(u32*)input = __SIRegs[32 + i]; + input += 4; + } + + rLen = Si.inputBytes & 3; + if (rLen) + { + u32 temp = __SIRegs[32 + i]; + for (i = 0; i < rLen; i++) + { + *input++ = (u8)((temp >> ((3 - i) * 8)) & 0xff); + } + } + + 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 (sr == 0) + { + sr = SI_ERROR_COLLISION; + } + } + else + { + TypeTime[Si.chan] = __OSGetSystemTime(); + sr = 0; + } + + Si.chan = -1; + } + return sr; +} + +static void SITransferNext(s32 chan) +{ + int i; + SIPacket* packet; + + for (i = 0; i < SI_MAX_CHAN; ++i) + { + ++chan; + chan %= SI_MAX_CHAN; + 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; + } + break; + } + } +} + +static void SIInterruptHandler(__OSInterrupt interrupt, OSContext* context) +{ + u32 reg; + + reg = __SIRegs[13]; + + if ((reg & 0xc0000000) == 0xc0000000) + { + s32 chan; + u32 sr; + SICallback callback; + + chan = Si.chan; + sr = CompleteTransfer(); + callback = Si.callback; + Si.callback = 0; + + SITransferNext(chan); + + if (callback) + { + callback(chan, sr, context); + } + + sr = __SIRegs[14]; + sr &= 0xf000000 >> (8 * chan); + __SIRegs[14] = sr; + + if (Type[chan] == SI_ERROR_BUSY && !SIIsChanBusy(chan)) + { + static u32 cmdTypeAndStatus = 0 << 24; + SITransfer(chan, &cmdTypeAndStatus, 1, &Type[chan], 3, GetTypeCallback, + OSMicrosecondsToTicks(65)); + } + } + + if ((reg & 0x18000000) == 0x18000000) + { + int i; + u32 vcount; + u32 x; + + vcount = VIGetCurrentLine() + 1; + x = (Si.poll & 0x03ff0000) >> 16; + + for (i = 0; i < SI_MAX_CHAN; ++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 < SI_MAX_CHAN; ++i) + { + InputBufferVcount[i] = 0; + } + + for (i = 0; i < 4; ++i) + { + if (RDSTHandler[i]) + { + RDSTHandler[i](interrupt, context); + } + } + } +} + +static BOOL SIEnablePollingInterrupt(BOOL enable) +{ + BOOL enabled; + BOOL rc; + u32 reg; + int i; + + enabled = OSDisableInterrupts(); + reg = __SIRegs[13]; + rc = (reg & 0x08000000) ? TRUE : FALSE; + if (enable) + { + reg |= 0x08000000; + for (i = 0; i < SI_MAX_CHAN; ++i) + { + InputBufferVcount[i] = 0; + } + } + else + { + reg &= ~0x08000000; + } + reg &= ~0x80000001; + __SIRegs[13] = reg; + OSRestoreInterrupts(enabled); + return rc; +} + +BOOL SIRegisterPollingHandler(__OSInterruptHandler handler) +{ + BOOL enabled; + int i; + + enabled = OSDisableInterrupts(); + for (i = 0; i < 4; ++i) + { + if (RDSTHandler[i] == handler) + { + OSRestoreInterrupts(enabled); + return TRUE; + } + } + for (i = 0; i < 4; ++i) + { + if (RDSTHandler[i] == 0) + { + RDSTHandler[i] = handler; + SIEnablePollingInterrupt(TRUE); + OSRestoreInterrupts(enabled); + return TRUE; + } + } + OSRestoreInterrupts(enabled); + return FALSE; +} + +BOOL SIUnregisterPollingHandler(__OSInterruptHandler handler) +{ + BOOL enabled; + int i; + + enabled = OSDisableInterrupts(); + for (i = 0; i < 4; ++i) + { + if (RDSTHandler[i] == handler) + { + RDSTHandler[i] = 0; + for (i = 0; i < 4; ++i) + { + if (RDSTHandler[i]) + { + break; + } + } + if (i == 4) + { + SIEnablePollingInterrupt(FALSE); + } + OSRestoreInterrupts(enabled); + return TRUE; + break; + } + } + OSRestoreInterrupts(enabled); + return FALSE; +} + +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) + ; + + __SIRegs[13] = 0x80000000; + + __OSSetInterruptHandler(__OS_INTERRUPT_PI_SI, SIInterruptHandler); + __OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_SI); + + SIGetType(0); + SIGetType(1); + SIGetType(2); + SIGetType(3); +} + +#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) + +static BOOL __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, + SICallback callback) +{ + BOOL enabled; + u32 rLen; + u32 i; + u32 sr; + SIComm_u comcsr; + + enabled = OSDisableInterrupts(); + if (Si.chan != -1) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + + sr = __SIRegs[14]; + sr &= (0xf000000) >> (8 * chan); + __SIRegs[14] = sr; + + Si.chan = chan; + Si.callback = callback; + Si.inputBytes = inputBytes; + Si.input = input; + + rLen = ROUND(outputBytes, 4) / 4; + for (i = 0; i < rLen; i++) + { + __SIRegs[32 + i] = ((u32*)output)[i]; + } + + comcsr.val = __SIRegs[13]; + 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.channel = chan; + comcsr.f.tstart = 1; + __SIRegs[13] = comcsr.val; + + OSRestoreInterrupts(enabled); + + return TRUE; +} + +u32 SISync(void) +{ + BOOL enabled; + u32 sr; + + while (__SIRegs[13] & 1) + ; + + enabled = OSDisableInterrupts(); + sr = CompleteTransfer(); + + SITransferNext(SI_MAX_CHAN); + + OSRestoreInterrupts(enabled); + + return sr; +} + +u32 SIGetStatus(s32 chan) +{ + BOOL enabled; + u32 sr; + int chanShift; + + enabled = OSDisableInterrupts(); + sr = __SIRegs[14]; + chanShift = 8 * (SI_MAX_CHAN - 1 - chan); + sr >>= chanShift; + if (sr & SI_ERROR_NO_RESPONSE) + { + if (!(Type[chan] & SI_ERROR_BUSY)) + { + Type[chan] = SI_ERROR_NO_RESPONSE; + } + } + OSRestoreInterrupts(enabled); + return sr; +} + +void SISetCommand(s32 chan, u32 command) +{ + __SIRegs[3 * chan] = command; +} + +u32 SIGetCommand(s32 chan) +{ + return __SIRegs[3 * chan]; +} + +void SITransferCommands(void) +{ + __SIRegs[14] = 0x80000000; +} + +u32 SISetXY(u32 x, u32 y) +{ + u32 poll; + BOOL enabled; + + poll = x << 16; + poll |= y << 8; + + enabled = OSDisableInterrupts(); + Si.poll &= ~(0x03ff0000 | 0x0000ff00); + Si.poll |= poll; + poll = Si.poll; + __SIRegs[12] = poll; + OSRestoreInterrupts(enabled); + return poll; +} + +u32 SIEnablePolling(u32 poll) +{ + BOOL enabled; + u32 en; + + if (poll == 0) + { + return Si.poll; + } + + enabled = OSDisableInterrupts(); + + poll >>= (31 - 7); + en = poll & 0xf0; + + poll &= (en >> 4) | 0x03fffff0; + + poll &= ~0x03ffff00; + + Si.poll &= ~(en >> 4); + + Si.poll |= poll; + + poll = Si.poll; + + SITransferCommands(); + + __SIRegs[12] = poll; + + OSRestoreInterrupts(enabled); + + return poll; +} + +u32 SIDisablePolling(u32 poll) +{ + BOOL enabled; + + if (poll == 0) + { + return Si.poll; + } + + enabled = OSDisableInterrupts(); + + poll >>= (31 - 7); + poll &= 0xf0; + + poll = Si.poll & ~poll; + + __SIRegs[12] = poll; + Si.poll = poll; + + OSRestoreInterrupts(enabled); + return poll; +} + +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]; + InputBufferValid[chan] = TRUE; + return TRUE; + } + return FALSE; +} + +BOOL SIGetResponse(s32 chan, void* data) +{ + BOOL rc; + BOOL enabled; + + 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; +} + +static void AlarmHandler(OSAlarm* alarm, OSContext* context) +{ +#pragma unused(context) + s32 chan; + SIPacket* packet; + + chan = alarm - Alarm; + packet = &Packet[chan]; + if (packet->chan != -1) + { + if (__SITransfer(packet->chan, packet->output, packet->outputBytes, packet->input, + packet->inputBytes, packet->callback)) + { + packet->chan = -1; + } + } +} + +BOOL SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, + SICallback callback, OSTime delay) +{ + BOOL enabled; + SIPacket* packet = &Packet[chan]; + OSTime now; + OSTime fire; + + enabled = OSDisableInterrupts(); + if (packet->chan != -1 || Si.chan == chan) + { + OSRestoreInterrupts(enabled); + return FALSE; + } + + now = __OSGetSystemTime(); + if (delay == 0) + { + fire = now; + } + else + { + fire = XferTime[chan] + delay; + } + if (now < fire) + { + delay = fire - now; + OSSetAlarm(&Alarm[chan], delay, AlarmHandler); + } + else if (__SITransfer(chan, output, outputBytes, input, inputBytes, callback)) + { + OSRestoreInterrupts(enabled); + return TRUE; + } + + packet->chan = chan; + packet->output = output; + packet->outputBytes = outputBytes; + packet->input = input; + packet->inputBytes = inputBytes; + packet->callback = callback; + packet->fire = fire; + + OSRestoreInterrupts(enabled); + return TRUE; +} + +static void CallTypeAndStatusCallback(s32 chan, u32 type) +{ + SITypeAndStatusCallback callback; + int i; + + for (i = 0; i < 4; ++i) + { + callback = TypeCallback[chan][i]; + if (callback) + { + TypeCallback[chan][i] = 0; + callback(chan, type); + } + } +} + +static void GetTypeCallback(s32 chan, u32 error, OSContext* context) +{ + static u32 cmdFixDevice[SI_MAX_CHAN]; + u32 type; + u32 chanBit; + BOOL fix; + u32 id; + + Type[chan] &= ~SI_ERROR_BUSY; + Type[chan] |= error; + TypeTime[chan] = __OSGetSystemTime(); + + type = Type[chan]; + + chanBit = SI_CHAN0_BIT >> chan; + fix = (BOOL)(__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)) + { + OSSetWirelessID(chan, 0); + CallTypeAndStatusCallback(chan, Type[chan]); + return; + } + + 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; + Type[chan] = SI_ERROR_BUSY; + 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)); + + 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); + } + + CallTypeAndStatusCallback(chan, Type[chan]); +} + +u32 SIGetType(s32 chan) +{ + static u32 cmdTypeAndStatus; + BOOL enabled; + u32 type; + OSTime diff; + + enabled = OSDisableInterrupts(); + + type = Type[chan]; + diff = __OSGetSystemTime() - TypeTime[chan]; + if (Si.poll & (0x80 >> chan)) + { + if (type != SI_ERROR_NO_RESPONSE) + { + TypeTime[chan] = __OSGetSystemTime(); + OSRestoreInterrupts(enabled); + return type; + } + 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)); + + OSRestoreInterrupts(enabled); + return type; +} + +u32 SIGetTypeAsync(s32 chan, SITypeAndStatusCallback callback) +{ + BOOL enabled; + u32 type; + + enabled = OSDisableInterrupts(); + type = SIGetType(chan); + if (Type[chan] & SI_ERROR_BUSY) + { + int i; + + for (i = 0; i < 4; ++i) + { + if (TypeCallback[chan][i] == callback) + { + break; + } + if (TypeCallback[chan][i] == 0) + { + TypeCallback[chan][i] = callback; + break; + } + } + } + else + { + 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_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_COLLISION | SI_ERROR_UNKNOWN)) + { + return SI_ERROR_UNKNOWN; + } + if (error) + { + return SI_ERROR_BUSY; + } + + if ((type & SI_TYPE_MASK) == SI_TYPE_N64) + { + switch (type & 0xffff0000) + { + case SI_N64_CONTROLLER: + case SI_N64_MIC: + case SI_N64_KEYBOARD: + case SI_N64_MOUSE: + case SI_GBA: + return type & 0xffff0000; + break; + } + return SI_ERROR_UNKNOWN; + } + + if ((type & SI_TYPE_MASK) != SI_TYPE_GC) + { + return SI_ERROR_UNKNOWN; + } + switch (type & 0xffff0000) + { + case SI_GC_CONTROLLER: + case SI_GC_STEERING: + return type & 0xffff0000; + break; + } + + if ((type & 0xffe00000) == SI_GC_KEYBOARD) + { + return SI_GC_KEYBOARD; + } + + if ((type & SI_GC_WIRELESS) && !(type & SI_WIRELESS_IR)) + { + if ((type & SI_GC_WAVEBIRD) == SI_GC_WAVEBIRD) + { + return SI_GC_WAVEBIRD; + } + else if (!(type & SI_WIRELESS_STATE)) + { + 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_N64_CONTROLLER: + return "N64 controller"; + case SI_N64_MIC: + return "N64 microphone"; + case SI_N64_KEYBOARD: + return "N64 keyboard"; + case SI_N64_MOUSE: + return "N64 mouse"; + case SI_GBA: + return "GameBoy Advance"; + case SI_GC_CONTROLLER: + return "Standard controller"; + case SI_GC_RECEIVER: + return "Wireless receiver"; + case SI_GC_WAVEBIRD: + return "WaveBird controller"; + case SI_GC_KEYBOARD: + return "Keyboard"; + case SI_GC_STEERING: + return "Steering"; + } +} \ No newline at end of file diff --git a/libs/dolphin/si/SISamplingRate.c b/libs/dolphin/si/SISamplingRate.c new file mode 100644 index 000000000..742759fe0 --- /dev/null +++ b/libs/dolphin/si/SISamplingRate.c @@ -0,0 +1,80 @@ +#include "dolphin/sipriv.h" +#include "dolphin/vi.h" +#include "dolphin/hw_regs.h" + +#pragma dont_inline on +static u32 SamplingRate; + +typedef struct XY +{ + u16 line; + u8 count; +} XY; + +static XY XYNTSC[12] = { + {263 - 17, 2}, + {15, 18}, + {30, 9}, + {44, 6}, + {52, 5}, + {65, 4}, + {87, 3}, + {87, 3}, + {87, 3}, + {131, 2}, + {131, 2}, + {131, 2}, +}; + +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}, +}; + +void SISetSamplingRate(u32 msec) +{ + XY *xy; + BOOL enabled; + + if (msec > 11) + { + msec = 11; + } + + enabled = OSDisableInterrupts(); + + SamplingRate = msec; + + switch (VIGetTvFormat()) + { + case VI_NTSC: + case VI_MPAL: + case VI_EURGB60: + xy = XYNTSC; + break; + case VI_PAL: + xy = XYPAL; + break; + default: + OSReport("SISetSamplingRate: unknown TV format. Use default."); + msec = 0; + xy = XYNTSC; + break; + } + + SISetXY((__VIRegs[54] & 1 ? 2u : 1u) * xy[msec].line, xy[msec].count); + OSRestoreInterrupts(enabled); +} + +void SIRefreshSamplingRate() { SISetSamplingRate(SamplingRate); } +#pragma dont_inline reset \ No newline at end of file diff --git a/libs/dolphin/si/SISteering.c b/libs/dolphin/si/SISteering.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/si/SISteeringAuto.c b/libs/dolphin/si/SISteeringAuto.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/si/SISteeringXfer.c b/libs/dolphin/si/SISteeringXfer.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/thp/THPAudio.c b/libs/dolphin/thp/THPAudio.c new file mode 100644 index 000000000..147d62180 --- /dev/null +++ b/libs/dolphin/thp/THPAudio.c @@ -0,0 +1,202 @@ +#include + +u32 THPAudioDecode(s16 *audioBuffer, u8 *audioFrame, s32 flag) +{ + THPAudioRecordHeader *header; + THPAudioDecodeInfo decInfo; + u8 *left, *right; + s16 *decLeftPtr, *decRightPtr; + s16 yn1, yn2; + s32 i; + s32 step; + s32 sample; + s64 yn; + + if (audioBuffer == NULL || audioFrame == NULL) + { + return 0; + } + + header = (THPAudioRecordHeader *)audioFrame; + left = audioFrame + sizeof(THPAudioRecordHeader); + right = left + header->offsetNextChannel; + + if (flag == 1) + { + decRightPtr = audioBuffer; + decLeftPtr = audioBuffer + header->sampleSize; + step = 1; + } + else + { + decRightPtr = audioBuffer; + decLeftPtr = audioBuffer + 1; + step = 2; + } + + if (header->offsetNextChannel == 0) + { + __THPAudioInitialize(&decInfo, left); + + yn1 = header->lYn1; + yn2 = header->lYn2; + + for (i = 0; i < header->sampleSize; i++) + { + sample = __THPAudioGetNewSample(&decInfo); + yn = header->lCoef[decInfo.predictor][1] * yn2; + yn += header->lCoef[decInfo.predictor][0] * yn1; + yn += (sample << decInfo.scale) << 11; + yn <<= 5; + + if ((u16)(yn & 0xffff) > 0x8000) + { + yn += 0x10000; + } + else if ((u16)(yn & 0xffff) == 0x8000) + { + if ((yn & 0x10000)) + yn += 0x10000; + } + + if (yn > 2147483647LL) + { + yn = 2147483647LL; + } + + if (yn < -2147483648LL) + { + yn = -2147483648LL; + } + + *decLeftPtr = (s16)(yn >> 16); + decLeftPtr += step; + *decRightPtr = (s16)(yn >> 16); + decRightPtr += step; + yn2 = yn1; + yn1 = (s16)(yn >> 16); + } + } + else + { + __THPAudioInitialize(&decInfo, left); + + yn1 = header->lYn1; + yn2 = header->lYn2; + + for (i = 0; i < header->sampleSize; i++) + { + sample = __THPAudioGetNewSample(&decInfo); + yn = header->lCoef[decInfo.predictor][1] * yn2; + yn += header->lCoef[decInfo.predictor][0] * yn1; + yn += (sample << decInfo.scale) << 11; + yn <<= 5; + if ((u16)(yn & 0xffff) > 0x8000) + { + yn += 0x10000; + } + else + { + if ((u16)(yn & 0xffff) == 0x8000) + { + if ((yn & 0x10000)) + yn += 0x10000; + } + } + + if (yn > 2147483647LL) + { + yn = 2147483647LL; + } + + if (yn < -2147483648LL) + { + yn = -2147483648LL; + } + + *decLeftPtr = (s16)(yn >> 16); + decLeftPtr += step; + yn2 = yn1; + yn1 = (s16)(yn >> 16); + } + + __THPAudioInitialize(&decInfo, right); + + yn1 = header->rYn1; + yn2 = header->rYn2; + + for (i = 0; i < header->sampleSize; i++) + { + sample = __THPAudioGetNewSample(&decInfo); + yn = header->rCoef[decInfo.predictor][1] * yn2; + yn += header->rCoef[decInfo.predictor][0] * yn1; + yn += (sample << decInfo.scale) << 11; + yn <<= 5; + + if ((u16)(yn & 0xffff) > 0x8000) + { + yn += 0x10000; + } + else + { + if ((u16)(yn & 0xffff) == 0x8000) + { + if ((yn & 0x10000)) + yn += 0x10000; + } + } + + if (yn > 2147483647LL) + { + yn = 2147483647LL; + } + + if (yn < -2147483648LL) + { + yn = -2147483648LL; + } + + *decRightPtr = (s16)(yn >> 16); + decRightPtr += step; + yn2 = yn1; + yn1 = (s16)(yn >> 16); + } + } + + return header->sampleSize; +} + +static s32 __THPAudioGetNewSample(THPAudioDecodeInfo *info) +{ + s32 sample; + + if (!(info->offsetNibbles & 0x0f)) + { + info->predictor = (u8)((*(info->encodeData) & 0x70) >> 4); + info->scale = (u8)((*(info->encodeData) & 0xF)); + info->encodeData++; + info->offsetNibbles += 2; + } + + if (info->offsetNibbles & 0x1) + { + sample = (s32)((*(info->encodeData) & 0xF) << 28) >> 28; + info->encodeData++; + } + else + { + sample = (s32)((*(info->encodeData) & 0xF0) << 24) >> 28; + } + + info->offsetNibbles++; + return sample; +} + +static void __THPAudioInitialize(THPAudioDecodeInfo *info, u8 *ptr) +{ + info->encodeData = ptr; + info->offsetNibbles = 2; + info->predictor = (u8)((*(info->encodeData) & 0x70) >> 4); + info->scale = (u8)((*(info->encodeData) & 0xF)); + info->encodeData++; +} \ No newline at end of file diff --git a/libs/dolphin/thp/THPDec.c b/libs/dolphin/thp/THPDec.c new file mode 100644 index 000000000..10ceb6189 --- /dev/null +++ b/libs/dolphin/thp/THPDec.c @@ -0,0 +1,2316 @@ +#include +#include + +const char *__THPVersion = "<< Dolphin SDK - THP\trelease build: Aug 27 2002 20:42:01 >>"; + +static THPHuffmanTab *Ydchuff __attribute__((aligned(32))); +static THPHuffmanTab *Udchuff __attribute__((aligned(32))); +static THPHuffmanTab *Vdchuff __attribute__((aligned(32))); +static THPHuffmanTab *Yachuff __attribute__((aligned(32))); +static THPHuffmanTab *Uachuff __attribute__((aligned(32))); +static THPHuffmanTab *Vachuff __attribute__((aligned(32))); +static f32 __THPIDCTWorkspace[64] __attribute__((aligned(32))); +static u8 *__THPHuffmanBits; +static u8 *__THPHuffmanSizeTab; +static u16 *__THPHuffmanCodeTab; +static THPSample *Gbase __attribute__((aligned(32))); +static u32 Gwid __attribute__((aligned(32))); +static f32 *Gq __attribute__((aligned(32))); +static u8 *__THPLCWork512[3]; +static u8 *__THPLCWork672[3]; +static u32 __THPOldGQR5; +static u32 __THPOldGQR6; +static u8 *__THPWorkArea; +static THPCoeff *__THPMCUBuffer[6]; +static THPFileInfo *__THPInfo; +static BOOL __THPInitFlag = FALSE; + +#define ROUNDUP(a, b) ((((s32)(a)) + ((s32)(b)-1L)) / ((s32)(b))) + +void __THPInverseDCTY8(register THPCoeff *, register u32); + +s32 THPVideoDecode(void *file, void *tileY, void *tileU, void *tileV, void *work) +{ + u8 all_done, status; + s32 errorCode; + + if (!file) + { + goto _err_no_input; + } + + if (tileY == NULL || tileU == NULL || tileV == NULL) + { + goto _err_no_output; + } + + if (!work) + { + goto _err_no_work; + } + + if (!(PPCMfhid2() & 0x10000000)) + { + goto _err_lc_not_enabled; + } + + if (__THPInitFlag == FALSE) + { + goto _err_not_initialized; + } + + __THPWorkArea = (u8 *)work; + __THPInfo = (THPFileInfo *)OSRoundUp32B(__THPWorkArea); + __THPWorkArea = (u8 *)OSRoundUp32B(__THPWorkArea) + sizeof(THPFileInfo); + DCZeroRange(__THPInfo, sizeof(THPFileInfo)); + __THPInfo->cnt = 33; + __THPInfo->decompressedY = 0; + __THPInfo->c = (u8 *)file; + all_done = FALSE; + + for (;;) + { + if ((*(__THPInfo->c)++) != 255) + { + goto _err_bad_syntax; + } + + while (*__THPInfo->c == 255) + { + ((__THPInfo->c)++); + } + + status = (*(__THPInfo->c)++); + + if (status <= 0xD7) + { + if (status == 196) + { + status = __THPReadHuffmanTableSpecification(); + if (status != 0) + { + goto _err_bad_status; + } + } + + else if (status == 192) + { + status = __THPReadFrameHeader(); + if (status != 0) + { + goto _err_bad_status; + } + } + + else + { + goto _err_unsupported_marker; + } + } + + else if (0xD8 <= status && status <= 0xDF) + { + if (status == 221) + { + __THPRestartDefinition(); + } + + else if (status == 219) + { + status = __THPReadQuantizationTable(); + if (status != 0) + { + goto _err_bad_status; + } + } + + else if (status == 218) + { + status = __THPReadScaneHeader(); + if (status != 0) + { + goto _err_bad_status; + } + + all_done = TRUE; + } + else if (status == 216) + { + // empty but required for match + } + else + { + goto _err_unsupported_marker; + } + } + + else if (0xE0 <= status) + { + if ((224 <= status && status <= 239) || status == 254) + { + __THPInfo->c += (__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]; + } + else + { + goto _err_unsupported_marker; + } + } + + if (all_done) + { + break; + } + } + + __THPSetupBuffers(); + __THPDecompressYUV(tileY, tileU, tileV); + return 0; + +_err_no_input: + errorCode = 25; + goto _err_exit; + +_err_no_output: + errorCode = 27; + goto _err_exit; + +_err_no_work: + errorCode = 26; + goto _err_exit; + +_err_unsupported_marker: + errorCode = 11; + goto _err_exit; + +_err_bad_resource: + errorCode = 1; + goto _err_exit; + +_err_no_mem: + errorCode = 6; + goto _err_exit; + +_err_bad_syntax: + errorCode = 3; + goto _err_exit; + +_err_bad_status: + errorCode = status; + goto _err_exit; + +_err_lc_not_enabled: + errorCode = 28; + goto _err_exit; + +_err_not_initialized: + errorCode = 29; + goto _err_exit; + +_err_exit: + return errorCode; +} + +static void __THPSetupBuffers(void) +{ + u8 i; + THPCoeff *buffer; + + buffer = (THPCoeff *)OSRoundUp32B(__THPWorkArea); + + for (i = 0; i < 6; i++) + { + __THPMCUBuffer[i] = &buffer[i * 64]; + } +} + +u8 __THPReadFrameHeader(void) +{ + u8 i, utmp8; + + __THPInfo->c += 2; + + utmp8 = (*(__THPInfo->c)++); + + if (utmp8 != 8) + { + return 10; + } + + __THPInfo->yPixelSize = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); + __THPInfo->c += 2; + __THPInfo->xPixelSize = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); + __THPInfo->c += 2; + + utmp8 = (*(__THPInfo->c)++); + if (utmp8 != 3) + { + return 12; + } + + for (i = 0; i < 3; i++) + { + utmp8 = (*(__THPInfo->c)++); + utmp8 = (*(__THPInfo->c)++); + if ((i == 0 && utmp8 != 0x22) || (i > 0 && utmp8 != 0x11)) + { + return 19; + } + + __THPInfo->components[i].quantizationTableSelector = (*(__THPInfo->c)++); + } + + return 0; +} + +/* there is an EXTREMELY tiny schedule swap but otherwise matching */ +u8 __THPReadScaneHeader(void) +{ + u8 i, utmp8; + __THPInfo->c += 2; + + utmp8 = (*(__THPInfo->c)++); + + if (utmp8 != 3) + { + return 12; + } + + for (i = 0; i < 3; i++) + { + utmp8 = (*(__THPInfo->c)++); + + utmp8 = (*(__THPInfo->c)++); + __THPInfo->components[i].DCTableSelector = (u8)(utmp8 >> 4); + __THPInfo->components[i].ACTableSelector = (u8)(utmp8 & 15); + + if ((__THPInfo->validHuffmanTabs & (1 << ((utmp8 >> 4)))) == 0) + { + return 15; + } + + if ((__THPInfo->validHuffmanTabs & (1 << ((utmp8 & 15) + 1))) == 0) + { + return 15; + } + } + + __THPInfo->c += 3; + __THPInfo->MCUsPerRow = (u16)ROUNDUP(__THPInfo->xPixelSize, 16); + __THPInfo->components[0].predDC = 0; + __THPInfo->components[1].predDC = 0; + __THPInfo->components[2].predDC = 0; + return 0; +} + +u8 __THPReadQuantizationTable(void) +{ + u16 length, id, i, row, col; + f32 q_temp[64]; + + length = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); + __THPInfo->c += 2; + length -= 2; + + for (;;) + { + id = (*(__THPInfo->c)++); + + for (i = 0; i < 64; i++) + { + q_temp[__THPJpegNaturalOrder[i]] = (f32)(*(__THPInfo->c)++); + } + + i = 0; + for (row = 0; row < 8; row++) + { + for (col = 0; col < 8; col++) + { + __THPInfo->quantTabs[id][i] = (f32)((f64)q_temp[i] * __THPAANScaleFactor[row] * __THPAANScaleFactor[col]); + i++; + } + } + + length -= 65; + if (!length) + { + break; + } + } + + return 0; +} + +u8 __THPReadHuffmanTableSpecification(void) +{ + u8 t_class, id, i, tab_index; + u16 length, num_Vij; + + __THPHuffmanSizeTab = __THPWorkArea; + __THPHuffmanCodeTab = (u16 *)((u32)__THPWorkArea + 256 + 1); + length = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); + __THPInfo->c += 2; + length -= 2; + + for (;;) + { + i = (*(__THPInfo->c)++); + id = (u8)(i & 15); + t_class = (u8)(i >> 4); + __THPHuffmanBits = __THPInfo->c; + tab_index = (u8)((id << 1) + t_class); + num_Vij = 0; + + for (i = 0; i < 16; i++) + { + num_Vij += (*(__THPInfo->c)++); + } + + __THPInfo->huffmanTabs[tab_index].Vij = __THPInfo->c; + __THPInfo->c += num_Vij; + __THPHuffGenerateSizeTable(); + __THPHuffGenerateCodeTable(); + __THPHuffGenerateDecoderTables(tab_index); + __THPInfo->validHuffmanTabs |= 1 << tab_index; + length -= 17 + num_Vij; + + if (length == 0) + { + break; + } + } + + return 0; +} + +static void __THPHuffGenerateSizeTable(void) +{ + s32 p, l, i; + p = 0; + + for (l = 1; l <= 16; l++) + { + i = (s32)__THPHuffmanBits[l - 1]; + while (i--) + { + __THPHuffmanSizeTab[p++] = (u8)l; + } + } + + __THPHuffmanSizeTab[p] = 0; +} + +static void __THPHuffGenerateCodeTable(void) +{ + u8 si; + u16 p, code; + + p = 0; + code = 0; + si = __THPHuffmanSizeTab[0]; + + while (__THPHuffmanSizeTab[p]) + { + while (__THPHuffmanSizeTab[p] == si) + { + __THPHuffmanCodeTab[p++] = code; + code++; + } + + code <<= 1; + si++; + } +} + +static void __THPHuffGenerateDecoderTables(u8 tabIndex) +{ + s32 p, l; + THPHuffmanTab *h; + + p = 0; + h = &__THPInfo->huffmanTabs[tabIndex]; + for (l = 1; l <= 16; l++) + { + if (__THPHuffmanBits[l - 1]) + { + h->valPtr[l] = p - __THPHuffmanCodeTab[p]; + p += __THPHuffmanBits[l - 1]; + h->maxCode[l] = __THPHuffmanCodeTab[p - 1]; + } + else + { + h->maxCode[l] = -1; + h->valPtr[l] = -1; + } + } + + h->maxCode[17] = 0xfffffL; +} + +static void __THPRestartDefinition(void) +{ + __THPInfo->RST = TRUE; + __THPInfo->c += 2; + __THPInfo->nMCU = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); + __THPInfo->c += 2; + __THPInfo->currMCU = __THPInfo->nMCU; +} + +static inline void __THPGQRSetup(void) +{ + register u32 tmp1, tmp2; + + asm { + mfspr tmp1, GQR5; + mfspr tmp2, GQR6; + } + + __THPOldGQR5 = tmp1; + __THPOldGQR6 = tmp2; + + asm { + li r3, 0x0007 + oris r3, r3, 0x0007 + mtspr GQR5, r3 + li r3, 0x3D04 + oris r3, r3, 0x3D04 + mtspr GQR6, r3 + } +} + +static inline void __THPGQRRestore(void) +{ + register u32 tmp1, tmp2; + tmp1 = __THPOldGQR5; + tmp2 = __THPOldGQR6; + + asm { + mtspr GQR5, tmp1; + mtspr GQR6, tmp2; + } +} + +void __THPPrepBitStream(void) +{ + u32 *ptr; + u32 offset, i, j, k; + + ptr = (u32 *)((u32)__THPInfo->c & 0xFFFFFFFC); + offset = (u32)__THPInfo->c & 3; + + if (__THPInfo->cnt != 33) + { + __THPInfo->cnt -= (3 - offset) * 8; + } + else + { + __THPInfo->cnt = (offset * 8) + 1; + } + + __THPInfo->c = (u8 *)ptr; + __THPInfo->currByte = *ptr; + + for (i = 0; i < 4; i++) + { + if (__THPInfo->validHuffmanTabs & (1 << i)) + { + for (j = 0; j < 32; j++) + { + __THPInfo->huffmanTabs[i].quick[j] = 0xFF; + + for (k = 0; k < 5; k++) + { + s32 code = (s32)(j >> (5 - k - 1)); + + if (code <= __THPInfo->huffmanTabs[i].maxCode[k + 1]) + { + __THPInfo->huffmanTabs[i].quick[j] = __THPInfo->huffmanTabs[i].Vij[(s32)(code + __THPInfo->huffmanTabs[i].valPtr[k + 1])]; + __THPInfo->huffmanTabs[i].increment[j] = (u8)(k + 1); + k = 99; + } + else + { + } + } + } + } + } + + { + s32 YdcTab, UdcTab, VdcTab, YacTab, UacTab, VacTab; + + YdcTab = (__THPInfo->components[0].DCTableSelector << 1); + UdcTab = (__THPInfo->components[1].DCTableSelector << 1); + VdcTab = (__THPInfo->components[2].DCTableSelector << 1); + + YacTab = (__THPInfo->components[0].ACTableSelector << 1) + 1; + UacTab = (__THPInfo->components[1].ACTableSelector << 1) + 1; + VacTab = (__THPInfo->components[2].ACTableSelector << 1) + 1; + + Ydchuff = &__THPInfo->huffmanTabs[YdcTab]; + Udchuff = &__THPInfo->huffmanTabs[UdcTab]; + Vdchuff = &__THPInfo->huffmanTabs[VdcTab]; + + Yachuff = &__THPInfo->huffmanTabs[YacTab]; + Uachuff = &__THPInfo->huffmanTabs[UacTab]; + Vachuff = &__THPInfo->huffmanTabs[VacTab]; + } +} + +void __THPDecompressYUV(void *tileY, void *tileU, void *tileV) +{ + u16 currentY, targetY; + __THPInfo->dLC[0] = tileY; + __THPInfo->dLC[1] = tileU; + __THPInfo->dLC[2] = tileV; + + currentY = __THPInfo->decompressedY; + targetY = __THPInfo->yPixelSize; + + __THPGQRSetup(); + __THPPrepBitStream(); + + if (__THPInfo->xPixelSize == 512 && targetY == 448) + { + while (currentY < targetY) + { + __THPDecompressiMCURow512x448(); + currentY += 16; + } + } + else if (__THPInfo->xPixelSize == 640 && targetY == 480) + { + while (currentY < targetY) + { + __THPDecompressiMCURow640x480(); + currentY += 16; + } + } + else + { + while (currentY < targetY) + { + __THPDecompressiMCURowNxN(); + currentY += 16; + } + } + + __THPGQRRestore(); +} + +inline void __THPInverseDCTNoYPos(register THPCoeff *in, register u32 xPos) +{ + register f32 *q, *ws; + register f32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; + register f32 tmp10, tmp11, tmp12, tmp13; + register f32 tmp20, tmp21, tmp22, tmp23; + register f32 cc4 = 1.414213562F; + register f32 cc2 = 1.847759065F; + register f32 cc2c6s = 1.082392200F; + register f32 cc2c6a = -2.613125930F; + register f32 bias = 1024.0F; + q = Gq; + ws = &__THPIDCTWorkspace[0] - 2; + + { + register u32 itmp0, itmp1, itmp2, itmp3; + asm { + li itmp2, 8 + mtctr itmp2 + + _loopHead0: + psq_l tmp10, 0(in), 0, 5 + psq_l tmp11, 0(q), 0, 0 + lwz itmp0, 12(in) + lwz itmp3, 8(in) + ps_mul tmp10, tmp10, tmp11 + lwz itmp1, 4(in) + lhz itmp2, 2(in) + or. itmp0, itmp0, itmp3 + + _loopHead1: + cmpwi itmp0, 0 + bne _regularIDCT + ps_merge00 tmp0, tmp10, tmp10 + cmpwi itmp1, 0 + psq_st tmp0, 8(ws), 0, 0 + bne _halfIDCT + psq_st tmp0, 16(ws), 0, 0 + cmpwi itmp2, 0 + psq_st tmp0, 24(ws), 0, 0 + bne _quarterIDCT + addi q, q, 8*sizeof(f32) + psq_stu tmp0, 32(ws), 0, 0 + addi in, in, 8*sizeof(THPCoeff) + bdnz _loopHead0 + b _loopEnd + + _quarterIDCT: + addi in, in, 8*sizeof(THPCoeff) + ps_msub tmp2, tmp10, cc2, tmp10 + addi q, q, 8*sizeof(f32) + ps_merge00 tmp9, tmp10, tmp10 + lwz itmp1, 4(in) + ps_sub tmp1, cc2, cc2c6s + ps_msub tmp3, tmp10, cc4, tmp2 + lhz itmp2, 2(in) + ps_merge11 tmp5, tmp10, tmp2 + psq_l tmp11, 0(q), 0, 0 + ps_nmsub tmp4, tmp10, tmp1, tmp3 + ps_add tmp7, tmp9, tmp5 + psq_l tmp10, 0(in), 0, 5 + ps_merge11 tmp6, tmp3, tmp4 + ps_sub tmp5, tmp9, tmp5 + lwz itmp0, 12(in) + ps_add tmp8, tmp9, tmp6 + lwz itmp3, 8(in) + ps_sub tmp6, tmp9, tmp6 + psq_stu tmp7, 8(ws), 0, 0 + ps_merge10 tmp6, tmp6, tmp6 + psq_stu tmp8, 8(ws), 0, 0 + ps_merge10 tmp5, tmp5, tmp5 + or itmp0, itmp0, itmp3 + psq_stu tmp6, 8(ws), 0, 0 + ps_mul tmp10, tmp10, tmp11 + psq_stu tmp5, 8(ws), 0, 0 + bdnz _loopHead1 + b _loopEnd + + _halfIDCT: + psq_l tmp1, 4(in), 0, 5 + psq_l tmp9, 8(q), 0, 0 + addi in, in, 8*sizeof(THPCoeff) + ps_mul tmp1, tmp1, tmp9 + addi q, q, 8*sizeof(f32) + ps_sub tmp3, tmp10, tmp1 + ps_add tmp2, tmp10, tmp1 + lwz itmp0, 12(in) + ps_madd tmp4, tmp1, cc4, tmp3 + ps_nmsub tmp5, tmp1, cc4, tmp2 + ps_mul tmp8, tmp3, cc2 + ps_merge00 tmp4, tmp2, tmp4 + lwz itmp3, 8(in) + ps_nmsub tmp6, tmp1, cc2c6a, tmp8 + ps_merge00 tmp5, tmp5, tmp3 + lwz itmp1, 4(in) + ps_sub tmp6, tmp6, tmp2 + ps_nmsub tmp7, tmp10, cc2c6s, tmp8 + lhz itmp2, 2(in) + ps_merge11 tmp2, tmp2, tmp6 + ps_msub tmp8, tmp3, cc4, tmp6 + psq_l tmp10, 0(in), 0, 5 + ps_add tmp9, tmp4, tmp2 + ps_sub tmp7, tmp7, tmp8 + psq_l tmp11, 0(q), 0, 0 + ps_merge11 tmp3, tmp8, tmp7 + ps_sub tmp4, tmp4, tmp2 + psq_stu tmp9, 8(ws), 0, 0 + ps_add tmp0, tmp5, tmp3 + ps_sub tmp1, tmp5, tmp3 + or itmp0, itmp0, itmp3 + psq_stu tmp0, 8(ws), 0, 0 + ps_merge10 tmp1, tmp1, tmp1 + ps_merge10 tmp4, tmp4, tmp4 + psq_stu tmp1, 8(ws), 0, 0 + ps_mul tmp10, tmp10, tmp11 + psq_stu tmp4, 8(ws), 0, 0 + bdnz _loopHead1 + b _loopEnd + + _regularIDCT: + psq_l tmp9, 4(in), 0, 5 + psq_l tmp5, 8(q), 0, 0 + ps_mul tmp9, tmp9, tmp5 + psq_l tmp2, 8(in), 0, 5 + psq_l tmp6, 16(q), 0, 0 + ps_merge01 tmp0, tmp10, tmp9 + psq_l tmp3, 12(in), 0, 5 + ps_merge01 tmp1, tmp9, tmp10 + psq_l tmp7, 24(q), 0, 0 + addi in, in, 8*sizeof(THPCoeff) + ps_madd tmp4, tmp2, tmp6, tmp0 + ps_nmsub tmp5, tmp2, tmp6, tmp0 + ps_madd tmp6, tmp3, tmp7, tmp1 + ps_nmsub tmp7, tmp3, tmp7, tmp1 + addi q, q, 8*sizeof(f32) + ps_add tmp0, tmp4, tmp6 + ps_sub tmp3, tmp4, tmp6 + ps_msub tmp2, tmp7, cc4, tmp6 + lwz itmp0, 12(in) + ps_sub tmp8, tmp7, tmp5 + ps_add tmp1, tmp5, tmp2 + ps_sub tmp2, tmp5, tmp2 + ps_mul tmp8, tmp8, cc2 + lwz itmp3, 8(in) + ps_merge00 tmp1, tmp0, tmp1 + ps_nmsub tmp6, tmp5, cc2c6a, tmp8 + ps_msub tmp4, tmp7, cc2c6s, tmp8 + lwz itmp1, 4(in) + ps_sub tmp6, tmp6, tmp0 + ps_merge00 tmp2, tmp2, tmp3 + lhz itmp2, 2(in) + ps_madd tmp5, tmp3, cc4, tmp6 + ps_merge11 tmp7, tmp0, tmp6 + psq_l tmp10, 0(in), 0, 5 + ps_sub tmp4, tmp4, tmp5 + ps_add tmp3, tmp1, tmp7 + psq_l tmp11, 0(q), 0, 0 + ps_merge11 tmp4, tmp5, tmp4 + ps_sub tmp0, tmp1, tmp7 + ps_mul tmp10, tmp10, tmp11 + ps_add tmp5, tmp2, tmp4 + ps_sub tmp6, tmp2, tmp4 + ps_merge10 tmp5, tmp5, tmp5 + psq_stu tmp3, 8(ws), 0, 0 + ps_merge10 tmp0, tmp0, tmp0 + psq_stu tmp6, 8(ws), 0, 0 + psq_stu tmp5, 8(ws), 0, 0 + or itmp0, itmp0, itmp3 + psq_stu tmp0, 8(ws), 0, 0 + bdnz _loopHead1 + + _loopEnd: + + } + } + + ws = &__THPIDCTWorkspace[0]; + + { + register THPSample *obase = Gbase; + register u32 wid = Gwid; + + register u32 itmp0, off0, off1; + register THPSample *out0, *out1; + + asm { + psq_l tmp10, 8*0*sizeof(f32)(ws), 0, 0 + slwi xPos, xPos, 2 + psq_l tmp11, 8*4*sizeof(f32)(ws), 0, 0 + slwi off1, wid, 2 + psq_l tmp12, 8*2*sizeof(f32)(ws), 0, 0 + mr off0, xPos + ps_add tmp6, tmp10, tmp11 + psq_l tmp13, 8*6*sizeof(f32)(ws), 0, 0 + ps_sub tmp8, tmp10, tmp11 + add off1, off0, off1 + ps_add tmp6, tmp6, bias + li itmp0, 3 + ps_add tmp7, tmp12, tmp13 + add out0, obase, off0 + ps_sub tmp9, tmp12, tmp13 + ps_add tmp0, tmp6, tmp7 + add out1, obase, off1 + ps_add tmp8, tmp8, bias + mtctr itmp0 + + _loopHead10: + psq_l tmp4, 8*1*sizeof(f32)(ws), 0, 0 + ps_msub tmp9, tmp9, cc4, tmp7 + psq_l tmp5, 8*3*sizeof(f32)(ws), 0, 0 + ps_sub tmp3, tmp6, tmp7 + ps_add tmp1, tmp8, tmp9 + psq_l tmp6, 8*5*sizeof(f32)(ws), 0, 0 + ps_sub tmp2, tmp8, tmp9 + psq_l tmp7, 8*7*sizeof(f32)(ws), 0, 0 + ps_add tmp8, tmp6, tmp5 + ps_sub tmp6, tmp6, tmp5 + addi ws, ws, 2*sizeof(f32) + ps_add tmp9, tmp4, tmp7 + ps_sub tmp4, tmp4, tmp7 + psq_l tmp10, 8*0*sizeof(f32)(ws), 0, 0 + ps_add tmp7, tmp9, tmp8 + ps_sub tmp5, tmp9, tmp8 + ps_add tmp8, tmp6, tmp4 + psq_l tmp11, 8*4*sizeof(f32)(ws), 0, 0 + ps_add tmp9, tmp0, tmp7 + ps_mul tmp8, tmp8, cc2 + psq_l tmp12, 8*2*sizeof(f32)(ws), 0, 0 + ps_sub tmp23, tmp0, tmp7 + ps_madd tmp6, tmp6, cc2c6a, tmp8 + psq_l tmp13, 8*6*sizeof(f32)(ws), 0, 0 + ps_sub tmp6, tmp6, tmp7 + addi off0, off0, 2*sizeof(THPSample) + psq_st tmp9, 0(out0), 0, 6 + ps_msub tmp4, tmp4, cc2c6s, tmp8 + ps_add tmp9, tmp1, tmp6 + ps_msub tmp5, tmp5, cc4, tmp6 + ps_sub tmp22, tmp1, tmp6 + psq_st tmp9, 8(out0), 0, 6 + ps_add tmp8, tmp2, tmp5 + ps_add tmp4, tmp4, tmp5 + psq_st tmp8, 16(out0), 0, 6 + addi off1, off1, 2*sizeof(THPSample) + ps_sub tmp9, tmp3, tmp4 + ps_add tmp20, tmp3, tmp4 + psq_st tmp9, 24(out0), 0, 6 + ps_sub tmp21, tmp2, tmp5 + ps_add tmp6, tmp10, tmp11 + psq_st tmp20, 0(out1), 0, 6 + ps_sub tmp8, tmp10, tmp11 + ps_add tmp6, tmp6, bias + psq_st tmp21, 8(out1), 0, 6 + ps_add tmp7, tmp12, tmp13 + ps_sub tmp9, tmp12, tmp13 + psq_st tmp22, 16(out1), 0, 6 + add out0, obase, off0 + ps_add tmp0, tmp6, tmp7 + psq_st tmp23, 24(out1), 0, 6 + ps_add tmp8, tmp8, bias + add out1, obase, off1 + bdnz _loopHead10 + psq_l tmp4, 8*1*sizeof(f32)(ws), 0, 0 + ps_msub tmp9, tmp9, cc4, tmp7 + psq_l tmp5, 8*3*sizeof(f32)(ws), 0, 0 + ps_sub tmp3, tmp6, tmp7 + ps_add tmp1, tmp8, tmp9 + psq_l tmp6, 8*5*sizeof(f32)(ws), 0, 0 + ps_sub tmp2, tmp8, tmp9 + psq_l tmp7, 8*7*sizeof(f32)(ws), 0, 0 + ps_add tmp8, tmp6, tmp5 + ps_sub tmp6, tmp6, tmp5 + ps_add tmp9, tmp4, tmp7 + ps_sub tmp4, tmp4, tmp7 + ps_add tmp7, tmp9, tmp8 + ps_sub tmp5, tmp9, tmp8 + ps_add tmp8, tmp6, tmp4 + ps_add tmp9, tmp0, tmp7 + ps_mul tmp8, tmp8, cc2 + ps_sub tmp23, tmp0, tmp7 + ps_madd tmp6, tmp6, cc2c6a, tmp8 + psq_st tmp9, 0(out0), 0, 6 + ps_sub tmp6, tmp6, tmp7 + ps_msub tmp4, tmp4, cc2c6s, tmp8 + psq_st tmp23, 24(out1), 0, 6 + ps_add tmp9, tmp1, tmp6 + ps_msub tmp5, tmp5, cc4, tmp6 + ps_sub tmp22, tmp1, tmp6 + psq_st tmp9, 8(out0), 0, 6 + ps_add tmp8, tmp2, tmp5 + ps_add tmp4, tmp4, tmp5 + psq_st tmp22, 16(out1), 0, 6 + psq_st tmp8, 16(out0), 0, 6 + ps_sub tmp9, tmp3, tmp4 + ps_add tmp20, tmp3, tmp4 + psq_st tmp9, 24(out0), 0, 6 + ps_sub tmp21, tmp2, tmp5 + psq_st tmp20, 0(out1), 0, 6 + psq_st tmp21, 8(out1), 0, 6 + } + } +} + +inline void __THPInverseDCTY8(register THPCoeff *in, register u32 xPos) +{ + register f32 *q, *ws; + register f32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; + register f32 tmp10, tmp11, tmp12, tmp13; + register f32 tmp20, tmp21, tmp22, tmp23; + register f32 cc4 = 1.414213562F; + register f32 cc2 = 1.847759065F; + register f32 cc2c6s = 1.082392200F; + register f32 cc2c6a = -2.613125930F; + register f32 bias = 1024.0F; + + q = Gq; + ws = &__THPIDCTWorkspace[0] - 2; + + { + register u32 itmp0, itmp1, itmp2, itmp3; + + asm { + li itmp2, 8 + mtctr itmp2 + + _loopHead0: + psq_l tmp10, 0(in), 0, 5 + psq_l tmp11, 0(q), 0, 0 + lwz itmp0, 12(in) + lwz itmp3, 8(in) + ps_mul tmp10, tmp10, tmp11 + lwz itmp1, 4(in) + lhz itmp2, 2(in) + or itmp0, itmp0, itmp3 + + _loopHead1: + cmpwi itmp0, 0 + bne _regularIDCT + ps_merge00 tmp0, tmp10, tmp10 + cmpwi itmp1, 0 + psq_st tmp0, 8(ws), 0, 0 + bne _halfIDCT + psq_st tmp0, 16(ws), 0, 0 + cmpwi itmp2, 0 + psq_st tmp0, 24(ws), 0, 0 + bne _quarterIDCT + addi q, q, 8*sizeof(f32) + psq_stu tmp0, 32(ws), 0, 0 + addi in, in, 8*sizeof(THPCoeff) + bdnz _loopHead0 + b _loopEnd + + _quarterIDCT: + ps_msub tmp2, tmp10, cc2, tmp10 + addi in, in, 8*sizeof(THPCoeff) + ps_merge00 tmp9, tmp10, tmp10 + addi q, q, 8*sizeof(f32) + ps_sub tmp1, cc2, cc2c6s + lwz itmp1, 4(in) + ps_msub tmp3, tmp10, cc4, tmp2 + lhz itmp2, 2(in) + ps_merge11 tmp5, tmp10, tmp2 + psq_l tmp11, 0(q), 0, 0 + ps_nmsub tmp4, tmp10, tmp1, tmp3 + ps_add tmp7, tmp9, tmp5 + psq_l tmp10, 0(in), 0, 5 + ps_merge11 tmp6, tmp3, tmp4 + ps_sub tmp5, tmp9, tmp5 + lwz itmp0, 12(in) + ps_add tmp8, tmp9, tmp6 + lwz itmp3, 8(in) + ps_sub tmp6, tmp9, tmp6 + psq_stu tmp7, 8(ws), 0, 0 + ps_merge10 tmp6, tmp6, tmp6 + psq_stu tmp8, 8(ws), 0, 0 + ps_merge10 tmp5, tmp5, tmp5 + or itmp0, itmp0, itmp3 + psq_stu tmp6, 8(ws), 0, 0 + ps_mul tmp10, tmp10, tmp11 + psq_stu tmp5, 8(ws), 0, 0 + bdnz _loopHead1 + b _loopEnd + + _halfIDCT: + psq_l tmp1, 4(in), 0, 5 + psq_l tmp9, 8(q), 0, 0 + addi in, in, 8*sizeof(THPCoeff) + ps_mul tmp1, tmp1, tmp9 + addi q, q, 8*sizeof(f32) + ps_sub tmp3, tmp10, tmp1 + ps_add tmp2, tmp10, tmp1 + lwz itmp0, 12(in) + ps_madd tmp4, tmp1, cc4, tmp3 + ps_nmsub tmp5, tmp1, cc4, tmp2 + ps_mul tmp8, tmp3, cc2 + ps_merge00 tmp4, tmp2, tmp4 + lwz itmp3, 8(in) + ps_nmsub tmp6, tmp1, cc2c6a, tmp8 + ps_merge00 tmp5, tmp5, tmp3 + lwz itmp1, 4(in) + ps_sub tmp6, tmp6, tmp2 + ps_nmsub tmp7, tmp10, cc2c6s, tmp8 + lhz itmp2, 2(in) + ps_merge11 tmp2, tmp2, tmp6 + ps_msub tmp8, tmp3, cc4, tmp6 + psq_l tmp10, 0(in), 0, 5 + ps_add tmp9, tmp4, tmp2 + ps_sub tmp7, tmp7, tmp8 + psq_l tmp11, 0(q), 0, 0 + ps_merge11 tmp3, tmp8, tmp7 + ps_sub tmp4, tmp4, tmp2 + psq_stu tmp9, 8(ws), 0, 0 + ps_add tmp0, tmp5, tmp3 + ps_sub tmp1, tmp5, tmp3 + or itmp0, itmp0, itmp3 + psq_stu tmp0, 8(ws), 0, 0 + ps_merge10 tmp1, tmp1, tmp1 + ps_merge10 tmp4, tmp4, tmp4 + psq_stu tmp1, 8(ws), 0, 0 + ps_mul tmp10, tmp10, tmp11 + psq_stu tmp4, 8(ws), 0, 0 + bdnz _loopHead1 + b _loopEnd + + _regularIDCT: + psq_l tmp9, 4(in), 0, 5 + psq_l tmp5, 8(q), 0, 0 + ps_mul tmp9, tmp9, tmp5 + psq_l tmp2, 8(in), 0, 5 + psq_l tmp6, 16(q), 0, 0 + ps_merge01 tmp0, tmp10, tmp9 + psq_l tmp3, 12(in), 0, 5 + ps_merge01 tmp1, tmp9, tmp10 + psq_l tmp7, 24(q), 0, 0 + addi in, in, 8*sizeof(THPCoeff) + ps_madd tmp4, tmp2, tmp6, tmp0 + ps_nmsub tmp5, tmp2, tmp6, tmp0 + ps_madd tmp6, tmp3, tmp7, tmp1 + ps_nmsub tmp7, tmp3, tmp7, tmp1 + addi q, q, 8*sizeof(f32) + ps_add tmp0, tmp4, tmp6 + ps_sub tmp3, tmp4, tmp6 + ps_msub tmp2, tmp7, cc4, tmp6 + lwz itmp0, 12(in) + ps_sub tmp8, tmp7, tmp5 + ps_add tmp1, tmp5, tmp2 + ps_sub tmp2, tmp5, tmp2 + ps_mul tmp8, tmp8, cc2 + lwz itmp3, 8(in) + ps_merge00 tmp1, tmp0, tmp1 + ps_nmsub tmp6, tmp5, cc2c6a, tmp8 + ps_msub tmp4, tmp7, cc2c6s, tmp8 + lwz itmp1, 4(in) + ps_sub tmp6, tmp6, tmp0 + ps_merge00 tmp2, tmp2, tmp3 + lhz itmp2, 2(in) + ps_madd tmp5, tmp3, cc4, tmp6 + ps_merge11 tmp7, tmp0, tmp6 + psq_l tmp10, 0(in), 0, 5 + ps_sub tmp4, tmp4, tmp5 + ps_add tmp3, tmp1, tmp7 + psq_l tmp11, 0(q), 0, 0 + ps_merge11 tmp4, tmp5, tmp4 + ps_sub tmp0, tmp1, tmp7 + ps_mul tmp10, tmp10, tmp11 + ps_add tmp5, tmp2, tmp4 + ps_sub tmp6, tmp2, tmp4 + ps_merge10 tmp5, tmp5, tmp5 + psq_stu tmp3, 8(ws), 0, 0 + ps_merge10 tmp0, tmp0, tmp0 + psq_stu tmp6, 8(ws), 0, 0 + psq_stu tmp5, 8(ws), 0, 0 + or itmp0, itmp0, itmp3 + psq_stu tmp0, 8(ws), 0, 0 + bdnz _loopHead1 + + _loopEnd: + + } + } + + ws = &__THPIDCTWorkspace[0]; + + { + register THPSample *obase = Gbase; + register u32 wid = Gwid; + + register u32 itmp0, off0, off1; + register THPSample *out0, *out1; + + asm { + psq_l tmp10, 8*0*sizeof(f32)(ws), 0, 0 + slwi off0, wid, 3; + psq_l tmp11, 8*4*sizeof(f32)(ws), 0, 0 + slwi xPos, xPos, 2 + psq_l tmp12, 8*2*sizeof(f32)(ws), 0, 0 + slwi off1, wid, 2 + ps_add tmp6, tmp10, tmp11 + add off0, off0, xPos + psq_l tmp13, 8*6*sizeof(f32)(ws), 0, 0 + ps_sub tmp8, tmp10, tmp11 + add off1, off0, off1 + ps_add tmp6, tmp6, bias + li itmp0, 3 + ps_add tmp7, tmp12, tmp13 + add out0, obase, off0 + ps_sub tmp9, tmp12, tmp13 + ps_add tmp0, tmp6, tmp7 + add out1, obase, off1 + ps_add tmp8, tmp8, bias + mtctr itmp0 + + _loopHead10: + psq_l tmp4, 8*1*sizeof(f32)(ws), 0, 0 + ps_msub tmp9, tmp9, cc4, tmp7 + psq_l tmp5, 8*3*sizeof(f32)(ws), 0, 0 + ps_sub tmp3, tmp6, tmp7 + ps_add tmp1, tmp8, tmp9 + psq_l tmp6, 8*5*sizeof(f32)(ws), 0, 0 + ps_sub tmp2, tmp8, tmp9 + psq_l tmp7, 8*7*sizeof(f32)(ws), 0, 0 + ps_add tmp8, tmp6, tmp5 + ps_sub tmp6, tmp6, tmp5 + addi ws, ws, 2*sizeof(f32) + ps_add tmp9, tmp4, tmp7 + ps_sub tmp4, tmp4, tmp7 + psq_l tmp10, 8*0*sizeof(f32)(ws), 0, 0 + ps_add tmp7, tmp9, tmp8 + ps_sub tmp5, tmp9, tmp8 + ps_add tmp8, tmp6, tmp4 + psq_l tmp11, 8*4*sizeof(f32)(ws), 0, 0 + ps_add tmp9, tmp0, tmp7 + ps_mul tmp8, tmp8, cc2 + psq_l tmp12, 8*2*sizeof(f32)(ws), 0, 0 + ps_sub tmp23, tmp0, tmp7 + ps_madd tmp6, tmp6, cc2c6a, tmp8 + psq_l tmp13, 8*6*sizeof(f32)(ws), 0, 0 + ps_sub tmp6, tmp6, tmp7 + addi off0, off0, 2*sizeof(THPSample) + psq_st tmp9, 0(out0), 0, 6 + ps_msub tmp4, tmp4, cc2c6s, tmp8 + ps_add tmp9, tmp1, tmp6 + ps_msub tmp5, tmp5, cc4, tmp6 + ps_sub tmp22, tmp1, tmp6 + psq_st tmp9, 8(out0), 0, 6 + ps_add tmp8, tmp2, tmp5 + ps_add tmp4, tmp4, tmp5 + psq_st tmp8, 16(out0), 0, 6 + addi off1, off1, 2*sizeof(THPSample) + ps_sub tmp9, tmp3, tmp4 + ps_add tmp20, tmp3, tmp4 + psq_st tmp9, 24(out0), 0, 6 + ps_sub tmp21, tmp2, tmp5 + ps_add tmp6, tmp10, tmp11 + psq_st tmp20, 0(out1), 0, 6 + ps_sub tmp8, tmp10, tmp11 + ps_add tmp6, tmp6, bias + psq_st tmp21, 8(out1), 0, 6 + ps_add tmp7, tmp12, tmp13 + ps_sub tmp9, tmp12, tmp13 + psq_st tmp22, 16(out1), 0, 6 + add out0, obase, off0 + ps_add tmp0, tmp6, tmp7 + psq_st tmp23, 24(out1), 0, 6 + ps_add tmp8, tmp8, bias + add out1, obase, off1 + + bdnz _loopHead10 + psq_l tmp4, 8*1*sizeof(f32)(ws), 0, 0 + ps_msub tmp9, tmp9, cc4, tmp7 + psq_l tmp5, 8*3*sizeof(f32)(ws), 0, 0 + ps_sub tmp3, tmp6, tmp7 + ps_add tmp1, tmp8, tmp9 + psq_l tmp6, 8*5*sizeof(f32)(ws), 0, 0 + ps_sub tmp2, tmp8, tmp9 + psq_l tmp7, 8*7*sizeof(f32)(ws), 0, 0 + ps_add tmp8, tmp6, tmp5 + ps_sub tmp6, tmp6, tmp5 + ps_add tmp9, tmp4, tmp7 + ps_sub tmp4, tmp4, tmp7 + ps_add tmp7, tmp9, tmp8 + ps_sub tmp5, tmp9, tmp8 + ps_add tmp8, tmp6, tmp4 + ps_add tmp9, tmp0, tmp7 + ps_mul tmp8, tmp8, cc2 + ps_sub tmp23, tmp0, tmp7 + ps_madd tmp6, tmp6, cc2c6a, tmp8 + psq_st tmp9, 0(out0), 0, 6 + ps_sub tmp6, tmp6, tmp7 + ps_msub tmp4, tmp4, cc2c6s, tmp8 + psq_st tmp23, 24(out1), 0, 6 + ps_add tmp9, tmp1, tmp6 + ps_msub tmp5, tmp5, cc4, tmp6 + ps_sub tmp22, tmp1, tmp6 + psq_st tmp9, 8(out0), 0, 6 + ps_add tmp8, tmp2, tmp5 + ps_add tmp4, tmp4, tmp5 + psq_st tmp8, 16(out0), 0, 6 + ps_sub tmp9, tmp3, tmp4 + psq_st tmp22, 16(out1), 0, 6 + ps_add tmp20, tmp3, tmp4 + psq_st tmp9, 24(out0), 0, 6 + ps_sub tmp21, tmp2, tmp5 + psq_st tmp20, 0(out1), 0, 6 + psq_st tmp21, 8(out1), 0, 6 + + } + } +} + +void __THPDecompressiMCURow512x448(void) +{ + u8 cl_num; + u32 x_pos; + THPComponent *comp; + + LCQueueWait(3); + + for (cl_num = 0; cl_num < __THPInfo->MCUsPerRow; cl_num++) + { + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[0]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[1]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[2]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[3]); + __THPHuffDecodeDCTCompU(__THPInfo, __THPMCUBuffer[4]); + __THPHuffDecodeDCTCompV(__THPInfo, __THPMCUBuffer[5]); + + comp = &__THPInfo->components[0]; + Gbase = __THPLCWork512[0]; + Gwid = 512; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + x_pos = (u32)(cl_num * 16); + __THPInverseDCTNoYPos(__THPMCUBuffer[0], x_pos); + __THPInverseDCTNoYPos(__THPMCUBuffer[1], x_pos + 8); + __THPInverseDCTY8(__THPMCUBuffer[2], x_pos); + __THPInverseDCTY8(__THPMCUBuffer[3], x_pos + 8); + + comp = &__THPInfo->components[1]; + Gbase = __THPLCWork512[1]; + Gwid = 256; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + x_pos /= 2; + __THPInverseDCTNoYPos(__THPMCUBuffer[4], x_pos); + comp = &__THPInfo->components[2]; + Gbase = __THPLCWork512[2]; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + __THPInverseDCTNoYPos(__THPMCUBuffer[5], x_pos); + + if (__THPInfo->RST != 0) + { + if ((--__THPInfo->currMCU) == 0) + { + __THPInfo->currMCU = __THPInfo->nMCU; + __THPInfo->cnt = 1 + ((__THPInfo->cnt + 6) & 0xFFFFFFF8); + + if (__THPInfo->cnt > 33) + { + __THPInfo->cnt = 33; + } + + __THPInfo->components[0].predDC = 0; + __THPInfo->components[1].predDC = 0; + __THPInfo->components[2].predDC = 0; + } + } + } + + LCStoreData(__THPInfo->dLC[0], __THPLCWork512[0], 0x2000); + LCStoreData(__THPInfo->dLC[1], __THPLCWork512[1], 0x800); + LCStoreData(__THPInfo->dLC[2], __THPLCWork512[2], 0x800); + + __THPInfo->dLC[0] += 0x2000; + __THPInfo->dLC[1] += 0x800; + __THPInfo->dLC[2] += 0x800; +} + +inline s32 __THPHuffDecodeTab(register THPFileInfo *info, register THPHuffmanTab *h) +{ + register s32 code; + register u32 cnt; + register s32 cb; + register u32 increment; + register s32 tmp; + +#define cnt4 code + asm + { + lwz cnt, info->cnt; + addi increment, h, 32; + lwz cb, info->currByte; + addi cnt4, cnt, 4; + cmpwi cnt, 28; + rlwnm tmp, cb, cnt4, 27, 31; + bgt _notEnoughBits; + lbzx code, h, tmp; + lbzx increment, increment, tmp; + cmpwi code, 0xFF; + beq _FailedCheckEnoughBits; + add cnt, cnt, increment; + stw cnt, info->cnt; + } +_done: + return code; + + { + register u32 maxcodebase; + register u32 tmp2; + + _FailedCheckEnoughBits: + maxcodebase = (u32) & (h->maxCode); + cnt += 5; + + asm { + li tmp2, sizeof(s32)*(5); + li code, 5; + add maxcodebase, maxcodebase, tmp2; + __WHILE_START: + cmpwi cnt, 33; + slwi tmp, tmp, 1 + + beq _FCEB_faster; + rlwnm increment, cb, cnt, 31, 31; + lwzu tmp2, 4(maxcodebase); + or tmp, tmp, increment + addi cnt, cnt, 1; + b __WHILE_CHECK; + + _FCEB_faster: + lwz increment, info->c; + li cnt, 1; + lwzu cb, 4(increment); + lwzu tmp2, 4(maxcodebase); + + stw increment, info->c; + rlwimi tmp, cb, 1,31,31; + stw cb, info->currByte; + b __FL_WHILE_CHECK; + + __FL_WHILE_START: + slwi tmp, tmp, 1; + rlwnm increment, cb, cnt, 31, 31; + lwzu tmp2, 4(maxcodebase); + or tmp, tmp, increment; + + __FL_WHILE_CHECK: + cmpw tmp,tmp2 + addi cnt, cnt, 1; + addi code, code, 1 + bgt __FL_WHILE_START; + b _FCEB_Done; + + __WHILE_CHECK: + cmpw tmp,tmp2 + addi code, code, 1 + bgt __WHILE_START; + } + } +_FCEB_Done: + info->cnt = cnt; + return (h->Vij[(s32)(tmp + h->valPtr[code])]); + + asm + { // 6684 + _notEnoughBits: + cmpwi cnt, 33; + lwz tmp, info->c; + beq _getfullword; + + cmpwi cnt, 32; + rlwnm code, cb, cnt4, 27, 31 + beq _1bitleft; + + lbzx tmp, h, code; + lbzx increment, increment, code; + cmpwi tmp, 0xFF; + add code, cnt, increment; + beq _FailedCheckNoBits0; + + cmpwi code, 33; + stw code, info->cnt; + bgt _FailedCheckNoBits1; + } + return tmp; + + asm + { + _1bitleft: + lwzu cb, 4(tmp); + + stw tmp, info->c; + rlwimi code, cb, 4, 28, 31; + lbzx tmp, h, code; + lbzx increment, increment, code + stw cb, info->currByte; + cmpwi tmp, 0xFF + stw increment, info->cnt; + beq _DammitRead4; + + } + return tmp; + +_DammitRead4: +{ + register u32 maxcodebase = (u32) & (h->maxCode); + register u32 tmp2; + + asm + { + li cnt, sizeof(s32)*5; + add maxcodebase, maxcodebase, cnt; + + slwi tmp, code, 32-5; + li cnt,5; + rlwimi tmp, cb, 32-1, 1,31; + + __DR4_WHILE_START: + + subfic cb, cnt, 31; + lwzu tmp2, 4(maxcodebase); + srw code, tmp, cb; + __DR4_WHILE_CHECK: + cmpw code, tmp2 + addi cnt, cnt, 1 + bgt __DR4_WHILE_START; + + } +} + + info->cnt = cnt; +__CODE_PLUS_VP_CNT: + return (h->Vij[(s32)(code + h->valPtr[cnt])]); + +_getfullword: + asm + { + lwzu cb, 4(tmp); + + rlwinm code, cb, 5, 27, 31 + stw tmp, info->c; + lbzx cnt, h, code; + lbzx increment, increment, code; + cmpwi cnt, 0xFF + stw cb, info->currByte; + addi increment, increment, 1 + beq _FailedCheckEnoughbits_Updated; + + stw increment, info->cnt; + } + return (s32)cnt; + +_FailedCheckEnoughbits_Updated: + + cnt = 5; + do + { + asm + { + subfic tmp, cnt, 31; + addi cnt, cnt, 1; + srw code, cb, tmp; + } + } while (code > h->maxCode[cnt]); + + info->cnt = cnt + 1; + goto __CODE_PLUS_VP_CNT; + +#undef cnt4 + +_FailedCheckNoBits0: +_FailedCheckNoBits1: + +{ + register u32 mask = 0xFFFFFFFF << (33 - cnt); + register u32 tmp2; + + code = (s32)(cb & (~mask)); + mask = (u32) & (h->maxCode); + + asm + { + lwz tmp, info->c; + subfic tmp2, cnt, 33; + addi cnt, tmp2, 1; + slwi tmp2, tmp2, 2; + lwzu cb, 4(tmp); + add mask,mask, tmp2; + stw tmp, info->c; + slwi code, code, 1; + stw cb, info->currByte; + rlwimi code, cb, 1, 31, 31; + lwzu tmp2, 4(mask); + li tmp, 2; + b __FCNB1_WHILE_CHECK; + + __FCNB1_WHILE_START: + slwi code, code, 1; + + addi cnt, cnt, 1; + lwzu tmp2, 4(mask); + add code, code, increment; + addi tmp, tmp, 1; + + __FCNB1_WHILE_CHECK: + cmpw code, tmp2; + rlwnm increment, cb, tmp, 31, 31; + bgt __FCNB1_WHILE_START; + + } +} + + info->cnt = (u32)tmp; + return (h->Vij[(s32)(code + h->valPtr[cnt])]); +} + +void __THPDecompressiMCURow640x480(void) +{ + u8 cl_num; + u32 x_pos; + THPComponent *comp; + + LCQueueWait(3); + + { + for (cl_num = 0; cl_num < __THPInfo->MCUsPerRow; cl_num++) + { + THPFileInfo *um = __THPInfo; + __THPHuffDecodeDCTCompY(um, __THPMCUBuffer[0]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[1]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[2]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[3]); + __THPHuffDecodeDCTCompU(__THPInfo, __THPMCUBuffer[4]); + __THPHuffDecodeDCTCompV(__THPInfo, __THPMCUBuffer[5]); + + comp = &__THPInfo->components[0]; + Gbase = __THPLCWork672[0]; + Gwid = 640; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + x_pos = (u32)(cl_num * 16); + __THPInverseDCTNoYPos(__THPMCUBuffer[0], x_pos); + __THPInverseDCTNoYPos(__THPMCUBuffer[1], x_pos + 8); + __THPInverseDCTY8(__THPMCUBuffer[2], x_pos); + __THPInverseDCTY8(__THPMCUBuffer[3], x_pos + 8); + + comp = &__THPInfo->components[1]; + Gbase = __THPLCWork672[1]; + Gwid = 320; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + x_pos /= 2; + __THPInverseDCTNoYPos(__THPMCUBuffer[4], x_pos); + + comp = &__THPInfo->components[2]; + Gbase = __THPLCWork672[2]; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + __THPInverseDCTNoYPos(__THPMCUBuffer[5], x_pos); + + if (__THPInfo->RST != 0) + { + __THPInfo->currMCU--; + if (__THPInfo->currMCU == 0) + { + __THPInfo->currMCU = __THPInfo->nMCU; + + __THPInfo->cnt = 1 + ((__THPInfo->cnt + 6) & 0xFFFFFFF8); + + if (__THPInfo->cnt > 32) + { + __THPInfo->cnt = 33; + } + + __THPInfo->components[0].predDC = 0; + __THPInfo->components[1].predDC = 0; + __THPInfo->components[2].predDC = 0; + } + } + } + } + + LCStoreData(__THPInfo->dLC[0], __THPLCWork672[0], 0x2800); + LCStoreData(__THPInfo->dLC[1], __THPLCWork672[1], 0xA00); + LCStoreData(__THPInfo->dLC[2], __THPLCWork672[2], 0xA00); + + __THPInfo->dLC[0] += 0x2800; + __THPInfo->dLC[1] += 0xA00; + __THPInfo->dLC[2] += 0xA00; +} + +void __THPDecompressiMCURowNxN(void) +{ + u8 cl_num; + u32 x_pos, x; + THPComponent *comp; + + x = __THPInfo->xPixelSize; + + LCQueueWait(3); + + for (cl_num = 0; cl_num < __THPInfo->MCUsPerRow; cl_num++) + { + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[0]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[1]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[2]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[3]); + __THPHuffDecodeDCTCompU(__THPInfo, __THPMCUBuffer[4]); + __THPHuffDecodeDCTCompV(__THPInfo, __THPMCUBuffer[5]); + + comp = &__THPInfo->components[0]; + Gbase = __THPLCWork672[0]; + Gwid = x; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + x_pos = (u32)(cl_num * 16); + __THPInverseDCTNoYPos(__THPMCUBuffer[0], x_pos); + __THPInverseDCTNoYPos(__THPMCUBuffer[1], x_pos + 8); + __THPInverseDCTY8(__THPMCUBuffer[2], x_pos); + __THPInverseDCTY8(__THPMCUBuffer[3], x_pos + 8); + + comp = &__THPInfo->components[1]; + Gbase = __THPLCWork672[1]; + Gwid = x / 2; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + x_pos /= 2; + __THPInverseDCTNoYPos(__THPMCUBuffer[4], x_pos); + + comp = &__THPInfo->components[2]; + Gbase = __THPLCWork672[2]; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + __THPInverseDCTNoYPos(__THPMCUBuffer[5], x_pos); + + if (__THPInfo->RST != 0) + { + __THPInfo->currMCU--; + if (__THPInfo->currMCU == 0) + { + __THPInfo->currMCU = __THPInfo->nMCU; + __THPInfo->cnt = 1 + ((__THPInfo->cnt + 6) & 0xFFFFFFF8); + + if (__THPInfo->cnt > 32) + { + __THPInfo->cnt = 33; + } + + __THPInfo->components[0].predDC = 0; + __THPInfo->components[1].predDC = 0; + __THPInfo->components[2].predDC = 0; + } + } + } + + LCStoreData(__THPInfo->dLC[0], __THPLCWork672[0], ((4 * sizeof(u8) * 64) * (x / 16))); + LCStoreData(__THPInfo->dLC[1], __THPLCWork672[1], ((sizeof(u8) * 64) * (x / 16))); + LCStoreData(__THPInfo->dLC[2], __THPLCWork672[2], ((sizeof(u8) * 64) * (x / 16))); + __THPInfo->dLC[0] += ((4 * sizeof(u8) * 64) * (x / 16)); + __THPInfo->dLC[1] += ((sizeof(u8) * 64) * (x / 16)); + __THPInfo->dLC[2] += ((sizeof(u8) * 64) * (x / 16)); +} + +void __THPHuffDecodeDCTCompY(register THPFileInfo *info, THPCoeff *block) +{ + { + register s32 t; + THPCoeff dc; + register THPCoeff diff; + + __dcbz((void *)block, 0); + t = __THPHuffDecodeTab(info, Ydchuff); + __dcbz((void *)block, 32); + diff = 0; + __dcbz((void *)block, 64); + + if (t) + { + { + register s32 v; + register u32 cb; + register u32 cnt; + register u32 cnt33; + register u32 tmp; + register u32 cnt1; + register u32 tmp1; + asm { + lwz cnt,info->cnt; + subfic cnt33,cnt,33; + lwz cb,info->currByte; + + subfc. tmp, cnt33, t; + subi cnt1,cnt,1; + + bgt _notEnoughBitsDIFF; + add v,cnt,t; + + slw cnt,cb,cnt1; + stw v,info->cnt; + subfic v,t,32; + srw diff,cnt,v; + } + + asm + { + b _DoneDIFF; + _notEnoughBitsDIFF: + lwz tmp1, info->c; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, cnt33; + stw tmp1, info->c; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, t, 32; + srw diff, v, tmp; + _DoneDIFF: + } + } + + if (__cntlzw((u32)diff) > 32 - t) + { + diff += ((0xFFFFFFFF << t) + 1); + } + }; + + __dcbz((void *)block, 96); + dc = (s16)(info->components[0].predDC + diff); + block[0] = info->components[0].predDC = dc; + } + + { + register s32 k; + register s32 code; + register u32 cnt; + register u32 cb; + register u32 increment; + register s32 tmp; + register THPHuffmanTab *h = Yachuff; + +#define cnt4 code + asm + { + lwz cnt, info->cnt; + addi increment, h, 32; + lwz cb, info->currByte; + } + + for (k = 1; k < 64; k++) + { + register s32 ssss; + register s32 rrrr; + + asm { + addi cnt4, cnt, 4; + cmpwi cnt, 28; + rlwnm tmp, cb, cnt4, 27, 31; + bgt _notEnoughBits; + + lbzx ssss, h, tmp; + lbzx code, increment, tmp; + cmpwi ssss, 0xFF; + + beq _FailedCheckEnoughBits; + add cnt, cnt, code; + b _DoneDecodeTab; + } + + { + register u32 maxcodebase; + register u32 tmp2; + + _FailedCheckEnoughBits: + cnt += 5; + maxcodebase = (u32) & (h->maxCode); + asm { + li tmp2, sizeof(s32)*(5); + li code, 5; + add maxcodebase, maxcodebase, tmp2; + __WHILE_START: + cmpwi cnt, 33; + slwi tmp, tmp, 1 + + beq _FCEB_faster; + rlwnm ssss, cb, cnt, 31, 31; + lwzu tmp2, 4(maxcodebase); + or tmp, tmp, ssss + addi cnt, cnt, 1; + b __WHILE_CHECK; + + _FCEB_faster: + lwz ssss, info->c; + li cnt, 1; + lwzu cb, 4(ssss); + + lwzu tmp2, 4(maxcodebase); + + stw ssss, info->c; + rlwimi tmp, cb, 1,31,31; + b __FL_WHILE_CHECK; + + __FL_WHILE_START: + slwi tmp, tmp, 1; + + rlwnm ssss, cb, cnt, 31, 31; + lwzu tmp2, 4(maxcodebase); + or tmp, tmp, ssss; + + __FL_WHILE_CHECK: + cmpw tmp,tmp2 + addi cnt, cnt, 1; + addi code, code, 1 + bgt __FL_WHILE_START; + b _FCEB_Done; + + __WHILE_CHECK: + cmpw tmp,tmp2 + addi code, code, 1 + bgt __WHILE_START; + } + } + _FCEB_Done: + ssss = (h->Vij[(s32)(tmp + h->valPtr[code])]); + goto _DoneDecodeTab; + + _notEnoughBits: + asm + { + cmpwi cnt, 33; + lwz tmp, info->c; + beq _getfullword; + + cmpwi cnt, 32; + rlwnm code, cb, cnt4, 27, 31 + beq _1bitleft; + + lbzx ssss, h, code; + lbzx rrrr, increment, code; + cmpwi ssss, 0xFF; + add code, cnt, rrrr; + beq _FailedCheckNoBits0; + + cmpwi code, 33; + bgt _FailedCheckNoBits1; + } + cnt = (u32)code; + goto _DoneDecodeTab; + + _getfullword: + { + asm + { + lwzu cb, 4(tmp); + rlwinm code, cb, 5, 27, 31 + stw tmp, info->c; + lbzx ssss, h, code; + lbzx tmp, increment, code; + cmpwi ssss, 0xFF + addi cnt, tmp, 1 + beq _FailedCheckEnoughbits_Updated; + } + } + goto _DoneDecodeTab; + + _FailedCheckEnoughbits_Updated: + ssss = 5; + do + { + asm + { + subfic tmp, ssss, 31; + addi ssss, ssss, 1; + srw code, cb, tmp; + } + } while (code > h->maxCode[ssss]); + + cnt = (u32)(ssss + 1); + ssss = (h->Vij[(s32)(code + h->valPtr[ssss])]); + + goto _DoneDecodeTab; + + _1bitleft: + asm { + lwzu cb, 4(tmp); + + stw tmp, info->c; + rlwimi code, cb, 4, 28, 31; + lbzx ssss, h, code; + lbzx cnt, increment, code + cmpwi ssss, 0xFF + beq _DammitRead4; + + } + + goto _DoneDecodeTab; + + _DammitRead4: + { + register u32 maxcodebase = (u32) & (h->maxCode); + register u32 tmp2; + + asm { + li cnt, sizeof(s32)*5; + add maxcodebase, maxcodebase, cnt; + + slwi tmp, code, 32-5; + li cnt,5; + rlwimi tmp, cb, 32-1, 1,31; + + __DR4_WHILE_START: + + subfic ssss, cnt, 31; + lwzu tmp2, 4(maxcodebase); + srw code, tmp, ssss; + __DR4_WHILE_CHECK: + cmpw code, tmp2 + addi cnt, cnt, 1 + bgt __DR4_WHILE_START; + + } + } + ssss = (h->Vij[(s32)(code + h->valPtr[cnt])]); + goto _DoneDecodeTab; + + _FailedCheckNoBits0: + _FailedCheckNoBits1: + _REALFAILEDCHECKNOBITS: + { + register u32 mask = 0xFFFFFFFF << (33 - cnt); + register u32 tmp2; + register u32 tmp3; + code = (s32)(cb & (~mask)); + mask = (u32) & (h->maxCode); + + asm { + lwz tmp, info->c; + subfic tmp2, cnt, 33; + addi tmp3, tmp2, 1; + slwi tmp2, tmp2, 2; + lwzu cb, 4(tmp); + add mask,mask, tmp2; + stw tmp, info->c; + slwi code, code, 1; + rlwimi code, cb, 1, 31, 31; + lwzu tmp2, 4(mask); + li cnt, 2; + b __FCNB1_WHILE_CHECK; + + __FCNB1_WHILE_START: + slwi code, code, 1; + + addi tmp3, tmp3, 1; + lwzu tmp2, 4(mask); + add code, code, rrrr; + addi cnt, cnt, 1; + + __FCNB1_WHILE_CHECK: + cmpw code, tmp2; + rlwnm rrrr, cb, cnt, 31, 31; + bgt __FCNB1_WHILE_START; + + } + ssss = (h->Vij[(s32)(code + h->valPtr[tmp3])]); + } + + goto _DoneDecodeTab; + + _DoneDecodeTab: + asm { + andi. rrrr, ssss, 15; + srawi ssss, ssss, 4; + beq _RECV_SSSS_ZERO; + } + + { + k += ssss; + { + register s32 v; +#define cnt33 code + register u32 cnt1; + register u32 tmp1; + asm + { + subfic cnt33,cnt,33; + subfc. tmp, cnt33, rrrr; + subi cnt1,cnt,1; + bgt _RECVnotEnoughBits; + add cnt,cnt,rrrr; + slw tmp1,cb,cnt1; + subfic v,rrrr,32; + srw ssss,tmp1,v; + } + asm + { + b _RECVDone; + _RECVnotEnoughBits: + lwz tmp1, info->c; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi cnt, tmp, 1; + stw tmp1, info->c; + srw tmp1, cb, cnt33; + + add v, tmp1, v; + subfic tmp, rrrr, 32; + srw ssss, v, tmp; + _RECVDone: + } + } + +#undef cnt33 + + if (__cntlzw((u32)ssss) > 32 - rrrr) + { + ssss += ((0xFFFFFFFF << rrrr) + 1); + } + + block[__THPJpegNaturalOrder[k]] = (s16)ssss; + goto _RECV_END; + } + + { + _RECV_SSSS_ZERO: + if (ssss != 15) + { + break; + } + + k += 15; + }; + + asm + { + _RECV_END: + } + } + info->cnt = cnt; + info->currByte = cb; + } +#undef cnt4 +} + +void __THPHuffDecodeDCTCompU(register THPFileInfo *info, THPCoeff *block) +{ + register s32 t; + register THPCoeff diff; + THPCoeff dc; + register s32 v; + register u32 cb; + register u32 cnt; + register u32 cnt33; + register u32 tmp; + register u32 cnt1; + register u32 tmp1; + register s32 k; + register s32 ssss; + register s32 rrrr; + + __dcbz((void *)block, 0); + t = __THPHuffDecodeTab(info, Udchuff); + __dcbz((void *)block, 32); + diff = 0; + __dcbz((void *)block, 64); + + if (t) + { + asm + { + lwz cnt,info->cnt; + subfic cnt33,cnt,33; + lwz cb,info->currByte; + subfc. tmp, cnt33, t; + subi cnt1,cnt,1; + bgt _notEnoughBitsDIFF; + add v,cnt,t; + slw cnt,cb,cnt1; + stw v,info->cnt; + subfic v,t,32; + srw diff,cnt,v; + } + + asm + { + b _DoneDIFF; + _notEnoughBitsDIFF: + lwz tmp1, info->c; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, cnt33; + stw tmp1, info->c; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, t, 32; + srw diff, v, tmp; + _DoneDIFF: + } + + if (__cntlzw((u32)diff) > 32 - t) + { + diff += ((0xFFFFFFFF << t) + 1); + } + } + + __dcbz((void *)block, 96); + dc = (s16)(info->components[1].predDC + diff); + block[0] = info->components[1].predDC = dc; + + for (k = 1; k < 64; k++) + { + ssss = __THPHuffDecodeTab(info, Uachuff); + rrrr = ssss >> 4; + ssss &= 15; + + if (ssss) + { + k += rrrr; + asm + { + lwz cnt,info->cnt; + subfic cnt33,cnt,33; + lwz cb,info->currByte; + subf. tmp, cnt33, ssss; + subi cnt1,cnt,1; + bgt _notEnoughBits; + add v,cnt,ssss; + slw cnt,cb,cnt1; + stw v,info->cnt; + subfic v,ssss,32; + srw rrrr,cnt,v; + } + + asm + { + b _Done; + _notEnoughBits: + lwz tmp1, info->c; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, cnt33; + stw tmp1, info->c; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, ssss, 32; + srw rrrr, v, tmp; + _Done: + } + + if (__cntlzw((u32)rrrr) > 32 - ssss) + { + rrrr += ((0xFFFFFFFF << ssss) + 1); + } + + block[__THPJpegNaturalOrder[k]] = (s16)rrrr; + } + + else + { + if (rrrr != 15) + break; + k += 15; + } + } +} + +void __THPHuffDecodeDCTCompV(register THPFileInfo *info, THPCoeff *block) +{ + register s32 t; + register THPCoeff diff; + THPCoeff dc; + register s32 v; + register u32 cb; + register u32 cnt; + register u32 cnt33; + register u32 tmp; + register u32 cnt1; + register u32 tmp1; + register s32 k; + register s32 ssss; + register s32 rrrr; + + __dcbz((void *)block, 0); + t = __THPHuffDecodeTab(info, Vdchuff); + __dcbz((void *)block, 32); + diff = 0; + __dcbz((void *)block, 64); + + if (t) + { + asm + { + lwz cnt,info->cnt; + subfic cnt33,cnt,33; + lwz cb,info->currByte; + subf. tmp, cnt33, t; + subi cnt1,cnt,1; + bgt _notEnoughBitsDIFF; + add v,cnt,t; + slw cnt,cb,cnt1; + stw v,info->cnt; + subfic v,t,32; + srw diff,cnt,v; + } + + asm + { + b _DoneDIFF; + _notEnoughBitsDIFF: + lwz tmp1, info->c; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, cnt33; + stw tmp1, info->c; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, t, 32; + srw diff, v, tmp; + _DoneDIFF: + } + + if (__cntlzw((u32)diff) > 32 - t) + { + diff += ((0xFFFFFFFF << t) + 1); + } + } + + __dcbz((void *)block, 96); + + dc = (s16)(info->components[2].predDC + diff); + block[0] = info->components[2].predDC = dc; + + for (k = 1; k < 64; k++) + { + ssss = __THPHuffDecodeTab(info, Vachuff); + rrrr = ssss >> 4; + ssss &= 15; + + if (ssss) + { + k += rrrr; + + asm + { + lwz cnt,info->cnt; + subfic cnt33,cnt,33; + lwz cb,info->currByte; + + subf. tmp, cnt33, ssss; + subi cnt1,cnt,1; + + bgt _notEnoughBits; + add v,cnt,ssss; + + slw cnt,cb,cnt1; + stw v,info->cnt; + subfic v,ssss,32; + srw rrrr,cnt,v; + } + + asm + { + b _Done; + _notEnoughBits: + lwz tmp1, info->c; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, cnt33; + stw tmp1, info->c; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, ssss, 32; + srw rrrr, v, tmp; + _Done: + } + + if (__cntlzw((u32)rrrr) > 32 - ssss) + { + rrrr += ((0xFFFFFFFF << ssss) + 1); + } + + block[__THPJpegNaturalOrder[k]] = (s16)rrrr; + } + else + { + if (rrrr != 15) + break; + k += 15; + } + } +} + +BOOL THPInit(void) +{ + u8 *base; + OSRegisterVersion(__THPVersion); + base = (u8 *)(0xE000 << 16); // lc base + + __THPLCWork512[0] = base; + base += 0x2000; + __THPLCWork512[1] = base; + base += 0x800; + __THPLCWork512[2] = base; + base += 0x200; + + base = (u8 *)(0xE000 << 16); // lc base + __THPLCWork672[0] = base; + base += 0x2800; + __THPLCWork672[1] = base; + base += 0xA00; + __THPLCWork672[2] = base; + base += 0xA80; + + OSInitFastCast(); + + __THPInitFlag = TRUE; + return TRUE; +} \ No newline at end of file diff --git a/libs/dolphin/upnp/UPnP.c b/libs/dolphin/upnp/UPnP.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/upnp/UPnPHttp.c b/libs/dolphin/upnp/UPnPHttp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/upnp/UPnPHttpd.c b/libs/dolphin/upnp/UPnPHttpd.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/upnp/UPnPHttpdResponse.c b/libs/dolphin/upnp/UPnPHttpdResponse.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/upnp/UPnPSsdp.c b/libs/dolphin/upnp/UPnPSsdp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/upnp/UPnPUri.c b/libs/dolphin/upnp/UPnPUri.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/upnp/UPnPUuid.c b/libs/dolphin/upnp/UPnPUuid.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/vi/vi.c b/libs/dolphin/vi/vi.c new file mode 100644 index 000000000..61ed43d58 --- /dev/null +++ b/libs/dolphin/vi/vi.c @@ -0,0 +1,1037 @@ +#include +#include +#include +#include + +#include + +// Useful macros. +#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))) + +const char* __VIVersion = "<< Dolphin SDK - VI\trelease build: Apr 17 2003 12:33:22 (0x2301) >>"; + +static BOOL IsInitialized; +static vu32 retraceCount; +static u32 flushFlag; +static OSThreadQueue retraceQueue; +static VIRetraceCallback PreCB; +static VIRetraceCallback PostCB; +static VIPositionCallback PositionCallback; +static u32 encoderType; + +static s16 displayOffsetH; +static s16 displayOffsetV; + +static vu32 changeMode; +static vu64 changed; + +static vu32 shdwChangeMode; +static vu64 shdwChanged; + +static VITimingInfo* CurrTiming; +static u32 CurrTvMode; + +static u32 NextBufAddr; +static u32 CurrBufAddr; + +static u32 FBSet; + +static vu16 regs[59]; +static vu16 shdwRegs[59]; + +static VIPositionInfo HorVer; +// clang-format off +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, + }, +}; +// clang-format on + +static u16 taps[25] = { 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 }; + +// forward declaring statics +static u32 getCurrentFieldEvenOdd(); + +static void getEncoderType(void) +{ + // UNUSED FUNCTION +} + +static int cntlzd(u64 bit) +{ + u32 hi, lo; + int value; + + hi = (u32)(bit >> 32); + lo = (u32)(bit & 0xFFFFFFFF); + value = __cntlzw(hi); + + if (value < 32) { + return value; + } + + return (32 + __cntlzw(lo)); +} + +static BOOL VISetRegs(void) +{ + int regIndex; + + if (!((shdwChangeMode == 1) && (getCurrentFieldEvenOdd() == 0))) { + while (shdwChanged) { + regIndex = cntlzd(shdwChanged); + __VIRegs[regIndex] = shdwRegs[regIndex]; + shdwChanged &= ~(VI_BITMASK(regIndex)); + } + + shdwChangeMode = 0; + CurrTiming = HorVer.timing; + CurrTvMode = HorVer.tv; + CurrBufAddr = NextBufAddr; + + return TRUE; + } + return FALSE; +} + +static void __VIRetraceHandler(__OSInterrupt interrupt, OSContext* context) +{ + OSContext exceptionContext; + u16 viReg; + u32 inter = 0; + + viReg = __VIRegs[VI_DISP_INT_0]; + if (viReg & 0x8000) { + __VIRegs[VI_DISP_INT_0] = (u16)(viReg & ~0x8000); + inter |= 1; + } + + viReg = __VIRegs[VI_DISP_INT_1]; + if (viReg & 0x8000) { + __VIRegs[VI_DISP_INT_1] = (u16)(viReg & ~0x8000); + inter |= 2; + } + + viReg = __VIRegs[VI_DISP_INT_2]; + if (viReg & 0x8000) { + __VIRegs[VI_DISP_INT_2] = (u16)(viReg & ~0x8000); + inter |= 4; + } + + viReg = __VIRegs[VI_DISP_INT_3]; + if (viReg & 0x8000) { + __VIRegs[VI_DISP_INT_3] = (u16)(viReg & ~0x8000); + inter |= 8; + } + + if ((inter & 4) || (inter & 8)) { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + if (PositionCallback) { + s16 x, y; + __VIGetCurrentPosition(&x, &y); + (*PositionCallback)(x, y); + } + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + return; + } + + retraceCount++; + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + if (PreCB) { + (*PreCB)(retraceCount); + } + + if (flushFlag) { + if (VISetRegs()) { + flushFlag = 0; + SIRefreshSamplingRate(); + } + } + + if (PostCB) { + OSClearContext(&exceptionContext); + (*PostCB)(retraceCount); + } + + OSWakeupThread(&retraceQueue); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback callback) +{ + int interrupt; + VIRetraceCallback oldCallback; + + oldCallback = PreCB; + + interrupt = OSDisableInterrupts(); + PreCB = callback; + OSRestoreInterrupts(interrupt); + + return oldCallback; +} + +VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback callback) +{ + int interrupt; + VIRetraceCallback oldCallback; + + oldCallback = PostCB; + + interrupt = OSDisableInterrupts(); + PostCB = callback; + OSRestoreInterrupts(interrupt); + + return oldCallback; +} + +static VITimingInfo* 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]; + } + + return nullptr; +} + +void __VIInit(VITVMode mode) +{ + VITimingInfo* tm; + u32 nonInter; + vu32 a; + u32 tv, tvForReg; + + u16 hct, vct; + + nonInter = mode & 2; + tv = (u32)mode >> 2; + + *(u32*)OSPhysicalToCached(0xCC) = tv; + + tm = getTiming(mode); + + __VIRegs[VI_DISP_CONFIG] = 2; + for (a = 0; a < 1000; a++) { + ; + } + + __VIRegs[VI_DISP_CONFIG] = 0; + + __VIRegs[VI_HORIZ_TIMING_0U] = tm->hlw << 0; + __VIRegs[VI_HORIZ_TIMING_0L] = (tm->hce << 0) | (tm->hcs << 8); + + __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[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; + + if (mode != VI_TVMODE_NTSC_PROG && mode != VI_TVMODE_NTSC_3D && mode != VI_TVMODE_GCA_PROG) { + __VIRegs[VI_DISP_CONFIG] = (1 << 0) | (0 << 1) | (nonInter << 2) | (0 << 3) | (0 << 4) | (0 << 6) | (tv << 8); + __VIRegs[VI_CLOCK_SEL] = 0; + + } else { + __VIRegs[VI_DISP_CONFIG] = (1 << 0) | (0 << 1) | (1 << 2) | (0 << 3) | (0 << 4) | (0 << 6) | (tv << 8); + __VIRegs[VI_CLOCK_SEL] = 1; + } +} + +static void AdjustPosition(u16 acv) +{ + s32 coeff, frac; + + HorVer.adjDispPosX = (u16)CLAMP(0, 720 - HorVer.dispSizeX, (s16)HorVer.dispPosX + displayOffsetH); + + 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); +} + +static void ImportAdjustingValues(void) +{ + displayOffsetH = __OSLockSram()->displayOffsetH; + displayOffsetV = 0; + __OSUnlockSram(FALSE); +} + +void VIInit(void) +{ + u16 dspCfg; + u32 value, tv, tvInBootrom; + + if (IsInitialized) { + return; + } + + OSRegisterVersion(__VIVersion); + IsInitialized = TRUE; + encoderType = 1; + + if (!(__VIRegs[VI_DISP_CONFIG] & 1)) { + __VIInit(VI_TVMODE_NTSC_INT); + } + + retraceCount = 0; + changed = 0; + shdwChanged = 0; + changeMode = 0; + 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; + ImportAdjustingValues(); + tvInBootrom = *(u32*)OSPhysicalToCached(0xCC); + dspCfg = __VIRegs[VI_DISP_CONFIG]; + + HorVer.nonInter = ((((u32)(dspCfg)) >> 2 & 0x00000001)); + HorVer.tv = ((((u32)(dspCfg)) & 0x00000300) >> 8); + + 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; + + 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; + + AdjustPosition(CurrTiming->acv); + + 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; + + 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; + + PreCB = nullptr; + PostCB = nullptr; + + __OSSetInterruptHandler(24, __VIRetraceHandler); + __OSUnmaskInterrupts((0x80000000u >> (24))); +} + +void VIWaitForRetrace(void) +{ + int interrupt; + u32 startCount; + + interrupt = OSDisableInterrupts(); + startCount = retraceCount; + do { + OSSleepThread(&retraceQueue); + } while (startCount == retraceCount); + OSRestoreInterrupts(interrupt); +} + +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); + + vct++; + hct++; + + 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); +} + +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 setBBIntervalRegs(VITimingInfo* 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 = (u16)((((u32)(tm->bs3))) | (((u32)(tm->be3)) << 5)); + regs[VI_BBI_ODD] = val; + changed |= VI_BITMASK(VI_BBI_ODD); + + val = (u16)((((u32)(tm->bs2))) | (((u32)(tm->be2)) << 5)); + regs[VI_BBI_EVEN_U] = val; + changed |= VI_BITMASK(VI_BBI_EVEN_U); + + val = (u16)((((u32)(tm->bs4))) | (((u32)(tm->be4)) << 5)); + regs[VI_BBI_EVEN] = val; + changed |= VI_BITMASK(VI_BBI_EVEN); +} + +static void setScalingRegs(u16 panSizeX, u16 dispSizeX, BOOL is3D) +{ + u32 scale; + + panSizeX = (u16)(is3D ? panSizeX * 2 : 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); + } else { + regs[VI_HSR] = (u16)((((u32)(256))) | (((u32)(0)) << 12)); + changed |= VI_BITMASK(VI_HSR); + } +} + +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); + + if (dispPosY % 2 == 1) { + u32 tmp = *tfbb; + *tfbb = *bfbb; + *bfbb = tmp; + } + + *tfbb = ToPhysical(*tfbb); + *bfbb = ToPhysical(*bfbb); +} + +static void setFbbRegs(VIPositionInfo* hv, 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); + } + + if (IS_LOWER_16MB(*tfbb) && IS_LOWER_16MB(*bfbb) && IS_LOWER_16MB(*rtfbb) && IS_LOWER_16MB(*rbfbb)) { + shifted = 0; + } else { + shifted = 1; + } + + if (shifted) { + *tfbb >>= 5; + *bfbb >>= 5; + *rtfbb >>= 5; + *rbfbb >>= 5; + } + + regs[VI_TOP_FIELD_BASE_LEFT_U] = (u16)(*tfbb & 0xFFFF); + changed |= VI_BITMASK(VI_TOP_FIELD_BASE_LEFT_U); + + 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); + } +} + +static void setHorizontalRegs(VITimingInfo* tm, u16 dispPosX, u16 dispSizeX) +{ + u32 hbe, hbs, hbeLo, 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); + 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); +} + +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; + + if (regs[VI_CLOCK_SEL] & 1) { + c = 1; + d = 2; + } else { + c = 2; + 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)); + } 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)); + } + + actualAcv = (u16)(dispSizeY / c); + + if (black) { + actualPrbOdd += 2 * actualAcv - 2; + actualPsbOdd += 2; + actualPrbEven += 2 * actualAcv - 2; + actualPsbEven += 2; + 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); +} + +static void PrintDebugPalCaution(void) +{ + static u32 message = 0; + + if (message == 0) { + message = 1; + OSReport("***************************************\n"); + OSReport(" ! ! ! C A U T I O N ! ! ! \n"); + OSReport("This TV format \"DEBUG_PAL\" is only for \n"); + OSReport("temporary solution until PAL DAC board \n"); + OSReport("is available. Please do NOT use this \n"); + OSReport("mode in real games!!! \n"); + OSReport("***************************************\n"); + } +} + +void VIConfigure(const GXRenderModeObj* obj) +{ + VITimingInfo* tm; + u32 regDspCfg; + BOOL enabled; + u32 newNonInter, tvInBootrom, tvInGame; + + enabled = OSDisableInterrupts(); + newNonInter = (u32)obj->viTVmode & 3; + + if (HorVer.nonInter != newNonInter) { + changeMode = 1; + HorVer.nonInter = newNonInter; + } + + tvInGame = (u32)obj->viTVmode >> 2; + tvInBootrom = *(u32*)OSPhysicalToCached(0xCC); + + if (tvInGame == VI_DEBUG_PAL) { + PrintDebugPalCaution(); + } + + switch (tvInBootrom) { + case VI_MPAL: + case VI_NTSC: + case VI_GCA: + if (tvInGame == VI_NTSC || tvInGame == VI_MPAL || tvInGame == VI_GCA) { + break; + } + goto panic; + case VI_PAL: + case VI_EURGB60: + if (tvInGame == VI_PAL || tvInGame == VI_EURGB60) { + break; + } + default: + panic: + OSErrorLine(1908, "VIConfigure(): Tried to change mode from (%d) to (%d), which is forbidden\n", tvInBootrom, tvInGame); + } + // if (((tvInBootrom != VI_PAL && tvInBootrom != VI_EURGB60) && (tvInGame == VI_PAL || tvInGame == VI_EURGB60)) + // || ((tvInBootrom == VI_PAL || tvInBootrom == VI_EURGB60) && (tvInGame != VI_PAL && tvInGame != VI_EURGB60))) { + + // OSErrorLine(1908, "VIConfigure(): Tried to change mode from (%d) to (%d), which is forbidden\n", tvInBootrom, tvInGame); + // } + + if ((tvInGame == VI_NTSC) || (tvInGame == VI_MPAL)) { + HorVer.tv = tvInBootrom; + } else { + HorVer.tv = tvInGame; + } + + HorVer.dispPosX = obj->viXOrigin; + HorVer.dispPosY = (u16)((HorVer.nonInter == VI_NON_INTERLACE) ? (u16)(obj->viYOrigin * 2) : obj->viYOrigin); + HorVer.dispSizeX = obj->viWidth; + HorVer.fbSizeX = obj->fbWidth; + HorVer.fbSizeY = obj->xfbHeight; + HorVer.xfbMode = obj->xFBmode; + HorVer.panSizeX = HorVer.fbSizeX; + HorVer.panSizeY = HorVer.fbSizeY; + HorVer.panPosX = 0; + HorVer.panPosY = 0; + + 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)); + HorVer.timing = tm; + + AdjustPosition(tm->acv); + if (encoderType == 0) { + HorVer.tv = VI_DEBUG; + } + setInterruptRegs(tm); + + regDspCfg = regs[VI_DISP_CONFIG]; + // TODO: USE BIT MACROS OR SOMETHING + if ((HorVer.nonInter == VI_PROGRESSIVE) || (HorVer.nonInter == VI_3D)) { + regDspCfg = (((u32)(regDspCfg)) & ~0x00000004) | (((u32)(1)) << 2); + } else { + regDspCfg = (((u32)(regDspCfg)) & ~0x00000004) | (((u32)(HorVer.nonInter & 1)) << 2); + } + + regDspCfg = (((u32)(regDspCfg)) & ~0x00000008) | (((u32)(HorVer.is3D)) << 3); + + if ((HorVer.tv == VI_DEBUG_PAL) || (HorVer.tv == VI_EURGB60) || (HorVer.tv == VI_GCA)) { + regDspCfg = (((u32)(regDspCfg)) & ~0x00000300); + } else { + regDspCfg = (((u32)(regDspCfg)) & ~0x00000300) | (((u32)(HorVer.tv)) << 8); + } + + regs[VI_DISP_CONFIG] = (u16)regDspCfg; + changed |= VI_BITMASK(0x01); + + regDspCfg = regs[VI_CLOCK_SEL]; + if (obj->viTVmode == VI_TVMODE_NTSC_PROG || obj->viTVmode == VI_TVMODE_NTSC_3D || obj->viTVmode == VI_TVMODE_GCA_PROG) { + regDspCfg = (u32)(regDspCfg & ~0x1) | 1; + } else { + regDspCfg = (u32)(regDspCfg & ~0x1); + } + + regs[VI_CLOCK_SEL] = (u16)regDspCfg; + + changed |= 0x200; + + setScalingRegs(HorVer.panSizeX, HorVer.dispSizeX, HorVer.is3D); + setHorizontalRegs(tm, HorVer.adjDispPosX, HorVer.dispSizeX); + setBBIntervalRegs(tm); + setPicConfig(HorVer.fbSizeX, HorVer.xfbMode, HorVer.panPosX, HorVer.panSizeX, &HorVer.wordPerLine, &HorVer.std, &HorVer.wpl, + &HorVer.xof); + + if (FBSet) { + 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); + OSRestoreInterrupts(enabled); +} + +void VIConfigurePan(u16 panPosX, u16 panPosY, u16 panSizeX, u16 panSizeY) +{ + // UNUSED FUNCTION +} + +void VIFlush(void) +{ + BOOL enabled; + s32 regIndex; + u32 val; // for stack. + + enabled = OSDisableInterrupts(); + shdwChangeMode |= changeMode; + changeMode = 0; + shdwChanged |= changed; + + while (changed) { + regIndex = cntlzd(changed); + shdwRegs[regIndex] = regs[regIndex]; + changed &= ~VI_BITMASK(regIndex); + } + + flushFlag = 1; + NextBufAddr = HorVer.bufAddr; + OSRestoreInterrupts(enabled); +} + +void VISetNextFrameBuffer(void* fb) +{ + BOOL enabled = OSDisableInterrupts(); + HorVer.bufAddr = (u32)fb; + FBSet = 1; + setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); + OSRestoreInterrupts(enabled); +} + +void* VIGetNextFrameBuffer(void) { return (void*)NextBufAddr; } + +void* VIGetCurrentFrameBuffer(void) { return (void*)CurrBufAddr; } + +void VISetNextRightFrameBuffer(void* fb) +{ + // UNUSED FUNCTION +} + +void VISetBlack(BOOL isBlack) +{ + int interrupt; + VITimingInfo* tm; + + 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); +} + +void VISet3D(void) +{ + // UNUSED FUNCTION +} + +u32 VIGetRetraceCount(void) { return retraceCount; } + +static void GetCurrentDisplayPosition(u32* hct, u32* vct) +{ + u32 hcount, vcount0, vcount; + vcount = __VIRegs[VI_VERT_COUNT] & 0x7FF; + + do { + vcount0 = vcount; + hcount = __VIRegs[VI_HORIZ_COUNT] & 0x7FF; + vcount = __VIRegs[VI_VERT_COUNT] & 0x7FF; + } while (vcount0 != vcount); + + *hct = hcount; + *vct = vcount; +} + +static u32 getCurrentHalfLine(void) +{ + u32 hcount, vcount; + GetCurrentDisplayPosition(&hcount, &vcount); + + return ((vcount - 1) << 1) + ((hcount - 1) / CurrTiming->hlw); +} + +static u32 getCurrentFieldEvenOdd() { return (getCurrentHalfLine() < CurrTiming->numHalfLines) ? 1 : 0; } + +u32 VIGetNextField(void) +{ + u32 nextField; + int interrupt; + + interrupt = OSDisableInterrupts(); + nextField = getCurrentFieldEvenOdd() ^ 1; + OSRestoreInterrupts(interrupt); + return nextField ^ (HorVer.adjDispPosY & 1); +} + +u32 VIGetCurrentLine(void) +{ + u32 line; + VITimingInfo* tm; + int interrupt; + + tm = CurrTiming; + interrupt = OSDisableInterrupts(); + line = getCurrentHalfLine(); + OSRestoreInterrupts(interrupt); + + if (line >= tm->numHalfLines) { + line -= tm->numHalfLines; + } + + return (line >> 1); +} + +u32 VIGetTvFormat(void) +{ + u32 fmt; + int interrupt; + + interrupt = OSDisableInterrupts(); + + switch (CurrTvMode) { + case VI_NTSC: + case VI_DEBUG: + case VI_GCA: + fmt = VI_NTSC; + break; + case VI_PAL: + case VI_DEBUG_PAL: + fmt = VI_PAL; + break; + case VI_EURGB60: + case VI_MPAL: + fmt = CurrTvMode; + break; + } + + OSRestoreInterrupts(interrupt); + return fmt; +} + +u32 VIGetDTVStatus(void) +{ + u32 stat; + int interrupt; + + interrupt = OSDisableInterrupts(); + stat = (__VIRegs[VI_DTV_STAT] & 3); + OSRestoreInterrupts(interrupt); + return (stat & 1); +} + +void __VIDisplayPositionToXY(u32 hcount, u32 vcount, s16* x, s16* y) +{ + u32 halfLine = ((vcount - 1) << 1) + ((hcount - 1) / CurrTiming->hlw); + + if (HorVer.nonInter == VI_INTERLACE) { + if (halfLine < CurrTiming->numHalfLines) { + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) { + *y = -1; + } else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbOdd) { + *y = -1; + } else { + *y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd) & ~1); + } + } else { + halfLine -= CurrTiming->numHalfLines; + + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbEven) { + *y = -1; + } else if (halfLine >= CurrTiming->numHalfLines - 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->equ * 3 + CurrTiming->prbOdd) { + *y = -1; + } else if (halfLine >= CurrTiming->numHalfLines - 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->equ * 3 + CurrTiming->prbOdd) { + *y = -1; + } else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbOdd) { + *y = -1; + } else { + *y = (s16)(halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd); + } + } else { + halfLine -= CurrTiming->numHalfLines; + + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbEven) { + *y = -1; + } else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbEven) { + *y = -1; + } else + *y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbEven) & ~1); + } + } + + *x = (s16)(hcount - 1); +} + +void __VIGetCurrentPosition(s16* x, s16* y) +{ + u32 h, v; + GetCurrentDisplayPosition(&h, &v); + __VIDisplayPositionToXY(h, v, x, y); +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Export/mslsupp.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Export/mslsupp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/UDP_Stubs.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/UDP_Stubs.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/targcont.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/targcont.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/target_options.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/target_options.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/usr_put.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/usr_put.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/dispatch.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/dispatch.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/main_TRK.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/main_TRK.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mainloop.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mainloop.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mem_TRK.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mem_TRK.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msg.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msg.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mutex_TRK.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mutex_TRK.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/notify.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/notify.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubevent.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubevent.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubinit.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubinit.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/serpoll.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/serpoll.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/gamedev/cust_connection/cc/exi2/GCN/EXI2_DDH_GCN/main.c b/libs/runtime_libs/gamedev/cust_connection/cc/exi2/GCN/EXI2_DDH_GCN/main.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/gamedev/cust_connection/cc/exi2/GCN/EXI2_GDEV_GCN/main.c b/libs/runtime_libs/gamedev/cust_connection/cc/exi2/GCN/EXI2_GDEV_GCN/main.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/gamedev/cust_connection/utils/common/CircleBuffer.c b/libs/runtime_libs/gamedev/cust_connection/utils/common/CircleBuffer.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/gamedev/cust_connection/utils/common/MWTrace.c b/libs/runtime_libs/gamedev/cust_connection/utils/common/MWTrace.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/gamedev/cust_connection/utils/gc/MWCriticalSection_gc.cpp b/libs/runtime_libs/gamedev/cust_connection/utils/gc/MWCriticalSection_gc.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/SB/Core/gc/iFMV.cpp b/src/SB/Core/gc/iFMV.cpp index 2d348521f..8fd0a89e1 100644 --- a/src/SB/Core/gc/iFMV.cpp +++ b/src/SB/Core/gc/iFMV.cpp @@ -8,6 +8,7 @@ #include "xFile.h" #include "xPar.h" +#include "gx.h" #include "zGlobals.h" diff --git a/src/SB/Core/gc/iFMV.h b/src/SB/Core/gc/iFMV.h index 3c49fed20..57b28f7f3 100644 --- a/src/SB/Core/gc/iFMV.h +++ b/src/SB/Core/gc/iFMV.h @@ -3,7 +3,7 @@ #include #include -#include +#include #ifdef __cplusplus diff --git a/src/SB/Core/gc/iMath.cpp b/src/SB/Core/gc/iMath.cpp index 35f6ff623..286d856ec 100644 --- a/src/SB/Core/gc/iMath.cpp +++ b/src/SB/Core/gc/iMath.cpp @@ -1,6 +1,6 @@ #include "iMath.h" -#include +#include F32 isin(F32 x) { diff --git a/src/SB/Core/gc/iMemMgr.cpp b/src/SB/Core/gc/iMemMgr.cpp index ec7aaf201..7772094ba 100644 --- a/src/SB/Core/gc/iMemMgr.cpp +++ b/src/SB/Core/gc/iMemMgr.cpp @@ -3,7 +3,7 @@ #include "xMemMgr.h" #include -#include +#include #include U32 mem_top_alloc; diff --git a/src/SB/Core/gc/iMix.c b/src/SB/Core/gc/iMix.c index e1fba9861..a08f0f46e 100644 --- a/src/SB/Core/gc/iMix.c +++ b/src/SB/Core/gc/iMix.c @@ -6,358 +6,135 @@ static unsigned int __MIXSoundMode; static int __MIXDvdStreamAttenUser; static int __MIXDvdStreamAttenCurrent; -unsigned short __MIXVolumeTable[] = -{ - 0x0, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, - 0x2, 0x3, 0x3, 0x3, - 0x3, 0x3, 0x3, 0x3, - 0x3, 0x3, 0x3, 0x3, - 0x3, 0x3, 0x3, 0x3, - 0x3, 0x3, 0x3, 0x3, - 0x3, 0x3, 0x3, 0x3, - 0x3, 0x3, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, - 0x4, 0x5, 0x5, 0x5, - 0x5, 0x5, 0x5, 0x5, - 0x5, 0x5, 0x5, 0x5, - 0x5, 0x5, 0x5, 0x5, - 0x5, 0x6, 0x6, 0x6, - 0x6, 0x6, 0x6, 0x6, - 0x6, 0x6, 0x6, 0x6, - 0x6, 0x6, 0x7, 0x7, - 0x7, 0x7, 0x7, 0x7, - 0x7, 0x7, 0x7, 0x7, - 0x7, 0x7, 0x8, 0x8, - 0x8, 0x8, 0x8, 0x8, - 0x8, 0x8, 0x8, 0x8, - 0x9, 0x9, 0x9, 0x9, - 0x9, 0x9, 0x9, 0x9, - 0x9, 0xA, 0xA, 0xA, - 0xA, 0xA, 0xA, 0xA, - 0xA, 0xA, 0xB, 0xB, - 0xB, 0xB, 0xB, 0xB, - 0xB, 0xC, 0xC, 0xC, - 0xC, 0xC, 0xC, 0xC, - 0xD, 0xD, 0xD, 0xD, - 0xD, 0xD, 0xD, 0xE, - 0xE, 0xE, 0xE, 0xE, - 0xE, 0xF, 0xF, 0xF, - 0xF, 0xF, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x11, - 0x11, 0x11, 0x11, 0x11, - 0x12, 0x12, 0x12, 0x12, - 0x12, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x14, 0x14, - 0x14, 0x14, 0x15, 0x15, - 0x15, 0x15, 0x16, 0x16, - 0x16, 0x16, 0x17, 0x17, - 0x17, 0x18, 0x18, 0x18, - 0x18, 0x19, 0x19, 0x19, - 0x1A, 0x1A, 0x1A, 0x1A, - 0x1B, 0x1B, 0x1B, 0x1C, - 0x1C, 0x1C, 0x1D, 0x1D, - 0x1D, 0x1E, 0x1E, 0x1E, - 0x1F, 0x1F, 0x20, 0x20, - 0x20, 0x21, 0x21, 0x21, - 0x22, 0x22, 0x23, 0x23, - 0x23, 0x24, 0x24, 0x25, - 0x25, 0x26, 0x26, 0x26, - 0x27, 0x27, 0x28, 0x28, - 0x29, 0x29, 0x2A, 0x2A, - 0x2B, 0x2B, 0x2C, 0x2C, - 0x2D, 0x2D, 0x2E, 0x2E, - 0x2F, 0x2F, 0x30, 0x31, - 0x31, 0x32, 0x32, 0x33, - 0x33, 0x34, 0x35, 0x35, - 0x36, 0x37, 0x37, 0x38, - 0x38, 0x39, 0x3A, 0x3A, - 0x3B, 0x3C, 0x3D, 0x3D, - 0x3E, 0x3F, 0x3F, 0x40, - 0x41, 0x42, 0x42, 0x43, - 0x44, 0x45, 0x46, 0x46, - 0x47, 0x48, 0x49, 0x4A, - 0x4B, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, - 0x52, 0x53, 0x54, 0x55, - 0x56, 0x57, 0x58, 0x59, - 0x5A, 0x5B, 0x5C, 0x5D, - 0x5E, 0x5F, 0x60, 0x61, - 0x62, 0x64, 0x65, 0x66, - 0x67, 0x68, 0x6A, 0x6B, - 0x6C, 0x6D, 0x6F, 0x70, - 0x71, 0x72, 0x74, 0x75, - 0x76, 0x78, 0x79, 0x7B, - 0x7C, 0x7E, 0x7F, 0x80, - 0x82, 0x83, 0x85, 0x87, - 0x88, 0x8A, 0x8B, 0x8D, - 0x8F, 0x90, 0x92, 0x94, - 0x95, 0x97, 0x99, 0x9B, - 0x9C, 0x9E, 0xA0, 0xA2, - 0xA4, 0xA6, 0xA8, 0xAA, - 0xAB, 0xAD, 0xAF, 0xB2, - 0xB4, 0xB6, 0xB8, 0xBA, - 0xBC, 0xBE, 0xC0, 0xC3, - 0xC5, 0xC7, 0xCA, 0xCC, - 0xCE, 0xD1, 0xD3, 0xD6, - 0xD8, 0xDB, 0xDD, 0xE0, - 0xE2, 0xE5, 0xE7, 0xEA, - 0xED, 0xF0, 0xF2, 0xF5, - 0xF8, 0xFB, 0xFE, 0x101, - 0x104, 0x107, 0x10A, 0x10D, - 0x110, 0x113, 0x116, 0x11A, - 0x11D, 0x120, 0x124, 0x127, - 0x12A, 0x12E, 0x131, 0x135, - 0x138, 0x13C, 0x140, 0x143, - 0x147, 0x14B, 0x14F, 0x153, - 0x157, 0x15B, 0x15F, 0x163, - 0x167, 0x16B, 0x16F, 0x173, - 0x178, 0x17C, 0x180, 0x185, - 0x189, 0x18E, 0x193, 0x197, - 0x19C, 0x1A1, 0x1A6, 0x1AB, - 0x1AF, 0x1B4, 0x1BA, 0x1BF, - 0x1C4, 0x1C9, 0x1CE, 0x1D4, - 0x1D9, 0x1DF, 0x1E4, 0x1EA, - 0x1EF, 0x1F5, 0x1FB, 0x201, - 0x207, 0x20D, 0x213, 0x219, - 0x21F, 0x226, 0x22C, 0x232, - 0x239, 0x240, 0x246, 0x24D, - 0x254, 0x25B, 0x262, 0x269, - 0x270, 0x277, 0x27E, 0x286, - 0x28D, 0x295, 0x29D, 0x2A4, - 0x2AC, 0x2B4, 0x2BC, 0x2C4, - 0x2CC, 0x2D5, 0x2DD, 0x2E6, - 0x2EE, 0x2F7, 0x300, 0x309, - 0x312, 0x31B, 0x324, 0x32D, - 0x337, 0x340, 0x34A, 0x354, - 0x35D, 0x367, 0x371, 0x37C, - 0x386, 0x390, 0x39B, 0x3A6, - 0x3B1, 0x3BB, 0x3C7, 0x3D2, - 0x3DD, 0x3E9, 0x3F4, 0x400, - 0x40C, 0x418, 0x424, 0x430, - 0x43D, 0x449, 0x456, 0x463, - 0x470, 0x47D, 0x48A, 0x498, - 0x4A5, 0x4B3, 0x4C1, 0x4CF, - 0x4DD, 0x4EC, 0x4FA, 0x509, - 0x518, 0x527, 0x536, 0x546, - 0x555, 0x565, 0x575, 0x586, - 0x596, 0x5A6, 0x5B7, 0x5C8, - 0x5D9, 0x5EB, 0x5FC, 0x60E, - 0x620, 0x632, 0x644, 0x657, - 0x66A, 0x67D, 0x690, 0x6A4, - 0x6B7, 0x6CB, 0x6DF, 0x6F4, - 0x708, 0x71D, 0x732, 0x748, - 0x75D, 0x773, 0x789, 0x79F, - 0x7B6, 0x7CD, 0x7E4, 0x7FB, - 0x813, 0x82B, 0x843, 0x85C, - 0x874, 0x88E, 0x8A7, 0x8C1, - 0x8DA, 0x8F5, 0x90F, 0x92A, - 0x945, 0x961, 0x97D, 0x999, - 0x9B5, 0x9D2, 0x9EF, 0xA0D, - 0xA2A, 0xA48, 0xA67, 0xA86, - 0xAA5, 0xAC5, 0xAE5, 0xB05, - 0xB25, 0xB47, 0xB68, 0xB8A, - 0xBAC, 0xBCF, 0xBF2, 0xC15, - 0xC39, 0xC5D, 0xC82, 0xCA7, - 0xCCC, 0xCF2, 0xD19, 0xD3F, - 0xD67, 0xD8E, 0xDB7, 0xDDF, - 0xE08, 0xE32, 0xE5C, 0xE87, - 0xEB2, 0xEDD, 0xF09, 0xF36, - 0xF63, 0xF91, 0xFBF, 0xFEE, - 0x101D, 0x104D, 0x107D, 0x10AE, - 0x10DF, 0x1111, 0x1144, 0x1177, - 0x11AB, 0x11DF, 0x1214, 0x124A, - 0x1280, 0x12B7, 0x12EE, 0x1326, - 0x135F, 0x1399, 0x13D3, 0x140D, - 0x1449, 0x1485, 0x14C2, 0x14FF, - 0x153E, 0x157D, 0x15BC, 0x15FD, - 0x163E, 0x1680, 0x16C3, 0x1706, - 0x174A, 0x178F, 0x17D5, 0x181C, - 0x1863, 0x18AC, 0x18F5, 0x193F, - 0x198A, 0x19D5, 0x1A22, 0x1A6F, - 0x1ABE, 0x1B0D, 0x1B5D, 0x1BAE, - 0x1C00, 0x1C53, 0x1CA7, 0x1CFC, - 0x1D52, 0x1DA9, 0x1E01, 0x1E5A, - 0x1EB4, 0x1F0F, 0x1F6B, 0x1FC8, - 0x2026, 0x2086, 0x20E6, 0x2148, - 0x21AA, 0x220E, 0x2273, 0x22D9, - 0x2341, 0x23A9, 0x2413, 0x247E, - 0x24EA, 0x2557, 0x25C6, 0x2636, - 0x26A7, 0x271A, 0x278E, 0x2803, - 0x287A, 0x28F2, 0x296B, 0x29E6, - 0x2A62, 0x2AE0, 0x2B5F, 0x2BDF, - 0x2C61, 0x2CE5, 0x2D6A, 0x2DF1, - 0x2E79, 0x2F03, 0x2F8E, 0x301B, - 0x30AA, 0x313A, 0x31CC, 0x325F, - 0x32F5, 0x338C, 0x3425, 0x34BF, - 0x355B, 0x35FA, 0x369A, 0x373C, - 0x37DF, 0x3885, 0x392C, 0x39D6, - 0x3A81, 0x3B2F, 0x3BDE, 0x3C90, - 0x3D43, 0x3DF9, 0x3EB1, 0x3F6A, - 0x4026, 0x40E5, 0x41A5, 0x4268, - 0x432C, 0x43F4, 0x44BD, 0x4589, - 0x4657, 0x4727, 0x47FA, 0x48D0, - 0x49A8, 0x4A82, 0x4B5F, 0x4C3E, - 0x4D20, 0x4E05, 0x4EEC, 0x4FD6, - 0x50C3, 0x51B2, 0x52A4, 0x5399, - 0x5491, 0x558C, 0x5689, 0x578A, - 0x588D, 0x5994, 0x5A9D, 0x5BAA, - 0x5CBA, 0x5DCD, 0x5EE3, 0x5FFC, - 0x6119, 0x6238, 0x635C, 0x6482, - 0x65AC, 0x66D9, 0x680A, 0x693F, - 0x6A77, 0x6BB2, 0x6CF2, 0x6E35, - 0x6F7B, 0x70C6, 0x7214, 0x7366, - 0x74BC, 0x7616, 0x7774, 0x78D6, - 0x7A3D, 0x7BA7, 0x7D16, 0x7E88, - 0x7FFF, 0x817B, 0x82FB, 0x847F, - 0x8608, 0x8795, 0x8927, 0x8ABE, - 0x8C59, 0x8DF9, 0x8F9E, 0x9148, - 0x92F6, 0x94AA, 0x9663, 0x9820, - 0x99E3, 0x9BAB, 0x9D79, 0x9F4C, - 0xA124, 0xA302, 0xA4E5, 0xA6CE, - 0xA8BC, 0xAAB0, 0xACAA, 0xAEAA, - 0xB0B0, 0xB2BC, 0xB4CE, 0xB6E5, - 0xB904, 0xBB28, 0xBD53, 0xBF84, - 0xC1BC, 0xC3FA, 0xC63F, 0xC88B, - 0xCADD, 0xCD37, 0xCF97, 0xD1FE, - 0xD46D, 0xD6E3, 0xD960, 0xDBE4, - 0xDE70, 0xE103, 0xE39E, 0xE641, - 0xE8EB, 0xEB9E, 0xEE58, 0xF11B, - 0xF3E6, 0xF6B9, 0xF994, 0xFC78, - 0xFF64 +unsigned short __MIXVolumeTable[] = { + 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, + 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, + 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, + 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, + 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, + 0x5, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, + 0x6, 0x6, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, + 0x7, 0x7, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0xA, 0xA, 0xA, + 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xB, 0xB, 0xB, 0xB, 0xB, 0xB, + 0xB, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xD, 0xD, 0xD, 0xD, + 0xD, 0xD, 0xD, 0xE, 0xE, 0xE, 0xE, 0xE, 0xE, 0xF, 0xF, 0xF, + 0xF, 0xF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, + 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, + 0x17, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1B, 0x1B, 0x1B, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1D, 0x1E, 0x1E, 0x1E, + 0x1F, 0x1F, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, + 0x23, 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, + 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B, 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, + 0x2F, 0x2F, 0x30, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, 0x34, 0x35, 0x35, + 0x36, 0x37, 0x37, 0x38, 0x38, 0x39, 0x3A, 0x3A, 0x3B, 0x3C, 0x3D, 0x3D, + 0x3E, 0x3F, 0x3F, 0x40, 0x41, 0x42, 0x42, 0x43, 0x44, 0x45, 0x46, 0x46, + 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, + 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, + 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x64, 0x65, 0x66, 0x67, 0x68, 0x6A, 0x6B, + 0x6C, 0x6D, 0x6F, 0x70, 0x71, 0x72, 0x74, 0x75, 0x76, 0x78, 0x79, 0x7B, + 0x7C, 0x7E, 0x7F, 0x80, 0x82, 0x83, 0x85, 0x87, 0x88, 0x8A, 0x8B, 0x8D, + 0x8F, 0x90, 0x92, 0x94, 0x95, 0x97, 0x99, 0x9B, 0x9C, 0x9E, 0xA0, 0xA2, + 0xA4, 0xA6, 0xA8, 0xAA, 0xAB, 0xAD, 0xAF, 0xB2, 0xB4, 0xB6, 0xB8, 0xBA, + 0xBC, 0xBE, 0xC0, 0xC3, 0xC5, 0xC7, 0xCA, 0xCC, 0xCE, 0xD1, 0xD3, 0xD6, + 0xD8, 0xDB, 0xDD, 0xE0, 0xE2, 0xE5, 0xE7, 0xEA, 0xED, 0xF0, 0xF2, 0xF5, + 0xF8, 0xFB, 0xFE, 0x101, 0x104, 0x107, 0x10A, 0x10D, 0x110, 0x113, 0x116, 0x11A, + 0x11D, 0x120, 0x124, 0x127, 0x12A, 0x12E, 0x131, 0x135, 0x138, 0x13C, 0x140, 0x143, + 0x147, 0x14B, 0x14F, 0x153, 0x157, 0x15B, 0x15F, 0x163, 0x167, 0x16B, 0x16F, 0x173, + 0x178, 0x17C, 0x180, 0x185, 0x189, 0x18E, 0x193, 0x197, 0x19C, 0x1A1, 0x1A6, 0x1AB, + 0x1AF, 0x1B4, 0x1BA, 0x1BF, 0x1C4, 0x1C9, 0x1CE, 0x1D4, 0x1D9, 0x1DF, 0x1E4, 0x1EA, + 0x1EF, 0x1F5, 0x1FB, 0x201, 0x207, 0x20D, 0x213, 0x219, 0x21F, 0x226, 0x22C, 0x232, + 0x239, 0x240, 0x246, 0x24D, 0x254, 0x25B, 0x262, 0x269, 0x270, 0x277, 0x27E, 0x286, + 0x28D, 0x295, 0x29D, 0x2A4, 0x2AC, 0x2B4, 0x2BC, 0x2C4, 0x2CC, 0x2D5, 0x2DD, 0x2E6, + 0x2EE, 0x2F7, 0x300, 0x309, 0x312, 0x31B, 0x324, 0x32D, 0x337, 0x340, 0x34A, 0x354, + 0x35D, 0x367, 0x371, 0x37C, 0x386, 0x390, 0x39B, 0x3A6, 0x3B1, 0x3BB, 0x3C7, 0x3D2, + 0x3DD, 0x3E9, 0x3F4, 0x400, 0x40C, 0x418, 0x424, 0x430, 0x43D, 0x449, 0x456, 0x463, + 0x470, 0x47D, 0x48A, 0x498, 0x4A5, 0x4B3, 0x4C1, 0x4CF, 0x4DD, 0x4EC, 0x4FA, 0x509, + 0x518, 0x527, 0x536, 0x546, 0x555, 0x565, 0x575, 0x586, 0x596, 0x5A6, 0x5B7, 0x5C8, + 0x5D9, 0x5EB, 0x5FC, 0x60E, 0x620, 0x632, 0x644, 0x657, 0x66A, 0x67D, 0x690, 0x6A4, + 0x6B7, 0x6CB, 0x6DF, 0x6F4, 0x708, 0x71D, 0x732, 0x748, 0x75D, 0x773, 0x789, 0x79F, + 0x7B6, 0x7CD, 0x7E4, 0x7FB, 0x813, 0x82B, 0x843, 0x85C, 0x874, 0x88E, 0x8A7, 0x8C1, + 0x8DA, 0x8F5, 0x90F, 0x92A, 0x945, 0x961, 0x97D, 0x999, 0x9B5, 0x9D2, 0x9EF, 0xA0D, + 0xA2A, 0xA48, 0xA67, 0xA86, 0xAA5, 0xAC5, 0xAE5, 0xB05, 0xB25, 0xB47, 0xB68, 0xB8A, + 0xBAC, 0xBCF, 0xBF2, 0xC15, 0xC39, 0xC5D, 0xC82, 0xCA7, 0xCCC, 0xCF2, 0xD19, 0xD3F, + 0xD67, 0xD8E, 0xDB7, 0xDDF, 0xE08, 0xE32, 0xE5C, 0xE87, 0xEB2, 0xEDD, 0xF09, 0xF36, + 0xF63, 0xF91, 0xFBF, 0xFEE, 0x101D, 0x104D, 0x107D, 0x10AE, 0x10DF, 0x1111, 0x1144, 0x1177, + 0x11AB, 0x11DF, 0x1214, 0x124A, 0x1280, 0x12B7, 0x12EE, 0x1326, 0x135F, 0x1399, 0x13D3, 0x140D, + 0x1449, 0x1485, 0x14C2, 0x14FF, 0x153E, 0x157D, 0x15BC, 0x15FD, 0x163E, 0x1680, 0x16C3, 0x1706, + 0x174A, 0x178F, 0x17D5, 0x181C, 0x1863, 0x18AC, 0x18F5, 0x193F, 0x198A, 0x19D5, 0x1A22, 0x1A6F, + 0x1ABE, 0x1B0D, 0x1B5D, 0x1BAE, 0x1C00, 0x1C53, 0x1CA7, 0x1CFC, 0x1D52, 0x1DA9, 0x1E01, 0x1E5A, + 0x1EB4, 0x1F0F, 0x1F6B, 0x1FC8, 0x2026, 0x2086, 0x20E6, 0x2148, 0x21AA, 0x220E, 0x2273, 0x22D9, + 0x2341, 0x23A9, 0x2413, 0x247E, 0x24EA, 0x2557, 0x25C6, 0x2636, 0x26A7, 0x271A, 0x278E, 0x2803, + 0x287A, 0x28F2, 0x296B, 0x29E6, 0x2A62, 0x2AE0, 0x2B5F, 0x2BDF, 0x2C61, 0x2CE5, 0x2D6A, 0x2DF1, + 0x2E79, 0x2F03, 0x2F8E, 0x301B, 0x30AA, 0x313A, 0x31CC, 0x325F, 0x32F5, 0x338C, 0x3425, 0x34BF, + 0x355B, 0x35FA, 0x369A, 0x373C, 0x37DF, 0x3885, 0x392C, 0x39D6, 0x3A81, 0x3B2F, 0x3BDE, 0x3C90, + 0x3D43, 0x3DF9, 0x3EB1, 0x3F6A, 0x4026, 0x40E5, 0x41A5, 0x4268, 0x432C, 0x43F4, 0x44BD, 0x4589, + 0x4657, 0x4727, 0x47FA, 0x48D0, 0x49A8, 0x4A82, 0x4B5F, 0x4C3E, 0x4D20, 0x4E05, 0x4EEC, 0x4FD6, + 0x50C3, 0x51B2, 0x52A4, 0x5399, 0x5491, 0x558C, 0x5689, 0x578A, 0x588D, 0x5994, 0x5A9D, 0x5BAA, + 0x5CBA, 0x5DCD, 0x5EE3, 0x5FFC, 0x6119, 0x6238, 0x635C, 0x6482, 0x65AC, 0x66D9, 0x680A, 0x693F, + 0x6A77, 0x6BB2, 0x6CF2, 0x6E35, 0x6F7B, 0x70C6, 0x7214, 0x7366, 0x74BC, 0x7616, 0x7774, 0x78D6, + 0x7A3D, 0x7BA7, 0x7D16, 0x7E88, 0x7FFF, 0x817B, 0x82FB, 0x847F, 0x8608, 0x8795, 0x8927, 0x8ABE, + 0x8C59, 0x8DF9, 0x8F9E, 0x9148, 0x92F6, 0x94AA, 0x9663, 0x9820, 0x99E3, 0x9BAB, 0x9D79, 0x9F4C, + 0xA124, 0xA302, 0xA4E5, 0xA6CE, 0xA8BC, 0xAAB0, 0xACAA, 0xAEAA, 0xB0B0, 0xB2BC, 0xB4CE, 0xB6E5, + 0xB904, 0xBB28, 0xBD53, 0xBF84, 0xC1BC, 0xC3FA, 0xC63F, 0xC88B, 0xCADD, 0xCD37, 0xCF97, 0xD1FE, + 0xD46D, 0xD6E3, 0xD960, 0xDBE4, 0xDE70, 0xE103, 0xE39E, 0xE641, 0xE8EB, 0xEB9E, 0xEE58, 0xF11B, + 0xF3E6, 0xF6B9, 0xF994, 0xFC78, 0xFF64 }; -int __MIXPanTable[] = -{ - 0x0, 0x0, 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 +int __MIXPanTable[] = { + 0x0, 0x0, 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 }; -short __MIX_DPL2_front[] = -{ - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 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 +short __MIX_DPL2_front[] = { + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 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 }; -short __MIX_DPL2_rear[] = -{ - 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 +short __MIX_DPL2_rear[] = { + 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 }; static int __MIXGetVolume(int param_1) @@ -373,18 +150,18 @@ static int __MIXGetVolume(int param_1) return __MIXVolumeTable[param_1 + 0x388]; } -static int __MIXSetPan(struct MIXChannel *param_1) +static int __MIXSetPan(struct MIXChannel* param_1) { - int iVar1 = *(int *)((int)param_1 + 0x14); - int iVar3 = *(int *)((int)param_1 + 0x18); + int iVar1 = *(int*)((int)param_1 + 0x14); + int iVar3 = *(int*)((int)param_1 + 0x18); int iVar2 = 0x7f - iVar1; int iVar4 = 0x7f - iVar3; if (__MIXSoundMode == 3) { - param_1->data[8] = __MIX_DPL2_front[iVar1]; - param_1->data[9] = __MIX_DPL2_front[iVar2]; + param_1->data[8] = __MIX_DPL2_front[iVar1]; + param_1->data[9] = __MIX_DPL2_front[iVar2]; param_1->data[10] = __MIX_DPL2_front[iVar4]; param_1->data[11] = __MIX_DPL2_front[iVar3]; param_1->data[12] = __MIX_DPL2_rear[iVar2]; @@ -392,14 +169,15 @@ static int __MIXSetPan(struct MIXChannel *param_1) } else { - param_1->data[8] = __MIXPanTable[iVar1]; - param_1->data[9] = __MIXPanTable[iVar2]; + param_1->data[8] = __MIXPanTable[iVar1]; + param_1->data[9] = __MIXPanTable[iVar2]; param_1->data[10] = __MIXPanTable[iVar4]; param_1->data[11] = __MIXPanTable[iVar3]; } + return 0; } -static void __MIXResetChannel(struct MIXChannel *param_1) +static void __MIXResetChannel(struct MIXChannel* param_1) { param_1->data[1] = 0x50000000; param_1->data[2] = 0; @@ -443,17 +221,18 @@ void MIXInit() int iVar1 = 0; do { - __MIXResetChannel((struct MIXChannel *)&__MIXChannel[iVar1]); + __MIXResetChannel((struct MIXChannel*)&__MIXChannel[iVar1]); iVar1++; } while (iVar1 < 0x40); __MIXDvdStreamAttenCurrent = 0; __MIXDvdStreamAttenUser = 0; - __MIXSoundMode = OSGetSoundMode(); + //__MIXSoundMode = OSGetSoundMode(); } -void MIXInitChannel(int param_1, unsigned int param_2, int param_3, int param_4, int param_5, int param_6, int param_7, int param_8) +void MIXInitChannel(int param_1, unsigned int param_2, int param_3, int param_4, int param_5, + int param_6, int param_7, int param_8) { - struct MIXChannel* chan = &__MIXChannel[*(int *)((int)param_1 + 0x18)]; + struct MIXChannel* chan = &__MIXChannel[*(int*)((int)param_1 + 0x18)]; short sVar1; unsigned short uVar2; @@ -468,173 +247,201 @@ void MIXInitChannel(int param_1, unsigned int param_2, int param_3, int param_4, chan->data[6] = param_7; chan->data[7] = param_8; - __MIXSetPan( chan); + __MIXSetPan(chan); - if ( (chan->data[1] & 4)) + if ((chan->data[1] & 4)) { - *(unsigned short *)( &chan->data[0xe]) = 0; + *(unsigned short*)(&chan->data[0xe]) = 0; } else { - *(unsigned short *)( &chan->data[0xe]) = __MIXGetVolume(param_3); + *(unsigned short*)(&chan->data[0xe]) = __MIXGetVolume(param_3); } - uVar4 = 0; switch ((int)__MIXSoundMode) { - case 0: - *(unsigned short *)(&chan->data[0xf]) = __MIXGetVolume(chan->data[7]+ chan->data[10]); - *(unsigned short *)(&chan->data[0x10]) = __MIXGetVolume(chan->data[7] + chan->data[10]); - *(unsigned short *)(&chan->data[0x11]) = __MIXGetVolume(chan->data[7] + chan->data[11]); + case 0: + *(unsigned short*)(&chan->data[0xf]) = __MIXGetVolume(chan->data[7] + chan->data[10]); + *(unsigned short*)(&chan->data[0x10]) = __MIXGetVolume(chan->data[7] + chan->data[10]); + *(unsigned short*)(&chan->data[0x11]) = __MIXGetVolume(chan->data[7] + chan->data[11]); if ((chan->data[1] & 1U) != 0) { - *(unsigned short *)(&chan->data[0x12]) = __MIXGetVolume(chan->data[3] + chan->data[10] ); - *(unsigned short *)(&chan->data[0x13]) = __MIXGetVolume(chan->data[3] + chan->data[10] ); - *(unsigned short *)(&chan->data[0x14]) = __MIXGetVolume(chan->data[3] + chan->data[11] - 0x3c); + *(unsigned short*)(&chan->data[0x12]) = __MIXGetVolume(chan->data[3] + chan->data[10]); + *(unsigned short*)(&chan->data[0x13]) = __MIXGetVolume(chan->data[3] + chan->data[10]); + *(unsigned short*)(&chan->data[0x14]) = + __MIXGetVolume(chan->data[3] + chan->data[11] - 0x3c); } else { - *(unsigned short *)(&chan->data[0x12]) = __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[10]); - *(unsigned short *)(&chan->data[0x13]) = __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[10] ); - *(unsigned short *)(&chan->data[0x14]) = __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[11] - 0x3c); - + *(unsigned short*)(&chan->data[0x12]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[10]); + *(unsigned short*)(&chan->data[0x13]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[10]); + *(unsigned short*)(&chan->data[0x14]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[11] - 0x3c); } if (chan->data[1] & 2) { - - *(unsigned short *)(&chan->data[0x15]) = __MIXGetVolume(chan->data[4] + chan->data[10]); - *(unsigned short *)(&chan->data[0x16]) = __MIXGetVolume(chan->data[4] + chan->data[10]); - *(unsigned short *)(&chan->data[0x17]) = __MIXGetVolume(chan->data[4] + chan->data[11] - 0x3c); + *(unsigned short*)(&chan->data[0x15]) = __MIXGetVolume(chan->data[4] + chan->data[10]); + *(unsigned short*)(&chan->data[0x16]) = __MIXGetVolume(chan->data[4] + chan->data[10]); + *(unsigned short*)(&chan->data[0x17]) = + __MIXGetVolume(chan->data[4] + chan->data[11] - 0x3c); } else { - *(unsigned short *)(&chan->data[0x15]) = __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[10]); - *(unsigned short *)(&chan->data[0x16]) = __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[10]); - *(unsigned short *)(&chan->data[0x17]) = __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[11] - 0x3c); + *(unsigned short*)(&chan->data[0x15]) = + __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[10]); + *(unsigned short*)(&chan->data[0x16]) = + __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[10]); + *(unsigned short*)(&chan->data[0x17]) = + __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[11] - 0x3c); } - - break; - case 1: - case 2: - *(unsigned short *)(&chan->data[0xf]) = __MIXGetVolume(chan->data[7] + chan->data[8] + chan->data[10]); - *(unsigned short *)(&chan->data[0x10]) = __MIXGetVolume(chan->data[7] + chan->data[9] + chan->data[10]); - *(unsigned short *)(&chan->data[0x11]) = __MIXGetVolume(chan->data[7] + chan->data[11]); - - if ( (chan->data[1] & 1) != 0) - { - *(unsigned short *)(&chan->data[0x12]) = __MIXGetVolume(chan->data[3] + chan->data[8] + chan->data[10]); - *(unsigned short *)(&chan->data[0x13]) = __MIXGetVolume(chan->data[3] + chan->data[9] + chan->data[10]); - *(unsigned short *)(&chan->data[0x14]) = __MIXGetVolume(chan->data[3] + chan->data[11] + -0x3c); - } - else - { - *(unsigned short *)(&chan->data[0x12]) = __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[8] + chan->data[10]); - *(unsigned short *)(&chan->data[0x13]) = __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[9] + chan->data[10]); - *(unsigned short *)(&chan->data[0x14]) = __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[11] + -0x3c); - } - if (chan->data[1] & 2U) - { - *(unsigned short *)(&chan->data[0x15]) = __MIXGetVolume(chan->data[4] + chan->data[8] + chan->data[10]); - *(unsigned short *)(&chan->data[0x16]) = __MIXGetVolume(chan->data[4] + chan->data[9] + chan->data[10]); - *(unsigned short *)(&chan->data[0x17]) = __MIXGetVolume(chan->data[4] + chan->data[11] + -0x3c); - } - else - { - *(unsigned short *)(&chan->data[0x15]) = __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[8] + chan->data[10]); - *(unsigned short *)(&chan->data[0x16]) = __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[9] + chan->data[10]); - *(unsigned short *)(&chan->data[0x17]) = __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[11] + -0x3c); - } + case 1: + case 2: + *(unsigned short*)(&chan->data[0xf]) = + __MIXGetVolume(chan->data[7] + chan->data[8] + chan->data[10]); + *(unsigned short*)(&chan->data[0x10]) = + __MIXGetVolume(chan->data[7] + chan->data[9] + chan->data[10]); + *(unsigned short*)(&chan->data[0x11]) = __MIXGetVolume(chan->data[7] + chan->data[11]); + + if ((chan->data[1] & 1) != 0) + { + *(unsigned short*)(&chan->data[0x12]) = + __MIXGetVolume(chan->data[3] + chan->data[8] + chan->data[10]); + *(unsigned short*)(&chan->data[0x13]) = + __MIXGetVolume(chan->data[3] + chan->data[9] + chan->data[10]); + *(unsigned short*)(&chan->data[0x14]) = + __MIXGetVolume(chan->data[3] + chan->data[11] + -0x3c); + } + else + { + *(unsigned short*)(&chan->data[0x12]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[8] + chan->data[10]); + *(unsigned short*)(&chan->data[0x13]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[9] + chan->data[10]); + *(unsigned short*)(&chan->data[0x14]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[11] + -0x3c); + } + if (chan->data[1] & 2U) + { + *(unsigned short*)(&chan->data[0x15]) = + __MIXGetVolume(chan->data[4] + chan->data[8] + chan->data[10]); + *(unsigned short*)(&chan->data[0x16]) = + __MIXGetVolume(chan->data[4] + chan->data[9] + chan->data[10]); + *(unsigned short*)(&chan->data[0x17]) = + __MIXGetVolume(chan->data[4] + chan->data[11] + -0x3c); + } + else + { + *(unsigned short*)(&chan->data[0x15]) = + __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[8] + chan->data[10]); + *(unsigned short*)(&chan->data[0x16]) = + __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[9] + chan->data[10]); + *(unsigned short*)(&chan->data[0x17]) = + __MIXGetVolume(chan->data[7] + chan->data[4] + chan->data[11] + -0x3c); + } break; - case 3: - *(unsigned short *)(&chan->data[15]) = __MIXGetVolume(chan->data[7] + chan->data[8] + chan->data[10]); - *(unsigned short *)(&chan->data[16]) = __MIXGetVolume(chan->data[7] + chan->data[9] + chan->data[10]); - *(unsigned short *)(&chan->data[21]) = __MIXGetVolume(chan->data[7] + chan->data[12] + chan->data[11]); - *(unsigned short *)(&chan->data[22]) = __MIXGetVolume(chan->data[7] + chan->data[13] + chan->data[11]); - - if ((chan->data[1] & 1) != 0) - { - *(unsigned short *)(&chan->data[0x12]) = __MIXGetVolume(chan->data[3] + chan->data[8] + chan->data[10] ); - *(unsigned short *)(&chan->data[0x13]) = __MIXGetVolume(chan->data[3] + chan->data[9] + chan->data[10] ); - *(unsigned short *)(&chan->data[0x14]) = __MIXGetVolume(chan->data[3] + chan->data[12] + chan->data[11]); - *(unsigned short *)(&chan->data[0x17]) = __MIXGetVolume(chan->data[3] + chan->data[13] + chan->data[11]); - } - else - { - *(unsigned short *)(&chan->data[0x12]) = __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[8] + chan->data[10]); - *(unsigned short *)(&chan->data[0x13]) = __MIXGetVolume(chan->data[7] + chan->data[3]+ chan->data[9]+ chan->data[10] ); - *(unsigned short *)(&chan->data[0x14]) = __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[12] + chan->data[11]); - *(unsigned short *)(&chan->data[0x17]) = __MIXGetVolume(chan->data[7] + chan->data[3]+ chan->data[13] + chan->data[11]); - } - - uVar4 |= 0x4000; - break; + case 3: + *(unsigned short*)(&chan->data[15]) = + __MIXGetVolume(chan->data[7] + chan->data[8] + chan->data[10]); + *(unsigned short*)(&chan->data[16]) = + __MIXGetVolume(chan->data[7] + chan->data[9] + chan->data[10]); + *(unsigned short*)(&chan->data[21]) = + __MIXGetVolume(chan->data[7] + chan->data[12] + chan->data[11]); + *(unsigned short*)(&chan->data[22]) = + __MIXGetVolume(chan->data[7] + chan->data[13] + chan->data[11]); + + if ((chan->data[1] & 1) != 0) + { + *(unsigned short*)(&chan->data[0x12]) = + __MIXGetVolume(chan->data[3] + chan->data[8] + chan->data[10]); + *(unsigned short*)(&chan->data[0x13]) = + __MIXGetVolume(chan->data[3] + chan->data[9] + chan->data[10]); + *(unsigned short*)(&chan->data[0x14]) = + __MIXGetVolume(chan->data[3] + chan->data[12] + chan->data[11]); + *(unsigned short*)(&chan->data[0x17]) = + __MIXGetVolume(chan->data[3] + chan->data[13] + chan->data[11]); + } + else + { + *(unsigned short*)(&chan->data[0x12]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[8] + chan->data[10]); + *(unsigned short*)(&chan->data[0x13]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[9] + chan->data[10]); + *(unsigned short*)(&chan->data[0x14]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[12] + chan->data[11]); + *(unsigned short*)(&chan->data[0x17]) = + __MIXGetVolume(chan->data[7] + chan->data[3] + chan->data[13] + chan->data[11]); + } + uVar4 |= 0x4000; + break; } - OSDisableInterrupts(); + //OSDisableInterrupts(); - *(unsigned short *)((int)param_1 + 0x19c) = *(unsigned short *)(&chan->data[0xe]); // Target sets to r4 instead of r3. - *(unsigned short *)((int)param_1 + 0x19e) = 0; - if ( (*(unsigned short *)((int)param_1 + 0x14a) = *(unsigned short *)(&chan->data[0xf])) ) + *(unsigned short*)((int)param_1 + 0x19c) = + *(unsigned short*)(&chan->data[0xe]); // Target sets to r4 instead of r3. + *(unsigned short*)((int)param_1 + 0x19e) = 0; + if ((*(unsigned short*)((int)param_1 + 0x14a) = *(unsigned short*)(&chan->data[0xf]))) { uVar4 |= 1; } - *(unsigned short *)((int)param_1 + 0x14c) = 0; + *(unsigned short*)((int)param_1 + 0x14c) = 0; - if (*(unsigned short *)(param_1 + 0x14e) = *(unsigned short *)(&chan->data[0x10])) + if (*(unsigned short*)(param_1 + 0x14e) = *(unsigned short*)(&chan->data[0x10])) { uVar4 = uVar4 | 2; } - *(unsigned short *)(param_1 + 0x150) = 0; + *(unsigned short*)(param_1 + 0x150) = 0; - if (*(unsigned short *)(param_1 + 0x152) = *(unsigned short *)(&chan->data[0x12])) + if (*(unsigned short*)(param_1 + 0x152) = *(unsigned short*)(&chan->data[0x12])) { uVar4 = uVar4 | 0x10; } - *(unsigned short *)((int)param_1 + 0x154) = 0; - if (*(unsigned short *)((int)param_1 + 0x156) = *(unsigned short *)(&chan->data[0x13])) + *(unsigned short*)((int)param_1 + 0x154) = 0; + if (*(unsigned short*)((int)param_1 + 0x156) = *(unsigned short*)(&chan->data[0x13])) { uVar4 = uVar4 | 0x20; } - *(unsigned short *)(param_1 + 0x158) = 0; - if (*(unsigned short *)(param_1 + 0x15a) = *(unsigned short *)(&chan->data[0x15])) + *(unsigned short*)(param_1 + 0x158) = 0; + if (*(unsigned short*)(param_1 + 0x15a) = *(unsigned short*)(&chan->data[0x15])) { uVar4 = uVar4 | 0x200; } - *(unsigned short *)(param_1 + 0x15c) = 0; - if (*(unsigned short *)(param_1 + 0x15e) = *(unsigned short *)(&chan->data[0x16])) + *(unsigned short*)(param_1 + 0x15c) = 0; + if (*(unsigned short*)(param_1 + 0x15e) = *(unsigned short*)(&chan->data[0x16])) { uVar4 = uVar4 | 0x400; } - *(unsigned short *)(param_1 + 0x160) = 0; + *(unsigned short*)(param_1 + 0x160) = 0; ; - if (*(unsigned short *)(param_1 + 0x162) = *(unsigned short *)(&chan->data[0x17])) + if (*(unsigned short*)(param_1 + 0x162) = *(unsigned short*)(&chan->data[0x17])) { uVar4 = uVar4 | 0x1000; } - *(unsigned short *)(param_1 + 0x164) = 0; - if (*(unsigned short *)((int)param_1 + 0x166) = *(unsigned short *)(&chan->data[0x11])) + *(unsigned short*)(param_1 + 0x164) = 0; + if (*(unsigned short*)((int)param_1 + 0x166) = *(unsigned short*)(&chan->data[0x11])) { uVar4 = uVar4 | 4; } - *(unsigned short *)((int)param_1 + 0x168) = 0; - if (*(unsigned short *)(param_1 + 0x16a) = *(unsigned short *)(&chan->data[0x14])) + *(unsigned short*)((int)param_1 + 0x168) = 0; + if (*(unsigned short*)(param_1 + 0x16a) = *(unsigned short*)(&chan->data[0x14])) { uVar4 = uVar4 | 0x80; } - *(unsigned short *)((int)param_1 + 0x16c) = 0; - *(unsigned short *)((int)param_1 + 0x144) = uVar4; - *(unsigned int *)(param_1 + 0x1c) = *(unsigned int *)(param_1 + 0x1c) | 0x212; - OSRestoreInterrupts(); - + *(unsigned short*)((int)param_1 + 0x16c) = 0; + *(unsigned short*)((int)param_1 + 0x144) = uVar4; + *(unsigned int*)(param_1 + 0x1c) = *(unsigned int*)(param_1 + 0x1c) | 0x212; + //OSRestoreInterrupts(); } void MIXReleaseChannel(int* param_1) diff --git a/src/SB/Core/gc/iPad.cpp b/src/SB/Core/gc/iPad.cpp index 6a04b9cc2..39b66ff5f 100644 --- a/src/SB/Core/gc/iPad.cpp +++ b/src/SB/Core/gc/iPad.cpp @@ -4,6 +4,8 @@ #include "xTRC.h" #include "zGlobals.h" +#include + extern xGlobals* xglobals; extern zGlobals globals; diff --git a/src/SB/Core/gc/iTRC.cpp b/src/SB/Core/gc/iTRC.cpp index c4e17697b..56d02dbfd 100644 --- a/src/SB/Core/gc/iTRC.cpp +++ b/src/SB/Core/gc/iTRC.cpp @@ -1,5 +1,6 @@ #include "iTRC.h" +#include #include #include #include @@ -12,6 +13,7 @@ #include #include #include +#include #define FONT_MATRIX_ID 0x1E #define TEXTBOX_MAX_TEXT_LENGTH 256 @@ -192,10 +194,10 @@ void ROMFont::DrawCell(S32 param_1, S32 param_2, S32 param_3, S32 param_4) { U16 uVar1; U16 uVar2; - S16 sVar3; - S32 iVar4; - S32 iVar5; - S32 iVar6; + S16 sVar3 = 0; + S32 iVar4 = 0; + S32 iVar5 = 0; + S16 iVar6 = 0; uVar1 = mFontData->cellWidth; uVar2 = mFontData->cellHeight; @@ -211,14 +213,14 @@ void ROMFont::DrawCell(S32 param_1, S32 param_2, S32 param_3, S32 param_4) iVar6 = (int)(short)(param_3 + uVar1); - GXTexCoord2s16(iVar6, param_4); + GXTexCoord2s16(iVar6, sVar3); GXPosition3s16(iVar5, iVar4, 0); sVar3 = param_4 + uVar2; GXTexCoord2s16(iVar6, sVar3); GXPosition3s16((int)param_1, iVar4, 0); - GXTexCoord2s16((int)param_3, sVar3); + GXTexCoord2s16(iVar6, sVar3); GXEnd(); } diff --git a/src/SB/Core/gc/ngcrad3d.c b/src/SB/Core/gc/ngcrad3d.c index 163d52dba..8742bc781 100644 --- a/src/SB/Core/gc/ngcrad3d.c +++ b/src/SB/Core/gc/ngcrad3d.c @@ -1,5 +1,6 @@ #include "ngcrad3d.h" +#include #include "iFMV.h" static int D3D_surface_type[5]; @@ -29,37 +30,39 @@ static void Setup_surface_array() Built_tables = 1; } -HRAD3DIMAGE Open_RAD_3D_image(HBINK param_1, unsigned int param_2, unsigned int param_3, unsigned int param_4) -{ - HRAD3DIMAGE imgDat; - int pi_p4; - - Setup_surface_array(); +// HRAD3DIMAGE Open_RAD_3D_image(HBINK param_1, unsigned int param_2, unsigned int param_3, +// unsigned int param_4) +// { +// HRAD3DIMAGE imgDat; +// int pi_p4; - pi_p4 = Pixel_info[param_4] & 0xff; - imgDat = (HRAD3DIMAGE)iFMVmalloc(0x3c); +// Setup_surface_array(); - if (imgDat == 0) - { - return 0; - } +// pi_p4 = Pixel_info[param_4] & 0xff; +// imgDat = (HRAD3DIMAGE)iFMVmalloc(0x3c); - imgDat->a = param_2; - imgDat->b = param_3; - imgDat->c = Pixel_info[param_4] >> 31; - imgDat->d = pi_p4; - imgDat->e = param_4; +// if (imgDat == 0) +// { +// return 0; +// } - imgDat->g = GXGetTexBufferSize((unsigned short)param_2, (unsigned short)param_3, D3D_surface_type[param_4], 0, 0); - imgDat->f = (void*)iFMVmalloc(imgDat->g); +// imgDat->a = param_2; +// imgDat->b = param_3; +// imgDat->c = Pixel_info[param_4] >> 31; +// imgDat->d = pi_p4; +// imgDat->e = param_4; - GXInitTexObj((volatile int)imgDat + 0x1c, imgDat->f, param_2 & 0xffff, param_3 & 0xffff, D3D_surface_type[param_4], 0, 0, 0); +// imgDat->g = GXGetTexBufferSize((unsigned short)param_2, (unsigned short)param_3, +// D3D_surface_type[param_4], 0, 0); +// imgDat->f = (void*)iFMVmalloc(imgDat->g); - GXInitTexObjLOD(0.0f, 0.0f, 0.0f, (volatile int)imgDat + 0x1c, 1, 0, 0, 0, 0); +// GXInitTexObj((volatile int)imgDat + 0x1c, imgDat->f, param_2 & 0xffff, param_3 & 0xffff, +// D3D_surface_type[param_4], 0, 0, 0); - return imgDat; +// GXInitTexObjLOD(imgDat, 0.0f, 0.0f, (volatile int)imgDat + 0x1c, 1, 0, 0, 0, 0); -} +// return imgDat; +// } void Close_RAD_3D_image(struct RAD3DIMAGE* image) { @@ -74,7 +77,8 @@ void Close_RAD_3D_image(struct RAD3DIMAGE* image) } } -int Lock_RAD_3D_image(HRAD3DIMAGE rad_image, void* out_pixel_buffer, unsigned int* out_buffer_pitch, unsigned int* arg3) +int Lock_RAD_3D_image(HRAD3DIMAGE rad_image, void* out_pixel_buffer, unsigned int* out_buffer_pitch, + unsigned int* arg3) { if (rad_image == 0) { @@ -99,75 +103,74 @@ int Lock_RAD_3D_image(HRAD3DIMAGE rad_image, void* out_pixel_buffer, unsigned in return 1; } -void Unlock_RAD_3D_image(struct RAD3DIMAGE* image) -{ - if (image) - { - DCStoreRange(image->f, image->g); - } -} - -void GXEnd() { } - -static void GXTexCoord2f32(float f1, float f2) -{ - int ptr = 0xcc010000; - *(float*)((char*)(ptr) - 0x8000) = f1; - *(float*)((char*)(ptr) - 0x8000) = f2; -} +// void Unlock_RAD_3D_image(struct RAD3DIMAGE* image) +// { +// if (image) +// { +// DCStoreRange(image->f, image->g); +// } +// } + +// static void GXTexCoord2f32(float f1, float f2) +// { +// int ptr = 0xcc010000; +// *(float*)((char*)(ptr)-0x8000) = f1; +// *(float*)((char*)(ptr)-0x8000) = f2; +// } static void GXColor4u8(int r3, int r4, int r5, int r6) { int ptr = 0xcc010000; - *((char*)(ptr) - 0x8000) = r3; - *((char*)(ptr) - 0x8000) = r4; - *((char*)(ptr) - 0x8000) = r5; - *((char*)(ptr) - 0x8000) = r6; + *((char*)(ptr)-0x8000) = r3; + *((char*)(ptr)-0x8000) = r4; + *((char*)(ptr)-0x8000) = r5; + *((char*)(ptr)-0x8000) = r6; } static void GXPosition3s16(int r3, int r4, int r5) { int ptr = 0xcc010000; - *(short*)((char*)(ptr) - 0x8000) = r3; - *(short*)((char*)(ptr) - 0x8000) = r4; - *(short*)((char*)(ptr) - 0x8000) = r5; + *(short*)((char*)(ptr)-0x8000) = r3; + *(short*)((char*)(ptr)-0x8000) = r4; + *(short*)((char*)(ptr)-0x8000) = r5; } -static void GXSetTextCoordGen(int a, int b, int c, int d) -{ - GXSetTexCoordGen2(a, b, c, d, 0, 0x7d); -} - -static void Submit_vertices(float param_1, float param_2, float param_3, float param_4, long param_5, long param_6, float param_7) -{ - short uVar1 = (short)(param_7 * 255.0f) & 0xff; - short iVar3; - short iVar2; - short blah = (unsigned short)param_2; - - GXSetCullMode(0); - GXSetZMode(1, 7, 1); - GXSetColorUpdate(1); - GXBegin(0x80, 0, 4); - iVar3 = param_1; - iVar2 = param_6 * param_4 + param_2; - - GXPosition3s16(iVar3, iVar2, 0); - GXColor4u8(0xff, 0xff, 0xff, uVar1); - GXTexCoord2f32(0, 1.0f); - - GXPosition3s16(iVar3, blah, 0); - GXColor4u8(0xff, 0xff, 0xff, uVar1); - GXTexCoord2f32(0, 0); - iVar3 = param_5 * param_3 + param_1; - - GXPosition3s16(iVar3, blah, 0); - GXColor4u8(0xff, 0xff, 0xff, uVar1); - GXTexCoord2f32(4503601774854144.0, 0); - - GXPosition3s16(iVar3, iVar2, 0); - GXColor4u8(0xff, 0xff, 0xff, uVar1); - GXTexCoord2f32(1.0f, 1.0f); - - GXEnd(); -} \ No newline at end of file +// static void GXSetTextCoordGen(int a, int b, int c, int d) +// { +// GXSetTexCoordGen2(a, b, c, d, 0, 0x7d); +// } + +// static void Submit_vertices(float param_1, float param_2, float param_3, float param_4, +// long param_5, long param_6, float param_7) +// { +// short uVar1 = (short)(param_7 * 255.0f) & 0xff; +// short iVar3; +// short iVar2; +// short blah = (unsigned short)param_2; + +// GXSetCullMode(0); +// GXSetZMode(1, 7, 1); +// GXSetColorUpdate(1); +// GXBegin(0x80, 0, 4); +// iVar3 = param_1; +// iVar2 = param_6 * param_4 + param_2; + +// GXPosition3s16(iVar3, iVar2, 0); +// GXColor4u8(0xff, 0xff, 0xff, uVar1); +// GXTexCoord2f32(0, 1.0f); + +// GXPosition3s16(iVar3, blah, 0); +// GXColor4u8(0xff, 0xff, 0xff, uVar1); +// GXTexCoord2f32(0, 0); +// iVar3 = param_5 * param_3 + param_1; + +// GXPosition3s16(iVar3, blah, 0); +// GXColor4u8(0xff, 0xff, 0xff, uVar1); +// GXTexCoord2f32(4503601774854144.0, 0); + +// GXPosition3s16(iVar3, iVar2, 0); +// GXColor4u8(0xff, 0xff, 0xff, uVar1); +// GXTexCoord2f32(1.0f, 1.0f); + +// GXEnd(); +// } \ No newline at end of file diff --git a/src/SB/Core/x/xAnim.cpp b/src/SB/Core/x/xAnim.cpp index f08f07bf1..198549529 100644 --- a/src/SB/Core/x/xAnim.cpp +++ b/src/SB/Core/x/xAnim.cpp @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include @@ -360,19 +360,19 @@ void xAnimTempTransitionInit(U32 count) sizeof(xAnimTransition), count, count / 2); } -// TODO: move to xMathInlines.h -F32 xatan2(F32 y, F32 x) -{ - return xAngleClampFast(std::atan2f(y, x)); -} - #ifndef INLINE -float std::atan2f(float y, float x) +float atan2f(float y, float x) { return (float)atan2((double)y, (double)x); } #endif +// TODO: move to xMathInlines.h +F32 xatan2(F32 y, F32 x) +{ + return xAngleClampFast(std::atan2f(y, x)); +} + float CalcRecipBlendMax(U16* arg0) { float max = 0.0f; @@ -684,7 +684,7 @@ void xAnimFileEval(xAnimFile* data, F32 time, F32* bilinear, U32 flags, xVec3* t } #ifndef INLINE -float std::floorf(float x) +float floorf(float x) { return (float)floor((double)x); } @@ -2093,7 +2093,7 @@ void xAnimPoolCB(xMemPool* pool, void* data) clone->Pool = pool; } -#define ADD_4_BITS(x) (((x) & 1) + (((x) >> 1) & 1) + (((x) >> 2) & 1) + (((x) >> 3) & 1)) +#define ADD_4_BITS(x) (((x)&1) + (((x) >> 1) & 1) + (((x) >> 2) & 1) + (((x) >> 3) & 1)) void xAnimPoolInit(xMemPool* pool, U32 count, U32 singles, U32 blendFlags, U32 effectMax) { effectMax += effectMax & 1; diff --git a/src/SB/Core/x/xCamera.cpp b/src/SB/Core/x/xCamera.cpp index b3e6ca00b..791c0ba10 100644 --- a/src/SB/Core/x/xCamera.cpp +++ b/src/SB/Core/x/xCamera.cpp @@ -9,22 +9,16 @@ #include "iMath.h" -#include -#include - - +#include +#include #define CAMERAFX_ZOOM_MODE_0 0 #define CAMERAFX_ZOOM_MODE_1 1 #define CAMERAFX_ZOOM_MODE_2 2 #define CAMERAFX_ZOOM_MODE_3 3 - - #define CAMERAFX_TYPE_SHAKE 2 - - S32 sCamCollis; volatile S32 xcam_collis_owner_disable; S32 xcam_do_collis = 1; @@ -687,8 +681,8 @@ void xCameraFXShakeUpdate(cameraFX* f, F32 dt, const xMat4x3*, xMat4x3* m) xMat3x3GetEuler(m, &e); - e.z += - f->shake.cycleTime / f->shake.cycleMax * 0.63661975f * 0.1f * scale * f->shake.rotate_magnitude; + e.z += f->shake.cycleTime / f->shake.cycleMax * 0.63661975f * 0.1f * scale * + f->shake.rotate_magnitude; xMat3x3Euler(m, &e); } @@ -800,7 +794,8 @@ void xCameraMove(xCamera* cam, U32 flags, F32 dgoal, F32 hgoal, F32 pgoal, F32 t xCam_cyltoworld(&cam->mat.pos, cam->tgt_mat, dgoal, hgoal, pgoal, cam->flags); cam->omat.pos = cam->mat.pos; - cam->yaw_cur = cam->yaw_goal = cam->pcur + ((cam->pcur >= 3.1415927f) ? -3.1415927f : 3.1415927f); + cam->yaw_cur = cam->yaw_goal = + cam->pcur + ((cam->pcur >= 3.1415927f) ? -3.1415927f : 3.1415927f); } } else diff --git a/src/SB/Core/x/xCutscene.cpp b/src/SB/Core/x/xCutscene.cpp index 45e0e63c0..544c35097 100644 --- a/src/SB/Core/x/xCutscene.cpp +++ b/src/SB/Core/x/xCutscene.cpp @@ -10,6 +10,7 @@ #include #include +#include xCutscene sActiveCutscene; U32 sCutTocCount; @@ -143,7 +144,7 @@ S32 xCutscene_LoadStart(xCutscene* csn) return 1; } -S32 xCutscene_Update(xCutscene *csn, F32 dt) +S32 xCutscene_Update(xCutscene* csn, F32 dt) { if ((csn->SndStarted == FALSE) && (csn->SndNumChannel != 0)) { @@ -183,7 +184,8 @@ S32 xCutscene_Update(xCutscene *csn, F32 dt) if (csn->Waiting) { csn->Time = csn->Play->EndTime; - csn->CamTime = xCutsceneConvertBreak(csn->Time, csn->BreakList, csn->Info->BreakCount, -1); + csn->CamTime = + xCutsceneConvertBreak(csn->Time, csn->BreakList, csn->Info->BreakCount, -1); if (csn->BadReadPause == FALSE) { @@ -202,7 +204,9 @@ S32 xCutscene_Update(xCutscene *csn, F32 dt) if (csn->PlayIndex + 1 < csn->Info->NumTime) { - iCSFileAsyncRead(csn, csn->Stream, csn->TimeChunkOffs[csn->PlayIndex + 2] - csn->TimeChunkOffs[csn->PlayIndex + 1]); + iCSFileAsyncRead(csn, csn->Stream, + csn->TimeChunkOffs[csn->PlayIndex + 2] - + csn->TimeChunkOffs[csn->PlayIndex + 1]); } } @@ -244,7 +248,7 @@ void xCutscene_SetSpeed(xCutscene* csn, F32 speed) F32 xlog(F32 x) { - return std::logf(x); + return std::logf(x); } float std::logf(float x) diff --git a/src/SB/Core/x/xFont.cpp b/src/SB/Core/x/xFont.cpp index 594658a89..c6ecb8eec 100644 --- a/src/SB/Core/x/xFont.cpp +++ b/src/SB/Core/x/xFont.cpp @@ -13,6 +13,7 @@ #include #include +#include /* xtextbox flags */ diff --git a/src/SB/Core/x/xHud.cpp b/src/SB/Core/x/xHud.cpp index c17501952..eb7d9236c 100644 --- a/src/SB/Core/x/xHud.cpp +++ b/src/SB/Core/x/xHud.cpp @@ -9,7 +9,7 @@ #include "zEnt.h" -#include +#include #include #define lengthof(x) (sizeof(x) / sizeof((x)[0])) @@ -339,10 +339,10 @@ namespace xhud U32 widget_size; } known_types[] = { // TODO: The second value should probably be sizeof(...) - {0x3a, 0x9c}, - {0x3c, 0x19c}, - {0x3b, 0x15c}, - {0x47, 0x17c}, + { 0x3a, 0x9c }, + { 0x3c, 0x19c }, + { 0x3b, 0x15c }, + { 0x47, 0x17c }, }; struct functor_disable @@ -380,8 +380,7 @@ namespace xhud F32 delta_time; }; - template - void for_each(U8 widget_type, U32 type_size, F f) + template void for_each(U8 widget_type, U32 type_size, F f) { U32 count = globals.sceneCur->baseCount[widget_type]; U8* list = (U8*)globals.sceneCur->baseList[widget_type]; @@ -391,7 +390,8 @@ namespace xhud } } - void render_one_model(xModelInstance& model, F32 alpha, const basic_rect& rect, const xVec3& from, const xVec3& to, const xMat4x3& frame) + void render_one_model(xModelInstance& model, F32 alpha, const basic_rect& rect, + const xVec3& from, const xVec3& to, const xMat4x3& frame) { xModelSetMaterialAlpha(&model, 255.0f * alpha + 0.5f); xModelSetFrame(&model, &frame); @@ -402,7 +402,6 @@ namespace xhud void widget::debug_render() { - } void widget::setup_all() @@ -555,7 +554,7 @@ namespace xhud bool shake_motive_update(widget& w, motive& m, F32 dt) { - static const float mult[4] = {-1.0f, -1.0f, 1.0f, 1.0f}; + static const float mult[4] = { -1.0f, -1.0f, 1.0f, 1.0f }; *((U32*)&m.context) += 1; U32 context = *((U32*)&m.context); @@ -592,15 +591,14 @@ namespace xhud void xhud::render_model(xModelInstance& model, const xhud::render_context& rc) { - basic_rect rect = { 0 }; rect.x = rc.loc.x; rect.y = rc.loc.y; rect.w = rc.size.x; rect.h = rc.size.y; - xVec3 vecA = {0, 0, 1}; - xVec3 vecB = {0, 0, -rc.loc.z}; + xVec3 vecA = { 0, 0, 1 }; + xVec3 vecB = { 0, 0, -rc.loc.z }; xMat4x3 matrix; xMat3x3Euler(&matrix, rc.rot.x, rc.rot.y, rc.rot.z); diff --git a/src/SB/Core/x/xHudMeter.cpp b/src/SB/Core/x/xHudMeter.cpp index 31af911b3..9fa21340a 100644 --- a/src/SB/Core/x/xHudMeter.cpp +++ b/src/SB/Core/x/xHudMeter.cpp @@ -4,6 +4,7 @@ #include "xString.h" #include "xMathInlines.h" +#include "PowerPC_EABI_Support\MSL_C\MSL_Common\printf.h" namespace xhud { diff --git a/src/SB/Core/x/xHudModel.cpp b/src/SB/Core/x/xHudModel.cpp index 3b61a73f1..041d72cbb 100644 --- a/src/SB/Core/x/xHudModel.cpp +++ b/src/SB/Core/x/xHudModel.cpp @@ -2,7 +2,7 @@ #include "xHud.h" #include "xString.h" -#include +#include #include xAnimTable* XHUD_AnimTable_Idle() diff --git a/src/SB/Core/x/xHudText.cpp b/src/SB/Core/x/xHudText.cpp index 5c9597a56..49202adcb 100644 --- a/src/SB/Core/x/xHudText.cpp +++ b/src/SB/Core/x/xHudText.cpp @@ -4,8 +4,8 @@ #include "zScene.h" #include "zTextBox.h" -#include -#include +#include +#include #include void xhud::text_widget::load(xBase& data, xDynAsset& asset, size_t) diff --git a/src/SB/Core/x/xIni.cpp b/src/SB/Core/x/xIni.cpp index d1a270bc3..90c0e45a2 100644 --- a/src/SB/Core/x/xIni.cpp +++ b/src/SB/Core/x/xIni.cpp @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include char* TrimWhitespace(char* string) { diff --git a/src/SB/Core/x/xJaw.cpp b/src/SB/Core/x/xJaw.cpp index f94519f97..4c04d9545 100644 --- a/src/SB/Core/x/xJaw.cpp +++ b/src/SB/Core/x/xJaw.cpp @@ -2,7 +2,7 @@ #include "xstransvc.h" -#include +#include struct xJawDataTable { @@ -45,13 +45,13 @@ void* xJaw_FindData(U32 soundID) #define swap(data) \ { \ - U8 c; \ - c = ((U8*)(data))[3]; \ - ((U8*)(data))[3] = ((U8*)(data))[0]; \ - ((U8*)(data))[0] = c; \ - c = ((U8*)(data))[2]; \ - ((U8*)(data))[2] = ((U8*)(data))[1]; \ - ((U8*)(data))[1] = c; \ + U8 c; \ + c = ((U8*)(data))[3]; \ + ((U8*)(data))[3] = ((U8*)(data))[0]; \ + ((U8*)(data))[0] = c; \ + c = ((U8*)(data))[2]; \ + ((U8*)(data))[2] = ((U8*)(data))[1]; \ + ((U8*)(data))[1] = c; \ } F32 xJaw_EvalData(void* data, F32 time) diff --git a/src/SB/Core/x/xMath.cpp b/src/SB/Core/x/xMath.cpp index ed37d17c2..a1c64c580 100644 --- a/src/SB/Core/x/xMath.cpp +++ b/src/SB/Core/x/xMath.cpp @@ -1,7 +1,7 @@ #include "xMath.h" #include -#include +#include #include "xMathInlines.h" @@ -98,7 +98,8 @@ U32 xMathSolveQuadratic(F32 a, F32 b, F32 c, F32* x1, F32* x2) return 2; } -U32 xMathSolveCubic(F32 a, F32 b, F32 c, F32 d, F32* x1, F32* x2, F32* x3) { +U32 xMathSolveCubic(F32 a, F32 b, F32 c, F32 d, F32* x1, F32* x2, F32* x3) +{ F32 arecip; // F32 fA; // p F32 fB; // q @@ -118,10 +119,12 @@ U32 xMathSolveCubic(F32 a, F32 b, F32 c, F32 d, F32* x1, F32* x2, F32* x3) { F32 temp_f29; F32 var_f1; - if (a == 0.0f) { + if (a == 0.0f) + { return xMathSolveQuadratic(b, c, d, x1, x2); } - if (a != 1.0f) { + if (a != 1.0f) + { arecip = 1.0f / a; b *= arecip; c *= arecip; @@ -132,27 +135,36 @@ U32 xMathSolveCubic(F32 a, F32 b, F32 c, F32 d, F32* x1, F32* x2, F32* x3) { fOffset = 0.33333334f * b; fDiscr = (0.25f * (fB * fB)) + (0.037037037f * (fA * (fA * fA))); fHalfB = 0.5f * fB; - if ((F32) __fabs(fDiscr) < 0.000001f) { + if ((F32)__fabs(fDiscr) < 0.000001f) + { fDiscr = 0.0f; } - if (fDiscr > 0.0f) { + if (fDiscr > 0.0f) + { temp_f1 = xsqrt(fDiscr); temp_f1_2 = -fHalfB + temp_f1; - if (temp_f1_2 >= 0.0f) { + if (temp_f1_2 >= 0.0f) + { *x1 = xpow(temp_f1_2, 0.33333334f); - } else { + } + else + { *x1 = -xpow(-temp_f1_2, 0.33333334f); } temp_f1_3 = -fHalfB - temp_f1; - if (temp_f1_3 >= 0.0f) { + if (temp_f1_3 >= 0.0f) + { *x1 += xpow(temp_f1_3, 0.33333334f); - } else { + } + else + { *x1 -= xpow(-temp_f1_3, 0.33333334f); } *x1 -= fOffset; return 1; } - if (fDiscr < 0.0f) { + if (fDiscr < 0.0f) + { temp_f29 = xsqrt(-0.33333334f * fA); temp_f28_2 = 0.33333334f * xatan2(xsqrt(-fDiscr), -fHalfB); fCos = icos(temp_f28_2); @@ -162,9 +174,12 @@ U32 xMathSolveCubic(F32 a, F32 b, F32 c, F32 d, F32* x1, F32* x2, F32* x3) { *x3 = (-temp_f29 * (fCos - 1.7320508f * fSin)) - fOffset; return 3; } - if (fHalfB >= 0.0f) { + if (fHalfB >= 0.0f) + { var_f1 = -xpow(fHalfB, 0.33333334f); - } else { + } + else + { var_f1 = xpow(-fHalfB, 0.33333334f); } *x1 = (2.0f * var_f1) - fOffset; @@ -220,7 +235,8 @@ F32 xDangleClamp(F32 a) return rem; } -void xAccelMove(F32& x, F32& v, F32 a, F32 dt, F32 endx, F32 maxv) { +void xAccelMove(F32& x, F32& v, F32 a, F32 dt, F32 endx, F32 maxv) +{ F32 offset; F32 t1; F32 t2; @@ -249,97 +265,144 @@ void xAccelMove(F32& x, F32& v, F32 a, F32 dt, F32 endx, F32 maxv) { temp_f29 = endx - x; var_r3 = 1; - if (!((F32) __fabs(v) < 0.001f)) { - if (v < 0.0f) { + if (!((F32)__fabs(v) < 0.001f)) + { + if (v < 0.0f) + { var_r4 = 1; - } else { + } + else + { var_r4 = 0; } - if (temp_f29 < 0.0f) { + if (temp_f29 < 0.0f) + { var_r0 = 1; - } else { + } + else + { var_r0 = 0; } - if (var_r0 == var_r4) { + if (var_r0 == var_r4) + { var_r3 = 0; } } - if (var_r3 != 0) { + if (var_r3 != 0) + { var_f31 = 1e38f; - } else { + } + else + { var_f31 = temp_f29 / v; } - temp_f28 = (F32) __fabs(v / a); - if (var_f31 < temp_f28) { + temp_f28 = (F32)__fabs(v / a); + if (var_f31 < temp_f28) + { a *= -1.0f; } - if (temp_f29 < 0.0f) { + if (temp_f29 < 0.0f) + { a *= -1.0f; } dv = a * dt; oldv = v; newv = oldv + dv; - if ((F32) __fabs(newv) == maxv) { + if ((F32)__fabs(newv) == maxv) + { v = newv; var_f0 = 0.5f * dv * dt; - } else { - - if ((F32) __fabs(oldv) == maxv) { + } + else + { + if ((F32)__fabs(oldv) == maxv) + { v = range_limit(newv, -maxv, maxv); - if (oldv != v) { + if (oldv != v) + { temp_f1_2 = v - oldv; var_f0 = (0.5f * temp_f1_2 * temp_f1_2) / a; - } else { + } + else + { var_f0 = 0.0f; } - } else { - if (dv < 0.0f) { + } + else + { + if (dv < 0.0f) + { var_r3_2 = 1; - } else { + } + else + { var_r3_2 = 0; } - if (newv < 0.0f) { + if (newv < 0.0f) + { var_r0_2 = 1; - } else { + } + else + { var_r0_2 = 0; } - if (var_r0_2 != var_r3_2) { + if (var_r0_2 != var_r3_2) + { v = newv; var_f0 = 0.5f * dv * dt; - } else { + } + else + { var_f0 = 0.0f; } } } var_f2 = (oldv * dt) + var_f0; - if (var_f31 > temp_f28) { - if (temp_f29 < 0.0f) { + if (var_f31 > temp_f28) + { + if (temp_f29 < 0.0f) + { var_r3_3 = 1; - } else { + } + else + { var_r3_3 = 0; } - if (var_f2 < 0.0f) { + if (var_f2 < 0.0f) + { var_r0_3 = 1; - } else { + } + else + { var_r0_3 = 0; } - if ((var_r0_3 == var_r3_3) && ((F32) __fabs(var_f2) > (F32) __fabs(temp_f29))) { + if ((var_r0_3 == var_r3_3) && ((F32)__fabs(var_f2) > (F32)__fabs(temp_f29))) + { var_f2 = temp_f29; v = 0.0f; } - } else { - if (temp_f29 < 0.0f) { + } + else + { + if (temp_f29 < 0.0f) + { var_r3_4 = 1; - } else { + } + else + { var_r3_4 = 0; } - if (var_f2 < 0.0f) { + if (var_f2 < 0.0f) + { var_r0_4 = 1; - } else { + } + else + { var_r0_4 = 0; } - if (var_r0_4 != var_r3_4) { + if (var_r0_4 != var_r3_4) + { var_f2 = temp_f29; v = 0.0f; } @@ -359,33 +422,44 @@ F32 xAccelMoveTime(F32 dx, F32 a, F32, F32 maxv) return 2.0f * dx; } -void xAccelMove(F32& x, F32& v, F32 a, F32 dt, F32 maxv) { +void xAccelMove(F32& x, F32& v, F32 a, F32 dt, F32 maxv) +{ U32 bn; // r10 U32 bp; // r7 U32 aa; // r29+0xC F32 diff; F32 dv; - if ((F32) __fabs(v) > (F32) __fabs(maxv)) { - if (v < 0.0f) { - if (a > 0.0f) { + if ((F32)__fabs(v) > (F32)__fabs(maxv)) + { + if (v < 0.0f) + { + if (a > 0.0f) + { a = -a; } - } else if (a < 0.0f) { + } + else if (a < 0.0f) + { a = -a; } a = -a; } - if (a < 0.0f) { - if (maxv > 0.0f) { + if (a < 0.0f) + { + if (maxv > 0.0f) + { maxv = -maxv; } - } else if (maxv < 0.0f) { + } + else if (maxv < 0.0f) + { maxv = -maxv; } diff = maxv - v; dv = a * dt; - if ((F32) __fabs(diff) < (F32) __fabs(dv)) { + if ((F32)__fabs(diff) < (F32)__fabs(dv)) + { x += (v * dt) + ((0.5f * diff * diff) / a); v = maxv; return; @@ -394,7 +468,8 @@ void xAccelMove(F32& x, F32& v, F32 a, F32 dt, F32 maxv) { v += dv; } -void xAccelStop(F32& x, F32& v, F32 a, F32 dt) { +void xAccelStop(F32& x, F32& v, F32 a, F32 dt) +{ S32 aa; // From DWARF, currently unused. F32 oldv; @@ -402,47 +477,61 @@ void xAccelStop(F32& x, F32& v, F32 a, F32 dt) { S32 var_r5; oldv = v; - if (!(oldv >= -0.00001f) || !(oldv <= 0.00001f)) { - if (oldv < 0.0f) { - if (a > 0.0f) { + if (!(oldv >= -0.00001f) || !(oldv <= 0.00001f)) + { + if (oldv < 0.0f) + { + if (a > 0.0f) + { a = -a; } - } else if (a < 0.0f) { + } + else if (a < 0.0f) + { a = -a; } v += -a * dt; - if (v < 0.0f) { + if (v < 0.0f) + { var_r5 = 1; - } else { + } + else + { var_r5 = 0; } - if (oldv < 0.0f) { + if (oldv < 0.0f) + { var_r0 = 1; - } else { + } + else + { var_r0 = 0; } - if (var_r0 == var_r5) { + if (var_r0 == var_r5) + { x += (-a * (0.5f * dt * dt)) + (oldv * dt); return; } - if (!(-a >= -0.00001f) || !(-a <= 0.00001f)) { + if (!(-a >= -0.00001f) || !(-a <= 0.00001f)) + { x -= (0.5f * oldv * oldv) / -a; } v = 0.0f; } } -void xFuncPiece_EndPoints(xFuncPiece* func, F32 pi, F32 pf, F32 fi, F32 ff) { +void xFuncPiece_EndPoints(xFuncPiece* func, F32 pi, F32 pf, F32 fi, F32 ff) +{ F32 xfinv; // from DWARF data func->end = pf - pi; func->order = 1; - func->coef[0]= fi; + func->coef[0] = fi; func->coef[1] = (ff - fi) * (1.0f / func->end); xFuncPiece_ShiftPiece(func, func, -pi); } diff --git a/src/SB/Core/x/xModelBucket.cpp b/src/SB/Core/x/xModelBucket.cpp index 790ebfdca..b95b13618 100644 --- a/src/SB/Core/x/xModelBucket.cpp +++ b/src/SB/Core/x/xModelBucket.cpp @@ -3,7 +3,7 @@ #include "iCamera.h" #include -#include +#include extern RpWorld* sBucketDummyWorld; extern RwCamera* sBucketDummyCamera; diff --git a/src/SB/Core/x/xPtankPool.cpp b/src/SB/Core/x/xPtankPool.cpp index c65b0b7a5..c2ea08778 100644 --- a/src/SB/Core/x/xPtankPool.cpp +++ b/src/SB/Core/x/xPtankPool.cpp @@ -3,7 +3,7 @@ #include "xMemMgr.h" #include -#include +#include #include #include diff --git a/src/SB/Core/x/xRMemData.h b/src/SB/Core/x/xRMemData.h index 9d0a94be2..4a94d448f 100644 --- a/src/SB/Core/x/xRMemData.h +++ b/src/SB/Core/x/xRMemData.h @@ -3,7 +3,7 @@ #include "xBase.h" -#include +#include struct RyzMemGrow { diff --git a/src/SB/Core/x/xString.h b/src/SB/Core/x/xString.h index 8ceaf9250..27c809232 100644 --- a/src/SB/Core/x/xString.h +++ b/src/SB/Core/x/xString.h @@ -2,7 +2,7 @@ #define XSTRING_H #include -#include +//#include struct substr { diff --git a/src/SB/Core/x/xpkrsvc.h b/src/SB/Core/x/xpkrsvc.h index 7b25e75e0..d07914095 100644 --- a/src/SB/Core/x/xpkrsvc.h +++ b/src/SB/Core/x/xpkrsvc.h @@ -2,7 +2,8 @@ #define XPKRSVC_H #include -#include +#include +#include "PowerPC_EABI_Support\MSL_C\MSL_Common\time.h" #include "xhipio.h" #include "xordarray.h" diff --git a/src/SB/Core/x/xutil.cpp b/src/SB/Core/x/xutil.cpp index 9a518ff66..77537c9fd 100644 --- a/src/SB/Core/x/xutil.cpp +++ b/src/SB/Core/x/xutil.cpp @@ -3,6 +3,8 @@ #include "xMath.h" #include +#include +#include static volatile S32 g_xutilinit; // volatile so xUtilShutdown matches static S32 g_crc_needinit = 1; diff --git a/src/SB/Game/zAssetTypes.cpp b/src/SB/Game/zAssetTypes.cpp index 5733cb4b1..c4ff20f4e 100644 --- a/src/SB/Game/zAssetTypes.cpp +++ b/src/SB/Game/zAssetTypes.cpp @@ -6,6 +6,7 @@ #include "xJSP.h" #include +#include #include #include #include diff --git a/src/SB/Game/zCamera.h b/src/SB/Game/zCamera.h index 5318d6685..791f6686e 100644 --- a/src/SB/Game/zCamera.h +++ b/src/SB/Game/zCamera.h @@ -3,6 +3,8 @@ #include "xCamera.h" +#include + enum WallJumpViewState { WJVS_DISABLED, diff --git a/src/SB/Game/zDiscoFloor.cpp b/src/SB/Game/zDiscoFloor.cpp index 78303e9bf..09fa33956 100644 --- a/src/SB/Game/zDiscoFloor.cpp +++ b/src/SB/Game/zDiscoFloor.cpp @@ -16,6 +16,7 @@ #include #include +#include extern U32 current_disco_floor; diff --git a/src/SB/Game/zEnt.cpp b/src/SB/Game/zEnt.cpp index 1355560a2..0254af9f0 100644 --- a/src/SB/Game/zEnt.cpp +++ b/src/SB/Game/zEnt.cpp @@ -14,8 +14,9 @@ #include "xSnd.h" #include "xCollide.h" #include "zNPCTypes.h" -#include +#include #include +#include void zEntInit(zEnt* ent, xEntAsset* asset, U32 type) { diff --git a/src/SB/Game/zEntCruiseBubble.cpp b/src/SB/Game/zEntCruiseBubble.cpp index 2e68af6fb..c40a995a1 100644 --- a/src/SB/Game/zEntCruiseBubble.cpp +++ b/src/SB/Game/zEntCruiseBubble.cpp @@ -1,5 +1,5 @@ #include "zNPCHazard.h" -#include +#include #include #include "stdio.h" diff --git a/src/SB/Game/zEntPlayerBungeeState.cpp b/src/SB/Game/zEntPlayerBungeeState.cpp index 3171c796c..1973a95bb 100644 --- a/src/SB/Game/zEntPlayerBungeeState.cpp +++ b/src/SB/Game/zEntPlayerBungeeState.cpp @@ -26,8 +26,7 @@ #include "zLightning.h" #include "zScene.h" -#include "zCameraTweak.h" -#include +#include #include // FIXME: remove this when no longer needed for float data order diff --git a/src/SB/Game/zFX.cpp b/src/SB/Game/zFX.cpp index 9263fafce..d6b0d4c8a 100644 --- a/src/SB/Game/zFX.cpp +++ b/src/SB/Game/zFX.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include extern xFXRing sPatrickStunRing[3]; extern xFXRing sPorterRing[2]; diff --git a/src/SB/Game/zMain.cpp b/src/SB/Game/zMain.cpp index ab5238744..a69f9d97d 100644 --- a/src/SB/Game/zMain.cpp +++ b/src/SB/Game/zMain.cpp @@ -2,7 +2,7 @@ #include "zGlobals.h" #include "zMain.h" -#include +#include #include #include "iSystem.h" diff --git a/src/SB/Game/zParPTank.cpp b/src/SB/Game/zParPTank.cpp index dc537a55f..9a131a508 100644 --- a/src/SB/Game/zParPTank.cpp +++ b/src/SB/Game/zParPTank.cpp @@ -1,6 +1,6 @@ #include "zParPTank.h" -#include +#include #include #include @@ -65,8 +65,7 @@ static float sSteamAnimTime; const RwV2d sparkle_size = { 0.3f, 0.3f }; -static void zParPTankSparkleCreate(zParPTank* zp, U32 max_particles, - zParPTankUpdateCallback update) +static void zParPTankSparkleCreate(zParPTank* zp, U32 max_particles, zParPTankUpdateCallback update) { zp->num_particles = 0; zp->max_particles = max_particles; @@ -228,8 +227,7 @@ void zParPTankSpawnSparkles(xVec3* pos, U32 count) const RwRGBA bubble_color = { 0x80, 0x80, 0x80, 0xFF }; // Equivalent, float scheduling -static void zParPTankBubbleCreate(zParPTank* zp, U32 max_particles, - zParPTankUpdateCallback update) +static void zParPTankBubbleCreate(zParPTank* zp, U32 max_particles, zParPTankUpdateCallback update) { zp->num_particles = 0; zp->max_particles = max_particles; @@ -616,8 +614,7 @@ void zParPTankSpawnSnow(xVec3* pos, xVec3* vel, U32 count) const RwV2d steam_size = { 0.4f, 0.4f }; -static void zParPTankSteamCreate(zParPTank* zp, U32 max_particles, - zParPTankUpdateCallback update) +static void zParPTankSteamCreate(zParPTank* zp, U32 max_particles, zParPTankUpdateCallback update) { zp->num_particles = 0; zp->max_particles = max_particles; diff --git a/src/SB/Game/zUI.cpp b/src/SB/Game/zUI.cpp index 35178ac91..934195a30 100644 --- a/src/SB/Game/zUI.cpp +++ b/src/SB/Game/zUI.cpp @@ -20,7 +20,7 @@ #include "iMath.h" -#include +#include #include #include @@ -1358,8 +1358,7 @@ static zUIFont* findUIFont(zScene* zsc, U32 id) return ui; } -S32 zUIPortalEventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, - xBase* toParamWidget) +S32 zUIPortalEventCB(xBase* from, xBase* to, U32 toEvent, const F32* toParam, xBase* toParamWidget) { S32 result; diff --git a/src/SB/Game/zVar.cpp b/src/SB/Game/zVar.cpp index 68a7a5619..2de635362 100644 --- a/src/SB/Game/zVar.cpp +++ b/src/SB/Game/zVar.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "iTime.h" From e9fe72b7b9485251d326cb2c036e690aad160eb3 Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Sat, 24 May 2025 20:24:59 -0400 Subject: [PATCH 07/19] Finished adding in the last files for the SDK. All files are added. --- config/GQPE78/symbols.txt | 2 +- configure.py | 125 +- include/dolphin/dvd.h | 22 +- include/dolphin/gx/GXEnum.h | 1557 ++++++++++++---------- include/dolphin/gx/GXFrameBuffer.h | 4 +- include/dolphin/gx/GXGeometry.h | 9 +- include/dolphin/gx/GXManage.h | 1 + include/dolphin/gx/GXTexture.h | 6 +- include/dolphin/os/OSFont.h | 8 + include/dolphin/os/OSRtc.h | 25 +- include/fake_tgmath.h | 66 + libs/dolphin/OdemuExi2/DebuggerDriver.c | 448 +++++++ libs/dolphin/amcstubs/AmcExi2Stubs.c | 29 + libs/dolphin/ax/AXCL.c | 2 +- libs/dolphin/ax/AXOut.c | 4 - libs/dolphin/ax/AXVPB.c | 20 +- libs/dolphin/base/PPCArch.c | 191 +-- libs/dolphin/dvd/dvd.c | 45 +- libs/dolphin/dvd/dvdFatal.c | 95 -- libs/dolphin/dvd/dvderror.c | 23 +- libs/dolphin/dvd/dvdfs.c | 200 +-- libs/dolphin/dvd/dvdlow.c | 40 +- libs/dolphin/dvd/dvdqueue.c | 124 +- libs/dolphin/exi/EXIBios.c | 179 +-- libs/dolphin/exi/EXIUart.c | 14 +- libs/dolphin/gx/GXAttr.c | 622 +++++++++ libs/dolphin/gx/GXBump.c | 207 +++ libs/dolphin/gx/GXDisplayList.c | 29 + libs/dolphin/gx/GXDraw.c | 571 ++++++++ libs/dolphin/gx/GXFifo.c | 426 ++++++ libs/dolphin/gx/GXFrameBuf.c | 591 ++++++++ libs/dolphin/gx/GXGeometry.c | 192 +++ libs/dolphin/gx/GXInit.c | 562 ++++++++ libs/dolphin/gx/GXLight.c | 457 +++++++ libs/dolphin/gx/GXMisc.c | 346 +++++ libs/dolphin/gx/GXPerf.c | 364 +++++ libs/dolphin/gx/GXPixel.c | 321 +++++ libs/dolphin/gx/GXSave.c | 601 +++++++++ libs/dolphin/gx/GXStubs.c | 7 + libs/dolphin/gx/GXTev.c | 486 +++++++ libs/dolphin/gx/GXTexture.c | 856 ++++++++++++ libs/dolphin/gx/GXTransform.c | 495 +++++++ libs/dolphin/gx/GXVerifRAS.c | 943 +++++++++++++ libs/dolphin/gx/GXVerifXF.c | 1291 ++++++++++++++++++ libs/dolphin/gx/GXVerify.c | 399 ++++++ libs/dolphin/gx/GXVert.c | 110 ++ libs/dolphin/gx/__gx.h | 632 +++++++++ libs/dolphin/mtx/mtx.c | 96 ++ libs/dolphin/mtx/mtx44.c | 30 + libs/dolphin/mtx/mtx44vec.c | 284 +++- libs/dolphin/mtx/mtxstack.c | 108 ++ libs/dolphin/mtx/mtxvec.c | 204 +++ libs/dolphin/mtx/psmtx.c | 336 +++++ libs/dolphin/mtx/quat.c | 486 +++++++ libs/dolphin/mtx/vec.c | 506 ++++--- libs/dolphin/odenotstub/odenotstub.c | 9 + libs/dolphin/os/OSAlarm.c | 60 +- libs/dolphin/os/OSAlloc.c | 86 +- libs/dolphin/os/OSArena.c | 42 +- libs/dolphin/os/OSCache.c | 344 ++--- libs/dolphin/os/OSContext.c | 353 ++--- libs/dolphin/os/OSError.c | 372 +++--- libs/dolphin/os/OSFont.c | 752 ++++++++++- libs/dolphin/os/OSInterrupt.c | 670 +++++----- libs/dolphin/os/OSLink.c | 554 +------- libs/dolphin/os/OSMemory.c | 184 ++- libs/dolphin/os/OSMutex.c | 258 +--- libs/dolphin/os/OSReset.c | 262 ++-- libs/dolphin/os/OSResetSW.c | 14 +- libs/dolphin/os/OSRtc.c | 578 ++++---- libs/dolphin/os/OSThread.c | 872 ++++++------ libs/dolphin/os/OSTime.c | 177 +-- libs/dolphin/os/__os.h | 133 ++ libs/dolphin/os/init/__ppc_eabi_init.cpp | 24 +- libs/dolphin/pad/Padclamp.c | 67 +- libs/dolphin/upnp/UPnP.c | 0 libs/dolphin/upnp/UPnPHttp.c | 0 libs/dolphin/upnp/UPnPHttpd.c | 0 libs/dolphin/upnp/UPnPHttpdResponse.c | 0 libs/dolphin/upnp/UPnPSsdp.c | 0 libs/dolphin/upnp/UPnPUri.c | 0 libs/dolphin/upnp/UPnPUuid.c | 0 82 files changed, 16851 insertions(+), 4757 deletions(-) create mode 100644 include/fake_tgmath.h create mode 100644 libs/dolphin/amcstubs/AmcExi2Stubs.c create mode 100644 libs/dolphin/gx/GXSave.c create mode 100644 libs/dolphin/gx/GXStubs.c create mode 100644 libs/dolphin/gx/GXVerifRAS.c create mode 100644 libs/dolphin/gx/GXVerifXF.c create mode 100644 libs/dolphin/gx/GXVerify.c create mode 100644 libs/dolphin/gx/GXVert.c create mode 100644 libs/dolphin/gx/__gx.h create mode 100644 libs/dolphin/mtx/mtxstack.c create mode 100644 libs/dolphin/mtx/psmtx.c create mode 100644 libs/dolphin/os/__os.h delete mode 100644 libs/dolphin/upnp/UPnP.c delete mode 100644 libs/dolphin/upnp/UPnPHttp.c delete mode 100644 libs/dolphin/upnp/UPnPHttpd.c delete mode 100644 libs/dolphin/upnp/UPnPHttpdResponse.c delete mode 100644 libs/dolphin/upnp/UPnPSsdp.c delete mode 100644 libs/dolphin/upnp/UPnPUri.c delete mode 100644 libs/dolphin/upnp/UPnPUuid.c diff --git a/config/GQPE78/symbols.txt b/config/GQPE78/symbols.txt index 4dcb07112..e039ef79f 100644 --- a/config/GQPE78/symbols.txt +++ b/config/GQPE78/symbols.txt @@ -11990,7 +11990,7 @@ axDspSlave = .data:0x802B2000; // type:object size:0x1EC0 scope:global ...data.0 = .data:0x802B3EC0; // type:label scope:local @1 = .data:0x802B3EC0; // type:object size:0x46 scope:local data:string ResetFunctionInfo = .data:0x802B3F08; // type:object size:0x10 scope:local -CardData = .data:0x802B3F20; // type:object size:0x160 scope:local +CardData = .data:0x802B3F20; // type:object size:0x160 scope:local align:32 SectorSizeTable = .data:0x802B4080; // type:object size:0x20 scope:local LatencyTable = .data:0x802B40A0; // type:object size:0x20 scope:local @9 = .data:0x802B40C0; // type:object size:0x18 scope:local data:string diff --git a/configure.py b/configure.py index 9350e48da..442cb5405 100644 --- a/configure.py +++ b/configure.py @@ -630,14 +630,13 @@ def MatchingFor(*versions): DolphinLib( "base", [ - # Needs a lot of Extended ASM work - # Object(NonMatching, "dolphin/base/PPCArch.c") + Object(Matching, "dolphin/base/PPCArch.c") ] ), DolphinLib( "card", [ - Object(NonMatching, "dolphin/card/CARDBios.c"), + Object(Matching, "dolphin/card/CARDBios.c"), Object(NonMatching, "dolphin/card/CARDUnlock.c"), Object(Matching, "dolphin/card/CARDRdwr.c"), Object(Matching, "dolphin/card/CARDBlock.c"), @@ -675,22 +674,13 @@ def MatchingFor(*versions): Object(NonMatching, "dolphin/dvd/dvdlow.c"), Object(NonMatching, "dolphin/dvd/dvdfs.c"), Object(NonMatching, "dolphin/dvd/dvd.c"), - Object(NonMatching, "dolphin/dvd/dvdqueue.c"), + Object(Matching, "dolphin/dvd/dvdqueue.c"), Object(NonMatching, "dolphin/dvd/dvderror.c"), Object(Matching, "dolphin/dvd/dvdidutils.c"), - Object(NonMatching, "dolphin/dvd/dvdFatal.c"), - Object(NonMatching, "dolphin/dvd/emu_level2/fstload.c"), + Object(Matching, "dolphin/dvd/dvdFatal.c"), + Object(Matching, "dolphin/dvd/emu_level2/fstload.c"), ], ), - DolphinLib( - "eth", - [ - Object(Matching, "dolphin/eth/eth.c"), - Object(Matching, "dolphin/eth/ethsec.c"), - Object(Matching, "dolphin/eth/md5.c"), - Object(Matching, "dolphin/eth/base64.c") - ] - ), DolphinLib( "exi", [ @@ -698,13 +688,6 @@ def MatchingFor(*versions): Object(NonMatching, "dolphin/exi/EXIUart.c") ] ), - DolphinLib( - "gd", - [ - Object(NonMatching, "dolphin/gd/GDBase.c"), - Object(NonMatching, "dolphin/gd/GDGeometry.c") - ] - ), DolphinLib( "gx", [ @@ -720,64 +703,22 @@ def MatchingFor(*versions): Object(NonMatching, "dolphin/gx/GXTev.c"), Object(NonMatching, "dolphin/gx/GXPixel.c"), Object(NonMatching, "dolphin/gx/GXDraw.c"), - Object(NonMatching, "dolphin/gx/GXDisplayList.c"), + Object(Matching, "dolphin/gx/GXDisplayList.c"), Object(NonMatching, "dolphin/gx/GXTransform.c"), - Object(NonMatching, "dolphin/gx/GXPerf.c") - ] - ), - DolphinLib( - "hio", - [ - Object(NonMatching, "dolphin/hio/hio.c") - ] - ), - DolphinLib( - "ip", - [ - Object(NonMatching, "dolphin/ip/IP.c"), - Object(NonMatching, "dolphin/ip/IPArp.c"), - Object(NonMatching, "dolphin/ip/IPIcmp.c"), - Object(NonMatching, "dolphin/ip/IPRoute.c"), - Object(NonMatching, "dolphin/ip/IPUdp.c"), - Object(NonMatching, "dolphin/ip/IPFrag.c"), - Object(NonMatching, "dolphin/ip/IPEther.c"), - Object(NonMatching, "dolphin/ip/IFFifo.c"), - Object(NonMatching, "dolphin/ip/IFRing.c"), - Object(NonMatching, "dolphin/ip/IPTcp.c"), - Object(NonMatching, "dolphin/ip/IPTcpOutput.c"), - Object(NonMatching, "dolphin/ip/IPTcpTimer.c"), - Object(NonMatching, "dolphin/ip/IPTcpUser.c"), - Object(NonMatching, "dolphin/ip/IPTcpTimeWait.c"), - Object(NonMatching, "dolphin/ip/IPDns.c"), - Object(NonMatching, "dolphin/ip/IPDhcp.c"), - Object(NonMatching, "dolphin/ip/IPZero.c"), - Object(NonMatching, "dolphin/ip/IPOpt.c"), - Object(NonMatching, "dolphin/ip/IPSocket.c"), - Object(NonMatching, "dolphin/ip/IPPPP.c"), - Object(NonMatching, "dolphin/ip/IPPPPoE.c"), - Object(NonMatching, "dolphin/ip/IPLcp.c"), - Object(NonMatching, "dolphin/ip/IPIpcp.c"), - Object(NonMatching, "dolphin/ip/IPPap.c"), - Object(NonMatching, "dolphin/ip/IPChap.c"), - Object(NonMatching, "dolphin/ip/IPIgmp.c"), - Object(NonMatching, "dolphin/ip/IPUuid.c") - ] - ), - DolphinLib( - "lg", # unofficial name - [ - Object(NonMatching, "dolphin/lg/allsrc.c") + Object(Matching, "dolphin/gx/GXPerf.c") ] ), + # DolphinLib( + # "lg", # unofficial name + # [ + # Object(NonMatching, "dolphin/lg/allsrc.c") + # ] + # ), DolphinLib( "mtx", [ Object(NonMatching, "dolphin/mtx/mtx.c"), - Object(NonMatching, "dolphin/mtx/mtxvec.c"), Object(NonMatching, "dolphin/mtx/mtx44.c"), - Object(Matching, "dolphin/mtx/mtx44vec.c"), - Object(Matching, "dolphin/mtx/vec.c"), - Object(NonMatching, "dolphin/mtx/quat.c"), ] ), DolphinLib( @@ -789,7 +730,7 @@ def MatchingFor(*versions): DolphinLib( "odenotstub", [ - Object(NonMatching, "dolphin/odenotstub/odenotstub.c") + Object(Matching, "dolphin/odenotstub/odenotstub.c") ] ), DolphinLib( @@ -797,25 +738,24 @@ def MatchingFor(*versions): [ Object(NonMatching, "dolphin/os/OS.c"), Object(NonMatching, "dolphin/os/OSAlarm.c"), - Object(NonMatching, "dolphin/os/OSAlloc.c"), - Object(NonMatching, "dolphin/os/OSArena.c"), + Object(Matching, "dolphin/os/OSAlloc.c"), + Object(Matching, "dolphin/os/OSArena.c"), Object(Matching, "dolphin/os/OSAudioSystem.c"), Object(NonMatching, "dolphin/os/OSCache.c"), - Object(NonMatching, "dolphin/os/OSContext.c"), + Object(Matching, "dolphin/os/OSContext.c"), Object(NonMatching, "dolphin/os/OSError.c"), Object(NonMatching, "dolphin/os/OSFont.c"), - Object(NonMatching, "dolphin/os/OSInterrupt.c"), - Object(NonMatching, "dolphin/os/OSLink.c"), - Object(NonMatching, "dolphin/os/OSMessage.c"), - Object(NonMatching, "dolphin/os/OSMemory.c"), - Object(NonMatching, "dolphin/os/OSMutex.c"), + Object(Matching, "dolphin/os/OSInterrupt.c"), + Object(Matching, "dolphin/os/OSLink.c"), + Object(Matching, "dolphin/os/OSMemory.c"), + Object(Matching, "dolphin/os/OSMutex.c"), Object(Matching, "dolphin/os/OSReboot.c"), Object(NonMatching, "dolphin/os/OSReset.c"), - Object(NonMatching, "dolphin/os/OSResetSW.c"), + Object(Matching, "dolphin/os/OSResetSW.c"), Object(NonMatching, "dolphin/os/OSRtc.c"), Object(NonMatching, "dolphin/os/OSThread.c"), Object(NonMatching, "dolphin/os/OSTime.c"), - Object(NonMatching, "dolphin/os/OSSync.c"), + Object(Matching, "dolphin/os/OSSync.c"), Object(NonMatching, "dolphin/os/init/__start.c"), Object(NonMatching, "dolphin/os/init/__ppc_eabi_init.cpp") ] @@ -834,31 +774,12 @@ def MatchingFor(*versions): Object(Matching, "dolphin/si/SISamplingRate.c"), ] ), - DolphinLib( - "upnp", - [ - Object(NonMatching, "dolphin/upnp/UPnP.c"), - Object(NonMatching, "dolphin/upnp/UPnPHttp.c"), - Object(NonMatching, "dolphin/upnp/UPnPSsdp.c"), - Object(NonMatching, "dolphin/upnp/UPnPUuid.c"), - Object(NonMatching, "dolphin/upnp/UPnPUri.c"), - Object(NonMatching, "dolphin/upnp/UPnPHttpd.c"), - Object(NonMatching, "dolphin/upnp/UPnPHttpdResponse.c") - ] - ), DolphinLib( "vi", [ Object(NonMatching, "dolphin/vi/vi.c"), ], ), - DolphinLib( - "thp", - [ - Object(Matching, "dolphin/thp/THPDec.c"), - Object(Matching, "dolphin/thp/THPAudio.c") - ] - ), mslLib( "Runtime.PPCEABI.H", [], diff --git a/include/dolphin/dvd.h b/include/dolphin/dvd.h index 0774f0459..b750eb142 100644 --- a/include/dolphin/dvd.h +++ b/include/dolphin/dvd.h @@ -2,8 +2,7 @@ #define _DOLPHIN_PUBLIC_DVD_H #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif #include @@ -11,6 +10,25 @@ extern "C" #include #include +// 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 + #ifdef __cplusplus } #endif diff --git a/include/dolphin/gx/GXEnum.h b/include/dolphin/gx/GXEnum.h index e69c621b7..f8d731ba1 100644 --- a/include/dolphin/gx/GXEnum.h +++ b/include/dolphin/gx/GXEnum.h @@ -15,886 +15,969 @@ typedef u8 GXBool; #define GX_ENABLE ((GXBool)1) #define GX_DISABLE ((GXBool)0) -typedef enum _GXProjectionType { - GX_PERSPECTIVE, - GX_ORTHOGRAPHIC, +typedef enum _GXCopyMode +{ + GX_COPY_PROGRESSIVE = 0, + GX_COPY_INTLC_EVEN = 2, + GX_COPY_INTLC_ODD = 3, +} GXCopyMode; + +typedef enum _GXAlphaReadMode +{ + GX_READ_00, + GX_READ_FF, + GX_READ_NONE, +} GXAlphaReadMode; + +typedef enum _GXProjectionType +{ + GX_PERSPECTIVE, + GX_ORTHOGRAPHIC, } GXProjectionType; -typedef enum _GXCompare { - GX_NEVER, - GX_LESS, - GX_EQUAL, - GX_LEQUAL, - GX_GREATER, - GX_NEQUAL, - GX_GEQUAL, - GX_ALWAYS, +typedef enum _GXCompare +{ + GX_NEVER, + GX_LESS, + GX_EQUAL, + GX_LEQUAL, + GX_GREATER, + GX_NEQUAL, + GX_GEQUAL, + GX_ALWAYS, } GXCompare; -typedef enum _GXAlphaOp { - GX_AOP_AND, - GX_AOP_OR, - GX_AOP_XOR, - GX_AOP_XNOR, - GX_MAX_ALPHAOP, +typedef enum _GXAlphaOp +{ + GX_AOP_AND, + GX_AOP_OR, + GX_AOP_XOR, + GX_AOP_XNOR, + GX_MAX_ALPHAOP, } GXAlphaOp; -typedef enum _GXFBClamp { - GX_CLAMP_NONE, - GX_CLAMP_TOP, - GX_CLAMP_BOTTOM, +typedef enum _GXFBClamp +{ + GX_CLAMP_NONE, + GX_CLAMP_TOP, + GX_CLAMP_BOTTOM, } GXFBClamp; -typedef enum _GXZFmt16 { - GX_ZC_LINEAR, - GX_ZC_NEAR, - GX_ZC_MID, - GX_ZC_FAR, +typedef enum _GXZFmt16 +{ + GX_ZC_LINEAR, + GX_ZC_NEAR, + GX_ZC_MID, + GX_ZC_FAR, } GXZFmt16; -typedef enum _GXGamma { - GX_GM_1_0, - GX_GM_1_7, - GX_GM_2_2, +typedef enum _GXGamma +{ + GX_GM_1_0, + GX_GM_1_7, + GX_GM_2_2, } GXGamma; -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, +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; -typedef enum _GXPrimitive { - GX_QUADS = 0x80, - GX_TRIANGLES = 0x90, - GX_TRIANGLESTRIP = 0x98, - GX_TRIANGLEFAN = 0xA0, - GX_LINES = 0xA8, - GX_LINESTRIP = 0xB0, - GX_POINTS = 0xB8, +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 _GXVtxFmt { - GX_VTXFMT0, - GX_VTXFMT1, - GX_VTXFMT2, - GX_VTXFMT3, - GX_VTXFMT4, - GX_VTXFMT5, - GX_VTXFMT6, - GX_VTXFMT7, - GX_MAX_VTXFMT, +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 _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, +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; #define GX_MAX_VTXDESCLIST_SZ (GX_VA_MAX_ATTR + 1) -typedef enum _GXAttrType { - GX_NONE, - GX_DIRECT, - GX_INDEX8, - GX_INDEX16, +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, +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, +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, +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, +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, +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, +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, +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, +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, +typedef enum _GXTevMode +{ + GX_MODULATE, + GX_DECAL, + GX_BLEND, + GX_REPLACE, + GX_PASSCLR, } GXTevMode; -typedef enum _GXTexMtxType { - GX_MTX3x4, - GX_MTX2x4, +typedef enum _GXTexMtxType +{ + GX_MTX3x4, + GX_MTX2x4, } GXTexMtxType; -typedef enum _GXTexGenType { - 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, +typedef enum _GXTexGenType +{ + 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 _GXPosNrmMtx { - 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, +typedef enum _GXPosNrmMtx +{ + 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, - 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, +typedef enum _GXTexMtx +{ + 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, +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, - GX_MAX_TEXGENSRC, +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, + GX_MAX_TEXGENSRC, } GXTexGenSrc; -typedef enum _GXBlendMode { - GX_BM_NONE, - GX_BM_BLEND, - GX_BM_LOGIC, - GX_BM_SUBTRACT, - GX_MAX_BLENDMODE, +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, +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, +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, +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, +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, - 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, +typedef enum _GXPTTexMtx +{ + 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 _GXTevRegID { - GX_TEVPREV, - GX_TEVREG0, - GX_TEVREG1, - GX_TEVREG2, - GX_MAX_TEVREG, +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, +typedef enum _GXDiffuseFn +{ + GX_DF_NONE, + GX_DF_SIGN, + GX_DF_CLAMP, } GXDiffuseFn; -typedef enum _GXColorSrc { - GX_SRC_REG, - GX_SRC_VTX, +typedef enum _GXColorSrc +{ + GX_SRC_REG, + GX_SRC_VTX, } GXColorSrc; -typedef enum _GXAttnFn { - GX_AF_SPEC, - GX_AF_SPOT, - GX_AF_NONE, +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, +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, +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, +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, +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, +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, +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, +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 = GX_FOG_PERSP_LIN, - GX_FOG_EXP = GX_FOG_PERSP_EXP, - GX_FOG_EXP2 = GX_FOG_PERSP_EXP2, - GX_FOG_REVEXP = GX_FOG_PERSP_REVEXP, - GX_FOG_REVEXP2 = GX_FOG_PERSP_REVEXP2, +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 = GX_FOG_PERSP_LIN, + GX_FOG_EXP = GX_FOG_PERSP_EXP, + GX_FOG_EXP2 = GX_FOG_PERSP_EXP2, + GX_FOG_REVEXP = GX_FOG_PERSP_REVEXP, + GX_FOG_REVEXP2 = GX_FOG_PERSP_REVEXP2, } GXFogType; -typedef enum _GXTevColorArg { - GX_CC_CPREV, - GX_CC_APREV, - GX_CC_C0, - GX_CC_A0, - GX_CC_C1, - GX_CC_A1, - GX_CC_C2, - GX_CC_A2, - GX_CC_TEXC, - GX_CC_TEXA, - GX_CC_RASC, - GX_CC_RASA, - GX_CC_ONE, - GX_CC_HALF, - GX_CC_KONST, - GX_CC_ZERO, +typedef enum _GXTevColorArg +{ + GX_CC_CPREV, + GX_CC_APREV, + GX_CC_C0, + GX_CC_A0, + GX_CC_C1, + GX_CC_A1, + GX_CC_C2, + GX_CC_A2, + GX_CC_TEXC, + GX_CC_TEXA, + GX_CC_RASC, + GX_CC_RASA, + GX_CC_ONE, + GX_CC_HALF, + GX_CC_KONST, + GX_CC_ZERO, } GXTevColorArg; -typedef enum _GXTevAlphaArg { - GX_CA_APREV, - GX_CA_A0, - GX_CA_A1, - GX_CA_A2, - GX_CA_TEXA, - GX_CA_RASA, - GX_CA_KONST, - GX_CA_ZERO, +typedef enum _GXTevAlphaArg +{ + GX_CA_APREV, + GX_CA_A0, + GX_CA_A1, + GX_CA_A2, + GX_CA_TEXA, + GX_CA_RASA, + GX_CA_KONST, + GX_CA_ZERO, } 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, +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, +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, +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_8_8 = 0x00, - GX_TEV_KCSEL_7_8 = 0x01, - GX_TEV_KCSEL_6_8 = 0x02, - GX_TEV_KCSEL_5_8 = 0x03, - GX_TEV_KCSEL_4_8 = 0x04, - GX_TEV_KCSEL_3_8 = 0x05, - GX_TEV_KCSEL_2_8 = 0x06, - GX_TEV_KCSEL_1_8 = 0x07, - GX_TEV_KCSEL_1 = GX_TEV_KCSEL_8_8, - GX_TEV_KCSEL_3_4 = GX_TEV_KCSEL_6_8, - GX_TEV_KCSEL_1_2 = GX_TEV_KCSEL_4_8, - GX_TEV_KCSEL_1_4 = GX_TEV_KCSEL_2_8, - 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, +typedef enum _GXTevKColorSel +{ + GX_TEV_KCSEL_8_8 = 0x00, + GX_TEV_KCSEL_7_8 = 0x01, + GX_TEV_KCSEL_6_8 = 0x02, + GX_TEV_KCSEL_5_8 = 0x03, + GX_TEV_KCSEL_4_8 = 0x04, + GX_TEV_KCSEL_3_8 = 0x05, + GX_TEV_KCSEL_2_8 = 0x06, + GX_TEV_KCSEL_1_8 = 0x07, + GX_TEV_KCSEL_1 = GX_TEV_KCSEL_8_8, + GX_TEV_KCSEL_3_4 = GX_TEV_KCSEL_6_8, + GX_TEV_KCSEL_1_2 = GX_TEV_KCSEL_4_8, + GX_TEV_KCSEL_1_4 = GX_TEV_KCSEL_2_8, + 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_8_8 = 0x00, - GX_TEV_KASEL_7_8 = 0x01, - GX_TEV_KASEL_6_8 = 0x02, - GX_TEV_KASEL_5_8 = 0x03, - GX_TEV_KASEL_4_8 = 0x04, - GX_TEV_KASEL_3_8 = 0x05, - GX_TEV_KASEL_2_8 = 0x06, - GX_TEV_KASEL_1_8 = 0x07, - GX_TEV_KASEL_1 = GX_TEV_KASEL_8_8, - GX_TEV_KASEL_3_4 = GX_TEV_KASEL_6_8, - GX_TEV_KASEL_1_2 = GX_TEV_KASEL_4_8, - GX_TEV_KASEL_1_4 = GX_TEV_KASEL_2_8, - 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, +typedef enum _GXTevKAlphaSel +{ + GX_TEV_KASEL_8_8 = 0x00, + GX_TEV_KASEL_7_8 = 0x01, + GX_TEV_KASEL_6_8 = 0x02, + GX_TEV_KASEL_5_8 = 0x03, + GX_TEV_KASEL_4_8 = 0x04, + GX_TEV_KASEL_3_8 = 0x05, + GX_TEV_KASEL_2_8 = 0x06, + GX_TEV_KASEL_1_8 = 0x07, + GX_TEV_KASEL_1 = GX_TEV_KASEL_8_8, + GX_TEV_KASEL_3_4 = GX_TEV_KASEL_6_8, + GX_TEV_KASEL_1_2 = GX_TEV_KASEL_4_8, + GX_TEV_KASEL_1_4 = GX_TEV_KASEL_2_8, + 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, +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, +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, +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, +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, +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, +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, +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, +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, +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 _GXClipMode { - GX_CLIP_ENABLE = 0, - GX_CLIP_DISABLE = 1, +typedef enum _GXClipMode +{ + GX_CLIP_ENABLE = 0, + GX_CLIP_DISABLE = 1, } GXClipMode; -typedef enum _GXTlut { - GX_TLUT0 = 0, - GX_TLUT1 = 1, - GX_TLUT2 = 2, - GX_TLUT3 = 3, - GX_TLUT4 = 4, - GX_TLUT5 = 5, - GX_TLUT6 = 6, - GX_TLUT7 = 7, - GX_TLUT8 = 8, - GX_TLUT9 = 9, - GX_TLUT10 = 10, - GX_TLUT11 = 11, - GX_TLUT12 = 12, - GX_TLUT13 = 13, - GX_TLUT14 = 14, - GX_TLUT15 = 15, - GX_BIGTLUT0 = 16, - GX_BIGTLUT1 = 17, - GX_BIGTLUT2 = 18, - GX_BIGTLUT3 = 19, +typedef enum _GXTlut +{ + GX_TLUT0 = 0, + GX_TLUT1 = 1, + GX_TLUT2 = 2, + GX_TLUT3 = 3, + GX_TLUT4 = 4, + GX_TLUT5 = 5, + GX_TLUT6 = 6, + GX_TLUT7 = 7, + GX_TLUT8 = 8, + GX_TLUT9 = 9, + GX_TLUT10 = 10, + GX_TLUT11 = 11, + GX_TLUT12 = 12, + GX_TLUT13 = 13, + GX_TLUT14 = 14, + GX_TLUT15 = 15, + GX_BIGTLUT0 = 16, + GX_BIGTLUT1 = 17, + GX_BIGTLUT2 = 18, + GX_BIGTLUT3 = 19, } GXTlut; -typedef enum _GXTlutFmt { - GX_TL_IA8, - GX_TL_RGB565, - GX_TL_RGB5A3, - GX_MAX_TLUTFMT, +typedef enum _GXTlutFmt +{ + GX_TL_IA8, + GX_TL_RGB565, + GX_TL_RGB5A3, + GX_MAX_TLUTFMT, } GXTlutFmt; -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, +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; -typedef enum _GXMiscToken { - GX_MT_NULL = 0, - GX_MT_XF_FLUSH = 1, - GX_MT_DL_SAVE_CONTEXT = 2, - GX_MT_ABORT_WAIT_COPYOUT = 3, +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; -typedef enum _GXTexCacheSize { - GX_TEXCACHE_32K, - GX_TEXCACHE_128K, - GX_TEXCACHE_512K, - GX_TEXCACHE_NONE +typedef enum _GXTexCacheSize +{ + GX_TEXCACHE_32K, + GX_TEXCACHE_128K, + GX_TEXCACHE_512K, + GX_TEXCACHE_NONE } GXTexCacheSize; -typedef enum _GXPerf0 { - 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, - 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, - 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, - GX_PERF0_NONE +typedef enum _GXPerf0 +{ + 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, + 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, + 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, + GX_PERF0_NONE } GXPerf0; -typedef enum _GXPerf1 { - 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, - 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, - GX_PERF1_CALL_REQ, - GX_PERF1_VC_MISS_REQ, - GX_PERF1_CP_ALL_REQ, - - GX_PERF1_CLOCKS, - GX_PERF1_NONE +typedef enum _GXPerf1 +{ + 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, + 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, + GX_PERF1_CALL_REQ, + GX_PERF1_VC_MISS_REQ, + GX_PERF1_CP_ALL_REQ, + + GX_PERF1_CLOCKS, + GX_PERF1_NONE } GXPerf1; -typedef enum _GXVCachePerf { - GX_VC_POS, - GX_VC_NRM, - GX_VC_CLR0, - GX_VC_CLR1, - GX_VC_TEX0, - GX_VC_TEX1, - GX_VC_TEX2, - GX_VC_TEX3, - GX_VC_TEX4, - GX_VC_TEX5, - GX_VC_TEX6, - GX_VC_TEX7, - GX_VC_ALL = 0xf +typedef enum _GXVCachePerf +{ + GX_VC_POS, + GX_VC_NRM, + GX_VC_CLR0, + GX_VC_CLR1, + GX_VC_TEX0, + GX_VC_TEX1, + GX_VC_TEX2, + GX_VC_TEX3, + GX_VC_TEX4, + GX_VC_TEX5, + GX_VC_TEX6, + GX_VC_TEX7, + GX_VC_ALL = 0xf } GXVCachePerf; diff --git a/include/dolphin/gx/GXFrameBuffer.h b/include/dolphin/gx/GXFrameBuffer.h index 2579fc00f..91c9f7921 100644 --- a/include/dolphin/gx/GXFrameBuffer.h +++ b/include/dolphin/gx/GXFrameBuffer.h @@ -43,7 +43,7 @@ extern GXRenderModeObj GXEurgb60Hz480IntAa; #define GX_MAX_Z24 0x00FFFFFF void GXSetCopyClear(GXColor clear_clr, u32 clear_z); -void GXAdjustForOverscan(GXRenderModeObj* rmin, GXRenderModeObj* rmout, u16 hor, u16 ver); +void GXAdjustForOverscan(const GXRenderModeObj* rmin, GXRenderModeObj* rmout, u16 hor, u16 ver); void GXCopyDisp(void* dest, GXBool clear); void GXSetDispCopyGamma(GXGamma gamma); void GXSetDispCopySrc(u16 left, u16 top, u16 wd, u16 ht); @@ -51,7 +51,7 @@ void GXSetDispCopyDst(u16 wd, u16 ht); f32 GXGetYScaleFactor(u16 efbHeight, u16 xfbHeight); u32 GXSetDispCopyYScale(f32 vscale); u16 GXGetNumXfbLines(u16 efbHeight, f32 yScale); -void GXSetCopyFilter(GXBool aa, u8 sample_pattern[12][2], GXBool vf, u8 vfilter[7]); +void GXSetCopyFilter(GXBool aa, const u8 sample_pattern[12][2], GXBool vf, const u8 vfilter[7]); void GXSetPixelFmt(GXPixelFmt pix_fmt, GXZFmt16 z_fmt); void GXSetTexCopySrc(u16 left, u16 top, u16 wd, u16 ht); void GXSetTexCopyDst(u16 wd, u16 ht, GXTexFmt fmt, GXBool mipmap); diff --git a/include/dolphin/gx/GXGeometry.h b/include/dolphin/gx/GXGeometry.h index 870e7d2e9..bfafcdc03 100644 --- a/include/dolphin/gx/GXGeometry.h +++ b/include/dolphin/gx/GXGeometry.h @@ -8,7 +8,7 @@ extern "C" { #endif void GXSetVtxDesc(GXAttr attr, GXAttrType type); -void GXSetVtxDescv(GXVtxDescList* list); +void GXSetVtxDescv(const GXVtxDescList* list); void GXClearVtxDesc(void); void GXSetVtxAttrFmt(GXVtxFmt vtxfmt, GXAttr attr, GXCompCnt cnt, GXCompType type, u8 frac); void GXSetNumTexGens(u8 nTexGens); @@ -18,12 +18,13 @@ void GXSetTexCoordGen2(GXTexCoordID dst_coord, GXTexGenType func, GXTexGenSrc sr void GXSetLineWidth(u8 width, GXTexOffset texOffsets); void GXSetPointSize(u8 pointSize, GXTexOffset texOffsets); void GXEnableTexOffsets(GXTexCoordID coord, GXBool line_enable, GXBool point_enable); -void GXSetArray(GXAttr attr, const void* data, u8 stride); +void GXSetArray(GXAttr attr, void* data, u8 stride); void GXInvalidateVtxCache(void); 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); + GXTexGenSrc src_param, u32 mtx) +{ + GXSetTexCoordGen2(dst_coord, func, src_param, mtx, GX_FALSE, GX_PTIDENTITY); } #ifdef __cplusplus diff --git a/include/dolphin/gx/GXManage.h b/include/dolphin/gx/GXManage.h index ab3a72c84..019647578 100644 --- a/include/dolphin/gx/GXManage.h +++ b/include/dolphin/gx/GXManage.h @@ -7,6 +7,7 @@ extern "C" { #endif +typedef void (*GXDrawSyncCallback)(u16 token); typedef void (*GXDrawDoneCallback)(void); GXFifoObj* GXInit(void* base, u32 size); diff --git a/include/dolphin/gx/GXTexture.h b/include/dolphin/gx/GXTexture.h index 76bae19c1..a91670306 100644 --- a/include/dolphin/gx/GXTexture.h +++ b/include/dolphin/gx/GXTexture.h @@ -8,9 +8,10 @@ extern "C" { #endif -typedef GXTexRegion* (*GXTexRegionCallback)(const GXTexObj* obj, GXTexMapID id); +typedef GXTexRegion* (*GXTexRegionCallback)(GXTexObj* obj, GXTexMapID id); +typedef GXTlutRegion* (*GXTlutRegionCallback)(u32 idx); -void GXInitTexObj(GXTexObj* obj, void* image_ptr, u16 width, u16 height, GXTexFmt format, +void GXInitTexObj(GXTexObj* obj, const void* image_ptr, u16 width, u16 height, GXTexFmt format, GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, GXBool mipmap); void GXInitTexObjCI(GXTexObj* obj, const void* data, u16 width, u16 height, GXCITexFmt format, GXTexWrapMode wrapS, GXTexWrapMode wrapT, GXBool mipmap, u32 tlut); @@ -28,6 +29,7 @@ void GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 ss, u16 t void GXInitTexCacheRegion(GXTexRegion* region, GXBool is_32b_mipmap, u32 tmem_even, GXTexCacheSize size_even, u32 tmem_odd, GXTexCacheSize size_odd); GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback callback); +GXTlutRegionCallback GXSetTlutRegionCallback(GXTlutRegionCallback f); void GXInvalidateTexRegion(const GXTexRegion* region); #ifdef __cplusplus diff --git a/include/dolphin/os/OSFont.h b/include/dolphin/os/OSFont.h index ba312bde0..1c9d7d9b2 100644 --- a/include/dolphin/os/OSFont.h +++ b/include/dolphin/os/OSFont.h @@ -7,6 +7,14 @@ extern "C" { #endif +#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 { u16 fontType; // _00 diff --git a/include/dolphin/os/OSRtc.h b/include/dolphin/os/OSRtc.h index ed3c3dd81..0ae3f40d2 100644 --- a/include/dolphin/os/OSRtc.h +++ b/include/dolphin/os/OSRtc.h @@ -8,20 +8,21 @@ extern "C" { #endif // make the assert happy -#define OS_SOUND_MODE_MONO 0 -#define OS_SOUND_MODE_STEREO 1 +//#define OS_SOUND_MODE_MONO 0 +//#define OS_SOUND_MODE_STEREO 1 // make the asserts happy #define OS_VIDEO_MODE_NTSC 0 #define OS_VIDEO_MODE_MPAL 2 -#define OS_PROGRESSIVE_MODE_OFF 0 -#define OS_PROGRESSIVE_MODE_ON 1 +// #define OS_PROGRESSIVE_MODE_OFF 0 +// #define OS_PROGRESSIVE_MODE_ON 1 -#define OS_EURGB60_OFF 0 -#define OS_EURGB60_ON 1 +// #define OS_EURGB60_OFF 0 +// #define OS_EURGB60_ON 1 -typedef struct OSSram { +typedef struct OSSram +{ u16 checkSum; u16 checkSumInv; u32 ead0; @@ -33,7 +34,8 @@ typedef struct OSSram { u8 flags; } OSSram; -typedef struct OSSramEx { +typedef struct OSSramEx +{ u8 flashID[2][12]; u32 wirelessKeyboardID; u16 wirelessPadID[4]; @@ -46,8 +48,9 @@ typedef struct OSSramEx { #define SRAM_SIZE (sizeof(OSSram) + sizeof(OSSramEx)) -typedef struct SramControl { - u8 sram[SRAM_SIZE]; // dummy for OSSram + OSSramEx +typedef struct SramControl +{ + u8 sram[SRAM_SIZE]; // dummy for OSSram + OSSramEx u32 offset; BOOL enabled; BOOL locked; @@ -57,7 +60,7 @@ typedef struct SramControl { u32 OSGetSoundMode(void); void OSSetSoundMode(u32 mode); -u32 OSGetVideoMode(void); +u32 OSGetVideoMode(); void OSSetVideoMode(u32 mode); u8 OSGetLanguage(void); void OSSetLanguage(u8 language); diff --git a/include/fake_tgmath.h b/include/fake_tgmath.h new file mode 100644 index 000000000..41a982106 --- /dev/null +++ b/include/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/libs/dolphin/OdemuExi2/DebuggerDriver.c b/libs/dolphin/OdemuExi2/DebuggerDriver.c index e69de29bb..c2c5e7c3d 100644 --- a/libs/dolphin/OdemuExi2/DebuggerDriver.c +++ b/libs/dolphin/OdemuExi2/DebuggerDriver.c @@ -0,0 +1,448 @@ +#include "types.h" +#include "Dolphin/os.h" +#include "Dolphin/hw_regs.h" + +typedef void (*MTRCallbackType)(int); + +static MTRCallbackType MTRCallback; +static void (*DBGCallback)(u32, OSContext*); + +static u32 SendMailData; +static s32 RecvDataLeng; + +static u8* pEXIInputFlag; +static u8 EXIInputFlag; + +static u8 SendCount = 0x80; + +#define IS_TRUE(x) ((x) != FALSE) +#define IS_FALSE(x) !IS_TRUE(x) +#define ROUND_UP(x, align) (((x) + (align)-1) & (-(align))) + +void DBGEXIInit() +{ + __OSMaskInterrupts(0x18000); + __EXIRegs[10] = 0; +} + +/* + * --INFO-- + * Address: ........ + * Size: 000028 + */ + +static u32 DBGEXISelect(u32 v) +{ + u32 regs = __EXIRegs[10]; + regs &= 0x405; + regs |= 0x80 | (v << 4); + __EXIRegs[10] = regs; + return TRUE; +} + +/* + * --INFO-- + * Address: ........ + * Size: 00001C + */ +BOOL DBGEXIDeselect(void) +{ + __EXIRegs[10] &= 0x405; + return TRUE; +} + +/* + * --INFO-- + * Address: ........ + * Size: 00001C + */ +static BOOL DBGEXISync() +{ + while (__EXIRegs[13] & 1) + ; + + return TRUE; +} + +/* + * --INFO-- + * Address: 802214D8 + * Size: 000298 + */ +static BOOL DBGEXIImm(void* buffer, s32 bytecounter, u32 write) +{ + u8* tempPointer; + u32 writeOutValue; + int i; + + if (write) + { + tempPointer = buffer; + writeOutValue = 0; + for (i = 0; i < bytecounter; i++) + { + u8* temp = ((u8*)buffer) + i; + writeOutValue |= *temp << ((3 - i) << 3); + } + __EXIRegs[14] = writeOutValue; + } + + __EXIRegs[13] = 1 | write << 2 | (bytecounter - 1) << 4; + DBGEXISync(); + + if (!write) + { + writeOutValue = __EXIRegs[14]; + tempPointer = buffer; + for (i = 0; i < bytecounter; i++) + { + *tempPointer++ = writeOutValue >> ((3 - i) << 3); + } + } + + return TRUE; +} + +/* + * --INFO-- + * Address: ........ + * Size: 00008C + */ +static BOOL DBGWriteMailbox(u32 p1) +{ + BOOL total = FALSE; + u32 v; + + if (!DBGEXISelect(4)) + { + return FALSE; + } + + v = (p1 & 0x1fffffff) | (0xC0000000); + total |= IS_FALSE(DBGEXIImm(&v, sizeof(v), 1)); + total |= IS_FALSE(DBGEXISync()); + total |= IS_FALSE(DBGEXIDeselect()); + + return IS_FALSE(total); +} + +/* + * --INFO-- + * Address: 80221770 + * Size: 0000AC + */ +static BOOL DBGReadMailbox(u32* p1) +{ + BOOL total = FALSE; + u32 v; + + if (!DBGEXISelect(4)) + { + return FALSE; + } + + v = 0x60000000; + total |= IS_FALSE(DBGEXIImm(&v, 2, 1)); + total |= IS_FALSE(DBGEXISync()); + + total |= IS_FALSE(DBGEXIImm(p1, 4, 0)); + total |= IS_FALSE(DBGEXISync()); + + total |= IS_FALSE(DBGEXIDeselect()); + + return IS_FALSE(total); +} + +/* + * --INFO-- + * Address: 8022181C + * Size: 0000DC + */ +static BOOL DBGRead(u32 count, u32* buffer, s32 param3) +{ + BOOL total = FALSE; + u32* buf_p = (u32*)buffer; + u32 v1; + u32 v; + + if (!DBGEXISelect(4)) + { + return FALSE; + } + + v1 = (count & 0x1fffc) << 8 | 0x20000000; + total |= IS_FALSE(DBGEXIImm(&v1, sizeof(v1), 1)); + total |= IS_FALSE(DBGEXISync()); + + while (param3) + { + total |= IS_FALSE(DBGEXIImm(&v, sizeof(v), 0)); + total |= IS_FALSE(DBGEXISync()); + + *buf_p++ = v; + + param3 -= 4; + if (param3 < 0) + { + param3 = 0; + } + } + + total |= IS_FALSE(DBGEXIDeselect()); + return IS_FALSE(total); +} + +/* + * --INFO-- + * Address: 802218F8 + * Size: 0000DC + */ +static BOOL DBGWrite(u32 count, void* buffer, s32 param3) +{ + BOOL total = FALSE; + u32* buf_p = (u32*)buffer; + u32 v1; + u32 v; + + if (!DBGEXISelect(4)) + { + return FALSE; + } + + v1 = (count & 0x1fffc) << 8 | 0xa0000000; + total |= IS_FALSE(DBGEXIImm(&v1, sizeof(v1), 1)); + total |= IS_FALSE(DBGEXISync()); + + while (param3 != 0) + { + v = *buf_p++; + + total |= IS_FALSE(DBGEXIImm(&v, sizeof(v), 1)); + total |= IS_FALSE(DBGEXISync()); + + param3 -= 4; + if (param3 < 0) + { + param3 = 0; + } + } + + total |= IS_FALSE(DBGEXIDeselect()); + return IS_FALSE(total); +} + +/* + * --INFO-- + * Address: 802219D4 + * Size: 0000AC + */ +static BOOL DBGReadStatus(u32* p1) +{ + BOOL total = FALSE; + u32 v; + + if (!DBGEXISelect(4)) + { + return FALSE; + } + + v = 1 << 30; + total |= IS_FALSE(DBGEXIImm((u8*)&v, 2, 1)); + total |= IS_FALSE(DBGEXISync()); + + total |= IS_FALSE(DBGEXIImm(p1, 4, 0)); + total |= IS_FALSE(DBGEXISync()); + + total |= IS_FALSE(DBGEXIDeselect()); + + return IS_FALSE(total); +} + +/* + * --INFO-- + * Address: 80221A80 + * Size: 00003C + */ +static void MWCallback(u32 a, OSContext* b) +{ + EXIInputFlag = TRUE; + if (MTRCallback) + { + MTRCallback(0); + } +} + +/* + * --INFO-- + * Address: 80221ABC + * Size: 000040 + */ +static void DBGHandler(s16 a, OSContext* b) +{ + *__PIRegs = 0x1000; + if (DBGCallback) + { + DBGCallback(a, b); + } +} + +/* + * --INFO-- + * Address: 80221AFC + * Size: 000078 + */ +void DBInitComm(u8** a, MTRCallbackType b) +{ + BOOL interrupts = OSDisableInterrupts(); + { + pEXIInputFlag = (u8*)EXIInputFlag; + pEXIInputFlag = &EXIInputFlag; + + *a = pEXIInputFlag; + + MTRCallback = b; + + DBGEXIInit(); + } + OSRestoreInterrupts(interrupts); +} + +/* + * --INFO-- + * Address: 80221B74 + * Size: 000054 + */ +void DBInitInterrupts(void) +{ + __OSMaskInterrupts(0x18000); + __OSMaskInterrupts(0x40); + DBGCallback = &MWCallback; + __OSSetInterruptHandler(0x19, DBGHandler); + __OSUnmaskInterrupts(0x40); +} + +/* + * --INFO-- + * Address: ........ + * Size: 000150 + */ +static void CheckMailBox(void) +{ + u32 v; + DBGReadStatus(&v); + if (v & 1) + { + DBGReadMailbox(&v); + v &= 0x1fffffff; + + if ((v & 0x1f000000) == 0x1f000000) + { + SendMailData = v; + RecvDataLeng = v & 0x7fff; + EXIInputFlag = 1; + } + } +} + +/* + * --INFO-- + * Address: 80221BC8 + * Size: 00009C + */ +u32 DBQueryData(void) +{ + BOOL interrupts; + + EXIInputFlag = 0; + if (!RecvDataLeng) + { + interrupts = OSDisableInterrupts(); + CheckMailBox(); + } + OSRestoreInterrupts(interrupts); + return RecvDataLeng; +} + +/* + * --INFO-- + * Address: 80221C64 + * Size: 00008C + */ +BOOL DBRead(u32* buffer, s32 count) +{ + u32 interrupts = OSDisableInterrupts(); + u32 v = SendMailData & 0x10000 ? 0x1000 : 0; + + DBGRead(v + 0x1e000, buffer, ROUND_UP(count, 4)); + + RecvDataLeng = 0; + EXIInputFlag = 0; + + OSRestoreInterrupts(interrupts); + + return 0; +} + +/* + * --INFO-- + * Address: 80221CF0 + * Size: 000260 + */ +BOOL DBWrite(const void* src, u32 size) +{ + u32 v; + u32 busyFlag; + BOOL interrupts; + + interrupts = OSDisableInterrupts(); + + do + { + DBGReadStatus(&busyFlag); + } while (busyFlag & 2); + + SendCount++; + v = ((SendCount & 1) ? 0x1000 : 0); + + while (!DBGWrite(v | 0x1c000, (u32*)src, ROUND_UP(size, 4))) + ; + + do + { + DBGReadStatus(&busyFlag); + } while (busyFlag & 2); + + v = (SendCount << 0x10) | 0x1F000000 | size; + while (!DBGWriteMailbox(v)) + ; + + do + { + while (!DBGReadStatus(&busyFlag)) + ; + } while (busyFlag & 2); + + OSRestoreInterrupts(interrupts); + + return 0; +} + +/* + * --INFO-- + * Address: 80221F50 + * Size: 000004 + */ +void DBOpen(void) +{ + return; +} + +/* + * * --INFO-- + * Address: 80221F54 + * Size: 000004 + */ +void DBClose(void) +{ + return; +} \ No newline at end of file diff --git a/libs/dolphin/amcstubs/AmcExi2Stubs.c b/libs/dolphin/amcstubs/AmcExi2Stubs.c new file mode 100644 index 000000000..99073a34c --- /dev/null +++ b/libs/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/libs/dolphin/ax/AXCL.c b/libs/dolphin/ax/AXCL.c index 4487e3cb8..7653eff26 100644 --- a/libs/dolphin/ax/AXCL.c +++ b/libs/dolphin/ax/AXCL.c @@ -72,7 +72,7 @@ void __AXNextFrame(void* sbuffer, void* buffer) case 2: break; default: - ASSERTMSGLINE(193, 0, "Unknown AX mode!"); + return; } data = (u32)__AXGetPBs(); diff --git a/libs/dolphin/ax/AXOut.c b/libs/dolphin/ax/AXOut.c index 7ead2b859..885c40f54 100644 --- a/libs/dolphin/ax/AXOut.c +++ b/libs/dolphin/ax/AXOut.c @@ -178,10 +178,6 @@ 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; diff --git a/libs/dolphin/ax/AXVPB.c b/libs/dolphin/ax/AXVPB.c index b91ad2e30..6fa4269c9 100644 --- a/libs/dolphin/ax/AXVPB.c +++ b/libs/dolphin/ax/AXVPB.c @@ -33,7 +33,6 @@ void __AXServiceVPB(AXVPB* pvpb) AXPB* ppbUser; u32 sync; - ASSERTLINE(0xA1, (pvpb->index >= 0) && (pvpb->index < AX_MAX_VOICES)); __AXNumVoices += 1; ppbDsp = &__AXPB[pvpb->index]; ppbUser = &pvpb->pb; @@ -662,8 +661,8 @@ void __AXSetPBDefault(AXVPB* p) p->sync = 0xA4; 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.update.updNum[59] = 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; } void __AXVPBInit(void) @@ -688,9 +687,6 @@ void __AXVPBInit(void) ppbi = &__AXITD[i]; ppbu = &__AXUpdates[i]; pvpb = &__AXVPB[i]; - ASSERTLINE(0x2F6, (u32)ppb ^ 0x1F); - ASSERTLINE(0x2F7, (u32)ppbi ^ 0x1F); - ASSERTLINE(0x2F8, (u32)ppbu ^ 0x1F); pvpb->index = i; pvpb->updateWrite = pvpb->updateData; pvpb->itdBuffer = ppbi; @@ -735,8 +731,6 @@ void AXSetVoiceSrcType(AXVPB* p, u32 type) int old; AXPB* ppb; - ASSERTLINE(0x35E, p); - ASSERTLINE(0x35F, type <= AX_SRC_TYPE_4TAP_16K); old = OSDisableInterrupts(); ppb = &p->pb; switch (type) @@ -931,7 +925,6 @@ void AXSetVoiceUpdateIncrement(AXVPB* p) old = OSDisableInterrupts(); p->updateMS++; p->sync |= AX_SYNC_FLAG_COPYUPDATE; - ASSERTMSGLINE(0x431, p->updateMS <= 4, "PB updates cannot exceed 5ms\n"); OSRestoreInterrupts(old); } @@ -941,7 +934,7 @@ void AXSetVoiceUpdateWrite(AXVPB* p, u16 param, u16 data) old = OSDisableInterrupts(); p->updateCounter += 2; - ASSERTMSGLINE(0x43F, p->updateCounter <= 128, "PB update block exceeded 128 words\n"); + *(p->updateWrite) = param; p->updateWrite += 1; *(p->updateWrite) = data; @@ -1051,12 +1044,6 @@ void AXSetVoiceAddr(AXVPB* p, AXPBADDR* addr) switch (addr->format) { case 0: - ASSERTMSGLINE(0x4BA, (addr->loopAddressLo & 0xF) > 1, - "*** loop address on ADPCM frame header! ***\n"); - ASSERTMSGLINE(0x4BF, (addr->endAddressLo & 0xF) > 1, - "*** end address on ADPCM frame header! ***\n"); - ASSERTMSGLINE(0x4C4, (addr->currentAddressLo & 0xF) > 1, - "*** current address on ADPCM frame header! ***\n"); break; case 10: dst += 1; @@ -1105,7 +1092,6 @@ void AXSetVoiceAddr(AXVPB* p, AXPBADDR* addr) dst += 1; break; default: - ASSERTMSGLINE(0x4F0, 0, "unknown addr->formaqt in PB\n"); break; } p->sync &= ~(AX_SYNC_FLAG_COPYLOOP | AX_SYNC_FLAG_COPYLOOPADDR | AX_SYNC_FLAG_COPYENDADDR | diff --git a/libs/dolphin/base/PPCArch.c b/libs/dolphin/base/PPCArch.c index 33dc03e67..1b0ca3bee 100644 --- a/libs/dolphin/base/PPCArch.c +++ b/libs/dolphin/base/PPCArch.c @@ -16,78 +16,58 @@ void PPCMthid0(u32 newHID0); asm u32 PPCMfmsr(void) { - nofralloc mfmsr r3 blr + nofralloc; + mfmsr r3; + blr } asm void PPCMtmsr(register u32 newMSR) { - nofralloc mtmsr newMSR blr -} - -void PPCOrMsr(void) -{ - // UNUSED FUNCTION -} - -void PPCAndMsr(void) -{ - // UNUSED FUNCTION -} - -void PPCAndCMsr(void) -{ - // UNUSED FUNCTION + nofralloc; + mtmsr newMSR; + blr } asm u32 PPCMfhid0(void) { - nofralloc mfspr r3, HID0 blr + nofralloc; + mfspr r3, HID0; + blr } asm void PPCMthid0(register u32 newHID0) { - nofralloc mtspr HID0, newHID0 blr -} - -void PPCMfhid1(void) -{ - // UNUSED FUNCTION + nofralloc; + mtspr HID0, newHID0; + blr } asm u32 PPCMfl2cr(void) { - nofralloc mfspr r3, L2CR blr + nofralloc; + mfspr r3, L2CR; + blr } asm void PPCMtl2cr(register u32 newL2cr) { - nofralloc mtspr L2CR, newL2cr blr + nofralloc; + mtspr L2CR, newL2cr; + blr } __declspec(weak) asm void PPCMtdec(register u32 newDec) { - nofralloc mtdec newDec blr -} - -void PPCMfdec(void) -{ - // UNUSED FUNCTION + nofralloc; + mtdec newDec; + blr } asm void PPCSync(void) { - nofralloc sc blr -} - -asm void PPCEieio(void) -{ - nofralloc mfmsr r5 rlwinm r6, r5, 0, 0x11, 0xf mtmsr r6 mfspr r3, hid0 ori r4, r3, 8 mtspr hid0, - r4 isync eieio isync - - mtspr hid0, - r3 mtmsr r5 isync - - blr + nofralloc; + sc; + blr } __declspec(weak) asm void PPCHalt(void) //spins infinitely @@ -96,79 +76,56 @@ __declspec(weak) asm void PPCHalt(void) //spins infinitely sync - _spin : nop li r3, - 0 nop b _spin + _spin : nop; + li r3, 0; + nop; + b _spin // NEVER REACHED } -asm void PPCMfmmcr0(void) -{ - nofralloc mfspr r3, MMCR0 blr -} - asm void PPCMtmmcr0(register u32 newMmcr0) { - nofralloc mtspr MMCR0, newMmcr0 blr -} - -asm void PPCMfmmcr1(void) -{ - nofralloc mfspr r3, MMCR1 blr + nofralloc; + mtspr MMCR0, newMmcr0; + blr } asm void PPCMtmmcr1(register u32 newMmcr1) { - nofralloc mtspr MMCR1, newMmcr1 blr -} - -asm void PPCMfpmc1(void) -{ - nofralloc mfspr r3, PMC1 blr + nofralloc; + mtspr MMCR1, newMmcr1; + blr } asm void PPCMtpmc1(register u32 newPmc1) { - nofralloc mtspr PMC1, newPmc1 blr -} - -asm void PPCMfpmc2(void) -{ - nofralloc mfspr r3, PMC2 blr + nofralloc; + mtspr PMC1, newPmc1; + blr } asm void PPCMtpmc2(register u32 newPmc2) { - nofralloc mtspr PMC2, newPmc2 blr -} - -asm void PPCMfpmc3(void) -{ - nofralloc mfspr r3, PMC2 blr + nofralloc; + mtspr PMC2, newPmc2; + blr } asm void PPCMtpmc3(register u32 newPmc3) { - nofralloc mtspr PMC3, newPmc3 blr -} - -asm void PPCMfpmc4(void) -{ - nofralloc mfspr r3, PMC4 blr + nofralloc; + mtspr PMC3, newPmc3; + blr } asm void PPCMtpmc4(register u32 newPmc4) { - nofralloc mtspr PMC4, newPmc4 blr + nofralloc; + mtspr PMC4, newPmc4; + blr } -asm void PPCMfsia(void) -{ - nofralloc mfspr r3, SIA blr -} - -asm void PPCMtsia(register u32 newSia){ nofralloc mtspr SIA, newSia blr } - u32 PPCMffpscr(void) { union FpscrUnion m; @@ -198,52 +155,23 @@ void PPCMtfpscr(register u32 newFPSCR) asm u32 PPCMfhid2(void) { - nofralloc mfspr r3, 0x398 blr + nofralloc; + mfspr r3, 0x398; + blr } asm void PPCMthid2(register u32 newhid2) { - nofralloc mtspr 0x398, newhid2 blr -} - -asm u32 PPCMfwpar(void) -{ - nofralloc sync mfspr r3, WPAR blr + nofralloc; + mtspr 0x398, newhid2; + blr } asm void PPCMtwpar(register u32 newwpar) { - nofralloc mtspr WPAR, newwpar blr -} - -asm void PPCMfdmaU(void) -{ - nofralloc mfspr r3, DMA_U blr -} - -asm void PPCMfdmaL(void) -{ - nofralloc mfspr r3, DMA_L blr -} - -void PPCMtdmaU(void) -{ - // UNUSED FUNCTION -} - -void PPCMtdmaL(void) -{ - // UNUSED FUNCTION -} - -void PPCMfpvr(void) -{ - // UNUSED FUNCTION -} - -void PPCEnableSpeculation(void) -{ - // UNUSED FUNCTION + nofralloc; + mtspr WPAR, newwpar; + blr } void PPCDisableSpeculation(void) @@ -251,13 +179,10 @@ void PPCDisableSpeculation(void) PPCMthid0(PPCMfhid0() | HID0_SPD); } -asm void PPCSetFpIEEEMode(void) -{ - nofralloc mtfsb0 4 * 7 + 1 blr -} - asm void PPCSetFpNonIEEEMode(void) { - nofralloc mtfsb1 29 blr + nofralloc; + mtfsb1 29; + blr } // clang-format on \ No newline at end of file diff --git a/libs/dolphin/dvd/dvd.c b/libs/dolphin/dvd/dvd.c index 30b70e61e..de5304885 100644 --- a/libs/dolphin/dvd/dvd.c +++ b/libs/dolphin/dvd/dvd.c @@ -4,7 +4,7 @@ #include #include -const char* __DVDVersion = "<< Dolphin SDK - DVD\trelease build: Jul 23 2003 11:27:57 (0x2301) >>"; +const char* __DVDVersion = "<< Dolphin SDK - DVD\trelease build: Apr 22 2003 15:49:00 (0x2301) >>"; // need to be "<< Dolphin SDK - DSP\trelease build: Apr 17 2003 12:34:16 (0x2301) >>" typedef void (*stateFunc)(DVDCommandBlock* block); @@ -114,7 +114,7 @@ static void stateReadingFST() if (bootInfo->FSTMaxLength < BB2.FSTLength) { -#line 650 +#line 644 OSHalt("DVDChangeDisk(): FST in the new disc is too big. "); } @@ -1093,6 +1093,18 @@ BOOL DVDReadAbsAsyncPrio(DVDCommandBlock* block, void* addr, s32 length, s32 off return idle; } +int DVDSeekAbsAsyncPrio(DVDCommandBlock* block, s32 offset, DVDCBCallback callback, s32 prio) +{ + int idle; + + block->command = DVD_COMMAND_SEEK; + block->offset = offset; + block->callback = callback; + + idle = issueCommand(prio, block); + return idle; +} + BOOL DVDReadAbsAsyncForBS(DVDCommandBlock* block, void* addr, s32 length, s32 offset, DVDCBCallback callback) { @@ -1483,27 +1495,30 @@ static void cbForCancelSync(s32 result, DVDCommandBlock* block) OSWakeupThread(&__DVDThreadQueue); } -inline 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) + { retVal = DVDCancelAsync(executing, callback); + } else { - retVal = TRUE; + retVal = 1; if (callback) - (*callback)(0, NULL); + { + callback(0, NULL); + } } DVDResume(); @@ -1648,17 +1663,3 @@ void __DVDPrepareResetAsync(DVDCBCallback callback) OSRestoreInterrupts(enabled); } - -BOOL __DVDTestAlarm(OSAlarm* alarm) -{ - BOOL ret; - if (alarm == &ResetAlarm) - { - ret = TRUE; - } - else - { - ret = __DVDLowTestAlarm(alarm); - } - return ret; -} \ No newline at end of file diff --git a/libs/dolphin/dvd/dvdFatal.c b/libs/dolphin/dvd/dvdFatal.c index 43359a1a4..2d27647db 100644 --- a/libs/dolphin/dvd/dvdFatal.c +++ b/libs/dolphin/dvd/dvdFatal.c @@ -7,101 +7,6 @@ void __DVDPrintFatalMessage(void); static void (*FatalFunc)(void) = NULL; -const char *Japanese = "\n\n\nエラーが発生しました。" - "\n\n本体のパワーボタンを押して電源をOFFにし、" - "\n本体の取扱説明書の指示に従ってください。"; - -const char *English = "\n\n\nAn error has occurred." - "\nTurn the power off and refer to the" - "\nNintendo GameCube Instruction Booklet" - "\nfor further instructions."; - -const char *const Europe[] = { - // English - "\n\n\nAn error has occurred." - "\nTurn the power off and refer to the" - "\nNintendo GameCube" - "\x99" - " Instruction Booklet" - "\nfor further instructions.", - - // German - "\n\n\nEin Fehler ist aufgetreten." - "\nBitte schalten Sie den NINTENDO GAMECUBE" - "\naus und lesen Sie die Bedienungsanleitung," - "\num weitere Informationen zu erhalten.", - - // French - "\n\n\nUne erreur est survenue." - "\nEteignez la console et r" - "\xe9" - "f" - "\xe9" - "rez-vous au" - "\nmanuel d'instructions NINTENDO GAMECUBE" - "\npour de plus amples informations.", - - // Spanish - "\n\n\nSe ha producido un error." - "\nApaga la consola y consulta el manual" - "\nde instrucciones de NINTENDO GAMECUBE" - "\npara obtener m" - "\xe1" - "s informaci" - "\xf3" - "n.", - - // Italian - "\n\n\nSi \xe8 verificato un errore." - "\nSpegni (OFF) e controlla il manuale" - "\nd'istruzioni del NINTENDO GAMECUBE" - "\nper ulteriori indicazioni.", - - // Dutch - "\n\n\nEr is een fout opgetreden." - "\nZet de NINTENDO GAMECUBE uit en" - "\nraadpleeg de handleiding van de" - "\nNintendo GameCube voor nadere" - "\ninstructies.", -}; - -static void ShowMessage(void) -{ - const char *message; - GXColor bg = {0, 0, 0, 0}; - GXColor fg = {255, 255, 255, 0}; - - if (VIGetTvFormat() == VI_NTSC) - { - if (OSGetFontEncode() == OS_FONT_ENCODE_SJIS) - { - message = Japanese; - } - else - { - message = English; - } - } - else - { - message = Europe[OSGetLanguage()]; - } - - OSFatal(fg, bg, message); -} - -BOOL DVDSetAutoFatalMessaging(BOOL enable) -{ - BOOL enabled; - BOOL prev; - - enabled = OSDisableInterrupts(); - prev = FatalFunc ? TRUE : FALSE; - FatalFunc = enable ? ShowMessage : NULL; - OSRestoreInterrupts(enabled); - return prev; -} - void __DVDPrintFatalMessage(void) { if (!FatalFunc) diff --git a/libs/dolphin/dvd/dvderror.c b/libs/dolphin/dvd/dvderror.c index a2f294393..259e8a5bf 100644 --- a/libs/dolphin/dvd/dvderror.c +++ b/libs/dolphin/dvd/dvderror.c @@ -2,24 +2,9 @@ #include "dolphin/OSRtcPriv.h" static u32 ErrorTable[] = { - 0, - 0x00023A00, - 0x00062800, - 0x00030200, - 0x00031100, - 0x00052000, - 0x00052001, - 0x00052100, - 0x00052400, - 0x00052401, - 0x00052402, - 0x000B5A01, - 0x00056300, - 0x00020401, - 0x00020400, - 0x00040800, - 0x00100007, - 0, + 0, 0x00023A00, 0x00062800, 0x00030200, 0x00031100, 0x00052000, + 0x00052001, 0x00052100, 0x00052400, 0x00052401, 0x00052402, 0x000B5A01, + 0x00056300, 0x00020401, 0x00020400, 0x00040800, 0x00100007, 0, }; static u8 ErrorCode2Num(u32 errorCode) @@ -66,7 +51,7 @@ static u8 Convert(u32 error) void __DVDStoreErrorCode(u32 error) { - OSSramEx *sram; + OSSramEx* sram; u8 num; num = Convert(error); diff --git a/libs/dolphin/dvd/dvdfs.c b/libs/dolphin/dvd/dvdfs.c index 7b688f415..27e75e9df 100644 --- a/libs/dolphin/dvd/dvdfs.c +++ b/libs/dolphin/dvd/dvdfs.c @@ -11,30 +11,30 @@ struct FSTEntry unsigned int nextEntryOrLength; }; -static OSBootInfo *BootInfo; -static FSTEntry *FstStart; -static char *FstStringStart; +static OSBootInfo* BootInfo; +static FSTEntry* FstStart; +static char* FstStringStart; static u32 MaxEntryNum; static u32 currentDirectory = 0; OSThreadQueue __DVDThreadQueue; u32 __DVDLongFileNameFlag = 0; -static void cbForReadAsync(s32 result, DVDCommandBlock *block); -static void cbForReadSync(s32 result, DVDCommandBlock *block); -static void cbForSeekAsync(s32 result, DVDCommandBlock *block); -static void cbForSeekSync(s32 result, DVDCommandBlock *block); -static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock *block); -static void cbForPrepareStreamSync(s32 result, DVDCommandBlock *block); +static void cbForReadAsync(s32 result, DVDCommandBlock* block); +static void cbForReadSync(s32 result, DVDCommandBlock* block); +static void cbForSeekAsync(s32 result, DVDCommandBlock* block); +static void cbForSeekSync(s32 result, DVDCommandBlock* block); +static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock* block); +static void cbForPrepareStreamSync(s32 result, DVDCommandBlock* block); void __DVDFSInit() { - BootInfo = (OSBootInfo *)OSPhysicalToCached(0); - FstStart = (FSTEntry *)BootInfo->FSTLocation; + BootInfo = (OSBootInfo*)OSPhysicalToCached(0); + FstStart = (FSTEntry*)BootInfo->FSTLocation; if (FstStart) { MaxEntryNum = FstStart[0].nextEntryOrLength; - FstStringStart = (char *)&(FstStart[MaxEntryNum]); + FstStringStart = (char*)&(FstStart[MaxEntryNum]); } } @@ -46,7 +46,7 @@ void __DVDFSInit() #define filePosition(i) (FstStart[i].parentOrPosition) #define fileLength(i) (FstStart[i].nextEntryOrLength) -static BOOL isSame(const char *path, const char *string) +static BOOL isSame(const char* path, const char* string) { while (*string != '\0') { @@ -64,16 +64,16 @@ static BOOL isSame(const char *path, const char *string) return FALSE; } -s32 DVDConvertPathToEntrynum(const char *pathPtr) +s32 DVDConvertPathToEntrynum(const char* pathPtr) { - const char *ptr; - char *stringPtr; + const char* ptr; + char* stringPtr; BOOL isDir; u32 length; u32 dirLookAt; u32 i; - const char *origPathPtr = pathPtr; - const char *extentionStart; + const char* origPathPtr = pathPtr; + const char* extentionStart; BOOL illegal; BOOL extention; @@ -81,7 +81,6 @@ s32 DVDConvertPathToEntrynum(const char *pathPtr) while (1) { - if (*pathPtr == '\0') { return (s32)dirLookAt; @@ -142,14 +141,16 @@ s32 DVDConvertPathToEntrynum(const char *pathPtr) if ((extention == TRUE) && (ptr - extentionStart > 3)) illegal = TRUE; - if (illegal) { - OSPanic(__FILE__, 383, - "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); - } + if (illegal) + { + OSPanic( + __FILE__, 383, + "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 { @@ -190,7 +191,7 @@ s32 DVDConvertPathToEntrynum(const char *pathPtr) } } -BOOL DVDFastOpen(s32 entrynum, DVDFileInfo *fileInfo) +BOOL DVDFastOpen(s32 entrynum, DVDFileInfo* fileInfo) { if ((entrynum < 0) || (entrynum >= MaxEntryNum) || entryIsDir(entrynum)) { @@ -205,7 +206,7 @@ BOOL DVDFastOpen(s32 entrynum, DVDFileInfo *fileInfo) return TRUE; } -BOOL DVDOpen(const char *fileName, DVDFileInfo *fileInfo) +BOOL DVDOpen(const char* fileName, DVDFileInfo* fileInfo) { s32 entry; char currentDir[128]; @@ -232,13 +233,13 @@ BOOL DVDOpen(const char *fileName, DVDFileInfo *fileInfo) return TRUE; } -BOOL DVDClose(DVDFileInfo *fileInfo) +BOOL DVDClose(DVDFileInfo* fileInfo) { DVDCancel(&(fileInfo->cb)); return TRUE; } -static u32 myStrncpy(char *dest, char *src, u32 maxlen) +static u32 myStrncpy(char* dest, char* src, u32 maxlen) { u32 i = maxlen; @@ -251,9 +252,9 @@ static u32 myStrncpy(char *dest, char *src, u32 maxlen) return (maxlen - i); } -static u32 entryToPath(u32 entry, char *path, u32 maxlen) +static u32 entryToPath(u32 entry, char* path, u32 maxlen) { - char *name; + char* name; u32 loc; if (entry == 0) @@ -277,7 +278,7 @@ static u32 entryToPath(u32 entry, char *path, u32 maxlen) return loc; } -static BOOL DVDConvertEntrynumToPath(s32 entrynum, char *path, u32 maxlen) +static BOOL DVDConvertEntrynumToPath(s32 entrynum, char* path, u32 maxlen) { u32 loc; @@ -304,12 +305,12 @@ static BOOL DVDConvertEntrynumToPath(s32 entrynum, char *path, u32 maxlen) return TRUE; } -BOOL DVDGetCurrentDir(char *path, u32 maxlen) +BOOL DVDGetCurrentDir(char* path, u32 maxlen) { return DVDConvertEntrynumToPath((s32)currentDirectory, path, maxlen); } -BOOL DVDChangeDir(char *dirName) +BOOL DVDChangeDir(char* dirName) { s32 entry; entry = DVDConvertPathToEntrynum(dirName); @@ -323,10 +324,9 @@ BOOL DVDChangeDir(char *dirName) return TRUE; } -BOOL DVDReadAsyncPrio(DVDFileInfo *fileInfo, void *addr, s32 length, s32 offset, +BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, DVDCallback callback, s32 prio) { - if (!((0 <= offset) && (offset < fileInfo->length))) { #line 746 @@ -346,24 +346,24 @@ BOOL DVDReadAsyncPrio(DVDFileInfo *fileInfo, void *addr, s32 length, s32 offset, return TRUE; } #ifndef offsetof -#define offsetof(type, memb) ((u32) & ((type *)0)->memb) +#define offsetof(type, memb) ((u32) & ((type*)0)->memb) #endif -static void cbForReadAsync(s32 result, DVDCommandBlock *block) +static void cbForReadAsync(s32 result, DVDCommandBlock* block) { - DVDFileInfo *fileInfo; + DVDFileInfo* fileInfo; - fileInfo = (DVDFileInfo *)((char *)block - offsetof(DVDFileInfo, cb)); + fileInfo = (DVDFileInfo*)((char*)block - offsetof(DVDFileInfo, cb)); if (fileInfo->callback) { (fileInfo->callback)(result, fileInfo); } } -s32 DVDReadPrio(DVDFileInfo *fileInfo, void *addr, s32 length, s32 offset, s32 prio) +s32 DVDReadPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, s32 prio) { BOOL result; - DVDCommandBlock *block; + DVDCommandBlock* block; s32 state; BOOL enabled; s32 retVal; @@ -394,7 +394,7 @@ s32 DVDReadPrio(DVDFileInfo *fileInfo, void *addr, s32 length, s32 offset, s32 p while (1) { - state = ((volatile DVDCommandBlock *)block)->state; + state = ((volatile DVDCommandBlock*)block)->state; if (state == DVD_STATE_END) { @@ -420,27 +420,29 @@ s32 DVDReadPrio(DVDFileInfo *fileInfo, void *addr, s32 length, s32 offset, s32 p } /* This is based on the revolution SDK, these may not match in all cases */ -static void cbForReadSync(s32 result, DVDCommandBlock *block) { OSWakeupThread(&__DVDThreadQueue); } +static void cbForReadSync(s32 result, DVDCommandBlock* block) +{ + OSWakeupThread(&__DVDThreadQueue); +} /* This is based on the revolution SDK, these may not match in all cases */ -BOOL DVDSeekAsyncPrio(DVDFileInfo *fileInfo, s32 offset, DVDCallback callback, s32 prio) +BOOL DVDSeekAsyncPrio(DVDFileInfo* fileInfo, s32 offset, DVDCallback callback, s32 prio) { - if (!((0 <= offset) && (offset <= fileInfo->length))) + if (!((0 <= offset) && (offset < fileInfo->length))) { - OSPanic(__FILE__, 0, "DVDSeek(): offset is out of the file "); + OSPanic(__FILE__, 0x387, "DVDSeek(): offset is out of the file "); } fileInfo->callback = callback; - DVDSeekAbsAsyncPrio(&(fileInfo->cb), (s32)(fileInfo->startAddr + offset), cbForSeekAsync, - prio); + DVDSeekAbsAsyncPrio(&(fileInfo->cb), (s32)(fileInfo->startAddr + offset), cbForSeekAsync, prio); return TRUE; } /* This is based on the revolution SDK, these may not match in all cases */ -static void cbForSeekAsync(s32 result, DVDCommandBlock *block) +static void cbForSeekAsync(s32 result, DVDCommandBlock* block) { - DVDFileInfo *fileInfo; + DVDFileInfo* fileInfo; - fileInfo = (DVDFileInfo *)((char *)block - offsetof(DVDFileInfo, cb)); + fileInfo = (DVDFileInfo*)((char*)block - offsetof(DVDFileInfo, cb)); if (fileInfo->callback) { @@ -448,18 +450,17 @@ static void cbForSeekAsync(s32 result, DVDCommandBlock *block) } } /* This is based on the revolution SDK, these may not match in all cases */ -s32 DVDSeekPrio(DVDFileInfo *fileInfo, s32 offset, s32 prio) +s32 DVDSeekPrio(DVDFileInfo* fileInfo, s32 offset, s32 prio) { BOOL result; - DVDCommandBlock *block; + DVDCommandBlock* block; s32 state; BOOL enabled; s32 retVal; block = &(fileInfo->cb); - result = - DVDSeekAbsAsyncPrio(block, (s32)(fileInfo->startAddr + offset), cbForSeekSync, prio); + result = DVDSeekAbsAsyncPrio(block, (s32)(fileInfo->startAddr + offset), cbForSeekSync, prio); if (result == FALSE) { @@ -470,7 +471,7 @@ s32 DVDSeekPrio(DVDFileInfo *fileInfo, s32 offset, s32 prio) while (1) { - state = ((volatile DVDCommandBlock *)block)->state; + state = ((volatile DVDCommandBlock*)block)->state; if (state == DVD_STATE_END) { @@ -495,18 +496,20 @@ s32 DVDSeekPrio(DVDFileInfo *fileInfo, s32 offset, s32 prio) return retVal; } /* This is based on the revolution SDK, these may not match in all cases */ -static void cbForSeekSync(s32 result, DVDCommandBlock *block) { OSWakeupThread(&__DVDThreadQueue); } +static void cbForSeekSync(s32 result, DVDCommandBlock* block) +{ + OSWakeupThread(&__DVDThreadQueue); +} /* This is based on the revolution SDK, these may not match in all cases */ -s32 DVDGetFileInfoStatus(DVDFileInfo *fileInfo) +s32 DVDGetFileInfoStatus(DVDFileInfo* fileInfo) { return DVDGetCommandBlockStatus(&fileInfo->cb); } /* This is based on the revolution SDK, these may not match in all cases */ -BOOL DVDFastOpenDir(s32 entrynum, DVDDir *dir) +BOOL DVDFastOpenDir(s32 entrynum, DVDDir* dir) { - if ((entrynum < 0) || (entrynum >= MaxEntryNum) || !entryIsDir(entrynum)) { return FALSE; @@ -520,7 +523,7 @@ BOOL DVDFastOpenDir(s32 entrynum, DVDDir *dir) } /* This is based on the revolution SDK, these may not match in all cases */ -BOOL DVDOpenDir(char *dirName, DVDDir *dir) +BOOL DVDOpenDir(char* dirName, DVDDir* dir) { s32 entry; char currentDir[128]; @@ -545,7 +548,7 @@ BOOL DVDOpenDir(char *dirName, DVDDir *dir) return TRUE; } -BOOL DVDReadDir(DVDDir *dir, DVDDirEntry *dirent) +BOOL DVDReadDir(DVDDir* dir, DVDDirEntry* dirent) { u32 loc = dir->location; if ((loc <= dir->entryNum) || (dir->next <= loc)) @@ -561,18 +564,27 @@ BOOL DVDReadDir(DVDDir *dir, DVDDirEntry *dirent) } /* This is based on the revolution SDK, these may not match in all cases */ -BOOL DVDCloseDir(DVDDir *dir) { return TRUE; } +BOOL DVDCloseDir(DVDDir* dir) +{ + return TRUE; +} /* This is based on the revolution SDK, these may not match in all cases */ -void DVDRewindDir(DVDDir *dir) { dir->location = dir->entryNum + 1; } +void DVDRewindDir(DVDDir* dir) +{ + dir->location = dir->entryNum + 1; +} /* This is based on the revolution SDK, these may not match in all cases */ -void *DVDGetFSTLocation(void) { return BootInfo->FSTLocation; } +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) +BOOL DVDPrepareStreamAsync(DVDFileInfo* fileInfo, u32 length, u32 offset, DVDCallback callback) { u32 start; @@ -580,10 +592,11 @@ BOOL DVDPrepareStreamAsync(DVDFileInfo *fileInfo, u32 length, u32 offset, DVDCal if (!Is32KBAligned(start)) { - OSPanic(__FILE__, 1189, - "DVDPrepareStreamAsync(): Specified start address (filestart(0x%x) + offset(0x%x)) is " - "not 32KB aligned", - fileInfo->startAddr, offset); + OSPanic( + __FILE__, 1189, + "DVDPrepareStreamAsync(): Specified start address (filestart(0x%x) + offset(0x%x)) is " + "not 32KB aligned", + fileInfo->startAddr, offset); } if (length == 0) @@ -591,17 +604,19 @@ BOOL DVDPrepareStreamAsync(DVDFileInfo *fileInfo, u32 length, u32 offset, DVDCal if (!Is32KBAligned(length)) { - OSPanic(__FILE__, 1199, - "DVDPrepareStreamAsync(): Specified length (0x%x) is not a multiple of 32768(32*1024)", - length); + OSPanic( + __FILE__, 1199, + "DVDPrepareStreamAsync(): Specified length (0x%x) is not a multiple of 32768(32*1024)", + length); } if (!((offset < fileInfo->length) && (offset + length <= fileInfo->length))) { - OSPanic(__FILE__, 1207, - "DVDPrepareStreamAsync(): The area specified (offset(0x%x), length(0x%x)) is out of " - "the file", - offset, length); + OSPanic( + __FILE__, 1207, + "DVDPrepareStreamAsync(): The area specified (offset(0x%x), length(0x%x)) is out of " + "the file", + offset, length); } fileInfo->callback = callback; @@ -609,11 +624,11 @@ BOOL DVDPrepareStreamAsync(DVDFileInfo *fileInfo, u32 length, u32 offset, DVDCal cbForPrepareStreamAsync); } -static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock *block) +static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock* block) { - DVDFileInfo *fileInfo; + DVDFileInfo* fileInfo; - fileInfo = (DVDFileInfo *)((char *)block - offsetof(DVDFileInfo, cb)); + fileInfo = (DVDFileInfo*)((char*)block - offsetof(DVDFileInfo, cb)); if (fileInfo->callback) { @@ -622,10 +637,10 @@ static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock *block) } /* This is based on the revolution SDK, these may not match in all cases */ -s32 DVDPrepareStream(DVDFileInfo *fileInfo, u32 length, u32 offset) +s32 DVDPrepareStream(DVDFileInfo* fileInfo, u32 length, u32 offset) { BOOL result; - DVDCommandBlock *block; + DVDCommandBlock* block; s32 state; BOOL enabled; s32 retVal; @@ -634,10 +649,11 @@ s32 DVDPrepareStream(DVDFileInfo *fileInfo, u32 length, u32 offset) if (!Is32KBAligned(start)) { - OSPanic(__FILE__, 0, - "DVDPrepareStream(): Specified start address (filestart(0x%x) + offset(0x%x)) is not " - "32KB aligned", - fileInfo->startAddr, offset); + OSPanic( + __FILE__, 0, + "DVDPrepareStream(): Specified start address (filestart(0x%x) + offset(0x%x)) is not " + "32KB aligned", + fileInfo->startAddr, offset); } if (length == 0) @@ -670,7 +686,7 @@ s32 DVDPrepareStream(DVDFileInfo *fileInfo, u32 length, u32 offset) while (1) { - state = ((volatile DVDCommandBlock *)block)->state; + state = ((volatile DVDCommandBlock*)block)->state; if (state == DVD_STATE_END) { @@ -696,16 +712,16 @@ s32 DVDPrepareStream(DVDFileInfo *fileInfo, u32 length, u32 offset) } /* This is based on the revolution SDK, these may not match in all cases */ -static void cbForPrepareStreamSync(s32 result, DVDCommandBlock *block) +static void cbForPrepareStreamSync(s32 result, DVDCommandBlock* block) { OSWakeupThread(&__DVDThreadQueue); } /* This is based on the revolution SDK, these may not match in all cases */ -s32 DVDGetTransferredSize(DVDFileInfo *fileinfo) +s32 DVDGetTransferredSize(DVDFileInfo* fileinfo) { s32 bytes; - DVDCommandBlock *cb; + DVDCommandBlock* cb; cb = &(fileinfo->cb); diff --git a/libs/dolphin/dvd/dvdlow.c b/libs/dolphin/dvd/dvdlow.c index c09c54eb9..3c2aab44b 100644 --- a/libs/dolphin/dvd/dvdlow.c +++ b/libs/dolphin/dvd/dvdlow.c @@ -19,7 +19,7 @@ static vu32 NextCommandNumber = 0; typedef struct DVDBuffer { - void *addr; + void* addr; u32 length; u32 offset; } DVDBuffer; @@ -27,7 +27,7 @@ typedef struct DVDBuffer typedef struct DVDCommand { s32 cmd; - void *addr; + void* addr; u32 length; u32 offset; DVDLowCallback callback; @@ -48,7 +48,7 @@ void __DVDInitWA() OSInitAlarm(); } -static void Read(void *addr, u32 length, u32 offset, DVDLowCallback callback); +static void Read(void* addr, u32 length, u32 offset, DVDLowCallback callback); static BOOL ProcessNextCommand() { @@ -72,7 +72,7 @@ static BOOL ProcessNextCommand() return FALSE; } -void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext *context) +void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext* context) { DVDLowCallback cb; OSContext exceptionContext; @@ -195,13 +195,13 @@ void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext *context) OSSetCurrentContext(context); } -static void AlarmHandler(OSAlarm *alarm, OSContext *context) +static void AlarmHandler(OSAlarm* alarm, OSContext* context) { BOOL error = ProcessNextCommand(); ASSERTMSG(error != FALSE, "Failed assertion processed"); } -static void AlarmHandlerForTimeout(OSAlarm *alarm, OSContext *context) +static void AlarmHandlerForTimeout(OSAlarm* alarm, OSContext* context) { OSContext tmpContext; DVDLowCallback callback; @@ -224,7 +224,7 @@ static void SetTimeoutAlarm(OSTime timeout) OSSetAlarm(&AlarmForTimeout, timeout, AlarmHandlerForTimeout); } -static void Read(void *addr, u32 length, u32 offset, DVDLowCallback callback) +static void Read(void* addr, u32 length, u32 offset, DVDLowCallback callback) { StopAtNextInt = FALSE; LastCommandWasRead = TRUE; @@ -249,7 +249,7 @@ static void Read(void *addr, u32 length, u32 offset, DVDLowCallback callback) } } -BOOL HitCache(DVDBuffer *cur, DVDBuffer *prev) +BOOL HitCache(DVDBuffer* cur, DVDBuffer* prev) { u32 uVar1 = (prev->offset + prev->length - 1) >> 15; u32 uVar2 = (cur->offset >> 15); @@ -262,14 +262,14 @@ BOOL HitCache(DVDBuffer *cur, DVDBuffer *prev) return FALSE; } -static void DoJustRead(void *addr, u32 length, u32 offset, DVDLowCallback callback) +static void DoJustRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { CommandList[0].cmd = -1; NextCommandNumber = 0; Read(addr, length, offset, callback); } -static void SeekTwiceBeforeRead(void *addr, u32 length, u32 offset, DVDLowCallback callback) +static void SeekTwiceBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { u32 newOffset = offset & ~0x7FFF; if (!newOffset) @@ -293,7 +293,7 @@ static void SeekTwiceBeforeRead(void *addr, u32 length, u32 offset, DVDLowCallba DVDLowSeek(newOffset, callback); } -static void WaitBeforeRead(void *addr, u32 length, u32 offset, DVDLowCallback callback, +static void WaitBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback, OSTime timeout) { CommandList[0].cmd = 1; @@ -307,7 +307,7 @@ static void WaitBeforeRead(void *addr, u32 length, u32 offset, DVDLowCallback ca OSSetAlarm(&AlarmForWA, timeout, AlarmHandler); } -BOOL DVDLowRead(void *addr, u32 length, u32 offset, DVDLowCallback callback) +BOOL DVDLowRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { OSTime diff; u32 prev; @@ -346,7 +346,8 @@ BOOL DVDLowRead(void *addr, u32 length, u32 offset, DVDLowCallback callback) else { WaitBeforeRead(addr, length, offset, callback, - OSMillisecondsToTicks(5) - diff + OSMicrosecondsToTicks(500)); + OSMillisecondsToTicks(5) - diff + + OSMicrosecondsToTicks(500)); } } else @@ -380,7 +381,7 @@ BOOL DVDLowWaitCoverClose(DVDLowCallback callback) return TRUE; } -BOOL DVDLowReadDiskID(DVDDiskID *diskID, DVDLowCallback callback) +BOOL DVDLowReadDiskID(DVDDiskID* diskID, DVDLowCallback callback) { StopAtNextInt = FALSE; Callback = callback; @@ -414,7 +415,7 @@ BOOL DVDLowRequestError(DVDLowCallback callback) return TRUE; } -BOOL DVDLowInquiry(DVDDriveInfo *info, DVDLowCallback callback) +BOOL DVDLowInquiry(DVDDriveInfo* info, DVDLowCallback callback) { StopAtNextInt = FALSE; Callback = callback; @@ -503,11 +504,14 @@ void __DVDLowSetWAType(u32 type, u32 location) OSRestoreInterrupts(enabled); } -BOOL __DVDLowTestAlarm(OSAlarm *alarm) { - if(alarm == &AlarmForBreak) { +BOOL __DVDLowTestAlarm(OSAlarm* alarm) +{ + if (alarm == &AlarmForBreak) + { return TRUE; } - if(alarm == &AlarmForTimeout) { + if (alarm == &AlarmForTimeout) + { return TRUE; } diff --git a/libs/dolphin/dvd/dvdqueue.c b/libs/dolphin/dvd/dvdqueue.c index 54851a3c3..62f6a1c5c 100644 --- a/libs/dolphin/dvd/dvdqueue.c +++ b/libs/dolphin/dvd/dvdqueue.c @@ -3,8 +3,8 @@ #define MAX_QUEUES 4 typedef struct { - DVDCommandBlock *next; - DVDCommandBlock *prev; + DVDCommandBlock* next; + DVDCommandBlock* prev; } DVDQueue; static DVDQueue WaitingQueue[MAX_QUEUES]; @@ -15,22 +15,22 @@ void __DVDClearWaitingQueue(void) for (i = 0; i < MAX_QUEUES; i++) { - DVDCommandBlock *q; + DVDCommandBlock* q; - q = (DVDCommandBlock *)&(WaitingQueue[i]); + q = (DVDCommandBlock*)&(WaitingQueue[i]); q->next = q; q->prev = q; } } -BOOL __DVDPushWaitingQueue(s32 prio, DVDCommandBlock *block) +BOOL __DVDPushWaitingQueue(s32 prio, DVDCommandBlock* block) { BOOL enabled; - DVDCommandBlock *q; + DVDCommandBlock* q; enabled = OSDisableInterrupts(); - q = (DVDCommandBlock *)&(WaitingQueue[prio]); + q = (DVDCommandBlock*)&(WaitingQueue[prio]); q->prev->next = block; block->prev = q->prev; @@ -42,62 +42,76 @@ BOOL __DVDPushWaitingQueue(s32 prio, DVDCommandBlock *block) return TRUE; } -static DVDCommandBlock *PopWaitingQueuePrio(s32 prio) -{ - DVDCommandBlock *tmp; - BOOL enabled; - DVDCommandBlock *q; +// static DVDCommandBlock* PopWaitingQueuePrio(s32 prio) +// { +// DVDCommandBlock* tmp; +// BOOL enabled; +// DVDCommandBlock* q; - enabled = OSDisableInterrupts(); +// enabled = OSDisableInterrupts(); - q = (DVDCommandBlock *)&(WaitingQueue[prio]); +// q = (DVDCommandBlock*)&(WaitingQueue[prio]); - tmp = q->next; - q->next = tmp->next; - tmp->next->prev = q; +// tmp = q->next; +// q->next = tmp->next; +// tmp->next->prev = q; - OSRestoreInterrupts(enabled); +// OSRestoreInterrupts(enabled); - tmp->next = (DVDCommandBlock *)NULL; - tmp->prev = (DVDCommandBlock *)NULL; +// tmp->next = (DVDCommandBlock*)NULL; +// tmp->prev = (DVDCommandBlock*)NULL; - return tmp; -} +// return tmp; +// } -DVDCommandBlock *__DVDPopWaitingQueue(void) +DVDCommandBlock* __DVDPopWaitingQueue(void) { u32 i; BOOL enabled; - DVDCommandBlock *q; + DVDCommandBlock* q; + DVDCommandBlock* tmp; enabled = OSDisableInterrupts(); for (i = 0; i < MAX_QUEUES; i++) { - q = (DVDCommandBlock *)&(WaitingQueue[i]); + q = (DVDCommandBlock*)&(WaitingQueue[i]); if (q->next != q) { OSRestoreInterrupts(enabled); - return PopWaitingQueuePrio((s32)i); + enabled = OSDisableInterrupts(); + + q = (DVDCommandBlock*)&(WaitingQueue[i]); + + tmp = q->next; + q->next = tmp->next; + tmp->next->prev = q; + + OSRestoreInterrupts(enabled); + + tmp->next = (DVDCommandBlock*)NULL; + tmp->prev = (DVDCommandBlock*)NULL; + + return tmp; } } OSRestoreInterrupts(enabled); - return (DVDCommandBlock *)NULL; + return (DVDCommandBlock*)NULL; } BOOL __DVDCheckWaitingQueue(void) { u32 i; BOOL enabled; - DVDCommandBlock *q; + DVDCommandBlock* q; enabled = OSDisableInterrupts(); for (i = 0; i < MAX_QUEUES; i++) { - q = (DVDCommandBlock *)&(WaitingQueue[i]); + q = (DVDCommandBlock*)&(WaitingQueue[i]); if (q->next != q) { OSRestoreInterrupts(enabled); @@ -110,18 +124,18 @@ BOOL __DVDCheckWaitingQueue(void) return FALSE; } -BOOL __DVDDequeueWaitingQueue(DVDCommandBlock *block) +BOOL __DVDDequeueWaitingQueue(DVDCommandBlock* block) { BOOL enabled; - DVDCommandBlock *prev; - DVDCommandBlock *next; + DVDCommandBlock* prev; + DVDCommandBlock* next; enabled = OSDisableInterrupts(); prev = block->prev; next = block->next; - if ((prev == (DVDCommandBlock *)NULL) || (next == (DVDCommandBlock *)NULL)) + if ((prev == (DVDCommandBlock*)NULL) || (next == (DVDCommandBlock*)NULL)) { OSRestoreInterrupts(enabled); return FALSE; @@ -135,25 +149,25 @@ BOOL __DVDDequeueWaitingQueue(DVDCommandBlock *block) return TRUE; } -BOOL __DVDIsBlockInWaitingQueue(DVDCommandBlock *block) -{ - u32 i; - DVDCommandBlock *start; - DVDCommandBlock *q; - - for (i = 0; i < MAX_QUEUES; i++) - { - start = (DVDCommandBlock *)&(WaitingQueue[i]); - - if (start->next != start) - { - for (q = start->next; q != start; q = q->next) - { - if (q == block) - return TRUE; - } - } - } - - return FALSE; -} \ No newline at end of file +// BOOL __DVDIsBlockInWaitingQueue(DVDCommandBlock *block) +// { +// u32 i; +// DVDCommandBlock *start; +// DVDCommandBlock *q; + +// for (i = 0; i < MAX_QUEUES; i++) +// { +// start = (DVDCommandBlock *)&(WaitingQueue[i]); + +// if (start->next != start) +// { +// for (q = start->next; q != start; q = q->next) +// { +// if (q == block) +// return TRUE; +// } +// } +// } + +// return FALSE; +// } \ No newline at end of file diff --git a/libs/dolphin/exi/EXIBios.c b/libs/dolphin/exi/EXIBios.c index 66653a0a9..3b50ca02d 100644 --- a/libs/dolphin/exi/EXIBios.c +++ b/libs/dolphin/exi/EXIBios.c @@ -1,7 +1,7 @@ #include "dolphin/os.h" #include "dolphin/hw_regs.h" -static const char *__EXIVersion = +static const char* __EXIVersion = "<< Dolphin SDK - EXI\trelease build: Apr 17 2003 12:33:17 (0x2301) >>"; #define MAX_DEV 3 @@ -18,7 +18,7 @@ static const char *__EXIVersion = #define STATE_ATTACHED 0x08 #define STATE_LOCKED 0x10 -#define EXI_0CR(tstart, dma, rw, tlen) \ +#define EXI_0CR(tstart, dma, rw, tlen) \ ((((u32)(tstart)) << 0) | (((u32)(dma)) << 1) | (((u32)(rw)) << 2) | (((u32)(tlen)) << 4)) #define CPR_CS(x) ((1u << (x)) << 7) @@ -31,7 +31,7 @@ typedef struct EXIControl EXICallback extCallback; vu32 state; int immLen; - u8 *immBuf; + u8* immBuf; u32 dev; u32 id; s32 idTime; @@ -49,9 +49,9 @@ s32 __EXIProbeStartTime[2] : (OS_BASE_CACHED | 0x30C0); #pragma scheduling off -static void SetExiInterruptMask(s32 chan, EXIControl *exi) +static void SetExiInterruptMask(s32 chan, EXIControl* exi) { - EXIControl *exi2; + EXIControl* exi2; exi2 = &Ecb[2]; switch (chan) @@ -91,8 +91,8 @@ static void SetExiInterruptMask(s32 chan, EXIControl *exi) static void CompleteTransfer(s32 chan) { - EXIControl *exi = &Ecb[chan]; - u8 *buf; + EXIControl* exi = &Ecb[chan]; + u8* buf; u32 data; int i; int len; @@ -112,9 +112,9 @@ static void CompleteTransfer(s32 chan) } } -BOOL EXIImm(s32 chan, void *buf, s32 len, u32 type, EXICallback callback) +BOOL EXIImm(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL enabled; enabled = OSDisableInterrupts(); @@ -141,7 +141,7 @@ BOOL EXIImm(s32 chan, void *buf, s32 len, u32 type, EXICallback callback) data = 0; for (i = 0; i < len; i++) { - data |= ((u8 *)buf)[i] << ((3 - i) * 8); + data |= ((u8*)buf)[i] << ((3 - i) * 8); } REG(chan, 4) = data; } @@ -156,7 +156,7 @@ BOOL EXIImm(s32 chan, void *buf, s32 len, u32 type, EXICallback callback) return TRUE; } -BOOL EXIImmEx(s32 chan, void *buf, s32 len, u32 mode) +BOOL EXIImmEx(s32 chan, void* buf, s32 len, u32 mode) { s32 xLen; @@ -173,15 +173,15 @@ BOOL EXIImmEx(s32 chan, void *buf, s32 len, u32 mode) return FALSE; } - (u8 *)buf += xLen; + (u8*)buf += xLen; len -= xLen; } return TRUE; } -BOOL EXIDma(s32 chan, void *buf, s32 len, u32 type, EXICallback callback) +BOOL EXIDma(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL enabled; enabled = OSDisableInterrupts(); @@ -215,7 +215,7 @@ vu16 __OSDeviceCode : (OS_BASE_CACHED | 0x30E6); BOOL EXISync(s32 chan) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL rc = FALSE; BOOL enabled; @@ -227,8 +227,9 @@ BOOL EXISync(s32 chan) if (exi->state & STATE_SELECTED) { CompleteTransfer(chan); - if (__OSGetDIConfig() != 0xff || ((OSGetConsoleType() & OS_CONSOLE_MASK) == OS_CONSOLE_TDEV) || exi->immLen != 4 || - (REG(chan, 0) & 0x00000070) != (EXI_FREQ_1M << 4) || + if (__OSGetDIConfig() != 0xff || + ((OSGetConsoleType() & OS_CONSOLE_MASK) == OS_CONSOLE_TDEV) || + 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) @@ -262,7 +263,7 @@ u32 EXIClearInterrupts(s32 chan, BOOL exi, BOOL tc, BOOL ext) EXICallback EXISetExiCallback(s32 chan, EXICallback exiCallback) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; EXICallback prev; BOOL enabled; @@ -283,17 +284,9 @@ EXICallback EXISetExiCallback(s32 chan, EXICallback exiCallback) return prev; } -void EXIProbeReset(void) -{ - __EXIProbeStartTime[0] = __EXIProbeStartTime[1] = 0; - Ecb[0].idTime = Ecb[1].idTime = 0; - __EXIProbe(0); - __EXIProbe(1); -} - static BOOL __EXIProbe(s32 chan) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL enabled; BOOL rc; u32 cpr; @@ -345,7 +338,7 @@ static BOOL __EXIProbe(s32 chan) BOOL EXIProbe(s32 chan) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL rc; u32 id; @@ -375,7 +368,7 @@ s32 EXIProbeEx(s32 chan) static BOOL __EXIAttach(s32 chan, EXICallback extCallback) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL enabled; enabled = OSDisableInterrupts(); @@ -397,7 +390,7 @@ static BOOL __EXIAttach(s32 chan, EXICallback extCallback) BOOL EXIAttach(s32 chan, EXICallback extCallback) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL enabled; BOOL rc; @@ -416,7 +409,7 @@ BOOL EXIAttach(s32 chan, EXICallback extCallback) BOOL EXIDetach(s32 chan) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL enabled; enabled = OSDisableInterrupts(); @@ -439,7 +432,7 @@ BOOL EXIDetach(s32 chan) BOOL EXISelect(s32 chan, u32 dev, u32 freq) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; u32 cpr; BOOL enabled; @@ -477,7 +470,7 @@ BOOL EXISelect(s32 chan, u32 dev, u32 freq) BOOL EXIDeselect(s32 chan) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; u32 cpr; BOOL enabled; @@ -514,10 +507,10 @@ BOOL EXIDeselect(s32 chan) return TRUE; } -static void EXIIntrruptHandler(__OSInterrupt interrupt, OSContext *context) +static void EXIIntrruptHandler(__OSInterrupt interrupt, OSContext* context) { s32 chan; - EXIControl *exi; + EXIControl* exi; EXICallback callback; chan = (interrupt - __OS_INTERRUPT_EXI_0_EXI) / 3; @@ -538,11 +531,11 @@ static void EXIIntrruptHandler(__OSInterrupt interrupt, OSContext *context) } } -static void TCIntrruptHandler(__OSInterrupt interrupt, OSContext *context) +static void TCIntrruptHandler(__OSInterrupt interrupt, OSContext* context) { OSContext exceptionContext; s32 chan; - EXIControl *exi; + EXIControl* exi; EXICallback callback; chan = (interrupt - __OS_INTERRUPT_EXI_0_TC) / 3; @@ -565,10 +558,10 @@ static void TCIntrruptHandler(__OSInterrupt interrupt, OSContext *context) } } -static void EXTIntrruptHandler(__OSInterrupt interrupt, OSContext *context) +static void EXTIntrruptHandler(__OSInterrupt interrupt, OSContext* context) { s32 chan; - EXIControl *exi; + EXIControl* exi; EXICallback callback; chan = (interrupt - __OS_INTERRUPT_EXI_0_EXT) / 3; @@ -594,12 +587,15 @@ static void EXTIntrruptHandler(__OSInterrupt interrupt, OSContext *context) void EXIInit(void) { u32 id; - while (((REG(0, 3) & 0x1) == 1) || ((REG(1, 3) & 0x1) == 1) || ((REG(2, 3) & 0x1) == 1)) { + while (((REG(0, 3) & 0x1) == 1) || ((REG(1, 3) & 0x1) == 1) || ((REG(2, 3) & 0x1) == 1)) + { continue; } - __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); + __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_0_TC | + OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_1_EXI | + OS_INTERRUPTMASK_EXI_1_TC | OS_INTERRUPTMASK_EXI_1_EXT | + OS_INTERRUPTMASK_EXI_2_EXI | OS_INTERRUPTMASK_EXI_2_TC); REG(0, 0) = 0; REG(1, 0) = 0; @@ -618,14 +614,19 @@ void EXIInit(void) EXIGetID(0, 2, &IDSerialPort1); - if (__OSInIPL) { + if (__OSInIPL) + { __EXIProbeStartTime[0] = __EXIProbeStartTime[1] = 0; Ecb[0].idTime = Ecb[1].idTime = 0; __EXIProbe(0); __EXIProbe(1); - } else if (EXIGetID(0, 0, &id) && id == 0x07010000) { + } + else if (EXIGetID(0, 0, &id) && id == 0x07010000) + { __OSEnableBarnacle(1, 0); - } else if (EXIGetID(1, 0, &id) && id == 0x07010000) { + } + else if (EXIGetID(1, 0, &id) && id == 0x07010000) + { __OSEnableBarnacle(0, 2); } @@ -634,7 +635,7 @@ void EXIInit(void) BOOL EXILock(s32 chan, u32 dev, EXICallback unlockedCallback) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL enabled; int i; @@ -669,7 +670,7 @@ BOOL EXILock(s32 chan, u32 dev, EXICallback unlockedCallback) BOOL EXIUnlock(s32 chan) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; BOOL enabled; EXICallback unlockedCallback; @@ -698,12 +699,12 @@ BOOL EXIUnlock(s32 chan) u32 EXIGetState(s32 chan) { - EXIControl *exi = &Ecb[chan]; + EXIControl* exi = &Ecb[chan]; return (u32)exi->state; } -static void UnlockedHandler(s32 chan, OSContext *context) +static void UnlockedHandler(s32 chan, OSContext* context) { u32 id; @@ -719,32 +720,39 @@ s32 EXIGetID(s32 chan, u32 dev, u32* id) BOOL enabled; BOOL interrupt; - if (chan == 0 && dev == 2 && IDSerialPort1) { + if (chan == 0 && dev == 2 && IDSerialPort1) + { *id = IDSerialPort1; return 1; } - if (chan < 2 && dev == 0) { - if (!__EXIProbe(chan)) { + if (chan < 2 && dev == 0) + { + if (!__EXIProbe(chan)) + { return 0; } - if (exi->idTime == __EXIProbeStartTime[chan]) { + if (exi->idTime == __EXIProbeStartTime[chan]) + { *id = exi->id; return exi->idTime; } - if (!__EXIAttach(chan, NULL)) { + if (!__EXIAttach(chan, NULL)) + { return 0; } startTime = __EXIProbeStartTime[chan]; } interrupt = OSDisableInterrupts(); - err = !EXILock(chan, dev, (chan < 2 && dev == 0) ? UnlockedHandler : NULL); - if (!err) { + err = !EXILock(chan, dev, (chan < 2 && dev == 0) ? UnlockedHandler : NULL); + if (!err) + { err = !EXISelect(chan, dev, EXI_FREQ_1M); - if (!err) { + if (!err) + { cmd = 0; err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, NULL); err |= !EXISync(chan); @@ -756,12 +764,14 @@ s32 EXIGetID(s32 chan, u32 dev, u32* id) } OSRestoreInterrupts(interrupt); - if (chan < 2 && dev == 0) { + if (chan < 2 && dev == 0) + { EXIDetach(chan); enabled = OSDisableInterrupts(); err |= (startTime != __EXIProbeStartTime[chan]); - if (!err) { - exi->id = *id; + if (!err) + { + exi->id = *id; exi->idTime = startTime; } OSRestoreInterrupts(enabled); @@ -772,55 +782,10 @@ s32 EXIGetID(s32 chan, u32 dev, u32* id) return err ? 0 : !0; } -s32 EXIGetType(s32 chan, u32 dev, u32 *type) { - u32 _type; - s32 probe; - - probe = EXIGetID(chan, dev, &_type); - if(probe == 0) - return probe; - - switch(_type & 0xffffff00) - { - case 0x4020100: - case 0x4020200: - case 0x4020300: - case 0x4060000: - *type = _type & 0xffffff00; - return probe; - } - - switch(_type & 0xffff0000) - { - case 0: - { - if ((_type & 0x3803)) - break; - - switch (_type & 0xfc) - { - case 4: - case 8: - case 16: - case 32: - case 64: - case 128: - *type = _type & 0xfc; - return probe; - } - break; - } - case 0x5070000: - *type = 0x5070000; - return probe; - } - *type = _type; - return probe; -} - char* EXIGetTypeString(u32 type) { - switch (type) { + switch (type) + { case EXI_MEMORY_CARD_59: return "Memory Card 59"; case EXI_MEMORY_CARD_123: diff --git a/libs/dolphin/exi/EXIUart.c b/libs/dolphin/exi/EXIUart.c index 8e8734a1a..73efc2cef 100644 --- a/libs/dolphin/exi/EXIUart.c +++ b/libs/dolphin/exi/EXIUart.c @@ -8,7 +8,7 @@ static u32 Dev; static u32 Enabled = 0; static u32 BarnacleEnabled = 0; -static BOOL ProbeBarnacle(s32 chan, u32 dev, u32 *revision) +static BOOL ProbeBarnacle(s32 chan, u32 dev, u32* revision) { BOOL err; u32 cmd; @@ -111,8 +111,6 @@ u32 InitializeUART(u32 baudRate) } } -u32 ReadUARTN(void *bytes, unsigned long length) { return 4; } - static int QueueLength(void) { u32 cmd; @@ -131,13 +129,13 @@ static int QueueLength(void) return 16 - (int)((cmd >> 24) & 0xff); } -u32 WriteUARTN(const void *buf, unsigned long len) +u32 WriteUARTN(const void* buf, unsigned long len) { BOOL enabled; u32 cmd; int qLen; long xLen; - char *ptr; + char* ptr; BOOL locked; u32 error; @@ -153,7 +151,7 @@ u32 WriteUARTN(const void *buf, unsigned long len) return 0; } - for (ptr = (char *)buf; ptr - buf < len; ptr++) + for (ptr = (char*)buf; ptr - buf < len; ptr++) { if (*ptr == '\n') *ptr = '\r'; @@ -187,8 +185,8 @@ u32 WriteUARTN(const void *buf, unsigned long len) if (qLen < 4 && qLen < len) break; xLen = (len < 4) ? (long)len : 4; - EXIImm(Chan, (void *)buf, xLen, EXI_WRITE, NULL); - (u8 *)buf += xLen; + EXIImm(Chan, (void*)buf, xLen, EXI_WRITE, NULL); + (u8*)buf += xLen; len -= xLen; qLen -= xLen; EXISync(Chan); diff --git a/libs/dolphin/gx/GXAttr.c b/libs/dolphin/gx/GXAttr.c index e69de29bb..6af279ddd 100644 --- a/libs/dolphin/gx/GXAttr.c +++ b/libs/dolphin/gx/GXAttr.c @@ -0,0 +1,622 @@ +#include +#include + +#include + +#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 = 1; + __GXData->hasBiNrms = 0; + __GXData->nrmType = Type; + } + else + { + __GXData->hasNrms = 0; + } + break; + case GX_VA_NBT: + if (Type != GX_NONE) + { + __GXData->hasBiNrms = 1; + __GXData->hasNrms = 0; + __GXData->nrmType = Type; + } + else + { + __GXData->hasBiNrms = 0; + } + 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 attr, GXAttrType type) +{ + SETVCDATTR(attr, type); + if (__GXData->hasNrms || __GXData->hasBiNrms) + { + SET_REG_FIELD(280, __GXData->vcdLo, 2, 11, __GXData->nrmType); + } + else + { + SET_REG_FIELD(0, __GXData->vcdLo, 2, 11, 0); + } + __GXData->dirtyState |= 8; +} + +void __GXSetVCD(void) +{ + GX_WRITE_SOME_REG4(8, 0x50, __GXData->vcdLo, -12); + GX_WRITE_SOME_REG4(8, 0x60, __GXData->vcdHi, -12); + __GXXfVtxSpecs(); +} + +void __GXCalculateVLim(void) +{ + static u8 tbl1[] = { 0, 4, 1, 2 }; + static u8 tbl2[] = { 0, 8, 1, 2 }; + static u8 tbl3[] = { 0, 12, 1, 2 }; + + GXCompCnt nc = 0; + u32 vlm; + u32 b; + u32 vl; + u32 vh; + u32 va; + + if (__GXData->vNum != 0) + { + vl = __GXData->vcdLo; + vh = __GXData->vcdHi; + va = __GXData->vatA[0]; + nc = GET_REG_FIELD(va, 1, 9); + + 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 + { + b = 1; + } + + 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 GXClearVtxDesc(void) +{ + CHECK_GXBEGIN(543, "GXClearVtxDesc"); + __GXData->vcdLo = 0; + SET_REG_FIELD(0, __GXData->vcdLo, 2, 9, 1); + __GXData->vcdHi = 0; + __GXData->hasNrms = 0; + __GXData->hasBiNrms = 0; + __GXData->dirtyState |= 8; +} + +static inline void SETVAT(u32* va, u32* vb, u32* vc, GXAttr attr, GXCompCnt cnt, GXCompType type, + u8 shft) +{ + switch (attr) + { + case GX_VA_POS: + 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: + 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 + { + SET_REG_FIELD(599, *va, 1, 9, cnt); + SET_REG_FIELD(599, *va, 1, 31, 0); + } + break; + case GX_VA_CLR0: + SET_REG_FIELD(605, *va, 1, 13, cnt); + SET_REG_FIELD(606, *va, 3, 14, type); + break; + case GX_VA_CLR1: + SET_REG_FIELD(609, *va, 1, 0x11, cnt); + SET_REG_FIELD(610, *va, 3, 18, type); + break; + case GX_VA_TEX0: + 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: + 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: + 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: + 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: + 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: + 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: + 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: + 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; + } +} + +void GXSetVtxAttrFmt(GXVtxFmt vtxfmt, GXAttr attr, GXCompCnt cnt, GXCompType type, u8 frac) +{ + u32* va; + u32* vb; + u32* vc; + + //CHECK_GXBEGIN(666, "GXSetVtxAttrFmt"); + //CHECK_VTXFMT(667, vtxfmt); + //CHECK_ATTRNAME4(671, attr); + //CHECK_FRAC(672, frac); + + 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); +} + +void GXSetVtxAttrFmtv(GXVtxFmt vtxfmt, const GXVtxAttrFmtList* list) +{ + u32* va; + u32* vb; + u32* vc; + + va = &__GXData->vatA[vtxfmt]; + vb = &__GXData->vatB[vtxfmt]; + vc = &__GXData->vatC[vtxfmt]; + + while (list->attr != GX_VA_NULL) + { + 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 |= 0x10; + __GXData->dirtyVAT |= (u8)(1 << (u8)vtxfmt); +} + +void __GXSetVAT(void) +{ + s32 i; + u32 dirty = __GXData->dirtyVAT; + + i = 0; + do + { + 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); + } + + dirty >>= 1; + i++; + } while (dirty != 0); + + __GXData->dirtyVAT = 0; +} + +static inline u8 GetFracForNrm(GXCompType type) +{ + u8 frac; + + switch (type) + { + case GX_S8: + frac = 6; + break; + case GX_S16: + frac = 14; + break; + default: + case GX_U16: + frac = 0; + break; + } + + return frac; +} + +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: + 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(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: + 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 + { + SET_REG_FIELD(0, reg, 3, 4, 3); + } + SET_REG_FIELD(0, reg, 5, 7, 2); + break; + default: + //ASSERTMSGLINE(1113, 0, "GXSetTexCoordGen: Invalid function"); + break; + } + + GX_WRITE_XF_REG(dst_coord + 0x40, reg); + reg = 0; + 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); + + 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; + } + + mtxIdAttr = dst_coord + 1; + __GXSetMatrixIndex(mtxIdAttr); +} + +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/libs/dolphin/gx/GXBump.c b/libs/dolphin/gx/GXBump.c index e69de29bb..bf02bbbba 100644 --- a/libs/dolphin/gx/GXBump.c +++ b/libs/dolphin/gx/GXBump.c @@ -0,0 +1,207 @@ +#include +#include + +#include + +#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 + +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; +} + +void GXSetIndTexMtx(GXIndTexMtxID mtx_id, const f32 offset[2][3], s8 scale_exp) +{ + s32 mtx[6]; + u32 reg; + u32 id; + + CHECK_GXBEGIN(186, "GXSetIndTexMtx"); + + switch (mtx_id) + { + case GX_ITM_0: + case GX_ITM_1: + case GX_ITM_2: + id = mtx_id - 1; + break; + case GX_ITM_S0: + case GX_ITM_S1: + case GX_ITM_S2: + id = mtx_id - 5; + break; + case GX_ITM_T0: + case GX_ITM_T1: + case GX_ITM_T2: + id = mtx_id - 9; + break; + default: + id = 0; + break; + } + + 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); + + 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); + + 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; +} + +void GXSetIndTexCoordScale(GXIndTexStageID ind_state, GXIndTexScale scale_s, GXIndTexScale scale_t) +{ + CHECK_GXBEGIN(249, "GXSetIndTexScale"); + + switch (ind_state) + { + case GX_INDTEXSTAGE0: + 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: + 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: + 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: + 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: + + break; + } + __GXData->bpSentNot = 0; +} + +void GXSetIndTexOrder(GXIndTexStageID ind_stage, GXTexCoordID tex_coord, GXTexMapID tex_map) +{ + CHECK_GXBEGIN(302, "GXSetIndTexOrder"); + + if (tex_map == GX_TEXMAP_NULL) + { + tex_map = GX_TEXMAP0; + } + + if (tex_coord == GX_TEXCOORD_NULL) + { + tex_coord = GX_TEXCOORD0; + } + + switch (ind_stage) + { + case GX_INDTEXSTAGE0: + SET_REG_FIELD(319, __GXData->iref, 3, 0, tex_map); + SET_REG_FIELD(320, __GXData->iref, 3, 3, tex_coord); + break; + case GX_INDTEXSTAGE1: + SET_REG_FIELD(323, __GXData->iref, 3, 6, tex_map); + SET_REG_FIELD(324, __GXData->iref, 3, 9, tex_coord); + break; + case GX_INDTEXSTAGE2: + SET_REG_FIELD(327, __GXData->iref, 3, 12, tex_map); + SET_REG_FIELD(328, __GXData->iref, 3, 15, tex_coord); + break; + case GX_INDTEXSTAGE3: + SET_REG_FIELD(331, __GXData->iref, 3, 18, tex_map); + SET_REG_FIELD(332, __GXData->iref, 3, 21, tex_coord); + break; + default: + 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"); + + 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 __GXUpdateBPMask(void) +{ +} + +void __GXFlushTextureState(void) +{ + GX_WRITE_SOME_REG5(GX_LOAD_BP_REG, __GXData->bpMask); + __GXData->bpSentNot = 0; +} diff --git a/libs/dolphin/gx/GXDisplayList.c b/libs/dolphin/gx/GXDisplayList.c index e69de29bb..061f9e670 100644 --- a/libs/dolphin/gx/GXDisplayList.c +++ b/libs/dolphin/gx/GXDisplayList.c @@ -0,0 +1,29 @@ +#include + +#include +#include + +#include + +void GXCallDisplayList(const void* list, u32 nbytes) +{ + CHECK_GXBEGIN(254, "GXCallDisplayList"); + + if (__GXData->dirtyState != 0) + { + __GXSetDirtyState(); + } + +#if DEBUG + __GXShadowDispList(list, nbytes); +#endif + + if (*(u32*)&__GXData->vNumNot == 0) + { // checks both vNum and bpSent + __GXSendFlushPrim(); + } + + GX_WRITE_U8(GX_CMD_CALL_DL); + GX_WRITE_U32(list); + GX_WRITE_U32(nbytes); +} diff --git a/libs/dolphin/gx/GXDraw.c b/libs/dolphin/gx/GXDraw.c index e69de29bb..c457eb712 100644 --- a/libs/dolphin/gx/GXDraw.c +++ b/libs/dolphin/gx/GXDraw.c @@ -0,0 +1,571 @@ +#include + +#include +#include + +#include + +static GXVtxDescList vcd[27]; +static GXVtxAttrFmtList vat[27]; + +static void GetVertState(void) +{ + GXGetVtxDescv(vcd); + GXGetVtxAttrFmtv(GX_VTXFMT3, vat); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_NRM, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT3, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0); +} + +static void RestoreVertState(void) +{ + GXSetVtxDescv(vcd); + GXSetVtxAttrFmtv(GX_VTXFMT3, vat); +} + +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) +{ + s32 i; + f32 top; + f32 bottom; + f32 x[100]; + f32 y[100]; + f32 angle; + + top = 1.0f; + bottom = -top; + ASSERTMSGLINE(216, numEdges <= 99, "GXDrawCylinder: too many edges"); + + GetVertState(); + + for (i = 0; i <= numEdges; i++) + { + 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(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, top); + GXNormal3f32(0.0f, 0.0f, 1.0f); + for (i = 0; i <= numEdges; i++) + { + 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, bottom); + GXNormal3f32(0.0f, 0.0f, -1.0f); + for (i = 0; i <= numEdges; i++) + { + GXPosition3f32(x[i], y[i], bottom); + GXNormal3f32(0.0f, 0.0f, -1.0f); + } + GXEnd(); + + RestoreVertState(); +} + +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/libs/dolphin/gx/GXFifo.c b/libs/dolphin/gx/GXFifo.c index e69de29bb..940304938 100644 --- a/libs/dolphin/gx/GXFifo.c +++ b/libs/dolphin/gx/GXFifo.c @@ -0,0 +1,426 @@ +#include +#include +#include +#include + +#include + +static OSThread* __GXCurrentThread; +static GXBool CPGPLinked; +static BOOL GXOverflowSuspendInProgress; +static GXBreakPtCallback BreakPointCB; +static u32 __GXOverflowCount; + +#if DEBUG +static BOOL IsWGPipeRedirected; +#endif + +__GXFifoObj* CPUFifo; +__GXFifoObj* GPFifo; +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(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); +} + +#define SOME_SET_REG_MACRO(reg, size, shift, val) \ + do \ + { \ + (reg) = \ + (u32)__rlwimi((u32)(reg), (val), (shift), (32 - (shift) - (size)), (31 - (shift))); \ + } while (0); + +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 != NULL) + { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + BreakPointCB(); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } +} + +static void GXCPInterruptHandler(__OSInterrupt interrupt, OSContext* context) +{ + __GXData->cpStatus = GX_GET_CP_REG(0); + if (GET_REG_FIELD(__GXData->cpEnable, 1, 3) && GET_REG_FIELD(__GXData->cpStatus, 1, 1)) + { + GXUnderflowHandler(interrupt, context); + } + if (GET_REG_FIELD(__GXData->cpEnable, 1, 2) && GET_REG_FIELD(__GXData->cpStatus, 1, 0)) + { + GXOverflowHandler(interrupt, context); + } + if (GET_REG_FIELD(__GXData->cpEnable, 1, 5) && GET_REG_FIELD(__GXData->cpStatus, 1, 4)) + { + GXBreakPointHandler(interrupt, context); + } +} + +void GXInitFifoBase(GXFifoObj* fifo, void* base, u32 size) +{ + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + + 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); +} + +void GXInitFifoPtrs(GXFifoObj* fifo, void* readPtr, void* writePtr) +{ + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + BOOL enabled; + + enabled = OSDisableInterrupts(); + realFifo->rdPtr = readPtr; + realFifo->wrPtr = writePtr; + realFifo->count = (u8*)writePtr - (u8*)readPtr; + if (realFifo->count < 0) + { + realFifo->count += realFifo->size; + } + OSRestoreInterrupts(enabled); +} + +void GXInitFifoLimits(GXFifoObj* fifo, u32 hiWatermark, u32 loWatermark) +{ + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + + realFifo->hiWatermark = hiWatermark; + realFifo->loWatermark = loWatermark; +} + +#define GX_SET_PI_REG(offset, val) (*(volatile u32*)((volatile u32*)(__piReg) + (offset)) = val) + +// NONMATCHING DEBUG +void GXSetCPUFifo(GXFifoObj* fifo) +{ + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + BOOL enabled = OSDisableInterrupts(); + + CPUFifo = realFifo; + if (CPUFifo == GPFifo) + { + u32 reg = 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); + + CPGPLinked = GX_TRUE; + + __GXWriteFifoIntReset(1, 1); + __GXWriteFifoIntEnable(1, 0); + __GXFifoLink(1); + } + else + { + u32 reg; + + if (CPGPLinked) + { + __GXFifoLink(0); + CPGPLinked = GX_FALSE; + } + + __GXWriteFifoIntEnable(0, 0); + reg = 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(enabled); +} + +void GXSetGPFifo(GXFifoObj* fifo) +{ + __GXFifoObj* realFifo = (__GXFifoObj*)fifo; + BOOL enabled = OSDisableInterrupts(); +#if SDK_REVISION >= 2 + u32 stbtmp; +#endif + + __GXFifoReadDisable(); + __GXWriteFifoIntEnable(0, 0); + GPFifo = realFifo; + + 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) + { + CPGPLinked = GX_TRUE; + __GXWriteFifoIntEnable(1, 0); + __GXFifoLink(1); + } + else + { + CPGPLinked = GX_FALSE; + __GXWriteFifoIntEnable(0, 0); + __GXFifoLink(0); + } + +#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(enabled); +} + +#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 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; + } + } + + *readPtr = realFifo->rdPtr; + *writePtr = realFifo->wrPtr; +} + +GXBreakPtCallback GXSetBreakPtCallback(GXBreakPtCallback cb) +{ + GXBreakPtCallback oldcb = BreakPointCB; + BOOL enabled = OSDisableInterrupts(); + + BreakPointCB = cb; + 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); +} + +void __GXFifoInit(void) +{ + __OSSetInterruptHandler(0x11, GXCPInterruptHandler); + __OSUnmaskInterrupts(0x4000); + __GXCurrentThread = OSGetCurrentThread(); + GXOverflowSuspendInProgress = FALSE; + CPUFifo = NULL; + GPFifo = NULL; +} + +static void __GXFifoReadEnable(void) +{ + SET_REG_FIELD(0, __GXData->cpEnable, 1, 0, 1); + GX_SET_CP_REG(1, __GXData->cpEnable); +} + +static void __GXFifoReadDisable(void) +{ + SET_REG_FIELD(0, __GXData->cpEnable, 1, 0, 0); + GX_SET_CP_REG(1, __GXData->cpEnable); +} + +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); +} + +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); +} + +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); +} + +OSThread* GXSetCurrentGXThread(void) +{ + BOOL enabled; + OSThread* prev; + + enabled = OSDisableInterrupts(); + prev = __GXCurrentThread; + __GXCurrentThread = OSGetCurrentThread(); + OSRestoreInterrupts(enabled); + return prev; +} + +GXFifoObj* GXGetCPUFifo(void) +{ + return (GXFifoObj*)CPUFifo; +} + +GXFifoObj* GXGetGPFifo(void) +{ + return (GXFifoObj*)GPFifo; +} \ No newline at end of file diff --git a/libs/dolphin/gx/GXFrameBuf.c b/libs/dolphin/gx/GXFrameBuf.c index e69de29bb..b6a32d569 100644 --- a/libs/dolphin/gx/GXFrameBuf.c +++ b/libs/dolphin/gx/GXFrameBuf.c @@ -0,0 +1,591 @@ +#include +#include + +#include +#include + +GXRenderModeObj GXNtsc480IntDf = { 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 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 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 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 } }; + +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; + + 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; + + 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_YUVA8: + SET_REG_FIELD(0, __GXData->cpTex, 2, 15, 3); + break; + default: + SET_REG_FIELD(0, __GXData->cpTex, 2, 15, 2); + break; + } + + __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); + + __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); +} + +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); +} + +void GXSetCopyClamp(GXFBClamp clamp) +{ + 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 efbHt, u32 iScale) +{ + u32 count; + u32 realHt; + u32 iScaleD; + + count = (efbHt - 1) * 0x100; + realHt = (count / iScale) + 1; + + iScaleD = iScale; + + if (iScaleD > 0x80 && iScaleD < 0x100) + { + while (iScaleD % 2 == 0) + { + iScaleD /= 2; + } + + if (efbHt % iScaleD == 0) + { + realHt++; + } + } + + if (realHt > 0x400) + { + realHt = 0x400; + } + + return realHt; +} + +f32 GXGetYScaleFactor(u16 efbHeight, u16 xfbHeight) +{ + f32 fScale; + f32 yScale; + u32 iScale; + u32 tgtHt; + u32 realHt; + + 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); + } + + fScale = yScale; + while (realHt < xfbHeight) + { + fScale = yScale; + tgtHt++; + yScale = (f32)tgtHt / (f32)efbHeight; + iScale = (u32)(256.0f / yScale) & 0x1FF; + realHt = __GXGetNumXfbLines(efbHeight, iScale); + } + + return fScale; +} + +u32 GXSetDispCopyYScale(f32 vscale) +{ + u8 enable; + u32 iScale; + u32 ht; + u32 reg; + + 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; + 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); +} + +void GXSetCopyClear(GXColor clear_clr, u32 clear_z) +{ + u32 reg; + + CHECK_GXBEGIN(1596, "GXSetCopyClear"); + //ASSERTMSGLINE(1598, clear_z <= 0xFFFFFF, "GXSetCopyClear: Z clear value is out of range"); + + 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; +} + +void GXCopyTex(void* dest, GXBool clear) +{ + u32 reg; + u32 tempPeCtrl; + u32 phyAddr; + u8 changePeCtrl; + + CHECK_GXBEGIN(1916, "GXCopyTex"); + +#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 = 0; + tempPeCtrl = __GXData->peCtrl; + + if (__GXData->cpTexZ && ((tempPeCtrl & 7) != 3)) + { + changePeCtrl = 1; + SET_REG_FIELD(0, tempPeCtrl, 3, 0, 3); + } + + if ((clear || ((u32)(tempPeCtrl & 7) == 3)) && ((u32)((tempPeCtrl >> 6) & 1) == 1)) + { + changePeCtrl = 1; + SET_REG_FIELD(0, tempPeCtrl, 1, 6, 0); + } + + 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; + SET_REG_FIELD(1965, reg, 21, 0, phyAddr >> 5); + SET_REG_FIELD(1965, reg, 8, 24, 0x4B); + GX_WRITE_RAS_REG(reg); + + 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 (clear) + { + GX_WRITE_RAS_REG(__GXData->zmode); + GX_WRITE_RAS_REG(__GXData->cmode0); + } + + if (changePeCtrl) + { + GX_WRITE_RAS_REG(__GXData->peCtrl); + } + + __GXData->bpSentNot = 0; +} + +void GXClearBoundingBox(void) +{ + u32 reg; + + CHECK_GXBEGIN(2003, "GXClearBoundingBox"); + reg = 0x550003FF; + GX_WRITE_RAS_REG(reg); + reg = 0x560003FF; + GX_WRITE_RAS_REG(reg); + __GXData->bpSentNot = 0; +} \ No newline at end of file diff --git a/libs/dolphin/gx/GXGeometry.c b/libs/dolphin/gx/GXGeometry.c index e69de29bb..a6b7d661c 100644 --- a/libs/dolphin/gx/GXGeometry.c +++ b/libs/dolphin/gx/GXGeometry.c @@ -0,0 +1,192 @@ +#include +#include +#include + +#include + +void __GXSetDirtyState(void) +{ + u32 dState = __GXData->dirtyState; + + if (dState & 1) + { + __GXSetSUTexRegs(); + } + if (dState & 2) + { + __GXUpdateBPMask(); + } + if (dState & 4) + { + __GXSetGenMode(); + } + if (dState & 8) + { + __GXSetVCD(); + } + if (dState & 0x10) + { + __GXSetVAT(); + } + if (dState & 0x18) + { + __GXCalculateVLim(); + } + + __GXData->dirtyState = 0; +} + +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 (__GXData->dirtyState != 0) + { + __GXSetDirtyState(); + } + +#if DEBUG + if (!__GXData->inDispList) + { + __GXVerifyState(vtxfmt); + } + __GXinBegin = 1; +#endif + + if (*(u32*)&__GXData->vNumNot == 0) + { // checks both vNum and bpSentNot + __GXSendFlushPrim(); + } + GX_WRITE_U8(vtxfmt | type); + GX_WRITE_U16(nverts); +} + +void __GXSendFlushPrim(void) +{ + u32 i; + u32 numD = __GXData->vNum * __GXData->vLim; + + GX_WRITE_U8(0x98); + GX_WRITE_U16(__GXData->vNum); + for (i = 0; i < numD; i += 4) + { + GX_WRITE_U32(0); + } + __GXData->bpSentNot = 1; +} + +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; +} + +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/libs/dolphin/gx/GXInit.c b/libs/dolphin/gx/GXInit.c index e69de29bb..86f823eba 100644 --- a/libs/dolphin/gx/GXInit.c +++ b/libs/dolphin/gx/GXInit.c @@ -0,0 +1,562 @@ +#include + +#include +#include +#include +#include + +#include +#include + +#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 + +static GXFifoObj FifoObj; + +static GXData gxData; +GXData* const __GXData = &gxData; + +// these are supposed to be in-function static, but it messed up sbss order +u32 resetFuncRegistered; +u32 calledOnce; +OSTime time; +u32 peCount; + +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 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 (fmt) + { + case GX_TF_RGBA8: + 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 (mm) + { + return &__GXData->TexRegions1[id]; + } + return &__GXData->TexRegions0[id]; + } +} + +static GXTlutRegion* __GXDefaultTlutRegionCallback(u32 idx) +{ + if (idx >= 20) + { + return NULL; + } + return &__GXData->TlutRegions[idx]; +} + +#if DEBUG +static void __GXDefaultVerifyCallback(GXWarningLevel level, u32 id, const char* msg) +{ + OSReport("Level %1d, Warning %3d: %s\n", level, id, msg); +} +#endif + +static int __GXShutdown(BOOL final) +{ + u32 reg; + u32 peCountNew; + OSTime timeNew; + + if (!final) + { + if (!calledOnce) + { + peCount = __GXReadMEMCounterU32(0x28, 0x27); + time = OSGetTime(); + calledOnce = 1; + return 0; + } + + timeNew = OSGetTime(); + peCountNew = __GXReadMEMCounterU32(0x28, 0x27); + + if (timeNew - time < 10) + { + return 0; + } + + if (peCountNew != peCount) + { + peCount = peCountNew; + time = timeNew; + return 0; + } + } + else + { + GXSetBreakPtCallback(NULL); + GXSetDrawSyncCallback(NULL); + GXSetDrawDoneCallback(NULL); + + 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(); + + reg = 0; + GX_SET_CP_REG(1, reg); + + reg = 3; + GX_SET_CP_REG(2, reg); + + __GXData->abtWaitPECopy = 1; + + __GXAbort(); + } + + return 1; +} + +#define SOME_SET_REG_MACRO(reg, size, shift, val) \ + do \ + { \ + (reg) = \ + (u32)__rlwimi((u32)(reg), (val), (shift), (32 - (shift) - (size)), (31 - (shift))); \ + } while (0); + +GXFifoObj* GXInit(void* base, u32 size) +{ + u32 i; + u32 reg; + u32 freqBase; + + OSRegisterVersion(__GXVersion); + + __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 = OSPhysicalToUncached(0xC003000); + __cpReg = OSPhysicalToUncached(0xC000000); + __peReg = OSPhysicalToUncached(0xC001000); + __memReg = OSPhysicalToUncached(0xC004000); + __GXFifoInit(); + GXInitFifoBase(&FifoObj, base, size); + GXSetCPUFifo(&FifoObj); + GXSetGPFifo(&FifoObj); + + if (!resetFuncRegistered) + { + OSRegisterResetFunction(&GXResetFuncInfo); + resetFuncRegistered = 1; + } + + __GXPEInit(); + EnableWriteGatherPipe(); + + __GXData->genMode = 0; + SET_REG_FIELD(0, __GXData->genMode, 8, 24, 0); + __GXData->bpMask = 255; + SET_REG_FIELD(0, __GXData->bpMask, 8, 24, 0x0F); + __GXData->lpSize = 0; + SET_REG_FIELD(0, __GXData->lpSize, 8, 24, 0x22); + + 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; + 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; + SET_REG_FIELD(0, __GXData->iref, 8, 24, 0x27); + + for (i = 0; i < 8; ++i) + { + __GXData->suTs0[i] = 0; + __GXData->suTs1[i] = 0; + SET_REG_FIELD(1144, __GXData->suTs0[i], 8, 24, 0x30 + i * 2); + SET_REG_FIELD(1145, __GXData->suTs1[i], 8, 24, 0x31 + i * 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 = FALSE; + +#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 < 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], + GX_TEXCACHE_32K, GXTexRegionAddrTable[i + 24], GX_TEXCACHE_32K); + GXInitTexCacheRegion(&__GXData->TexRegions2[i], GX_TRUE, GXTexRegionAddrTable[i + 32], + GX_TEXCACHE_32K, GXTexRegionAddrTable[i + 40], GX_TEXCACHE_32K); + } + + for (i = 0; i < 16; i++) + { + GXInitTlutRegion(&__GXData->TlutRegions[i], 0xC0000 + 0x2000 * i, GX_TLUT_256); + } + + for (i = 0; i < 4; i++) + { + GXInitTlutRegion(&__GXData->TlutRegions[i + 16], 0xE0000 + 0x8000 * i, GX_TLUT_1K); + } + + { + u32 reg = 0; +#if DEBUG + s32 regAddr; +#endif + GX_SET_CP_REG(3, reg); + + 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); + + reg = 0x24000000; + GX_WRITE_RAS_REG(reg); + + reg = 0x67000000; + GX_WRITE_RAS_REG(reg); + } + + __GXSetIndirectMask(0); + __GXSetTmemConfig(2); + __GXInitGX(); + + return &FifoObj; +} + +void __GXInitGX(void) +{ + 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: + rmode = &GXNtsc480IntDf; + break; + case VI_PAL: + rmode = &GXPal528IntDf; + break; + case VI_EURGB60: + rmode = &GXEurgb60Hz480IntDf; + break; + case VI_MPAL: + rmode = &GXMpal480IntDf; + break; + default: + //ASSERTMSGLINE(1342, 0, "GXInit: invalid TV format"); + rmode = &GXNtsc480IntDf; + break; + } + + 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(i, __GXData, 0); + } + + 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, 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(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_DISABLE); + GXSetCullMode(GX_CULL_BACK); + GXSetClipMode(GX_CLIP_ENABLE); + GXSetScissor(0, 0, rmode->fbWidth, rmode->efbHeight); + GXSetScissorBoxOffset(0, 0); + GXSetNumChans(0); + 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((GXTexRegionCallback)__GXDefaultTexRegionCallback); + GXSetTlutRegionCallback(__GXDefaultTlutRegionCallback); + + 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); + GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD2, GX_TEXMAP2, GX_COLOR0A0); + GXSetTevOrder(GX_TEVSTAGE3, GX_TEXCOORD3, GX_TEXMAP3, GX_COLOR0A0); + GXSetTevOrder(GX_TEVSTAGE4, GX_TEXCOORD4, GX_TEXMAP4, GX_COLOR0A0); + 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); + GXSetTevOrder(GX_TEVSTAGE11, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE12, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE13, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE14, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE15, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + + 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 = 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); + } + + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_RED, GX_CH_RED, GX_CH_ALPHA); + 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 = GX_TEVSTAGE0; i < GX_MAX_TEVSTAGE; i++) + GXSetTevDirect((GXTevStageID)i); + + GXSetNumIndStages(0); + GXSetIndTexCoordScale(GX_INDTEXSTAGE0, GX_ITS_1, GX_ITS_1); + 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); + + 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_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 : 0)); + + 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(); + + GXPokeColorUpdate(GX_TRUE); + GXPokeAlphaUpdate(GX_TRUE); + GXPokeDither(GX_FALSE); + GXPokeBlendMode(GX_BM_NONE, GX_BL_ZERO, GX_BL_ONE, GX_LO_SET); + GXPokeAlphaMode(GX_ALWAYS, 0); + GXPokeAlphaRead(GX_READ_FF); + GXPokeDstAlpha(GX_DISABLE, 0); + GXPokeZMode(GX_TRUE, GX_ALWAYS, GX_TRUE); + + GXSetGPMetric(GX_PERF0_NONE, GX_PERF1_NONE); + GXClearGPMetric(); +} diff --git a/libs/dolphin/gx/GXLight.c b/libs/dolphin/gx/GXLight.c index e69de29bb..8bc3fb616 100644 --- a/libs/dolphin/gx/GXLight.c +++ b/libs/dolphin/gx/GXLight.c @@ -0,0 +1,457 @@ +#include +#include +#include + +#include + +// 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; + + 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; +} + +void GXInitLightAttnA(GXLightObj* lt_obj, f32 a0, f32 a1, f32 a2) +{ + __GXLightObjInt_struct* obj; + + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(144, "GXInitLightAttnA"); + obj->a[0] = a0; + obj->a[1] = a1; + obj->a[2] = a2; +} + +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: + a0 = -1000.0f * cr; + a1 = 1000.0f; + a2 = 0.0f; + break; + case GX_SP_COS: + a1 = 1.0f / (1.0f - cr); + a0 = -cr * a1; + a2 = 0.0f; + break; + case GX_SP_COS2: + a2 = 1.0f / (1.0f - cr); + a0 = 0.0f; + a1 = -cr * a2; + break; + case GX_SP_SHARP: + 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 - 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 - 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; + } + obj->a[0] = a0; + obj->a[1] = a1; + obj->a[2] = a2; +} + +void GXInitLightDistAttn(GXLightObj* lt_obj, f32 ref_dist, f32 ref_br, GXDistAttnFn dist_func) +{ + f32 k0, k1, k2; + __GXLightObjInt_struct* obj; + + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(275, "GXInitLightDistAttn"); + + 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_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_br * ref_dist * ref_dist); + break; + case GX_DA_STEEP: + k0 = 1.0f; + k1 = 0.0f; + k2 = (1.0f - ref_br) / (ref_br * ref_dist * ref_dist); + break; + case GX_DA_OFF: + default: + k0 = 1.0f; + k1 = 0.0f; + k2 = 0.0f; + break; + } + + obj->k[0] = k0; + obj->k[1] = k1; + obj->k[2] = k2; +} + +void GXInitLightPos(GXLightObj* lt_obj, f32 x, f32 y, f32 z) +{ + __GXLightObjInt_struct* obj; + + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(330, "GXInitLightPos"); + + obj->lpos[0] = x; + obj->lpos[1] = y; + obj->lpos[2] = z; +} + +void GXInitLightDir(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz) +{ + __GXLightObjInt_struct* obj; + + obj = (__GXLightObjInt_struct*)lt_obj; + + obj->ldir[0] = -nx; + obj->ldir[1] = -ny; + obj->ldir[2] = -nz; +} + +void GXInitLightColor(GXLightObj* lt_obj, GXColor color) +{ + __GXLightObjInt_struct* obj; + + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(463, "GXInitLightColor"); + + *(u32*)&obj->Color = *(u32*)&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) +{ + register u32 zero, color; + register f32 a0_a1, a2_k0, k1_k2; + register f32 px_py, pz_dx, dy_dz; +#ifdef __MWERKS__ // clang-format off + asm { + lwz color, 12(lt_obj) + xor zero, zero, zero + psq_l a0_a1, 16(lt_obj), 0, 0 + psq_l a2_k0, 24(lt_obj), 0, 0 + psq_l k1_k2, 32(lt_obj), 0, 0 + psq_l px_py, 40(lt_obj), 0, 0 + psq_l pz_dx, 48(lt_obj), 0, 0 + psq_l dy_dz, 56(lt_obj), 0, 0 + + stw zero, 0(dest) + stw zero, 0(dest) + stw zero, 0(dest) + stw color, 0(dest) + psq_st a0_a1, 0(dest), 0, 0 + psq_st a2_k0, 0(dest), 0, 0 + psq_st k1_k2, 0(dest), 0, 0 + psq_st px_py, 0(dest), 0, 0 + psq_st pz_dx, 0(dest), 0, 0 + psq_st dy_dz, 0(dest), 0, 0 + } +#endif // clang-format on +} + +void GXLoadLightObjImm(GXLightObj* lt_obj, GXLightID light) +{ + u32 addr; + u32 idx; + __GXLightObjInt_struct* obj; + + obj = (__GXLightObjInt_struct*)lt_obj; + CHECK_GXBEGIN(569, "GXLoadLightObjImm"); + +#if DEBUG + idx = ConvLightID2Num(light); +#else + idx = 31 - __cntlzw(light); +#endif + + idx &= 7; + + addr = idx * 0x10 + 0x600; + GX_WRITE_U8(0x10); + GX_WRITE_U32(addr | 0xF0000); + +#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 + + __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]; + 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]; + 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]; + SET_REG_FIELD(696, reg, 8, 0, amb_color.a); + colIdx = 0; + break; + case GX_ALPHA1: + reg = __GXData->ambColor[GX_COLOR1]; + SET_REG_FIELD(702, reg, 8, 0, amb_color.a); + colIdx = 1; + break; + case GX_COLOR0A0: + reg = GXCOLOR_AS_U32(amb_color); + colIdx = 0; + break; + case GX_COLOR1A1: + reg = GXCOLOR_AS_U32(amb_color); + colIdx = 1; + break; + default: + return; + } + + GX_WRITE_XF_REG(colIdx + 10, reg); + __GXData->bpSentNot = 1; + __GXData->ambColor[colIdx] = reg; +} + +void GXSetChanMatColor(GXChannelID chan, GXColor mat_color) +{ + u32 reg; + u32 rgb; + u32 colIdx; + + CHECK_GXBEGIN(762, "GXSetChanMatColor"); + + switch (chan) + { + case GX_COLOR0: + reg = __GXData->matColor[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]; + 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]; + SET_REG_FIELD(797, reg, 8, 0, mat_color.a); + colIdx = 0; + break; + case GX_ALPHA1: + reg = __GXData->matColor[GX_COLOR1]; + SET_REG_FIELD(803, reg, 8, 0, mat_color.a); + colIdx = 1; + break; + case GX_COLOR0A0: + reg = GXCOLOR_AS_U32(mat_color); + colIdx = 0; + break; + case GX_COLOR1A1: + reg = GXCOLOR_AS_U32(mat_color); + colIdx = 1; + break; + default: + return; + } + + GX_WRITE_XF_REG(colIdx + 12, reg); + __GXData->bpSentNot = 1; + __GXData->matColor[colIdx] = reg; +} + +void GXSetNumChans(u8 nChans) +{ + CHECK_GXBEGIN(857, "GXSetNumChans"); + + SET_REG_FIELD(860, __GXData->genMode, 3, 4, nChans); + GX_WRITE_XF_REG(9, nChans); + __GXData->dirtyState |= 4; +} + +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; + + CHECK_GXBEGIN(892, "GXSetChanCtrl"); + +#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 = 1; +} diff --git a/libs/dolphin/gx/GXMisc.c b/libs/dolphin/gx/GXMisc.c index e69de29bb..e3c11f1c5 100644 --- a/libs/dolphin/gx/GXMisc.c +++ b/libs/dolphin/gx/GXMisc.c @@ -0,0 +1,346 @@ +#include +#include +#include +#include +#include + +#include +#include + +static GXDrawSyncCallback TokenCB; +static GXDrawDoneCallback DrawDoneCB; +static u8 DrawDone; +static OSThreadQueue FinishQueue; + +void GXSetMisc(GXMiscToken token, u32 val) +{ + switch (token) + { + case GX_MT_XF_FLUSH: + __GXData->vNum = val; + __GXData->vNumNot = !__GXData->vNum; + __GXData->bpSentNot = 1; + + if (__GXData->vNum != 0) + { + __GXData->dirtyState |= 8; + } + break; + case GX_MT_DL_SAVE_CONTEXT: + __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; + } +} + +void GXFlush(void) +{ + CHECK_GXBEGIN(270, "GXFlush"); + if (__GXData->dirtyState) + { + __GXSetDirtyState(); + } + + 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; + OSTime time1; + + time0 = OSGetTime(); + do + { + time1 = OSGetTime(); + } while (time1 - time0 <= (clocks / 4)); +} + +static void __GXAbortWaitPECopyDone(void) +{ + u32 peCnt0; + u32 peCnt1; + + peCnt0 = __GXReadMEMCounterU32(0x28, 0x27); + do + { + peCnt1 = peCnt0; + __GXAbortWait(32); + + peCnt0 = __GXReadMEMCounterU32(0x28, 0x27); + } while (peCnt0 != peCnt1); +} + +void __GXAbort(void) +{ + if (__GXData->abtWaitPECopy && GXGetGPFifo() != (GXFifoObj*)NULL) + { + __GXAbortWaitPECopyDone(); + } + + __PIRegs[0x18 / 4] = 1; + __GXAbortWait(200); + __PIRegs[0x18 / 4] = 0; + __GXAbortWait(20); +} + +void GXSetDrawSync(u16 token) +{ + BOOL enabled; + u32 reg; + + CHECK_GXBEGIN(430, "GXSetDrawSync"); + + 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; +} + +void GXSetDrawDone(void) +{ + u32 reg; + BOOL enabled; + + CHECK_GXBEGIN(488, "GXSetDrawDone"); + enabled = OSDisableInterrupts(); + reg = 0x45000002; + GX_WRITE_RAS_REG(reg); + GXFlush(); + DrawDone = 0; + OSRestoreInterrupts(enabled); +} + +void GXWaitDrawDone(void) +{ + BOOL enabled; + + CHECK_GXBEGIN(534, "GXWaitDrawDone"); + + enabled = OSDisableInterrupts(); + while (!DrawDone) + { + OSSleepThread(&FinishQueue); + } + OSRestoreInterrupts(enabled); +} + +void GXDrawDone(void) +{ + // GXSetDrawDone uses GXFlush() + // This functions requires less lines in GXFlush + // but then GXFlush doesnt match + CHECK_GXBEGIN(566, "GXDrawDone"); + GXSetDrawDone(); + GXWaitDrawDone(); +} + +void GXPixModeSync(void) +{ + CHECK_GXBEGIN(601, "GXPixModeSync"); + GX_WRITE_RAS_REG(__GXData->peCtrl); + __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); +} + +void GXPokeAlphaRead(GXAlphaReadMode mode) +{ + 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); +} + +void GXPokeAlphaUpdate(GXBool update_enable) +{ + u32 reg; + + reg = GX_GET_PE_REG(1); + SET_REG_FIELD(704, reg, 1, 4, update_enable); + GX_SET_PE_REG(1, reg); +} + +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); +} + +void GXPokeDstAlpha(GXBool enable, u8 alpha) +{ + 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); +} + +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); +} + +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); +} + +GXDrawSyncCallback GXSetDrawSyncCallback(GXDrawSyncCallback cb) +{ + GXDrawSyncCallback oldcb; + BOOL enabled; + + oldcb = TokenCB; + enabled = OSDisableInterrupts(); + TokenCB = cb; + OSRestoreInterrupts(enabled); + return oldcb; +} + +static void GXTokenInterruptHandler(__OSInterrupt interrupt, OSContext* context) +{ + u16 token; + OSContext exceptionContext; + u32 reg; + + token = GX_GET_PE_REG(7); + if (TokenCB != NULL) + { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + TokenCB(token); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } + reg = GX_GET_PE_REG(5); + SET_REG_FIELD(0, reg, 1, 2, 1); + GX_SET_PE_REG(5, reg); +} + +GXDrawDoneCallback GXSetDrawDoneCallback(GXDrawDoneCallback cb) +{ + GXDrawDoneCallback oldcb; + BOOL enabled; + + oldcb = DrawDoneCB; + enabled = OSDisableInterrupts(); + DrawDoneCB = cb; + OSRestoreInterrupts(enabled); + return oldcb; +} + +static void GXFinishInterruptHandler(__OSInterrupt interrupt, OSContext* context) +{ + OSContext exceptionContext; + u32 reg; + + reg = GX_GET_PE_REG(5); + SET_REG_FIELD(0, reg, 1, 3, 1); + GX_SET_PE_REG(5, reg); + DrawDone = 1; + if (DrawDoneCB != NULL) + { + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + DrawDoneCB(); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + } + OSWakeupThread(&FinishQueue); +} + +void __GXPEInit(void) +{ + u32 reg; + __OSSetInterruptHandler(0x12, GXTokenInterruptHandler); + __OSSetInterruptHandler(0x13, GXFinishInterruptHandler); + OSInitThreadQueue(&FinishQueue); + __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); +} diff --git a/libs/dolphin/gx/GXPerf.c b/libs/dolphin/gx/GXPerf.c index e69de29bb..662872553 100644 --- a/libs/dolphin/gx/GXPerf.c +++ b/libs/dolphin/gx/GXPerf.c @@ -0,0 +1,364 @@ +#include +#include +#include + +#include + +void GXSetGPMetric(GXPerf0 perf0, GXPerf1 perf1) +{ + u32 reg; + + CHECK_GXBEGIN(134, "GXSetGPMetric"); + + switch (__GXData->perf0) + { + 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_CLIP_RATIO: + case GX_PERF0_CLOCKS: + reg = 0; + GX_WRITE_XF_REG(6, reg); + break; + 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: + reg = 0x23000000; + GX_WRITE_RAS_REG(reg); + break; + 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: + reg = 0x24000000; + GX_WRITE_RAS_REG(reg); + break; + case GX_PERF0_NONE: + break; + default: + + break; + } + + switch (__GXData->perf1) + { + case GX_PERF1_TEXELS: + case GX_PERF1_TX_IDLE: + case GX_PERF1_TX_REGS: + case GX_PERF1_TX_MEMSTALL: + case GX_PERF1_TC_CHECK1_2: + case GX_PERF1_TC_CHECK3_4: + case GX_PERF1_TC_CHECK5_6: + case GX_PERF1_TC_CHECK7_8: + case GX_PERF1_TC_MISS: + case GX_PERF1_CLOCKS: + 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: + 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: + 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: + reg = 0; + GX_SET_CP_REG(3, reg); + break; + case GX_PERF1_NONE: + break; + default: + + break; + } + + __GXData->perf0 = perf0; + switch (__GXData->perf0) + { + case GX_PERF0_VERTICES: + + reg = 0x273; + GX_WRITE_XF_REG(6, reg); + break; + 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: + + break; + } + + __GXData->perf1 = perf1; + switch (__GXData->perf1) + { + 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: + + break; + } + + __GXData->bpSentNot = 0; +} + +void GXClearGPMetric(void) +{ + u32 reg; + + reg = 4; + GX_SET_CP_REG(2, reg); +} diff --git a/libs/dolphin/gx/GXPixel.c b/libs/dolphin/gx/GXPixel.c index e69de29bb..47bb5ebd3 100644 --- a/libs/dolphin/gx/GXPixel.c +++ b/libs/dolphin/gx/GXPixel.c @@ -0,0 +1,321 @@ +#include +#include +#include +#include +#include + +#include + +void GXSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color) +{ + 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; + + fogclr = 0; + fog0 = 0; + fog1 = 0; + fog2 = 0; + fog3 = 0; + + CHECK_GXBEGIN(138, "GXSetFog"); + + 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)); + a = A * (farz - nearz); + c = A * (startz - nearz); + } + } + 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 = 0; + while (B_mant > 1.0) + { + B_mant /= 2.0f; + B_expn++; + } + while (B_mant > 0.0f && B_mant < 0.5) + { + B_mant *= 2.0f; + B_expn--; + } + + a = A / (f32)(1 << (B_expn + 1)); + b_m = 8.388638e6f * B_mant; + b_s = B_expn + 1; + c = C; + + SET_REG_FIELD(198, fog1, 24, 0, b_m); + SET_REG_FIELD(198, fog1, 8, 24, 0xEF); + + SET_REG_FIELD(201, fog2, 5, 0, b_s); + SET_REG_FIELD(201, fog2, 8, 24, 0xF0); + } + + a_hex = *(u32*)&a; + c_hex = *(u32*)&c; + + 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); + + 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)); + + SET_REG_FIELD(217, fog3, 1, 20, proj); + SET_REG_FIELD(218, fog3, 3, 21, fsel); + SET_REG_FIELD(218, fog3, 8, 24, 0xF1); + + rgba = *(u32*)&color; + SET_REG_FIELD(222, fogclr, 24, 0, rgba >> 8); + SET_REG_FIELD(222, fogclr, 8, 24, 0xF2); + + 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; +} + +void GXSetFogRangeAdj(GXBool enable, u16 center, GXFogAdjTable* table) +{ + u32 i; + u32 range_adj; + u32 range_c; + + CHECK_GXBEGIN(331, "GXSetFogRangeAdj"); + + if (enable) + { + for (i = 0; i < 10; i += 2) + { + range_adj = 0; + // complains about r + // 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); + } + } + 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; +} + +void GXSetBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor, + GXLogicOp op) +{ + u32 reg; + u32 blend_en; + + CHECK_GXBEGIN(375, "GXSetBlendMode"); + + 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; +} + +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; +} + +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; +} + +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; +} + +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; +} + +void GXSetPixelFmt(GXPixelFmt pix_fmt, GXZFmt16 z_fmt) +{ + u32 oldPeCtrl; + u8 aa; + static u32 p2f[8] = { 0, 1, 2, 3, 4, 4, 4, 5 }; + + CHECK_GXBEGIN(511, "GXSetPixelFmt"); + oldPeCtrl = __GXData->peCtrl; + + SET_REG_FIELD(517, __GXData->peCtrl, 3, 0, p2f[pix_fmt]); + SET_REG_FIELD(518, __GXData->peCtrl, 3, 3, z_fmt); + + 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[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 = 0; +} + +void GXSetDither(GXBool dither) +{ + 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; +} + +void GXSetDstAlpha(GXBool enable, u8 alpha) +{ + 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; +} + +void GXSetFieldMask(GXBool odd_mask, GXBool even_mask) +{ + u32 reg; + + 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; +} + +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(); + reg = field_mode | 0x68000000; + GX_WRITE_RAS_REG(reg); + __GXFlushTextureState(); +} diff --git a/libs/dolphin/gx/GXSave.c b/libs/dolphin/gx/GXSave.c new file mode 100644 index 000000000..42cb0b664 --- /dev/null +++ b/libs/dolphin/gx/GXSave.c @@ -0,0 +1,601 @@ +#if DEBUG + +#include +#include + +#include + +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/libs/dolphin/gx/GXStubs.c b/libs/dolphin/gx/GXStubs.c new file mode 100644 index 000000000..438c03104 --- /dev/null +++ b/libs/dolphin/gx/GXStubs.c @@ -0,0 +1,7 @@ +#include + +#include + +void __GXSetRange(f32 nearz, f32 fgSideX) +{ +} diff --git a/libs/dolphin/gx/GXTev.c b/libs/dolphin/gx/GXTev.c index e69de29bb..7dc8ae2d9 100644 --- a/libs/dolphin/gx/GXTev.c +++ b/libs/dolphin/gx/GXTev.c @@ -0,0 +1,486 @@ +#include +#include + +#include + +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 +}; + +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 +}; + +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 +}; + +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 +}; + +#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; + + CHECK_GXBEGIN(420, "GXSetTevOp"); + + if (id == GX_TEVSTAGE0) + { + ctmp = (u32*)TEVCOpTableST0 + mode; + atmp = (u32*)TEVAOpTableST0 + mode; + } + else + { + 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"); + + tevReg = __GXData->tevc[stage]; + 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"); + + tevReg = __GXData->teva[stage]; + 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 = 0; +} + +void GXSetTevColorOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, + GXTevRegID out_reg) +{ + u32 tevReg; + + CHECK_GXBEGIN(653, "GXSetTevColorOp"); + + tevReg = __GXData->tevc[stage]; + SET_REG_FIELD(663, tevReg, 1, 18, op & 1); + if (op <= 1) + { + SET_REG_FIELD(665, tevReg, 2, 20, scale); + SET_REG_FIELD(666, tevReg, 2, 16, bias); + } + else + { + 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); + + GX_WRITE_RAS_REG(tevReg); + __GXData->tevc[stage] = tevReg; + __GXData->bpSentNot = 0; +} + +void GXSetTevAlphaOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, + GXTevRegID out_reg) +{ + u32 tevReg; + + CHECK_GXBEGIN(699, "GXSetTevAlphaOp"); + + tevReg = __GXData->teva[stage]; + SET_REG_FIELD(708, tevReg, 1, 18, op & 1); + if (op <= 1) + { + SET_REG_FIELD(710, tevReg, 2, 20, scale); + SET_REG_FIELD(711, tevReg, 2, 16, bias); + } + else + { + 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); + + GX_WRITE_RAS_REG(tevReg); + __GXData->teva[stage] = tevReg; + __GXData->bpSentNot = 0; +} + +void GXSetTevColor(GXTevRegID id, GXColor color) +{ + u32 rgba; + u32 regRA; + u32 regBG; + + CHECK_GXBEGIN(740, "GXSetTevColor"); + rgba = *(u32*)&color; + + regRA = (0xE0 + id * 2) << 24; + SET_REG_FIELD(745, regRA, 8, 0, rgba >> 24); + SET_REG_FIELD(746, regRA, 8, 12, rgba & 0xFF); + + 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; +} + +void GXSetTevColorS10(GXTevRegID id, GXColorS10 color) +{ + u32 sRG; + u32 sBA; + u32 regRA; + u32 regBG; + + CHECK_GXBEGIN(782, "GXSetTevColorS10"); + sRG = *(u32*)&color; + sBA = *((u32*)&color + 1); + + 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; +} + +void GXSetTevKColor(GXTevKColorID id, GXColor color) +{ + u32 rgba; + u32 regRA; + u32 regBG; + + CHECK_GXBEGIN(833, "GXSetTevKColor"); + rgba = *(u32*)&color; + + 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); + + 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); + + GX_WRITE_RAS_REG(regRA); + GX_WRITE_RAS_REG(regBG); + + __GXData->bpSentNot = 0; +} + +void GXSetTevKColorSel(GXTevStageID stage, GXTevKColorSel sel) +{ + u32* Kreg; + + CHECK_GXBEGIN(872, "GXSetTevKColorSel"); + + Kreg = &__GXData->tevKsel[stage >> 1]; + if (stage & 1) + { + SET_REG_FIELD(0x36E, *Kreg, 5, 14, sel); + } + else + { + SET_REG_FIELD(0x370, *Kreg, 5, 4, sel); + } + + GX_WRITE_RAS_REG(*Kreg); + __GXData->bpSentNot = 0; +} + +void GXSetTevKAlphaSel(GXTevStageID stage, GXTevKAlphaSel sel) +{ + u32* Kreg; + + CHECK_GXBEGIN(905, "GXSetTevKAlphaSel"); + + Kreg = &__GXData->tevKsel[stage >> 1]; + if (stage & 1) + { + SET_REG_FIELD(911, *Kreg, 5, 19, sel); + } + else + { + SET_REG_FIELD(913, *Kreg, 5, 9, sel); + } + + GX_WRITE_RAS_REG(*Kreg); + __GXData->bpSentNot = 0; +} + +void GXSetTevSwapMode(GXTevStageID stage, GXTevSwapSel ras_sel, GXTevSwapSel tex_sel) +{ + u32* pTevReg; + + CHECK_GXBEGIN(942, "GXSetTevSwapMode"); + + 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; +} + +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 + + CHECK_GXBEGIN(978, "GXSetTevSwapModeTable"); + +#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); + + GX_WRITE_RAS_REG(*Kreg); + + Kreg = &__GXData->tevKsel[table * 2 + 1]; + SET_REG_FIELD(987, *Kreg, 2, 0, blue); + SET_REG_FIELD(988, *Kreg, 2, 2, alpha); + + GX_WRITE_RAS_REG(*Kreg); + __GXData->bpSentNot = 0; +} + +void GXSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1) +{ + u32 reg; + + CHECK_GXBEGIN(1046, "GXSetAlphaCompare"); + reg = 0xF3000000; + + 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); + + GX_WRITE_RAS_REG(reg); + __GXData->bpSentNot = 0; +} + +void GXSetZTexture(GXZTexOp op, GXTexFmt fmt, u32 bias) +{ + u32 zenv0; + u32 zenv1; + u32 type; + + CHECK_GXBEGIN(1077, "GXSetZTexture"); + + 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: + type = 0; + break; + case GX_TF_Z16: + type = 1; + break; + case GX_TF_Z24X8: + type = 2; + break; + default: + type = 2; + break; + } + + 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_WRITE_RAS_REG(zenv0); + GX_WRITE_RAS_REG(zenv1); + __GXData->bpSentNot = 0; +} + +void GXSetTevOrder(GXTevStageID stage, GXTexCoordID coord, GXTexMapID map, GXChannelID color) +{ + u32* ptref; + u32 tmap; + u32 tcoord; + static int c2r[] = { 0, 1, 0, 1, 0, 1, 7, 5, 6 }; + + CHECK_GXBEGIN(1131, "GXSetTevOrder"); + + ptref = &__GXData->tref[stage / 2]; + __GXData->texmapId[stage] = map; + + tmap = map & ~GX_TEX_DISABLE; + tmap = (tmap >= GX_MAX_TEXMAP) ? GX_TEXMAP0 : tmap; + + if (coord >= GX_MAX_TEXCOORD) + { + tcoord = GX_TEXCOORD0; + __GXData->tevTcEnab = __GXData->tevTcEnab & ~(1 << stage); + } + else + { + tcoord = coord; + __GXData->tevTcEnab = __GXData->tevTcEnab | (1 << stage); + } + + if (stage & 1) + { + 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 + { + 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_WRITE_RAS_REG(*ptref); + __GXData->bpSentNot = 0; + __GXData->dirtyState |= 1; +} + +void GXSetNumTevStages(u8 nStages) +{ + CHECK_GXBEGIN(1187, "GXSetNumTevStages"); + + SET_REG_FIELD(1190, __GXData->genMode, 4, 10, nStages - 1); + __GXData->dirtyState |= 4; +} diff --git a/libs/dolphin/gx/GXTexture.c b/libs/dolphin/gx/GXTexture.c index e69de29bb..3e1493494 100644 --- a/libs/dolphin/gx/GXTexture.c +++ b/libs/dolphin/gx/GXTexture.c @@ -0,0 +1,856 @@ +#include +#include + +#include + +// 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 0x8: + case GX_TF_CMPR: + case GX_CTF_R4: + case GX_CTF_Z4: + *rowTileS = 3; + *colTileS = 3; + break; + case GX_TF_I8: + case GX_TF_IA4: + 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_Z8M: + case GX_CTF_Z8L: + *rowTileS = 3; + *colTileS = 2; + break; + case GX_TF_IA8: + case GX_TF_RGB565: + case GX_TF_RGB5A3: + case GX_TF_RGBA8: + case 0xA: + case GX_TF_Z16: + case GX_TF_Z24X8: + case GX_CTF_RA8: + case GX_CTF_RG8: + case GX_CTF_GB8: + case GX_CTF_Z16L: + *rowTileS = 2; + *colTileS = 2; + break; + default: + *rowTileS = *colTileS = 0; + //ASSERTMSGLINEV(444, 0, "%s: invalid texture format", "GX"); + break; + } +} + +u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, GXBool mipmap, u8 max_lod) +{ + u32 tileShiftX; + u32 tileShiftY; + u32 tileBytes; + u32 bufferSize; + u32 nx; + u32 ny; + u32 level; + + __GXGetTexTileShift(format, &tileShiftX, &tileShiftY); + if (format == GX_TF_RGBA8 || format == GX_TF_Z24X8) + { + tileBytes = 64; + } + else + { + tileBytes = 32; + } + + if (mipmap == GX_TRUE) + { + nx = 1 << (31 - __cntlzw(width)); + ny = 1 << (31 - __cntlzw(height)); + + bufferSize = 0; + 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; + } + } + else + { + nx = (width + (1 << tileShiftX) - 1) >> tileShiftX; + ny = (height + (1 << tileShiftY) - 1) >> tileShiftY; + bufferSize = nx * ny * tileBytes; + } + + return bufferSize; +} + +void __GetImageTileCount(GXTexFmt fmt, u16 wd, u16 ht, u32* rowTiles, u32* colTiles, u32* cmpTiles) +{ + u32 texRowShift; + u32 texColShift; + + __GXGetTexTileShift(fmt, &texRowShift, &texColShift); + if (wd == 0) + { + wd = 1; + } + if (ht == 0) + { + ht = 1; + } + *rowTiles = (wd + (1 << texRowShift) - 1) >> texRowShift; + *colTiles = (ht + (1 << texColShift) - 1) >> texColShift; + *cmpTiles = (fmt == GX_TF_RGBA8 || fmt == GX_TF_Z24X8) ? 2 : 1; +} + +#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, const void* image_ptr, u16 width, u16 height, GXTexFmt format, + GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, GXBool mipmap) +{ + u32 imageBase; + u32 maxLOD; + u16 rowT; + u16 colT; + u32 rowC; + u32 colC; + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + CHECK_GXBEGIN(567, "GXInitTexObj"); + +#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 (format == 8 || format == 9 || format == 10) + { + SOME_SET_REG_MACRO(t->mode0, 3, 5, 5); + } + else + { + SOME_SET_REG_MACRO(t->mode0, 3, 5, 6); + } + + 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 + { + SOME_SET_REG_MACRO(t->mode0, 3, 5, 4); + } + + 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); + + imageBase = (u32)((u32)image_ptr >> 5) & 0x01FFFFFF; + SET_REG_FIELD(656, t->image3, 21, 0, imageBase); + + switch (format & 0xF) + { + case GX_TF_I4: + case 8: + t->loadFmt = 1; + rowT = 3; + colT = 3; + break; + case GX_TF_I8: + case GX_TF_IA4: + case 9: + t->loadFmt = 2; + rowT = 3; + colT = 2; + break; + case GX_TF_IA8: + case GX_TF_RGB565: + case GX_TF_RGB5A3: + case 10: + t->loadFmt = 2; + rowT = 2; + colT = 2; + break; + case GX_TF_RGBA8: + t->loadFmt = 3; + rowT = 2; + colT = 2; + break; + case GX_TF_CMPR: + t->loadFmt = 0; + rowT = 3; + colT = 3; + break; + default: + + t->loadFmt = 2; + rowT = 2; + colT = 2; + break; + } + + rowC = (width + (1 << rowT) - 1) >> rowT; + colC = (height + (1 << colT) - 1) >> colT; + t->loadCnt = (rowC * colC) & 0x7FFF; + t->flags |= 2; +} + +void GXInitTexObjCI(GXTexObj* obj, const void* image_ptr, u16 width, u16 height, GXCITexFmt format, + GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, GXBool mipmap, u32 tlut_name) +{ + __GXTexObjInt* t = (__GXTexObjInt*)obj; + + CHECK_GXBEGIN(739, "GXInitTexObjCI"); + GXInitTexObj(obj, image_ptr, width, height, format, wrap_s, wrap_t, mipmap); + t->flags &= 0xFFFFFFFD; + t->tlutName = tlut_name; +} + +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; + + CHECK_GXBEGIN(778, "GXInitTexObjLOD"); + + 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(788, t->mode0, 8, 9, lbias); + + SET_REG_FIELD(792, t->mode0, 1, 4, (mag_filt == GX_LINEAR) ? 1 : 0); + + 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 (min_lod < 0.0f) + { + min_lod = 0.0f; + } + else if (min_lod > 10.0f) + { + min_lod = 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; + } + lmax = 16.0f * max_lod; + SET_REG_FIELD(816, t->mode1, 8, 0, lmin); + SET_REG_FIELD(817, t->mode1, 8, 8, lmax); +} + +GXTexFmt GXGetTexObjFmt(const GXTexObj* to) +{ + const __GXTexObjInt* t = (const __GXTexObjInt*)to; + + return t->fmt; +} + +GXBool GXGetTexObjMipMap(const GXTexObj* to) +{ + const __GXTexObjInt* t = (const __GXTexObjInt*)to; + + return (t->flags & 1) == 1; +} + +f32 GXGetTexObjLODBias(const GXTexObj* tex_obj) +{ + s16 tmp; + const __GXTexObjInt* t = (const __GXTexObjInt*)tex_obj; + + 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; + + return (u32)GET_REG_FIELD(t->mode0, 1, 21); +} + +GXBool GXGetTexObjEdgeLOD(const GXTexObj* tex_obj) +{ + const __GXTexObjInt* t = (const __GXTexObjInt*)tex_obj; + + return !GET_REG_FIELD(t->mode0, 1, 8); +} + +GXAnisotropy GXGetTexObjMaxAniso(const GXTexObj* tex_obj) +{ + const __GXTexObjInt* t = (const __GXTexObjInt*)tex_obj; + + return GET_REG_FIELD(t->mode0, 2, 19); +} + +u32 GXGetTexObjTlut(const GXTexObj* tex_obj) +{ + const __GXTexObjInt* t = (const __GXTexObjInt*)tex_obj; + + 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; + + CHECK_GXBEGIN(1259, "GXLoadTexObjPreLoaded"); + + 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)) + { + tlr = (__GXTlutRegionInt*)__GXData->tlutRegionCallback(t->tlutName); + + SET_REG_FIELD(1291, tlr->tlutObj.tlut, 8, 24, GXTexTlutIds[id]); + GX_WRITE_RAS_REG(tlr->tlutObj.tlut); + } + + __GXData->tImage0[id] = t->image0; + __GXData->tMode0[id] = t->mode0; + __GXData->dirtyState |= 1; + __GXData->bpSentNot = 0; +} + +void GXLoadTexObj(GXTexObj* obj, GXTexMapID id) +{ + GXTexRegion* r; + + CHECK_GXBEGIN(1318, "GXLoadTexObj"); + + r = __GXData->texRegionCallback(obj, id); + + GXLoadTexObjPreLoaded(obj, r, id); +} + +void GXInitTlutObj(GXTlutObj* tlut_obj, const void* lut, GXTlutFmt fmt, u16 n_entries) +{ + __GXTlutObjInt* t = (__GXTlutObjInt*)tlut_obj; + + CHECK_GXBEGIN(1351, "GXInitTlutObj"); + + 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 GXLoadTlut(const GXTlutObj* tlut_obj, u32 tlut_name) +{ + __GXTlutRegionInt* r; + u32 tlut_offset; + __GXTlutObjInt* t = (__GXTlutObjInt*)tlut_obj; + + CHECK_GXBEGIN(1434, "GXLoadTlut"); + + r = (__GXTlutRegionInt*)__GXData->tlutRegionCallback(tlut_name); + + __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; + + CHECK_GXBEGIN(1486, "GXInitTexCacheRegion"); + + 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: + + 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: + 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 GXInitTlutRegion(GXTlutRegion* region, u32 tmem_addr, GXTlutSize tlut_size) +{ + __GXTlutRegionInt* t = (__GXTlutRegionInt*)region; + + CHECK_GXBEGIN(1654, "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 GXInvalidateTexRegion(const GXTexRegion* region) +{ + s32 wle; + s32 hle; + s32 wlo; + s32 hlo; + s32 count; + u32 reg0; + u32 reg1; + __GXTexRegionInt* r = (__GXTexRegionInt*)region; + + 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 GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 ss, u16 ts) +{ + CHECK_GXBEGIN(1989, "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; + } +} + +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: + tmap = GET_REG_FIELD(__GXData->iref, 3, 0); + coord = GET_REG_FIELD(__GXData->iref, 3, 3); + break; + case 1: + tmap = GET_REG_FIELD(__GXData->iref, 3, 6); + coord = GET_REG_FIELD(__GXData->iref, 3, 9); + break; + case 2: + tmap = GET_REG_FIELD(__GXData->iref, 3, 12); + coord = GET_REG_FIELD(__GXData->iref, 3, 15); + break; + case 3: + tmap = GET_REG_FIELD(__GXData->iref, 3, 18); + coord = GET_REG_FIELD(__GXData->iref, 3, 21); + break; + } + if (!(__GXData->tcsManEnab & (1 << coord))) + { + __SetSURegs(tmap, coord); + } + } + + i = 0; + for (i = 0; i < nStages; i++) + { + ptref = &__GXData->tref[i / 2]; + map = __GXData->texmapId[i]; + tmap = map & 0xFFFFFEFF; + if (i & 1) + { + coord = GET_REG_FIELD(*ptref, 3, 15); + } + else + { + coord = GET_REG_FIELD(*ptref, 3, 3); + } + if ((tmap != 0xFF) && !(__GXData->tcsManEnab & (1 << coord)) && + (__GXData->tevTcEnab & (1 << i))) + { + __SetSURegs(tmap, coord); + } + } + } +} + +void __GXSetTmemConfig(u32 config) +{ + switch (config) + { + case 2: + GX_WRITE_RAS_REG(0x8c0d8000); + GX_WRITE_RAS_REG(0x900dc000); + + GX_WRITE_RAS_REG(0x8d0d8800); + GX_WRITE_RAS_REG(0x910dc800); + + GX_WRITE_RAS_REG(0x8e0d9000); + GX_WRITE_RAS_REG(0x920dd000); + + GX_WRITE_RAS_REG(0x8f0d9800); + GX_WRITE_RAS_REG(0x930dd800); + + GX_WRITE_RAS_REG(0xac0da000); + GX_WRITE_RAS_REG(0xb00dc400); + + GX_WRITE_RAS_REG(0xad0da800); + GX_WRITE_RAS_REG(0xb10dcc00); + + GX_WRITE_RAS_REG(0xae0db000); + GX_WRITE_RAS_REG(0xb20dd400); + + GX_WRITE_RAS_REG(0xaf0db800); + GX_WRITE_RAS_REG(0xb30ddc00); + break; + case 1: + GX_WRITE_RAS_REG(0x8c0d8000); + GX_WRITE_RAS_REG(0x900dc000); + + GX_WRITE_RAS_REG(0x8d0d8800); + GX_WRITE_RAS_REG(0x910dc800); + + GX_WRITE_RAS_REG(0x8e0d9000); + GX_WRITE_RAS_REG(0x920dd000); + + GX_WRITE_RAS_REG(0x8f0d9800); + GX_WRITE_RAS_REG(0x930dd800); + + GX_WRITE_RAS_REG(0xac0da000); + GX_WRITE_RAS_REG(0xb00de000); + + GX_WRITE_RAS_REG(0xad0da800); + GX_WRITE_RAS_REG(0xb10de800); + + GX_WRITE_RAS_REG(0xae0db000); + GX_WRITE_RAS_REG(0xb20df000); + + GX_WRITE_RAS_REG(0xaf0db800); + GX_WRITE_RAS_REG(0xb30df800); + + break; + case 0: + default: + GX_WRITE_RAS_REG(0x8c0d8000); + GX_WRITE_RAS_REG(0x900dc000); + + GX_WRITE_RAS_REG(0x8d0d8400); + GX_WRITE_RAS_REG(0x910dc400); + + GX_WRITE_RAS_REG(0x8e0d8800); + GX_WRITE_RAS_REG(0x920dc800); + + GX_WRITE_RAS_REG(0x8f0d8c00); + GX_WRITE_RAS_REG(0x930dcc00); + + GX_WRITE_RAS_REG(0xac0d9000); + GX_WRITE_RAS_REG(0xb00dd000); + + GX_WRITE_RAS_REG(0xad0d9400); + GX_WRITE_RAS_REG(0xb10dd400); + + GX_WRITE_RAS_REG(0xae0d9800); + GX_WRITE_RAS_REG(0xb20dd800); + + GX_WRITE_RAS_REG(0xaf0d9c00); + GX_WRITE_RAS_REG(0xb30ddc00); + + break; + } +} diff --git a/libs/dolphin/gx/GXTransform.c b/libs/dolphin/gx/GXTransform.c index e69de29bb..0c19f70e1 100644 --- a/libs/dolphin/gx/GXTransform.c +++ b/libs/dolphin/gx/GXTransform.c @@ -0,0 +1,495 @@ +#include +#include +#include + +#include + +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; + + ASSERTMSGLINE(168, pm && vp && sx && sy && sz, "GXGet*: invalid null pointer"); + + 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 + { + 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]))); +} + +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) +{ + 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 +} + +void GXSetProjection(Mtx44 mtx, GXProjectionType type) +{ + CHECK_GXBEGIN(295, "GXSetProjection"); + + __GXData->projType = type; + __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] = mtx[0][3]; + __GXData->projMtx[3] = mtx[1][3]; + } + else + { + __GXData->projMtx[1] = mtx[0][2]; + __GXData->projMtx[3] = mtx[1][2]; + } + + __GXSetProjection(); + __GXData->bpSentNot = 1; +} + +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 = 1; +} + +#define qr0 0 + +void GXGetProjectionv(f32* ptr) +{ + 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(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; + + 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_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 + } +} + +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; + + asm { + 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) + } +} + +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(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 GXLoadNrmMtxImm(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 GXSetCurrentMtx(u32 id) +{ + CHECK_GXBEGIN(708, "GXSetCurrentMtx"); + SET_REG_FIELD(712, __GXData->matIdxA, 6, 0, id); + __GXSetMatrixIndex(GX_VA_PNMTXIDX); +} + +void GXLoadTexMtxImm(f32 mtx[][4], u32 id, GXTexMtxType type) +{ + u32 reg; + u32 addr; + u32 count; + + CHECK_GXBEGIN(741, "GXLoadTexMtxImm"); + + if (id >= GX_PTTEXMTX0) + { + addr = (id - GX_PTTEXMTX0) * 4 + 0x500; + } + else + { + addr = id * 4; + } + 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 +} + +void __GXSetViewport(void) +{ + f32 sx; + f32 sy; + f32 sz; + f32 ox; + f32 oy; + f32 oz; + f32 zmin; + f32 zmax; + u32 reg; + + 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)); + + zmin = __GXData->vpNearz * __GXData->zScale; + zmax = __GXData->vpFarz * __GXData->zScale; + + sz = zmax - zmin; + oz = zmax + __GXData->zOffset; + + 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); +} + +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; + } + + __GXData->vpLeft = left; + __GXData->vpTop = top; + __GXData->vpWd = wd; + __GXData->vpHt = ht; + __GXData->vpNearz = nearz; + __GXData->vpFarz = farz; + + __GXSetViewport(); + __GXData->bpSentNot = 1; +} + +void GXSetViewport(f32 left, f32 top, f32 wd, f32 ht, f32 nearz, f32 farz) +{ + GXSetViewportJitter(left, top, wd, ht, nearz, farz, 1); +} + +#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) + +void GXSetScissor(u32 left, u32 top, u32 wd, u32 ht) +{ + u32 tp; + u32 lf; + u32 bm; + u32 rt; + + CHECK_GXBEGIN(1048, "GXSetScissor"); + + tp = top + 342; + lf = left + 342; + bm = tp + ht - 1; + rt = lf + wd - 1; + + 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 GXSetScissorBoxOffset(s32 x_off, s32 y_off) +{ + u32 reg = 0; + u32 hx; + u32 hy; + + CHECK_GXBEGIN(1119, "GXSetScissorBoxOffset"); + + 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; +} + +void GXSetClipMode(GXClipMode mode) +{ + CHECK_GXBEGIN(1151, "GXSetClipMode"); + GX_WRITE_XF_REG(5, mode); + __GXData->bpSentNot = 1; +} + +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_WRITE_SOME_REG4(8, 0x40, __GXData->matIdxB, -12); + GX_WRITE_XF_REG(25, __GXData->matIdxB); + } + __GXData->bpSentNot = 1; +} diff --git a/libs/dolphin/gx/GXVerifRAS.c b/libs/dolphin/gx/GXVerifRAS.c new file mode 100644 index 000000000..eb69a0dcb --- /dev/null +++ b/libs/dolphin/gx/GXVerifRAS.c @@ -0,0 +1,943 @@ +#if DEBUG + +#include + +#include + +#include + +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/libs/dolphin/gx/GXVerifXF.c b/libs/dolphin/gx/GXVerifXF.c new file mode 100644 index 000000000..8a1715839 --- /dev/null +++ b/libs/dolphin/gx/GXVerifXF.c @@ -0,0 +1,1291 @@ +#if DEBUG + +#include + +#include + +#include + +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/libs/dolphin/gx/GXVerify.c b/libs/dolphin/gx/GXVerify.c new file mode 100644 index 000000000..12e6b984d --- /dev/null +++ b/libs/dolphin/gx/GXVerify.c @@ -0,0 +1,399 @@ +#if DEBUG + +#include + +#include + +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/libs/dolphin/gx/GXVert.c b/libs/dolphin/gx/GXVert.c new file mode 100644 index 000000000..a1f9a9686 --- /dev/null +++ b/libs/dolphin/gx/GXVert.c @@ -0,0 +1,110 @@ +#if DEBUG +#include + +#include + +#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/libs/dolphin/gx/__gx.h b/libs/dolphin/gx/__gx.h new file mode 100644 index 000000000..fe60c8852 --- /dev/null +++ b/libs/dolphin/gx/__gx.h @@ -0,0 +1,632 @@ +#ifndef _DOLPHIN_GX_INTERNAL_H_ +#define _DOLPHIN_GX_INTERNAL_H_ + +#include +#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 \ + { \ + (reg) = ((u32)__rlwimi((u32)(reg), (val), (shift), 32 - (shift) - (size), 31 - (shift))); \ + } while (0) + +#define CHECK_GXBEGIN(line, name) +// Commented out because it seems useless and lowers match% \ + 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/libs/dolphin/mtx/mtx.c b/libs/dolphin/mtx/mtx.c index e69de29bb..1ec3dd5d3 100644 --- a/libs/dolphin/mtx/mtx.c +++ b/libs/dolphin/mtx/mtx.c @@ -0,0 +1,96 @@ +#include +#include +#include "fake_tgmath.h" + +static f32 Unit01[2] = { 0.0f, 1.0f }; + +void PSMTXIdentity(register Mtx m) +{ + register f32 c_zero = 0.0f; + register f32 c_one = 1.0f; + register f32 c_01; + register f32 c_10; + + 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 + } +} + +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 PSMTXScale(register Mtx m, register f32 xS, register f32 yS, register f32 zS) +{ + register f32 c0 = 0.0f; + + 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) + } +} diff --git a/libs/dolphin/mtx/mtx44.c b/libs/dolphin/mtx/mtx44.c index e69de29bb..89615c9ae 100644 --- a/libs/dolphin/mtx/mtx44.c +++ b/libs/dolphin/mtx/mtx44.c @@ -0,0 +1,30 @@ +#include +#include +#include "fake_tgmath.h" + +static f32 mtxUnit[] = { 0.0f, 1.0f, 0.5f, 3.0f }; + +void C_MTXOrtho(Mtx44 m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f) +{ + f32 tmp; + + 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; +} diff --git a/libs/dolphin/mtx/mtx44vec.c b/libs/dolphin/mtx/mtx44vec.c index 2a12fbce9..478c49fc9 100644 --- a/libs/dolphin/mtx/mtx44vec.c +++ b/libs/dolphin/mtx/mtx44vec.c @@ -1,39 +1,247 @@ -#include "dolphin/mtx.h" - -// TODO: cleanup, documentation, check other builds -void PSMTX44MultVec(register const Mtx44 m, register const Vec *src, register Vec *dst) -{ - // clang-format off - __asm { - psq_l f0, 0(src), 0, 0 - psq_l f2, 0x30(m), 0, 0 - psq_l f1, 8(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, 0(m), 0, 0 - ps_merge00 f13, f13, f13 - psq_l f5, 8(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, 0(dst), 0, 0 - ps_mul f3, f3, f13 - psq_st f3, 8(dst), 1, 0 +#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++; } - // clang-format on -} \ No newline at end of file +} + +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/libs/dolphin/mtx/mtxstack.c b/libs/dolphin/mtx/mtxstack.c new file mode 100644 index 000000000..475175c2c --- /dev/null +++ b/libs/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/libs/dolphin/mtx/mtxvec.c b/libs/dolphin/mtx/mtxvec.c index e69de29bb..47146ee8b 100644 --- a/libs/dolphin/mtx/mtxvec.c +++ b/libs/dolphin/mtx/mtxvec.c @@ -0,0 +1,204 @@ +#include +#include +#include "fake_tgmath.h" + +void C_MTXMultVec(const Mtx m, const Vec* src, Vec* dst) { + Vec vTmp; + + 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; +} + +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 +} + +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 + subi dstBase, dstBase, 0x4 + psq_l f10, 0x18(m), 0, 0 + ps_merge11 f1, f13, f12 + mtctr count + psq_l f4, 0x20(m), 0, 0 + ps_merge00 f2, f11, f10 + psq_l f5, 0x28(m), 0, 0 + ps_merge11 f3, f11, f10 + 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 +L_000003C4: + psq_lu f6, 0x4(srcBase), 0, 0 + ps_madds0 f12, f2, f7, f8 + 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, 0x4(dstBase), 0, 0 + ps_madds1 f8, f1, f6, f8 + psq_stu f13, 0x8(dstBase), 1, 0 + ps_madd f10, f5, f7, f9 + bdnz L_000003C4 + ps_madds0 f12, f2, f7, f8 + ps_sum0 f13, f10, f9, f10 + psq_stu f12, 0x4(dstBase), 0, 0 + psq_stu f13, 0x8(dstBase), 1, 0 + blr +} + +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; +} + +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 +} + +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 + subi dstBase, dstBase, 0x4 + psq_l f10, 0x18(m), 1, 0 + ps_merge11 f1, f13, f12 + mtctr count + psq_l f3, 0x20(m), 0, 0 + ps_merge00 f2, f11, f10 + 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 +L_000007D0: + psq_lu f6, 0x4(srcBase), 0, 0 + ps_madds0 f12, f2, f7, f8 + 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, 0x4(dstBase), 0, 0 + ps_madds1 f8, f1, f6, f8 + psq_stu f13, 0x8(dstBase), 1, 0 + ps_madd f10, f4, f7, f9 + bdnz L_000007D0 + ps_madds0 f12, f2, f7, f8 + ps_sum0 f13, f10, f9, f9 + psq_stu f12, 0x4(dstBase), 0, 0 + psq_stu f13, 0x8(dstBase), 1, 0 + blr +} diff --git a/libs/dolphin/mtx/psmtx.c b/libs/dolphin/mtx/psmtx.c new file mode 100644 index 000000000..6ec6c2955 --- /dev/null +++ b/libs/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/libs/dolphin/mtx/quat.c b/libs/dolphin/mtx/quat.c index e69de29bb..79687f05a 100644 --- a/libs/dolphin/mtx/quat.c +++ b/libs/dolphin/mtx/quat.c @@ -0,0 +1,486 @@ +#include +#include +#include "fake_tgmath.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; + + asm { + 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 + } +} + +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; +} + +void PSQUATSubtract(const register Quaternion* p, const register Quaternion* q, register Quaternion* r) { + register f32 pxy, qxy, rxy, pzw, qzw, rzw; + + 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 + } +} + +void C_QUATMultiply(const Quaternion* p, const Quaternion* q, Quaternion* pq) { + Quaternion* r; + Quaternion pqTmp; + + 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 { + r = pq; + } + + 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/libs/dolphin/mtx/vec.c b/libs/dolphin/mtx/vec.c index 17ba7c59e..994ee18d8 100644 --- a/libs/dolphin/mtx/vec.c +++ b/libs/dolphin/mtx/vec.c @@ -1,262 +1,344 @@ -#include "types.h" -#include "dolphin/mtx.h" - -#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 - -void C_VECAdd(void) -{ - // UNUSED FUNCTION +#include +#include +#include "fake_tgmath.h" + +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; } -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 +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 } -void C_VECSubtract(void) -{ - // UNUSED FUNCTION +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 *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 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(void) -{ - // UNUSED FUNCTION +void C_VECScale(const Vec* src, Vec* dst, f32 scale) { + 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); } -void PSVECScale(register const Vec *src, register Vec *dst, register f32 scale) -{ - // clang-format off +void PSVECScale(const register Vec* src, register Vec* dst, register f32 scale) { register f32 vxy, vz, rxy, rz; - __asm { - psq_l vxy, 0(src), 0, 0 - psq_l vz, 8(src), 1, 0 - ps_muls0 rxy, vxy, scale - psq_st rxy, 0(dst), 0, 0 - ps_muls0 rz, vz, scale - psq_st rz, 8(dst), 1, 0 + + 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 } - // clang-format on } -void C_VECNormalize(void) -{ - // UNUSED FUNCTION +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 *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; +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 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; + 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 } -#endif // clang-format on } -void C_VECSquareMag(void) -{ - // UNUSED FUNCTION +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 Vec *v) -{ - // UNUSED FUNCTION +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; } -void C_VECMag(void) -{ - // UNUSED FUNCTION +f32 C_VECMag(const Vec* v) { + return sqrtf(C_VECSquareMag(v)); } -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 +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 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 + 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 } - #endif // clang-format on - three = 3.0f; - #ifdef __MWERKS__ // clang-format off + + c_three = 3.0f; + 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: + 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: } - #endif // clang-format on - return square_mag; + + return sqmag; } -void C_VECDotProduct(void) -{ - // UNUSED FUNCTION +f32 C_VECDotProduct(const Vec* a, const Vec* b) { + f32 dot; + + 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; } -ASM f32 PSVECDotProduct(register const Vec *a, register const Vec *b) -{ -#ifdef __MWERKS__ // clang-format off - nofralloc; - psq_l f2, 4(a), 0, 0; - psq_l f3, 4(b), 0, 0; - ps_mul f2, f2, f3; - psq_l f5, 0(a), 0, 0; - psq_l f4, 0(b), 0, 0; - ps_madd f3, f5, f4, f2; - ps_sum0 R_RET, f3, f2, f2; - blr -#endif // clang-format on +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 } -void C_VECCrossProduct(void) -{ - // UNUSED FUNCTION +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 *vec1, const register Vec *vec2, register Vec *ret) -{ -#ifdef __MWERKS__ // clang-format off - nofralloc; - psq_l fp1, 0(vec2), 0, 0 - lfs fp2, 8(vec1) - psq_l fp0, 0(vec1), 0, 0 - ps_merge10 fp6, fp1, fp1 - lfs fp3, 8(vec2) - ps_mul fp4, fp1, fp2 - ps_muls0 fp7, fp1, fp0 - ps_msub fp5, fp0, fp3, fp4 - ps_msub fp8, fp0, fp6, fp7 - ps_merge11 fp9, fp5, fp5 - ps_merge01 fp10, fp5, fp8 - psq_st fp9, 0(ret), 1, 0 - ps_neg fp10, fp10 - psq_st fp10, 4(ret), 0, 0 - blr; -#endif // clang-format on +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(void) -{ - // UNUSED FUNCTION +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(void) -{ - // UNUSED FUNCTION +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); } -void C_VECSquareDistance(void) -{ - // UNUSED FUNCTION +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)); } -f32 PSVECSquareDistance(const Vec *a, const Vec *b) -{ - // UNUSED FUNCTION +f32 PSVECSquareDistance(const register Vec* a, const register Vec* b) { + register f32 v0yz, v1yz, v0xy, v1xy, dyz, dxy; + register f32 sqdist; + + asm { + 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 + } + + return sqdist; } -void C_VECDistance(void) -{ - // UNUSED FUNCTION +f32 C_VECDistance(const Vec* a, const Vec* b) { + return sqrtf(C_VECSquareDistance(a, b)); } -// TODO: cleanup? -ASM f32 PSVECDistance(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; - lfs f3, 0.5f; - - ps_madd f1, f0, f0, f2; - fsubs f0, f3, f3; - ps_sum0 f1, f1, f2, f2; - fcmpu cr0, f0, f1; - beq exit; - lfs f4, 3.0f; - frsqrte f0, f1; - fmuls f2, f0, f0; - fmuls f0, f0, f3; - fnmsubs f2, f2, f1, f4; - fmuls f0, f2, f0; - fmuls R_RET, f1, f0; -exit: - blr -#endif // clang-format on -} \ No newline at end of file +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 { + 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 + } + + 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/libs/dolphin/odenotstub/odenotstub.c b/libs/dolphin/odenotstub/odenotstub.c index e69de29bb..094dc1b71 100644 --- a/libs/dolphin/odenotstub/odenotstub.c +++ b/libs/dolphin/odenotstub/odenotstub.c @@ -0,0 +1,9 @@ +#include + +// prototypes +__declspec(weak) int Hu_IsStub(); + +__declspec(weak) int Hu_IsStub() +{ + return 0; +} diff --git a/libs/dolphin/os/OSAlarm.c b/libs/dolphin/os/OSAlarm.c index c384f40b7..46eeff622 100644 --- a/libs/dolphin/os/OSAlarm.c +++ b/libs/dolphin/os/OSAlarm.c @@ -4,16 +4,14 @@ static struct OSAlarmQueue { - OSAlarm *head; - OSAlarm *tail; + OSAlarm* head; + OSAlarm* tail; } AlarmQueue; -static void DecrementerExceptionHandler(__OSException exception, OSContext *context); +static void DecrementerExceptionHandler(__OSException exception, OSContext* context); static BOOL OnReset(BOOL final); -static OSResetFunctionInfo ResetFunctionInfo = {OnReset, 0xFFFFFFFF}; - -static void SetTimer(OSAlarm *alarm) +static void SetTimer(OSAlarm* alarm) { OSTime delta; @@ -38,20 +36,19 @@ void OSInitAlarm(void) { AlarmQueue.head = AlarmQueue.tail = NULL; __OSSetExceptionHandler(8, DecrementerExceptionHandler); - OSRegisterResetFunction(&ResetFunctionInfo); } } -void OSCreateAlarm(OSAlarm *alarm) +void OSCreateAlarm(OSAlarm* alarm) { alarm->handler = 0; alarm->tag = 0; } -static void InsertAlarm(OSAlarm *alarm, OSTime fire, OSAlarmHandler handler) +static void InsertAlarm(OSAlarm* alarm, OSTime fire, OSAlarmHandler handler) { - OSAlarm *next; - OSAlarm *prev; + OSAlarm* next; + OSAlarm* prev; if (0 < alarm->period) { @@ -104,7 +101,7 @@ static void InsertAlarm(OSAlarm *alarm, OSTime fire, OSAlarmHandler handler) } } -void OSSetAlarm(OSAlarm *alarm, OSTime tick, OSAlarmHandler handler) +void OSSetAlarm(OSAlarm* alarm, OSTime tick, OSAlarmHandler handler) { BOOL enabled; enabled = OSDisableInterrupts(); @@ -113,7 +110,7 @@ void OSSetAlarm(OSAlarm *alarm, OSTime tick, OSAlarmHandler handler) OSRestoreInterrupts(enabled); } -void OSSetPeriodicAlarm(OSAlarm *alarm, OSTime start, OSTime period, OSAlarmHandler handler) +void OSSetPeriodicAlarm(OSAlarm* alarm, OSTime start, OSTime period, OSAlarmHandler handler) { BOOL enabled; enabled = OSDisableInterrupts(); @@ -123,9 +120,9 @@ void OSSetPeriodicAlarm(OSAlarm *alarm, OSTime start, OSTime period, OSAlarmHand OSRestoreInterrupts(enabled); } -void OSCancelAlarm(OSAlarm *alarm) +void OSCancelAlarm(OSAlarm* alarm) { - OSAlarm *next; + OSAlarm* next; BOOL enabled; enabled = OSDisableInterrupts(); @@ -163,10 +160,10 @@ void OSCancelAlarm(OSAlarm *alarm) } static void DecrementerExceptionCallback(register __OSException exception, - register OSContext *context) + register OSContext* context) { - OSAlarm *alarm; - OSAlarm *next; + OSAlarm* alarm; + OSAlarm* next; OSAlarmHandler handler; OSTime time; OSContext exceptionContext; @@ -218,7 +215,7 @@ static void DecrementerExceptionCallback(register __OSException exception, } static asm void DecrementerExceptionHandler(register __OSException exception, - register OSContext *context) + register OSContext* context) { // clang-format off nofralloc @@ -227,28 +224,3 @@ static asm void DecrementerExceptionHandler(register __OSException exception, b DecrementerExceptionCallback // clang-format on } - -static BOOL OnReset(BOOL final) -{ - OSAlarm *alarm; - OSAlarm *next; - - if (final) - { - alarm = AlarmQueue.head; - next = (alarm) ? alarm->next : NULL; - - while (alarm != NULL) - { - if (__DVDTestAlarm(alarm) == FALSE) - { - OSCancelAlarm(alarm); - } - - alarm = next; - next = (alarm) ? alarm->next : NULL; - } - } - - return TRUE; -} diff --git a/libs/dolphin/os/OSAlloc.c b/libs/dolphin/os/OSAlloc.c index bb2898e7a..fd9b8c0fe 100644 --- a/libs/dolphin/os/OSAlloc.c +++ b/libs/dolphin/os/OSAlloc.c @@ -3,31 +3,31 @@ typedef struct HeapCell { - struct HeapCell *prev; - struct HeapCell *next; + struct HeapCell* prev; + struct HeapCell* next; u32 size; } HeapCell; typedef struct Heap { s32 size; - struct HeapCell *free; // linked list of free cells - struct HeapCell *allocated; // linked list of allocated cells + struct HeapCell* free; // linked list of free cells + struct HeapCell* allocated; // linked list of allocated cells } Heap; -void *ArenaEnd; -void *ArenaStart; +void* ArenaEnd; +void* ArenaStart; int NumHeaps; -struct Heap *HeapArray; +struct Heap* HeapArray; volatile OSHeapHandle __OSCurrHeap = -1; -#define InRange(addr, start, end) ((u8 *)(start) <= (u8 *)(addr) && (u8 *)(addr) < (u8 *)(end)) +#define InRange(addr, start, end) ((u8*)(start) <= (u8*)(addr) && (u8*)(addr) < (u8*)(end)) #define OFFSET(addr, align) (((u32)(addr) & ((align)-1))) #define ALIGNMENT 32 #define MINOBJSIZE 64 -static inline void *DLAddFront(struct HeapCell *neighbor, struct HeapCell *cell) +static inline void* DLAddFront(struct HeapCell* neighbor, struct HeapCell* cell) { cell->next = neighbor; cell->prev = NULL; @@ -36,13 +36,8 @@ static inline void *DLAddFront(struct HeapCell *neighbor, struct HeapCell *cell) return cell; } -void DLLookup(void) -{ - // UNUSED FUNCTION -} - // removes 'cell' from 'list' and returns 'list' -static inline HeapCell *DLExtract(struct HeapCell *list, struct HeapCell *cell) +static inline HeapCell* DLExtract(struct HeapCell* list, struct HeapCell* cell) { if (cell->next != NULL) cell->next->prev = cell->prev; @@ -53,10 +48,11 @@ static inline HeapCell *DLExtract(struct HeapCell *list, struct HeapCell *cell) return list; } -static HeapCell *DLInsert(HeapCell *list, HeapCell *cell, void *unused /* needed to match OSFreeToHeap */) +static HeapCell* DLInsert(HeapCell* list, HeapCell* cell, + void* unused /* needed to match OSFreeToHeap */) { - HeapCell *before = NULL; - HeapCell *after = list; + HeapCell* before = NULL; + HeapCell* after = list; while (after != NULL) { @@ -70,7 +66,7 @@ static HeapCell *DLInsert(HeapCell *list, HeapCell *cell, void *unused /* needed if (after != NULL) { after->prev = cell; - if ((u8 *)cell + cell->size == (u8 *)after) + if ((u8*)cell + cell->size == (u8*)after) { cell->size += after->size; after = after->next; @@ -82,7 +78,7 @@ static HeapCell *DLInsert(HeapCell *list, HeapCell *cell, void *unused /* needed if (before != NULL) { before->next = cell; - if ((u8 *)before + before->size == (u8 *)cell) + if ((u8*)before + before->size == (u8*)cell) { before->size += cell->size; before->next = after; @@ -94,22 +90,12 @@ static HeapCell *DLInsert(HeapCell *list, HeapCell *cell, void *unused /* needed return cell; } -void DLOverlap(void) -{ - // UNUSED FUNCTION -} - -void DLSize(void) -{ - // UNUSED FUNCTION -} - -void *OSAllocFromHeap(OSHeapHandle heap, u32 size) +void* OSAllocFromHeap(OSHeapHandle heap, u32 size) { - struct Heap *hd = &HeapArray[heap]; + struct Heap* hd = &HeapArray[heap]; s32 sizeAligned = OSRoundUp32B(ALIGNMENT + size); - struct HeapCell *cell; - struct HeapCell *oldTail; + struct HeapCell* cell; + struct HeapCell* oldTail; u32 leftoverSpace; // find first cell with enough capacity @@ -131,7 +117,7 @@ void *OSAllocFromHeap(OSHeapHandle heap, u32 size) { // remove this cell from the free list and make a new cell out of the // remaining space - struct HeapCell *newcell = (void *)((u8 *)cell + sizeAligned); + struct HeapCell* newcell = (void*)((u8*)cell + sizeAligned); cell->size = sizeAligned; newcell->size = leftoverSpace; newcell->prev = cell->prev; @@ -147,14 +133,14 @@ void *OSAllocFromHeap(OSHeapHandle heap, u32 size) // add the cell to the beginning of the allocated list hd->allocated = DLAddFront(hd->allocated, cell); - return (u8 *)cell + ALIGNMENT; + return (u8*)cell + ALIGNMENT; } -void OSFreeToHeap(OSHeapHandle heap, void *ptr) +void OSFreeToHeap(OSHeapHandle heap, void* ptr) { - HeapCell *cell = (void *)((u8 *)ptr - ALIGNMENT); - Heap *hd = &HeapArray[heap]; - HeapCell *list = hd->allocated; + HeapCell* cell = (void*)((u8*)ptr - ALIGNMENT); + Heap* hd = &HeapArray[heap]; + HeapCell* list = hd->allocated; // remove cell from the allocated list // hd->allocated = DLExtract(hd->allocated, cell); @@ -176,7 +162,7 @@ OSHeapHandle OSSetCurrentHeap(OSHeapHandle heap) return old; } -void *OSInitAlloc(void *arenaStart, void *arenaEnd, int maxHeaps) +void* OSInitAlloc(void* arenaStart, void* arenaEnd, int maxHeaps) { u32 totalSize = maxHeaps * sizeof(struct Heap); int i; @@ -186,7 +172,7 @@ void *OSInitAlloc(void *arenaStart, void *arenaEnd, int maxHeaps) for (i = 0; i < NumHeaps; i++) { - Heap *heap = &HeapArray[i]; + Heap* heap = &HeapArray[i]; heap->size = -1; heap->free = heap->allocated = NULL; @@ -194,28 +180,28 @@ void *OSInitAlloc(void *arenaStart, void *arenaEnd, int maxHeaps) __OSCurrHeap = -1; - arenaStart = (u8 *)HeapArray + totalSize; - arenaStart = (void *)OSRoundUp32B(arenaStart); + arenaStart = (u8*)HeapArray + totalSize; + arenaStart = (void*)OSRoundUp32B(arenaStart); ArenaStart = arenaStart; - ArenaEnd = (void *)OSRoundDown32B(arenaEnd); + ArenaEnd = (void*)OSRoundDown32B(arenaEnd); return arenaStart; } -OSHeapHandle OSCreateHeap(void *start, void *end) +OSHeapHandle OSCreateHeap(void* start, void* end) { int i; - HeapCell *cell = (void *)OSRoundUp32B(start); + HeapCell* cell = (void*)OSRoundUp32B(start); - end = (void *)OSRoundDown32B(end); + end = (void*)OSRoundDown32B(end); for (i = 0; i < NumHeaps; i++) { - Heap *hd = &HeapArray[i]; + Heap* hd = &HeapArray[i]; if (hd->size < 0) { - hd->size = (u8 *)end - (u8 *)cell; + hd->size = (u8*)end - (u8*)cell; cell->prev = NULL; cell->next = NULL; cell->size = hd->size; diff --git a/libs/dolphin/os/OSArena.c b/libs/dolphin/os/OSArena.c index 97e7ede95..79b71e639 100644 --- a/libs/dolphin/os/OSArena.c +++ b/libs/dolphin/os/OSArena.c @@ -3,39 +3,25 @@ #define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) #define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) -void *__OSArenaHi; -void *__OSArenaLo = (void *)-1; +void* __OSArenaHi; +void* __OSArenaLo = (void*)-1; -void *OSGetArenaHi(void) { return __OSArenaHi; } - -void *OSGetArenaLo(void) { return __OSArenaLo; } - -void OSSetArenaHi(void *addr) { __OSArenaHi = addr; } - -void OSSetArenaLo(void *addr) { __OSArenaLo = addr; } - -void *OSAllocFromArenaLo(u32 size, u32 align) +void* OSGetArenaHi(void) { - void *ptr; - u8 *arenaLo; + return __OSArenaHi; +} - ptr = OSGetArenaLo(); - arenaLo = ptr = (void *)ROUND(ptr, align); - arenaLo += size; - arenaLo = (u8 *)ROUND(arenaLo, align); - OSSetArenaLo(arenaLo); - return ptr; +void* OSGetArenaLo(void) +{ + return __OSArenaLo; } -void *OSAllocFromArenaHi(u32 size, u32 align) +void OSSetArenaHi(void* addr) { - void *ptr; - u8 *arenaHi; + __OSArenaHi = addr; +} - arenaHi = OSGetArenaHi(); - arenaHi = (u8 *)TRUNC(arenaHi, align); - arenaHi -= size; - arenaHi = ptr = (void *)TRUNC(arenaHi, align); - OSSetArenaHi(arenaHi); - return ptr; +void OSSetArenaLo(void* addr) +{ + __OSArenaLo = addr; } \ No newline at end of file diff --git a/libs/dolphin/os/OSCache.c b/libs/dolphin/os/OSCache.c index 2cec4d3dd..11ba9094f 100644 --- a/libs/dolphin/os/OSCache.c +++ b/libs/dolphin/os/OSCache.c @@ -89,44 +89,6 @@ asm void DCFlushRangeNoSync(register void* addr, register u32 nBytes) { 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 -} - -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 ICInvalidateRange(register void* addr, register u32 nBytes) { nofralloc nofralloc @@ -169,76 +131,6 @@ asm void ICEnable() { #define LC_LINES 512 #define CACHE_LINES 1024 -asm void __LCEnable() { - 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 - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - - blr -} - -void LCEnable() { - BOOL enabled; - - enabled = OSDisableInterrupts(); - __LCEnable(); - OSRestoreInterrupts(enabled); -} - asm void LCDisable() { nofralloc @@ -255,172 +147,104 @@ asm void LCDisable() { 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 -} - /* clang-format on */ -u32 LCLoadData(register void* destAddr, register void* srcAddr, register u32 nBytes) { - u32 numBlocks = (nBytes + 31) / 32; - u32 numTransactions = (numBlocks + 128 - 1) / 128; - - while (numBlocks > 0) { - if (numBlocks < 128) { - LCLoadBlocks(destAddr, srcAddr, numBlocks); - numBlocks = 0; - } else { - LCLoadBlocks(destAddr, srcAddr, 0); - numBlocks -= 128; - destAddr = (void*)((u32)destAddr + 4096); - srcAddr = (void*)((u32)srcAddr + 4096); - } - } - - return numTransactions; -} -u32 LCStoreData(void* destAddr, void* srcAddr, u32 nBytes) { - u32 numBlocks = (nBytes + 31) / 32; - u32 numTransactions = (numBlocks + 128 - 1) / 128; - - 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; -} - /* clang-format off */ -asm u32 LCQueueLength() { - nofralloc - mfspr r4, HID2 - rlwinm r3, r4, 8, 28, 31 - blr -} - -asm void LCQueueWait(register u32 len) { - nofralloc -wait: - mfspr r4, HID2 - rlwinm r4, r4, 8, 28, 31 - cmpw r4, r3 - bgt wait - blr -} /* clang-format on */ -static void L2Disable(void) { - __sync(); - PPCMtl2cr(PPCMfl2cr() & ~0x80000000); - __sync(); -} - -void L2GlobalInvalidate(void) { - L2Disable(); - PPCMtl2cr(PPCMfl2cr() | 0x00200000); - while (PPCMfl2cr() & 0x00000001u) - ; - PPCMtl2cr(PPCMfl2cr() & ~0x00200000); - while (PPCMfl2cr() & 0x00000001u) { - DBPrintf(">>> L2 INVALIDATE : SHOULD NEVER HAPPEN\n"); - } -} - -static void L2Init(void) { - u32 oldMSR; - oldMSR = PPCMfmsr(); - __sync(); - PPCMtmsr(MSR_IR | MSR_DR); - __sync(); - L2Disable(); - L2GlobalInvalidate(); - PPCMtmsr(oldMSR); +static void L2Disable(void) +{ + __sync(); + PPCMtl2cr(PPCMfl2cr() & ~0x80000000); + __sync(); +} + +void L2GlobalInvalidate(void) +{ + L2Disable(); + PPCMtl2cr(PPCMfl2cr() | 0x00200000); + while (PPCMfl2cr() & 0x00000001u) + ; + PPCMtl2cr(PPCMfl2cr() & ~0x00200000); + while (PPCMfl2cr() & 0x00000001u) + { + DBPrintf(">>> L2 INVALIDATE : SHOULD NEVER HAPPEN\n"); + } } -void L2Enable(void) { PPCMtl2cr((PPCMfl2cr() | L2CR_L2E) & ~L2CR_L2I); } +static void L2Init(void) +{ + u32 oldMSR; + oldMSR = PPCMfmsr(); + __sync(); + PPCMtmsr(MSR_IR | MSR_DR); + __sync(); + L2Disable(); + L2GlobalInvalidate(); + PPCMtmsr(oldMSR); +} + +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)) + { + OSReport("Machine check was not DMA/locked cache related\n"); + OSDumpContext(context); + PPCHalt(); + } -void DMAErrorHandler(OSError error, OSContext* context, ...) { - u32 hid2 = PPCMfhid2(); + OSReport("DMAErrorHandler(): An error occurred while processing DMA.\n"); + OSReport("The following errors have been detected and cleared :\n"); - 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)) { - OSReport("Machine check was not DMA/locked cache related\n"); - OSDumpContext(context); - PPCHalt(); - } + if (hid2 & HID2_DCHERR) + { + OSReport("\t- Requested a locked cache tag that was already in the cache\n"); + } - OSReport("DMAErrorHandler(): An error occurred while processing DMA.\n"); - OSReport("The following errors have been detected and cleared :\n"); + if (hid2 & HID2_DNCERR) + { + OSReport("\t- DMA attempted to access normal cache\n"); + } - if (hid2 & HID2_DCHERR) { - OSReport("\t- Requested a locked cache tag that was already in the cache\n"); - } + if (hid2 & HID2_DCMERR) + { + OSReport("\t- DMA missed in data cache\n"); + } - if (hid2 & HID2_DNCERR) { - OSReport("\t- DMA attempted to access normal cache\n"); - } + if (hid2 & HID2_DQOERR) + { + OSReport("\t- DMA queue overflowed\n"); + } - if (hid2 & HID2_DCMERR) { - OSReport("\t- DMA missed in data cache\n"); - } + // write hid2 back to clear the error bits + PPCMthid2(hid2); +} - if (hid2 & HID2_DQOERR) { - OSReport("\t- DMA queue overflowed\n"); - } +void __OSCacheInit() +{ + if (!(PPCMfhid0() & HID0_ICE)) + { + ICEnable(); + DBPrintf("L1 i-caches initialized\n"); + } + if (!(PPCMfhid0() & HID0_DCE)) + { + DCEnable(); + DBPrintf("L1 d-caches initialized\n"); + } - // write hid2 back to clear the error bits - PPCMthid2(hid2); -} + if (!(PPCMfl2cr() & L2CR_L2E)) + { + L2Init(); + PPCMtl2cr((PPCMfl2cr() | L2CR_L2E) & ~L2CR_L2I); + DBPrintf("L2 cache initialized\n"); + } -void __OSCacheInit() { - if (!(PPCMfhid0() & HID0_ICE)) { - ICEnable(); - DBPrintf("L1 i-caches initialized\n"); - } - if (!(PPCMfhid0() & HID0_DCE)) { - DCEnable(); - DBPrintf("L1 d-caches initialized\n"); - } - - if (!(PPCMfl2cr() & L2CR_L2E)) { - L2Init(); - L2Enable(); - DBPrintf("L2 cache initialized\n"); - } - - OSSetErrorHandler(OS_ERROR_MACHINE_CHECK, DMAErrorHandler); - DBPrintf("Locked cache machine check handler installed\n"); + OSSetErrorHandler(OS_ERROR_MACHINE_CHECK, DMAErrorHandler); + DBPrintf("Locked cache machine check handler installed\n"); } diff --git a/libs/dolphin/os/OSContext.c b/libs/dolphin/os/OSContext.c index f8aae0446..35542bcfc 100644 --- a/libs/dolphin/os/OSContext.c +++ b/libs/dolphin/os/OSContext.c @@ -6,8 +6,9 @@ volatile OSContext* __OSCurrentContext : (OS_BASE_CACHED | 0x00D4); volatile OSContext* __OSFPUContext : (OS_BASE_CACHED | 0x00D8); -static asm void __OSLoadFPUContext(register u32, register OSContext* fpuContext) { - // clang-format off +static asm void __OSLoadFPUContext(register u32, register OSContext* fpuContext) +{ + // clang-format off nofralloc lhz r5, fpuContext->state; clrlwi. r5, r5, 31 @@ -87,11 +88,12 @@ static asm void __OSLoadFPUContext(register u32, register OSContext* fpuContext) lfd fp31, fpuContext->fpr[31] _return: blr - // clang-format on + // clang-format on } -static asm void __OSSaveFPUContext(register u32, register u32, register OSContext* fpuContext) { - // clang-format off +static asm void __OSSaveFPUContext(register u32, register u32, register OSContext* fpuContext) +{ + // clang-format off nofralloc lhz r3, fpuContext->state @@ -175,27 +177,20 @@ static asm void __OSSaveFPUContext(register u32, register u32, register OSContex _return: blr - // clang-format on -} - -asm void OSLoadFPUContext(register OSContext* fpuContext) { - // clang-format off - nofralloc - addi r4, fpuContext, 0 - b __OSLoadFPUContext - // clang-format on + // clang-format on } -asm void OSSaveFPUContext(register OSContext* fpuContext) { - // clang-format off +asm void OSSaveFPUContext(register OSContext* fpuContext) +{ + // clang-format off nofralloc addi r5, fpuContext, 0 b __OSSaveFPUContext - // clang-format on + // clang-format on } asm void OSSetCurrentContext(register OSContext* context){ - // clang-format off + // clang-format off nofralloc addis r4, r0, OS_CACHED_REGION_PREFIX @@ -227,15 +222,17 @@ asm void OSSetCurrentContext(register OSContext* context){ mtmsr r6 isync blr - // clang-format on + // clang-format on } -OSContext* OSGetCurrentContext(void) { - return (OSContext*)__OSCurrentContext; +OSContext* OSGetCurrentContext(void) +{ + return (OSContext*)__OSCurrentContext; } -asm u32 OSSaveContext(register OSContext* context) { - // clang-format off +asm u32 OSSaveContext(register OSContext* context) +{ + // clang-format off nofralloc stmw r13, context->gpr[13] mfspr r0, GQR1 @@ -269,14 +266,15 @@ asm u32 OSSaveContext(register OSContext* context) { stw r0, context->gpr[3] li r3, 0 blr - // clang-format on + // clang-format on } extern void __RAS_OSDisableInterrupts_begin(); extern void __RAS_OSDisableInterrupts_end(); -asm void OSLoadContext(register OSContext* context) { - // clang-format off +asm void OSLoadContext(register OSContext* context) +{ + // clang-format off nofralloc lis r4,__RAS_OSDisableInterrupts_begin@ha @@ -345,165 +343,88 @@ asm void OSLoadContext(register OSContext* context) { lwz r3, context->gpr[3] rfi - // clang-format on + // clang-format on } -asm u32 OSGetStackPointer() { - // clang-format off +asm u32 OSGetStackPointer() +{ + // clang-format off nofralloc mr r3, r1 blr - // clang-format on -} - -asm u32 OSSwitchStack(register u32 newsp) { - // clang-format off - nofralloc - mr r5, r1 - mr r1, newsp - mr r3, r5 - blr - // clang-format on -} - -asm int OSSwitchFiber(register u32 pc, register u32 newsp) { - // clang-format off - 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 - // clang-format on + // clang-format on } -void OSClearContext(register OSContext* context) { - context->mode = 0; - context->state = 0; - if (context == __OSFPUContext) - __OSFPUContext = NULL; -} - -asm void OSInitContext(register OSContext* context, register u32 pc, register u32 newsp) { - // clang-format off - 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 - // clang-format on +void OSClearContext(register OSContext* context) +{ + context->mode = 0; + context->state = 0; + if (context == __OSFPUContext) + __OSFPUContext = NULL; } -void OSDumpContext(OSContext* context) { - u32 i; - u32* p; - - OSReport("------------------------- Context 0x%08x -------------------------\n", 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]); - } - - OSReport("LR = 0x%08x CR = 0x%08x\n", context->lr, context->cr); - OSReport("SRR0 = 0x%08x SRR1 = 0x%08x\n", context->srr0, context->srr1); +void OSDumpContext(OSContext* context) +{ + u32 i; + u32* p; - 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("------------------------- Context 0x%08x -------------------------\n", context); - if (context->state & OS_CONTEXT_STATE_FPSAVED) { - OSContext* currentContext; - OSContext fpuContext; - BOOL enabled; + 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]); + } - enabled = OSDisableInterrupts(); - currentContext = OSGetCurrentContext(); - OSClearContext(&fpuContext); - OSSetCurrentContext(&fpuContext); + OSReport("LR = 0x%08x CR = 0x%08x\n", context->lr, context->cr); + OSReport("SRR0 = 0x%08x SRR1 = 0x%08x\n", context->srr0, context->srr1); - 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]); - } - 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->psf[i], i + 1, - (u32)context->psf[i + 1]); + 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]); } - OSClearContext(&fpuContext); - OSSetCurrentContext(currentContext); - OSRestoreInterrupts(enabled); - } + if (context->state & OS_CONTEXT_STATE_FPSAVED) + { + OSContext* currentContext; + OSContext fpuContext; + BOOL enabled; + + enabled = OSDisableInterrupts(); + 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]); + } + 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->psf[i], i + 1, + (u32)context->psf[i + 1]); + } + + OSClearContext(&fpuContext); + OSSetCurrentContext(currentContext); + OSRestoreInterrupts(enabled); + } - OSReport("\nAddress: Back Chain LR Save\n"); - for (i = 0, p = (u32*)context->gpr[1]; p && (u32)p != 0xffffffff && i++ < 16; p = (u32*)*p) { - OSReport("0x%08x: 0x%08x 0x%08x\n", p, p[0], p[1]); - } + OSReport("\nAddress: Back Chain LR Save\n"); + for (i = 0, p = (u32*)context->gpr[1]; p && (u32)p != 0xffffffff && i++ < 16; p = (u32*)*p) + { + OSReport("0x%08x: 0x%08x 0x%08x\n", p, p[0], p[1]); + } } -static asm void OSSwitchFPUContext(register __OSException exception, register OSContext* context) { - // clang-format off +static asm void OSSwitchFPUContext(register __OSException exception, register OSContext* context) +{ + // clang-format off nofralloc mfmsr r5 ori r5, r5, 0x2000 @@ -540,98 +461,12 @@ static asm void OSSwitchFPUContext(register __OSException exception, register OS lwz r3, OS_CONTEXT_R3(context) lwz r4, OS_CONTEXT_R4(context) rfi - // clang-format on -} - -void __OSContextInit(void) { - __OSSetExceptionHandler(__OS_EXCEPTION_FLOATING_POINT, OSSwitchFPUContext); - __OSFPUContext = NULL; - DBPrintf("FPU-unavailable handler installed\n"); + // clang-format on } -asm void OSFillFPUContext(register OSContext *context) +void __OSContextInit(void) { - // clang-format off - nofralloc - mfmsr r5 - ori r5, r5, 0x2000 - mtmsr r5 - - isync - stfd f0, 0x90(r3) - stfd f1, 0x98(r3) - stfd f2, 0xA0(r3) - stfd f3, 0xA8(r3) - stfd f4, 0xB0(r3) - stfd f5, 0xB8(r3) - stfd f6, 0xC0(r3) - stfd f7, 0xC8(r3) - stfd f8, 0xD0(r3) - stfd f9, 0xD8(r3) - stfd f10, 0xE0(r3) - stfd f11, 0xE8(r3) - stfd f12, 0xF0(r3) - stfd f13, 0xF8(r3) - stfd f14, 0x100(r3) - stfd f15, 0x108(r3) - stfd f16, 0x110(r3) - stfd f17, 0x118(r3) - stfd f18, 0x120(r3) - stfd f19, 0x128(r3) - stfd f20, 0x130(r3) - stfd f21, 0x138(r3) - stfd f22, 0x140(r3) - stfd f23, 0x148(r3) - stfd f24, 0x150(r3) - stfd f25, 0x158(r3) - stfd f26, 0x160(r3) - stfd f27, 0x168(r3) - stfd f28, 0x170(r3) - stfd f29, 0x178(r3) - stfd f30, 0x180(r3) - stfd f31, 0x188(r3) - mffs f0 - stfd f0, 0x190(r3) - lfd f0, 0x90(r3) - - mfspr r5, 0x398 - rlwinm. r5,r5,3,31,31 - beq- _return - - psq_st f0,0x1C8(r3),0,0 - psq_st f1,0x1D0(r3),0,0 - psq_st f2,0x1D8(r3),0,0 - psq_st f3,0x1E0(r3),0,0 - psq_st f4,0x1E8(r3),0,0 - psq_st f5,0x1F0(r3),0,0 - psq_st f6,0x1F8(r3),0,0 - psq_st f7,0x200(r3),0,0 - psq_st f8,0x208(r3),0,0 - psq_st f9,0x210(r3),0,0 - psq_st f10,0x218(r3),0,0 - psq_st f11,0x220(r3),0,0 - psq_st f12,0x228(r3),0,0 - psq_st f13,0x230(r3),0,0 - psq_st f14,0x238(r3),0,0 - psq_st f15,0x240(r3),0,0 - psq_st f16,0x248(r3),0,0 - psq_st f17,0x250(r3),0,0 - psq_st f18,0x258(r3),0,0 - psq_st f19,0x260(r3),0,0 - psq_st f20,0x268(r3),0,0 - psq_st f21,0x270(r3),0,0 - psq_st f22,0x278(r3),0,0 - psq_st f23,0x280(r3),0,0 - psq_st f24,0x288(r3),0,0 - psq_st f25,0x290(r3),0,0 - psq_st f26,0x298(r3),0,0 - psq_st f27,0x2A0(r3),0,0 - psq_st f28,0x2A8(r3),0,0 - psq_st f29,0x2B0(r3),0,0 - psq_st f30,0x2B8(r3),0,0 - psq_st f31,0x2C0(r3),0,0 - -_return: - blr - // clang-format on -} \ No newline at end of file + __OSSetExceptionHandler(__OS_EXCEPTION_FLOATING_POINT, OSSwitchFPUContext); + __OSFPUContext = NULL; + DBPrintf("FPU-unavailable handler installed\n"); +} diff --git a/libs/dolphin/os/OSError.c b/libs/dolphin/os/OSError.c index b7091c98f..ec942ba48 100644 --- a/libs/dolphin/os/OSError.c +++ b/libs/dolphin/os/OSError.c @@ -11,195 +11,225 @@ OSErrorHandler __OSErrorTable[OS_ERROR_MAX]; #define FPSCR_ENABLE (FPSCR_VE | FPSCR_OE | FPSCR_UE | FPSCR_ZE | FPSCR_XE) u32 __OSFpscrEnableBits = FPSCR_ENABLE; -__declspec(weak) void OSReport(const char* msg, ...) { - va_list args; - va_start(args, msg); - vprintf(msg, args); - va_end(args); +__declspec(weak) void OSReport(const char* msg, ...) +{ + va_list args; + va_start(args, msg); + vprintf(msg, args); + va_end(args); } -__declspec(weak) void OSVReport(const char* msg, va_list list) { vprintf(msg, list); } - -__declspec(weak) void OSPanic(const char* file, int line, const char* msg, ...) { - va_list marker; - u32 i; - u32* p; - - OSDisableInterrupts(); - va_start(marker, msg); - vprintf(msg, marker); - va_end(marker); - OSReport(" in \"%s\" on line %d.\n", file, line); +__declspec(weak) void OSVReport(const char* msg, va_list list) +{ + vprintf(msg, list); +} - OSReport("\nAddress: Back Chain LR Save\n"); - 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]); - } +__declspec(weak) void OSPanic(const char* file, int line, const char* msg, ...) +{ + va_list marker; + u32 i; + u32* p; + + OSDisableInterrupts(); + va_start(marker, msg); + vprintf(msg, marker); + va_end(marker); + OSReport(" in \"%s\" on line %d.\n", file, line); + + OSReport("\nAddress: Back Chain LR Save\n"); + 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(); + PPCHalt(); } -OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler) { - OSErrorHandler oldHandler; - BOOL enabled; - - enabled = OSDisableInterrupts(); - oldHandler = __OSErrorTable[error]; - __OSErrorTable[error] = handler; - - if (error == OS_ERROR_FPE) { - u32 msr; - u32 fpscr; - OSThread* thread; - - msr = PPCMfmsr(); - PPCMtmsr(msr | MSR_FP); - fpscr = PPCMffpscr(); - if (handler) { - for (thread = __OSActiveThreadQueue.head; thread; 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.psf[i] = (u64)0xffffffffffffffffLL; - } - thread->context.fpscr = FPSCR_NI; +OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler) +{ + OSErrorHandler oldHandler; + BOOL enabled; + + enabled = OSDisableInterrupts(); + oldHandler = __OSErrorTable[error]; + __OSErrorTable[error] = handler; + + if (error == OS_ERROR_FPE) + { + u32 msr; + u32 fpscr; + OSThread* thread; + + msr = PPCMfmsr(); + PPCMtmsr(msr | MSR_FP); + fpscr = PPCMffpscr(); + if (handler) + { + for (thread = __OSActiveThreadQueue.head; thread; 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.psf[i] = (u64)0xffffffffffffffffLL; + } + thread->context.fpscr = FPSCR_NI; + } + thread->context.fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE; + thread->context.fpscr &= + ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | + FPSCR_VXSNAN | FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | + FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI); + } + fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE; + msr |= MSR_FE0 | MSR_FE1; + } + else + { + for (thread = __OSActiveThreadQueue.head; thread; thread = thread->linkActive.next) + { + thread->context.srr1 &= ~(MSR_FE0 | MSR_FE1); + thread->context.fpscr &= ~FPSCR_ENABLE; + thread->context.fpscr &= + ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | + FPSCR_VXSNAN | FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | + FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI); + } + fpscr &= ~FPSCR_ENABLE; + msr &= ~(MSR_FE0 | MSR_FE1); } - thread->context.fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE; - thread->context.fpscr &= - ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | - FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | - FPSCR_OX | FPSCR_FX | FPSCR_FI); - } - fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE; - msr |= MSR_FE0 | MSR_FE1; - } else { - for (thread = __OSActiveThreadQueue.head; thread; thread = thread->linkActive.next) { - thread->context.srr1 &= ~(MSR_FE0 | MSR_FE1); - thread->context.fpscr &= ~FPSCR_ENABLE; - thread->context.fpscr &= - ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | - FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | - FPSCR_OX | FPSCR_FX | FPSCR_FI); - } - fpscr &= ~FPSCR_ENABLE; - msr &= ~(MSR_FE0 | MSR_FE1); - } - fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | - FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | - FPSCR_OX | FPSCR_FX | FPSCR_FI); + fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | + FPSCR_VXSNAN | FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | + FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI); - PPCMtfpscr(fpscr); - PPCMtmsr(msr); - } + PPCMtfpscr(fpscr); + PPCMtmsr(msr); + } - OSRestoreInterrupts(enabled); - return oldHandler; + OSRestoreInterrupts(enabled); + return oldHandler; } -void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar) { - OSTime now; - - now = OSGetTime(); - - if (!(context->srr1 & MSR_RI)) { - OSReport("Non-recoverable Exception %d", exception); - } else { - if (exception == __OS_EXCEPTION_PROGRAM && (context->srr1 & (0x80000000 >> 11)) && - __OSErrorTable[OS_ERROR_FPE] != 0) { - u32 fpscr; - u32 msr; - - exception = OS_ERROR_FPE; - - msr = PPCMfmsr(); - PPCMtmsr(msr | MSR_FP); - - if (__OSFPUContext) { - OSSaveFPUContext((OSContext*)__OSFPUContext); - } - - fpscr = PPCMffpscr(); - fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | - FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | - FPSCR_OX | FPSCR_FX | FPSCR_FI); - PPCMtfpscr(fpscr); - - PPCMtmsr(msr); - - if (__OSFPUContext == context) { - OSDisableScheduler(); - __OSErrorTable[exception](exception, context, dsisr, dar); - context->srr1 &= ~MSR_FP; - __OSFPUContext = NULL; - - context->fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | - FPSCR_VXSNAN | FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | - FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI); - OSEnableScheduler(); - __OSReschedule(); - } else { - context->srr1 &= ~MSR_FP; - __OSFPUContext = NULL; - } - - OSLoadContext(context); - } +void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar) +{ + OSTime now; - if (__OSErrorTable[exception]) { - OSDisableScheduler(); - __OSErrorTable[exception](exception, context, dsisr, dar); - OSEnableScheduler(); - __OSReschedule(); - OSLoadContext(context); + now = OSGetTime(); + + if (!(context->srr1 & MSR_RI)) + { + OSReport("Non-recoverable Exception %d", exception); } + else + { + if (exception == __OS_EXCEPTION_PROGRAM && (context->srr1 & (0x80000000 >> 11)) && + __OSErrorTable[OS_ERROR_FPE] != 0) + { + u32 fpscr; + u32 msr; + + exception = OS_ERROR_FPE; + + msr = PPCMfmsr(); + PPCMtmsr(msr | MSR_FP); + + if (__OSFPUContext) + { + OSSaveFPUContext((OSContext*)__OSFPUContext); + } + + fpscr = PPCMffpscr(); + fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | + FPSCR_VXSNAN | FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | + FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI); + PPCMtfpscr(fpscr); + + PPCMtmsr(msr); + + if (__OSFPUContext == context) + { + OSDisableScheduler(); + __OSErrorTable[exception](exception, context, dsisr, dar); + context->srr1 &= ~MSR_FP; + __OSFPUContext = NULL; + + context->fpscr &= + ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | + FPSCR_VXSNAN | FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | + FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI); + OSEnableScheduler(); + __OSReschedule(); + } + else + { + context->srr1 &= ~MSR_FP; + __OSFPUContext = NULL; + } + + OSLoadContext(context); + } + + if (__OSErrorTable[exception]) + { + OSDisableScheduler(); + __OSErrorTable[exception](exception, context, dsisr, dar); + OSEnableScheduler(); + __OSReschedule(); + OSLoadContext(context); + } - if (exception == OS_ERROR_DECREMENTER) { - OSLoadContext(context); + if (exception == OS_ERROR_DECREMENTER) + { + OSLoadContext(context); + } + + OSReport("Unhandled Exception %d", exception); } - OSReport("Unhandled Exception %d", exception); - } - - OSReport("\n"); - OSDumpContext(context); - OSReport("\nDSISR = 0x%08x DAR = 0x%08x\n", dsisr, dar); - OSReport("TB = 0x%016llx\n", now); - - 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); - break; - case __OS_EXCEPTION_ISI: - OSReport("\nAttempted to fetch instruction from invalid address 0x%x " - "(read from SRR0)\n", - context->srr0); - break; - 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); - break; - case __OS_EXCEPTION_PROGRAM: - OSReport("\nProgram exception : Possible illegal instruction/operation " - "at or around 0x%x (read from SRR0)\n", - context->srr0, dar); - break; - case OS_ERROR_PROTECTION: OSReport("\n"); - OSReport("AI DMA Address = 0x%04x%04x\n", __DSPRegs[0x00000018], __DSPRegs[0x00000018 + 1]); - OSReport("ARAM DMA Address = 0x%04x%04x\n", __DSPRegs[0x00000010], __DSPRegs[0x00000010 + 1]); - OSReport("DI DMA Address = 0x%08x\n", __DIRegs[0x00000005]); - break; - } + OSDumpContext(context); + OSReport("\nDSISR = 0x%08x DAR = 0x%08x\n", dsisr, dar); + OSReport("TB = 0x%016llx\n", now); + + 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); + break; + case __OS_EXCEPTION_ISI: + OSReport("\nAttempted to fetch instruction from invalid address 0x%x " + "(read from SRR0)\n", + context->srr0); + break; + 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); + break; + case __OS_EXCEPTION_PROGRAM: + OSReport("\nProgram exception : Possible illegal instruction/operation " + "at or around 0x%x (read from SRR0)\n", + context->srr0, dar); + break; + case OS_ERROR_PROTECTION: + OSReport("\n"); + OSReport("AI DMA Address = 0x%04x%04x\n", __DSPRegs[0x00000018], + __DSPRegs[0x00000018 + 1]); + OSReport("ARAM DMA Address = 0x%04x%04x\n", __DSPRegs[0x00000010], + __DSPRegs[0x00000010 + 1]); + OSReport("DI DMA Address = 0x%08x\n", __DIRegs[0x00000005]); + break; + } - OSReport("\nLast interrupt (%d): SRR0 = 0x%08x TB = 0x%016llx\n", __OSLastInterrupt, - __OSLastInterruptSrr0, __OSLastInterruptTime); + OSReport("\nLast interrupt (%d): SRR0 = 0x%08x TB = 0x%016llx\n", __OSLastInterrupt, + __OSLastInterruptSrr0, __OSLastInterruptTime); - PPCHalt(); + PPCHalt(); } diff --git a/libs/dolphin/os/OSFont.c b/libs/dolphin/os/OSFont.c index aa79fb6bc..aaf0a51a6 100644 --- a/libs/dolphin/os/OSFont.c +++ b/libs/dolphin/os/OSFont.c @@ -1,32 +1,760 @@ +#include #include -#include -#include -// there shoudl be more in this file, however this is the only thing that gets used, i'm not gonna add 1000 lines of text that have no value here +#include +#include -u16 OSGetFontEncode() +typedef char* (*ParseStringCallback)(u16, char*, OSFontHeader**, int*); + +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 c) +{ + return (0x40 <= c && c <= 0xFC) && (c != 0x7F); +} + +static int GetFontCode(u16 encode, u16 code) +{ + if (encode == OS_FONT_ENCODE_SJIS) + { + if (code >= 0x20 && code <= 0xDF) + { + return HankakuToCode[code - 0x20]; + } + + if (code > 0x889E && code <= 0x9872) + { + int i = ((code >> 8) - 0x88) * 188; + int j = (code & 0xFF); + + if (!IsSjisTrailByte(j)) + { + return 0; + } + + j -= 0x40; + if (j >= 0x40) + { + j--; + } + + return (i + j + 0x2BE); + } + + if (code >= 0x8140 && code < 0x879E) + { + int i = ((code >> 8) - 0x81) * 188; + int j = (code & 0xFF); + + if (!IsSjisTrailByte(j)) + { + return 0; + } + + j -= 0x40; + if (j >= 0x40) + { + j--; + } + + return Zenkaku2Code[i + j]; + } + } + else if (code > 0x20 && code <= 0xFF) + { + return code - 0x20; + } + + return 0; +} + +static void Decode(u8* s, u8* d) { - static u16 fontEncode = OS_FONT_ENCODE_NULL; + 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; + + os = *(int*)(s + 0x4); + r7 = *(int*)(s + 0x8); + r25 = *(int*)(s + 0xC); + + q = 0; + flag = 0; + p = 16; - if (fontEncode <= 1) + do { - return fontEncode; + // 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); } - switch (__OSTVMode) + return 0; +} + +u16 OSGetFontEncode(void) +{ + if (FontEncode != 0xFFFF) + { + return FontEncode; + } + + switch (*(int*)OSPhysicalToCached(0xCC)) { case VI_NTSC: - fontEncode = (__VIRegs[VI_DTV_STAT] & 2) ? 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: case VI_DEBUG: case VI_DEBUG_PAL: case VI_EURGB60: default: - fontEncode = OS_FONT_ENCODE_ANSI; + FontEncode = OS_FONT_ENCODE_ANSI; + } + + ParseString = (ParseStringCallback)ParseStringS; + return FontEncode; +} + +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 = *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; + } + + *pfont = font; + *pfontCode = GetFontCode(encode, code); + + 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); - return fontEncode; + 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/libs/dolphin/os/OSInterrupt.c b/libs/dolphin/os/OSInterrupt.c index a7bed16a5..12cedc3fa 100644 --- a/libs/dolphin/os/OSInterrupt.c +++ b/libs/dolphin/os/OSInterrupt.c @@ -24,8 +24,9 @@ static OSInterruptMask InterruptPrioTable[] = { 0xFFFFFFFF, }; -asm BOOL OSDisableInterrupts(void) { - // clang-format off +asm BOOL OSDisableInterrupts(void) +{ + // clang-format off nofralloc entry __RAS_OSDisableInterrupts_begin mfmsr r3 @@ -34,10 +35,11 @@ entry __RAS_OSDisableInterrupts_begin entry __RAS_OSDisableInterrupts_end rlwinm r3, r3, 17, 31, 31 blr - // clang-format on + // clang-format on } -asm BOOL OSEnableInterrupts(void) { - // clang-format off +asm BOOL OSEnableInterrupts(void) +{ + // clang-format off nofralloc mfmsr r3 @@ -45,11 +47,11 @@ asm BOOL OSEnableInterrupts(void) { mtmsr r4 rlwinm r3, r3, 17, 31, 31 blr - // clang-format on + // clang-format on } asm BOOL OSRestoreInterrupts(register BOOL level){ - // clang-format off + // clang-format off nofralloc @@ -64,364 +66,374 @@ asm BOOL OSRestoreInterrupts(register BOOL level){ mtmsr r5 rlwinm r3, r4, 17, 31, 31 blr - // clang-format on + // clang-format on } -__OSInterruptHandler - __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler) { - __OSInterruptHandler oldHandler; +__OSInterruptHandler __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler) +{ + __OSInterruptHandler oldHandler; - oldHandler = InterruptHandlerTable[interrupt]; - InterruptHandlerTable[interrupt] = handler; - return oldHandler; + oldHandler = InterruptHandlerTable[interrupt]; + InterruptHandlerTable[interrupt] = handler; + return oldHandler; } -__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt) { - return InterruptHandlerTable[interrupt]; +__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt) +{ + return InterruptHandlerTable[interrupt]; } -void __OSInterruptInit(void) { - InterruptHandlerTable = OSPhysicalToCached(0x3040); - memset(InterruptHandlerTable, 0, __OS_INTERRUPT_MAX * sizeof(__OSInterruptHandler)); +void __OSInterruptInit(void) +{ + InterruptHandlerTable = OSPhysicalToCached(0x3040); + memset(InterruptHandlerTable, 0, __OS_INTERRUPT_MAX * sizeof(__OSInterruptHandler)); - *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = 0; + *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = 0; - *(OSInterruptMask*)OSPhysicalToCached(0x00C8) = 0; + *(OSInterruptMask*)OSPhysicalToCached(0x00C8) = 0; - __PIRegs[1] = 0xf0; + __PIRegs[1] = 0xf0; - __OSMaskInterrupts(OS_INTERRUPTMASK_MEM | OS_INTERRUPTMASK_DSP | OS_INTERRUPTMASK_AI | - OS_INTERRUPTMASK_EXI | OS_INTERRUPTMASK_PI); + __OSMaskInterrupts(OS_INTERRUPTMASK_MEM | OS_INTERRUPTMASK_DSP | OS_INTERRUPTMASK_AI | + OS_INTERRUPTMASK_EXI | OS_INTERRUPTMASK_PI); - __OSSetExceptionHandler(4, ExternalInterruptHandler); + __OSSetExceptionHandler(4, ExternalInterruptHandler); } -u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current) { - u32 reg; - - switch (__cntlzw(mask)) { - 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; - if (!(current & OS_INTERRUPTMASK_MEM_1)) - reg |= 0x2; - if (!(current & OS_INTERRUPTMASK_MEM_2)) - reg |= 0x4; - if (!(current & OS_INTERRUPTMASK_MEM_3)) - reg |= 0x8; - if (!(current & OS_INTERRUPTMASK_MEM_ADDRESS)) - reg |= 0x10; - __MEMRegs[0x0000000e] = (u16)reg; - mask &= ~OS_INTERRUPTMASK_MEM; - break; - 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)) - reg |= 0x10; - if (!(current & OS_INTERRUPTMASK_DSP_ARAM)) - reg |= 0x40; - if (!(current & OS_INTERRUPTMASK_DSP_DSP)) - reg |= 0x100; - __DSPRegs[0x00000005] = (u16)reg; - mask &= ~OS_INTERRUPTMASK_DSP; - break; - case __OS_INTERRUPT_AI_AI: - reg = __AIRegs[0]; - reg &= ~0x2C; - if (!(current & OS_INTERRUPTMASK_AI_AI)) - reg |= 0x4; - __AIRegs[0] = reg; - mask &= ~OS_INTERRUPTMASK_AI; - break; - 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)) - reg |= 0x1; - if (!(current & OS_INTERRUPTMASK_EXI_0_TC)) - reg |= 0x4; - if (!(current & OS_INTERRUPTMASK_EXI_0_EXT)) - reg |= 0x400; - __EXIRegs[0] = reg; - mask &= ~OS_INTERRUPTMASK_EXI_0; - break; - case __OS_INTERRUPT_EXI_1_EXI: - case __OS_INTERRUPT_EXI_1_TC: - case __OS_INTERRUPT_EXI_1_EXT: - reg = __EXIRegs[5]; - reg &= ~0xC0F; - - if (!(current & OS_INTERRUPTMASK_EXI_1_EXI)) - reg |= 0x1; - if (!(current & OS_INTERRUPTMASK_EXI_1_TC)) - reg |= 0x4; - if (!(current & OS_INTERRUPTMASK_EXI_1_EXT)) - reg |= 0x400; - __EXIRegs[5] = reg; - mask &= ~OS_INTERRUPTMASK_EXI_1; - break; - case __OS_INTERRUPT_EXI_2_EXI: - case __OS_INTERRUPT_EXI_2_TC: - reg = __EXIRegs[10]; - reg &= ~0xF; - if (!(current & OS_INTERRUPTMASK_EXI_2_EXI)) - reg |= 0x1; - if (!(current & OS_INTERRUPTMASK_EXI_2_TC)) - reg |= 0x4; - - __EXIRegs[10] = reg; - mask &= ~OS_INTERRUPTMASK_EXI_2; - break; - 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)) { - reg |= 0x800; - } - if (!(current & OS_INTERRUPTMASK_PI_SI)) { - reg |= 0x8; - } - if (!(current & OS_INTERRUPTMASK_PI_DI)) { - reg |= 0x4; - } - if (!(current & OS_INTERRUPTMASK_PI_RSW)) { - reg |= 0x2; - } - if (!(current & OS_INTERRUPTMASK_PI_ERROR)) { - reg |= 0x1; - } - if (!(current & OS_INTERRUPTMASK_PI_VI)) { - reg |= 0x100; - } - if (!(current & OS_INTERRUPTMASK_PI_DEBUG)) { - reg |= 0x1000; - } - if (!(current & OS_INTERRUPTMASK_PI_PE_TOKEN)) { - reg |= 0x200; - } - if (!(current & OS_INTERRUPTMASK_PI_PE_FINISH)) { - reg |= 0x400; - } - if (!(current & OS_INTERRUPTMASK_PI_HSP)) { - reg |= 0x2000; +u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current) +{ + u32 reg; + + switch (__cntlzw(mask)) + { + 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; + if (!(current & OS_INTERRUPTMASK_MEM_1)) + reg |= 0x2; + if (!(current & OS_INTERRUPTMASK_MEM_2)) + reg |= 0x4; + if (!(current & OS_INTERRUPTMASK_MEM_3)) + reg |= 0x8; + if (!(current & OS_INTERRUPTMASK_MEM_ADDRESS)) + reg |= 0x10; + __MEMRegs[0x0000000e] = (u16)reg; + mask &= ~OS_INTERRUPTMASK_MEM; + break; + 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)) + reg |= 0x10; + if (!(current & OS_INTERRUPTMASK_DSP_ARAM)) + reg |= 0x40; + if (!(current & OS_INTERRUPTMASK_DSP_DSP)) + reg |= 0x100; + __DSPRegs[0x00000005] = (u16)reg; + mask &= ~OS_INTERRUPTMASK_DSP; + break; + case __OS_INTERRUPT_AI_AI: + reg = __AIRegs[0]; + reg &= ~0x2C; + if (!(current & OS_INTERRUPTMASK_AI_AI)) + reg |= 0x4; + __AIRegs[0] = reg; + mask &= ~OS_INTERRUPTMASK_AI; + break; + 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)) + reg |= 0x1; + if (!(current & OS_INTERRUPTMASK_EXI_0_TC)) + reg |= 0x4; + if (!(current & OS_INTERRUPTMASK_EXI_0_EXT)) + reg |= 0x400; + __EXIRegs[0] = reg; + mask &= ~OS_INTERRUPTMASK_EXI_0; + break; + case __OS_INTERRUPT_EXI_1_EXI: + case __OS_INTERRUPT_EXI_1_TC: + case __OS_INTERRUPT_EXI_1_EXT: + reg = __EXIRegs[5]; + reg &= ~0xC0F; + + if (!(current & OS_INTERRUPTMASK_EXI_1_EXI)) + reg |= 0x1; + if (!(current & OS_INTERRUPTMASK_EXI_1_TC)) + reg |= 0x4; + if (!(current & OS_INTERRUPTMASK_EXI_1_EXT)) + reg |= 0x400; + __EXIRegs[5] = reg; + mask &= ~OS_INTERRUPTMASK_EXI_1; + break; + case __OS_INTERRUPT_EXI_2_EXI: + case __OS_INTERRUPT_EXI_2_TC: + reg = __EXIRegs[10]; + reg &= ~0xF; + if (!(current & OS_INTERRUPTMASK_EXI_2_EXI)) + reg |= 0x1; + if (!(current & OS_INTERRUPTMASK_EXI_2_TC)) + reg |= 0x4; + + __EXIRegs[10] = reg; + mask &= ~OS_INTERRUPTMASK_EXI_2; + break; + 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)) + { + reg |= 0x800; + } + if (!(current & OS_INTERRUPTMASK_PI_SI)) + { + reg |= 0x8; + } + if (!(current & OS_INTERRUPTMASK_PI_DI)) + { + reg |= 0x4; + } + if (!(current & OS_INTERRUPTMASK_PI_RSW)) + { + reg |= 0x2; + } + if (!(current & OS_INTERRUPTMASK_PI_ERROR)) + { + reg |= 0x1; + } + if (!(current & OS_INTERRUPTMASK_PI_VI)) + { + reg |= 0x100; + } + if (!(current & OS_INTERRUPTMASK_PI_DEBUG)) + { + reg |= 0x1000; + } + if (!(current & OS_INTERRUPTMASK_PI_PE_TOKEN)) + { + reg |= 0x200; + } + if (!(current & OS_INTERRUPTMASK_PI_PE_FINISH)) + { + reg |= 0x400; + } + if (!(current & OS_INTERRUPTMASK_PI_HSP)) + { + reg |= 0x2000; + } + __PIRegs[1] = reg; + mask &= ~OS_INTERRUPTMASK_PI; + break; + default: + break; } - __PIRegs[1] = reg; - mask &= ~OS_INTERRUPTMASK_PI; - break; - default: - break; - } - return mask; -} - -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; + return mask; } -OSInterruptMask __OSMaskInterrupts(OSInterruptMask global) { - BOOL enabled; - OSInterruptMask prev; - OSInterruptMask local; - OSInterruptMask mask; - - enabled = OSDisableInterrupts(); - prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4); - local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8); - mask = ~(prev | local) & global; - global |= prev; - *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global; - while (mask) { - mask = SetInterruptMask(mask, global | local); - } - OSRestoreInterrupts(enabled); - return prev; +OSInterruptMask __OSMaskInterrupts(OSInterruptMask global) +{ + BOOL enabled; + OSInterruptMask prev; + OSInterruptMask local; + OSInterruptMask mask; + + enabled = OSDisableInterrupts(); + prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4); + local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8); + mask = ~(prev | local) & global; + global |= prev; + *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global; + while (mask) + { + mask = SetInterruptMask(mask, global | local); + } + OSRestoreInterrupts(enabled); + return prev; } -OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask global) { - BOOL enabled; - OSInterruptMask prev; - OSInterruptMask local; - OSInterruptMask mask; - - enabled = OSDisableInterrupts(); - prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4); - local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8); - mask = (prev | local) & global; - global = prev & ~global; - *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global; - while (mask) { - mask = SetInterruptMask(mask, global | local); - } - OSRestoreInterrupts(enabled); - return prev; +OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask global) +{ + BOOL enabled; + OSInterruptMask prev; + OSInterruptMask local; + OSInterruptMask mask; + + enabled = OSDisableInterrupts(); + prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4); + local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8); + mask = (prev | local) & global; + global = prev & ~global; + *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global; + while (mask) + { + mask = SetInterruptMask(mask, global | local); + } + OSRestoreInterrupts(enabled); + return prev; } volatile OSTime __OSLastInterruptTime; volatile __OSInterrupt __OSLastInterrupt; volatile u32 __OSLastInterruptSrr0; -void __OSDispatchInterrupt(__OSException exception, OSContext* context) { - u32 intsr; - u32 reg; - OSInterruptMask cause; - OSInterruptMask unmasked; - OSInterruptMask* prio; - __OSInterrupt interrupt; - __OSInterruptHandler handler; - intsr = __PIRegs[0]; - intsr &= ~0x00010000; - - if (intsr == 0 || (intsr & __PIRegs[1]) == 0) { - OSLoadContext(context); - } - - cause = 0; - - if (intsr & 0x00000080) { - reg = __MEMRegs[15]; - if (reg & 0x1) - cause |= OS_INTERRUPTMASK_MEM_0; - if (reg & 0x2) - cause |= OS_INTERRUPTMASK_MEM_1; - if (reg & 0x4) - cause |= OS_INTERRUPTMASK_MEM_2; - if (reg & 0x8) - cause |= OS_INTERRUPTMASK_MEM_3; - if (reg & 0x10) - cause |= OS_INTERRUPTMASK_MEM_ADDRESS; - } - - if (intsr & 0x00000040) { - reg = __DSPRegs[5]; - if (reg & 0x8) - cause |= OS_INTERRUPTMASK_DSP_AI; - if (reg & 0x20) - cause |= OS_INTERRUPTMASK_DSP_ARAM; - if (reg & 0x80) - cause |= OS_INTERRUPTMASK_DSP_DSP; - } - - if (intsr & 0x00000020) { - reg = __AIRegs[0]; - if (reg & 0x8) - cause |= OS_INTERRUPTMASK_AI_AI; - } - - if (intsr & 0x00000010) { - reg = __EXIRegs[0]; - if (reg & 0x2) - cause |= OS_INTERRUPTMASK_EXI_0_EXI; - if (reg & 0x8) - cause |= OS_INTERRUPTMASK_EXI_0_TC; - if (reg & 0x800) - cause |= OS_INTERRUPTMASK_EXI_0_EXT; - reg = __EXIRegs[5]; - if (reg & 0x2) - cause |= OS_INTERRUPTMASK_EXI_1_EXI; - if (reg & 0x8) - cause |= OS_INTERRUPTMASK_EXI_1_TC; - if (reg & 0x800) - cause |= OS_INTERRUPTMASK_EXI_1_EXT; - reg = __EXIRegs[10]; - if (reg & 0x2) - cause |= OS_INTERRUPTMASK_EXI_2_EXI; - if (reg & 0x8) - cause |= OS_INTERRUPTMASK_EXI_2_TC; - } - - if (intsr & 0x00002000) - cause |= OS_INTERRUPTMASK_PI_HSP; - if (intsr & 0x00001000) - cause |= OS_INTERRUPTMASK_PI_DEBUG; - if (intsr & 0x00000400) - cause |= OS_INTERRUPTMASK_PI_PE_FINISH; - if (intsr & 0x00000200) - cause |= OS_INTERRUPTMASK_PI_PE_TOKEN; - if (intsr & 0x00000100) - cause |= OS_INTERRUPTMASK_PI_VI; - if (intsr & 0x00000008) - cause |= OS_INTERRUPTMASK_PI_SI; - if (intsr & 0x00000004) - cause |= OS_INTERRUPTMASK_PI_DI; - if (intsr & 0x00000002) - cause |= OS_INTERRUPTMASK_PI_RSW; - if (intsr & 0x00000800) - cause |= OS_INTERRUPTMASK_PI_CP; - if (intsr & 0x00000001) - cause |= OS_INTERRUPTMASK_PI_ERROR; - - unmasked = cause & ~(*(OSInterruptMask*)OSPhysicalToCached(0x00C4) | - *(OSInterruptMask*)OSPhysicalToCached(0x00C8)); - if (unmasked) { - for (prio = InterruptPrioTable;; ++prio) { - if (unmasked & *prio) { - interrupt = (__OSInterrupt)__cntlzw(unmasked & *prio); - break; - } +void __OSDispatchInterrupt(__OSException exception, OSContext* context) +{ + u32 intsr; + u32 reg; + OSInterruptMask cause; + OSInterruptMask unmasked; + OSInterruptMask* prio; + __OSInterrupt interrupt; + __OSInterruptHandler handler; + intsr = __PIRegs[0]; + intsr &= ~0x00010000; + + if (intsr == 0 || (intsr & __PIRegs[1]) == 0) + { + OSLoadContext(context); + } + + cause = 0; + + if (intsr & 0x00000080) + { + reg = __MEMRegs[15]; + if (reg & 0x1) + cause |= OS_INTERRUPTMASK_MEM_0; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_MEM_1; + if (reg & 0x4) + cause |= OS_INTERRUPTMASK_MEM_2; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_MEM_3; + if (reg & 0x10) + cause |= OS_INTERRUPTMASK_MEM_ADDRESS; + } + + if (intsr & 0x00000040) + { + reg = __DSPRegs[5]; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_DSP_AI; + if (reg & 0x20) + cause |= OS_INTERRUPTMASK_DSP_ARAM; + if (reg & 0x80) + cause |= OS_INTERRUPTMASK_DSP_DSP; + } + + if (intsr & 0x00000020) + { + reg = __AIRegs[0]; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_AI_AI; + } + + if (intsr & 0x00000010) + { + reg = __EXIRegs[0]; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_EXI_0_EXI; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_EXI_0_TC; + if (reg & 0x800) + cause |= OS_INTERRUPTMASK_EXI_0_EXT; + reg = __EXIRegs[5]; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_EXI_1_EXI; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_EXI_1_TC; + if (reg & 0x800) + cause |= OS_INTERRUPTMASK_EXI_1_EXT; + reg = __EXIRegs[10]; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_EXI_2_EXI; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_EXI_2_TC; } - handler = __OSGetInterruptHandler(interrupt); - if (handler) { - if (__OS_INTERRUPT_MEM_ADDRESS < interrupt) { - __OSLastInterrupt = interrupt; - __OSLastInterruptTime = OSGetTime(); - __OSLastInterruptSrr0 = context->srr0; - } - - OSDisableScheduler(); - handler(interrupt, context); - OSEnableScheduler(); - __OSReschedule(); - OSLoadContext(context); + if (intsr & 0x00002000) + cause |= OS_INTERRUPTMASK_PI_HSP; + if (intsr & 0x00001000) + cause |= OS_INTERRUPTMASK_PI_DEBUG; + if (intsr & 0x00000400) + cause |= OS_INTERRUPTMASK_PI_PE_FINISH; + if (intsr & 0x00000200) + cause |= OS_INTERRUPTMASK_PI_PE_TOKEN; + if (intsr & 0x00000100) + cause |= OS_INTERRUPTMASK_PI_VI; + if (intsr & 0x00000008) + cause |= OS_INTERRUPTMASK_PI_SI; + if (intsr & 0x00000004) + cause |= OS_INTERRUPTMASK_PI_DI; + if (intsr & 0x00000002) + cause |= OS_INTERRUPTMASK_PI_RSW; + if (intsr & 0x00000800) + cause |= OS_INTERRUPTMASK_PI_CP; + if (intsr & 0x00000001) + cause |= OS_INTERRUPTMASK_PI_ERROR; + + unmasked = cause & ~(*(OSInterruptMask*)OSPhysicalToCached(0x00C4) | + *(OSInterruptMask*)OSPhysicalToCached(0x00C8)); + if (unmasked) + { + for (prio = InterruptPrioTable;; ++prio) + { + if (unmasked & *prio) + { + interrupt = (__OSInterrupt)__cntlzw(unmasked & *prio); + break; + } + } + + handler = __OSGetInterruptHandler(interrupt); + if (handler) + { + if (__OS_INTERRUPT_MEM_ADDRESS < interrupt) + { + __OSLastInterrupt = interrupt; + __OSLastInterruptTime = OSGetTime(); + __OSLastInterruptSrr0 = context->srr0; + } + + OSDisableScheduler(); + handler(interrupt, context); + OSEnableScheduler(); + __OSReschedule(); + OSLoadContext(context); + } } - } - OSLoadContext(context); + OSLoadContext(context); } static asm void ExternalInterruptHandler(register __OSException exception, - register OSContext* context) { + register OSContext* context) +{ #pragma unused(exception) - // clang-format off + // clang-format off nofralloc OS_EXCEPTION_SAVE_GPRS(context) stwu r1, -8(r1) b __OSDispatchInterrupt - // clang-format on + // clang-format on } diff --git a/libs/dolphin/os/OSLink.c b/libs/dolphin/os/OSLink.c index d6f5a51d7..c035ef60e 100644 --- a/libs/dolphin/os/OSLink.c +++ b/libs/dolphin/os/OSLink.c @@ -1,556 +1,10 @@ #include -#define SHN_UNDEF 0 -#define SHN_LORESERVE 0xff00 -#define SHN_LOPROC 0xff00 -#define SHN_HIPROC 0xff1f -#define SHN_ABS 0xfff1 -#define SHN_COMMON 0xfff2 -#define SHN_HIRESERVE 0xffff - -#define ELF32_R_SYM(i) ((i) >> 8) -#define ELF32_R_TYPE(i) ((unsigned char)(i)) -#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_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_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_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 - OSModuleQueue __OSModuleInfoList : (OS_BASE_CACHED | 0x30C8); const void* __OSStringTable : (OS_BASE_CACHED | 0x30D0); -#pragma dont_inline on -__declspec(weak) void OSNotifyLink(OSModuleInfo* module) {} - -__declspec(weak) void OSNotifyUnlink(OSModuleInfo* module) {} - -#pragma dont_inline reset - -#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) - -#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) - -void OSSetStringTable(const void* stringTable) { __OSStringTable = stringTable; } - -static BOOL Relocate(OSModuleHeader* newModule, OSModuleHeader* module) { - OSModuleID idNew; - OSImportInfo* imp; - OSRel* rel; - OSSectionInfo* si; - OSSectionInfo* siFlush; - u32* p; - u32 offset; - u32 x; - - idNew = newModule ? newModule->info.id : 0; - for (imp = (OSImportInfo*)module->impOffset; - imp < (OSImportInfo*)(module->impOffset + module->impSize); imp++) { - if (imp->id == idNew) { - goto Found; - } - } - return FALSE; - -Found: - siFlush = 0; - for (rel = (OSRel*)imp->offset; rel->type != R_DOLPHIN_END; rel++) { - (u8*)p += rel->offset; - if (idNew) { - si = &OSGetSectionInfo(newModule)[rel->section]; - offset = OS_SECTIONINFO_OFFSET(si->offset); - } else { - offset = 0; - } - switch (rel->type) { - case R_PPC_NONE: - break; - case R_PPC_ADDR32: - x = offset + rel->addend; - *p = x; - break; - case R_PPC_ADDR24: - x = offset + rel->addend; - *p = (*p & ~0x03fffffc) | (x & 0x03fffffc); - break; - case R_PPC_ADDR16: - x = offset + rel->addend; - *(u16*)p = (u16)(x & 0xffff); - break; - case R_PPC_ADDR16_LO: - x = offset + rel->addend; - *(u16*)p = (u16)(x & 0xffff); - break; - case R_PPC_ADDR16_HI: - x = offset + rel->addend; - *(u16*)p = (u16)(((x >> 16) & 0xffff)); - break; - case R_PPC_ADDR16_HA: - x = offset + rel->addend; - *(u16*)p = (u16)(((x >> 16) + ((x & 0x8000) ? 1 : 0)) & 0xffff); - break; - case R_PPC_ADDR14: - case R_PPC_ADDR14_BRTAKEN: - case R_PPC_ADDR14_BRNTAKEN: - x = offset + rel->addend; - *p = (*p & ~0x0000fffc) | (x & 0x0000fffc); - break; - case R_PPC_REL24: - x = offset + rel->addend - (u32)p; - *p = (*p & ~0x03fffffc) | (x & 0x03fffffc); - break; - case R_PPC_REL14: - case R_PPC_REL14_BRTAKEN: - case R_PPC_REL14_BRNTAKEN: - x = offset + rel->addend - (u32)p; - *p = (*p & ~0x0000fffc) | (x & 0x0000fffc); - break; - case R_DOLPHIN_NOP: - break; - case R_DOLPHIN_SECTION: - si = &OSGetSectionInfo(module)[rel->section]; - p = (u32*)OS_SECTIONINFO_OFFSET(si->offset); - if (siFlush) { - offset = OS_SECTIONINFO_OFFSET(siFlush->offset); - DCFlushRange((void*)offset, siFlush->size); - ICInvalidateRange((void*)offset, siFlush->size); - } - siFlush = (si->offset & OS_SECTIONINFO_EXEC) ? si : 0; - break; - default: - OSReport("OSLink: unknown relocation type %3d\n", rel->type); - break; - } - } - - if (siFlush) { - offset = OS_SECTIONINFO_OFFSET(siFlush->offset); - DCFlushRange((void*)offset, siFlush->size); - ICInvalidateRange((void*)offset, siFlush->size); - } - - return TRUE; -} - -#if OS_MODULE_VERSION >= 3 -static BOOL Link(OSModuleInfo* newModule, void* bss, BOOL fixed) { - u32 i; - OSSectionInfo* si; - OSModuleHeader* moduleHeader; - OSModuleInfo* moduleInfo; - OSImportInfo* imp; - - moduleHeader = (OSModuleHeader*)newModule; - moduleHeader->bssSection = 0; - - if (OS_MODULE_VERSION < newModule->version || - 2 <= newModule->version && - (moduleHeader->align && (u32)newModule % moduleHeader->align != 0 || - moduleHeader->bssAlign && (u32)bss % moduleHeader->bssAlign != 0)) { - return FALSE; - } - - EnqueueTail(&__OSModuleInfoList, newModule, link); - newModule->sectionInfoOffset += (u32)moduleHeader; - moduleHeader->relOffset += (u32)moduleHeader; - moduleHeader->impOffset += (u32)moduleHeader; - if (3 <= newModule->version) { - moduleHeader->fixSize += (u32)moduleHeader; - } - for (i = 1; i < newModule->numSections; i++) { - si = &OSGetSectionInfo(newModule)[i]; - if (si->offset != 0) { - si->offset += (u32)moduleHeader; - } else if (si->size != 0) { - moduleHeader->bssSection = (u8)i; - si->offset = (u32)bss; - bss = (void*)((u32)bss + si->size); - } - } - for (imp = (OSImportInfo*)moduleHeader->impOffset; - imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) { - imp->offset += (u32)moduleHeader; - } - if (moduleHeader->prologSection != SHN_UNDEF) { - moduleHeader->prolog += - OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->prologSection].offset); - } - if (moduleHeader->epilogSection != SHN_UNDEF) { - moduleHeader->epilog += - OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->epilogSection].offset); - } - if (moduleHeader->unresolvedSection != SHN_UNDEF) { - moduleHeader->unresolved += - OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->unresolvedSection].offset); - } - if (__OSStringTable) { - newModule->nameOffset += (u32)__OSStringTable; - } - - Relocate(0, moduleHeader); - - for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) { - Relocate(moduleHeader, (OSModuleHeader*)moduleInfo); - if (moduleInfo != newModule) { - Relocate((OSModuleHeader*)moduleInfo, moduleHeader); - } - } - - if (fixed) { - for (imp = (OSImportInfo*)moduleHeader->impOffset; - imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) { - if (imp->id == 0 || imp->id == newModule->id) { - moduleHeader->impSize = (u32)((u8*)imp - (u8*)moduleHeader->impOffset); - break; - } - } - } - - memset(bss, 0, moduleHeader->bssSize); - - OSNotifyLink(newModule); - - return TRUE; -} - -BOOL OSLink(OSModuleInfo* newModule, void* bss) { return Link(newModule, bss, FALSE); } - -BOOL OSLinkFixed(OSModuleInfo* newModule, void* bss) { - if (OS_MODULE_VERSION < newModule->version || newModule->version < 3) { - return FALSE; - } - return Link(newModule, bss, TRUE); -} -#else -BOOL OSLink(OSModuleInfo* newModule, void* bss) { - u32 i; - OSSectionInfo* si; - OSModuleHeader* moduleHeader; - OSModuleInfo* moduleInfo; - OSImportInfo* imp; - - moduleHeader = (OSModuleHeader*)newModule; - moduleHeader->bssSection = 0; - - if (OS_MODULE_VERSION < newModule->version || - 2 <= newModule->version && - (moduleHeader->align && (u32)newModule % moduleHeader->align != 0 || - moduleHeader->bssAlign && (u32)bss % moduleHeader->bssAlign != 0)) { - return FALSE; - } - - EnqueueTail(&__OSModuleInfoList, newModule, link); - memset(bss, 0, moduleHeader->bssSize); - newModule->sectionInfoOffset += (u32)moduleHeader; - moduleHeader->relOffset += (u32)moduleHeader; - moduleHeader->impOffset += (u32)moduleHeader; - - for (i = 1; i < newModule->numSections; i++) { - si = &OSGetSectionInfo(newModule)[i]; - if (si->offset != 0) { - si->offset += (u32)moduleHeader; - } else if (si->size != 0) { - moduleHeader->bssSection = (u8)i; - si->offset = (u32)bss; - bss = (void*)((u32)bss + si->size); - } - } - for (imp = (OSImportInfo*)moduleHeader->impOffset; - imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) { - imp->offset += (u32)moduleHeader; - } - if (moduleHeader->prologSection != SHN_UNDEF) { - moduleHeader->prolog += - OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->prologSection].offset); - } - if (moduleHeader->epilogSection != SHN_UNDEF) { - moduleHeader->epilog += - OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->epilogSection].offset); - } - if (moduleHeader->unresolvedSection != SHN_UNDEF) { - moduleHeader->unresolved += - OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->unresolvedSection].offset); - } - if (__OSStringTable) { - newModule->nameOffset += (u32)__OSStringTable; - } - - Relocate(0, moduleHeader); - - for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) { - Relocate(moduleHeader, (OSModuleHeader*)moduleInfo); - if (moduleInfo != newModule) { - Relocate((OSModuleHeader*)moduleInfo, moduleHeader); - } - } - - OSNotifyLink(newModule); - - return TRUE; -} -#endif - -static BOOL Undo(OSModuleHeader* newModule, OSModuleHeader* module) { - OSModuleID idNew; - OSImportInfo* imp; - OSRel* rel; - OSSectionInfo* si; - OSSectionInfo* siFlush; - u32* p; - u32 offset; - u32 x; - - idNew = newModule->info.id; - for (imp = (OSImportInfo*)module->impOffset; - imp < (OSImportInfo*)(module->impOffset + module->impSize); imp++) { - if (imp->id == idNew) { - goto Found; - } - } - return FALSE; - -Found: - siFlush = 0; - for (rel = (OSRel*)imp->offset; rel->type != R_DOLPHIN_END; rel++) { - (u8*)p += rel->offset; - si = &OSGetSectionInfo(newModule)[rel->section]; - offset = OS_SECTIONINFO_OFFSET(si->offset); - x = 0; - switch (rel->type) { - case R_PPC_NONE: - break; - case R_PPC_ADDR32: - *p = x; - break; - case R_PPC_ADDR24: - *p = (*p & ~0x03fffffc) | (x & 0x03fffffc); - break; - case R_PPC_ADDR16: - *(u16*)p = (u16)(x & 0xffff); - break; - case R_PPC_ADDR16_LO: - *(u16*)p = (u16)(x & 0xffff); - break; - case R_PPC_ADDR16_HI: - *(u16*)p = (u16)(((x >> 16) & 0xffff)); - break; - case R_PPC_ADDR16_HA: - *(u16*)p = (u16)(((x >> 16) + ((x & 0x8000) ? 1 : 0)) & 0xffff); - break; - case R_PPC_ADDR14: - case R_PPC_ADDR14_BRTAKEN: - case R_PPC_ADDR14_BRNTAKEN: - *p = (*p & ~0x0000fffc) | (x & 0x0000fffc); - break; - case R_PPC_REL24: - if (module->unresolvedSection != SHN_UNDEF) { - x = (u32)module->unresolved - (u32)p; - } - *p = (*p & ~0x03fffffc) | (x & 0x03fffffc); - break; - case R_PPC_REL14: - case R_PPC_REL14_BRTAKEN: - case R_PPC_REL14_BRNTAKEN: - *p = (*p & ~0x0000fffc) | (x & 0x0000fffc); - break; - case R_DOLPHIN_NOP: - break; - case R_DOLPHIN_SECTION: - si = &OSGetSectionInfo(module)[rel->section]; - p = (u32*)OS_SECTIONINFO_OFFSET(si->offset); - if (siFlush) { - offset = OS_SECTIONINFO_OFFSET(siFlush->offset); - DCFlushRange((void*)offset, siFlush->size); - ICInvalidateRange((void*)offset, siFlush->size); - } - siFlush = (si->offset & OS_SECTIONINFO_EXEC) ? si : 0; - break; - default: - OSReport("OSUnlink: unknown relocation type %3d\n", rel->type); - break; - } - } - - if (siFlush) { - offset = OS_SECTIONINFO_OFFSET(siFlush->offset); - DCFlushRange((void*)offset, siFlush->size); - ICInvalidateRange((void*)offset, siFlush->size); - } - - return TRUE; -} - -BOOL OSUnlink(OSModuleInfo* oldModule) { - OSModuleHeader* moduleHeader; - OSModuleInfo* moduleInfo; - u32 i; - OSSectionInfo* si; - OSImportInfo* imp; - - moduleHeader = (OSModuleHeader*)oldModule; - - DequeueItem(&__OSModuleInfoList, oldModule, link); - - for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) { - Undo(moduleHeader, (OSModuleHeader*)moduleInfo); - } - - OSNotifyUnlink(oldModule); - - if (__OSStringTable) { - oldModule->nameOffset -= (u32)__OSStringTable; - } - if (moduleHeader->prologSection != SHN_UNDEF) { - moduleHeader->prolog -= - OS_SECTIONINFO_OFFSET(OSGetSectionInfo(oldModule)[moduleHeader->prologSection].offset); - } - if (moduleHeader->epilogSection != SHN_UNDEF) { - moduleHeader->epilog -= - OS_SECTIONINFO_OFFSET(OSGetSectionInfo(oldModule)[moduleHeader->epilogSection].offset); - } - if (moduleHeader->unresolvedSection != SHN_UNDEF) { - moduleHeader->unresolved -= - OS_SECTIONINFO_OFFSET(OSGetSectionInfo(oldModule)[moduleHeader->unresolvedSection].offset); - } - for (imp = (OSImportInfo*)moduleHeader->impOffset; - imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) { - imp->offset -= (u32)moduleHeader; - } - for (i = 1; i < oldModule->numSections; i++) { - si = &OSGetSectionInfo(oldModule)[i]; - if (i == moduleHeader->bssSection) { - moduleHeader->bssSection = 0; - si->offset = 0; - } else if (si->offset != 0) { - si->offset -= (u32)moduleHeader; - } - } - moduleHeader->relOffset -= (u32)moduleHeader; - moduleHeader->impOffset -= (u32)moduleHeader; - oldModule->sectionInfoOffset -= (u32)moduleHeader; - - return TRUE; -} - -void __OSModuleInit(void) { - __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; - } - - for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) { - sectionInfo = OSGetSectionInfo(moduleInfo); - for (i = 0; i < moduleInfo->numSections; ++i) { - if (sectionInfo->size) { - baseSection = OS_SECTIONINFO_OFFSET(sectionInfo->offset); - if (baseSection <= (u32)ptr && (u32)ptr < baseSection + sectionInfo->size) { - if (section) { - *section = i; - } - if (offset) { - *offset = (u32)ptr - baseSection; - } - return moduleInfo; - } - } - sectionInfo++; - } - } - - return NULL; +void __OSModuleInit(void) +{ + __OSModuleInfoList.head = __OSModuleInfoList.tail = 0; + __OSStringTable = 0; } diff --git a/libs/dolphin/os/OSMemory.c b/libs/dolphin/os/OSMemory.c index 71d3097af..9fed89b6d 100644 --- a/libs/dolphin/os/OSMemory.c +++ b/libs/dolphin/os/OSMemory.c @@ -1,4 +1,5 @@ #include +#include #define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) #define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) @@ -12,72 +13,47 @@ static OSResetFunctionInfo ResetFunctionInfo = { 127, }; -u32 OSGetPhysicalMemSize() { return *(u32 *)(OSPhysicalToCached(0x0028)); } - -u32 OSGetConsoleSimulatedMemSize() { return *(u32 *)(OSPhysicalToCached(0x00F0)); } - -static BOOL OnReset(BOOL final) { - if (final != FALSE) { - __MEMRegs[8] = 0xFF; - __OSMaskInterrupts(0xf0000000); - } - return TRUE; +// u32 OSGetPhysicalMemSize() +// { +// return *(u32*)(OSPhysicalToCached(0x0028)); +// } + +// u32 OSGetConsoleSimulatedMemSize() +// { +// return *(u32*)(OSPhysicalToCached(0x00F0)); +// } + +static BOOL OnReset(BOOL final) +{ + if (final != FALSE) + { + __MEMRegs[8] = 0xFF; + __OSMaskInterrupts(0xf0000000); + } + return TRUE; } -static void MEMIntrruptHandler(__OSInterrupt interrupt, OSContext* context) { - u32 addr; - u32 cause; +static void MEMIntrruptHandler(__OSInterrupt interrupt, OSContext* context) +{ + u32 addr; + u32 cause; - cause = __MEMRegs[0xf]; - addr = (((u32)__MEMRegs[0x12] & 0x3ff) << 16) | __MEMRegs[0x11]; - __MEMRegs[0x10] = 0; + cause = __MEMRegs[0xf]; + addr = (((u32)__MEMRegs[0x12] & 0x3ff) << 16) | __MEMRegs[0x11]; + __MEMRegs[0x10] = 0; - if (__OSErrorTable[OS_ERROR_PROTECTION]) { - __OSErrorTable[OS_ERROR_PROTECTION](OS_ERROR_PROTECTION, context, cause, addr); - return; - } + if (__OSErrorTable[OS_ERROR_PROTECTION]) + { + __OSErrorTable[OS_ERROR_PROTECTION](OS_ERROR_PROTECTION, context, cause, addr); + return; + } - __OSUnhandledException(OS_ERROR_PROTECTION, context, cause, addr); + __OSUnhandledException(OS_ERROR_PROTECTION, context, cause, addr); } -void OSProtectRange(u32 chan, void* addr, u32 nBytes, u32 control) { - BOOL enabled; - u32 start; - u32 end; - u16 reg; - if (4 <= chan) { - return; - } - - control &= OS_PROTECT_CONTROL_RDWR; - - end = (u32)addr + nBytes; - start = TRUNC(addr, 1u << 10); - end = ROUND(end, 1u << 10); - - DCFlushRange((void*)start, end - start); - - enabled = OSDisableInterrupts(); - - __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 |= control << 2 * chan; - __MEMRegs[8] = reg; - - if (control != OS_PROTECT_CONTROL_RDWR) { - __OSUnmaskInterrupts(OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_0 + chan)); - } - - OSRestoreInterrupts(enabled); -} - -asm void Config24MB() { - // clang-format off +asm void Config24MB() +{ + // clang-format off nofralloc addi r7,r0,0 @@ -121,11 +97,12 @@ asm void Config24MB() { mflr r3 mtsrr0 r3 rfi - // clang-format on + // clang-format on } -asm void Config48MB() { - // clang-format off +asm void Config48MB() +{ + // clang-format off nofralloc addi r7,r0,0x0000 @@ -169,11 +146,12 @@ asm void Config48MB() { mflr r3 mtsrr0 r3 rfi - // clang-format on + // clang-format on } -asm void RealMode(register u32 addr) { - // clang-format off +asm void RealMode(register u32 addr) +{ + // clang-format off nofralloc clrlwi r3, r3, 2 mtsrr0 r3 @@ -181,43 +159,45 @@ asm void RealMode(register u32 addr) { rlwinm r3, r3, 0, 28, 25 mtsrr1 r3 rfi - // clang-format on + // clang-format on } -void __OSInitMemoryProtection() { - u32 padding[8]; - u32 simulatedSize; - BOOL enabled; - simulatedSize = OSGetConsoleSimulatedMemSize(); - enabled = OSDisableInterrupts(); - - __MEMRegs[16] = 0; - __MEMRegs[8] = 0xFF; - - __OSMaskInterrupts(OS_INTERRUPTMASK_MEM_0 | OS_INTERRUPTMASK_MEM_1 | OS_INTERRUPTMASK_MEM_2 | - OS_INTERRUPTMASK_MEM_3); - __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) { - DCInvalidateRange((void*)0x81800000, 0x1800000); - __MEMRegs[20] = 2; - } - - if (simulatedSize <= 0x1800000) - { - RealMode((u32)&Config24MB); - } - else if (simulatedSize <= 0x3000000) - { - RealMode((u32)&Config48MB); - } - - __OSUnmaskInterrupts(OS_INTERRUPTMASK_MEM_ADDRESS); - OSRestoreInterrupts(enabled); +void __OSInitMemoryProtection() +{ + u32 padding[12]; + u32 simulatedSize; + BOOL enabled; + simulatedSize = *(u32*)(OSPhysicalToCached(0x00F0)); + enabled = OSDisableInterrupts(); + + __MEMRegs[16] = 0; + __MEMRegs[8] = 0xFF; + + __OSMaskInterrupts(OS_INTERRUPTMASK_MEM_0 | OS_INTERRUPTMASK_MEM_1 | OS_INTERRUPTMASK_MEM_2 | + OS_INTERRUPTMASK_MEM_3); + __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 (*(u32*)(OSPhysicalToCached(0x00F0)) < *(u32*)(OSPhysicalToCached(0x0028)) && + *(u32*)(OSPhysicalToCached(0x00F0)) == 0x1800000) + { + DCInvalidateRange((void*)0x81800000, 0x1800000); + __MEMRegs[20] = 2; + } + + if (simulatedSize <= 0x1800000) + { + RealMode((u32)&Config24MB); + } + else if (simulatedSize <= 0x3000000) + { + RealMode((u32)&Config48MB); + } + + __OSUnmaskInterrupts(OS_INTERRUPTMASK_MEM_ADDRESS); + OSRestoreInterrupts(enabled); } diff --git a/libs/dolphin/os/OSMutex.c b/libs/dolphin/os/OSMutex.c index f853729e0..adfa396ab 100644 --- a/libs/dolphin/os/OSMutex.c +++ b/libs/dolphin/os/OSMutex.c @@ -1,223 +1,63 @@ #include "dolphin/os.h" #define PushTail(queue, mutex, link) \ - do { \ - OSMutex* __prev; \ + 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) + __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) #define PopHead(queue, mutex, link) \ - do { \ - OSMutex* __next; \ + 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) + (mutex) = (queue)->head; \ + __next = (mutex)->link.next; \ + if (__next == NULL) \ + (queue)->tail = NULL; \ + else \ + __next->link.prev = NULL; \ + (queue)->head = __next; \ + } while (0) #define PopItem(queue, mutex, link) \ - do { \ - OSMutex* __next; \ - OSMutex* __prev; \ + do \ + { \ + OSMutex* __next; \ + OSMutex* __prev; \ \ - __next = (mutex)->link.next; \ - __prev = (mutex)->link.prev; \ + __next = (mutex)->link.next; \ + __prev = (mutex)->link.prev; \ \ - if (__next == NULL) \ - (queue)->tail = __prev; \ - else \ - __next->link.prev = __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) - -void OSInitMutex(OSMutex* mutex) { - OSInitThreadQueue(&mutex->queue); - mutex->thread = 0; - mutex->count = 0; -} - -void OSLockMutex(OSMutex* mutex) { - BOOL enabled = OSDisableInterrupts(); - OSThread* currentThread = OSGetCurrentThread(); - OSThread* ownerThread; - - while (TRUE) { - ownerThread = ((OSMutex*)mutex)->thread; - if (ownerThread == 0) { - mutex->thread = currentThread; - mutex->count++; - PushTail(¤tThread->queueMutex, mutex, link); - break; - } else if (ownerThread == currentThread) { - mutex->count++; - break; - } else { - currentThread->mutex = mutex; - __OSPromoteThread(mutex->thread, currentThread->priority); - OSSleepThread(&mutex->queue); - currentThread->mutex = 0; - } - } - OSRestoreInterrupts(enabled); -} - -void OSUnlockMutex(OSMutex* mutex) { - BOOL enabled = OSDisableInterrupts(); - OSThread* currentThread = OSGetCurrentThread(); - - if (mutex->thread == currentThread && --mutex->count == 0) { - PopItem(¤tThread->queueMutex, mutex, link); - mutex->thread = NULL; - if (currentThread->priority < currentThread->base) { - currentThread->priority = __OSGetEffectivePriority(currentThread); - } - - OSWakeupThread(&mutex->queue); - } - OSRestoreInterrupts(enabled); -} - -void __OSUnlockAllMutex(OSThread* thread) { - OSMutex* mutex; - - while (thread->queueMutex.head) { - PopHead(&thread->queueMutex, mutex, link); - mutex->count = 0; - mutex->thread = NULL; - OSWakeupThread(&mutex->queue); - } -} - -BOOL OSTryLockMutex(OSMutex* mutex) { - BOOL enabled = OSDisableInterrupts(); - OSThread* currentThread = OSGetCurrentThread(); - BOOL locked; - if (mutex->thread == 0) { - mutex->thread = currentThread; - mutex->count++; - PushTail(¤tThread->queueMutex, mutex, link); - locked = TRUE; - } else if (mutex->thread == currentThread) { - mutex->count++; - locked = TRUE; - } else { - locked = FALSE; - } - OSRestoreInterrupts(enabled); - return locked; -} - -void OSInitCond(OSCond* cond) { OSInitThreadQueue(&cond->queue); } - -void OSWaitCond(OSCond* cond, OSMutex* mutex) { - BOOL enabled = OSDisableInterrupts(); - OSThread* currentThread = OSGetCurrentThread(); - s32 count; - - if (mutex->thread == currentThread) { - count = mutex->count; - mutex->count = 0; - PopItem(¤tThread->queueMutex, mutex, link); - mutex->thread = NULL; - - if (currentThread->priority < currentThread->base) { - currentThread->priority = __OSGetEffectivePriority(currentThread); + if (__prev == NULL) \ + (queue)->head = __next; \ + else \ + __prev->link.next = __next; \ + } while (0) + +void __OSUnlockAllMutex(OSThread* thread) +{ + OSMutex* mutex; + + while (thread->queueMutex.head) + { + PopHead(&thread->queueMutex, mutex, link); + mutex->count = 0; + mutex->thread = NULL; + OSWakeupThread(&mutex->queue); } - - OSDisableScheduler(); - OSWakeupThread(&mutex->queue); - OSEnableScheduler(); - OSSleepThread(&cond->queue); - OSLockMutex(mutex); - mutex->count = count; - } - - OSRestoreInterrupts(enabled); -} - -void OSSignalCond(OSCond* cond) { OSWakeupThread(&cond->queue); } - -static BOOL IsMember(OSMutexQueue* queue, OSMutex* mutex) { - OSMutex* member; - - for (member = queue->head; member; member = member->link.next) { - if (mutex == member) - return TRUE; - } - return FALSE; -} - -BOOL __OSCheckMutex(OSMutex* mutex) { - OSThread* thread; - OSThreadQueue* queue; - OSPriority 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->priority < priority) - return FALSE; - priority = thread->priority; - } - - if (mutex->thread) { - if (mutex->count <= 0) - return FALSE; - } else { - if (0 != mutex->count) - return FALSE; - } - - return TRUE; -} - -BOOL __OSCheckDeadLock(OSThread* thread) { - OSMutex* mutex; - - mutex = thread->mutex; - while (mutex && mutex->thread) { - if (mutex->thread == thread) - return TRUE; - mutex = mutex->thread->mutex; - } - return FALSE; -} - -BOOL __OSCheckMutexes(OSThread* thread) { - OSMutex* mutex; - - for (mutex = thread->queueMutex.head; mutex; mutex = mutex->link.next) { - if (mutex->thread != thread) - return FALSE; - if (!__OSCheckMutex(mutex)) - return FALSE; - } - return TRUE; } diff --git a/libs/dolphin/os/OSReset.c b/libs/dolphin/os/OSReset.c index 1194de004..8a9a2bd34 100644 --- a/libs/dolphin/os/OSReset.c +++ b/libs/dolphin/os/OSReset.c @@ -4,76 +4,88 @@ #include "dolphin/hw_regs.h" volatile u8 DAT_800030e2 : 0x800030e2; -typedef struct Unk { - u8 pad[0x24]; - u32 resetCode; +typedef struct Unk +{ + u8 pad[0x24]; + u32 resetCode; } Unk; volatile Unk DAT_cc003000 : 0xcc003000; -typedef struct Unk2 { - u16 _0; - u16 _2; +typedef struct Unk2 +{ + u16 _0; + u16 _2; } Unk2; volatile Unk2 DAT_cc002000 : 0xcc002000; -typedef struct OSResetQueue { - OSResetFunctionInfo* first; - OSResetFunctionInfo* last; +typedef struct OSResetQueue +{ + OSResetFunctionInfo* first; + OSResetFunctionInfo* last; } OSResetQueue; static OSResetQueue ResetFunctionQueue; static u32 bootThisDol; -void OSRegisterResetFunction(OSResetFunctionInfo* func) { - OSResetFunctionInfo* tmp; - OSResetFunctionInfo* iter; +void OSRegisterResetFunction(OSResetFunctionInfo* func) +{ + OSResetFunctionInfo* tmp; + OSResetFunctionInfo* iter; - for (iter = ResetFunctionQueue.first; iter && iter->priority <= func->priority; iter = iter->next) - ; + for (iter = ResetFunctionQueue.first; iter && iter->priority <= func->priority; + iter = iter->next) + ; - if (iter == NULL) { - tmp = ResetFunctionQueue.last; - if (tmp == NULL) { - ResetFunctionQueue.first = func; - } else { - tmp->next = func; + 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; } + + func->next = iter; + tmp = iter->prev; + iter->prev = func; func->prev = tmp; - func->next = NULL; - ResetFunctionQueue.last = func; - return; - } - - func->next = iter; - tmp = iter->prev; - iter->prev = func; - func->prev = tmp; - if (tmp == NULL) { - ResetFunctionQueue.first = func; - return; - } - tmp->next = func; + if (tmp == NULL) + { + ResetFunctionQueue.first = func; + return; + } + tmp->next = func; } -BOOL __OSCallResetFunctions(u32 arg0) { - OSResetFunctionInfo *info; - s32 err = 0; - - for (info = ResetFunctionQueue.first; info != NULL && err == 0; info = info->next) - { - err |= !info->func(arg0); - } - err |= !__OSSyncSram() ; - if (err) - { - return 0; - } - return 1; +BOOL __OSCallResetFunctions(u32 arg0) +{ + OSResetFunctionInfo* info; + s32 err = 0; + + for (info = ResetFunctionQueue.first; info != NULL && err == 0; info = info->next) + { + err |= !info->func(arg0); + } + err |= !__OSSyncSram(); + if (err) + { + return 0; + } + return 1; } -asm void Reset(register s32 resetCode) { - // clang-format off +asm void Reset(register s32 resetCode) +{ + // clang-format off nofralloc b lbl_8038315C lbl_80383140: @@ -112,100 +124,106 @@ asm void Reset(register s32 resetCode) { b lbl_803831A0 lbl_803831A8: b lbl_80383140 - // clang-format on + // clang-format on } OSThreadQueue __OSActiveThreadQueue : (OS_BASE_CACHED | 0x00DC); -static void KillThreads(void) { - OSThread* thread; - OSThread* next; - - for (thread = __OSActiveThreadQueue.head; thread; thread = next) { - next = thread->linkActive.next; - switch (thread->state) { - case 1: - case 4: - OSCancelThread(thread); - break; - default: - break; +static void KillThreads(void) +{ + OSThread* thread; + OSThread* next; + + for (thread = __OSActiveThreadQueue.head; thread; thread = next) + { + next = thread->linkActive.next; + switch (thread->state) + { + case 1: + case 4: + OSCancelThread(thread); + break; + default: + break; + } } - } } -void __OSDoHotReset(s32 arg0) { - OSDisableInterrupts(); - __VIRegs[1] = 0; - ICFlashInvalidate(); - Reset(arg0 * 8); +void __OSDoHotReset(s32 arg0) +{ + OSDisableInterrupts(); + __VIRegs[1] = 0; + ICFlashInvalidate(); + Reset(arg0 * 8); } void OSResetSystem(int reset, u32 resetCode, BOOL forceMenu) { - BOOL rc; - BOOL disableRecalibration; - u32 unk[3]; // dumb compiler + BOOL rc; + BOOL disableRecalibration; + u32 unk[3]; // dumb compiler - OSDisableScheduler(); - __OSStopAudioSystem(); + OSDisableScheduler(); + __OSStopAudioSystem(); - if (reset == OS_RESET_SHUTDOWN || (reset == OS_RESET_RESTART && bootThisDol != 0)) - { - disableRecalibration = __PADDisableRecalibration(TRUE); - } + if (reset == OS_RESET_SHUTDOWN || (reset == OS_RESET_RESTART && bootThisDol != 0)) + { + disableRecalibration = __PADDisableRecalibration(TRUE); + } - while (!__OSCallResetFunctions(FALSE)) - { - ; - } + while (!__OSCallResetFunctions(FALSE)) + { + ; + } - if (reset == OS_RESET_HOTRESET && forceMenu) - { - OSSram *sram; + if (reset == OS_RESET_HOTRESET && forceMenu) + { + OSSram* sram; + + sram = __OSLockSram(); + sram->flags |= 0x40; + __OSUnlockSram(TRUE); - sram = __OSLockSram(); - sram->flags |= 0x40; - __OSUnlockSram(TRUE); + while (!__OSSyncSram()) + { + ; + } + } - while (!__OSSyncSram()) + OSDisableInterrupts(); + __OSCallResetFunctions(TRUE); + LCDisable(); + if (reset == OS_RESET_HOTRESET) { - ; + __OSDoHotReset(resetCode); } - } - - OSDisableInterrupts(); - __OSCallResetFunctions(TRUE); - LCDisable(); - if (reset == OS_RESET_HOTRESET) - { - __OSDoHotReset(resetCode); - } - else if (reset == OS_RESET_RESTART) - { - if ((*(u32 *)OSPhysicalToCached(0x30EC) = bootThisDol) != 0) + else if (reset == OS_RESET_RESTART) { - __PADDisableRecalibration(disableRecalibration); + if ((*(u32*)OSPhysicalToCached(0x30EC) = bootThisDol) != 0) + { + __PADDisableRecalibration(disableRecalibration); + } + KillThreads(); + OSEnableScheduler(); + __OSReboot(resetCode, forceMenu); } + KillThreads(); - OSEnableScheduler(); - __OSReboot(resetCode, forceMenu); - } - - KillThreads(); - memset(OSPhysicalToCached(0x40), 0, 0xCC - 0x40); - memset(OSPhysicalToCached(0xD4), 0, 0xE8 - 0xD4); - memset(OSPhysicalToCached(0xF4), 0, 0xF8 - 0xF4); - memset(OSPhysicalToCached(0x3000), 0, 0xC0); - memset(OSPhysicalToCached(0x30C8), 0, 0xD4 - 0xC8); - memset(OSPhysicalToCached(0x30E2), 0, 1); - - __PADDisableRecalibration(disableRecalibration); + memset(OSPhysicalToCached(0x40), 0, 0xCC - 0x40); + memset(OSPhysicalToCached(0xD4), 0, 0xE8 - 0xD4); + memset(OSPhysicalToCached(0xF4), 0, 0xF8 - 0xF4); + memset(OSPhysicalToCached(0x3000), 0, 0xC0); + memset(OSPhysicalToCached(0x30C8), 0, 0xD4 - 0xC8); + memset(OSPhysicalToCached(0x30E2), 0, 1); + + __PADDisableRecalibration(disableRecalibration); } -u32 OSGetResetCode(void) { - if (DAT_800030e2 != 0) { - return 0x80000000; - } - return ((DAT_cc003000.resetCode & ~7) >> 3); +u32 OSGetResetCode(void) +{ + if (DAT_800030e2 != 0) + { + return 0x80000000; + } + return ((DAT_cc003000.resetCode & ~7) >> 3); } diff --git a/libs/dolphin/os/OSResetSW.c b/libs/dolphin/os/OSResetSW.c index 24766fd35..62897d2b8 100644 --- a/libs/dolphin/os/OSResetSW.c +++ b/libs/dolphin/os/OSResetSW.c @@ -14,7 +14,7 @@ static BOOL LastState; static OSTime HoldUp; static OSTime HoldDown; -void __OSResetSWInterruptHandler(__OSInterrupt interrupt, OSContext *context) +void __OSResetSWInterruptHandler(__OSInterrupt interrupt, OSContext* context) { OSResetCallback callback; @@ -88,9 +88,9 @@ BOOL OSGetResetButtonState(void) LastState = state; - if (GameChoice & 0x1f) + if (GameChoice & 0x3f) { - OSTime fire = (GameChoice & 0x1f) * 60; + OSTime fire = (GameChoice & 0x3f) * 60; fire = __OSStartTime + OSSecondsToTicks(fire); if (fire < now) { @@ -109,10 +109,4 @@ BOOL OSGetResetButtonState(void) OSRestoreInterrupts(enabled); return state; -} - -#pragma dont_inline on - -BOOL OSGetResetSwitchState(void) { return OSGetResetButtonState(); } - -#pragma dont_inline reset +} \ No newline at end of file diff --git a/libs/dolphin/os/OSRtc.c b/libs/dolphin/os/OSRtc.c index b76bcdc21..eab1d5301 100644 --- a/libs/dolphin/os/OSRtc.c +++ b/libs/dolphin/os/OSRtc.c @@ -11,389 +11,369 @@ #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); +typedef struct SramControlBlock +{ + u8 sram[RTC_SRAM_SIZE]; + u32 offset; + BOOL enabled; + BOOL locked; + BOOL sync; + void (*callback)(void); } SramControlBlock; static SramControlBlock Scb ALIGN(32); -static BOOL GetRTC(u32* rtc) { - BOOL err; - u32 cmd; - - if (!EXILock(RTC_CHAN, RTC_DEV, 0)) { - return FALSE; - } - if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { - EXIUnlock(RTC_CHAN); - return FALSE; - } - - cmd = RTC_CMD_READ; - err = FALSE; - err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL); - err |= !EXISync(RTC_CHAN); - err |= !EXIImm(RTC_CHAN, &cmd, 4, 0, NULL); - err |= !EXISync(RTC_CHAN); - err |= !EXIDeselect(RTC_CHAN); - EXIUnlock(RTC_CHAN); - - *rtc = cmd; - - return !err; -} +static BOOL ReadSram(void* buffer) +{ + BOOL err; + u32 cmd; -BOOL __OSGetRTC(u32* rtc) { - BOOL err; - u32 t0; - u32 t1; - int i; + DCInvalidateRange(buffer, RTC_SRAM_SIZE); - for (i = 0; i < 16; i++) { - err = FALSE; - err |= !GetRTC(&t0); - err |= !GetRTC(&t1); - if (err) { - break; + if (!EXILock(RTC_CHAN, RTC_DEV, 0)) + { + return FALSE; } - if (t0 == t1) { - *rtc = t0; - return TRUE; + if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) + { + EXIUnlock(RTC_CHAN); + return FALSE; } - } - return FALSE; -} -BOOL __OSSetRTC(u32 rtc) { - BOOL err; - u32 cmd; - - if (!EXILock(RTC_CHAN, RTC_DEV, 0)) { - return FALSE; - } - if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { + 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); - return FALSE; - } - - cmd = RTC_CMD_WRITE; - err = FALSE; - err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL); - err |= !EXISync(RTC_CHAN); - err |= !EXIImm(RTC_CHAN, &rtc, 4, 1, NULL); - err |= !EXISync(RTC_CHAN); - err |= !EXIDeselect(RTC_CHAN); - EXIUnlock(RTC_CHAN); - - return !err; -} -static BOOL ReadSram(void* buffer) { - BOOL err; - u32 cmd; - - DCInvalidateRange(buffer, RTC_SRAM_SIZE); - - if (!EXILock(RTC_CHAN, RTC_DEV, 0)) { - return FALSE; - } - if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { - EXIUnlock(RTC_CHAN); - return FALSE; - } - - 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); - - return !err; + return !err; } BOOL WriteSram(void* buffer, u32 offset, u32 size); -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; - } +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; + } } -BOOL WriteSram(void* buffer, u32 offset, u32 size) { - BOOL err; - u32 cmd; +BOOL WriteSram(void* buffer, u32 offset, u32 size) +{ + BOOL err; + u32 cmd; + + if (!EXILock(RTC_CHAN, RTC_DEV, WriteSramCallback)) + { + return FALSE; + } + if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) + { + EXIUnlock(RTC_CHAN); + return FALSE; + } - if (!EXILock(RTC_CHAN, RTC_DEV, WriteSramCallback)) { - return FALSE; - } - if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { + 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); - return FALSE; - } - - 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); - - return !err; + + return !err; } -void __OSInitSram() { - Scb.locked = Scb.enabled = FALSE; - Scb.sync = ReadSram(Scb.sram); - Scb.offset = RTC_SRAM_SIZE; +void __OSInitSram() +{ + Scb.locked = Scb.enabled = FALSE; + Scb.sync = ReadSram(Scb.sram); + Scb.offset = RTC_SRAM_SIZE; - OSSetGbsMode(OSGetGbsMode()); + OSSetGbsMode(OSGetGbsMode()); } -static void* LockSram(u32 offset) { - BOOL enabled; - enabled = OSDisableInterrupts(); +static void* LockSram(u32 offset) +{ + BOOL enabled; + enabled = OSDisableInterrupts(); - if (Scb.locked != FALSE) { - OSRestoreInterrupts(enabled); - return NULL; - } + if (Scb.locked != FALSE) + { + OSRestoreInterrupts(enabled); + return NULL; + } - Scb.enabled = enabled; - Scb.locked = TRUE; + Scb.enabled = enabled; + Scb.locked = TRUE; - return Scb.sram + offset; + return Scb.sram + offset; } -OSSram* __OSLockSram() { return LockSram(0); } - -OSSramEx* __OSLockSramEx() { return LockSram(sizeof(OSSram)); } - -static BOOL UnlockSram(BOOL commit, u32 offset) { - u16* p; - - if (commit) { - if (offset == 0) { - OSSram* sram = (OSSram*)Scb.sram; +OSSram* __OSLockSram() +{ + return LockSram(0); +} - if (2u < (sram->flags & 3)) { - sram->flags &= ~3; - } +OSSramEx* __OSLockSramEx() +{ + return LockSram(sizeof(OSSram)); +} - sram->checkSum = sram->checkSumInv = 0; - for (p = (u16*)&sram->counterBias; p < (u16*)(Scb.sram + sizeof(OSSram)); p++) { - sram->checkSum += *p; - sram->checkSumInv += ~*p; - } - } +static BOOL UnlockSram(BOOL commit, u32 offset) +{ + u16* p; - if (offset < Scb.offset) { - Scb.offset = offset; - } - // this isn't in prime? - if (Scb.offset <= 20) + if (commit) { - // this seems to work? esp. since we have GbsMode functions when prime doesn't - // wacky tho - OSSramEx *sramEx = (OSSramEx *)(&Scb.sram[20]); - if ((u32)(sramEx->gbs & 0x7C00) == 0x5000 || (u32)(sramEx->gbs & 0xC0) == 0xC0) - { - sramEx->gbs = 0; - } + if (offset == 0) + { + 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++) + { + sram->checkSum += *p; + sram->checkSumInv += ~*p; + } + } + + if (offset < Scb.offset) + { + Scb.offset = offset; + } + // this isn't in prime? + if (Scb.offset <= 20) + { + // this seems to work? esp. since we have GbsMode functions when prime doesn't + // wacky tho + OSSramEx* sramEx = (OSSramEx*)(&Scb.sram[20]); + if ((u32)(sramEx->gbs & 0x7C00) == 0x5000 || (u32)(sramEx->gbs & 0xC0) == 0xC0) + { + sramEx->gbs = 0; + } + } + + Scb.sync = WriteSram(Scb.sram + Scb.offset, Scb.offset, RTC_SRAM_SIZE - Scb.offset); + if (Scb.sync) + { + Scb.offset = RTC_SRAM_SIZE; + } } + Scb.locked = FALSE; + OSRestoreInterrupts(Scb.enabled); + return Scb.sync; +} - Scb.sync = WriteSram(Scb.sram + Scb.offset, Scb.offset, RTC_SRAM_SIZE - Scb.offset); - if (Scb.sync) { - Scb.offset = RTC_SRAM_SIZE; - } - } - Scb.locked = FALSE; - OSRestoreInterrupts(Scb.enabled); - return Scb.sync; +BOOL __OSUnlockSram(BOOL commit) +{ + return UnlockSram(commit, 0); } -BOOL __OSUnlockSram(BOOL commit) { return UnlockSram(commit, 0); } +BOOL __OSUnlockSramEx(BOOL commit) +{ + return UnlockSram(commit, sizeof(OSSram)); +} -BOOL __OSUnlockSramEx(BOOL commit) { return UnlockSram(commit, sizeof(OSSram)); } +BOOL __OSSyncSram() +{ + return Scb.sync; +} -BOOL __OSSyncSram() { return Scb.sync; } +BOOL __OSReadROM(void* buffer, s32 length, s32 offset) +{ + BOOL err; + u32 cmd; -BOOL __OSReadROM(void* buffer, s32 length, s32 offset) { - BOOL err; - u32 cmd; + DCInvalidateRange(buffer, (u32)length); - DCInvalidateRange(buffer, (u32)length); + if (!EXILock(RTC_CHAN, RTC_DEV, 0)) + { + return FALSE; + } + if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) + { + EXIUnlock(RTC_CHAN); + return FALSE; + } - if (!EXILock(RTC_CHAN, RTC_DEV, 0)) { - return FALSE; - } - if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { + cmd = (u32)(offset << 6); + err = FALSE; + err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL); + err |= !EXISync(RTC_CHAN); + err |= !EXIDma(RTC_CHAN, buffer, length, 0, NULL); + err |= !EXISync(RTC_CHAN); + err |= !EXIDeselect(RTC_CHAN); EXIUnlock(RTC_CHAN); - return FALSE; - } - - cmd = (u32)(offset << 6); - err = FALSE; - err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL); - err |= !EXISync(RTC_CHAN); - err |= !EXIDma(RTC_CHAN, buffer, length, 0, NULL); - err |= !EXISync(RTC_CHAN); - err |= !EXIDeselect(RTC_CHAN); - EXIUnlock(RTC_CHAN); - - return !err; + + return !err; } -inline OSSram* __OSLockSramHACK() { return LockSram(0); } -u32 OSGetSoundMode() { - OSSram* sram; - u32 mode; +inline OSSram* __OSLockSramHACK() +{ + return LockSram(0); +} +u32 OSGetSoundMode() +{ + OSSram* sram; + u32 mode; - sram = __OSLockSramHACK(); - mode = (sram->flags & 0x4) ? OS_SOUND_MODE_STEREO : OS_SOUND_MODE_MONO; - __OSUnlockSram(FALSE); - return mode; + sram = __OSLockSramHACK(); + mode = (sram->flags & 0x4) ? OS_SOUND_MODE_STEREO : OS_SOUND_MODE_MONO; + __OSUnlockSram(FALSE); + return mode; } -void OSSetSoundMode(u32 mode) { - OSSram* sram; - mode <<= 2; - mode &= 4; +void OSSetSoundMode(u32 mode) +{ + OSSram* sram; + mode <<= 2; + mode &= 4; - sram = __OSLockSramHACK(); - if (mode == (sram->flags & 4)) { - __OSUnlockSram(FALSE); - return; - } + sram = __OSLockSramHACK(); + if (mode == (sram->flags & 4)) + { + __OSUnlockSram(FALSE); + return; + } - sram->flags &= ~4; - sram->flags |= mode; - __OSUnlockSram(TRUE); + sram->flags &= ~4; + sram->flags |= mode; + __OSUnlockSram(TRUE); } -u32 OSGetProgressiveMode() { - OSSram* sram; - u32 mode; +u32 OSGetProgressiveMode() +{ + OSSram* sram; + u32 mode; - sram = __OSLockSramHACK(); - mode = (sram->flags & 0x80) >> 7; - __OSUnlockSram(FALSE); - return mode; + sram = __OSLockSramHACK(); + mode = (sram->flags & 0x80) >> 7; + __OSUnlockSram(FALSE); + return mode; } -void OSSetProgressiveMode(u32 mode) { - OSSram* sram; - mode <<= 7; - mode &= 0x80; +void OSSetProgressiveMode(u32 mode) +{ + OSSram* sram; + mode <<= 7; + mode &= 0x80; - sram = __OSLockSramHACK(); - if (mode == (sram->flags & 0x80)) { - __OSUnlockSram(FALSE); - return; - } + sram = __OSLockSramHACK(); + if (mode == (sram->flags & 0x80)) + { + __OSUnlockSram(FALSE); + return; + } - sram->flags &= ~0x80; - sram->flags |= mode; - __OSUnlockSram(TRUE); + sram->flags &= ~0x80; + sram->flags |= mode; + __OSUnlockSram(TRUE); } -u8 OSGetLanguage() { - OSSram* sram; - u8 language; +u8 OSGetLanguage() +{ + OSSram* sram; + u8 language; - sram = __OSLockSramHACK(); - language = sram->language; - __OSUnlockSram(FALSE); - return language; + sram = __OSLockSramHACK(); + language = sram->language; + __OSUnlockSram(FALSE); + return language; } -u32 OSGetEuRgb60Mode() { - OSSram *sram; - u32 on; - sram = __OSLockSramHACK(); - on = (sram->ntd >> 6) & 0x1; - __OSUnlockSram(FALSE); - return on; +u32 OSGetEuRgb60Mode() +{ + OSSram* sram; + u32 on; + sram = __OSLockSramHACK(); + on = (sram->ntd >> 6) & 0x1; + __OSUnlockSram(FALSE); + return on; } void OSSetEuRgb60Mode(u32 mode) { - OSSram *sram; - mode <<= 6; - mode &= 0x40; + OSSram* sram; + mode <<= 6; + mode &= 0x40; - sram = __OSLockSramHACK(); - if (mode == (sram->ntd & 0x40)) - { - __OSUnlockSram(FALSE); - return; - } + sram = __OSLockSramHACK(); + if (mode == (sram->ntd & 0x40)) + { + __OSUnlockSram(FALSE); + return; + } - sram->ntd &= ~0x40; - sram->ntd |= mode; - __OSUnlockSram(TRUE); + sram->ntd &= ~0x40; + sram->ntd |= mode; + __OSUnlockSram(TRUE); } -u16 OSGetWirelessID(s32 channel) { - OSSramEx* sram; - u16 id; +u16 OSGetWirelessID(s32 channel) +{ + OSSramEx* sram; + u16 id; - sram = __OSLockSramEx(); - id = sram->wirelessPadID[channel]; - __OSUnlockSramEx(FALSE); - return id; + sram = __OSLockSramEx(); + id = sram->wirelessPadID[channel]; + __OSUnlockSramEx(FALSE); + return id; } -void OSSetWirelessID(s32 channel, u16 id) { - OSSramEx* sram; +void OSSetWirelessID(s32 channel, u16 id) +{ + OSSramEx* sram; - sram = __OSLockSramEx(); - if (sram->wirelessPadID[channel] != id) { - sram->wirelessPadID[channel] = id; - __OSUnlockSramEx(TRUE); - return; - } + sram = __OSLockSramEx(); + if (sram->wirelessPadID[channel] != id) + { + sram->wirelessPadID[channel] = id; + __OSUnlockSramEx(TRUE); + return; + } - __OSUnlockSramEx(FALSE); + __OSUnlockSramEx(FALSE); } u16 OSGetGbsMode() { - OSSramEx *sram; - u16 id; + OSSramEx* sram; + u16 id; - sram = __OSLockSramEx(); - id = sram->gbs; - __OSUnlockSramEx(FALSE); - return id; + sram = __OSLockSramEx(); + id = sram->gbs; + __OSUnlockSramEx(FALSE); + return id; } void OSSetGbsMode(u16 mode) { - OSSramEx *sram; + OSSramEx* sram; - // same odd code as in UnlockSram? - if ((u32)(mode & 0x7C00) == 0x5000 || (u32)(mode & 0xC0) == 0xC0) - { - mode = 0; - } + // same odd code as in UnlockSram? + if ((u32)(mode & 0x7C00) == 0x5000 || (u32)(mode & 0xC0) == 0xC0) + { + mode = 0; + } - sram = __OSLockSramEx(); - if (mode == sram->gbs) - { - __OSUnlockSramEx(FALSE); - return; - } + sram = __OSLockSramEx(); + if (mode == sram->gbs) + { + __OSUnlockSramEx(FALSE); + return; + } - sram->gbs = mode; - __OSUnlockSramEx(TRUE); + sram->gbs = mode; + __OSUnlockSramEx(TRUE); } \ No newline at end of file diff --git a/libs/dolphin/os/OSThread.c b/libs/dolphin/os/OSThread.c index 016bfd3bd..e0a46b506 100644 --- a/libs/dolphin/os/OSThread.c +++ b/libs/dolphin/os/OSThread.c @@ -16,575 +16,509 @@ OSThreadQueue __OSActiveThreadQueue : OS_BASE_CACHED + 0x00DC; volatile OSContext __OSCurrentContext : OS_BASE_CACHED + 0x00D4; volatile OSContext* __OSFPUContext : OS_BASE_CACHED + 0x00D8; -static void DefaultSwitchThreadCallback(OSThread* from, OSThread* to) {} +static void DefaultSwitchThreadCallback(OSThread* from, OSThread* to) +{ +} extern u8 _stack_addr[]; extern u8 _stack_end[]; #define AddTail(queue, thread, link) \ - do { \ - OSThread* prev; \ + 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) + 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 AddPrio(queue, thread, link) \ - do { \ - OSThread *prev, *next; \ + do \ + { \ + OSThread *prev, *next; \ \ - for (next = (queue)->head; next && next->priority <= thread->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) + for (next = (queue)->head; next && next->priority <= thread->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 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) + 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 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) - -static inline void OSInitMutexQueue(OSMutexQueue* queue) { queue->head = queue->tail = NULL; } - -static inline void OSSetCurrentThread(OSThread* thread) { - SwitchThreadCallback(__OSCurrentThread, thread); - __OSCurrentThread = thread; + 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) + +static inline void OSInitMutexQueue(OSMutexQueue* queue) +{ + queue->head = queue->tail = NULL; } -void __OSThreadInit() { - OSThread* thread = &DefaultThread; - int prio; - - thread->state = OS_THREAD_STATE_RUNNING; - thread->attr = OS_THREAD_ATTR_DETACH; - thread->priority = thread->base = 16; - thread->suspend = 0; - thread->val = (void*)-1; - thread->mutex = NULL; - OSInitThreadQueue(&thread->queueJoin); - OSInitMutexQueue(&thread->queueMutex); - - __OSFPUContext = &thread->context; - - OSClearContext(&thread->context); - OSSetCurrentContext(&thread->context); - thread->stackBase = (void*)_stack_addr; - thread->stackEnd = (void*)_stack_end; - *(thread->stackEnd) = OS_THREAD_STACK_MAGIC; - - OSSetCurrentThread(thread); - OSClearStack(0); - - RunQueueBits = 0; - RunQueueHint = FALSE; - for (prio = OS_PRIORITY_MIN; prio <= OS_PRIORITY_MAX; ++prio) { - OSInitThreadQueue(&RunQueue[prio]); - } - - OSInitThreadQueue(&__OSActiveThreadQueue); - AddTail(&__OSActiveThreadQueue, thread, linkActive); - OSClearContext(&IdleContext); - Reschedule = 0; +static inline void OSSetCurrentThread(OSThread* thread) +{ + SwitchThreadCallback(__OSCurrentThread, thread); + __OSCurrentThread = thread; } -void OSInitThreadQueue(OSThreadQueue* queue) { queue->head = queue->tail = NULL; } +void __OSThreadInit() +{ + OSThread* thread = &DefaultThread; + int prio; + + thread->state = OS_THREAD_STATE_RUNNING; + thread->attr = OS_THREAD_ATTR_DETACH; + thread->priority = thread->base = 16; + thread->suspend = 0; + thread->val = (void*)-1; + thread->mutex = NULL; + OSInitThreadQueue(&thread->queueJoin); + OSInitMutexQueue(&thread->queueMutex); + + __OSFPUContext = &thread->context; + + OSClearContext(&thread->context); + OSSetCurrentContext(&thread->context); + thread->stackBase = (void*)_stack_addr; + thread->stackEnd = (void*)_stack_end; + *(thread->stackEnd) = OS_THREAD_STACK_MAGIC; + + OSSetCurrentThread(thread); + OSClearStack(0); + + RunQueueBits = 0; + RunQueueHint = FALSE; + for (prio = OS_PRIORITY_MIN; prio <= OS_PRIORITY_MAX; ++prio) + { + OSInitThreadQueue(&RunQueue[prio]); + } + + OSInitThreadQueue(&__OSActiveThreadQueue); + AddTail(&__OSActiveThreadQueue, thread, linkActive); + OSClearContext(&IdleContext); + Reschedule = 0; +} -OSThread* OSGetCurrentThread() { return __OSCurrentThread; } +void OSInitThreadQueue(OSThreadQueue* queue) +{ + queue->head = queue->tail = NULL; +} -static void __OSSwitchThread(OSThread *nextThread) +OSThread* OSGetCurrentThread() { - OSSetCurrentThread(nextThread); - OSSetCurrentContext(&nextThread->context); - OSLoadContext(&nextThread->context); + return __OSCurrentThread; } -BOOL OSIsThreadTerminated(OSThread *thread) +static void __OSSwitchThread(OSThread* nextThread) { - return (thread->state == OS_THREAD_STATE_MORIBUND || thread->state == OS_THREAD_STATE_NULL) ? TRUE : FALSE; + OSSetCurrentThread(nextThread); + OSSetCurrentContext(&nextThread->context); + OSLoadContext(&nextThread->context); } -s32 OSDisableScheduler() { - BOOL enabled; - s32 count; +s32 OSDisableScheduler() +{ + BOOL enabled; + s32 count; - enabled = OSDisableInterrupts(); - count = Reschedule++; - OSRestoreInterrupts(enabled); - return count; + enabled = OSDisableInterrupts(); + count = Reschedule++; + OSRestoreInterrupts(enabled); + return count; } -s32 OSEnableScheduler() { - BOOL enabled; - s32 count; +s32 OSEnableScheduler() +{ + BOOL enabled; + s32 count; - enabled = OSDisableInterrupts(); - count = Reschedule--; - OSRestoreInterrupts(enabled); - return count; + enabled = OSDisableInterrupts(); + count = Reschedule--; + OSRestoreInterrupts(enabled); + return count; } -static void SetRun(OSThread* thread) { - thread->queue = &RunQueue[thread->priority]; - AddTail(thread->queue, thread, link); - RunQueueBits |= 1u << (OS_PRIORITY_MAX - thread->priority); - RunQueueHint = TRUE; +static void SetRun(OSThread* thread) +{ + thread->queue = &RunQueue[thread->priority]; + AddTail(thread->queue, thread, link); + RunQueueBits |= 1u << (OS_PRIORITY_MAX - thread->priority); + RunQueueHint = TRUE; } #pragma dont_inline on -static void UnsetRun(OSThread* thread) { - OSThreadQueue* queue; - queue = thread->queue; - RemoveItem(queue, thread, link); - if (queue->head == 0) - RunQueueBits &= ~(1u << (OS_PRIORITY_MAX - thread->priority)); - thread->queue = NULL; +static void UnsetRun(OSThread* thread) +{ + OSThreadQueue* queue; + queue = thread->queue; + RemoveItem(queue, thread, link); + if (queue->head == 0) + RunQueueBits &= ~(1u << (OS_PRIORITY_MAX - thread->priority)); + thread->queue = NULL; } #pragma dont_inline reset -OSPriority __OSGetEffectivePriority(OSThread* thread) { - OSPriority priority; - OSMutex* mutex; - OSThread* blocked; +OSPriority __OSGetEffectivePriority(OSThread* thread) +{ + OSPriority priority; + OSMutex* mutex; + OSThread* blocked; - priority = thread->base; - for (mutex = thread->queueMutex.head; mutex; mutex = mutex->link.next) { - blocked = mutex->queue.head; - if (blocked && blocked->priority < priority) { - priority = blocked->priority; + priority = thread->base; + for (mutex = thread->queueMutex.head; mutex; mutex = mutex->link.next) + { + blocked = mutex->queue.head; + if (blocked && blocked->priority < priority) + { + priority = blocked->priority; + } } - } - return priority; + return priority; } -static OSThread* SetEffectivePriority(OSThread* thread, OSPriority priority) { - switch (thread->state) { - case OS_THREAD_STATE_READY: - UnsetRun(thread); - thread->priority = priority; - SetRun(thread); - break; - case OS_THREAD_STATE_WAITING: - RemoveItem(thread->queue, thread, link); - thread->priority = priority; - AddPrio(thread->queue, thread, link); - if (thread->mutex) { - return thread->mutex->thread; +static OSThread* SetEffectivePriority(OSThread* thread, OSPriority priority) +{ + switch (thread->state) + { + case OS_THREAD_STATE_READY: + UnsetRun(thread); + thread->priority = priority; + SetRun(thread); + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->priority = priority; + AddPrio(thread->queue, thread, link); + if (thread->mutex) + { + return thread->mutex->thread; + } + break; + case OS_THREAD_STATE_RUNNING: + RunQueueHint = TRUE; + thread->priority = priority; + break; } - break; - case OS_THREAD_STATE_RUNNING: - RunQueueHint = TRUE; - thread->priority = priority; - break; - } - return NULL; + return NULL; } -static void UpdatePriority(OSThread* thread) { - OSPriority priority; +static void UpdatePriority(OSThread* thread) +{ + OSPriority priority; - do { - if (0 < thread->suspend) { - break; - } - priority = __OSGetEffectivePriority(thread); - if (thread->priority == priority) { - break; - } - thread = SetEffectivePriority(thread, priority); - } while (thread); + do + { + if (0 < thread->suspend) + { + break; + } + priority = __OSGetEffectivePriority(thread); + if (thread->priority == priority) + { + break; + } + thread = SetEffectivePriority(thread, priority); + } while (thread); } -void __OSPromoteThread(OSThread *thread, OSPriority priority) +static OSThread* SelectThread(BOOL yield) { - do - { - if (thread->suspend > 0) + OSContext* currentContext; + OSThread* currentThread; + OSThread* nextThread; + OSPriority priority; + OSThreadQueue* queue; + + if (0 < Reschedule) { - break; + return 0; } - if (thread->priority <= priority) + + currentContext = OSGetCurrentContext(); + currentThread = OSGetCurrentThread(); + if (currentContext != ¤tThread->context) { - break; + return 0; } - thread = SetEffectivePriority(thread, priority); - } while (thread); -} - -static OSThread *SelectThread(BOOL yield) -{ - OSContext *currentContext; - OSThread *currentThread; - OSThread *nextThread; - OSPriority priority; - OSThreadQueue *queue; - - if (0 < Reschedule) - { - return 0; - } - - currentContext = OSGetCurrentContext(); - currentThread = OSGetCurrentThread(); - if (currentContext != ¤tThread->context) - { - return 0; - } - - if (currentThread) - { - if (currentThread->state == OS_THREAD_STATE_RUNNING) + if (currentThread) { - if (!yield) - { - priority = __cntlzw(RunQueueBits); - if (currentThread->priority <= priority) + if (currentThread->state == OS_THREAD_STATE_RUNNING) { - return 0; + if (!yield) + { + priority = __cntlzw(RunQueueBits); + if (currentThread->priority <= priority) + { + return 0; + } + } + currentThread->state = OS_THREAD_STATE_READY; + SetRun(currentThread); } - } - 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 & OS_CONTEXT_STATE_EXC) && + OSSaveContext(¤tThread->context)) + { + return 0; + } } - } - if (RunQueueBits == 0) - { - SwitchThreadCallback(__OSCurrentThread, nullptr); - __OSCurrentThread = nullptr; - OSSetCurrentContext(&IdleContext); - do + if (RunQueueBits == 0) { - OSEnableInterrupts(); - while (RunQueueBits == 0) - ; - OSDisableInterrupts(); - } while (RunQueueBits == 0); - - OSClearContext(&IdleContext); - } - - RunQueueHint = FALSE; - - priority = __cntlzw(RunQueueBits); - queue = &RunQueue[priority]; - RemoveHead(queue, nextThread, link); - if (queue->head == 0) - { - RunQueueBits &= ~(1u << (OS_PRIORITY_MAX - priority)); - } - nextThread->queue = NULL; - nextThread->state = OS_THREAD_STATE_RUNNING; - __OSSwitchThread(nextThread); - return nextThread; -} - -void __OSReschedule() { - if (!RunQueueHint) { - return; - } + SwitchThreadCallback(__OSCurrentThread, nullptr); + __OSCurrentThread = nullptr; + OSSetCurrentContext(&IdleContext); + do + { + OSEnableInterrupts(); + while (RunQueueBits == 0) + ; + OSDisableInterrupts(); + } while (RunQueueBits == 0); - SelectThread(FALSE); -} + OSClearContext(&IdleContext); + } -void OSYieldThread(void) { - BOOL enabled; + RunQueueHint = FALSE; - enabled = OSDisableInterrupts(); - SelectThread(TRUE); - OSRestoreInterrupts(enabled); + priority = __cntlzw(RunQueueBits); + queue = &RunQueue[priority]; + RemoveHead(queue, nextThread, link); + if (queue->head == 0) + { + RunQueueBits &= ~(1u << (OS_PRIORITY_MAX - priority)); + } + nextThread->queue = NULL; + nextThread->state = OS_THREAD_STATE_RUNNING; + __OSSwitchThread(nextThread); + return nextThread; } -BOOL OSCreateThread(OSThread *thread, OSThreadStartFunction func, void *param, void *stack, u32 stackSize, OSPriority priority, u16 attr) +void __OSReschedule() { - BOOL enable; - u32 stackThing; - int i; - u32 tmp[2]; // DUMB compiler smfh. - - if (priority < OS_PRIORITY_MIN || priority > OS_PRIORITY_MAX) - { - return FALSE; - } - - stackThing = ((u32)stack & 0xFFFFFFF8); // ?? - thread->state = OS_THREAD_STATE_READY; - thread->attr = attr & OS_THREAD_ATTR_DETACH; - thread->base = priority; - thread->priority = priority; - thread->suspend = 1; - thread->val = (void *)-1; - thread->mutex = nullptr; - OSInitThreadQueue(&thread->queueJoin); - OSInitMutexQueue(&thread->queueMutex); - *(u32 *)(stackThing - 8) = 0; - *(u32 *)(stackThing - 4) = 0; - - OSInitContext(&thread->context, (u32)func, (u32)(stackThing - 8)); - - thread->context.lr = (u32)&OSExitThread; - thread->context.gpr[3] = (u32)param; - thread->stackBase = stack; - thread->stackEnd = (u32 *)((u32)stack - stackSize); - *(thread->stackEnd) = OS_THREAD_STACK_MAGIC; - thread->error = 0; - thread->specific[0] = nullptr; - thread->specific[1] = nullptr; - - enable = OSDisableInterrupts(); - - if (__OSErrorTable[OS_ERROR_FPE] != nullptr) - { - thread->context.srr1 |= 0x900; // ?? - thread->context.state |= OS_CONTEXT_STATE_FPSAVED; - thread->context.fpscr = (__OSFpscrEnableBits & 0xF8) | 0x4; // ?? - - for (i = 0; i < 32; i++) + if (!RunQueueHint) { - *(u64 *)&thread->context.fpr[i] = -1; // ??????? - *(u64 *)&thread->context.psf[i] = -1; // ??????? + return; } - } - AddTail(&__OSActiveThreadQueue, thread, linkActive); - OSRestoreInterrupts(enable); - return TRUE; + SelectThread(FALSE); } -void OSExitThread(void *val) +void OSYieldThread(void) { - OSThread *thread; - BOOL enable; - - enable = OSDisableInterrupts(); - thread = __OSCurrentThread; - OSClearContext(&thread->context); - - if (thread->attr & OS_THREAD_ATTR_DETACH) - { - RemoveItem(&__OSActiveThreadQueue, thread, linkActive); - thread->state = OS_THREAD_STATE_NULL; - } - else - { - thread->state = OS_THREAD_STATE_MORIBUND; - thread->val = val; - } - - __OSUnlockAllMutex(thread); - OSWakeupThread(&thread->queueJoin); - RunQueueHint = TRUE; - if (RunQueueHint != FALSE) - { - SelectThread(FALSE); - } + BOOL enabled; - OSRestoreInterrupts(enable); + enabled = OSDisableInterrupts(); + SelectThread(TRUE); + OSRestoreInterrupts(enabled); } -void OSCancelThread(OSThread* thread) { - BOOL enabled; +void OSCancelThread(OSThread* thread) +{ + BOOL enabled; - enabled = OSDisableInterrupts(); + enabled = OSDisableInterrupts(); - switch (thread->state) { - case OS_THREAD_STATE_READY: - if (!(0 < thread->suspend)) { - UnsetRun(thread); - } - break; - case OS_THREAD_STATE_RUNNING: - RunQueueHint = TRUE; - break; - case OS_THREAD_STATE_WAITING: - RemoveItem(thread->queue, thread, link); - thread->queue = NULL; - if (!(0 < thread->suspend) && thread->mutex) { - UpdatePriority(thread->mutex->thread); + switch (thread->state) + { + case OS_THREAD_STATE_READY: + if (!(0 < thread->suspend)) + { + UnsetRun(thread); + } + break; + case OS_THREAD_STATE_RUNNING: + RunQueueHint = TRUE; + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->queue = NULL; + if (!(0 < thread->suspend) && thread->mutex) + { + UpdatePriority(thread->mutex->thread); + } + break; + default: + OSRestoreInterrupts(enabled); + return; } - break; - default: - OSRestoreInterrupts(enabled); - return; - } - OSClearContext(&thread->context); - if (thread->attr & OS_THREAD_ATTR_DETACH) { - RemoveItem(&__OSActiveThreadQueue, thread, linkActive); - thread->state = 0; - } else { - thread->state = OS_THREAD_STATE_MORIBUND; - } + OSClearContext(&thread->context); + if (thread->attr & OS_THREAD_ATTR_DETACH) + { + RemoveItem(&__OSActiveThreadQueue, thread, linkActive); + thread->state = 0; + } + else + { + thread->state = OS_THREAD_STATE_MORIBUND; + } - __OSUnlockAllMutex(thread); + __OSUnlockAllMutex(thread); - OSWakeupThread(&thread->queueJoin); + OSWakeupThread(&thread->queueJoin); - __OSReschedule(); - OSRestoreInterrupts(enabled); + __OSReschedule(); + OSRestoreInterrupts(enabled); - return; + return; } -void OSDetachThread(OSThread *thread) +s32 OSResumeThread(OSThread* thread) { - BOOL enable; - - enable = OSDisableInterrupts(); - thread->attr |= OS_THREAD_ATTR_DETACH; - if (thread->state == OS_THREAD_STATE_MORIBUND) - { - RemoveItem(&__OSActiveThreadQueue, thread, linkActive); - thread->state = OS_THREAD_STATE_NULL; - } - - OSWakeupThread(&thread->queueJoin); - OSRestoreInterrupts(enable); -} + BOOL enabled; + s32 suspendCount; -s32 OSResumeThread(OSThread* thread) { - BOOL enabled; - s32 suspendCount; - - enabled = OSDisableInterrupts(); - suspendCount = thread->suspend--; - if (thread->suspend < 0) { - thread->suspend = 0; - } else if (thread->suspend == 0) { - switch (thread->state) { - case OS_THREAD_STATE_READY: - thread->priority = __OSGetEffectivePriority(thread); - SetRun(thread); - break; - case OS_THREAD_STATE_WAITING: - RemoveItem(thread->queue, thread, link); - thread->priority = __OSGetEffectivePriority(thread); - AddPrio(thread->queue, thread, link); - if (thread->mutex) { - UpdatePriority(thread->mutex->thread); - } - break; + enabled = OSDisableInterrupts(); + suspendCount = thread->suspend--; + if (thread->suspend < 0) + { + thread->suspend = 0; } - __OSReschedule(); - } - OSRestoreInterrupts(enabled); - return suspendCount; + else if (thread->suspend == 0) + { + switch (thread->state) + { + case OS_THREAD_STATE_READY: + thread->priority = __OSGetEffectivePriority(thread); + SetRun(thread); + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->priority = __OSGetEffectivePriority(thread); + AddPrio(thread->queue, thread, link); + if (thread->mutex) + { + UpdatePriority(thread->mutex->thread); + } + break; + } + __OSReschedule(); + } + OSRestoreInterrupts(enabled); + return suspendCount; } -s32 OSSuspendThread(OSThread* thread) { - BOOL enabled; - s32 suspendCount; +s32 OSSuspendThread(OSThread* thread) +{ + BOOL enabled; + s32 suspendCount; - enabled = OSDisableInterrupts(); - suspendCount = thread->suspend++; - if (suspendCount == 0) { - switch (thread->state) { - case OS_THREAD_STATE_RUNNING: - RunQueueHint = TRUE; - thread->state = OS_THREAD_STATE_READY; - break; - case OS_THREAD_STATE_READY: - UnsetRun(thread); - break; - case OS_THREAD_STATE_WAITING: - RemoveItem(thread->queue, thread, link); - thread->priority = 32; - AddTail(thread->queue, thread, link); - if (thread->mutex) { - UpdatePriority(thread->mutex->thread); - } - break; - } + enabled = OSDisableInterrupts(); + suspendCount = thread->suspend++; + if (suspendCount == 0) + { + switch (thread->state) + { + case OS_THREAD_STATE_RUNNING: + RunQueueHint = TRUE; + thread->state = OS_THREAD_STATE_READY; + break; + case OS_THREAD_STATE_READY: + UnsetRun(thread); + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->priority = 32; + AddTail(thread->queue, thread, link); + if (thread->mutex) + { + UpdatePriority(thread->mutex->thread); + } + break; + } - __OSReschedule(); - } - OSRestoreInterrupts(enabled); - return suspendCount; + __OSReschedule(); + } + OSRestoreInterrupts(enabled); + return suspendCount; } -void OSSleepThread(OSThreadQueue* queue) { - BOOL enabled; - OSThread* currentThread; +void OSSleepThread(OSThreadQueue* queue) +{ + BOOL enabled; + OSThread* currentThread; - enabled = OSDisableInterrupts(); - currentThread = OSGetCurrentThread(); + enabled = OSDisableInterrupts(); + currentThread = OSGetCurrentThread(); - currentThread->state = OS_THREAD_STATE_WAITING; - currentThread->queue = queue; - AddPrio(queue, currentThread, link); - RunQueueHint = TRUE; - __OSReschedule(); - OSRestoreInterrupts(enabled); + currentThread->state = OS_THREAD_STATE_WAITING; + currentThread->queue = queue; + AddPrio(queue, currentThread, link); + RunQueueHint = TRUE; + __OSReschedule(); + OSRestoreInterrupts(enabled); } -void OSWakeupThread(OSThreadQueue* queue) { - BOOL enabled; - OSThread* thread; +void OSWakeupThread(OSThreadQueue* queue) +{ + BOOL enabled; + OSThread* thread; - enabled = OSDisableInterrupts(); - while (queue->head) { - RemoveHead(queue, thread, link); - thread->state = OS_THREAD_STATE_READY; - if (!(0 < thread->suspend)) { - SetRun(thread); + enabled = OSDisableInterrupts(); + while (queue->head) + { + RemoveHead(queue, thread, link); + thread->state = OS_THREAD_STATE_READY; + if (!(0 < thread->suspend)) + { + SetRun(thread); + } } - } - __OSReschedule(); - OSRestoreInterrupts(enabled); + __OSReschedule(); + OSRestoreInterrupts(enabled); } -OSPriority OSGetThreadPriority(OSThread *thread) { return thread->base; } - -void OSClearStack(u8 val) { - register u32 sp; - register u32* p; - register u32 pattern; +void OSClearStack(u8 val) +{ + register u32 sp; + register u32* p; + register u32 pattern; - pattern = ((u32)val << 24) | ((u32)val << 16) | ((u32)val << 8) | (u32)val; - sp = OSGetStackPointer(); - for (p = __OSCurrentThread->stackEnd + 1; p < (u32*)sp; ++p) { - *p = pattern; - } + pattern = ((u32)val << 24) | ((u32)val << 16) | ((u32)val << 8) | (u32)val; + sp = OSGetStackPointer(); + for (p = __OSCurrentThread->stackEnd + 1; p < (u32*)sp; ++p) + { + *p = pattern; + } } diff --git a/libs/dolphin/os/OSTime.c b/libs/dolphin/os/OSTime.c index 803fe10bc..7f893c0a5 100644 --- a/libs/dolphin/os/OSTime.c +++ b/libs/dolphin/os/OSTime.c @@ -5,13 +5,15 @@ #define OS_TIME_YEAR_DAY_MAX 365 // End of each month in standard year -static s32 YearDays[OS_TIME_MONTH_MAX] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; +static s32 YearDays[OS_TIME_MONTH_MAX] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; // End of each month in leap year -static s32 LeapYearDays[OS_TIME_MONTH_MAX] = {0, 31, 60, 91, 121, 152, - 182, 213, 244, 274, 305, 335}; +static s32 LeapYearDays[OS_TIME_MONTH_MAX] = { + 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 +}; -asm OSTime OSGetTime(void) { - // clang-format off +asm OSTime OSGetTime(void) +{ + // clang-format off nofralloc mftbu r3 @@ -23,7 +25,7 @@ asm OSTime OSGetTime(void) { bne OSGetTime blr - // clang-format on + // clang-format on } asm OSTick OSGetTick(void){ @@ -37,101 +39,110 @@ asm OSTick OSGetTick(void){ #define OS_SYSTEMTIME_BASE 0x30D8 -OSTime __OSGetSystemTime(void) { - BOOL enabled; - OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE); - OSTime result; +OSTime __OSGetSystemTime(void) +{ + BOOL enabled; + OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE); + OSTime result; - enabled = OSDisableInterrupts(); - result = *timeAdjustAddr + OSGetTime(); - OSRestoreInterrupts(enabled); + enabled = OSDisableInterrupts(); + result = *timeAdjustAddr + OSGetTime(); + OSRestoreInterrupts(enabled); - return result; + return result; } -OSTime __OSTimeToSystemTime(OSTime time) { - BOOL enabled; - OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE); - OSTime result; +OSTime __OSTimeToSystemTime(OSTime time) +{ + BOOL enabled; + OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE); + OSTime result; - enabled = OSDisableInterrupts(); - result = *timeAdjustAddr + time; - OSRestoreInterrupts(enabled); + enabled = OSDisableInterrupts(); + result = *timeAdjustAddr + time; + OSRestoreInterrupts(enabled); - return result; + return result; } -static BOOL IsLeapYear(s32 year) { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); } +static BOOL IsLeapYear(s32 year) +{ + return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); +} -static s32 GetYearDays(s32 year, s32 mon) { - return (IsLeapYear(year) ? LeapYearDays : YearDays)[mon]; +static s32 GetYearDays(s32 year, s32 mon) +{ + return (IsLeapYear(year) ? LeapYearDays : YearDays)[mon]; } -static s32 GetLeapDays(s32 year) { - if (year < 1) { - return 0; - } - return (year + 3) / 4 - (year - 1) / 100 + (year - 1) / 400; +static s32 GetLeapDays(s32 year) +{ + if (year < 1) + { + return 0; + } + return (year + 3) / 4 - (year - 1) / 100 + (year - 1) / 400; } -static void GetDates(s32 days, OSCalendarTime* cal) { - s32 year; - s32 totalDays; - s32* p_days; - s32 month; - cal->wday = (days + 6) % OS_TIME_WEEK_DAY_MAX; - - for (year = days / OS_TIME_YEAR_DAY_MAX; - days < (totalDays = year * OS_TIME_YEAR_DAY_MAX + GetLeapDays(year));) { - year--; - } - - days -= totalDays; - cal->year = year; - cal->yday = days; - - p_days = IsLeapYear(year) ? LeapYearDays : YearDays; - month = OS_TIME_MONTH_MAX; - while (days < p_days[--month]) { - ; - } - cal->mon = month; - cal->mday = days - p_days[month] + 1; +static void GetDates(s32 days, OSCalendarTime* cal) +{ + s32 year; + s32 totalDays; + s32* p_days; + s32 month; + cal->wday = (days + 6) % OS_TIME_WEEK_DAY_MAX; + + for (year = days / OS_TIME_YEAR_DAY_MAX; + days < (totalDays = year * OS_TIME_YEAR_DAY_MAX + GetLeapDays(year));) + { + year--; + } + + days -= totalDays; + cal->year = year; + cal->yday = days; + + p_days = IsLeapYear(year) ? LeapYearDays : YearDays; + month = OS_TIME_MONTH_MAX; + while (days < p_days[--month]) + { + ; + } + cal->mon = month; + cal->mday = days - p_days[month] + 1; } #define BIAS (2000 * 365 + (2000 + 3) / 4 - (2000 - 1) / 100 + (2000 - 1) / 400) #pragma push #pragma dont_inline on -void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* td) { - int days; - int secs; - OSTime d; - - d = ticks % OSSecondsToTicks(1); - if (d < 0) { - d += OSSecondsToTicks(1); - } - td->usec = (int)(OSTicksToMicroseconds(d) % 1000); - td->msec = (int)(OSTicksToMilliseconds(d) % 1000); - - ticks -= d; - days = (int)(OSTicksToSeconds(ticks) / 86400 + BIAS); - secs = (int)(OSTicksToSeconds(ticks) % 86400); - if (secs < 0) { - days -= 1; - secs += 24 * 60 * 60; - } - - GetDates(days, td); - - td->hour = secs / 60 / 60; - td->min = (secs / 60) % 60; - td->sec = secs % 60; +void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* td) +{ + int days; + int secs; + OSTime d; + + d = ticks % OSSecondsToTicks(1); + if (d < 0) + { + d += OSSecondsToTicks(1); + } + td->usec = (int)(OSTicksToMicroseconds(d) % 1000); + td->msec = (int)(OSTicksToMilliseconds(d) % 1000); + + ticks -= d; + days = (int)(OSTicksToSeconds(ticks) / 86400 + BIAS); + secs = (int)(OSTicksToSeconds(ticks) % 86400); + if (secs < 0) + { + days -= 1; + secs += 24 * 60 * 60; + } + + GetDates(days, td); + + td->hour = secs / 60 / 60; + td->min = (secs / 60) % 60; + td->sec = secs % 60; } #pragma dont_inline reset - -OSTime OSCalendarTimeToTicks(const OSCalendarTime* time) { - ; - ; -} diff --git a/libs/dolphin/os/__os.h b/libs/dolphin/os/__os.h new file mode 100644 index 000000000..9808a40da --- /dev/null +++ b/libs/dolphin/os/__os.h @@ -0,0 +1,133 @@ +#ifndef _DOLPHIN_OS_INTERNAL_H_ +#define _DOLPHIN_OS_INTERNAL_H_ + +#include +#include +#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/libs/dolphin/os/init/__ppc_eabi_init.cpp b/libs/dolphin/os/init/__ppc_eabi_init.cpp index ea0791dd2..e276d4a6b 100644 --- a/libs/dolphin/os/init/__ppc_eabi_init.cpp +++ b/libs/dolphin/os/init/__ppc_eabi_init.cpp @@ -48,27 +48,27 @@ __declspec(section ".init") asm void __flush_cache(void) { } // clang-format on - -void __init_user(void) { __init_cpp(); } +void __init_user(void) +{ + __init_cpp(); +} static void __init_cpp(void) { - voidfunctionptr* constructor; - /* + voidfunctionptr* constructor; + /* * call static initializers */ - for (constructor = _ctors; *constructor; constructor++) { - (*constructor)(); - } + for (constructor = _ctors; *constructor; constructor++) + { + (*constructor)(); + } } - -void __fini_cpp(void) +void _ExitProcess(void) { - // UNUSED FUNCTION + PPCHalt(); } - -void _ExitProcess(void) { PPCHalt(); } #ifdef __cplusplus } #endif diff --git a/libs/dolphin/pad/Padclamp.c b/libs/dolphin/pad/Padclamp.c index 89fbbfb8a..e6165d56a 100644 --- a/libs/dolphin/pad/Padclamp.c +++ b/libs/dolphin/pad/Padclamp.c @@ -2,8 +2,6 @@ #include "std/math.h" -s32 PAD_CHANMAX; - static const PADClampRegion ClampRegion = { // Triggers 30, @@ -98,51 +96,6 @@ static void ClampStick(s8* px, s8* py, s8 max, s8 xy, s8 min) *py = (s8)(signY * y); } -static void ClampCircle(s8* px, s8* py, s8 radius, s8 min) -{ - int x = *px; - int y = *py; - int squared; - int length; - - if (-min < x && x < min) - { - x = 0; - } - else if (0 < x) - { - x -= min; - } - else - { - x += min; - } - - if (-min < y && y < min) - { - y = 0; - } - else if (0 < y) - { - y -= min; - } - else - { - y += min; - } - - squared = x * x + y * y; - if (radius * radius < squared) - { - length = sqrtf(squared); - x = (x * radius) / length; - y = (y * radius) / length; - } - - *px = x; - *py = y; -} - static void ClampTrigger(u8* trigger, u8 min, u8 max) { if (*trigger <= min) @@ -163,7 +116,7 @@ static void ClampTrigger(u8* trigger, u8 min, u8 max) void PADClamp(PADStatus* status) { int i; - for (i = 0; i < PAD_CHANMAX; i++, status++) + for (i = 0; i < 4; i++, status++) { if (status->err != PAD_ERR_NONE) { @@ -178,21 +131,3 @@ void PADClamp(PADStatus* status) ClampTrigger(&status->triggerRight, ClampRegion.minTrigger, ClampRegion.maxTrigger); } } - -void PADClampCircle(PADStatus* status) -{ - int i; - for (i = 0; i < PAD_CHANMAX; ++i, status++) - { - if (status->err != PAD_ERR_NONE) - { - continue; - } - - 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); - } -} diff --git a/libs/dolphin/upnp/UPnP.c b/libs/dolphin/upnp/UPnP.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/upnp/UPnPHttp.c b/libs/dolphin/upnp/UPnPHttp.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/upnp/UPnPHttpd.c b/libs/dolphin/upnp/UPnPHttpd.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/upnp/UPnPHttpdResponse.c b/libs/dolphin/upnp/UPnPHttpdResponse.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/upnp/UPnPSsdp.c b/libs/dolphin/upnp/UPnPSsdp.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/upnp/UPnPUri.c b/libs/dolphin/upnp/UPnPUri.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/upnp/UPnPUuid.c b/libs/dolphin/upnp/UPnPUuid.c deleted file mode 100644 index e69de29bb..000000000 From b7afd597ff3852049da8f67cc1cf89559512d7e8 Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Sat, 24 May 2025 20:35:40 -0400 Subject: [PATCH 08/19] fixed a rebase issue and file cleanup --- libs/dolphin/eth/base64.c | 70 - libs/dolphin/eth/eth.c | 1031 ----------- libs/dolphin/eth/ethsec.c | 344 ---- libs/dolphin/eth/md5.c | 285 --- libs/dolphin/gd/GDBase.c | 0 libs/dolphin/gd/GDGeometry.c | 0 libs/dolphin/hio/hio.c | 0 libs/dolphin/ip/IFFifo.c | 0 libs/dolphin/ip/IFRing.c | 0 libs/dolphin/ip/IP.c | 0 libs/dolphin/ip/IPArp.c | 0 libs/dolphin/ip/IPChap.c | 0 libs/dolphin/ip/IPDhcp.c | 0 libs/dolphin/ip/IPDns.c | 0 libs/dolphin/ip/IPEther.c | 0 libs/dolphin/ip/IPFrag.c | 0 libs/dolphin/ip/IPIcmp.c | 0 libs/dolphin/ip/IPIgmp.c | 0 libs/dolphin/ip/IPIpcp.c | 0 libs/dolphin/ip/IPLcp.c | 0 libs/dolphin/ip/IPOpt.c | 0 libs/dolphin/ip/IPPPP.c | 0 libs/dolphin/ip/IPPPPoE.c | 0 libs/dolphin/ip/IPPap.c | 0 libs/dolphin/ip/IPRoute.c | 0 libs/dolphin/ip/IPSocket.c | 0 libs/dolphin/ip/IPTcp.c | 0 libs/dolphin/ip/IPTcpOutput.c | 0 libs/dolphin/ip/IPTcpTimeWait.c | 0 libs/dolphin/ip/IPTcpTimer.c | 0 libs/dolphin/ip/IPTcpUser.c | 0 libs/dolphin/ip/IPUdp.c | 0 libs/dolphin/ip/IPUuid.c | 0 libs/dolphin/ip/IPZero.c | 0 libs/dolphin/lg/allsrc.c | 0 libs/dolphin/thp/THPAudio.c | 202 --- libs/dolphin/thp/THPDec.c | 2316 ------------------------- src/SB/Core/x/xCollide.cpp | 38 +- src/SB/Game/zEntPlayerBungeeState.cpp | 1 + 39 files changed, 15 insertions(+), 4272 deletions(-) delete mode 100644 libs/dolphin/eth/base64.c delete mode 100644 libs/dolphin/eth/eth.c delete mode 100644 libs/dolphin/eth/ethsec.c delete mode 100644 libs/dolphin/eth/md5.c delete mode 100644 libs/dolphin/gd/GDBase.c delete mode 100644 libs/dolphin/gd/GDGeometry.c delete mode 100644 libs/dolphin/hio/hio.c delete mode 100644 libs/dolphin/ip/IFFifo.c delete mode 100644 libs/dolphin/ip/IFRing.c delete mode 100644 libs/dolphin/ip/IP.c delete mode 100644 libs/dolphin/ip/IPArp.c delete mode 100644 libs/dolphin/ip/IPChap.c delete mode 100644 libs/dolphin/ip/IPDhcp.c delete mode 100644 libs/dolphin/ip/IPDns.c delete mode 100644 libs/dolphin/ip/IPEther.c delete mode 100644 libs/dolphin/ip/IPFrag.c delete mode 100644 libs/dolphin/ip/IPIcmp.c delete mode 100644 libs/dolphin/ip/IPIgmp.c delete mode 100644 libs/dolphin/ip/IPIpcp.c delete mode 100644 libs/dolphin/ip/IPLcp.c delete mode 100644 libs/dolphin/ip/IPOpt.c delete mode 100644 libs/dolphin/ip/IPPPP.c delete mode 100644 libs/dolphin/ip/IPPPPoE.c delete mode 100644 libs/dolphin/ip/IPPap.c delete mode 100644 libs/dolphin/ip/IPRoute.c delete mode 100644 libs/dolphin/ip/IPSocket.c delete mode 100644 libs/dolphin/ip/IPTcp.c delete mode 100644 libs/dolphin/ip/IPTcpOutput.c delete mode 100644 libs/dolphin/ip/IPTcpTimeWait.c delete mode 100644 libs/dolphin/ip/IPTcpTimer.c delete mode 100644 libs/dolphin/ip/IPTcpUser.c delete mode 100644 libs/dolphin/ip/IPUdp.c delete mode 100644 libs/dolphin/ip/IPUuid.c delete mode 100644 libs/dolphin/ip/IPZero.c delete mode 100644 libs/dolphin/lg/allsrc.c delete mode 100644 libs/dolphin/thp/THPAudio.c delete mode 100644 libs/dolphin/thp/THPDec.c diff --git a/libs/dolphin/eth/base64.c b/libs/dolphin/eth/base64.c deleted file mode 100644 index a2c6b0053..000000000 --- a/libs/dolphin/eth/base64.c +++ /dev/null @@ -1,70 +0,0 @@ -#include - -static const char Base64[] = { - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" -}; - -char *__IPEncodeToBase64(void *_src, s32 len , char *dst) { - const u8 *src; - int i; - char *p; - - src = _src; - p = dst; - for (i = 0; i < len - len % 3; i += 3) { - *p++ = Base64[(src[i+0] >> 2) & 0x3f]; - *p++ = Base64[((src[i+0] & 0x3) << 4) | ((src[i+1] >> 4) & 0xf)]; - *p++ = Base64[((src[i+1] & 0xf) << 2) | ((src[i+2] >> 6) & 0x3)]; - *p++ = Base64[src[i+2] & 0x3f]; - } - - i = len - len % 3; - // Encode remaining characters - switch (len % 3) { - case 2: { - *p++ = Base64[(src[i+0] >> 2) & 0x3f]; - *p++ = Base64[((src[i+0] & 0x3) << 4) | ((src[i+1] >> 4) & 0xf)]; - *p++ = Base64[((src[i+1] & 0xf) << 2)]; - *p++ = '='; - break; - } - case 1: { - *p++ = Base64[(src[i+0] >> 2) & 0x3f]; - *p++ = Base64[((src[i+0] & 0x3) << 4)]; - *p++ = '='; - *p++ = '='; - break; - } - } - - return p; -} - -void *__IPDecodeFromBase64(const char *src, long len , void *_dst) { - u8 *dst; - int i; - u8 *p; - - dst = _dst; - p = dst; - for (i = 0; i < len; i += 4) { - int n0; - int n1; - int n2; - int n3; - n0 = strchr(Base64, src[i+0]) - Base64; - n1 = strchr(Base64, src[i+1]) - Base64; - *p++ = (n0 << 2) | (n1 >> 4) & 0x3; - - if (src[i+2] == '=') break; - - n2 = strchr(Base64, src[i+2]) - Base64; - *p++ = ((n1 << 4) & 0xff) | (n2 >> 2) & 0xf; - - if (src[i+3] == '=') break; - - n3 = strchr(Base64, src[i+3]) - Base64; - *p++ = ((n2 << 6) & 0xff) | (n3 & 0x3f); - } - return p; -} diff --git a/libs/dolphin/eth/eth.c b/libs/dolphin/eth/eth.c deleted file mode 100644 index 871352662..000000000 --- a/libs/dolphin/eth/eth.c +++ /dev/null @@ -1,1031 +0,0 @@ -#include - -#include -#include -#include -#include - -#include "types.h" - -#ifdef DEBUG -const char* __ETHVersion = "<< Dolphin SDK - ETH\tdebug build: Aug 5 2003 17:18:42 (0x2301) >>"; -#else -const char* __ETHVersion = "<< Dolphin SDK - ETH\trelease build: Aug 5 2003 17:18:42 (0x2301) >>"; -#endif - -static u8 broadcastheader[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -static u8 private_macaddr[6]; -static u8 __revid = 0; -static u16 __devid = 0xD107; -static u8 __acstart = 0x4E; -static OSThreadQueue threadQ; -static BOOL lockUpdate = FALSE; -static BOOL __sendbusy = FALSE; -static BOOL sendUpdate = FALSE; -static ETHStat ethstat; -static u16* protoarray = NULL; -static s32 protonum = 0; -static void* (*recvcallback0)(u16, s32, u8) = NULL; -static void (*recvcallback1)(u8*, s32) = NULL; -static BOOL recvcallbackUpdate = FALSE; -static void (*__sendcallback)(u8) = NULL; -static BOOL __recvpriorityflag = FALSE; -static u8* __sendadr = NULL; -static s32 __sendlen = 0; -static s32 __senddmalen = 0; -static s32 __sendimmlen = 0; -static u8 tmppool0[1536] ATTRIBUTE_ALIGN(32); -static u8 tmppool1[1536] ATTRIBUTE_ALIGN(32); -static u32 recvlen0 = 0; -static u32 recvlen1 = 0; - -typedef struct Descriptor { - u8 nextpacketL; - u8 packetlengthL : 4; - u8 nextpacketH : 4; - u8 packetLengthH; - u8 status; -} Descriptor; - -typedef struct Descriptor2 { - u16 nextpacket; - u16 packetlength; - u8 status; -} Descriptor2; - -static Descriptor2 d2; - -static u8* recvaddr = NULL; -static u16 rwp = 0; -static u16 rrp = 0; -static u8 mcastmap[8]; -static BOOL mcastUpdate = FALSE; - - -static BOOL lock(void); -static void unlock(void); - -static void recvsub0(void); -static void recvsub1(void); - -static void sendsub0(void); -static void sendsub1(s32 chan, OSContext* context); - -static void readbuffer0(u16 cmd); -static void readbuffer1(s32 chan, OSContext* context); -static void readbuffersub(s32 chan, OSContext* context); - -static void exiinthandler(s32 chan, OSContext* context); - -static inline u16 swap16(u16 val) { - u16 ret = __lhbrx(&val, 0); - return ret; -} - -static inline u8 higher(u16 val) { - return (val >> 8) & 0xff; -} - -static inline u8 lower(u16 val) { - return val & 0xff; -} - -static void waitexilock(void) { - BOOL enabled; - - enabled = OSDisableInterrupts(); - while (TRUE) { - if (lock() != FALSE) { - OSRestoreInterrupts(enabled); - return; - } - - lockUpdate = TRUE; - OSSleepThread(&threadQ); - OSRestoreInterrupts(enabled); - } -} - -static void waitmicro(s32 usec) { - OSTick start; - OSTick interval; - - start = OSGetTick(); - interval = OSMicrosecondsToTicks(usec); - - while (TRUE) { - if (OSGetTick() - start >= interval) { - break; - } - } -} - -static u8 readEXIcmd(u8 cmd) { - u16 ethcmd; - u8 rdata; - - ethcmd = 0x0000 | (cmd << 8); - EXISelect(0, 2, 5); - EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); - EXISync(0); - EXIImm(0, &rdata, sizeof(rdata), EXI_READ, NULL); - EXISync(0); - EXIDeselect(0); - return rdata; -} - -static u8 readEXIcmdWait200Micro(u8 cmd) { - u16 ethcmd; - u8 rdata; - - ethcmd = 0x0000 | (cmd << 8); - EXISelect(0, 2, 5); - EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); - EXISync(0); - EXIImm(0, &rdata, sizeof(rdata), EXI_READ, NULL); - EXISync(0); - waitmicro(200); - EXIDeselect(0); - return rdata; -} - -static void writeEXIcmd(u8 cmd, u8 imr) { - BOOL ret; - u16 ethcmd; - - ethcmd = 0x4000 | (cmd << 8); - ret = EXISelect(0, 2, 5); - EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); - EXISync(0); - EXIImm(0, &imr, sizeof(imr), EXI_WRITE, NULL); - EXISync(0); - EXIDeselect(0); -} - -static void readEXIcmdLong(u8 cmd, void* address, s32 length) { - u16 ethcmd; - - ethcmd = cmd << 8; - EXISelect(0, 2, 5); - EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); - EXISync(0); - EXIImmEx(0, address, length, EXI_READ); - EXIDeselect(0); -} - -static void writeEXIcmdLong(u8 cmd, void* address, s32 length) { - BOOL ret; - u16 ethcmd; - - ethcmd = 0x4000 | (cmd << 8); - ret = EXISelect(0, 2, 5); - EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); - EXISync(0); - EXIImmEx(0, address, length, EXI_WRITE); - EXIDeselect(0); -} - -static void readcmdLong(u16 cmd, void* addr, s32 length) { - u32 ethcmd; - - ethcmd = 0x80000000 | (cmd << 8); - EXISelect(0, 2, 5); - EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); - EXISync(0); - EXIImmEx(0, addr, length, EXI_READ); - EXIDeselect(0); -} - -static void writecmdLong(u16 cmd, void* addr, s32 length) { - u32 ethcmd = 0xC0000000 | (cmd << 8); - EXISelect(0, 2, 5); - EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); - EXISync(0); - EXIImmEx(0, addr, length, EXI_WRITE); - EXIDeselect(0); -} - -static u8 readcmd(u16 cmd) { - u8 val; - - readcmdLong(cmd, &val, sizeof(val)); - return val; -} - -static void writecmd(u16 cmd, u8 val) { - writecmdLong(cmd, &val, sizeof(val)); -} - -static void StaOutput(unsigned int bit) { - writecmd(0x0060, bit * 2); - writecmd(0x0060, 8 + bit * 2); - writecmd(0x0060, 8 + bit * 2); - writecmd(0x0060, bit * 2); -} - -static u8 StaInput(void) { - unsigned char bit; - - writecmd(0x0060, 0x0C); - bit = readcmd(0x0060); - bit &= 1; - writecmd(0x0060, 0x04); - writecmd(0x0060, 0x04); - return bit; -} - -static u16 PhyRead(unsigned int regNo) { - int i; - u16 value; - - /* Clear command */ - for (i = 0; i < 32; i++) { - StaOutput(1); - } - - /* Enter read mode */ - StaOutput(0); - StaOutput(1); - StaOutput(1); - StaOutput(0); - StaOutput(0); - StaOutput(0); - StaOutput(0); - StaOutput(0); - StaOutput(0); - - /* Set register */ - StaOutput((regNo >> 4) & 1); - StaOutput((regNo >> 3) & 1); - StaOutput((regNo >> 2) & 1); - StaOutput((regNo >> 1) & 1); - StaOutput((regNo >> 0) & 1); - writecmd(0x0060, 4); - value = StaInput(); - value = StaInput(); - - /* Read value */ - value = 0; - for (i = 0; i < 16; i++) { - value = value + (StaInput() << (15 - i)); - } - - /* Clear command */ - for (i = 0; i < 32; i++) { - StaOutput(1); - } - - return value; -} - -static void PhyWrite(unsigned int regNo, u16 value) { - int i; - - /* Clear command */ - for (i = 0; i < 32; i++) { - StaOutput(1); - } - - /* Enter write mode */ - StaOutput(0); - StaOutput(1); - StaOutput(0); - StaOutput(1); - StaOutput(0); - StaOutput(0); - StaOutput(0); - StaOutput(0); - StaOutput(0); - - /* Set register */ - StaOutput((regNo >> 4) & 1); - StaOutput((regNo >> 3) & 1); - StaOutput((regNo >> 2) & 1); - StaOutput((regNo >> 1) & 1); - StaOutput((regNo >> 0) & 1); - - StaOutput(1); - StaOutput(0); - - /* Write value */ - for (i = 0; i < 16; i++) { - StaOutput((u8)((value >> (15 - i)) & 1)); - } - - /* Clear command */ - for (i = 0; i < 32; i++) { - StaOutput(1); - } -} - -static void reset(void) { - writecmd(0x0060, 0); - waitmicro(10000); - readEXIcmdWait200Micro(0x0F); - waitmicro(10000); - writecmd(0x0000, 1); - writecmd(0x0000, 0); -} - -static void recvinit(void) { - u8 ncrb; - u16 swapped; - - swapped = higher(0x0001) | (lower(0x0001) << 8); - writecmdLong(0x000A, &swapped, sizeof(swapped)); - writecmdLong(0x0016, &swapped, sizeof(swapped)); - writecmdLong(0x0018, &swapped, sizeof(swapped)); - - swapped = higher(0x000F) | (lower(0x000F) << 8); - writecmdLong(0x001A, &swapped, sizeof(swapped)); - - ncrb = readcmd(0x0001); - ncrb &= ~0b00000011; // ~3 - ncrb |= 0b00010000; // | 0x10 - writecmd(0x0001, ncrb); - writecmd(0x0000, 0x08); - writecmd(0x0032, 0x08); -} - -static void getdescriptor(u16 address) { - Descriptor d; - - readcmdLong(address, &d, sizeof(d)); - d2.nextpacket = (d.nextpacketH << 8) | d.nextpacketL; - d2.packetlength = (d.packetLengthH << 4) | d.packetlengthL; - d2.status = d.status; -} - -static u16 readcmd16(u8 cmd) { - u16 tmp16; - - readcmdLong(cmd, &tmp16, sizeof(tmp16)); - - return swap16(tmp16); -} - -static void writecmd16(u8 cmd, u16 val) { - u16 tmp16; - - tmp16 = swap16(val); - writecmdLong(cmd, &tmp16, sizeof(tmp16)); -} - -static void recvsub0(void) { - rwp = readcmd16(0x16); - rrp = readcmd16(0x18); - recvsub1(); -} - -static void recvsub1(void) { - u16 packettype; - s32 i; - u8 lrps; - u16 address; - - recvlen0 = recvlen1 = 0; - do { - while (rrp != rwp) { - address = (rrp & 0xFF) << 8; - getdescriptor(address); - readcmdLong(address + 0x10U, &packettype, sizeof(packettype)); - - if (protonum > 0) { - for (i = 0; i < protonum; i++) { - if (packettype == protoarray[i]) { - break; - } - } - - if (i == protonum) { - goto update_pointers; - } - } - - if (recvcallback0) { - lrps = d2.status; - recvaddr = (*recvcallback0)(packettype, d2.packetlength, lrps); - - if (recvaddr != NULL) { - if (address + 4U + d2.packetlength > 0x1000U) { - recvlen1 = address - 0x0FFCU + d2.packetlength; - recvlen0 = d2.packetlength - recvlen1; - } else { - recvlen0 = d2.packetlength; - recvlen1 = 0; - } - - readbuffer0(address + 4U); - return; - } - } - -update_pointers: - rrp = d2.nextpacket; - rwp = readcmd16(0x16); - } - - writecmd16(0x18, rwp); - writecmd(0x0009, 0x02); - rwp = readcmd16(0x16); - rrp = readcmd16(0x18); - } while (rwp != rrp); - - writeEXIcmd(0x02, 0xF8); - unlock(); -} - -static void readbuffer0(u16 cmd) { - u32 etcmd; - u32 length; - - length = OSRoundUp32B(recvlen0); - etcmd = 0x80000000 | (cmd << 8); - - EXISelect(0, 2, 5); - EXIImm(0, &etcmd, sizeof(etcmd), EXI_WRITE, NULL); - EXISync(0); - EXIDma(0, tmppool0, length, EXI_READ, recvlen1 != 0 ? &readbuffersub : &readbuffer1); -} - -static void readbuffersub(s32 chan, OSContext* context) { - u32 etcmd; - u32 length; - - length = OSRoundUp32B(recvlen1); - EXIDeselect(0); - - etcmd = 0x80000000 | (0x0100 << 8); - EXISelect(0, 2, 5); - EXIImm(0, &etcmd, sizeof(etcmd), EXI_WRITE, NULL); - EXISync(0); - EXIDma(0, tmppool1, length, EXI_READ, readbuffer1); - __ETHInterruptTime = OSGetTime() - __OSLastInterruptTime; -} - -static void readbuffer1(s32 chan, OSContext* context) { - EXIDeselect(0); - - DCInvalidateRange(tmppool0, OSRoundUp32B(recvlen0)); - if (recvlen1 != 0) { - DCInvalidateRange(tmppool1, OSRoundUp32B(recvlen1)); - } - - if (recvcallback1) { - memcpy(recvaddr, tmppool0, recvlen0); - if (recvlen1 != 0) { - memcpy(recvaddr + recvlen0, tmppool1, recvlen1); - } - __ETHFilter(recvaddr, d2.packetlength); - (*recvcallback1)(recvaddr, d2.packetlength); - } - - rrp = d2.nextpacket; - rwp = readcmd16(0x16); - recvsub1(); - __ETHInterruptTime = OSGetTime() - __OSLastInterruptTime; -} - -#include - -static void patchthru(void) { - u32 rnda; - u32 fa; - - writeEXIcmd(0x05, __acstart); - readEXIcmdLong(0x08, &rnda, sizeof(rnda)); - fa = hashfunc(rnda); - writeEXIcmdLong(0x09, &fa, sizeof(fa)); -} - -static void exiinthandler(s32 chan, OSContext* context) { - u8 ir; - u8 exiisr; - BOOL ret; - BOOL sendcbflag; - u8 ltps; - u8 lrps; - u8 result; - void (*callback)(u8); - - sendcbflag = FALSE; - ret = EXILock(0, 2, &exiinthandler); - if (ret != FALSE) { - exiisr = readEXIcmd(0x03); - writeEXIcmd(0x02, 0x00); - - switch (__cntlzw(exiisr)) { - case 0x18: { - writeEXIcmd(0x03, 0x80); - break; - } - - case 0x1A: { - writeEXIcmd(0x03, 0x20); - writeEXIcmd(0x02, 0xF8); - unlock(); - #ifdef DEBUG - OSPanic(__FILE__, 765, "exi cmderr\n"); - #endif - return; - } - - case 0x19: { - writeEXIcmd(0x03, 0x40); - writeEXIcmd(0x02, 0xF8); - unlock(); - return; - } - - case 0x1B: { - patchthru(); - writeEXIcmd(0x03, 0x10); - writeEXIcmd(0x02, 0xF8); - unlock(); - return; - } - - case 0x1C: { - result = readEXIcmd(0x0B); - writeEXIcmd(0x03, 0x08); - writeEXIcmd(0x02, 0xF8); - unlock(); - - if (result != 1) { - #ifdef DEBUG - OSPanic(__FILE__, 785, "ETHLIB: hash func error\n"); - #endif - } - - return; - } - } - - ir = readcmd(0x0009); - if (__recvpriorityflag == TRUE && (ir & 2) != 0) { - ethstat.rcvcount++; - recvsub0(); - __ETHInterruptTime = OSGetTime() - __OSLastInterruptTime; - } else { - switch (__cntlzw(ir)) { - case 0x18: { - ethstat.rbf++; - writecmd(0x0009, 0x80); - break; - } - - case 0x19: { - writecmd(0x0009, 0x40); - break; - } - - case 0x1A: { - ethstat.fifoe++; - writecmd(0x0009, 0x20); - break; - } - - case 0x1B: { - ethstat.te++; - //ASSERTLINE(816, __sendbusy); - __sendbusy = FALSE; - ltps = readcmd(0x0004); - - if ((ltps & 0x10) != 0) { - ethstat.tx_crs++; - } - - if ((ltps & 0x20) != 0) { - ethstat.tx_uf++; - } - - if ((ltps & 0x40) != 0) { - ethstat.tx_owc++; - } - - sendcbflag = TRUE; - writecmd(0x0009, 0x10); - break; - } - - case 0x1C: { - ethstat.re++; - - lrps = readcmd(0x0005); - if ((lrps & 1) != 0) { - ethstat.rx_bf++; - } - - if ((lrps & 2) != 0) { - ethstat.rx_crc++; - } - - if ((lrps & 4) != 0) { - ethstat.rx_fae++; - } - - if ((lrps & 8) != 0) { - ethstat.rx_fo++; - } - - if ((lrps & 0x10) != 0) { - ethstat.rx_rw++; - } - - if ((lrps & 0x40) != 0) { - ethstat.rx_rf++; - } - - writecmd(0x0009, 0x08); - break; - } - - case 0x1D: { - //ASSERTLINE(868, __sendbusy); - ethstat.sendcount++; - __sendbusy = FALSE; - sendcbflag = TRUE; - ltps = readcmd(0x0004); - writecmd(0x0009, 0x04); - break; - } - - case 0x1E: { - ethstat.rcvcount++; - recvsub0(); - return; - } - - case 0x1F: { - ethstat.cntof++; - writecmd(0x0009, 0x01); - break; - } - } - - writeEXIcmd(0x02, 0xF8); - unlock(); - - if (sendcbflag) { - callback = __sendcallback; - __sendcallback = NULL; - __ETHPostSend(ltps, callback, __sendadr); - } - - __ETHInterruptTime = OSGetTime() - __OSLastInterruptTime; - } - } -} - -s32 ETHInit(s32 mode) { - static BOOL initialized = FALSE; - u32 cid; - u8 fcsr; - u8 phy0r; - - if (initialized == FALSE) { - initialized = TRUE; - OSRegisterVersion(__ETHVersion); - } - - OSInitThreadQueue(&threadQ); - __SIRegs[15] = __SIRegs[15] & ~0x80000000; // turn on 32MHz EXI clock setting allowance - waitexilock(); - __sendbusy = FALSE; - memset(ðstat, 0, sizeof(ethstat)); - protoarray = NULL; - protonum = 0; - recvcallback0 = NULL; - recvcallback1 = NULL; - - cid = 0; - EXIGetID(0, 2, &cid); - if (cid != EXI_ETHER) { - unlock(); - OSReport("cid = %08x\n", cid); - return -1; - } else { - reset(); - readcmdLong(0x0020, private_macaddr, sizeof(private_macaddr)); - __revid = readEXIcmd(0x01); - writeEXIcmdLong(0x04, &__devid, sizeof(__devid)); - writeEXIcmd(0x05, __acstart); - - fcsr = readcmd(0x005B); - fcsr &= ~0x80; - writecmd(0x005B, fcsr); - writecmd(0x005E, 0x01); - - phy0r = readcmd(0x005C); - phy0r |= 0x04; - writecmd(0x005C, phy0r); - - writecmd(0x0001, 0x00); - writecmd(0x0003, 0x2E); - writecmd(0x0050, 0x80); - writecmd(0x0008, 0x00); - writeEXIcmd(0x02, 0xF8); - EXISetExiCallback(2, (EXICallback)&exiinthandler); - unlock(); - - return ETH_OK; - } -} - -void ETHSendAsync(void* addr, s32 length, void (*callback2)(u8)) { - BOOL disabled; - - //ASSERTLINE(985, !__sendbusy); - //ASSERTLINE(986, ((u32) addr % 32) == 0); - DCStoreRange(addr, length); - - disabled = OSDisableInterrupts(); - __sendbusy = TRUE; - __sendadr = addr; - __sendlen = length < 60 ? 60 : length; - __sendcallback = callback2; - sendUpdate = TRUE; - - if (lock()) { - unlock(); - } - - OSRestoreInterrupts(disabled); -} - -static void sendsub0(void) { - u32 etcmd; - - __senddmalen = OSRoundDown32B(__sendlen); - __sendimmlen = __sendlen - __senddmalen; - - etcmd = 0xC0000000 | (0x0048 << 8); - EXISelect(0, 2, 5); - EXIImm(0, &etcmd, sizeof(etcmd), EXI_WRITE, NULL); - EXISync(0); - EXIDma(0, __sendadr, __senddmalen, EXI_WRITE, &sendsub1); -} - -static void sendsub1(s32 chan, OSContext* context) { - u8 ncra; - - if (__sendimmlen != 0) { - EXIImmEx(0, __sendadr + __senddmalen, __sendimmlen, EXI_WRITE); - } - - EXIDeselect(0); - ncra = readcmd(0x0000); - //ASSERTLINE(1033, (ncra & ME_NCRA_TXFIFO) == 0); - ncra |= ME_NCRA_TXFIFO; - writecmd(0x0000, ncra); - unlock(); -} - -void ETHGetMACAddr(u8* macaddr) { - memcpy(macaddr, private_macaddr, sizeof(private_macaddr)); -} - -void ETHSetMACAddr(u8* macaddr) { - memcpy(private_macaddr, macaddr, sizeof(private_macaddr)); - waitexilock(); - writecmdLong(0x0020, private_macaddr, sizeof(private_macaddr)); - unlock(); -} - -void ETHSetRecvCallback(void* (*cb0)(u16, s32, u8), void (*cb1)(u8*, s32)) { - BOOL disabled; - - disabled = OSDisableInterrupts(); - recvcallback0 = cb0; - recvcallback1 = cb1; - recvcallbackUpdate = TRUE; - - if (lock()) { - unlock(); - } - - OSRestoreInterrupts(disabled); -} - -static BOOL linkState(void) { - u8 nways; - - nways = readcmd(0x0031); - if ((nways & 1) != 0 || (nways & 2) != 0) { - return TRUE; - } - - return FALSE; -} - -static BOOL ETHGetLinkState(void) { - BOOL ret; - - waitexilock(); - ret = linkState(); - unlock(); - return ret; -} - -static BOOL linkStateAsyncMain(BOOL* linkstateptr) { - if (EXILock(0, 2, NULL)) { - *linkstateptr = linkState(); - unlock(); - return TRUE; - } - - return FALSE; -} - -BOOL ETHGetLinkStateAsync(BOOL* status) { - //ASSERTLINE(1104, status); - return linkStateAsyncMain(status); -} - -s32 ETHGetNWAYMode(void) { - u8 nways; - - waitexilock(); - nways = readcmd(0x0031); - unlock(); - - if ((nways & 0x10) != 0) { - return 1; - } - - if ((nways & 0x20) != 0) { - return 2; - } - - if ((nways & 0x40) != 0) { - return 3; - } - - if ((nways & 0x80) != 0) { - return 4; - } - - return 5; -} - -void ETHSetProtoType(u16* array, s32 num) { - BOOL flag; - - //ASSERTLINE(1139, (num != 0 && array != NULL) || (num == 0 && array == NULL)); - flag = OSDisableInterrupts(); - protoarray = array; - protonum = num; - OSRestoreInterrupts(flag); -} - -void ETHGetStatus(ETHStat* stat) { - BOOL flag; - - //ASSERTLINE(1150, stat); - flag = OSDisableInterrupts(); - *stat = ethstat; - OSRestoreInterrupts(flag); -} - -s32 ETHGetLibraryVersion(void) { - return 0x506; -} - -s32 ETHGetBBAType(void) { - return 2; -} - -static u16 HashIndex(const u8* address) { - u32 crc; - u16 index; - u32 msb; - u8 byte; - s32 byteLen; - s32 bit; - s32 shift; - - crc = 0xFFFFFFFF; - index = 0; - - for (byteLen = 0; byteLen < 6; byteLen++, address++) { - byte = *address; - bit = 0; - for (bit = 0; bit < 8; bit++, byte >>= 1) { - msb = (crc >> 31) & 1; - crc = crc << 1; - - if (msb ^ (byte & 1)) { - crc ^= 0x04C11DB6; - crc |= 1; - } - } - } - - bit = 31; - for (shift = 5; shift >= 0; shift--, bit--) { - index |= ((crc >> bit) & 1) << shift; - } - - return index; -} - -void ETHAddMulticastAddress(const u8* macaddr) { - BOOL disabled; - u16 index; - u8 marNo; - u8 bitNo; - u8 ncrb; - - if (memcmp(macaddr, broadcastheader, sizeof(broadcastheader)) == 0) { - waitexilock(); - ncrb = readcmd(0x0001); - ncrb |= 4; - writecmd(0x0001, ncrb); - unlock(); - } else { - index = HashIndex(macaddr); - marNo = index / 8; - bitNo = index % 8; - disabled = OSDisableInterrupts(); - mcastmap[marNo] |= 1 << bitNo; - mcastUpdate = TRUE; - - if (lock()) { - unlock(); - } - - OSRestoreInterrupts(disabled); - } -} - -void ETHChangeIntPriority(BOOL flag) { - __recvpriorityflag = flag; -} - -u32 ETHGetREVID(void) { - u32 revid; - - waitexilock(); - revid = readEXIcmd(0x01); - unlock(); - return revid; -} - -void ETHClearMulticastAddresses(void) { - BOOL disabled; - - disabled = OSDisableInterrupts(); - memset(mcastmap, 0, sizeof(mcastmap)); - mcastUpdate = TRUE; - if (lock()) { - unlock(); - } - OSRestoreInterrupts(disabled); -} - -static void unlockcallback(s32 chan, OSContext* context) { - if (lock()) { - unlock(); - } -} - -static BOOL lock() { - return EXILock(0, 2, &unlockcallback); -} - -static void unlock(void) { - BOOL disabled; - - disabled = OSDisableInterrupts(); - - if (mcastUpdate) { - mcastUpdate = FALSE; - writecmdLong(0x0026, mcastmap, sizeof(mcastmap)); - } - - if (recvcallbackUpdate) { - recvcallbackUpdate = FALSE; - - if (recvcallback0 == NULL) { - writecmd(0x0000, 0x00); - writecmd(0x0008, 0x14); - } else { - //ASSERTLINE(1308, recvcallback0 != NULL && recvcallback1 != NULL); - writecmd(0x0008, 0xFF); - recvinit(); - } - } - - if (sendUpdate) { - sendUpdate = FALSE; - sendsub0(); - } else { - EXIUnlock(0); - if (lockUpdate) { - lockUpdate = FALSE; - OSWakeupThread(&threadQ); - } - } - - OSRestoreInterrupts(disabled); -} diff --git a/libs/dolphin/eth/ethsec.c b/libs/dolphin/eth/ethsec.c deleted file mode 100644 index b86953b5e..000000000 --- a/libs/dolphin/eth/ethsec.c +++ /dev/null @@ -1,344 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -#define IP_MIN_HLEN (s32)sizeof(IPHeader) -#define TCP_MIN_HLEN (s32)sizeof(TCPHeader) - -static TCPResetInfo Ri; -static u8 SendBuf[82]; -static const u8 NintendoAddr[6] = { 0,9,191,0,0,0 }; - -extern u32 __OSGetDIConfig(void); -vu16 __OSDeviceCode : (OS_BASE_CACHED | 0x30E6); - -static inline BOOL CheckConsoleType() { - if (__OSGetDIConfig() == 0xFF) { - switch (__OSDeviceCode) { - case 0x8200: { - return TRUE; - } - case 0x8001: { - if (OSGetPhysicalMemSize() == 0x3000000) { - return TRUE; - } - return FALSE; - } - } - return FALSE; - } - - if ((OSGetConsoleType() & OS_CONSOLE_MASK) == 0) { - return FALSE; - } - - return TRUE; -} - -static s16 AT_IP4_IsMyAddrMask(u8 val) { return 0; } - -/*static inline BOOL IPIsLocalAddr(u32, const u8 *addr) { - return AT_IP4_IsMyAddrMask(*addr) != -1; -}*/ - -static u16 CalcIpCheckSum(IPHeader *ip) { - int len; - u32 sum; - u16 *p; - - sum = 0; - len = (ip->verlen & 0xf) << 2; - p = (u16*)ip; - - while (len > 0) { - sum += *p++; - len -= 2; - } - - sum = (sum & 0xffff) + (sum >> 16); - sum = ((sum & 0xffff) + (sum >> 16)); - return sum ^ 0xffff; -} - -static u16 CalcTcpCheckSum(IPHeader *ip, s32 len) { - s32 hlen; - u16 *p; - u32 sum = 0; - -#line 212 - ASSERT(IP_MIN_HLEN + TCP_MIN_HLEN <= len); -#line 215 - ASSERT(ip->proto == IP_PROTO_TCP); - - hlen = (ip->verlen & 0xf) << 2; - sum += ((u16*)ip->src)[0]; - sum += ((u16*)ip->src)[1]; - sum += ((u16*)ip->dst)[0]; - sum += ((u16*)ip->dst)[1]; - sum += 6; - sum += (u32)len - (u32)hlen; - - p = (u16*)((u32)ip+hlen); - len = len - hlen; - while (len > 1) { - sum += *p++; - len -= 2; - } - - if (len == 1) { - sum += *((u8*)p) * 0x100; - } - - sum = (sum & 0xffff) + (sum >> 16); - sum = (sum & 0xffff) + (sum >> 16); - return sum ^ 0xffff; -} - -static s32 GetTcpSegLen(IPHeader *ip, TCPHeader *tcp) { - s32 len = ip->len - ((ip->verlen & 0xf) << 2) - (s32)(((tcp->flag & 0xf000) >> 10)); - - if (tcp->flag & 2) { - len += 1; - } - - if (tcp->flag & 1) { - len += 1; - } - - return len; -} - -static BOOL VerifyPacket(IPHeader *ip) { - if(ip->verlen >> 4 != 4 || ip->len < ((ip->verlen & 0xf) << 2)) { - return TRUE; - } - - if (CalcIpCheckSum(ip) != 0) { - return TRUE; - } - - if ((ip->dst[0] & 0xf0) == 0xe0 || (ip->src[0] & 0xf0) == 0xe0 || - (ip->dst[0] & 0xf8) == 0xf0 || (ip->src[0] & 0xf8) == 0xf0) { - return TRUE; - } - - ASSERT(ip->proto == IP_PROTO_TCP); - if (CalcTcpCheckSum(ip, ip->len) != 0) { - return TRUE; - } - - return FALSE; -} - -static void CalcDigest(u8 *digest, TCPHeader *tcp) { - MD5Context context; - u64 secret; - - MD5Init(&context); - MD5Update(&context,(u8*)&tcp->seq,sizeof(tcp->seq)); - MD5Update(&context,(u8*)&tcp->ack,sizeof(tcp->ack)); - - secret = ((tcp->seq ^ tcp->ack) * 0x5DEECE66Dll + 0xb) % 0x1000000000000ll; - MD5Update(&context,(u8 *)&secret + 2, sizeof(secret) - 2); - MD5Final(digest,&context); -} - -BOOL __ETHFilter(u8 *buf, s32 len) { - ETHHeader *eh; - IPHeader *ip; - TCPHeader *tcp; - TCPResetInfo *ri; - u8 digest1[16]; - u8 digest2[16]; - - ri = &Ri; - if (CheckConsoleType()) { - return TRUE; - } - - eh = (ETHHeader *)buf; - if (eh->type != 0x800) { - return TRUE; - } - - if (memcmp(eh->src, NintendoAddr, 3) == 0) { - return TRUE; - } - - len = len - sizeof(ETHHeader); - ip = (IPHeader *)(eh + 1); - if (len < IP_MIN_HLEN || len < ip->len) { - return TRUE; - } - - if(ip->proto != IP_PROTO_TCP) { - return TRUE; - } - - tcp = (TCPHeader *)((u32)ip + ((ip->verlen & 0xf) << 2)); - if ((s32)(((tcp->flag & 0xf000) >> 10)) < TCP_MIN_HLEN) { - return TRUE; - } - - if (ip->len < ((ip->verlen & 0xf) << 2) + (s32)(((tcp->flag & 0xf000) >> 10))) { - return TRUE; - } - - if ((tcp->flag & 3) == 2) { - switch(tcp->src) { - case 0x76c: - case 0x35: - return TRUE; - } - - switch (tcp->dst) { - case 0x76c: - return TRUE; - } - - if (IPIsLocalAddr(0, ip->src) == FALSE) { - return TRUE; - } - - if (tcp->flag & 4) { - return TRUE; - } - - if (VerifyPacket(ip)) { - return TRUE; - } - - if (ri->flag == 0) { - memmove(ri->addr, eh->src, sizeof(ri->addr)); - memmove(ri->dstAddr, ip->dst, sizeof(ri->dstAddr)); - memmove(ri->srcAddr, ip->src, sizeof(ri->dstAddr)); - ri->dstPort = tcp->dst; - ri->srcPort = tcp->src; - - if ((tcp->flag & 0x10) == 0) { - ri->seq = 0; - ri->ack = tcp->seq + GetTcpSegLen(ip, tcp); - ri->flag = (0x10 | 0x2 | 0x1); - } - else { - ri->seq = tcp->ack; - ri->ack = 0; - ri->flag = (0x2 | 0x1); - } - ri->id = 0; - return TRUE; - } - ip->len = 0; - return FALSE; - } - - if ((tcp->flag & 3) == 3) { - if ((s32)(((tcp->flag & 0xf000) >> 10)) != TCP_MIN_HLEN) { - return TRUE; - } - - if (ip->len != 0x40) { - return TRUE; - } - - if (IPIsLocalAddr(0, ip->src) == FALSE) { - return TRUE; - } - - if (VerifyPacket(ip)) { - return TRUE; - } - - CalcDigest(digest1, tcp); - __IPDecodeFromBase64(tcp + 1, 0x18, digest2); - - if (memcmp(digest1, digest2, sizeof(digest1))) { - return TRUE; - } - ip->len = 0; - return FALSE; - } - return TRUE; -} - -BOOL __ETHPostSend(u8 ltps , void (*callback)(u8), void *prev) { - ETHHeader *eh; - IPHeader *ip; - TCPHeader *tcp; - TCPResetInfo *ri; - u8 digest[16]; - - ri = &Ri; - - if (ri->flag == 0) { - ri = NULL; - } - else if (prev != SendBuf) { - eh = prev; - ip = (IPHeader *)(eh + 1); - tcp = (TCPHeader *)(ip + 1); - if (*((u32*)ip->dst) == *((u32*)ri->srcAddr) && *((u32*)ip->src) == *((u32*)ri->dstAddr) - && tcp->src == ri->dstPort && tcp->dst == ri->srcPort) { - - if (tcp->flag & 4) { - ri->flag = 0; - ri = NULL; - } - else { - ri->seq = tcp->seq + GetTcpSegLen(ip, tcp); - ri->ack = tcp->ack; - ri->flag |= tcp->flag & 0x10; - - ri->id = ip->id - 0x4000; - if (ri->id == 0) { - ri->id = 1; - } - } - } - } - - if (ri != NULL && ri->id != 0) { - eh = (ETHHeader *)SendBuf; - ip = (IPHeader *)(eh + 1); - eh->type = 0x800; - memmove(SendBuf, ri, 6); - ETHGetMACAddr(eh->src); - - ip->verlen = 0x45; - ip->tos = 0; - ip->len = 0x40; - ip->id = ri->id; - ip->frag = 0x4000; - ip->ttl = 0xff; - ip->proto = IP_PROTO_TCP; - ip->sum = 0; - memmove(ip->dst, ri->srcAddr, sizeof(ip->dst)); - memmove(ip->src, ri->dstAddr, sizeof(ip->src)); - - - tcp = (TCPHeader *)((u32)ip + ((ip->verlen & 0xf) << 2)); - tcp->src = ri->dstPort; - tcp->dst = ri->srcPort; - tcp->seq = ri->seq; - tcp->ack = ri->ack; - tcp->flag = ri->flag & 0x3f | 0x5000; - tcp->win = 0; - tcp->sum = 0; - tcp->urg = 0; - - CalcDigest(digest, tcp); - __IPEncodeToBase64(digest, sizeof(digest), tcp + 1); - ip->sum = CalcIpCheckSum(ip); - tcp->sum = CalcTcpCheckSum(ip, ip->len); - ri->flag = 0; - ETHSendAsync(SendBuf, 0x4e, callback); - } - else if (callback) { - (*callback)(ltps); - } - return ETH_OK; -} diff --git a/libs/dolphin/eth/md5.c b/libs/dolphin/eth/md5.c deleted file mode 100644 index 11c6c616d..000000000 --- a/libs/dolphin/eth/md5.c +++ /dev/null @@ -1,285 +0,0 @@ -/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm */ - -/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All - rights reserved. - - License to copy and use this software is granted provided that it - is identified as the "RSA Data Security, Inc. MD5 Message-Digest - Algorithm" in all material mentioning or referencing this software - or this function. - - License is also granted to make and use derivative works provided - that such works are identified as "derived from the RSA Data - Security, Inc. MD5 Message-Digest Algorithm" in all material - mentioning or referencing the derived work. - - RSA Data Security, Inc. makes no representations concerning either - the merchantability of this software or the suitability of this - software for any particular purpose. It is provided "as is" - without express or implied warranty of any kind. - - These notices must be retained in any copies of any part of this - documentation and/or software. - */ - -#include -#include - -/* Constants for MD5Transform routine. - */ -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - -static void MD5Transform (u32 state[4], u8 block[64]); -static void Encode(u8* output, u32* input, u32 len); -static void Decode(u32* output, u8* input, u32 len); - -static u8 PADDING[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* F, G, H and I are basic MD5 functions. - */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | (~z))) - -/* ROTATE_LEFT rotates x left n bits. - */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) - -/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. -Rotation is separate from addition to prevent recomputation. - */ -#define FF(a, b, c, d, x, s, ac) { \ - (a) += F ((b), (c), (d)) + (x) + (u32)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define GG(a, b, c, d, x, s, ac) { \ - (a) += G ((b), (c), (d)) + (x) + (u32)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define HH(a, b, c, d, x, s, ac) { \ - (a) += H ((b), (c), (d)) + (x) + (u32)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define II(a, b, c, d, x, s, ac) { \ - (a) += I ((b), (c), (d)) + (x) + (u32)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } - -/* MD5 initialization. Begins an MD5 operation, writing a new context. - */ -void MD5Init(MD5_CTX *context) -/* context: context */ -{ - context->count[0] = context->count[1] = 0; - /* Load magic initialization constants. */ - context->state[0] = 0x67452301; - context->state[1] = 0xefcdab89; - context->state[2] = 0x98badcfe; - context->state[3] = 0x10325476; -} - -/* MD5 block update operation. Continues an MD5 message-digest - operation, processing another message block, and updating the - context. - */ -void MD5Update(MD5_CTX *context, u8 *input, u32 inputLen) -/* context: context */ -/* input: input block */ -/* inputlen: length of input block */ -{ - u32 i, index, partLen; - - /* Compute number of bytes mod 64 */ - index = (u32)((context->count[0] >> 3) & 0x3F); - - /* Update number of bits */ - if ((context->count[0] += ((u32)inputLen << 3)) < ((u32)inputLen << 3)) - context->count[1]++; - context->count[1] += ((u32)inputLen >> 29); - partLen = 64 - index; - - /* Transform as many times as possible. */ - if (inputLen >= partLen) { - memcpy(&context->buffer[index], input, partLen); - MD5Transform(context->state, context->buffer); - - for (i = partLen; i + 63 < inputLen; i += 64) { - MD5Transform (context->state, &input[i]); - } - - index = 0; - } else { - i = 0; - } - - /* Buffer remaining input */ - memcpy(&context->buffer[index], &input[i], inputLen - i); -} - -/* MD5 finalization. Ends an MD5 message-digest operation, writing the - the message digest and zeroizing the context. - */ -void MD5Final(u8 digest[16], MD5_CTX *context) -/* digest: message digest */ -/* context: context */ -{ - u8 bits[8]; - u32 index, padLen; - - /* Save number of bits */ - Encode (bits, context->count, 8); - - /* Pad out to 56 mod 64. */ - index = (u32)((context->count[0] >> 3) & 0x3f); - padLen = (index < 56) ? (56 - index) : (120 - index); - MD5Update (context, PADDING, padLen); - - /* Append length (before padding) */ - MD5Update (context, bits, 8); - - /* Store state in digest */ - Encode (digest, context->state, 16); - - /* Zeroize sensitive information. */ - memset(context, 0, sizeof(*context)); -} - -/* MD5 basic transformation. Transforms state based on block. - */ -static void MD5Transform (u32 state[4], u8 block[64]) -{ - u32 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - - Decode (x, block, 64); - - /* Round 1 */ - FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ - FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ - FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ - FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ - FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ - FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ - FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ - FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ - FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ - FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ - FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ - FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ - FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ - FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ - FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ - FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ - - /* Round 2 */ - GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ - GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ - GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ - GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ - GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ - GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ - GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ - GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ - GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ - GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ - GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ - GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ - GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ - GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ - GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ - GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ - - /* Round 3 */ - HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ - HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ - HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ - HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ - HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ - HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ - HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ - HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ - HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ - HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ - HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ - HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ - HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ - HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ - HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ - HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ - - /* Round 4 */ - II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ - II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ - II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ - II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ - II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ - II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ - II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ - II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ - II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ - II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ - II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ - II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ - II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ - II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ - II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ - II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - - /* Zeroize sensitive information. */ - memset(x, 0, sizeof(x)); -} - -/* Encodes input (u32) into output (u8). Assumes len is - a multiple of 4. - */ -static void Encode(u8* output, u32* input, u32 len) -{ - u32 i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) { - output[j] = (u8)(input[i] & 0xff); - output[j+1] = (u8)((input[i] >> 8) & 0xff); - output[j+2] = (u8)((input[i] >> 16) & 0xff); - output[j+3] = (u8)((input[i] >> 24) & 0xff); - } -} - -/* Decodes input (u8) into output (u32). Assumes len is - a multiple of 4. - */ -static void Decode(u32* output, u8* input, u32 len) -{ - u32 i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) - output[i] = ((u32)input[j]) | (((u32)input[j+1]) << 8) | - (((u32)input[j+2]) << 16) | (((u32)input[j+3]) << 24); -} diff --git a/libs/dolphin/gd/GDBase.c b/libs/dolphin/gd/GDBase.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/gd/GDGeometry.c b/libs/dolphin/gd/GDGeometry.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/hio/hio.c b/libs/dolphin/hio/hio.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IFFifo.c b/libs/dolphin/ip/IFFifo.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IFRing.c b/libs/dolphin/ip/IFRing.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IP.c b/libs/dolphin/ip/IP.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPArp.c b/libs/dolphin/ip/IPArp.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPChap.c b/libs/dolphin/ip/IPChap.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPDhcp.c b/libs/dolphin/ip/IPDhcp.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPDns.c b/libs/dolphin/ip/IPDns.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPEther.c b/libs/dolphin/ip/IPEther.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPFrag.c b/libs/dolphin/ip/IPFrag.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPIcmp.c b/libs/dolphin/ip/IPIcmp.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPIgmp.c b/libs/dolphin/ip/IPIgmp.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPIpcp.c b/libs/dolphin/ip/IPIpcp.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPLcp.c b/libs/dolphin/ip/IPLcp.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPOpt.c b/libs/dolphin/ip/IPOpt.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPPPP.c b/libs/dolphin/ip/IPPPP.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPPPPoE.c b/libs/dolphin/ip/IPPPPoE.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPPap.c b/libs/dolphin/ip/IPPap.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPRoute.c b/libs/dolphin/ip/IPRoute.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPSocket.c b/libs/dolphin/ip/IPSocket.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPTcp.c b/libs/dolphin/ip/IPTcp.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPTcpOutput.c b/libs/dolphin/ip/IPTcpOutput.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPTcpTimeWait.c b/libs/dolphin/ip/IPTcpTimeWait.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPTcpTimer.c b/libs/dolphin/ip/IPTcpTimer.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPTcpUser.c b/libs/dolphin/ip/IPTcpUser.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPUdp.c b/libs/dolphin/ip/IPUdp.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPUuid.c b/libs/dolphin/ip/IPUuid.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/ip/IPZero.c b/libs/dolphin/ip/IPZero.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/lg/allsrc.c b/libs/dolphin/lg/allsrc.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/dolphin/thp/THPAudio.c b/libs/dolphin/thp/THPAudio.c deleted file mode 100644 index 147d62180..000000000 --- a/libs/dolphin/thp/THPAudio.c +++ /dev/null @@ -1,202 +0,0 @@ -#include - -u32 THPAudioDecode(s16 *audioBuffer, u8 *audioFrame, s32 flag) -{ - THPAudioRecordHeader *header; - THPAudioDecodeInfo decInfo; - u8 *left, *right; - s16 *decLeftPtr, *decRightPtr; - s16 yn1, yn2; - s32 i; - s32 step; - s32 sample; - s64 yn; - - if (audioBuffer == NULL || audioFrame == NULL) - { - return 0; - } - - header = (THPAudioRecordHeader *)audioFrame; - left = audioFrame + sizeof(THPAudioRecordHeader); - right = left + header->offsetNextChannel; - - if (flag == 1) - { - decRightPtr = audioBuffer; - decLeftPtr = audioBuffer + header->sampleSize; - step = 1; - } - else - { - decRightPtr = audioBuffer; - decLeftPtr = audioBuffer + 1; - step = 2; - } - - if (header->offsetNextChannel == 0) - { - __THPAudioInitialize(&decInfo, left); - - yn1 = header->lYn1; - yn2 = header->lYn2; - - for (i = 0; i < header->sampleSize; i++) - { - sample = __THPAudioGetNewSample(&decInfo); - yn = header->lCoef[decInfo.predictor][1] * yn2; - yn += header->lCoef[decInfo.predictor][0] * yn1; - yn += (sample << decInfo.scale) << 11; - yn <<= 5; - - if ((u16)(yn & 0xffff) > 0x8000) - { - yn += 0x10000; - } - else if ((u16)(yn & 0xffff) == 0x8000) - { - if ((yn & 0x10000)) - yn += 0x10000; - } - - if (yn > 2147483647LL) - { - yn = 2147483647LL; - } - - if (yn < -2147483648LL) - { - yn = -2147483648LL; - } - - *decLeftPtr = (s16)(yn >> 16); - decLeftPtr += step; - *decRightPtr = (s16)(yn >> 16); - decRightPtr += step; - yn2 = yn1; - yn1 = (s16)(yn >> 16); - } - } - else - { - __THPAudioInitialize(&decInfo, left); - - yn1 = header->lYn1; - yn2 = header->lYn2; - - for (i = 0; i < header->sampleSize; i++) - { - sample = __THPAudioGetNewSample(&decInfo); - yn = header->lCoef[decInfo.predictor][1] * yn2; - yn += header->lCoef[decInfo.predictor][0] * yn1; - yn += (sample << decInfo.scale) << 11; - yn <<= 5; - if ((u16)(yn & 0xffff) > 0x8000) - { - yn += 0x10000; - } - else - { - if ((u16)(yn & 0xffff) == 0x8000) - { - if ((yn & 0x10000)) - yn += 0x10000; - } - } - - if (yn > 2147483647LL) - { - yn = 2147483647LL; - } - - if (yn < -2147483648LL) - { - yn = -2147483648LL; - } - - *decLeftPtr = (s16)(yn >> 16); - decLeftPtr += step; - yn2 = yn1; - yn1 = (s16)(yn >> 16); - } - - __THPAudioInitialize(&decInfo, right); - - yn1 = header->rYn1; - yn2 = header->rYn2; - - for (i = 0; i < header->sampleSize; i++) - { - sample = __THPAudioGetNewSample(&decInfo); - yn = header->rCoef[decInfo.predictor][1] * yn2; - yn += header->rCoef[decInfo.predictor][0] * yn1; - yn += (sample << decInfo.scale) << 11; - yn <<= 5; - - if ((u16)(yn & 0xffff) > 0x8000) - { - yn += 0x10000; - } - else - { - if ((u16)(yn & 0xffff) == 0x8000) - { - if ((yn & 0x10000)) - yn += 0x10000; - } - } - - if (yn > 2147483647LL) - { - yn = 2147483647LL; - } - - if (yn < -2147483648LL) - { - yn = -2147483648LL; - } - - *decRightPtr = (s16)(yn >> 16); - decRightPtr += step; - yn2 = yn1; - yn1 = (s16)(yn >> 16); - } - } - - return header->sampleSize; -} - -static s32 __THPAudioGetNewSample(THPAudioDecodeInfo *info) -{ - s32 sample; - - if (!(info->offsetNibbles & 0x0f)) - { - info->predictor = (u8)((*(info->encodeData) & 0x70) >> 4); - info->scale = (u8)((*(info->encodeData) & 0xF)); - info->encodeData++; - info->offsetNibbles += 2; - } - - if (info->offsetNibbles & 0x1) - { - sample = (s32)((*(info->encodeData) & 0xF) << 28) >> 28; - info->encodeData++; - } - else - { - sample = (s32)((*(info->encodeData) & 0xF0) << 24) >> 28; - } - - info->offsetNibbles++; - return sample; -} - -static void __THPAudioInitialize(THPAudioDecodeInfo *info, u8 *ptr) -{ - info->encodeData = ptr; - info->offsetNibbles = 2; - info->predictor = (u8)((*(info->encodeData) & 0x70) >> 4); - info->scale = (u8)((*(info->encodeData) & 0xF)); - info->encodeData++; -} \ No newline at end of file diff --git a/libs/dolphin/thp/THPDec.c b/libs/dolphin/thp/THPDec.c deleted file mode 100644 index 10ceb6189..000000000 --- a/libs/dolphin/thp/THPDec.c +++ /dev/null @@ -1,2316 +0,0 @@ -#include -#include - -const char *__THPVersion = "<< Dolphin SDK - THP\trelease build: Aug 27 2002 20:42:01 >>"; - -static THPHuffmanTab *Ydchuff __attribute__((aligned(32))); -static THPHuffmanTab *Udchuff __attribute__((aligned(32))); -static THPHuffmanTab *Vdchuff __attribute__((aligned(32))); -static THPHuffmanTab *Yachuff __attribute__((aligned(32))); -static THPHuffmanTab *Uachuff __attribute__((aligned(32))); -static THPHuffmanTab *Vachuff __attribute__((aligned(32))); -static f32 __THPIDCTWorkspace[64] __attribute__((aligned(32))); -static u8 *__THPHuffmanBits; -static u8 *__THPHuffmanSizeTab; -static u16 *__THPHuffmanCodeTab; -static THPSample *Gbase __attribute__((aligned(32))); -static u32 Gwid __attribute__((aligned(32))); -static f32 *Gq __attribute__((aligned(32))); -static u8 *__THPLCWork512[3]; -static u8 *__THPLCWork672[3]; -static u32 __THPOldGQR5; -static u32 __THPOldGQR6; -static u8 *__THPWorkArea; -static THPCoeff *__THPMCUBuffer[6]; -static THPFileInfo *__THPInfo; -static BOOL __THPInitFlag = FALSE; - -#define ROUNDUP(a, b) ((((s32)(a)) + ((s32)(b)-1L)) / ((s32)(b))) - -void __THPInverseDCTY8(register THPCoeff *, register u32); - -s32 THPVideoDecode(void *file, void *tileY, void *tileU, void *tileV, void *work) -{ - u8 all_done, status; - s32 errorCode; - - if (!file) - { - goto _err_no_input; - } - - if (tileY == NULL || tileU == NULL || tileV == NULL) - { - goto _err_no_output; - } - - if (!work) - { - goto _err_no_work; - } - - if (!(PPCMfhid2() & 0x10000000)) - { - goto _err_lc_not_enabled; - } - - if (__THPInitFlag == FALSE) - { - goto _err_not_initialized; - } - - __THPWorkArea = (u8 *)work; - __THPInfo = (THPFileInfo *)OSRoundUp32B(__THPWorkArea); - __THPWorkArea = (u8 *)OSRoundUp32B(__THPWorkArea) + sizeof(THPFileInfo); - DCZeroRange(__THPInfo, sizeof(THPFileInfo)); - __THPInfo->cnt = 33; - __THPInfo->decompressedY = 0; - __THPInfo->c = (u8 *)file; - all_done = FALSE; - - for (;;) - { - if ((*(__THPInfo->c)++) != 255) - { - goto _err_bad_syntax; - } - - while (*__THPInfo->c == 255) - { - ((__THPInfo->c)++); - } - - status = (*(__THPInfo->c)++); - - if (status <= 0xD7) - { - if (status == 196) - { - status = __THPReadHuffmanTableSpecification(); - if (status != 0) - { - goto _err_bad_status; - } - } - - else if (status == 192) - { - status = __THPReadFrameHeader(); - if (status != 0) - { - goto _err_bad_status; - } - } - - else - { - goto _err_unsupported_marker; - } - } - - else if (0xD8 <= status && status <= 0xDF) - { - if (status == 221) - { - __THPRestartDefinition(); - } - - else if (status == 219) - { - status = __THPReadQuantizationTable(); - if (status != 0) - { - goto _err_bad_status; - } - } - - else if (status == 218) - { - status = __THPReadScaneHeader(); - if (status != 0) - { - goto _err_bad_status; - } - - all_done = TRUE; - } - else if (status == 216) - { - // empty but required for match - } - else - { - goto _err_unsupported_marker; - } - } - - else if (0xE0 <= status) - { - if ((224 <= status && status <= 239) || status == 254) - { - __THPInfo->c += (__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]; - } - else - { - goto _err_unsupported_marker; - } - } - - if (all_done) - { - break; - } - } - - __THPSetupBuffers(); - __THPDecompressYUV(tileY, tileU, tileV); - return 0; - -_err_no_input: - errorCode = 25; - goto _err_exit; - -_err_no_output: - errorCode = 27; - goto _err_exit; - -_err_no_work: - errorCode = 26; - goto _err_exit; - -_err_unsupported_marker: - errorCode = 11; - goto _err_exit; - -_err_bad_resource: - errorCode = 1; - goto _err_exit; - -_err_no_mem: - errorCode = 6; - goto _err_exit; - -_err_bad_syntax: - errorCode = 3; - goto _err_exit; - -_err_bad_status: - errorCode = status; - goto _err_exit; - -_err_lc_not_enabled: - errorCode = 28; - goto _err_exit; - -_err_not_initialized: - errorCode = 29; - goto _err_exit; - -_err_exit: - return errorCode; -} - -static void __THPSetupBuffers(void) -{ - u8 i; - THPCoeff *buffer; - - buffer = (THPCoeff *)OSRoundUp32B(__THPWorkArea); - - for (i = 0; i < 6; i++) - { - __THPMCUBuffer[i] = &buffer[i * 64]; - } -} - -u8 __THPReadFrameHeader(void) -{ - u8 i, utmp8; - - __THPInfo->c += 2; - - utmp8 = (*(__THPInfo->c)++); - - if (utmp8 != 8) - { - return 10; - } - - __THPInfo->yPixelSize = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); - __THPInfo->c += 2; - __THPInfo->xPixelSize = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); - __THPInfo->c += 2; - - utmp8 = (*(__THPInfo->c)++); - if (utmp8 != 3) - { - return 12; - } - - for (i = 0; i < 3; i++) - { - utmp8 = (*(__THPInfo->c)++); - utmp8 = (*(__THPInfo->c)++); - if ((i == 0 && utmp8 != 0x22) || (i > 0 && utmp8 != 0x11)) - { - return 19; - } - - __THPInfo->components[i].quantizationTableSelector = (*(__THPInfo->c)++); - } - - return 0; -} - -/* there is an EXTREMELY tiny schedule swap but otherwise matching */ -u8 __THPReadScaneHeader(void) -{ - u8 i, utmp8; - __THPInfo->c += 2; - - utmp8 = (*(__THPInfo->c)++); - - if (utmp8 != 3) - { - return 12; - } - - for (i = 0; i < 3; i++) - { - utmp8 = (*(__THPInfo->c)++); - - utmp8 = (*(__THPInfo->c)++); - __THPInfo->components[i].DCTableSelector = (u8)(utmp8 >> 4); - __THPInfo->components[i].ACTableSelector = (u8)(utmp8 & 15); - - if ((__THPInfo->validHuffmanTabs & (1 << ((utmp8 >> 4)))) == 0) - { - return 15; - } - - if ((__THPInfo->validHuffmanTabs & (1 << ((utmp8 & 15) + 1))) == 0) - { - return 15; - } - } - - __THPInfo->c += 3; - __THPInfo->MCUsPerRow = (u16)ROUNDUP(__THPInfo->xPixelSize, 16); - __THPInfo->components[0].predDC = 0; - __THPInfo->components[1].predDC = 0; - __THPInfo->components[2].predDC = 0; - return 0; -} - -u8 __THPReadQuantizationTable(void) -{ - u16 length, id, i, row, col; - f32 q_temp[64]; - - length = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); - __THPInfo->c += 2; - length -= 2; - - for (;;) - { - id = (*(__THPInfo->c)++); - - for (i = 0; i < 64; i++) - { - q_temp[__THPJpegNaturalOrder[i]] = (f32)(*(__THPInfo->c)++); - } - - i = 0; - for (row = 0; row < 8; row++) - { - for (col = 0; col < 8; col++) - { - __THPInfo->quantTabs[id][i] = (f32)((f64)q_temp[i] * __THPAANScaleFactor[row] * __THPAANScaleFactor[col]); - i++; - } - } - - length -= 65; - if (!length) - { - break; - } - } - - return 0; -} - -u8 __THPReadHuffmanTableSpecification(void) -{ - u8 t_class, id, i, tab_index; - u16 length, num_Vij; - - __THPHuffmanSizeTab = __THPWorkArea; - __THPHuffmanCodeTab = (u16 *)((u32)__THPWorkArea + 256 + 1); - length = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); - __THPInfo->c += 2; - length -= 2; - - for (;;) - { - i = (*(__THPInfo->c)++); - id = (u8)(i & 15); - t_class = (u8)(i >> 4); - __THPHuffmanBits = __THPInfo->c; - tab_index = (u8)((id << 1) + t_class); - num_Vij = 0; - - for (i = 0; i < 16; i++) - { - num_Vij += (*(__THPInfo->c)++); - } - - __THPInfo->huffmanTabs[tab_index].Vij = __THPInfo->c; - __THPInfo->c += num_Vij; - __THPHuffGenerateSizeTable(); - __THPHuffGenerateCodeTable(); - __THPHuffGenerateDecoderTables(tab_index); - __THPInfo->validHuffmanTabs |= 1 << tab_index; - length -= 17 + num_Vij; - - if (length == 0) - { - break; - } - } - - return 0; -} - -static void __THPHuffGenerateSizeTable(void) -{ - s32 p, l, i; - p = 0; - - for (l = 1; l <= 16; l++) - { - i = (s32)__THPHuffmanBits[l - 1]; - while (i--) - { - __THPHuffmanSizeTab[p++] = (u8)l; - } - } - - __THPHuffmanSizeTab[p] = 0; -} - -static void __THPHuffGenerateCodeTable(void) -{ - u8 si; - u16 p, code; - - p = 0; - code = 0; - si = __THPHuffmanSizeTab[0]; - - while (__THPHuffmanSizeTab[p]) - { - while (__THPHuffmanSizeTab[p] == si) - { - __THPHuffmanCodeTab[p++] = code; - code++; - } - - code <<= 1; - si++; - } -} - -static void __THPHuffGenerateDecoderTables(u8 tabIndex) -{ - s32 p, l; - THPHuffmanTab *h; - - p = 0; - h = &__THPInfo->huffmanTabs[tabIndex]; - for (l = 1; l <= 16; l++) - { - if (__THPHuffmanBits[l - 1]) - { - h->valPtr[l] = p - __THPHuffmanCodeTab[p]; - p += __THPHuffmanBits[l - 1]; - h->maxCode[l] = __THPHuffmanCodeTab[p - 1]; - } - else - { - h->maxCode[l] = -1; - h->valPtr[l] = -1; - } - } - - h->maxCode[17] = 0xfffffL; -} - -static void __THPRestartDefinition(void) -{ - __THPInfo->RST = TRUE; - __THPInfo->c += 2; - __THPInfo->nMCU = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); - __THPInfo->c += 2; - __THPInfo->currMCU = __THPInfo->nMCU; -} - -static inline void __THPGQRSetup(void) -{ - register u32 tmp1, tmp2; - - asm { - mfspr tmp1, GQR5; - mfspr tmp2, GQR6; - } - - __THPOldGQR5 = tmp1; - __THPOldGQR6 = tmp2; - - asm { - li r3, 0x0007 - oris r3, r3, 0x0007 - mtspr GQR5, r3 - li r3, 0x3D04 - oris r3, r3, 0x3D04 - mtspr GQR6, r3 - } -} - -static inline void __THPGQRRestore(void) -{ - register u32 tmp1, tmp2; - tmp1 = __THPOldGQR5; - tmp2 = __THPOldGQR6; - - asm { - mtspr GQR5, tmp1; - mtspr GQR6, tmp2; - } -} - -void __THPPrepBitStream(void) -{ - u32 *ptr; - u32 offset, i, j, k; - - ptr = (u32 *)((u32)__THPInfo->c & 0xFFFFFFFC); - offset = (u32)__THPInfo->c & 3; - - if (__THPInfo->cnt != 33) - { - __THPInfo->cnt -= (3 - offset) * 8; - } - else - { - __THPInfo->cnt = (offset * 8) + 1; - } - - __THPInfo->c = (u8 *)ptr; - __THPInfo->currByte = *ptr; - - for (i = 0; i < 4; i++) - { - if (__THPInfo->validHuffmanTabs & (1 << i)) - { - for (j = 0; j < 32; j++) - { - __THPInfo->huffmanTabs[i].quick[j] = 0xFF; - - for (k = 0; k < 5; k++) - { - s32 code = (s32)(j >> (5 - k - 1)); - - if (code <= __THPInfo->huffmanTabs[i].maxCode[k + 1]) - { - __THPInfo->huffmanTabs[i].quick[j] = __THPInfo->huffmanTabs[i].Vij[(s32)(code + __THPInfo->huffmanTabs[i].valPtr[k + 1])]; - __THPInfo->huffmanTabs[i].increment[j] = (u8)(k + 1); - k = 99; - } - else - { - } - } - } - } - } - - { - s32 YdcTab, UdcTab, VdcTab, YacTab, UacTab, VacTab; - - YdcTab = (__THPInfo->components[0].DCTableSelector << 1); - UdcTab = (__THPInfo->components[1].DCTableSelector << 1); - VdcTab = (__THPInfo->components[2].DCTableSelector << 1); - - YacTab = (__THPInfo->components[0].ACTableSelector << 1) + 1; - UacTab = (__THPInfo->components[1].ACTableSelector << 1) + 1; - VacTab = (__THPInfo->components[2].ACTableSelector << 1) + 1; - - Ydchuff = &__THPInfo->huffmanTabs[YdcTab]; - Udchuff = &__THPInfo->huffmanTabs[UdcTab]; - Vdchuff = &__THPInfo->huffmanTabs[VdcTab]; - - Yachuff = &__THPInfo->huffmanTabs[YacTab]; - Uachuff = &__THPInfo->huffmanTabs[UacTab]; - Vachuff = &__THPInfo->huffmanTabs[VacTab]; - } -} - -void __THPDecompressYUV(void *tileY, void *tileU, void *tileV) -{ - u16 currentY, targetY; - __THPInfo->dLC[0] = tileY; - __THPInfo->dLC[1] = tileU; - __THPInfo->dLC[2] = tileV; - - currentY = __THPInfo->decompressedY; - targetY = __THPInfo->yPixelSize; - - __THPGQRSetup(); - __THPPrepBitStream(); - - if (__THPInfo->xPixelSize == 512 && targetY == 448) - { - while (currentY < targetY) - { - __THPDecompressiMCURow512x448(); - currentY += 16; - } - } - else if (__THPInfo->xPixelSize == 640 && targetY == 480) - { - while (currentY < targetY) - { - __THPDecompressiMCURow640x480(); - currentY += 16; - } - } - else - { - while (currentY < targetY) - { - __THPDecompressiMCURowNxN(); - currentY += 16; - } - } - - __THPGQRRestore(); -} - -inline void __THPInverseDCTNoYPos(register THPCoeff *in, register u32 xPos) -{ - register f32 *q, *ws; - register f32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; - register f32 tmp10, tmp11, tmp12, tmp13; - register f32 tmp20, tmp21, tmp22, tmp23; - register f32 cc4 = 1.414213562F; - register f32 cc2 = 1.847759065F; - register f32 cc2c6s = 1.082392200F; - register f32 cc2c6a = -2.613125930F; - register f32 bias = 1024.0F; - q = Gq; - ws = &__THPIDCTWorkspace[0] - 2; - - { - register u32 itmp0, itmp1, itmp2, itmp3; - asm { - li itmp2, 8 - mtctr itmp2 - - _loopHead0: - psq_l tmp10, 0(in), 0, 5 - psq_l tmp11, 0(q), 0, 0 - lwz itmp0, 12(in) - lwz itmp3, 8(in) - ps_mul tmp10, tmp10, tmp11 - lwz itmp1, 4(in) - lhz itmp2, 2(in) - or. itmp0, itmp0, itmp3 - - _loopHead1: - cmpwi itmp0, 0 - bne _regularIDCT - ps_merge00 tmp0, tmp10, tmp10 - cmpwi itmp1, 0 - psq_st tmp0, 8(ws), 0, 0 - bne _halfIDCT - psq_st tmp0, 16(ws), 0, 0 - cmpwi itmp2, 0 - psq_st tmp0, 24(ws), 0, 0 - bne _quarterIDCT - addi q, q, 8*sizeof(f32) - psq_stu tmp0, 32(ws), 0, 0 - addi in, in, 8*sizeof(THPCoeff) - bdnz _loopHead0 - b _loopEnd - - _quarterIDCT: - addi in, in, 8*sizeof(THPCoeff) - ps_msub tmp2, tmp10, cc2, tmp10 - addi q, q, 8*sizeof(f32) - ps_merge00 tmp9, tmp10, tmp10 - lwz itmp1, 4(in) - ps_sub tmp1, cc2, cc2c6s - ps_msub tmp3, tmp10, cc4, tmp2 - lhz itmp2, 2(in) - ps_merge11 tmp5, tmp10, tmp2 - psq_l tmp11, 0(q), 0, 0 - ps_nmsub tmp4, tmp10, tmp1, tmp3 - ps_add tmp7, tmp9, tmp5 - psq_l tmp10, 0(in), 0, 5 - ps_merge11 tmp6, tmp3, tmp4 - ps_sub tmp5, tmp9, tmp5 - lwz itmp0, 12(in) - ps_add tmp8, tmp9, tmp6 - lwz itmp3, 8(in) - ps_sub tmp6, tmp9, tmp6 - psq_stu tmp7, 8(ws), 0, 0 - ps_merge10 tmp6, tmp6, tmp6 - psq_stu tmp8, 8(ws), 0, 0 - ps_merge10 tmp5, tmp5, tmp5 - or itmp0, itmp0, itmp3 - psq_stu tmp6, 8(ws), 0, 0 - ps_mul tmp10, tmp10, tmp11 - psq_stu tmp5, 8(ws), 0, 0 - bdnz _loopHead1 - b _loopEnd - - _halfIDCT: - psq_l tmp1, 4(in), 0, 5 - psq_l tmp9, 8(q), 0, 0 - addi in, in, 8*sizeof(THPCoeff) - ps_mul tmp1, tmp1, tmp9 - addi q, q, 8*sizeof(f32) - ps_sub tmp3, tmp10, tmp1 - ps_add tmp2, tmp10, tmp1 - lwz itmp0, 12(in) - ps_madd tmp4, tmp1, cc4, tmp3 - ps_nmsub tmp5, tmp1, cc4, tmp2 - ps_mul tmp8, tmp3, cc2 - ps_merge00 tmp4, tmp2, tmp4 - lwz itmp3, 8(in) - ps_nmsub tmp6, tmp1, cc2c6a, tmp8 - ps_merge00 tmp5, tmp5, tmp3 - lwz itmp1, 4(in) - ps_sub tmp6, tmp6, tmp2 - ps_nmsub tmp7, tmp10, cc2c6s, tmp8 - lhz itmp2, 2(in) - ps_merge11 tmp2, tmp2, tmp6 - ps_msub tmp8, tmp3, cc4, tmp6 - psq_l tmp10, 0(in), 0, 5 - ps_add tmp9, tmp4, tmp2 - ps_sub tmp7, tmp7, tmp8 - psq_l tmp11, 0(q), 0, 0 - ps_merge11 tmp3, tmp8, tmp7 - ps_sub tmp4, tmp4, tmp2 - psq_stu tmp9, 8(ws), 0, 0 - ps_add tmp0, tmp5, tmp3 - ps_sub tmp1, tmp5, tmp3 - or itmp0, itmp0, itmp3 - psq_stu tmp0, 8(ws), 0, 0 - ps_merge10 tmp1, tmp1, tmp1 - ps_merge10 tmp4, tmp4, tmp4 - psq_stu tmp1, 8(ws), 0, 0 - ps_mul tmp10, tmp10, tmp11 - psq_stu tmp4, 8(ws), 0, 0 - bdnz _loopHead1 - b _loopEnd - - _regularIDCT: - psq_l tmp9, 4(in), 0, 5 - psq_l tmp5, 8(q), 0, 0 - ps_mul tmp9, tmp9, tmp5 - psq_l tmp2, 8(in), 0, 5 - psq_l tmp6, 16(q), 0, 0 - ps_merge01 tmp0, tmp10, tmp9 - psq_l tmp3, 12(in), 0, 5 - ps_merge01 tmp1, tmp9, tmp10 - psq_l tmp7, 24(q), 0, 0 - addi in, in, 8*sizeof(THPCoeff) - ps_madd tmp4, tmp2, tmp6, tmp0 - ps_nmsub tmp5, tmp2, tmp6, tmp0 - ps_madd tmp6, tmp3, tmp7, tmp1 - ps_nmsub tmp7, tmp3, tmp7, tmp1 - addi q, q, 8*sizeof(f32) - ps_add tmp0, tmp4, tmp6 - ps_sub tmp3, tmp4, tmp6 - ps_msub tmp2, tmp7, cc4, tmp6 - lwz itmp0, 12(in) - ps_sub tmp8, tmp7, tmp5 - ps_add tmp1, tmp5, tmp2 - ps_sub tmp2, tmp5, tmp2 - ps_mul tmp8, tmp8, cc2 - lwz itmp3, 8(in) - ps_merge00 tmp1, tmp0, tmp1 - ps_nmsub tmp6, tmp5, cc2c6a, tmp8 - ps_msub tmp4, tmp7, cc2c6s, tmp8 - lwz itmp1, 4(in) - ps_sub tmp6, tmp6, tmp0 - ps_merge00 tmp2, tmp2, tmp3 - lhz itmp2, 2(in) - ps_madd tmp5, tmp3, cc4, tmp6 - ps_merge11 tmp7, tmp0, tmp6 - psq_l tmp10, 0(in), 0, 5 - ps_sub tmp4, tmp4, tmp5 - ps_add tmp3, tmp1, tmp7 - psq_l tmp11, 0(q), 0, 0 - ps_merge11 tmp4, tmp5, tmp4 - ps_sub tmp0, tmp1, tmp7 - ps_mul tmp10, tmp10, tmp11 - ps_add tmp5, tmp2, tmp4 - ps_sub tmp6, tmp2, tmp4 - ps_merge10 tmp5, tmp5, tmp5 - psq_stu tmp3, 8(ws), 0, 0 - ps_merge10 tmp0, tmp0, tmp0 - psq_stu tmp6, 8(ws), 0, 0 - psq_stu tmp5, 8(ws), 0, 0 - or itmp0, itmp0, itmp3 - psq_stu tmp0, 8(ws), 0, 0 - bdnz _loopHead1 - - _loopEnd: - - } - } - - ws = &__THPIDCTWorkspace[0]; - - { - register THPSample *obase = Gbase; - register u32 wid = Gwid; - - register u32 itmp0, off0, off1; - register THPSample *out0, *out1; - - asm { - psq_l tmp10, 8*0*sizeof(f32)(ws), 0, 0 - slwi xPos, xPos, 2 - psq_l tmp11, 8*4*sizeof(f32)(ws), 0, 0 - slwi off1, wid, 2 - psq_l tmp12, 8*2*sizeof(f32)(ws), 0, 0 - mr off0, xPos - ps_add tmp6, tmp10, tmp11 - psq_l tmp13, 8*6*sizeof(f32)(ws), 0, 0 - ps_sub tmp8, tmp10, tmp11 - add off1, off0, off1 - ps_add tmp6, tmp6, bias - li itmp0, 3 - ps_add tmp7, tmp12, tmp13 - add out0, obase, off0 - ps_sub tmp9, tmp12, tmp13 - ps_add tmp0, tmp6, tmp7 - add out1, obase, off1 - ps_add tmp8, tmp8, bias - mtctr itmp0 - - _loopHead10: - psq_l tmp4, 8*1*sizeof(f32)(ws), 0, 0 - ps_msub tmp9, tmp9, cc4, tmp7 - psq_l tmp5, 8*3*sizeof(f32)(ws), 0, 0 - ps_sub tmp3, tmp6, tmp7 - ps_add tmp1, tmp8, tmp9 - psq_l tmp6, 8*5*sizeof(f32)(ws), 0, 0 - ps_sub tmp2, tmp8, tmp9 - psq_l tmp7, 8*7*sizeof(f32)(ws), 0, 0 - ps_add tmp8, tmp6, tmp5 - ps_sub tmp6, tmp6, tmp5 - addi ws, ws, 2*sizeof(f32) - ps_add tmp9, tmp4, tmp7 - ps_sub tmp4, tmp4, tmp7 - psq_l tmp10, 8*0*sizeof(f32)(ws), 0, 0 - ps_add tmp7, tmp9, tmp8 - ps_sub tmp5, tmp9, tmp8 - ps_add tmp8, tmp6, tmp4 - psq_l tmp11, 8*4*sizeof(f32)(ws), 0, 0 - ps_add tmp9, tmp0, tmp7 - ps_mul tmp8, tmp8, cc2 - psq_l tmp12, 8*2*sizeof(f32)(ws), 0, 0 - ps_sub tmp23, tmp0, tmp7 - ps_madd tmp6, tmp6, cc2c6a, tmp8 - psq_l tmp13, 8*6*sizeof(f32)(ws), 0, 0 - ps_sub tmp6, tmp6, tmp7 - addi off0, off0, 2*sizeof(THPSample) - psq_st tmp9, 0(out0), 0, 6 - ps_msub tmp4, tmp4, cc2c6s, tmp8 - ps_add tmp9, tmp1, tmp6 - ps_msub tmp5, tmp5, cc4, tmp6 - ps_sub tmp22, tmp1, tmp6 - psq_st tmp9, 8(out0), 0, 6 - ps_add tmp8, tmp2, tmp5 - ps_add tmp4, tmp4, tmp5 - psq_st tmp8, 16(out0), 0, 6 - addi off1, off1, 2*sizeof(THPSample) - ps_sub tmp9, tmp3, tmp4 - ps_add tmp20, tmp3, tmp4 - psq_st tmp9, 24(out0), 0, 6 - ps_sub tmp21, tmp2, tmp5 - ps_add tmp6, tmp10, tmp11 - psq_st tmp20, 0(out1), 0, 6 - ps_sub tmp8, tmp10, tmp11 - ps_add tmp6, tmp6, bias - psq_st tmp21, 8(out1), 0, 6 - ps_add tmp7, tmp12, tmp13 - ps_sub tmp9, tmp12, tmp13 - psq_st tmp22, 16(out1), 0, 6 - add out0, obase, off0 - ps_add tmp0, tmp6, tmp7 - psq_st tmp23, 24(out1), 0, 6 - ps_add tmp8, tmp8, bias - add out1, obase, off1 - bdnz _loopHead10 - psq_l tmp4, 8*1*sizeof(f32)(ws), 0, 0 - ps_msub tmp9, tmp9, cc4, tmp7 - psq_l tmp5, 8*3*sizeof(f32)(ws), 0, 0 - ps_sub tmp3, tmp6, tmp7 - ps_add tmp1, tmp8, tmp9 - psq_l tmp6, 8*5*sizeof(f32)(ws), 0, 0 - ps_sub tmp2, tmp8, tmp9 - psq_l tmp7, 8*7*sizeof(f32)(ws), 0, 0 - ps_add tmp8, tmp6, tmp5 - ps_sub tmp6, tmp6, tmp5 - ps_add tmp9, tmp4, tmp7 - ps_sub tmp4, tmp4, tmp7 - ps_add tmp7, tmp9, tmp8 - ps_sub tmp5, tmp9, tmp8 - ps_add tmp8, tmp6, tmp4 - ps_add tmp9, tmp0, tmp7 - ps_mul tmp8, tmp8, cc2 - ps_sub tmp23, tmp0, tmp7 - ps_madd tmp6, tmp6, cc2c6a, tmp8 - psq_st tmp9, 0(out0), 0, 6 - ps_sub tmp6, tmp6, tmp7 - ps_msub tmp4, tmp4, cc2c6s, tmp8 - psq_st tmp23, 24(out1), 0, 6 - ps_add tmp9, tmp1, tmp6 - ps_msub tmp5, tmp5, cc4, tmp6 - ps_sub tmp22, tmp1, tmp6 - psq_st tmp9, 8(out0), 0, 6 - ps_add tmp8, tmp2, tmp5 - ps_add tmp4, tmp4, tmp5 - psq_st tmp22, 16(out1), 0, 6 - psq_st tmp8, 16(out0), 0, 6 - ps_sub tmp9, tmp3, tmp4 - ps_add tmp20, tmp3, tmp4 - psq_st tmp9, 24(out0), 0, 6 - ps_sub tmp21, tmp2, tmp5 - psq_st tmp20, 0(out1), 0, 6 - psq_st tmp21, 8(out1), 0, 6 - } - } -} - -inline void __THPInverseDCTY8(register THPCoeff *in, register u32 xPos) -{ - register f32 *q, *ws; - register f32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; - register f32 tmp10, tmp11, tmp12, tmp13; - register f32 tmp20, tmp21, tmp22, tmp23; - register f32 cc4 = 1.414213562F; - register f32 cc2 = 1.847759065F; - register f32 cc2c6s = 1.082392200F; - register f32 cc2c6a = -2.613125930F; - register f32 bias = 1024.0F; - - q = Gq; - ws = &__THPIDCTWorkspace[0] - 2; - - { - register u32 itmp0, itmp1, itmp2, itmp3; - - asm { - li itmp2, 8 - mtctr itmp2 - - _loopHead0: - psq_l tmp10, 0(in), 0, 5 - psq_l tmp11, 0(q), 0, 0 - lwz itmp0, 12(in) - lwz itmp3, 8(in) - ps_mul tmp10, tmp10, tmp11 - lwz itmp1, 4(in) - lhz itmp2, 2(in) - or itmp0, itmp0, itmp3 - - _loopHead1: - cmpwi itmp0, 0 - bne _regularIDCT - ps_merge00 tmp0, tmp10, tmp10 - cmpwi itmp1, 0 - psq_st tmp0, 8(ws), 0, 0 - bne _halfIDCT - psq_st tmp0, 16(ws), 0, 0 - cmpwi itmp2, 0 - psq_st tmp0, 24(ws), 0, 0 - bne _quarterIDCT - addi q, q, 8*sizeof(f32) - psq_stu tmp0, 32(ws), 0, 0 - addi in, in, 8*sizeof(THPCoeff) - bdnz _loopHead0 - b _loopEnd - - _quarterIDCT: - ps_msub tmp2, tmp10, cc2, tmp10 - addi in, in, 8*sizeof(THPCoeff) - ps_merge00 tmp9, tmp10, tmp10 - addi q, q, 8*sizeof(f32) - ps_sub tmp1, cc2, cc2c6s - lwz itmp1, 4(in) - ps_msub tmp3, tmp10, cc4, tmp2 - lhz itmp2, 2(in) - ps_merge11 tmp5, tmp10, tmp2 - psq_l tmp11, 0(q), 0, 0 - ps_nmsub tmp4, tmp10, tmp1, tmp3 - ps_add tmp7, tmp9, tmp5 - psq_l tmp10, 0(in), 0, 5 - ps_merge11 tmp6, tmp3, tmp4 - ps_sub tmp5, tmp9, tmp5 - lwz itmp0, 12(in) - ps_add tmp8, tmp9, tmp6 - lwz itmp3, 8(in) - ps_sub tmp6, tmp9, tmp6 - psq_stu tmp7, 8(ws), 0, 0 - ps_merge10 tmp6, tmp6, tmp6 - psq_stu tmp8, 8(ws), 0, 0 - ps_merge10 tmp5, tmp5, tmp5 - or itmp0, itmp0, itmp3 - psq_stu tmp6, 8(ws), 0, 0 - ps_mul tmp10, tmp10, tmp11 - psq_stu tmp5, 8(ws), 0, 0 - bdnz _loopHead1 - b _loopEnd - - _halfIDCT: - psq_l tmp1, 4(in), 0, 5 - psq_l tmp9, 8(q), 0, 0 - addi in, in, 8*sizeof(THPCoeff) - ps_mul tmp1, tmp1, tmp9 - addi q, q, 8*sizeof(f32) - ps_sub tmp3, tmp10, tmp1 - ps_add tmp2, tmp10, tmp1 - lwz itmp0, 12(in) - ps_madd tmp4, tmp1, cc4, tmp3 - ps_nmsub tmp5, tmp1, cc4, tmp2 - ps_mul tmp8, tmp3, cc2 - ps_merge00 tmp4, tmp2, tmp4 - lwz itmp3, 8(in) - ps_nmsub tmp6, tmp1, cc2c6a, tmp8 - ps_merge00 tmp5, tmp5, tmp3 - lwz itmp1, 4(in) - ps_sub tmp6, tmp6, tmp2 - ps_nmsub tmp7, tmp10, cc2c6s, tmp8 - lhz itmp2, 2(in) - ps_merge11 tmp2, tmp2, tmp6 - ps_msub tmp8, tmp3, cc4, tmp6 - psq_l tmp10, 0(in), 0, 5 - ps_add tmp9, tmp4, tmp2 - ps_sub tmp7, tmp7, tmp8 - psq_l tmp11, 0(q), 0, 0 - ps_merge11 tmp3, tmp8, tmp7 - ps_sub tmp4, tmp4, tmp2 - psq_stu tmp9, 8(ws), 0, 0 - ps_add tmp0, tmp5, tmp3 - ps_sub tmp1, tmp5, tmp3 - or itmp0, itmp0, itmp3 - psq_stu tmp0, 8(ws), 0, 0 - ps_merge10 tmp1, tmp1, tmp1 - ps_merge10 tmp4, tmp4, tmp4 - psq_stu tmp1, 8(ws), 0, 0 - ps_mul tmp10, tmp10, tmp11 - psq_stu tmp4, 8(ws), 0, 0 - bdnz _loopHead1 - b _loopEnd - - _regularIDCT: - psq_l tmp9, 4(in), 0, 5 - psq_l tmp5, 8(q), 0, 0 - ps_mul tmp9, tmp9, tmp5 - psq_l tmp2, 8(in), 0, 5 - psq_l tmp6, 16(q), 0, 0 - ps_merge01 tmp0, tmp10, tmp9 - psq_l tmp3, 12(in), 0, 5 - ps_merge01 tmp1, tmp9, tmp10 - psq_l tmp7, 24(q), 0, 0 - addi in, in, 8*sizeof(THPCoeff) - ps_madd tmp4, tmp2, tmp6, tmp0 - ps_nmsub tmp5, tmp2, tmp6, tmp0 - ps_madd tmp6, tmp3, tmp7, tmp1 - ps_nmsub tmp7, tmp3, tmp7, tmp1 - addi q, q, 8*sizeof(f32) - ps_add tmp0, tmp4, tmp6 - ps_sub tmp3, tmp4, tmp6 - ps_msub tmp2, tmp7, cc4, tmp6 - lwz itmp0, 12(in) - ps_sub tmp8, tmp7, tmp5 - ps_add tmp1, tmp5, tmp2 - ps_sub tmp2, tmp5, tmp2 - ps_mul tmp8, tmp8, cc2 - lwz itmp3, 8(in) - ps_merge00 tmp1, tmp0, tmp1 - ps_nmsub tmp6, tmp5, cc2c6a, tmp8 - ps_msub tmp4, tmp7, cc2c6s, tmp8 - lwz itmp1, 4(in) - ps_sub tmp6, tmp6, tmp0 - ps_merge00 tmp2, tmp2, tmp3 - lhz itmp2, 2(in) - ps_madd tmp5, tmp3, cc4, tmp6 - ps_merge11 tmp7, tmp0, tmp6 - psq_l tmp10, 0(in), 0, 5 - ps_sub tmp4, tmp4, tmp5 - ps_add tmp3, tmp1, tmp7 - psq_l tmp11, 0(q), 0, 0 - ps_merge11 tmp4, tmp5, tmp4 - ps_sub tmp0, tmp1, tmp7 - ps_mul tmp10, tmp10, tmp11 - ps_add tmp5, tmp2, tmp4 - ps_sub tmp6, tmp2, tmp4 - ps_merge10 tmp5, tmp5, tmp5 - psq_stu tmp3, 8(ws), 0, 0 - ps_merge10 tmp0, tmp0, tmp0 - psq_stu tmp6, 8(ws), 0, 0 - psq_stu tmp5, 8(ws), 0, 0 - or itmp0, itmp0, itmp3 - psq_stu tmp0, 8(ws), 0, 0 - bdnz _loopHead1 - - _loopEnd: - - } - } - - ws = &__THPIDCTWorkspace[0]; - - { - register THPSample *obase = Gbase; - register u32 wid = Gwid; - - register u32 itmp0, off0, off1; - register THPSample *out0, *out1; - - asm { - psq_l tmp10, 8*0*sizeof(f32)(ws), 0, 0 - slwi off0, wid, 3; - psq_l tmp11, 8*4*sizeof(f32)(ws), 0, 0 - slwi xPos, xPos, 2 - psq_l tmp12, 8*2*sizeof(f32)(ws), 0, 0 - slwi off1, wid, 2 - ps_add tmp6, tmp10, tmp11 - add off0, off0, xPos - psq_l tmp13, 8*6*sizeof(f32)(ws), 0, 0 - ps_sub tmp8, tmp10, tmp11 - add off1, off0, off1 - ps_add tmp6, tmp6, bias - li itmp0, 3 - ps_add tmp7, tmp12, tmp13 - add out0, obase, off0 - ps_sub tmp9, tmp12, tmp13 - ps_add tmp0, tmp6, tmp7 - add out1, obase, off1 - ps_add tmp8, tmp8, bias - mtctr itmp0 - - _loopHead10: - psq_l tmp4, 8*1*sizeof(f32)(ws), 0, 0 - ps_msub tmp9, tmp9, cc4, tmp7 - psq_l tmp5, 8*3*sizeof(f32)(ws), 0, 0 - ps_sub tmp3, tmp6, tmp7 - ps_add tmp1, tmp8, tmp9 - psq_l tmp6, 8*5*sizeof(f32)(ws), 0, 0 - ps_sub tmp2, tmp8, tmp9 - psq_l tmp7, 8*7*sizeof(f32)(ws), 0, 0 - ps_add tmp8, tmp6, tmp5 - ps_sub tmp6, tmp6, tmp5 - addi ws, ws, 2*sizeof(f32) - ps_add tmp9, tmp4, tmp7 - ps_sub tmp4, tmp4, tmp7 - psq_l tmp10, 8*0*sizeof(f32)(ws), 0, 0 - ps_add tmp7, tmp9, tmp8 - ps_sub tmp5, tmp9, tmp8 - ps_add tmp8, tmp6, tmp4 - psq_l tmp11, 8*4*sizeof(f32)(ws), 0, 0 - ps_add tmp9, tmp0, tmp7 - ps_mul tmp8, tmp8, cc2 - psq_l tmp12, 8*2*sizeof(f32)(ws), 0, 0 - ps_sub tmp23, tmp0, tmp7 - ps_madd tmp6, tmp6, cc2c6a, tmp8 - psq_l tmp13, 8*6*sizeof(f32)(ws), 0, 0 - ps_sub tmp6, tmp6, tmp7 - addi off0, off0, 2*sizeof(THPSample) - psq_st tmp9, 0(out0), 0, 6 - ps_msub tmp4, tmp4, cc2c6s, tmp8 - ps_add tmp9, tmp1, tmp6 - ps_msub tmp5, tmp5, cc4, tmp6 - ps_sub tmp22, tmp1, tmp6 - psq_st tmp9, 8(out0), 0, 6 - ps_add tmp8, tmp2, tmp5 - ps_add tmp4, tmp4, tmp5 - psq_st tmp8, 16(out0), 0, 6 - addi off1, off1, 2*sizeof(THPSample) - ps_sub tmp9, tmp3, tmp4 - ps_add tmp20, tmp3, tmp4 - psq_st tmp9, 24(out0), 0, 6 - ps_sub tmp21, tmp2, tmp5 - ps_add tmp6, tmp10, tmp11 - psq_st tmp20, 0(out1), 0, 6 - ps_sub tmp8, tmp10, tmp11 - ps_add tmp6, tmp6, bias - psq_st tmp21, 8(out1), 0, 6 - ps_add tmp7, tmp12, tmp13 - ps_sub tmp9, tmp12, tmp13 - psq_st tmp22, 16(out1), 0, 6 - add out0, obase, off0 - ps_add tmp0, tmp6, tmp7 - psq_st tmp23, 24(out1), 0, 6 - ps_add tmp8, tmp8, bias - add out1, obase, off1 - - bdnz _loopHead10 - psq_l tmp4, 8*1*sizeof(f32)(ws), 0, 0 - ps_msub tmp9, tmp9, cc4, tmp7 - psq_l tmp5, 8*3*sizeof(f32)(ws), 0, 0 - ps_sub tmp3, tmp6, tmp7 - ps_add tmp1, tmp8, tmp9 - psq_l tmp6, 8*5*sizeof(f32)(ws), 0, 0 - ps_sub tmp2, tmp8, tmp9 - psq_l tmp7, 8*7*sizeof(f32)(ws), 0, 0 - ps_add tmp8, tmp6, tmp5 - ps_sub tmp6, tmp6, tmp5 - ps_add tmp9, tmp4, tmp7 - ps_sub tmp4, tmp4, tmp7 - ps_add tmp7, tmp9, tmp8 - ps_sub tmp5, tmp9, tmp8 - ps_add tmp8, tmp6, tmp4 - ps_add tmp9, tmp0, tmp7 - ps_mul tmp8, tmp8, cc2 - ps_sub tmp23, tmp0, tmp7 - ps_madd tmp6, tmp6, cc2c6a, tmp8 - psq_st tmp9, 0(out0), 0, 6 - ps_sub tmp6, tmp6, tmp7 - ps_msub tmp4, tmp4, cc2c6s, tmp8 - psq_st tmp23, 24(out1), 0, 6 - ps_add tmp9, tmp1, tmp6 - ps_msub tmp5, tmp5, cc4, tmp6 - ps_sub tmp22, tmp1, tmp6 - psq_st tmp9, 8(out0), 0, 6 - ps_add tmp8, tmp2, tmp5 - ps_add tmp4, tmp4, tmp5 - psq_st tmp8, 16(out0), 0, 6 - ps_sub tmp9, tmp3, tmp4 - psq_st tmp22, 16(out1), 0, 6 - ps_add tmp20, tmp3, tmp4 - psq_st tmp9, 24(out0), 0, 6 - ps_sub tmp21, tmp2, tmp5 - psq_st tmp20, 0(out1), 0, 6 - psq_st tmp21, 8(out1), 0, 6 - - } - } -} - -void __THPDecompressiMCURow512x448(void) -{ - u8 cl_num; - u32 x_pos; - THPComponent *comp; - - LCQueueWait(3); - - for (cl_num = 0; cl_num < __THPInfo->MCUsPerRow; cl_num++) - { - __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[0]); - __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[1]); - __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[2]); - __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[3]); - __THPHuffDecodeDCTCompU(__THPInfo, __THPMCUBuffer[4]); - __THPHuffDecodeDCTCompV(__THPInfo, __THPMCUBuffer[5]); - - comp = &__THPInfo->components[0]; - Gbase = __THPLCWork512[0]; - Gwid = 512; - Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; - x_pos = (u32)(cl_num * 16); - __THPInverseDCTNoYPos(__THPMCUBuffer[0], x_pos); - __THPInverseDCTNoYPos(__THPMCUBuffer[1], x_pos + 8); - __THPInverseDCTY8(__THPMCUBuffer[2], x_pos); - __THPInverseDCTY8(__THPMCUBuffer[3], x_pos + 8); - - comp = &__THPInfo->components[1]; - Gbase = __THPLCWork512[1]; - Gwid = 256; - Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; - x_pos /= 2; - __THPInverseDCTNoYPos(__THPMCUBuffer[4], x_pos); - comp = &__THPInfo->components[2]; - Gbase = __THPLCWork512[2]; - Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; - __THPInverseDCTNoYPos(__THPMCUBuffer[5], x_pos); - - if (__THPInfo->RST != 0) - { - if ((--__THPInfo->currMCU) == 0) - { - __THPInfo->currMCU = __THPInfo->nMCU; - __THPInfo->cnt = 1 + ((__THPInfo->cnt + 6) & 0xFFFFFFF8); - - if (__THPInfo->cnt > 33) - { - __THPInfo->cnt = 33; - } - - __THPInfo->components[0].predDC = 0; - __THPInfo->components[1].predDC = 0; - __THPInfo->components[2].predDC = 0; - } - } - } - - LCStoreData(__THPInfo->dLC[0], __THPLCWork512[0], 0x2000); - LCStoreData(__THPInfo->dLC[1], __THPLCWork512[1], 0x800); - LCStoreData(__THPInfo->dLC[2], __THPLCWork512[2], 0x800); - - __THPInfo->dLC[0] += 0x2000; - __THPInfo->dLC[1] += 0x800; - __THPInfo->dLC[2] += 0x800; -} - -inline s32 __THPHuffDecodeTab(register THPFileInfo *info, register THPHuffmanTab *h) -{ - register s32 code; - register u32 cnt; - register s32 cb; - register u32 increment; - register s32 tmp; - -#define cnt4 code - asm - { - lwz cnt, info->cnt; - addi increment, h, 32; - lwz cb, info->currByte; - addi cnt4, cnt, 4; - cmpwi cnt, 28; - rlwnm tmp, cb, cnt4, 27, 31; - bgt _notEnoughBits; - lbzx code, h, tmp; - lbzx increment, increment, tmp; - cmpwi code, 0xFF; - beq _FailedCheckEnoughBits; - add cnt, cnt, increment; - stw cnt, info->cnt; - } -_done: - return code; - - { - register u32 maxcodebase; - register u32 tmp2; - - _FailedCheckEnoughBits: - maxcodebase = (u32) & (h->maxCode); - cnt += 5; - - asm { - li tmp2, sizeof(s32)*(5); - li code, 5; - add maxcodebase, maxcodebase, tmp2; - __WHILE_START: - cmpwi cnt, 33; - slwi tmp, tmp, 1 - - beq _FCEB_faster; - rlwnm increment, cb, cnt, 31, 31; - lwzu tmp2, 4(maxcodebase); - or tmp, tmp, increment - addi cnt, cnt, 1; - b __WHILE_CHECK; - - _FCEB_faster: - lwz increment, info->c; - li cnt, 1; - lwzu cb, 4(increment); - lwzu tmp2, 4(maxcodebase); - - stw increment, info->c; - rlwimi tmp, cb, 1,31,31; - stw cb, info->currByte; - b __FL_WHILE_CHECK; - - __FL_WHILE_START: - slwi tmp, tmp, 1; - rlwnm increment, cb, cnt, 31, 31; - lwzu tmp2, 4(maxcodebase); - or tmp, tmp, increment; - - __FL_WHILE_CHECK: - cmpw tmp,tmp2 - addi cnt, cnt, 1; - addi code, code, 1 - bgt __FL_WHILE_START; - b _FCEB_Done; - - __WHILE_CHECK: - cmpw tmp,tmp2 - addi code, code, 1 - bgt __WHILE_START; - } - } -_FCEB_Done: - info->cnt = cnt; - return (h->Vij[(s32)(tmp + h->valPtr[code])]); - - asm - { // 6684 - _notEnoughBits: - cmpwi cnt, 33; - lwz tmp, info->c; - beq _getfullword; - - cmpwi cnt, 32; - rlwnm code, cb, cnt4, 27, 31 - beq _1bitleft; - - lbzx tmp, h, code; - lbzx increment, increment, code; - cmpwi tmp, 0xFF; - add code, cnt, increment; - beq _FailedCheckNoBits0; - - cmpwi code, 33; - stw code, info->cnt; - bgt _FailedCheckNoBits1; - } - return tmp; - - asm - { - _1bitleft: - lwzu cb, 4(tmp); - - stw tmp, info->c; - rlwimi code, cb, 4, 28, 31; - lbzx tmp, h, code; - lbzx increment, increment, code - stw cb, info->currByte; - cmpwi tmp, 0xFF - stw increment, info->cnt; - beq _DammitRead4; - - } - return tmp; - -_DammitRead4: -{ - register u32 maxcodebase = (u32) & (h->maxCode); - register u32 tmp2; - - asm - { - li cnt, sizeof(s32)*5; - add maxcodebase, maxcodebase, cnt; - - slwi tmp, code, 32-5; - li cnt,5; - rlwimi tmp, cb, 32-1, 1,31; - - __DR4_WHILE_START: - - subfic cb, cnt, 31; - lwzu tmp2, 4(maxcodebase); - srw code, tmp, cb; - __DR4_WHILE_CHECK: - cmpw code, tmp2 - addi cnt, cnt, 1 - bgt __DR4_WHILE_START; - - } -} - - info->cnt = cnt; -__CODE_PLUS_VP_CNT: - return (h->Vij[(s32)(code + h->valPtr[cnt])]); - -_getfullword: - asm - { - lwzu cb, 4(tmp); - - rlwinm code, cb, 5, 27, 31 - stw tmp, info->c; - lbzx cnt, h, code; - lbzx increment, increment, code; - cmpwi cnt, 0xFF - stw cb, info->currByte; - addi increment, increment, 1 - beq _FailedCheckEnoughbits_Updated; - - stw increment, info->cnt; - } - return (s32)cnt; - -_FailedCheckEnoughbits_Updated: - - cnt = 5; - do - { - asm - { - subfic tmp, cnt, 31; - addi cnt, cnt, 1; - srw code, cb, tmp; - } - } while (code > h->maxCode[cnt]); - - info->cnt = cnt + 1; - goto __CODE_PLUS_VP_CNT; - -#undef cnt4 - -_FailedCheckNoBits0: -_FailedCheckNoBits1: - -{ - register u32 mask = 0xFFFFFFFF << (33 - cnt); - register u32 tmp2; - - code = (s32)(cb & (~mask)); - mask = (u32) & (h->maxCode); - - asm - { - lwz tmp, info->c; - subfic tmp2, cnt, 33; - addi cnt, tmp2, 1; - slwi tmp2, tmp2, 2; - lwzu cb, 4(tmp); - add mask,mask, tmp2; - stw tmp, info->c; - slwi code, code, 1; - stw cb, info->currByte; - rlwimi code, cb, 1, 31, 31; - lwzu tmp2, 4(mask); - li tmp, 2; - b __FCNB1_WHILE_CHECK; - - __FCNB1_WHILE_START: - slwi code, code, 1; - - addi cnt, cnt, 1; - lwzu tmp2, 4(mask); - add code, code, increment; - addi tmp, tmp, 1; - - __FCNB1_WHILE_CHECK: - cmpw code, tmp2; - rlwnm increment, cb, tmp, 31, 31; - bgt __FCNB1_WHILE_START; - - } -} - - info->cnt = (u32)tmp; - return (h->Vij[(s32)(code + h->valPtr[cnt])]); -} - -void __THPDecompressiMCURow640x480(void) -{ - u8 cl_num; - u32 x_pos; - THPComponent *comp; - - LCQueueWait(3); - - { - for (cl_num = 0; cl_num < __THPInfo->MCUsPerRow; cl_num++) - { - THPFileInfo *um = __THPInfo; - __THPHuffDecodeDCTCompY(um, __THPMCUBuffer[0]); - __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[1]); - __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[2]); - __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[3]); - __THPHuffDecodeDCTCompU(__THPInfo, __THPMCUBuffer[4]); - __THPHuffDecodeDCTCompV(__THPInfo, __THPMCUBuffer[5]); - - comp = &__THPInfo->components[0]; - Gbase = __THPLCWork672[0]; - Gwid = 640; - Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; - x_pos = (u32)(cl_num * 16); - __THPInverseDCTNoYPos(__THPMCUBuffer[0], x_pos); - __THPInverseDCTNoYPos(__THPMCUBuffer[1], x_pos + 8); - __THPInverseDCTY8(__THPMCUBuffer[2], x_pos); - __THPInverseDCTY8(__THPMCUBuffer[3], x_pos + 8); - - comp = &__THPInfo->components[1]; - Gbase = __THPLCWork672[1]; - Gwid = 320; - Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; - x_pos /= 2; - __THPInverseDCTNoYPos(__THPMCUBuffer[4], x_pos); - - comp = &__THPInfo->components[2]; - Gbase = __THPLCWork672[2]; - Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; - __THPInverseDCTNoYPos(__THPMCUBuffer[5], x_pos); - - if (__THPInfo->RST != 0) - { - __THPInfo->currMCU--; - if (__THPInfo->currMCU == 0) - { - __THPInfo->currMCU = __THPInfo->nMCU; - - __THPInfo->cnt = 1 + ((__THPInfo->cnt + 6) & 0xFFFFFFF8); - - if (__THPInfo->cnt > 32) - { - __THPInfo->cnt = 33; - } - - __THPInfo->components[0].predDC = 0; - __THPInfo->components[1].predDC = 0; - __THPInfo->components[2].predDC = 0; - } - } - } - } - - LCStoreData(__THPInfo->dLC[0], __THPLCWork672[0], 0x2800); - LCStoreData(__THPInfo->dLC[1], __THPLCWork672[1], 0xA00); - LCStoreData(__THPInfo->dLC[2], __THPLCWork672[2], 0xA00); - - __THPInfo->dLC[0] += 0x2800; - __THPInfo->dLC[1] += 0xA00; - __THPInfo->dLC[2] += 0xA00; -} - -void __THPDecompressiMCURowNxN(void) -{ - u8 cl_num; - u32 x_pos, x; - THPComponent *comp; - - x = __THPInfo->xPixelSize; - - LCQueueWait(3); - - for (cl_num = 0; cl_num < __THPInfo->MCUsPerRow; cl_num++) - { - __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[0]); - __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[1]); - __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[2]); - __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[3]); - __THPHuffDecodeDCTCompU(__THPInfo, __THPMCUBuffer[4]); - __THPHuffDecodeDCTCompV(__THPInfo, __THPMCUBuffer[5]); - - comp = &__THPInfo->components[0]; - Gbase = __THPLCWork672[0]; - Gwid = x; - Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; - x_pos = (u32)(cl_num * 16); - __THPInverseDCTNoYPos(__THPMCUBuffer[0], x_pos); - __THPInverseDCTNoYPos(__THPMCUBuffer[1], x_pos + 8); - __THPInverseDCTY8(__THPMCUBuffer[2], x_pos); - __THPInverseDCTY8(__THPMCUBuffer[3], x_pos + 8); - - comp = &__THPInfo->components[1]; - Gbase = __THPLCWork672[1]; - Gwid = x / 2; - Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; - x_pos /= 2; - __THPInverseDCTNoYPos(__THPMCUBuffer[4], x_pos); - - comp = &__THPInfo->components[2]; - Gbase = __THPLCWork672[2]; - Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; - __THPInverseDCTNoYPos(__THPMCUBuffer[5], x_pos); - - if (__THPInfo->RST != 0) - { - __THPInfo->currMCU--; - if (__THPInfo->currMCU == 0) - { - __THPInfo->currMCU = __THPInfo->nMCU; - __THPInfo->cnt = 1 + ((__THPInfo->cnt + 6) & 0xFFFFFFF8); - - if (__THPInfo->cnt > 32) - { - __THPInfo->cnt = 33; - } - - __THPInfo->components[0].predDC = 0; - __THPInfo->components[1].predDC = 0; - __THPInfo->components[2].predDC = 0; - } - } - } - - LCStoreData(__THPInfo->dLC[0], __THPLCWork672[0], ((4 * sizeof(u8) * 64) * (x / 16))); - LCStoreData(__THPInfo->dLC[1], __THPLCWork672[1], ((sizeof(u8) * 64) * (x / 16))); - LCStoreData(__THPInfo->dLC[2], __THPLCWork672[2], ((sizeof(u8) * 64) * (x / 16))); - __THPInfo->dLC[0] += ((4 * sizeof(u8) * 64) * (x / 16)); - __THPInfo->dLC[1] += ((sizeof(u8) * 64) * (x / 16)); - __THPInfo->dLC[2] += ((sizeof(u8) * 64) * (x / 16)); -} - -void __THPHuffDecodeDCTCompY(register THPFileInfo *info, THPCoeff *block) -{ - { - register s32 t; - THPCoeff dc; - register THPCoeff diff; - - __dcbz((void *)block, 0); - t = __THPHuffDecodeTab(info, Ydchuff); - __dcbz((void *)block, 32); - diff = 0; - __dcbz((void *)block, 64); - - if (t) - { - { - register s32 v; - register u32 cb; - register u32 cnt; - register u32 cnt33; - register u32 tmp; - register u32 cnt1; - register u32 tmp1; - asm { - lwz cnt,info->cnt; - subfic cnt33,cnt,33; - lwz cb,info->currByte; - - subfc. tmp, cnt33, t; - subi cnt1,cnt,1; - - bgt _notEnoughBitsDIFF; - add v,cnt,t; - - slw cnt,cb,cnt1; - stw v,info->cnt; - subfic v,t,32; - srw diff,cnt,v; - } - - asm - { - b _DoneDIFF; - _notEnoughBitsDIFF: - lwz tmp1, info->c; - slw v, cb, cnt1; - lwzu cb, 4(tmp1); - addi tmp, tmp, 1; - stw cb, info->currByte; - srw cb, cb, cnt33; - stw tmp1, info->c; - add v, cb, v; - stw tmp, info->cnt; - subfic tmp, t, 32; - srw diff, v, tmp; - _DoneDIFF: - } - } - - if (__cntlzw((u32)diff) > 32 - t) - { - diff += ((0xFFFFFFFF << t) + 1); - } - }; - - __dcbz((void *)block, 96); - dc = (s16)(info->components[0].predDC + diff); - block[0] = info->components[0].predDC = dc; - } - - { - register s32 k; - register s32 code; - register u32 cnt; - register u32 cb; - register u32 increment; - register s32 tmp; - register THPHuffmanTab *h = Yachuff; - -#define cnt4 code - asm - { - lwz cnt, info->cnt; - addi increment, h, 32; - lwz cb, info->currByte; - } - - for (k = 1; k < 64; k++) - { - register s32 ssss; - register s32 rrrr; - - asm { - addi cnt4, cnt, 4; - cmpwi cnt, 28; - rlwnm tmp, cb, cnt4, 27, 31; - bgt _notEnoughBits; - - lbzx ssss, h, tmp; - lbzx code, increment, tmp; - cmpwi ssss, 0xFF; - - beq _FailedCheckEnoughBits; - add cnt, cnt, code; - b _DoneDecodeTab; - } - - { - register u32 maxcodebase; - register u32 tmp2; - - _FailedCheckEnoughBits: - cnt += 5; - maxcodebase = (u32) & (h->maxCode); - asm { - li tmp2, sizeof(s32)*(5); - li code, 5; - add maxcodebase, maxcodebase, tmp2; - __WHILE_START: - cmpwi cnt, 33; - slwi tmp, tmp, 1 - - beq _FCEB_faster; - rlwnm ssss, cb, cnt, 31, 31; - lwzu tmp2, 4(maxcodebase); - or tmp, tmp, ssss - addi cnt, cnt, 1; - b __WHILE_CHECK; - - _FCEB_faster: - lwz ssss, info->c; - li cnt, 1; - lwzu cb, 4(ssss); - - lwzu tmp2, 4(maxcodebase); - - stw ssss, info->c; - rlwimi tmp, cb, 1,31,31; - b __FL_WHILE_CHECK; - - __FL_WHILE_START: - slwi tmp, tmp, 1; - - rlwnm ssss, cb, cnt, 31, 31; - lwzu tmp2, 4(maxcodebase); - or tmp, tmp, ssss; - - __FL_WHILE_CHECK: - cmpw tmp,tmp2 - addi cnt, cnt, 1; - addi code, code, 1 - bgt __FL_WHILE_START; - b _FCEB_Done; - - __WHILE_CHECK: - cmpw tmp,tmp2 - addi code, code, 1 - bgt __WHILE_START; - } - } - _FCEB_Done: - ssss = (h->Vij[(s32)(tmp + h->valPtr[code])]); - goto _DoneDecodeTab; - - _notEnoughBits: - asm - { - cmpwi cnt, 33; - lwz tmp, info->c; - beq _getfullword; - - cmpwi cnt, 32; - rlwnm code, cb, cnt4, 27, 31 - beq _1bitleft; - - lbzx ssss, h, code; - lbzx rrrr, increment, code; - cmpwi ssss, 0xFF; - add code, cnt, rrrr; - beq _FailedCheckNoBits0; - - cmpwi code, 33; - bgt _FailedCheckNoBits1; - } - cnt = (u32)code; - goto _DoneDecodeTab; - - _getfullword: - { - asm - { - lwzu cb, 4(tmp); - rlwinm code, cb, 5, 27, 31 - stw tmp, info->c; - lbzx ssss, h, code; - lbzx tmp, increment, code; - cmpwi ssss, 0xFF - addi cnt, tmp, 1 - beq _FailedCheckEnoughbits_Updated; - } - } - goto _DoneDecodeTab; - - _FailedCheckEnoughbits_Updated: - ssss = 5; - do - { - asm - { - subfic tmp, ssss, 31; - addi ssss, ssss, 1; - srw code, cb, tmp; - } - } while (code > h->maxCode[ssss]); - - cnt = (u32)(ssss + 1); - ssss = (h->Vij[(s32)(code + h->valPtr[ssss])]); - - goto _DoneDecodeTab; - - _1bitleft: - asm { - lwzu cb, 4(tmp); - - stw tmp, info->c; - rlwimi code, cb, 4, 28, 31; - lbzx ssss, h, code; - lbzx cnt, increment, code - cmpwi ssss, 0xFF - beq _DammitRead4; - - } - - goto _DoneDecodeTab; - - _DammitRead4: - { - register u32 maxcodebase = (u32) & (h->maxCode); - register u32 tmp2; - - asm { - li cnt, sizeof(s32)*5; - add maxcodebase, maxcodebase, cnt; - - slwi tmp, code, 32-5; - li cnt,5; - rlwimi tmp, cb, 32-1, 1,31; - - __DR4_WHILE_START: - - subfic ssss, cnt, 31; - lwzu tmp2, 4(maxcodebase); - srw code, tmp, ssss; - __DR4_WHILE_CHECK: - cmpw code, tmp2 - addi cnt, cnt, 1 - bgt __DR4_WHILE_START; - - } - } - ssss = (h->Vij[(s32)(code + h->valPtr[cnt])]); - goto _DoneDecodeTab; - - _FailedCheckNoBits0: - _FailedCheckNoBits1: - _REALFAILEDCHECKNOBITS: - { - register u32 mask = 0xFFFFFFFF << (33 - cnt); - register u32 tmp2; - register u32 tmp3; - code = (s32)(cb & (~mask)); - mask = (u32) & (h->maxCode); - - asm { - lwz tmp, info->c; - subfic tmp2, cnt, 33; - addi tmp3, tmp2, 1; - slwi tmp2, tmp2, 2; - lwzu cb, 4(tmp); - add mask,mask, tmp2; - stw tmp, info->c; - slwi code, code, 1; - rlwimi code, cb, 1, 31, 31; - lwzu tmp2, 4(mask); - li cnt, 2; - b __FCNB1_WHILE_CHECK; - - __FCNB1_WHILE_START: - slwi code, code, 1; - - addi tmp3, tmp3, 1; - lwzu tmp2, 4(mask); - add code, code, rrrr; - addi cnt, cnt, 1; - - __FCNB1_WHILE_CHECK: - cmpw code, tmp2; - rlwnm rrrr, cb, cnt, 31, 31; - bgt __FCNB1_WHILE_START; - - } - ssss = (h->Vij[(s32)(code + h->valPtr[tmp3])]); - } - - goto _DoneDecodeTab; - - _DoneDecodeTab: - asm { - andi. rrrr, ssss, 15; - srawi ssss, ssss, 4; - beq _RECV_SSSS_ZERO; - } - - { - k += ssss; - { - register s32 v; -#define cnt33 code - register u32 cnt1; - register u32 tmp1; - asm - { - subfic cnt33,cnt,33; - subfc. tmp, cnt33, rrrr; - subi cnt1,cnt,1; - bgt _RECVnotEnoughBits; - add cnt,cnt,rrrr; - slw tmp1,cb,cnt1; - subfic v,rrrr,32; - srw ssss,tmp1,v; - } - asm - { - b _RECVDone; - _RECVnotEnoughBits: - lwz tmp1, info->c; - slw v, cb, cnt1; - lwzu cb, 4(tmp1); - addi cnt, tmp, 1; - stw tmp1, info->c; - srw tmp1, cb, cnt33; - - add v, tmp1, v; - subfic tmp, rrrr, 32; - srw ssss, v, tmp; - _RECVDone: - } - } - -#undef cnt33 - - if (__cntlzw((u32)ssss) > 32 - rrrr) - { - ssss += ((0xFFFFFFFF << rrrr) + 1); - } - - block[__THPJpegNaturalOrder[k]] = (s16)ssss; - goto _RECV_END; - } - - { - _RECV_SSSS_ZERO: - if (ssss != 15) - { - break; - } - - k += 15; - }; - - asm - { - _RECV_END: - } - } - info->cnt = cnt; - info->currByte = cb; - } -#undef cnt4 -} - -void __THPHuffDecodeDCTCompU(register THPFileInfo *info, THPCoeff *block) -{ - register s32 t; - register THPCoeff diff; - THPCoeff dc; - register s32 v; - register u32 cb; - register u32 cnt; - register u32 cnt33; - register u32 tmp; - register u32 cnt1; - register u32 tmp1; - register s32 k; - register s32 ssss; - register s32 rrrr; - - __dcbz((void *)block, 0); - t = __THPHuffDecodeTab(info, Udchuff); - __dcbz((void *)block, 32); - diff = 0; - __dcbz((void *)block, 64); - - if (t) - { - asm - { - lwz cnt,info->cnt; - subfic cnt33,cnt,33; - lwz cb,info->currByte; - subfc. tmp, cnt33, t; - subi cnt1,cnt,1; - bgt _notEnoughBitsDIFF; - add v,cnt,t; - slw cnt,cb,cnt1; - stw v,info->cnt; - subfic v,t,32; - srw diff,cnt,v; - } - - asm - { - b _DoneDIFF; - _notEnoughBitsDIFF: - lwz tmp1, info->c; - slw v, cb, cnt1; - lwzu cb, 4(tmp1); - addi tmp, tmp, 1; - stw cb, info->currByte; - srw cb, cb, cnt33; - stw tmp1, info->c; - add v, cb, v; - stw tmp, info->cnt; - subfic tmp, t, 32; - srw diff, v, tmp; - _DoneDIFF: - } - - if (__cntlzw((u32)diff) > 32 - t) - { - diff += ((0xFFFFFFFF << t) + 1); - } - } - - __dcbz((void *)block, 96); - dc = (s16)(info->components[1].predDC + diff); - block[0] = info->components[1].predDC = dc; - - for (k = 1; k < 64; k++) - { - ssss = __THPHuffDecodeTab(info, Uachuff); - rrrr = ssss >> 4; - ssss &= 15; - - if (ssss) - { - k += rrrr; - asm - { - lwz cnt,info->cnt; - subfic cnt33,cnt,33; - lwz cb,info->currByte; - subf. tmp, cnt33, ssss; - subi cnt1,cnt,1; - bgt _notEnoughBits; - add v,cnt,ssss; - slw cnt,cb,cnt1; - stw v,info->cnt; - subfic v,ssss,32; - srw rrrr,cnt,v; - } - - asm - { - b _Done; - _notEnoughBits: - lwz tmp1, info->c; - slw v, cb, cnt1; - lwzu cb, 4(tmp1); - addi tmp, tmp, 1; - stw cb, info->currByte; - srw cb, cb, cnt33; - stw tmp1, info->c; - add v, cb, v; - stw tmp, info->cnt; - subfic tmp, ssss, 32; - srw rrrr, v, tmp; - _Done: - } - - if (__cntlzw((u32)rrrr) > 32 - ssss) - { - rrrr += ((0xFFFFFFFF << ssss) + 1); - } - - block[__THPJpegNaturalOrder[k]] = (s16)rrrr; - } - - else - { - if (rrrr != 15) - break; - k += 15; - } - } -} - -void __THPHuffDecodeDCTCompV(register THPFileInfo *info, THPCoeff *block) -{ - register s32 t; - register THPCoeff diff; - THPCoeff dc; - register s32 v; - register u32 cb; - register u32 cnt; - register u32 cnt33; - register u32 tmp; - register u32 cnt1; - register u32 tmp1; - register s32 k; - register s32 ssss; - register s32 rrrr; - - __dcbz((void *)block, 0); - t = __THPHuffDecodeTab(info, Vdchuff); - __dcbz((void *)block, 32); - diff = 0; - __dcbz((void *)block, 64); - - if (t) - { - asm - { - lwz cnt,info->cnt; - subfic cnt33,cnt,33; - lwz cb,info->currByte; - subf. tmp, cnt33, t; - subi cnt1,cnt,1; - bgt _notEnoughBitsDIFF; - add v,cnt,t; - slw cnt,cb,cnt1; - stw v,info->cnt; - subfic v,t,32; - srw diff,cnt,v; - } - - asm - { - b _DoneDIFF; - _notEnoughBitsDIFF: - lwz tmp1, info->c; - slw v, cb, cnt1; - lwzu cb, 4(tmp1); - addi tmp, tmp, 1; - stw cb, info->currByte; - srw cb, cb, cnt33; - stw tmp1, info->c; - add v, cb, v; - stw tmp, info->cnt; - subfic tmp, t, 32; - srw diff, v, tmp; - _DoneDIFF: - } - - if (__cntlzw((u32)diff) > 32 - t) - { - diff += ((0xFFFFFFFF << t) + 1); - } - } - - __dcbz((void *)block, 96); - - dc = (s16)(info->components[2].predDC + diff); - block[0] = info->components[2].predDC = dc; - - for (k = 1; k < 64; k++) - { - ssss = __THPHuffDecodeTab(info, Vachuff); - rrrr = ssss >> 4; - ssss &= 15; - - if (ssss) - { - k += rrrr; - - asm - { - lwz cnt,info->cnt; - subfic cnt33,cnt,33; - lwz cb,info->currByte; - - subf. tmp, cnt33, ssss; - subi cnt1,cnt,1; - - bgt _notEnoughBits; - add v,cnt,ssss; - - slw cnt,cb,cnt1; - stw v,info->cnt; - subfic v,ssss,32; - srw rrrr,cnt,v; - } - - asm - { - b _Done; - _notEnoughBits: - lwz tmp1, info->c; - slw v, cb, cnt1; - lwzu cb, 4(tmp1); - addi tmp, tmp, 1; - stw cb, info->currByte; - srw cb, cb, cnt33; - stw tmp1, info->c; - add v, cb, v; - stw tmp, info->cnt; - subfic tmp, ssss, 32; - srw rrrr, v, tmp; - _Done: - } - - if (__cntlzw((u32)rrrr) > 32 - ssss) - { - rrrr += ((0xFFFFFFFF << ssss) + 1); - } - - block[__THPJpegNaturalOrder[k]] = (s16)rrrr; - } - else - { - if (rrrr != 15) - break; - k += 15; - } - } -} - -BOOL THPInit(void) -{ - u8 *base; - OSRegisterVersion(__THPVersion); - base = (u8 *)(0xE000 << 16); // lc base - - __THPLCWork512[0] = base; - base += 0x2000; - __THPLCWork512[1] = base; - base += 0x800; - __THPLCWork512[2] = base; - base += 0x200; - - base = (u8 *)(0xE000 << 16); // lc base - __THPLCWork672[0] = base; - base += 0x2800; - __THPLCWork672[1] = base; - base += 0xA00; - __THPLCWork672[2] = base; - base += 0xA80; - - OSInitFastCast(); - - __THPInitFlag = TRUE; - return TRUE; -} \ No newline at end of file diff --git a/src/SB/Core/x/xCollide.cpp b/src/SB/Core/x/xCollide.cpp index 00f77dcf3..70f0b0265 100644 --- a/src/SB/Core/x/xCollide.cpp +++ b/src/SB/Core/x/xCollide.cpp @@ -5,7 +5,7 @@ #include "rpcollis.h" #include "xMathInlines.h" -#include +#include #include S32 sSweptSphereHitFound; @@ -274,8 +274,6 @@ S32 xParabolaHitsEnv(xParabola*, const xEnv*, xCollis*) return false; } - - U32 xBoxHitsObb(const xBox*, const xBox*, const xMat4x3*, xCollis*) { return 0; @@ -293,13 +291,10 @@ xVec3 xCollisTriHit(const xCollis::tri_data&, const xModelInstance&) struct RpCollBSPTree; struct RpV3dGradient; -RpCollBSPTree* _rpCollBSPTreeForAllCapsuleLeafNodeIntersections( - RpCollBSPTree* tree, - RwLine* line, - F32 radius, - RpV3dGradient* grad, - S32 (* callBack)(S32, S32, void*), - void* data) +RpCollBSPTree* _rpCollBSPTreeForAllCapsuleLeafNodeIntersections(RpCollBSPTree* tree, RwLine* line, + F32 radius, RpV3dGradient* grad, + S32 (*callBack)(S32, S32, void*), + void* data) { return NULL; } @@ -344,9 +339,9 @@ S32 xSweptSphereToBox(xSweptSphere*, xBox*, xMat4x3*) return 0; } -RpCollisionTriangle* SweptSphereHitsEnvCB( - RpIntersection* intersection, RpWorldSector* sector, RpCollisionTriangle* collTriangle, - RwReal distance, void* data) +RpCollisionTriangle* SweptSphereHitsEnvCB(RpIntersection* intersection, RpWorldSector* sector, + RpCollisionTriangle* collTriangle, RwReal distance, + void* data) { return NULL; } @@ -397,14 +392,9 @@ S32 xSweptSphereToEnv(xSweptSphere* sphere, xEnv* env) gradient.dxdz = delx * zfactor; gradient.dydz = dely * zfactor; - xClumpColl_ForAllCapsuleLeafNodeIntersections( - env->geom->jsp->colltree, - &line, - sphere->radius, - &gradient, - SweptSphereLeafNodeCB, - sphere - ); + xClumpColl_ForAllCapsuleLeafNodeIntersections(env->geom->jsp->colltree, &line, + sphere->radius, &gradient, + SweptSphereLeafNodeCB, sphere); } else { @@ -414,8 +404,8 @@ S32 xSweptSphereToEnv(xSweptSphere* sphere, xEnv* env) // some struct with RwV3ds in it instead of an xBox. intersect.t.box.sup = *(RwV3d*)(&sphere->box.upper); intersect.t.box.inf = *(RwV3d*)(&sphere->box.lower); - RpCollisionWorldForAllIntersections(env->geom->world, &intersect, - SweptSphereHitsEnvCB, sphere); + RpCollisionWorldForAllIntersections(env->geom->world, &intersect, SweptSphereHitsEnvCB, + sphere); } return sSweptSphereHitFound; } @@ -491,7 +481,7 @@ F32 xVec3Dist(const xVec3* a, const xVec3* b) return xsqrt(dx * dx + dy * dy + dz * dz); } -void xMat4x3OrthoInv(xMat4x3* a,const xMat4x3* b) +void xMat4x3OrthoInv(xMat4x3* a, const xMat4x3* b) { xVec3 vec; xMat3x3Transpose(a, b); diff --git a/src/SB/Game/zEntPlayerBungeeState.cpp b/src/SB/Game/zEntPlayerBungeeState.cpp index 1973a95bb..d5ba45371 100644 --- a/src/SB/Game/zEntPlayerBungeeState.cpp +++ b/src/SB/Game/zEntPlayerBungeeState.cpp @@ -23,6 +23,7 @@ #include "zEntPlayer.h" #include "zGameExtras.h" #include "zGlobals.h" +#include "zCameraTweak.h" #include "zLightning.h" #include "zScene.h" From d0d1d14185c098a110c97247cc2eb34aed2954da Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Sat, 24 May 2025 20:41:35 -0400 Subject: [PATCH 09/19] temp fix for ok bot --- configure.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.py b/configure.py index 442cb5405..7c7e31f9a 100644 --- a/configure.py +++ b/configure.py @@ -889,9 +889,9 @@ def MatchingFor(*versions): Object(NonMatching, "debugger/embedded/MetroTRK/Portable/mem_TRK.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/string_TRK.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s"), + #Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s"), Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s"), + #Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s"), Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/usr_put.c"), From 9157ffb0371516529fe631082a26339485fc3f03 Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Sat, 24 May 2025 20:51:15 -0400 Subject: [PATCH 10/19] Seperated bink from the dolphin SDK --- configure.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.py b/configure.py index 7c7e31f9a..24cdc9958 100644 --- a/configure.py +++ b/configure.py @@ -574,7 +574,7 @@ def MatchingFor(*versions): "lib": "binkngc", "mw_version": "GC/1.3.2", "cflags": cflags_runtime, - "progress_category": "sdk", + "progress_category": "bink", "objects": [ Object(NonMatching, "bink/src/sdk/decode/ngc/binkngc.c"), Object(NonMatching, "bink/src/sdk/decode/ngc/ngcsnd.c"), @@ -1117,6 +1117,7 @@ def link_order_callback(module_id: int, objects: List[str]) -> List[str]: ProgressCategory("sdk", "SDK Code"), ProgressCategory("msl", "MSL"), ProgressCategory("RW", "Renderware SDK"), + ProgressCategory("bink", "Bink SDK"), ] config.progress_each_module = args.verbose From 87115f7db29df2d52a5708ec015edf0163e1fdb2 Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Sat, 24 May 2025 21:52:17 -0400 Subject: [PATCH 11/19] Fixed the commented code --- src/SB/Core/gc/ngcrad3d.c | 89 --------------------------------------- 1 file changed, 89 deletions(-) diff --git a/src/SB/Core/gc/ngcrad3d.c b/src/SB/Core/gc/ngcrad3d.c index 8742bc781..055b44e81 100644 --- a/src/SB/Core/gc/ngcrad3d.c +++ b/src/SB/Core/gc/ngcrad3d.c @@ -30,40 +30,6 @@ static void Setup_surface_array() Built_tables = 1; } -// HRAD3DIMAGE Open_RAD_3D_image(HBINK param_1, unsigned int param_2, unsigned int param_3, -// unsigned int param_4) -// { -// HRAD3DIMAGE imgDat; -// int pi_p4; - -// Setup_surface_array(); - -// pi_p4 = Pixel_info[param_4] & 0xff; -// imgDat = (HRAD3DIMAGE)iFMVmalloc(0x3c); - -// if (imgDat == 0) -// { -// return 0; -// } - -// imgDat->a = param_2; -// imgDat->b = param_3; -// imgDat->c = Pixel_info[param_4] >> 31; -// imgDat->d = pi_p4; -// imgDat->e = param_4; - -// imgDat->g = GXGetTexBufferSize((unsigned short)param_2, (unsigned short)param_3, -// D3D_surface_type[param_4], 0, 0); -// imgDat->f = (void*)iFMVmalloc(imgDat->g); - -// GXInitTexObj((volatile int)imgDat + 0x1c, imgDat->f, param_2 & 0xffff, param_3 & 0xffff, -// D3D_surface_type[param_4], 0, 0, 0); - -// GXInitTexObjLOD(imgDat, 0.0f, 0.0f, (volatile int)imgDat + 0x1c, 1, 0, 0, 0, 0); - -// return imgDat; -// } - void Close_RAD_3D_image(struct RAD3DIMAGE* image) { if (image != 0) @@ -103,21 +69,6 @@ int Lock_RAD_3D_image(HRAD3DIMAGE rad_image, void* out_pixel_buffer, unsigned in return 1; } -// void Unlock_RAD_3D_image(struct RAD3DIMAGE* image) -// { -// if (image) -// { -// DCStoreRange(image->f, image->g); -// } -// } - -// static void GXTexCoord2f32(float f1, float f2) -// { -// int ptr = 0xcc010000; -// *(float*)((char*)(ptr)-0x8000) = f1; -// *(float*)((char*)(ptr)-0x8000) = f2; -// } - static void GXColor4u8(int r3, int r4, int r5, int r6) { int ptr = 0xcc010000; @@ -134,43 +85,3 @@ static void GXPosition3s16(int r3, int r4, int r5) *(short*)((char*)(ptr)-0x8000) = r4; *(short*)((char*)(ptr)-0x8000) = r5; } - -// static void GXSetTextCoordGen(int a, int b, int c, int d) -// { -// GXSetTexCoordGen2(a, b, c, d, 0, 0x7d); -// } - -// static void Submit_vertices(float param_1, float param_2, float param_3, float param_4, -// long param_5, long param_6, float param_7) -// { -// short uVar1 = (short)(param_7 * 255.0f) & 0xff; -// short iVar3; -// short iVar2; -// short blah = (unsigned short)param_2; - -// GXSetCullMode(0); -// GXSetZMode(1, 7, 1); -// GXSetColorUpdate(1); -// GXBegin(0x80, 0, 4); -// iVar3 = param_1; -// iVar2 = param_6 * param_4 + param_2; - -// GXPosition3s16(iVar3, iVar2, 0); -// GXColor4u8(0xff, 0xff, 0xff, uVar1); -// GXTexCoord2f32(0, 1.0f); - -// GXPosition3s16(iVar3, blah, 0); -// GXColor4u8(0xff, 0xff, 0xff, uVar1); -// GXTexCoord2f32(0, 0); -// iVar3 = param_5 * param_3 + param_1; - -// GXPosition3s16(iVar3, blah, 0); -// GXColor4u8(0xff, 0xff, 0xff, uVar1); -// GXTexCoord2f32(4503601774854144.0, 0); - -// GXPosition3s16(iVar3, iVar2, 0); -// GXColor4u8(0xff, 0xff, 0xff, uVar1); -// GXTexCoord2f32(1.0f, 1.0f); - -// GXEnd(); -// } \ No newline at end of file From 50ab0e354991d801737a6ed72be0721b324f62fb Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Sun, 25 May 2025 23:26:33 -0400 Subject: [PATCH 12/19] Add MSL sdk into project --- config/GQPE78/splits.txt | 2 +- config/GQPE78/symbols.txt | 2 +- configure.py | 33 +- include/dolphin/os/OSInterrupt.h | 28 +- .../MSL_C/MSL_Common/char_io.h | 17 + .../MSL_C/MSL_Common/math_api.h | 35 +- .../PowerPC_EABI_Support/MetroTRK/dstypes.h | 27 + .../PowerPC_EABI_Support/MetroTRK/memmap.h | 15 + .../PowerPC_EABI_Support/MetroTRK/ppc_reg.h | 242 ++ .../PowerPC_EABI_Support/MetroTRK/trk.h | 355 +-- .../PowerPC_EABI_Support/MetroTRK/trkenum.h | 212 ++ .../PowerPC_EABI_Support/MetroTRK/trktypes.h | 144 + .../src/MSL_C/MSL_Common/alloc.c | 538 ++-- .../src/MSL_C/MSL_Common/ansi_files.c | 61 +- .../src/MSL_C/MSL_Common/char_io.c | 115 + .../Math/Double_precision/e_acos.c | 105 + .../Math/Double_precision/w_acos.c | 6 + .../Math/Double_precision/w_log.c | 7 + .../src/MSL_C/PPC_EABI/abort_exit.c | 95 +- .../PPC_EABI/critical_regions.gamecube.c | 17 +- .../src/MSL_C/PPC_EABI/math_ppc.c | 1 - .../src/Runtime/CPlusLibPPC.cp | 18 - libs/PowerPC_EABI_Support/src/Runtime/New.cp | 5 + libs/PowerPC_EABI_Support/src/Runtime/__mem.c | 89 +- .../src/Runtime/global_destructor_chain.c | 32 +- .../src/Runtime/runtime.c | 1309 +++++----- .../src/runtime3/READ_ME.txt | 6 - .../src/runtime3/runtime.c | 920 ------- libs/dolphin/amcstubs/AmcExi2Stubs.c | 30 +- libs/dolphin/ax/AXSPB.c | 2 +- libs/dolphin/card/CARDNet.c | 64 +- libs/dolphin/dsp/dsp.c | 33 + libs/dolphin/dvd/dvderror.c | 2 +- libs/dolphin/dvd/dvdfs.c | 324 +-- libs/dolphin/dvd/dvdlow.c | 36 +- libs/dolphin/eth/base64.c | 70 + libs/dolphin/eth/eth.c | 1031 ++++++++ libs/dolphin/eth/ethsec.c | 344 +++ libs/dolphin/eth/md5.c | 285 ++ libs/dolphin/exi/EXIUart.c | 2 +- libs/dolphin/gd/GDBase.c | 0 libs/dolphin/gd/GDGeometry.c | 0 libs/dolphin/hio/hio.c | 0 libs/dolphin/ip/IFFifo.c | 0 libs/dolphin/ip/IFRing.c | 0 libs/dolphin/ip/IP.c | 0 libs/dolphin/ip/IPArp.c | 0 libs/dolphin/ip/IPChap.c | 0 libs/dolphin/ip/IPDhcp.c | 0 libs/dolphin/ip/IPDns.c | 0 libs/dolphin/ip/IPEther.c | 0 libs/dolphin/ip/IPFrag.c | 0 libs/dolphin/ip/IPIcmp.c | 0 libs/dolphin/ip/IPIgmp.c | 0 libs/dolphin/ip/IPIpcp.c | 0 libs/dolphin/ip/IPLcp.c | 0 libs/dolphin/ip/IPOpt.c | 0 libs/dolphin/ip/IPPPP.c | 0 libs/dolphin/ip/IPPPPoE.c | 0 libs/dolphin/ip/IPPap.c | 0 libs/dolphin/ip/IPRoute.c | 0 libs/dolphin/ip/IPSocket.c | 0 libs/dolphin/ip/IPTcp.c | 0 libs/dolphin/ip/IPTcpOutput.c | 0 libs/dolphin/ip/IPTcpTimeWait.c | 0 libs/dolphin/ip/IPTcpTimer.c | 0 libs/dolphin/ip/IPTcpUser.c | 0 libs/dolphin/ip/IPUdp.c | 0 libs/dolphin/ip/IPUuid.c | 0 libs/dolphin/ip/IPZero.c | 0 libs/dolphin/lg/allsrc.c | 0 libs/dolphin/os/OSError.c | 1 + libs/dolphin/os/OSFont.c | 1 - libs/dolphin/os/__os.h | 133 - libs/dolphin/os/init/__ppc_eabi_init.cpp | 48 +- libs/dolphin/thp/THPAudio.c | 202 ++ libs/dolphin/thp/THPDec.c | 2316 +++++++++++++++++ libs/dolphin/upnp/UPnP.c | 0 libs/dolphin/upnp/UPnPHttp.c | 0 libs/dolphin/upnp/UPnPHttpd.c | 0 libs/dolphin/upnp/UPnPHttpdResponse.c | 0 libs/dolphin/upnp/UPnPSsdp.c | 0 libs/dolphin/upnp/UPnPUri.c | 0 libs/dolphin/upnp/UPnPUuid.c | 0 .../embedded/MetroTRK/Export/mslsupp.c | 65 + .../MetroTRK/Os/dolphin/dolphin_trk.c | 168 ++ .../MetroTRK/Os/dolphin/dolphin_trk_glue.c | 259 ++ .../embedded/MetroTRK/Os/dolphin/targcont.c | 16 + .../MetroTRK/Os/dolphin/target_options.h | 17 + .../embedded/MetroTRK/Os/dolphin/usr_put.c | 140 + .../embedded/MetroTRK/Portable/dispatch.c | 60 + .../embedded/MetroTRK/Portable/main_TRK.c | 20 + .../embedded/MetroTRK/Portable/mainloop.c | 76 + .../embedded/MetroTRK/Portable/mem_TRK.c | 96 + .../debugger/embedded/MetroTRK/Portable/msg.c | 33 + .../embedded/MetroTRK/Portable/msgbuf.c | 536 ++++ .../embedded/MetroTRK/Portable/msghndlr.c | 741 ++++++ .../embedded/MetroTRK/Portable/msghndlr.h | 23 + .../embedded/MetroTRK/Portable/mutex_TRK.c | 16 + .../embedded/MetroTRK/Portable/notify.c | 51 + .../embedded/MetroTRK/Portable/nubevent.c | 106 + .../embedded/MetroTRK/Portable/nubinit.c | 88 + .../embedded/MetroTRK/Portable/serpoll.c | 135 + .../embedded/MetroTRK/Portable/support.c | 174 ++ .../MetroTRK/Processor/ppc/Export/targsupp.h | 19 + .../MetroTRK/Processor/ppc/Export/targsupp.s | 25 + .../Processor/ppc/Generic/__exception.s | 1998 ++++++++++++++ .../Processor/ppc/Generic/flush_cache.c | 31 + .../Processor/ppc/Generic/mpc_7xx_603e.c | 263 ++ .../MetroTRK/Processor/ppc/Generic/targimpl.c | 1494 +++++++++++ 110 files changed, 13284 insertions(+), 2726 deletions(-) create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/char_io.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dstypes.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/memmap.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/ppc_reg.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trkenum.h create mode 100644 libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trktypes.h create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/char_io.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_acos.c create mode 100644 libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log.c create mode 100644 libs/PowerPC_EABI_Support/src/Runtime/New.cp delete mode 100644 libs/PowerPC_EABI_Support/src/runtime3/READ_ME.txt delete mode 100644 libs/PowerPC_EABI_Support/src/runtime3/runtime.c create mode 100644 libs/dolphin/eth/base64.c create mode 100644 libs/dolphin/eth/eth.c create mode 100644 libs/dolphin/eth/ethsec.c create mode 100644 libs/dolphin/eth/md5.c create mode 100644 libs/dolphin/gd/GDBase.c create mode 100644 libs/dolphin/gd/GDGeometry.c create mode 100644 libs/dolphin/hio/hio.c create mode 100644 libs/dolphin/ip/IFFifo.c create mode 100644 libs/dolphin/ip/IFRing.c create mode 100644 libs/dolphin/ip/IP.c create mode 100644 libs/dolphin/ip/IPArp.c create mode 100644 libs/dolphin/ip/IPChap.c create mode 100644 libs/dolphin/ip/IPDhcp.c create mode 100644 libs/dolphin/ip/IPDns.c create mode 100644 libs/dolphin/ip/IPEther.c create mode 100644 libs/dolphin/ip/IPFrag.c create mode 100644 libs/dolphin/ip/IPIcmp.c create mode 100644 libs/dolphin/ip/IPIgmp.c create mode 100644 libs/dolphin/ip/IPIpcp.c create mode 100644 libs/dolphin/ip/IPLcp.c create mode 100644 libs/dolphin/ip/IPOpt.c create mode 100644 libs/dolphin/ip/IPPPP.c create mode 100644 libs/dolphin/ip/IPPPPoE.c create mode 100644 libs/dolphin/ip/IPPap.c create mode 100644 libs/dolphin/ip/IPRoute.c create mode 100644 libs/dolphin/ip/IPSocket.c create mode 100644 libs/dolphin/ip/IPTcp.c create mode 100644 libs/dolphin/ip/IPTcpOutput.c create mode 100644 libs/dolphin/ip/IPTcpTimeWait.c create mode 100644 libs/dolphin/ip/IPTcpTimer.c create mode 100644 libs/dolphin/ip/IPTcpUser.c create mode 100644 libs/dolphin/ip/IPUdp.c create mode 100644 libs/dolphin/ip/IPUuid.c create mode 100644 libs/dolphin/ip/IPZero.c create mode 100644 libs/dolphin/lg/allsrc.c delete mode 100644 libs/dolphin/os/__os.h create mode 100644 libs/dolphin/thp/THPAudio.c create mode 100644 libs/dolphin/thp/THPDec.c create mode 100644 libs/dolphin/upnp/UPnP.c create mode 100644 libs/dolphin/upnp/UPnPHttp.c create mode 100644 libs/dolphin/upnp/UPnPHttpd.c create mode 100644 libs/dolphin/upnp/UPnPHttpdResponse.c create mode 100644 libs/dolphin/upnp/UPnPSsdp.c create mode 100644 libs/dolphin/upnp/UPnPUri.c create mode 100644 libs/dolphin/upnp/UPnPUuid.c create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/target_options.h create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.h create mode 100644 libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.h diff --git a/config/GQPE78/splits.txt b/config/GQPE78/splits.txt index 4f8b6fd67..dd9a38a4a 100644 --- a/config/GQPE78/splits.txt +++ b/config/GQPE78/splits.txt @@ -2904,7 +2904,7 @@ MSL_C/MSL_Common/arith.c: MSL_C/MSL_Common/buffer_io.c: .text start:0x801E1E30 end:0x801E215C -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/char_io.c: +MSL_C/MSL_Common/char_io.c: .text start:0x801E215C end:0x801E25FC MSL_C/PPC_EABI/critical_regions.gamecube.c: diff --git a/config/GQPE78/symbols.txt b/config/GQPE78/symbols.txt index e039ef79f..975586644 100644 --- a/config/GQPE78/symbols.txt +++ b/config/GQPE78/symbols.txt @@ -12698,7 +12698,7 @@ __AXDSPTask = .bss:0x8036BBA0; // type:object size:0x50 scope:local __AXLocalProfile = .bss:0x8036BBF0; // type:object size:0x38 scope:global __AXStudio = .bss:0x8036BC40; // type:object size:0x36 scope:local data:4byte ...bss.0 = .bss:0x8036BC40; // type:label scope:local -__AXPB = .bss:0x8036BC80; // type:object size:0x3D00 scope:local data:2byte +__AXPB = .bss:0x8036BC80; // type:object size:0x3D00 scope:local align:32 data:2byte ...bss.0 = .bss:0x8036BC80; // type:label scope:local __AXITD = .bss:0x8036F980; // type:object size:0x1000 scope:local __AXUpdates = .bss:0x80370980; // type:object size:0x4000 scope:local diff --git a/configure.py b/configure.py index 24cdc9958..582c65c94 100644 --- a/configure.py +++ b/configure.py @@ -620,7 +620,7 @@ def MatchingFor(*versions): Object(Matching, "dolphin/ax/AXAux.c"), Object(NonMatching, "dolphin/ax/AXCL.c"), Object(NonMatching, "dolphin/ax/AXOut.c"), - Object(NonMatching, "dolphin/ax/AXSPB.c"), + Object(Matching, "dolphin/ax/AXSPB.c"), Object(NonMatching, "dolphin/ax/AXVPB.c"), Object(Matching, "dolphin/ax/AXComp.c"), Object(NonMatching, "dolphin/ax/DSPCode.c"), @@ -672,10 +672,10 @@ def MatchingFor(*versions): "dvd", [ Object(NonMatching, "dolphin/dvd/dvdlow.c"), - Object(NonMatching, "dolphin/dvd/dvdfs.c"), + Object(Matching, "dolphin/dvd/dvdfs.c"), Object(NonMatching, "dolphin/dvd/dvd.c"), Object(Matching, "dolphin/dvd/dvdqueue.c"), - Object(NonMatching, "dolphin/dvd/dvderror.c"), + Object(Matching, "dolphin/dvd/dvderror.c"), Object(Matching, "dolphin/dvd/dvdidutils.c"), Object(Matching, "dolphin/dvd/dvdFatal.c"), Object(Matching, "dolphin/dvd/emu_level2/fstload.c"), @@ -685,7 +685,7 @@ def MatchingFor(*versions): "exi", [ Object(NonMatching, "dolphin/exi/EXIBios.c"), - Object(NonMatching, "dolphin/exi/EXIUart.c") + Object(Matching, "dolphin/exi/EXIUart.c") ] ), DolphinLib( @@ -789,9 +789,9 @@ def MatchingFor(*versions): Object(NonMatching, "Runtime/global_destructor_chain.c"), Object(NonMatching, "Runtime/New.cp"), Object(NonMatching, "Runtime/NMWException.cp"), - Object(NonMatching, "Runtime/CPlusLibPPC.cp"), + Object(Matching, "Runtime/CPlusLibPPC.cp"), Object(NonMatching, "Runtime/ptmf.c"), - #Object(NonMatching, "Runtime/runtime.c"), + Object(NonMatching, "Runtime/runtime.c"), Object(NonMatching, "Runtime/__init_cpp_exceptions.cpp"), Object(NonMatching, "Runtime/Gecko_ExceptionPPC.cp"), Object(NonMatching, "Runtime/GCN_mem_alloc.c"), @@ -808,7 +808,7 @@ def MatchingFor(*versions): Object(NonMatching, "MSL_C/MSL_Common/arith.c"), Object(NonMatching, "MSL_C/MSL_Common/bsearch.c"), Object(NonMatching, "MSL_C/MSL_Common/buffer_io.c"), - Object(NonMatching, "MSL_C/PPC_EABI/critical_regions.gamecube.c"), + Object(Matching, "MSL_C/PPC_EABI/critical_regions.gamecube.c"), Object(NonMatching, "MSL_C/MSL_Common/ctype.c"), Object(NonMatching, "MSL_C/MSL_Common/direct_io.c"), Object(Matching, "MSL_C/MSL_Common/errno.c"), @@ -828,8 +828,7 @@ def MatchingFor(*versions): Object(NonMatching, "MSL_C/MSL_Common/strtold.c"), Object(NonMatching, "MSL_C/MSL_Common/strtoul.c"), Object(NonMatching, "MSL_C/MSL_Common/float.c"), - # Causes cyclic dependency error - # Object(NonMatching, "MSL_C/MSL_Common/char_io.c"), + Object(NonMatching, "MSL_C/MSL_Common/char_io.c"), Object(NonMatching, "MSL_C/MSL_Common/wchar_io.c"), Object(NonMatching, "MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c") ] @@ -860,12 +859,12 @@ def MatchingFor(*versions): Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_modf.c"), Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_sin.c"), Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/s_tan.c"), - Object(NonMatching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_acos.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_acos.c"), Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_asin.c"), Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_atan2.c"), Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_exp.c"), Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c"), - Object(NonMatching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log.c"), Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c"), Object(NonMatching, "MSL_C/PPC_EABI/math_ppc.c"), ] @@ -883,20 +882,20 @@ def MatchingFor(*versions): Object(NonMatching, "debugger/embedded/MetroTRK/Portable/dispatch.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msghndlr.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/support.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/mutex_TRK.c"), + Object(Matching, "debugger/embedded/MetroTRK/Portable/mutex_TRK.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/notify.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/main_TRK.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/mem_TRK.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/string_TRK.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c"), - #Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s"), + Object(Matching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s"), Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c"), - #Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s"), - Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c"), + Object(Matching, "debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s"), + Object(Matching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/usr_put.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/targcont.c"), + Object(Matching, "debugger/embedded/MetroTRK/Os/dolphin/targcont.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/target_options.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/UDP_Stubs.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Export/mslsupp.c"), diff --git a/include/dolphin/os/OSInterrupt.h b/include/dolphin/os/OSInterrupt.h index 9e5d2aa03..8baa37d0b 100644 --- a/include/dolphin/os/OSInterrupt.h +++ b/include/dolphin/os/OSInterrupt.h @@ -45,32 +45,32 @@ extern "C" { #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 \ - (OS_INTERRUPTMASK_MEM_0 | OS_INTERRUPTMASK_MEM_1 | OS_INTERRUPTMASK_MEM_2 | \ - OS_INTERRUPTMASK_MEM_3 | OS_INTERRUPTMASK_MEM_ADDRESS) + (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) + (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_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) + (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) + (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) + (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) @@ -83,10 +83,10 @@ extern "C" { #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 void (*__OSInterruptHandler)(__OSInterrupt interrupt, OSContext* context); @@ -95,13 +95,13 @@ typedef u32 OSInterruptMask; extern volatile __OSInterrupt __OSLastInterrupt; extern volatile u32 __OSLastInterruptSrr0; -extern volatile OSTime __OSLastInterruptTime; +// extern volatile OSTime __OSLastInterruptTime; __OSInterruptHandler __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler); __OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt); -void __OSDispatchInterrupt(__OSException exception, OSContext* context); +//void __OSDispatchInterrupt(__OSException exception, OSContext* context); OSInterruptMask OSGetInterruptMask(void); OSInterruptMask OSSetInterruptMask(OSInterruptMask mask); diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/char_io.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/char_io.h new file mode 100644 index 000000000..5ac7be5cc --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/char_io.h @@ -0,0 +1,17 @@ +#ifndef _MSL_COMMON_CHAR_IO_H +#define _MSL_COMMON_CHAR_IO_H + +#include "ansi_files.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int fputs(const char* str, FILE* stream); +int __put_char(int c, FILE* stream); + +#ifdef __cplusplus +} +#endif + +#endif /* _MSL_COMMON_CHAR_IO_H */ \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h index 45d502265..d44317150 100644 --- a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h @@ -16,6 +16,26 @@ int __fpclassifyd(double); #define MATH_INLINE inline #endif +MATH_INLINE float powf(float __x, float __y) +{ + return pow((double)__x, (double)__y); +} + +MATH_INLINE float sinf(float __x) +{ + return sin((double)__x); +} + +MATH_INLINE float cosf(float __x) +{ + return cos((double)__x); +} + +MATH_INLINE float atanf(float __x) +{ + return atan((double)__x); +} + MATH_INLINE int __fpclassifyf(f32 x) { switch ((*(s32*)&x) & 0x7f800000) @@ -64,21 +84,6 @@ MATH_INLINE int __fpclassifyd(f64 x) return 4; } -MATH_INLINE float cosf(float __x) -{ - return cos((double)__x); -} - -MATH_INLINE float sinf(float __x) -{ - return sin((double)__x); -} - -MATH_INLINE float tanf(float __x) -{ - return tan((double)__x); -} - #define fpclassify(x) \ ((sizeof(x) == sizeof(float)) ? __fpclassifyf((float)(x)) : __fpclassifyd((double)(x))) diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dstypes.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dstypes.h new file mode 100644 index 000000000..9da077014 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/dstypes.h @@ -0,0 +1,27 @@ +#ifndef METROTRK_DSTYPES +#define METROTRK_DSTYPES + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +// typedef unsigned char ui8; +// typedef unsigned short ui16; +// typedef unsigned long ui32; +// typedef unsigned long long ui64; +typedef unsigned char u128[16]; + +// typedef unsigned long size_t; +// typedef unsigned int uint; + +// typedef int bool; + +// #define true 1 +// #define false 0 +// #define NULL 0 + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/memmap.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/memmap.h new file mode 100644 index 000000000..205246646 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/memmap.h @@ -0,0 +1,15 @@ +#ifndef METROTRK_MEM_TRK_H +#define METROTRK_MEM_TRK_H +#include "PowerPC_EABI_Support/MetroTRK/dstypes.h" +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +typedef struct memRange { + u8* start; + u8* end; + BOOL readable; + BOOL writeable; +} memRange; + +const memRange gTRKMemMap[1] = { { (u8*)0, (u8*)-1, TRUE, TRUE } }; + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/ppc_reg.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/ppc_reg.h new file mode 100644 index 000000000..11411a7b1 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/ppc_reg.h @@ -0,0 +1,242 @@ +#ifndef _PPC_REG_H +#define _PPC_REG_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +typedef struct Default_PPC { + u32 GPR[32]; + u32 PC; + u32 LR; + u32 CR; + u32 CTR; + u32 XER; +} Default_PPC; + +typedef struct Float_PPC { + u64 FPR[32]; + u64 FPSCR; + u64 FPECR; +} Float_PPC; + +typedef struct Extended1_PPC_6xx_7xx { + // u8 pad[0x168]; + u32 SR[16]; + u32 TBL; + u32 TBU; + u32 HID0_; + u32 HID1; + u32 MSR; + u32 PVR; + u32 IBAT0U; + u32 IBAT0L; + u32 IBAT1U; + u32 IBAT1L; + u32 IBAT2U; + u32 IBAT2L; + u32 IBAT3U; + u32 IBAT3L; + u32 DBAT0U; + u32 DBAT0L; + u32 DBAT1U; + u32 DBAT1L; + u32 DBAT2U; + u32 DBAT2L; + u32 DBAT3U_; + u32 DBAT3L_; + u32 DMISS; + u32 DCMP; + u32 HASH1; + u32 HASH2; + u32 IMISS; + u32 ICMP; + u32 RPA; + u32 SDR1; + u32 DAR; + u32 DSISR; + u32 SPRG0; + u32 SPRG1; + u32 SPRG2; + u32 SPRG3; + u32 DEC; + u32 IABR; + u32 EAR; + u32 DABR; + u32 PMC1; + u32 PMC2; + u32 PMC3; + u32 PMC4; + u32 SIA; + u32 MMCR0; + u32 MMCR1; + u32 THRM1; + u32 THRM2; + u32 THRM3; + u32 ICTC; + u32 L2CR; + u32 UMMCR2; + u32 UBAMR; + u32 UMMCR0; + u32 UPMC1; + u32 UPMC2; + u32 USIA; + u32 UMMCR1; + u32 UPMC3; + u32 UPMC4; + u32 USDA; + u32 MMCR2; + u32 BAMR; + u32 SDA; + u32 MSSCR0; + u32 MSSCR1; + u32 PIR; + u32 exceptionID; + u32 GQR[8]; + u32 HID_G; + u32 WPAR; + u32 DMA_U_; + u32 DMA_L_; +} Extended1_PPC_6xx_7xx; + +typedef struct Extended2_PPC_6xx_7xx { + u32 PSR[32][2]; +} Extended2_PPC_6xx_7xx; + +typedef struct ProcessorState_PPC_6xx_7xx { + Default_PPC Default; + Float_PPC Float; + Extended1_PPC_6xx_7xx Extended1; + Extended2_PPC_6xx_7xx Extended2; + u32 transport_handler_saved_ra; +} ProcessorState_PPC_6xx_7xx; + +typedef ProcessorState_PPC_6xx_7xx ProcessorState_PPC; + +#define SPR_XER 1 +#define SPR_LR 8 +#define SPR_CTR 9 +#define SPR_DSISR 18 +#define SPR_DAR 19 +#define SPR_DEC 22 +#define SPR_SDR1 25 +#define SPR_SRR0 26 +#define SPR_SRR1 27 +#define SPR_SPRG0 272 +#define SPR_SPRG1 273 +#define SPR_SPRG2 274 +#define SPR_SPRG3 275 +#define SPR_EAR 282 +#define SPR_TBL 284 +#define SPR_TBU 285 +#define SPR_PVR 287 +#define SPR_IBAT0U 528 +#define SPR_IBAT0L 529 +#define SPR_IBAT1U 530 +#define SPR_IBAT1L 531 +#define SPR_IBAT2U 532 +#define SPR_IBAT2L 533 +#define SPR_IBAT3U 534 +#define SPR_IBAT3L 535 +#define SPR_IBAT4U 560 +#define SPR_IBAT4L 561 +#define SPR_IBAT5U 562 +#define SPR_IBAT5L 563 +#define SPR_IBAT6U 564 +#define SPR_IBAT6L 565 +#define SPR_IBAT7U 566 +#define SPR_IBAT7L 567 +#define SPR_DBAT0U 536 +#define SPR_DBAT0L 537 +#define SPR_DBAT1U 538 +#define SPR_DBAT1L 539 +#define SPR_DBAT2U 540 +#define SPR_DBAT2L 541 +#define SPR_DBAT3U 542 +#define SPR_DBAT3L 543 +#define SPR_DBAT4U 568 +#define SPR_DBAT4L 569 +#define SPR_DBAT5U 570 +#define SPR_DBAT5L 571 +#define SPR_DBAT6U 572 +#define SPR_DBAT6L 573 +#define SPR_DBAT7U 574 +#define SPR_DBAT7L 575 +#define SPR_GQR0 912 +#define SPR_GQR1 913 +#define SPR_GQR2 914 +#define SPR_GQR3 915 +#define SPR_GQR4 916 +#define SPR_GQR5 917 +#define SPR_GQR6 918 +#define SPR_GQR7 919 +#define SPR_HID2 920 +#define SPR_WPAR 921 +#define SPR_DMA_U 922 +#define SPR_DMA_L 923 +#define SPR_UMMCR0 936 +#define SPR_UPMC1 937 +#define SPR_UPMC2 938 +#define SPR_USIA 939 +#define SPR_UMMCR1 940 +#define SPR_UPMC3 941 +#define SPR_UPMC4 942 +#define SPR_USDA 943 +#define SPR_MMCR0 952 +#define SPR_PMC1 953 +#define SPR_PMC2 954 +#define SPR_SIA 955 +#define SPR_MMCR1 956 +#define SPR_PMC3 957 +#define SPR_PMC4 958 +#define SPR_SDA 959 +#define SPR_HID0 1008 +#define SPR_HID1 1009 +#define SPR_IABR 1010 +#define SPR_HID4 1011 +#define SPR_DABR 1013 +#define SPR_L2CR 1017 +#define SPR_ICTC 1019 +#define SPR_THRM1 1020 +#define SPR_THRM2 1021 +#define SPR_FPECR 1022 + +// PPC exceptions +// 0x000 is reserved +#define PPC_SystemReset 0x100 +#define PPC_MachineCheck 0x200 +#define PPC_DataStorage 0x300 +#define PPC_InstructionStorage 0x400 +#define PPC_ExternalInterrupt 0x500 +#define PPC_Alignment 0x600 +#define PPC_Program 0x700 +#define PPC_FloatingPointUnavaiable 0x800 +#define PPC_Decrementer 0x900 +// 0xA00-0xB00 are reserved +#define PPC_SystemCall 0xC00 +#define PPC_Trace 0xD00 +#define PPC_FloatingPointAssist 0xE00 // unimplemented in 750CL +#define PPC_PerformanceMonitor 0xF00 // Dolphin/Broadway specific +// 0x1000-0x1200 are unimplemented in 750CL +#define PPC_InstructionAddressBreakpoint 0x1300 // Dolphin/Broadway specific +// 0x1400-0x2F00 are reserved, but TRK uses some +#define PPC_SystemManagementInterrupt 0x1400 +// 0x1500-0x1600 are unimplemented in 750CL +#define PPC_ThermalManagementInterrupt 0x1700 +#define PPC_1800Exception 0x1800 +#define PPC_1900Exception 0x1900 +#define PPC_1A00Exception 0x1A00 +#define PPC_1B00Exception 0x1B00 +#define PPC_1C00Exception 0x1C00 // Data breakpoint? +#define PPC_1D00Exception 0x1D00 // Instruction breakpoint? +#define PPC_1E00Exception 0x1E00 // Peripheral breakpoint? +#define PPC_1F00Exception 0x1F00 // Non maskable development port? +#define PPC_2000Exception 0x2000 + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trk.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trk.h index e11a7854c..4bb4788f7 100644 --- a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trk.h +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trk.h @@ -2,215 +2,220 @@ #define _DOLPHIN_TRK_H #include "types.h" -#include "Dolphin/db.h" +#include "PowerPC_EABI_Support/MetroTRK/trktypes.h" +#include "PowerPC_EABI_Support/MetroTRK/ppc_reg.h" #ifdef __cplusplus extern "C" { #endif // ifdef __cplusplus -/* TRK */ - -#define TRK_DISPATCH_CMD_CONNECT 1 /* Connect to the console */ -#define TRK_DISPATCH_CMD_DISCONNECT 2 /* Disconnect from the console */ -#define TRK_DISPATCH_CMD_RESET 3 /* Reset the debugger */ -#define TRK_DISPATCH_CMD_GETVERSION 4 /* Get debugger version */ -#define TRK_DISPATCH_CMD_GETSUPPORTMASK 5 /* Get Support Mask */ -#define TRK_DISPATCH_CMD_OVERRIDE 7 /* Override? */ -#define TRK_DISPATCH_CMD_READMEM 16 /* Reading from memory */ -#define TRK_DISPATCH_CMD_WRITEMEM 17 /* Writing to memory */ -#define TRK_DISPATCH_CMD_READREGS 18 /* Read a register value */ -#define TRK_DISPATCH_CMD_WRITEREGS 19 /* Set a register */ -#define TRK_DISPATCH_CMD_SETOPTION 23 /* Set an option? */ -#define TRK_DISPATCH_CMD_CONTINUE 24 /* Continue debugging */ -#define TRK_DISPATCH_CMD_STEP 25 /* Step through an instruction */ -#define TRK_DISPATCH_CMD_STOP 26 /* Stop the debugger */ - -typedef struct _TRK_Msg { - u8 _00[8]; // _00 - u32 mMsgLength; // _08 - u32 _0C; // _0C - u32 mMsg; // _10 -} TRK_Msg; - -/** - * @size{0xC} - */ -typedef struct TRKEvent { - int mEventType; - int _04; - int mBufferIndex; -} TRKEvent; - -/** - * @size{0x28} - */ -typedef struct TRKEventQueue { - u8 _00[4]; - int mCurrEvtID; - int mNextSlotToOverwrite; - TRKEvent mEvents[2]; - u32 _24; /* max of 0x100? */ -} TRKEventQueue; - -/** - * @size{0xA4} - */ -typedef struct TRKState { - u32 _00; - u32 _04; - u32 _08; - u32 _0C; - u32 _10; - u32 _14; - u32 _18; - u32 _1C; - u32 _20; - u32 _24; - u32 _28; - u32 _2C; - u32 _30; - u32 _34; - u32 _38; - u32 _3C; - u32 _40; - u32 _44; - u32 _48; - u32 _4C; - u32 _50; - u32 _54; - u32 _58; - u32 _5C; - u32 _60; - u32 _64; - u32 _68; - u32 _6C; - u32 _70; - u32 _74; - u32 _78; - u32 _7C; - u32 _80; - u32 _84; - u32 _88; - u32 _8C; - u32 _90; - u32 _94; - BOOL mIsStopped; - u32 _9C; - u32 _A0; - u32 _A4; - u32 _A8; - u32 _AC; -} TRKState; - -typedef struct TRKBuffer { - u8 _00[4]; - u32 _04; - s32 _08; - u32 _0C; - u32 _10; - u8 mBuffer[0x87C]; /* _10 */ -} TRKBuffer; -typedef enum { TRKSuccess = 0, TRKError100 = 0x100, TRKError301 = 0x301, TRKError302 = 0x302 } TRKResult; - -extern BOOL gTRKBigEndian; - -u32 TRKDoConnect(TRKBuffer*); -u32 TRKDoDisconnect(TRKBuffer*); -u32 TRKDoReset(TRKBuffer*); -u32 TRKDoVersions(TRKBuffer*); -u32 TRKDoSupportMask(TRKBuffer*); -u32 TRKDoOverride(TRKBuffer*); -u32 TRKDoReadMemory(TRKBuffer*); -u32 TRKDoWriteMemory(TRKBuffer*); -u32 TRKDoReadRegisters(TRKBuffer*); -u32 TRKDoWriteRegisters(TRKBuffer*); -u32 TRKDoSetOption(TRKBuffer*); -u32 TRKDoContinue(TRKBuffer*); -u32 TRKDoStep(TRKBuffer*); -u32 TRKDoStop(TRKBuffer*); - +////// MSG HANDLING FUNCTIONS ////// +DSError TRKDoConnect(TRKBuffer*); +DSError TRKDoDisconnect(TRKBuffer*); +DSError TRKDoReset(TRKBuffer*); +DSError TRKDoVersions(TRKBuffer*); +DSError TRKDoSupportMask(TRKBuffer*); +DSError TRKDoOverride(TRKBuffer*); +DSError TRKDoReadMemory(TRKBuffer*); +DSError TRKDoWriteMemory(TRKBuffer*); +DSError TRKDoReadRegisters(TRKBuffer*); +DSError TRKDoWriteRegisters(TRKBuffer*); +DSError TRKDoSetOption(TRKBuffer*); +DSError TRKDoContinue(TRKBuffer*); +DSError TRKDoStep(TRKBuffer*); +DSError TRKDoStop(TRKBuffer*); +DSError TRKDoUnsupported(TRKBuffer*); +DSError TRKDoCPUType(TRKBuffer*); +DSError TRKDoFlushCache(TRKBuffer*); + +void __TRK_copy_vectors(); + +void SetBufferPosition(TRKBuffer*, u32); +void SetTRKConnected(int); +int GetTRKConnected(void); + +DSError TRKGetFreeBuffer(int*, TRKBuffer**); +void OutputData(void* data, int length); +void TRKResetBuffer(TRKBuffer* msg, u8 keepData); + +DSError TRKReadBuffer_ui8(TRKBuffer* buffer, u8* data, int count); +DSError TRKReadBuffer_ui32(TRKBuffer* buffer, u32* data, int count); + +DSError TRKReadBuffer1_ui8(TRKBuffer* buffer, u8* data); +DSError TRKReadBuffer1_ui16(TRKBuffer* buffer, u16* data); +DSError TRKReadBuffer1_ui32(TRKBuffer* buffer, u32* data); +DSError TRKReadBuffer1_ui64(TRKBuffer* buffer, u64* data); + +DSError TRKAppendBuffer_ui8(TRKBuffer* buffer, const u8* data, int count); +DSError TRKAppendBuffer_ui32(TRKBuffer* buffer, const u32* data, int count); +DSError TRKAppendBuffer1_ui16(TRKBuffer* buffer, const u16 data); +DSError TRKAppendBuffer1_ui32(TRKBuffer* buffer, const u32 data); +DSError TRKAppendBuffer1_ui64(TRKBuffer* buffer, const u64 data); +//////////////////////////////////// + +/////// DOLPHIN TRK FUNCTIONS ////// void InitMetroTRK(void); void InitMetroTRK_BBA(void); void EnableMetroTRKInterrupts(void); -void TRKDestructEvent(TRKEvent*); -TRKResult TRKDispatchMessage(TRKBuffer*); +void TRKLoadContext(OSContext* ctx, u32); +void TRKSaveExtended1Block(); +void TRKRestoreExtended1Block(); +int InitMetroTRKCommTable(int); +void TRK_board_display(char*); +//////////////////////////////////// + +////////// GDEV FUNCTIONS ////////// +int gdev_cc_initialize(void* flagOut, __OSInterruptHandler handler); +int gdev_cc_shutdown(); +int gdev_cc_open(); +int gdev_cc_close(); +int gdev_cc_read(u8* dest, int size); +int gdev_cc_write(const u8* src, int size); +int gdev_cc_pre_continue(); +int gdev_cc_post_stop(); +int gdev_cc_peek(); +int gdev_cc_initinterrupts(); +//////////////////////////////////// + +/////////// UDP FUNCTIONS ////////// +int udp_cc_initialize(void* flagOut, __OSInterruptHandler handler); +int udp_cc_shutdown(); +int udp_cc_open(); +int udp_cc_close(); +int udp_cc_read(u8* dest, int size); +int udp_cc_write(const u8* src, int size); +int udp_cc_pre_continue(); +int udp_cc_post_stop(); +int udp_cc_peek(); +int udp_cc_initinterrupts(); +//////////////////////////////////// + +/////////// DDH FUNCTIONS ////////// +#define DDH_ERR_NOT_INITIALIZED -0x2711 +#define DDH_ERR_ALREADY_INITIALIZED -0x2715 +#define DDH_ERR_READ_ERROR -0x2719 + +int ddh_cc_initialize(void* flagOut, __OSInterruptHandler handler); +int ddh_cc_shutdown(); +int ddh_cc_open(); +int ddh_cc_close(); +int ddh_cc_read(u8* dest, int size); +int ddh_cc_write(const u8* src, int size); +int ddh_cc_pre_continue(); +int ddh_cc_post_stop(); +int ddh_cc_peek(); +int ddh_cc_initinterrupts(); +//////////////////////////////////// + +////////// EVENT FUNCTIONS ///////// +void TRKConstructEvent(TRKEvent* event, int eventType); +void TRKDestructEvent(TRKEvent* event); +DSError TRKPostEvent(TRKEvent* event); +BOOL TRKGetNextEvent(TRKEvent* event); +DSError TRKDispatchMessage(TRKBuffer*); void* TRKGetBuffer(int); void TRKReleaseBuffer(int); void TRKGetInput(); -BOOL TRKGetNextEvent(TRKEvent*); +//////////////////////////////////// -TRKResult TRKTargetContinue(void); -TRKResult TRKTargetInterrupt(TRKEvent*); +///////// TARGET FUNCTIONS ///////// +DSError TRKTargetContinue(void); +DSError TRKTargetInterrupt(TRKEvent*); BOOL TRKTargetStopped(); void TRKTargetSetStopped(uint); -TRKResult TRKTargetSupportRequest(); +DSError TRKTargetSupportRequest(); +//////////////////////////////////// -TRKResult TRKAppendBuffer_ui8(TRKBuffer*, u8*, int); -TRKResult TRKSetBufferPosition(TRKBuffer*, u32); +////// NUB AND MEM FUNCTIONS /////// +DSError TRKAppendBuffer_ui8(TRKBuffer*, const u8*, int); +DSError TRKSetBufferPosition(TRKBuffer*, u32); -TRKResult TRKMessageSend(TRK_Msg*); +DSError TRKMessageSend(TRKBuffer*); void TRKSwapAndGo(void); -TRKResult TRKWriteUARTN(const void* bytes, u32 length); -TRKResult TRKInitializeNub(void); -TRKResult TRKTerminateNub(void); +DSError TRKInitializeNub(void); +DSError TRKTerminateNub(void); void TRKNubWelcome(void); void TRKNubMainLoop(void); -TRKResult TRKInitializeMutex(void*); -TRKResult TRKAcquireMutex(void*); -TRKResult TRKReleaseMutex(void*); +DSError TRKInitializeMutex(void*); +DSError TRKAcquireMutex(void*); +DSError TRKReleaseMutex(void*); void* TRK_memcpy(void* dst, const void* src, size_t n); - -TRKResult TRKInitializeEventQueue(); -TRKResult TRKInitializeMessageBuffers(); -TRKResult TRKInitializeDispatcher(); -TRKResult InitializeProgramEndTrap(); -TRKResult TRKInitializeSerialHandler(); -TRKResult TRKInitializeTarget(); - +//////////////////////////////////// + +/////// INITIALIZE FUNCTIONS /////// +DSError TRKInitializeEventQueue(); +DSError TRKInitializeMessageBuffers(); +DSError TRKInitializeDispatcher(); +DSError InitializeProgramEndTrap(); +DSError TRKInitializeSerialHandler(); +DSError TRKTerminateSerialHandler(); +DSError TRKInitializeTarget(); +//////////////////////////////////// + +////////// EXI2 FUNCTIONS ////////// /* EXI2 */ void UnreserveEXI2Port(void); void ReserveEXI2Port(void); +//////////////////////////////////// -/* MW */ +/////////// MW FUNCTIONS /////////// void MWTRACE(u8, char*, ...); +//////////////////////////////////// -/* UART */ -typedef int UARTError; +//////// SUPPORT FUNCTIONS ///////// +DSError TRKRequestSend(); +u32 TRKAccessFile(u32, u32, u32*, u8*); +//////////////////////////////////// -enum { - kUARTNoError = 0, - kUARTUnknownBaudRate, - kUARTConfigurationError, - kUARTBufferOverflow, /* specified buffer was too small */ - kUARTNoData /* no data available from polling */ -}; - -typedef enum { - kBaudHWSet = -1, /* use HW settings such as DIP switches */ - kBaud300 = 300, /* valid baud rates */ - kBaud600 = 600, - kBaud1200 = 1200, - kBaud1800 = 1800, - kBaud2000 = 2000, - kBaud2400 = 2400, - kBaud3600 = 3600, - kBaud4800 = 4800, - kBaud7200 = 7200, - kBaud9600 = 9600, - kBaud19200 = 19200, - kBaud38400 = 38400, - kBaud57600 = 57600, - kBaud115200 = 115200, - kBaud230400 = 230400 -} UARTBaudRate; +///// SERIAL POLLING FUNCTIONS ///// +TRKBufferID TRKTestForPacker(); +void TRKGetInput(); +void TRKProcessInput(TRKBufferID bufID); +//////////////////////////////////// +////////// OTHER FUNCTIONS ///////// +DSError TRK_main(void); UARTError InitializeUART(UARTBaudRate baudRate); -TRKResult TRKInitializeIntDrivenUART(unknown, unknown, unknown, void*); +DSError TRKInitializeIntDrivenUART(u32, u32, u32, volatile u8**); +int TRKPollUART(); +UARTError TRKReadUARTN(void*, u32); +UARTError TRKWriteUARTN(const void* bytes, u32 length); void usr_put_initialize(); void TRKTargetSetInputPendingPtr(void*); +void SetUseSerialIO(u8); +u8 GetUseSerialIO(void); +u8 TRKTargetCPUMinorType(); + +DSError TRKTargetAddStopInfo(TRKBuffer*); +DSError TRKTargetAddExceptionInfo(TRKBuffer*); +void TRKInterruptHandler(); +BOOL usr_puts_serial(const char* msg); +//////////////////////////////////// + +//////// EXTERNAL DECLARES ///////// +extern BOOL gTRKBigEndian; extern void* gTRKInputPendingPtr; +extern ProcessorState_PPC gTRKCPUState; +extern ProcessorRestoreFlags_PPC gTRKRestoreFlags; +extern u8 gTRKInterruptVectorTable[]; +extern TRKState gTRKState; +extern TRKBuffer gTRKMsgBufs[3]; +//////////////////////////////////// + +////////// USEFUL STATICS ////////// +static inline DSError TRKAppendBuffer1_ui8(TRKBuffer* buffer, const u8 data) +{ + if (buffer->position >= 0x880) { + return DS_MessageBufferOverflow; + } + + buffer->data[buffer->position++] = data; + buffer->length++; + return DS_NoError; +} +//////////////////////////////////// #ifdef __cplusplus }; diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trkenum.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trkenum.h new file mode 100644 index 000000000..6755a48b0 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trkenum.h @@ -0,0 +1,212 @@ +#ifndef _METROTRK_TRKENUM_H +#define _METROTRK_TRKENUM_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +//////////// TRK ENUMS ///////////// +// Hardware types. +typedef enum { + HARDWARE_AMC_DDH = 0, + HARDWARE_GDEV = 1, + HARDWARE_BBA = 2, +} HardwareType; + +// DS Error returns. +typedef enum { + DS_NoError = 0x0, + DS_StepError = 0x1, + DS_ParameterError = 0x2, + + DS_EventQueueFull = 0x100, + + DS_NoMessageBufferAvailable = 0x300, + DS_MessageBufferOverflow = 0x301, + DS_MessageBufferReadError = 0x302, + + DS_DispatchError = 0x500, + + DS_InvalidMemory = 0x700, + DS_InvalidRegister = 0x701, + DS_CWDSException = 0x702, + DS_UnsupportedError = 0x703, + DS_InvalidProcessID = 0x704, + DS_InvalidThreadID = 0x705, + DS_OSError = 0x706, + + DS_Error800 = 0x800, +} DSError; + +typedef struct DSCPUType { + u8 cpuMajor; + u8 cpuMinor; + u8 bigEndian; + u8 defaultTypeSize; + u8 fpTypeSize; + u8 extended1TypeSize; + u8 extended2TypeSize; +} DSCPUType; +DSError TRKTargetCPUType(DSCPUType* cpuType); + +// Where to read/write. +typedef enum { + DS_Stdin = 0, + DS_Stdout = 1, + DS_Stderr = 2, +} DSFileHandle; + +// IO returns. +typedef enum { + DS_IONoError = 0, + DS_IOError = 1, + DS_IOEOF = 2, +} DSIOResult; + +// Message command IDs +typedef enum { + DSMSG_Ping = 0x0, + DSMSG_Connect = 0x1, + DSMSG_Disconnect = 0x2, + DSMSG_Reset = 0x3, + DSMSG_Versions = 0x4, + DSMSG_SupportMask = 0x5, + DSMSG_Override = 0x7, + + DSMSG_ReadMemory = 0x10, + DSMSG_WriteMemory = 0x11, + DSMSG_ReadRegisters = 0x12, + DSMSG_WriteRegisters = 0x13, + DSMSG_SetOption = 0x17, + DSMSG_Continue = 0x18, + DSMSG_Step = 0x19, + DSMSG_Stop = 0x1A, + + DSMSG_ReplyACK = 0x80, + + DSMSG_NotifyStopped = 0x90, + DSMSG_NotifyException = 0x91, + + DSMSG_WriteFile = 0xD0, + DSMSG_ReadFile = 0xD1, + DSMSG_OpenFile = 0xD2, + DSMSG_CloseFile = 0xD3, + DSMSG_PositionFile = 0xD4, + + DSMSG_ReplyNAK = 0xFF, +} MessageCommandID; + +// Register commands. +typedef enum { + DSREG_Default = 0, + DSREG_FP = 1, + DSREG_Extended1 = 2, + DSREG_Extended2 = 3, +} DSMessageRegisterOptions; + +// Step commands. +typedef enum { + DSSTEP_IntoCount = 0x0, + DSSTEP_IntoRange = 0x1, + DSSTEP_OverCount = 0x10, + DSSTEP_OverRange = 0x11, +} DSMessageStepOptions; + +typedef enum { + DSREPLY_NoError = 0x0, + DSREPLY_Error = 0x1, + DSREPLY_PacketSizeError = 0x2, + DSREPLY_CWDSError = 0x3, + DSREPLY_EscapeError = 0x4, + DSREPLY_BadFCS = 0x5, + DSREPLY_Overflow = 0x6, + DSREPLY_SequenceMissing = 0x7, + + DSREPLY_UnsupportedCommandError = 0x10, + DSREPLY_ParameterError = 0x11, + DSREPLY_UnsupportedOptionError = 0x12, + DSREPLY_InvalidMemoryRange = 0x13, + DSREPLY_InvalidRegisterRange = 0x14, + DSREPLY_CWDSException = 0x15, + DSREPLY_NotStopped = 0x16, + DSREPLY_BreakpointsFull = 0x17, + DSREPLY_BreakpointConflict = 0x18, + + DSREPLY_OSError = 0x20, + DSREPLY_InvalidProcessID = 0x21, + DSREPLY_InvalidThreadID = 0x22, + DSREPLY_DebugSecurityError = 0x23, +} DSReplyError; + +typedef enum { + DSRECV_Wait = 0, + DSRECV_Found = 1, + DSRECV_InFrame = 2, + DSRECV_FrameOverflow = 3, +} ReceiverState; + +typedef enum { + DSMSGMEMORY_Segmented = 0x01, /* non-flat addr space */ + DSMSGMEMORY_Extended = 0x02, /* > 32-bit data addr */ + DSMSGMEMORY_Protected = 0x04, /* non-user memory */ + DSMSGMEMORY_Userview = 0x08, /* breakpoints are invisible */ + DSMSGMEMORY_Space_program = 0x00, + DSMSGMEMORY_Space_data = 0x40, + DSMSGMEMORY_Space_io = 0x80 +}; + +typedef enum { + NUBEVENT_Null = 0, + NUBEVENT_Shutdown = 1, + NUBEVENT_Request = 2, + NUBEVENT_Breakpoint = 3, + NUBEVENT_Exception = 4, + NUBEVENT_Support = 5, +} NubEventType; + +typedef enum { + VALIDMEM_Readable = 0, + VALIDMEM_Writeable = 1, +} ValidMemoryOptions; + +typedef enum { + MEMACCESS_UserMemory = 0, + MEMACCESS_DebuggerMemory = 1, +} MemoryAccessOptions; + +typedef enum { + UART_NoError = 0, + UART_UnknownBaudRate = 1, + UART_ConfigurationError = 2, + UART_BufferOverflow = 3, // specified buffer was too small + UART_NoData = 4, // no data available from polling +} UARTErrorOptions; + +typedef enum { + kBaudHWSet = -1, // use HW settings such as DIP switches + kBaud300 = 300, // valid baud rates + kBaud600 = 600, + kBaud1200 = 1200, + kBaud1800 = 1800, + kBaud2000 = 2000, + kBaud2400 = 2400, + kBaud3600 = 3600, + kBaud4800 = 4800, + kBaud7200 = 7200, + kBaud9600 = 9600, + kBaud19200 = 19200, + kBaud38400 = 38400, + kBaud57600 = 57600, + kBaud115200 = 115200, + kBaud230400 = 230400 +} UARTBaudRate; + +//////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trktypes.h b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trktypes.h new file mode 100644 index 000000000..d7f071062 --- /dev/null +++ b/libs/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trktypes.h @@ -0,0 +1,144 @@ +#ifndef _METROTRK_TRKTYPES_H +#define _METROTRK_TRKTYPES_H + +#include "types.h" +#include "Dolphin/OS/OSInterrupt.h" +#include "PowerPC_EABI_Support/MetroTRK/trkenum.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +/////// TRK STRUCTS AND TYPES ////// +// Function types for DB communications. +typedef int (*DBCommFunc)(); +typedef void (*DBCommInitFunc)(volatile u8**, __OSInterruptHandler); +typedef int (*DBCommReadFunc)(void*, u32); +typedef int (*DBCommWriteFunc)(const void*, u32); + +// Message buffer ID type. +typedef int TRKBufferID; + +// Nub event ID type. +typedef u32 NubEventID; + +// UART Error type. +typedef int UARTError; + +// Size of message buffer. +#define TRKMSGBUF_SIZE (0x800 + 0x80) + +// Struct for sending and receiving messages (size 0x88C). +typedef struct TRKBuffer { + u32 mutex; // _00 + BOOL isInUse; // _04 + u32 length; // _08 + u32 position; // _0C + u8 data[TRKMSGBUF_SIZE]; // _10 +} TRKBuffer; + +// Struct for storing DB communication functions (size 0x1C). +typedef struct DBCommTable { + DBCommInitFunc initialize_func; // _00 + DBCommFunc init_interrupts_func; // _04 + DBCommFunc peek_func; // _08 + DBCommReadFunc read_func; // _0C + DBCommWriteFunc write_func; // _10 + DBCommFunc open_func; // _14 + DBCommFunc close_func; // _18 +} DBCommTable; + +// Struct for information on DS versions (kernel and protocol) (size 0x4) +typedef struct DSVersions { + u8 kernelMajor; // _00 + u8 kernelMinor; // _01 + u8 protocolMajor; // _02 + u8 protocolMinor; // _03 +} DSVersions; + +// Struct for packet information (size 0x8). +typedef struct TRKPacketSeq { + u16 _00; // _00, unknown + u8 _02[6]; // _02, unknown +} TRKPacketSeq; + +// Struct for receiving packets from serial poll (size 0x14). +typedef struct TRKFramingState { + TRKBufferID msgBufID; // _00 + TRKBuffer* buffer; // _04 + u8 receiveState; // _08 + BOOL isEscape; // _0C + u8 fcsType; // _10 +} TRKFramingState; + +// Command reply information (size 0x40). +typedef struct CommandReply { + u32 _00; // _00 + union { + u8 b; + MessageCommandID m; + } commandID; // _04, use MessageCommandID enum + union { + u8 b; + DSReplyError r; + } replyError; // _08, use DSReplyError enum - should be enum type? check size. + u32 _0C; // _0C + u8 _10[0x30]; // _10, unknown +} CommandReply; + +// Nub event information (size 0xC). +typedef struct TRKEvent { + u8 eventType; // _00 + NubEventID eventID; // _04 + TRKBufferID msgBufID; // _08 +} TRKEvent; + +// Event queue (size 0x28). +typedef struct TRKEventQueue { + u8 _00[4]; // _00, unknown + int count; // _04, number of events in queue + int next; // _08, next event in `events` to handle (0 or 1) + TRKEvent events[2]; // _0C + NubEventID eventID; // _24, ID to assign next event, min 0x100 +} TRKEventQueue; + +// Struct for state information (size 0xB0). +typedef struct TRKState { + u32 gpr[32]; // _00 + u32 lr; // _80 + u32 ctr; // _84 + u32 xer; // _88 + u32 msr; // _8C + u32 dar; // _90 + u32 dsisr; // _94 + BOOL isStopped; // _98 + BOOL inputActivated; // _9C + void* inputPendingPtr; // _A0 +} TRKState; + +typedef struct TRKState_PPC { + u32 GPR[32]; // 0x0 + u32 LR; // 0x80 + u32 CTR; // 0x84 + u32 XER; // 0x88 + u32 MSR; // 0x8c + u32 DAR; // 0x90 + u32 DSISR; // 0x94 + BOOL stopped; // 0x98 + BOOL inputActivated; // 0x9c + u8* inputPendingPtr; // 0xA0 +} TRKState_PPC; + +typedef struct ProcessorRestoreFlags_PPC { + u8 TBR; + u8 DEC; + u8 linker_padding[0x9 - 0x2]; +} ProcessorRestoreFlags_PPC; + +//////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/alloc.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/alloc.c index 016240ad6..e3dae74c4 100644 --- a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/alloc.c +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/alloc.c @@ -1,83 +1,95 @@ #include "PowerPC_EABI_Support/MSL_C/MSL_Common/alloc.h" #include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" -typedef struct Block { - struct Block* prev; - struct Block* next; - unsigned long max_size; - unsigned long size; +typedef struct Block +{ + struct Block* prev; + struct Block* next; + unsigned long max_size; + unsigned long size; } Block; -typedef struct SubBlock { - unsigned long size; - Block* block; - struct SubBlock* prev; - struct SubBlock* next; +typedef struct SubBlock +{ + unsigned long size; + Block* block; + struct SubBlock* prev; + struct SubBlock* next; } SubBlock; struct FixSubBlock; -typedef struct FixBlock { - struct FixBlock* prev_; - struct FixBlock* next_; - unsigned long client_size_; - struct FixSubBlock* start_; - unsigned long n_allocated_; +typedef struct FixBlock +{ + struct FixBlock* prev_; + struct FixBlock* next_; + unsigned long client_size_; + struct FixSubBlock* start_; + unsigned long n_allocated_; } FixBlock; -typedef struct FixSubBlock { - FixBlock* block_; - struct FixSubBlock* next_; +typedef struct FixSubBlock +{ + FixBlock* block_; + struct FixSubBlock* next_; } FixSubBlock; -typedef struct FixStart { - FixBlock* tail_; - FixBlock* head_; +typedef struct FixStart +{ + FixBlock* tail_; + FixBlock* head_; } FixStart; -typedef struct __mem_pool_obj { - Block* start_; - FixStart fix_start[6]; +typedef struct __mem_pool_obj +{ + Block* start_; + FixStart fix_start[6]; } __mem_pool_obj; -typedef struct __mem_pool { - void* reserved[14]; +typedef struct __mem_pool +{ + void* reserved[14]; } __mem_pool; typedef signed long tag_word; -typedef struct block_header { - tag_word tag; - struct block_header* prev; - struct block_header* next; +typedef struct block_header +{ + tag_word tag; + struct block_header* prev; + struct block_header* next; } block_header; -typedef struct list_header { - block_header* rover; - block_header header; +typedef struct list_header +{ + block_header* rover; + block_header header; } list_header; -typedef struct heap_header { - struct heap_header* prev; - struct heap_header* next; +typedef struct heap_header +{ + struct heap_header* prev; + struct heap_header* next; } heap_header; struct mem_pool_obj; typedef void* (*sys_alloc_ptr)(unsigned long, struct mem_pool_obj*); typedef void (*sys_free_ptr)(void*, struct mem_pool_obj*); -typedef struct pool_options { - sys_alloc_ptr sys_alloc_func; - sys_free_ptr sys_free_func; - unsigned long min_heap_size; - int always_search_first; +typedef struct pool_options +{ + sys_alloc_ptr sys_alloc_func; + sys_free_ptr sys_free_func; + unsigned long min_heap_size; + int always_search_first; } pool_options; -typedef struct mem_pool_obj { - list_header free_list; - pool_options options; - heap_header* heap_list; - void* userData; +typedef struct mem_pool_obj +{ + list_header free_list; + pool_options options; + heap_header* heap_list; + void* userData; } mem_pool_obj; @@ -89,364 +101,400 @@ static void SubBlock_merge_next(SubBlock*, SubBlock**); static const unsigned long fix_pool_sizes[] = { 4, 12, 20, 36, 52, 68 }; -#define SubBlock_size(ths) ((ths)->size & 0xFFFFFFF8) +#define SubBlock_size(ths) ((ths)->size & 0xFFFFFFF8) #define SubBlock_block(ths) ((Block*)((unsigned long)((ths)->block) & ~0x1)) -#define Block_size(ths) ((ths)->size & 0xFFFFFFF8) -#define Block_start(ths) (*(SubBlock**)((char*)(ths) + Block_size((ths)) - sizeof(unsigned long))) +#define Block_size(ths) ((ths)->size & 0xFFFFFFF8) +#define Block_start(ths) (*(SubBlock**)((char*)(ths) + Block_size((ths)) - sizeof(unsigned long))) -#define SubBlock_set_free(ths) \ - unsigned long this_size = SubBlock_size((ths)); \ - (ths)->size &= ~0x2; \ - *(unsigned long*)((char*)(ths) + this_size) &= ~0x4; \ - *(unsigned long*)((char*)(ths) + this_size - sizeof(unsigned long)) = this_size +#define SubBlock_set_free(ths) \ + unsigned long this_size = SubBlock_size((ths)); \ + (ths)->size &= ~0x2; \ + *(unsigned long*)((char*)(ths) + this_size) &= ~0x4; \ + *(unsigned long*)((char*)(ths) + this_size - sizeof(unsigned long)) = this_size #define SubBlock_is_free(ths) !((ths)->size & 2) -#define SubBlock_set_size(ths, sz) \ - (ths)->size &= ~0xFFFFFFF8; \ - (ths)->size |= (sz)&0xFFFFFFF8; \ - if (SubBlock_is_free((ths))) \ - *(unsigned long*)((char*)(ths) + (sz) - sizeof(unsigned long)) = (sz) +#define SubBlock_set_size(ths, sz) \ + (ths)->size &= ~0xFFFFFFF8; \ + (ths)->size |= (sz)&0xFFFFFFF8; \ + if (SubBlock_is_free((ths))) \ + *(unsigned long*)((char*)(ths) + (sz) - sizeof(unsigned long)) = (sz) -#define SubBlock_from_pointer(ptr) ((SubBlock*)((char*)(ptr)-8)) +#define SubBlock_from_pointer(ptr) ((SubBlock*)((char*)(ptr)-8)) #define FixSubBlock_from_pointer(ptr) ((FixSubBlock*)((char*)(ptr)-4)) #define FixBlock_client_size(ths) ((ths)->client_size_) -#define FixSubBlock_size(ths) (FixBlock_client_size((ths)->block_)) +#define FixSubBlock_size(ths) (FixBlock_client_size((ths)->block_)) #define classify(ptr) (*(unsigned long*)((char*)(ptr) - sizeof(unsigned long)) & 1) -#define __msize_inline(ptr) \ - (!classify(ptr) ? FixSubBlock_size(FixSubBlock_from_pointer(ptr)) : SubBlock_size(SubBlock_from_pointer(ptr)) - 8) +#define __msize_inline(ptr) \ + (!classify(ptr) ? FixSubBlock_size(FixSubBlock_from_pointer(ptr)) : \ + SubBlock_size(SubBlock_from_pointer(ptr)) - 8) -#define Block_empty(ths) (_sb = (SubBlock*)((char*)(ths) + 16)), SubBlock_is_free(_sb) && SubBlock_size(_sb) == Block_size((ths)) - 24 +#define Block_empty(ths) \ + (_sb = (SubBlock*)((char*)(ths) + 16)), \ + SubBlock_is_free(_sb) && SubBlock_size(_sb) == Block_size((ths)) - 24 void Block_construct(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } void Block_subBlock(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } void Block_link(Block* ths, SubBlock* sb) { - SubBlock** st; - SubBlock_set_free(sb); - st = &Block_start(ths); - - if (*st != 0) { - sb->prev = (*st)->prev; - sb->prev->next = sb; - sb->next = *st; - (*st)->prev = sb; - *st = sb; - *st = SubBlock_merge_prev(*st, st); - SubBlock_merge_next(*st, st); - } else { - *st = sb; - sb->prev = sb; - sb->next = sb; - } - if (ths->max_size < SubBlock_size(*st)) - ths->max_size = SubBlock_size(*st); + SubBlock** st; + SubBlock_set_free(sb); + st = &Block_start(ths); + + if (*st != 0) + { + sb->prev = (*st)->prev; + sb->prev->next = sb; + sb->next = *st; + (*st)->prev = sb; + *st = sb; + *st = SubBlock_merge_prev(*st, st); + SubBlock_merge_next(*st, st); + } + else + { + *st = sb; + sb->prev = sb; + sb->next = sb; + } + if (ths->max_size < SubBlock_size(*st)) + ths->max_size = SubBlock_size(*st); } void Block_unlink(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } void Block_report(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } void SubBlock_construct(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } void SubBlock_split(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } static SubBlock* SubBlock_merge_prev(SubBlock* ths, SubBlock** start) { - unsigned long prevsz; - SubBlock* p; + unsigned long prevsz; + SubBlock* p; - if (!(ths->size & 0x04)) { - prevsz = *(unsigned long*)((char*)ths - sizeof(unsigned long)); - if (prevsz & 0x2) - return ths; - p = (SubBlock*)((char*)ths - prevsz); - SubBlock_set_size(p, prevsz + SubBlock_size(ths)); + if (!(ths->size & 0x04)) + { + prevsz = *(unsigned long*)((char*)ths - sizeof(unsigned long)); + if (prevsz & 0x2) + return ths; + p = (SubBlock*)((char*)ths - prevsz); + SubBlock_set_size(p, prevsz + SubBlock_size(ths)); - if (*start == ths) - *start = (*start)->next; - ths->next->prev = ths->prev; - ths->next->prev->next = ths->next; - return p; - } - return ths; + if (*start == ths) + *start = (*start)->next; + ths->next->prev = ths->prev; + ths->next->prev->next = ths->next; + return p; + } + return ths; } static void SubBlock_merge_next(SubBlock* pBlock, SubBlock** pStart) { - SubBlock* next_sub_block; - unsigned long this_cur_size; + SubBlock* next_sub_block; + unsigned long this_cur_size; - next_sub_block = (SubBlock*)((char*)pBlock + (pBlock->size & 0xFFFFFFF8)); + next_sub_block = (SubBlock*)((char*)pBlock + (pBlock->size & 0xFFFFFFF8)); - if (!(next_sub_block->size & 2)) { - this_cur_size = (pBlock->size & 0xFFFFFFF8) + (next_sub_block->size & 0xFFFFFFF8); + if (!(next_sub_block->size & 2)) + { + this_cur_size = (pBlock->size & 0xFFFFFFF8) + (next_sub_block->size & 0xFFFFFFF8); - pBlock->size &= ~0xFFFFFFF8; - pBlock->size |= this_cur_size & 0xFFFFFFF8; + pBlock->size &= ~0xFFFFFFF8; + pBlock->size |= this_cur_size & 0xFFFFFFF8; - if (!(pBlock->size & 2)) { - *(unsigned long*)((char*)(pBlock) + (this_cur_size)-4) = (this_cur_size); - } + if (!(pBlock->size & 2)) + { + *(unsigned long*)((char*)(pBlock) + (this_cur_size)-4) = (this_cur_size); + } - if (!(pBlock->size & 2)) { - *(unsigned long*)((char*)pBlock + this_cur_size) &= ~4; - } else { - *(unsigned long*)((char*)pBlock + this_cur_size) |= 4; - } + if (!(pBlock->size & 2)) + { + *(unsigned long*)((char*)pBlock + this_cur_size) &= ~4; + } + else + { + *(unsigned long*)((char*)pBlock + this_cur_size) |= 4; + } - if (*pStart == next_sub_block) { - *pStart = (*pStart)->next; - } + if (*pStart == next_sub_block) + { + *pStart = (*pStart)->next; + } - if (*pStart == next_sub_block) { - *pStart = 0; - } + if (*pStart == next_sub_block) + { + *pStart = 0; + } - next_sub_block->next->prev = next_sub_block->prev; - next_sub_block->prev->next = next_sub_block->next; - } + next_sub_block->next->prev = next_sub_block->prev; + next_sub_block->prev->next = next_sub_block->next; + } } void SubBlock_report(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } void link(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } static Block* __unlink(__mem_pool_obj* pool_obj, Block* bp) { - Block* result = bp->next; - if (result == bp) { - result = 0; - } + Block* result = bp->next; + if (result == bp) + { + result = 0; + } - if (pool_obj->start_ == bp) { - pool_obj->start_ = result; - } + if (pool_obj->start_ == bp) + { + pool_obj->start_ = result; + } - if (result != 0) { - result->prev = bp->prev; - result->prev->next = result; - } + if (result != 0) + { + result->prev = bp->prev; + result->prev->next = result; + } - bp->next = 0; - bp->prev = 0; - return result; + bp->next = 0; + bp->prev = 0; + return result; } void link_new_block(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } void allocate_from_var_pools(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } void soft_allocate_from_var_pools(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } static void deallocate_from_var_pools(__mem_pool_obj* pool_obj, void* ptr) { - SubBlock* sb = SubBlock_from_pointer(ptr); - SubBlock* _sb; + SubBlock* sb = SubBlock_from_pointer(ptr); + SubBlock* _sb; - Block* bp = SubBlock_block(sb); - Block_link(bp, sb); + Block* bp = SubBlock_block(sb); + Block_link(bp, sb); - if (Block_empty(bp)) { - __unlink(pool_obj, bp); - __sys_free(bp); - } + if (Block_empty(bp)) + { + __unlink(pool_obj, bp); + __sys_free(bp); + } } void FixBlock_construct(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } -void __init_pool_obj(__mem_pool* pool_obj) { memset(pool_obj, 0, sizeof(__mem_pool_obj)); } +void __init_pool_obj(__mem_pool* pool_obj) +{ + memset(pool_obj, 0, sizeof(__mem_pool_obj)); +} static __mem_pool* get_malloc_pool(void) { - static __mem_pool protopool; - static unsigned char init = 0; - if (!init) { - __init_pool_obj(&protopool); - init = 1; - } + static __mem_pool protopool; + static unsigned char init = 0; + if (!init) + { + __init_pool_obj(&protopool); + init = 1; + } - return &protopool; + return &protopool; } void allocate_from_fixed_pools(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } void deallocate_from_fixed_pools(__mem_pool_obj* pool_obj, void* ptr, unsigned long size) { - unsigned long i = 0; - FixSubBlock* p; - FixBlock* b; - FixStart* fs; - - while (size > fix_pool_sizes[i]) { - ++i; - } - - fs = &pool_obj->fix_start[i]; - p = FixSubBlock_from_pointer(ptr); - b = p->block_; - - if (b->start_ == 0 && fs->head_ != b) { - if (fs->tail_ == b) { - fs->head_ = fs->head_->prev_; - fs->tail_ = fs->tail_->prev_; - } else { - b->prev_->next_ = b->next_; - b->next_->prev_ = b->prev_; - b->next_ = fs->head_; - b->prev_ = b->next_->prev_; - b->prev_->next_ = b; - b->next_->prev_ = b; - fs->head_ = b; - } - } - - p->next_ = b->start_; - b->start_ = p; - - if (--b->n_allocated_ == 0) { - if (fs->head_ == b) { - fs->head_ = b->next_; - } - - if (fs->tail_ == b) { - fs->tail_ = b->prev_; - } - - b->prev_->next_ = b->next_; - b->next_->prev_ = b->prev_; - - if (fs->head_ == b) { - fs->head_ = 0; - } - - if (fs->tail_ == b) { - fs->tail_ = 0; - } - - deallocate_from_var_pools(pool_obj, b); - } + unsigned long i = 0; + FixSubBlock* p; + FixBlock* b; + FixStart* fs; + + while (size > fix_pool_sizes[i]) + { + ++i; + } + + fs = &pool_obj->fix_start[i]; + p = FixSubBlock_from_pointer(ptr); + b = p->block_; + + if (b->start_ == 0 && fs->head_ != b) + { + if (fs->tail_ == b) + { + fs->head_ = fs->head_->prev_; + fs->tail_ = fs->tail_->prev_; + } + else + { + b->prev_->next_ = b->next_; + b->next_->prev_ = b->prev_; + b->next_ = fs->head_; + b->prev_ = b->next_->prev_; + b->prev_->next_ = b; + b->next_->prev_ = b; + fs->head_ = b; + } + } + + p->next_ = b->start_; + b->start_ = p; + + if (--b->n_allocated_ == 0) + { + if (fs->head_ == b) + { + fs->head_ = b->next_; + } + + if (fs->tail_ == b) + { + fs->tail_ = b->prev_; + } + + b->prev_->next_ = b->next_; + b->next_->prev_ = b->prev_; + + if (fs->head_ == b) + { + fs->head_ = 0; + } + + if (fs->tail_ == b) + { + fs->tail_ = 0; + } + + deallocate_from_var_pools(pool_obj, b); + } } void __report_on_pool_heap(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } void __report_on_heap(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } void __msize(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } void __pool_alloc(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } void __pool_free(__mem_pool* pool, void* ptr) { - __mem_pool_obj* pool_obj; - unsigned long size; + __mem_pool_obj* pool_obj; + unsigned long size; - if (ptr == 0) { - return; - } + if (ptr == 0) + { + return; + } - pool_obj = (__mem_pool_obj*)pool; - size = __msize_inline(ptr); + pool_obj = (__mem_pool_obj*)pool; + size = __msize_inline(ptr); - if (size <= 68) { - deallocate_from_fixed_pools(pool_obj, ptr, size); - } else { - deallocate_from_var_pools(pool_obj, ptr); - } + if (size <= 68) + { + deallocate_from_fixed_pools(pool_obj, ptr, size); + } + else + { + deallocate_from_var_pools(pool_obj, ptr); + } } void __pool_realloc(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } void __pool_alloc_clear(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } void malloc(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } void free(void* ptr) { - __begin_critical_region(malloc_pool_access); - __pool_free(get_malloc_pool(), ptr); - __end_critical_region(malloc_pool_access); + __begin_critical_region(malloc_pool_access); + __pool_free(get_malloc_pool(), ptr); + __end_critical_region(malloc_pool_access); } void realloc(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } void calloc(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } void __pool_free_all(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } void __malloc_free_all(void) { - // UNUSED FUNCTION + // UNUSED FUNCTION } \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ansi_files.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ansi_files.c index a210e106f..84b3063ef 100644 --- a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ansi_files.c +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ansi_files.c @@ -115,40 +115,45 @@ FILE __files[4] = void __close_all() { - FILE* p = &__files[0]; - FILE* plast; + FILE* p = &__files[0]; + FILE* plast; - __begin_critical_region(stdin_access); + __begin_critical_region(stdin_access); - while (p) { - if (p->mMode.file_kind != __closed_file) { - fclose(p); - } + while (p) + { + if (p->mMode.file_kind != __closed_file) + { + fclose(p); + } - plast = p; - p = p->mNextFile; - if (plast->mIsDynamicallyAllocated) - free(plast); - else { - plast->mMode.file_kind = __unavailable_file; - if ((p != NULL) && p->mIsDynamicallyAllocated) - plast->mNextFile = nullptr; - } - } + plast = p; + p = p->mNextFile; + if (plast->mIsDynamicallyAllocated) + free(plast); + else + { + plast->mMode.file_kind = __unavailable_file; + if ((p != NULL) && p->mIsDynamicallyAllocated) + plast->mNextFile = nullptr; + } + } - __end_critical_region(stdin_access); + __end_critical_region(stdin_access); } u32 __flush_all() { - u32 retval = 0; - FILE* __stream; - __stream = &__files[0]; - while (__stream) { - if ((__stream->mMode.file_kind) && (fflush(__stream))) { - retval = -1; - } - __stream = __stream->mNextFile; - }; - return retval; + u32 retval = 0; + FILE* __stream; + __stream = &__files[0]; + while (__stream) + { + if ((__stream->mMode.file_kind) && (fflush(__stream))) + { + retval = -1; + } + __stream = __stream->mNextFile; + }; + return retval; } diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/char_io.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/char_io.c new file mode 100644 index 000000000..a960f8103 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common/char_io.c @@ -0,0 +1,115 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/char_io.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/wchar_io.h" + +// int __put_char(int c, FILE* stream) +// { +// int ret; + +// int file_kind = stream->file_mode.file_kind; +// stream->buffer_length = 0; + +// if (stream->file_state.error != 0 || file_kind == __closed_file) +// { +// return -1; +// } + +// if (file_kind == __console_file) +// { +// __stdio_atexit(); +// } + +// if (stream->file_state.io_state == __neutral && (stream->file_mode.io_mode & __write)) +// { +// if ((stream->file_mode.io_mode & __append) && fseek(stream, 0, 2) != 0) +// { +// return 0; +// } + +// stream->file_state.io_state = __writing; +// __prep_buffer(stream); +// } + +// if (stream->file_state.io_state != __writing) +// { +// stream->file_state.error = 1; +// ret = -1; +// stream->buffer_length = 0; +// } +// else if ((stream->file_mode.buffer_mode == 2 || +// stream->buffer_size == +// (unsigned int)stream->buffer_ptr - (unsigned int)stream->buffer) && +// __flush_buffer(stream, NULL) != 0) +// { +// stream->file_state.error = 1; +// ret = -1; +// stream->buffer_length = 0; +// } +// else +// { +// stream->buffer_length--; +// *stream->buffer_ptr++ = c; + +// if (stream->file_mode.buffer_mode != 2) +// { +// if ((stream->file_mode.buffer_mode == 0 || c == 10) && +// __flush_buffer(stream, NULL) != 0) +// { +// stream->file_state.error = 1; +// ret = -1; +// stream->buffer_length = 0; +// goto exit; +// } +// stream->buffer_length = 0; +// } + +// ret = c & 0xFF; +// } + +// exit: +// return ret; +// } + +// int fputs(const char* s, FILE* stream) +// { +// char c; +// int var_r3; +// unsigned long len; +// int ret = 0; + +// __begin_critical_region(stdin_access); +// while (c = *s++, c != 0) +// { +// if (fwide(stream, -1) >= 0) +// { +// var_r3 = -1; +// } +// else +// { +// len = stream->buffer_length; +// stream->buffer_length = len - 1; + +// if (len != 0) +// { +// char* buf = (char*)stream->buffer_ptr; +// stream->buffer_ptr++; + +// *buf = var_r3 = c & 0xFF; +// } +// else +// { +// var_r3 = __put_char(c, stream); +// } +// } + +// if (var_r3 == -1) +// { +// ret = -1; +// break; +// } +// } +// __end_critical_region(stdin_access); + +// return ret; +// } \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c new file mode 100644 index 000000000..1bbd7a6e3 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c @@ -0,0 +1,105 @@ + +/* @(#)e_acos.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_acos(x) + * Method : + * acos(x) = pi/2 - asin(x) + * acos(-x) = pi/2 + asin(x) + * For |x|<=0.5 + * acos(x) = pi/2 - (x + x*x^2*R(x^2)) (see asin.c) + * For x>0.5 + * acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2))) + * = 2asin(sqrt((1-x)/2)) + * = 2s + 2s*z*R(z) ...z=(1-x)/2, s=sqrt(z) + * = 2f + (2c + 2s*z*R(z)) + * where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term + * for f so that f+c ~ sqrt(z). + * For x<-0.5 + * acos(x) = pi - 2asin(sqrt((1-|x|)/2)) + * = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z) + * + * Special cases: + * if x is NaN, return x itself; + * if |x|>1, return NaN with invalid signal. + * + * Function needed: sqrt + */ + +#include "math.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +one= 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */ +pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ +pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */ +pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */ +pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */ +pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */ +pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */ +pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */ +pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */ +qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */ +qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ +qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ +qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ + +#ifdef __STDC__ + double __ieee754_acos(double x) +#else + double __ieee754_acos(x) + double x; +#endif +{ + double z,p,q,r,w,s,c,df; + int hx,ix; + hx = __HI(x); + ix = hx&0x7fffffff; + if(ix>=0x3ff00000) { /* |x| >= 1 */ + if(((ix-0x3ff00000)|__LO(x))==0) { /* |x|==1 */ + if(hx>0) return 0.0; /* acos(1) = 0 */ + else return pi+2.0*pio2_lo; /* acos(-1)= pi */ + } + return NAN; /* acos(|x|>1) is NaN */ + } + if(ix<0x3fe00000) { /* |x| < 0.5 */ + if(ix<=0x3c600000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/ + z = x*x; + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + r = p/q; + return pio2_hi - (x - (pio2_lo-x*r)); + } else if (hx<0) { /* x < -0.5 */ + z = (one+x)*0.5; + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + s = sqrt(z); + r = p/q; + w = r*s-pio2_lo; + return pi - 2.0*(s+w); + } else { /* x > 0.5 */ + z = (one-x)*0.5; + s = sqrt(z); + df = s; + __LO(df) = 0; + c = (z-df*df)/(s+df); + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + r = p/q; + w = r*s+c; + return 2.0*(df+w); + } +} \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_acos.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_acos.c new file mode 100644 index 000000000..4a127f1e4 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_acos.c @@ -0,0 +1,6 @@ +#include "fdlibm.h" + +double acos(double x) +{ + return __ieee754_acos(x); +} \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log.c b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log.c new file mode 100644 index 000000000..aab55a899 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log.c @@ -0,0 +1,7 @@ + +#include "fdlibm.h" + +double log(double x) +{ + return __ieee754_log(x); +} \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/abort_exit.c b/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/abort_exit.c index 634c65d93..4da38d45f 100644 --- a/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/abort_exit.c +++ b/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/abort_exit.c @@ -16,55 +16,62 @@ static void (*__atexit_funcs[64])(void); void abort(void) { - raise(1); - __aborting = 1; - exit(1); -} + raise(1); + __aborting = 1; + __begin_critical_region(atexit_funcs_access); -void atexit(void) -{ - // UNUSED FUNCTION -} + while (__atexit_curr_func > 0) + __atexit_funcs[--__atexit_curr_func](); -void __atexit(void) -{ - // UNUSED FUNCTION + __end_critical_region(atexit_funcs_access); + __kill_critical_regions(); + + if (__console_exit != NULL) + { + __console_exit(); + __console_exit = NULL; + } + + _ExitProcess(); } void exit(int status) { - int i; - void (**dtor)(void); - - if (!__aborting) { - __begin_critical_region(atexit_funcs_access); - __end_critical_region(atexit_funcs_access); - __destroy_global_chain(); - dtor = _dtors; - while (*dtor != NULL) { - (*dtor)(); - dtor++; - } - if (__stdio_exit != NULL) { - __stdio_exit(); - __stdio_exit = NULL; - } - } - __exit(status); -} + int i; + void (**dtor)(void); -void __exit(int status) -{ - __begin_critical_region(atexit_funcs_access); - while (__atexit_curr_func > 0) - __atexit_funcs[--__atexit_curr_func](); - __end_critical_region(atexit_funcs_access); - __kill_critical_regions(); - if (__console_exit != NULL) - { - - __console_exit(); - __console_exit = NULL; - } - _ExitProcess(); + if (!__aborting) + { + __begin_critical_region(atexit_funcs_access); + __end_critical_region(atexit_funcs_access); + __destroy_global_chain(); + + dtor = _dtors; + while (*dtor != NULL) + { + (*dtor)(); + dtor++; + } + + if (__stdio_exit != NULL) + { + __stdio_exit(); + __stdio_exit = NULL; + } + } + + __begin_critical_region(atexit_funcs_access); + while (__atexit_curr_func > 0) + __atexit_funcs[--__atexit_curr_func](); + + __end_critical_region(atexit_funcs_access); + __kill_critical_regions(); + + if (__console_exit != NULL) + { + __console_exit(); + __console_exit = NULL; + } + + _ExitProcess(); } diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/critical_regions.gamecube.c b/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/critical_regions.gamecube.c index 9cbd811b7..a339ca04c 100644 --- a/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/critical_regions.gamecube.c +++ b/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/critical_regions.gamecube.c @@ -1,10 +1,17 @@ #include "types.h" #include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" -void __init_critical_regions(void) { return; } +void __end_critical_region(int region) +{ + return; +} -void __kill_critical_regions(void) { return; } +void __begin_critical_region(int region) +{ + return; +} -void __begin_critical_region(int region) { return; } - -void __end_critical_region(int region) { return; } +void __kill_critical_regions(void) +{ + return; +} diff --git a/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/math_ppc.c b/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/math_ppc.c index ae9047d99..d8b2edb5e 100644 --- a/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/math_ppc.c +++ b/libs/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/math_ppc.c @@ -283,7 +283,6 @@ void atan2f(void) // UNUSED FUNCTION }*/ - /*void coshf(void) { // UNUSED FUNCTION diff --git a/libs/PowerPC_EABI_Support/src/Runtime/CPlusLibPPC.cp b/libs/PowerPC_EABI_Support/src/Runtime/CPlusLibPPC.cp index b9efdad8b..05e5f9fb0 100644 --- a/libs/PowerPC_EABI_Support/src/Runtime/CPlusLibPPC.cp +++ b/libs/PowerPC_EABI_Support/src/Runtime/CPlusLibPPC.cp @@ -18,24 +18,6 @@ void* __copy(char *dest, char *src, size_t size) return(dest); } -void __init_arr(void) -{ - // UNUSED FUNCTION -} - -void __new_arr(void) -{ - // UNUSED FUNCTION -} -void __del_arr(void) -{ - // UNUSED FUNCTION -} - -void __dc_arr(void) -{ - // UNUSED FUNCTION -} } diff --git a/libs/PowerPC_EABI_Support/src/Runtime/New.cp b/libs/PowerPC_EABI_Support/src/Runtime/New.cp new file mode 100644 index 000000000..e5e2d5986 --- /dev/null +++ b/libs/PowerPC_EABI_Support/src/Runtime/New.cp @@ -0,0 +1,5 @@ +#include "PowerPC_EABI_Support/Runtime/Gecko_ExceptionPPC.h" +#include "PowerPC_EABI_Support/Runtime/MWCPlusPlusLib.h" +#include "PowerPC_EABI_Support/Runtime/NMWException.h" +#include "PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h" + diff --git a/libs/PowerPC_EABI_Support/src/Runtime/__mem.c b/libs/PowerPC_EABI_Support/src/Runtime/__mem.c index 51d788a94..a9a4a5a67 100644 --- a/libs/PowerPC_EABI_Support/src/Runtime/__mem.c +++ b/libs/PowerPC_EABI_Support/src/Runtime/__mem.c @@ -1,44 +1,21 @@ #include #include -void *memcpy(void *dst, const void *src, size_t n) +void* memset(void* dst, int c, size_t n) { - u8 *__src; - u8 *__dst; - int i; - - if (src >= dst) - { - __src = ((u8 *)src) - 1; - __dst = ((u8 *)dst) - 1; - i = n + 1; - while (--i) - { - *((u8 *)++__dst) = *((u8 *)++__src); - } - return dst; - } - else - { - __src = ((u8 *)src) + n; - __dst = ((u8 *)dst) + n; - i = n + 1; - while (--i) - { - *((u8 *)--__dst) = *((u8 *)--__src); - } - return dst; - } + __fill_mem(dst, c, n); + return dst; } -void __fill_mem(void *dst, int c, size_t n) + +void __fill_mem(void* dst, int c, size_t n) { - u8 *cdest; - u32 *idest; + u8* cdest; + u32* idest; u32 i; u32 cval; cval = (u8)c; - cdest = (u8 *)dst - 1; + cdest = (u8*)dst - 1; if (n >= 32) { @@ -56,19 +33,19 @@ void __fill_mem(void *dst, int c, size_t n) cval = cval << 24 | cval << 16 | cval << 8 | cval; } - idest = (u32 *)(cdest - 3); + idest = (u32*)(cdest - 3); i = n >> 5; if (i != 0) { do { - idest[1] = cval; // 4 - idest[2] = cval; // 8 - idest[3] = cval; // c - idest[4] = cval; // 10 - idest[5] = cval; // 14 - idest[6] = cval; // 18 - idest[7] = cval; // 1c + idest[1] = cval; // 4 + idest[2] = cval; // 8 + idest[3] = cval; // c + idest[4] = cval; // 10 + idest[5] = cval; // 14 + idest[6] = cval; // 18 + idest[7] = cval; // 1c *(idest += 8) = cval; // 20 } while (--i); } @@ -83,7 +60,7 @@ void __fill_mem(void *dst, int c, size_t n) } while (--i); } - cdest = (u8 *)idest + 3; + cdest = (u8*)idest + 3; n &= 3; } if (n != 0) @@ -95,8 +72,32 @@ void __fill_mem(void *dst, int c, size_t n) } } -void *memset(void *dst, int c, size_t n) +void* memcpy(void* dst, const void* src, size_t n) { - __fill_mem(dst, c, n); - return dst; -} \ No newline at end of file + u8* __src; + u8* __dst; + int i; + + if (src >= dst) + { + __src = ((u8*)src) - 1; + __dst = ((u8*)dst) - 1; + i = n + 1; + while (--i) + { + *((u8*)++__dst) = *((u8*)++__src); + } + return dst; + } + else + { + __src = ((u8*)src) + n; + __dst = ((u8*)dst) + n; + i = n + 1; + while (--i) + { + *((u8*)--__dst) = *((u8*)--__src); + } + return dst; + } +} diff --git a/libs/PowerPC_EABI_Support/src/Runtime/global_destructor_chain.c b/libs/PowerPC_EABI_Support/src/Runtime/global_destructor_chain.c index c017fde19..b09b0fa2a 100644 --- a/libs/PowerPC_EABI_Support/src/Runtime/global_destructor_chain.c +++ b/libs/PowerPC_EABI_Support/src/Runtime/global_destructor_chain.c @@ -1,32 +1,18 @@ #include "PowerPC_EABI_Support/Runtime/global_destructor_chain.h" #include "PowerPC_EABI_Support/Runtime/MWCPlusPlusLib.h" -DestructorChain *__global_destructor_chain; - -void *__register_global_object(void *object, void *destructor, void *regmem) -{ - ((DestructorChain *)regmem)->next = __global_destructor_chain; - ((DestructorChain *)regmem)->destructor = destructor; - ((DestructorChain *)regmem)->object = object; - __global_destructor_chain = (DestructorChain *)regmem; - - return object; -} +DestructorChain* __global_destructor_chain; void __destroy_global_chain(void) { - DestructorChain *iter; + DestructorChain* iter; - while ((iter = __global_destructor_chain) != 0) - { - __global_destructor_chain = iter->next; - DTORCALL_COMPLETE(iter->destructor, iter->object); - } -} - -// unused -int __register_atexit(void (*func)(void)) -{ + while ((iter = __global_destructor_chain) != 0) + { + __global_destructor_chain = iter->next; + DTORCALL_COMPLETE(iter->destructor, iter->object); + } } -__declspec(section ".dtors") static void *const __destroy_global_chain_reference = __destroy_global_chain; +__declspec(section + ".dtors") static void* const __destroy_global_chain_reference = __destroy_global_chain; diff --git a/libs/PowerPC_EABI_Support/src/Runtime/runtime.c b/libs/PowerPC_EABI_Support/src/Runtime/runtime.c index 68cb136c6..94da236b7 100644 --- a/libs/PowerPC_EABI_Support/src/Runtime/runtime.c +++ b/libs/PowerPC_EABI_Support/src/Runtime/runtime.c @@ -147,188 +147,275 @@ static const unsigned long __constants[] = { asm unsigned long __cvt_fp2unsigned(register double d) { - nofralloc stwu r1, -16(r1)lis r4, __constants @h ori r4, r4, __constants @l li r3, 0 lfd fp0, - 0(r4)lfd fp3, 8(r4)lfd fp4, 16(r4)fcmpu cr0, fp1, fp0 fcmpu cr6, fp1, fp3 blt cr0, - @exit addi r3, r3, -1 bge cr6, @exit fcmpu cr7, fp1, fp4 fmr fp2, fp1 blt cr7, @1 fsub fp2, - fp1, fp4 @1 fctiwz fp2, fp2 stfd fp2, 8(r1)lwz r3, 12(r1)blt cr7, @exit addis r3, r3, - -0x8000 @exit : addi r1, r1, 16 blr + nofralloc; + stwu r1, -16(r1); + lis r4, __constants @h; + ori r4, r4, __constants @l; + li r3, 0; + lfd fp0, 0(r4); + lfd fp3, 8(r4); + lfd fp4, 16(r4); + fcmpu cr0, fp1, fp0; + fcmpu cr6, fp1, fp3; + blt cr0, @exit; + addi r3, r3, -1; + bge cr6, @exit; + fcmpu cr7, fp1, fp4; + fmr fp2, fp1; + blt cr7, @1; + fsub fp2, fp1, fp4; + @1; + fctiwz fp2, fp2; + stfd fp2, 8(r1); + lwz r3, 12(r1); + blt cr7, @exit; + addis r3, r3, -0x8000; + @exit:; + addi r1, r1, 16; + blr } static asm void __save_fpr(void) { - nofralloc ENTRY_SAVE_FPR(14) ENTRY_SAVE_FPR2(14) stfd fp14, - -144(save_restore_reg)ENTRY_SAVE_FPR(15) ENTRY_SAVE_FPR2(15) stfd fp15, - -136(save_restore_reg)ENTRY_SAVE_FPR(16) ENTRY_SAVE_FPR2(16) stfd fp16, - -128(save_restore_reg)ENTRY_SAVE_FPR(17) ENTRY_SAVE_FPR2(17) stfd fp17, - -120(save_restore_reg)ENTRY_SAVE_FPR(18) ENTRY_SAVE_FPR2(18) stfd fp18, - -112(save_restore_reg)ENTRY_SAVE_FPR(19) ENTRY_SAVE_FPR2(19) stfd fp19, - -104(save_restore_reg)ENTRY_SAVE_FPR(20) ENTRY_SAVE_FPR2(20) stfd fp20, - -96(save_restore_reg)ENTRY_SAVE_FPR(21) ENTRY_SAVE_FPR2(21) stfd fp21, - -88(save_restore_reg)ENTRY_SAVE_FPR(22) ENTRY_SAVE_FPR2(22) stfd fp22, - -80(save_restore_reg)ENTRY_SAVE_FPR(23) ENTRY_SAVE_FPR2(23) stfd fp23, - -72(save_restore_reg)ENTRY_SAVE_FPR(24) ENTRY_SAVE_FPR2(24) stfd fp24, - -64(save_restore_reg)ENTRY_SAVE_FPR(25) ENTRY_SAVE_FPR2(25) stfd fp25, - -56(save_restore_reg)ENTRY_SAVE_FPR(26) ENTRY_SAVE_FPR2(26) stfd fp26, - -48(save_restore_reg)ENTRY_SAVE_FPR(27) ENTRY_SAVE_FPR2(27) stfd fp27, - -40(save_restore_reg)ENTRY_SAVE_FPR(28) ENTRY_SAVE_FPR2(28) stfd fp28, - -32(save_restore_reg)ENTRY_SAVE_FPR(29) ENTRY_SAVE_FPR2(29) stfd fp29, - -24(save_restore_reg)ENTRY_SAVE_FPR(30) ENTRY_SAVE_FPR2(30) stfd fp30, - -16(save_restore_reg)ENTRY_SAVE_FPR(31) ENTRY_SAVE_FPR2(31) stfd fp31, - -8(save_restore_reg)blr + nofralloc; + ENTRY_SAVE_FPR(14) + ENTRY_SAVE_FPR2(14) + stfd fp14, -144(save_restore_reg); + ENTRY_SAVE_FPR(15) + ENTRY_SAVE_FPR2(15) + stfd fp15, -136(save_restore_reg); + ENTRY_SAVE_FPR(16); + ENTRY_SAVE_FPR2(16) stfd fp16, -128(save_restore_reg); + ENTRY_SAVE_FPR(17); + ENTRY_SAVE_FPR2(17) stfd fp17, -120(save_restore_reg); + ENTRY_SAVE_FPR(18); + ENTRY_SAVE_FPR2(18) stfd fp18, -112(save_restore_reg); + ENTRY_SAVE_FPR(19); + ENTRY_SAVE_FPR2(19) stfd fp19, -104(save_restore_reg); + ENTRY_SAVE_FPR(20); + ENTRY_SAVE_FPR2(20) stfd fp20, -96(save_restore_reg); + ENTRY_SAVE_FPR(21); + ENTRY_SAVE_FPR2(21) stfd fp21, -88(save_restore_reg); + ENTRY_SAVE_FPR(22); + ENTRY_SAVE_FPR2(22) stfd fp22, -80(save_restore_reg); + ENTRY_SAVE_FPR(23); + ENTRY_SAVE_FPR2(23) stfd fp23, -72(save_restore_reg); + ENTRY_SAVE_FPR(24); + ENTRY_SAVE_FPR2(24) stfd fp24, -64(save_restore_reg); + ENTRY_SAVE_FPR(25); + ENTRY_SAVE_FPR2(25) stfd fp25, -56(save_restore_reg); + ENTRY_SAVE_FPR(26); + ENTRY_SAVE_FPR2(26) stfd fp26, -48(save_restore_reg); + ENTRY_SAVE_FPR(27); + ENTRY_SAVE_FPR2(27) stfd fp27, -40(save_restore_reg); + ENTRY_SAVE_FPR(28); + ENTRY_SAVE_FPR2(28) stfd fp28, -32(save_restore_reg); + ENTRY_SAVE_FPR(29); + ENTRY_SAVE_FPR2(29) stfd fp29, -24(save_restore_reg); + ENTRY_SAVE_FPR(30); + ENTRY_SAVE_FPR2(30) stfd fp30, -16(save_restore_reg); + ENTRY_SAVE_FPR(31); + ENTRY_SAVE_FPR2(31) stfd fp31, -8(save_restore_reg); + blr } static asm void __restore_fpr(void) { - nofralloc ENTRY_RESTORE_FPR(14) ENTRY_RESTORE_FPR2(14) lfd fp14, - -144(save_restore_reg)ENTRY_RESTORE_FPR(15) ENTRY_RESTORE_FPR2(15) lfd fp15, - -136(save_restore_reg)ENTRY_RESTORE_FPR(16) ENTRY_RESTORE_FPR2(16) lfd fp16, - -128(save_restore_reg)ENTRY_RESTORE_FPR(17) ENTRY_RESTORE_FPR2(17) lfd fp17, - -120(save_restore_reg)ENTRY_RESTORE_FPR(18) ENTRY_RESTORE_FPR2(18) lfd fp18, - -112(save_restore_reg)ENTRY_RESTORE_FPR(19) ENTRY_RESTORE_FPR2(19) lfd fp19, - -104(save_restore_reg)ENTRY_RESTORE_FPR(20) ENTRY_RESTORE_FPR2(20) lfd fp20, - -96(save_restore_reg)ENTRY_RESTORE_FPR(21) ENTRY_RESTORE_FPR2(21) lfd fp21, - -88(save_restore_reg)ENTRY_RESTORE_FPR(22) ENTRY_RESTORE_FPR2(22) lfd fp22, - -80(save_restore_reg)ENTRY_RESTORE_FPR(23) ENTRY_RESTORE_FPR2(23) lfd fp23, - -72(save_restore_reg)ENTRY_RESTORE_FPR(24) ENTRY_RESTORE_FPR2(24) lfd fp24, - -64(save_restore_reg)ENTRY_RESTORE_FPR(25) ENTRY_RESTORE_FPR2(25) lfd fp25, - -56(save_restore_reg)ENTRY_RESTORE_FPR(26) ENTRY_RESTORE_FPR2(26) lfd fp26, - -48(save_restore_reg)ENTRY_RESTORE_FPR(27) ENTRY_RESTORE_FPR2(27) lfd fp27, - -40(save_restore_reg)ENTRY_RESTORE_FPR(28) ENTRY_RESTORE_FPR2(28) lfd fp28, - -32(save_restore_reg)ENTRY_RESTORE_FPR(29) ENTRY_RESTORE_FPR2(29) lfd fp29, - -24(save_restore_reg)ENTRY_RESTORE_FPR(30) ENTRY_RESTORE_FPR2(30) lfd fp30, - -16(save_restore_reg)ENTRY_RESTORE_FPR(31) ENTRY_RESTORE_FPR2(31) lfd fp31, - -8(save_restore_reg)blr + nofralloc; + ENTRY_RESTORE_FPR(14); + ENTRY_RESTORE_FPR2(14) lfd fp14, -144(save_restore_reg); + ENTRY_RESTORE_FPR(15); + ENTRY_RESTORE_FPR2(15) lfd fp15, -136(save_restore_reg); + ENTRY_RESTORE_FPR(16); + ENTRY_RESTORE_FPR2(16) lfd fp16, -128(save_restore_reg); + ENTRY_RESTORE_FPR(17); + ENTRY_RESTORE_FPR2(17) lfd fp17, -120(save_restore_reg); + ENTRY_RESTORE_FPR(18); + ENTRY_RESTORE_FPR2(18) lfd fp18, -112(save_restore_reg); + ENTRY_RESTORE_FPR(19); + ENTRY_RESTORE_FPR2(19) lfd fp19, -104(save_restore_reg); + ENTRY_RESTORE_FPR(20); + ENTRY_RESTORE_FPR2(20) lfd fp20, -96(save_restore_reg); + ENTRY_RESTORE_FPR(21); + ENTRY_RESTORE_FPR2(21) lfd fp21, -88(save_restore_reg); + ENTRY_RESTORE_FPR(22); + ENTRY_RESTORE_FPR2(22) lfd fp22, -80(save_restore_reg); + ENTRY_RESTORE_FPR(23); + ENTRY_RESTORE_FPR2(23) lfd fp23, -72(save_restore_reg); + ENTRY_RESTORE_FPR(24); + ENTRY_RESTORE_FPR2(24) lfd fp24, -64(save_restore_reg); + ENTRY_RESTORE_FPR(25); + ENTRY_RESTORE_FPR2(25) lfd fp25, -56(save_restore_reg); + ENTRY_RESTORE_FPR(26); + ENTRY_RESTORE_FPR2(26) lfd fp26, -48(save_restore_reg); + ENTRY_RESTORE_FPR(27); + ENTRY_RESTORE_FPR2(27) lfd fp27, -40(save_restore_reg); + ENTRY_RESTORE_FPR(28); + ENTRY_RESTORE_FPR2(28) lfd fp28, -32(save_restore_reg); + ENTRY_RESTORE_FPR(29); + ENTRY_RESTORE_FPR2(29) lfd fp29, -24(save_restore_reg); + ENTRY_RESTORE_FPR(30); + ENTRY_RESTORE_FPR2(30) lfd fp30, -16(save_restore_reg); + ENTRY_RESTORE_FPR(31); + ENTRY_RESTORE_FPR2(31) lfd fp31, -8(save_restore_reg); + blr } static asm void __save_gpr(void) { - nofralloc ENTRY_SAVE_GPR(14) stw r14, -72(save_restore_reg)ENTRY_SAVE_GPR(15) stw r15, - -68(save_restore_reg)ENTRY_SAVE_GPR(16) stw r16, - -64(save_restore_reg)ENTRY_SAVE_GPR(17) stw r17, - -60(save_restore_reg)ENTRY_SAVE_GPR(18) stw r18, - -56(save_restore_reg)ENTRY_SAVE_GPR(19) stw r19, - -52(save_restore_reg)ENTRY_SAVE_GPR(20) stw r20, - -48(save_restore_reg)ENTRY_SAVE_GPR(21) stw r21, - -44(save_restore_reg)ENTRY_SAVE_GPR(22) stw r22, - -40(save_restore_reg)ENTRY_SAVE_GPR(23) stw r23, - -36(save_restore_reg)ENTRY_SAVE_GPR(24) stw r24, - -32(save_restore_reg)ENTRY_SAVE_GPR(25) stw r25, - -28(save_restore_reg)ENTRY_SAVE_GPR(26) stw r26, - -24(save_restore_reg)ENTRY_SAVE_GPR(27) stw r27, - -20(save_restore_reg)ENTRY_SAVE_GPR(28) stw r28, - -16(save_restore_reg)ENTRY_SAVE_GPR(29) stw r29, - -12(save_restore_reg)ENTRY_SAVE_GPR(30) stw r30, - -8(save_restore_reg)ENTRY_SAVE_GPR(31) stw r31, -4(save_restore_reg)blr + nofralloc; + ENTRY_SAVE_GPR(14); + stw r14, -72(save_restore_reg); + ENTRY_SAVE_GPR(15); + stw r15, -68(save_restore_reg); + ENTRY_SAVE_GPR(16); + stw r16, -64(save_restore_reg); + ENTRY_SAVE_GPR(17); + stw r17, -60(save_restore_reg); + ENTRY_SAVE_GPR(18); + stw r18, -56(save_restore_reg); + ENTRY_SAVE_GPR(19); + stw r19, -52(save_restore_reg); + ENTRY_SAVE_GPR(20); + stw r20, -48(save_restore_reg); + ENTRY_SAVE_GPR(21); + stw r21, -44(save_restore_reg); + ENTRY_SAVE_GPR(22); + stw r22, -40(save_restore_reg); + ENTRY_SAVE_GPR(23); + stw r23, -36(save_restore_reg); + ENTRY_SAVE_GPR(24); + stw r24, -32(save_restore_reg); + ENTRY_SAVE_GPR(25); + stw r25, -28(save_restore_reg); + ENTRY_SAVE_GPR(26); + stw r26, -24(save_restore_reg); + ENTRY_SAVE_GPR(27); + stw r27, -20(save_restore_reg); + ENTRY_SAVE_GPR(28); + stw r28, -16(save_restore_reg); + ENTRY_SAVE_GPR(29); + stw r29, -12(save_restore_reg); + ENTRY_SAVE_GPR(30); + stw r30, -8(save_restore_reg); + ENTRY_SAVE_GPR(31); + stw r31, -4(save_restore_reg); + blr } static asm void __restore_gpr(void) { - nofralloc ENTRY_RESTORE_GPR(14) lwz r14, -72(save_restore_reg)ENTRY_RESTORE_GPR(15) lwz r15, - -68(save_restore_reg)ENTRY_RESTORE_GPR(16) lwz r16, - -64(save_restore_reg)ENTRY_RESTORE_GPR(17) lwz r17, - -60(save_restore_reg)ENTRY_RESTORE_GPR(18) lwz r18, - -56(save_restore_reg)ENTRY_RESTORE_GPR(19) lwz r19, - -52(save_restore_reg)ENTRY_RESTORE_GPR(20) lwz r20, - -48(save_restore_reg)ENTRY_RESTORE_GPR(21) lwz r21, - -44(save_restore_reg)ENTRY_RESTORE_GPR(22) lwz r22, - -40(save_restore_reg)ENTRY_RESTORE_GPR(23) lwz r23, - -36(save_restore_reg)ENTRY_RESTORE_GPR(24) lwz r24, - -32(save_restore_reg)ENTRY_RESTORE_GPR(25) lwz r25, - -28(save_restore_reg)ENTRY_RESTORE_GPR(26) lwz r26, - -24(save_restore_reg)ENTRY_RESTORE_GPR(27) lwz r27, - -20(save_restore_reg)ENTRY_RESTORE_GPR(28) lwz r28, - -16(save_restore_reg)ENTRY_RESTORE_GPR(29) lwz r29, - -12(save_restore_reg)ENTRY_RESTORE_GPR(30) lwz r30, - -8(save_restore_reg)ENTRY_RESTORE_GPR(31) lwz r31, -4(save_restore_reg)blr + nofralloc; + ENTRY_RESTORE_GPR(14); + lwz r14, -72(save_restore_reg); + ENTRY_RESTORE_GPR(15); + lwz r15, -68(save_restore_reg); + ENTRY_RESTORE_GPR(16); + lwz r16, -64(save_restore_reg); + ENTRY_RESTORE_GPR(17); + lwz r17, -60(save_restore_reg); + ENTRY_RESTORE_GPR(18); + lwz r18, -56(save_restore_reg); + ENTRY_RESTORE_GPR(19); + lwz r19, -52(save_restore_reg); + ENTRY_RESTORE_GPR(20); + lwz r20, -48(save_restore_reg); + ENTRY_RESTORE_GPR(21); + lwz r21, -44(save_restore_reg); + ENTRY_RESTORE_GPR(22); + lwz r22, -40(save_restore_reg); + ENTRY_RESTORE_GPR(23); + lwz r23, -36(save_restore_reg); + ENTRY_RESTORE_GPR(24); + lwz r24, -32(save_restore_reg); + ENTRY_RESTORE_GPR(25); + lwz r25, -28(save_restore_reg); + ENTRY_RESTORE_GPR(26); + lwz r26, -24(save_restore_reg); + ENTRY_RESTORE_GPR(27); + lwz r27, -20(save_restore_reg); + ENTRY_RESTORE_GPR(28); + lwz r28, -16(save_restore_reg); + ENTRY_RESTORE_GPR(29); + lwz r29, -12(save_restore_reg); + ENTRY_RESTORE_GPR(30); + lwz r30, -8(save_restore_reg); + ENTRY_RESTORE_GPR(31); + lwz r31, -4(save_restore_reg); + blr } asm void __div2u(void) { - nofralloc cmpwi cr0, r3, 0 cntlzw r0, r3 cntlzw r9, r4 bne cr0, lab1 addi r0, r9, - 32 lab1 : cmpwi cr0, - r5, - 0 cntlzw r9, - r5 cntlzw r10, - r6 bne cr0, - lab2 addi r9, - r10, - 32 lab2 : cmpw cr0, - r0, - r9 subfic r10, - r0, - 64 bgt cr0, - lab9 addi r9, - r9, - 1 subfic r9, - r9, - 64 add r0, - r0, - r9 subf r9, - r9, - r10 mtctr r9 cmpwi cr0, - r9, - 32 addi r7, - r9, - -32 blt cr0, - lab3 srw r8, - r3, - r7 li r7, - 0 b lab4 lab3 : srw r8, - r4, - r9 subfic r7, - r9, - 32 slw r7, - r3, - r7 or r8, - r8, - r7 srw r7, - r3, - r9 lab4 : cmpwi cr0, - r0, - 32 addic r9, - r0, - -32 blt cr0, - lab5 slw r3, - r4, - r9 li r4, - 0 b lab6 lab5 : slw r3, - r3, - r0 subfic r9, - r0, - 32 srw r9, - r4, - r9 or r3, - r3, - r9 slw r4, - r4, - r0 lab6 : li r10, - -1 addic r7, - r7, - 0 lab7 - : adde r4, - r4, - r4 adde r3, - r3, - r3 adde r8, - r8, - r8 adde r7, - r7, - r7 subfc r0, - r6, - r8 subfe.r9, - r5, - r7 blt cr0, - lab8 mr r8, - r0 mr r7, - r9 addic r0, - r10, - 1 lab8 : bdnz lab7 adde r4, - r4, - r4 adde r3, - r3, - r3 blr lab9 : li r4, - 0 li r3, - 0 blr + nofralloc; + cmpwi cr0, r3, 0; + cntlzw r0, r3; + cntlzw r9, r4; + bne cr0, lab1; + addi r0, r9, 32; +lab1:; + cmpwi cr0, r5, 0; + cntlzw r9, r5; + cntlzw r10, r6; + bne cr0, lab2; + addi r9, r10, 32; +lab2:; + cmpw cr0, r0, r9; + subfic r10, r0, 64; + bgt cr0, lab9; + addi r9, r9, 1; + subfic r9, r9, 64; + add r0, r0, r9; + subf r9, r9, r10; + mtctr r9; + cmpwi cr0, r9, 32; + addi r7, r9, -32; + blt cr0, lab3; + srw r8, r3, r7; + li r7, 0; + b lab4; +lab3:; + srw r8, r4, r9; + subfic r7, r9, 32; + slw r7, r3, r7; + or r8, r8, r7; + srw r7, r3, r9; +lab4:; + cmpwi cr0, r0, 32; + addic r9, r0, -32; + blt cr0, lab5; + slw r3, r4, r9; + li r4, 0; + b lab6; +lab5:; + slw r3, r3, r0; + subfic r9, r0, 32; + srw r9, r4, r9; + or r3, r3, r9; + slw r4, r4, r0; +lab6:; + li r10, -1; + addic r7, r7, 0; +lab7: + adde r4, r4, r4; + adde r3, r3, r3; + adde r8, r8, r8; + adde r7, r7, r7; + subfc r0, r6, r8; + subfe.r9, r5, r7; + blt cr0, lab8; + mr r8, r0; + mr r7, r9; + addic r0, r10, 1; +lab8:; + bdnz lab7; + adde r4, r4, r4; + adde r3, r3, r3; + blr; +lab9:; + li r4, 0; + li r3, 0; + blr } #pragma push @@ -336,123 +423,98 @@ asm void __div2u(void) #pragma optimizewithasm off asm void __div2i(void) { - nofralloc stwu r1, -16(r1)rlwinm.r9, r3, 0, 0, 0 beq cr0, positive1 subfic r4, r4, 0 subfze r3, - r3 positive1 : stw r9, - 8(r1)rlwinm.r10, - r5, - 0, - 0, - 0 beq cr0, - positive2 subfic r6, - r6, - 0 subfze r5, - r5 positive2 : stw r10, - 12(r1)cmpwi cr0, - r3, - 0 cntlzw r0, - r3 cntlzw r9, - r4 bne cr0, - lab1 addi r0, - r9, - 32 lab1 : cmpwi cr0, - r5, - 0 cntlzw r9, - r5 cntlzw r10, - r6 bne cr0, - lab2 addi r9, - r10, - 32 lab2 : cmpw cr0, - r0, - r9 subfic r10, - r0, - 64 bgt cr0, - lab9 addi r9, - r9, - 1 subfic r9, - r9, - 64 add r0, - r0, - r9 subf r9, - r9, - r10 mtctr r9 cmpwi cr0, - r9, - 32 addi r7, - r9, - -32 blt cr0, - lab3 srw r8, - r3, - r7 li r7, - 0 b lab4 lab3 : srw r8, - r4, - r9 subfic r7, - r9, - 32 slw r7, - r3, - r7 or r8, - r8, - r7 srw r7, - r3, - r9 lab4 : cmpwi cr0, - r0, - 32 addic r9, - r0, - -32 blt cr0, - lab5 slw r3, - r4, - r9 li r4, - 0 b lab6 lab5 - : slw r3, - r3, - r0 subfic r9, - r0, - 32 srw r9, - r4, - r9 or r3, - r3, - r9 slw r4, - r4, - r0 lab6 : li r10, - -1 addic r7, - r7, - 0 lab7 : adde r4, - r4, - r4 adde r3, - r3, - r3 adde r8, - r8, - r8 adde r7, - r7, - r7 subfc r0, - r6, - r8 subfe.r9, - r5, - r7 blt cr0, - lab8 mr r8, - r0 mr r7, - r9 addic r0, - r10, - 1 lab8 : bdnz lab7 adde r4, - r4, - r4 adde r3, - r3, - r3 lwz r9, - 8(r1)lwz r10, - 12(r1) xor.r7, - r9, - r10 beq func_end cmpwi cr0, - r9, - 0 subfic r4, - r4, - 0 subfze r3, - r3 - - no_adjust : b func_end - - lab9 : li r4, - 0 li r3, - 0 func_end : addi r1, - r1, - 16 blr + nofralloc; + stwu r1, -16(r1); + rlwinm.r9, r3, 0, 0, 0; + beq cr0, positive1; + subfic r4, r4, 0; + subfze r3, r3; +positive1:; + stw r9, 8(r1); + rlwinm.r10, r5, 0, 0, 0; + beq cr0, positive2; + subfic r6, r6, 0; + subfze r5, r5; +positive2:; + stw r10, 12(r1); + cmpwi cr0, r3, 0; + cntlzw r0, r3; + cntlzw r9, r4; + bne cr0, lab1; + addi r0, r9, 32; +lab1:; + cmpwi cr0, r5, 0; + cntlzw r9, r5; + cntlzw r10, r6; + bne cr0, lab2; + addi r9, r10, 32; +lab2:; + cmpw cr0, r0, r9; + subfic r10, r0, 64; + bgt cr0, lab9; + addi r9, r9, 1; + subfic r9, r9, 64; + add r0, r0, r9; + subf r9, r9, r10; + mtctr r9; + cmpwi cr0, r9, 32; + addi r7, r9, -32; + blt cr0, lab3; + srw r8, r3, r7; + li r7, 0; + b lab4; +lab3:; + srw r8, r4, r9; + subfic r7, r9, 32; + slw r7, r3, r7; + or r8, r8, r7; + srw r7, r3, r9; +lab4:; + cmpwi cr0, r0, 32; + addic r9, r0, -32; + blt cr0, lab5; + slw r3, r4, r9; + li r4, 0; + b lab6; +lab5:; + slw r3, r3, r0; + subfic r9, r0, 32; + srw r9, r4, r9; + or r3, r3, r9; + slw r4, r4, r0; +lab6:; + li r10, -1; + addic r7, r7, 0; +lab7:; + adde r4, r4, r4; + adde r3, r3, r3; + adde r8, r8, r8; + adde r7, r7, r7; + subfc r0, r6, r8; + subfe.r9, r5, r7; + blt cr0, lab8; + mr r8, r0; + mr r7, r9; + addic r0, r10, 1; +lab8:; + bdnz lab7; + adde r4, r4, r4; + adde r3, r3, r3; + lwz r9, 8(r1); + lwz r10, 12(r1); + xor.r7, r9, r10; + beq func_end; + cmpwi cr0, r9, 0; + subfic r4, r4, 0; + subfze r3, r3; +no_adjust: + b func_end; +lab9:; + li r4, 0; + li r3, 0; +func_end:; + addi r1, r1, 16; + blr } #pragma pop @@ -461,86 +523,73 @@ asm void __div2i(void) #pragma optimizewithasm off asm void __mod2u(void) { - nofralloc cmpwi cr0, r3, 0 cntlzw r0, r3 cntlzw r9, r4 bne cr0, lab1 addi r0, r9, - 32 lab1 : cmpwi cr0, - r5, - 0 cntlzw r9, - r5 cntlzw r10, - r6 bne cr0, - lab2 addi r9, - r10, - 32 lab2 : cmpw cr0, - r0, - r9 subfic r10, - r0, - 64 bgtlr cr0 addi r9, - r9, - 1 subfic r9, - r9, - 64 add r0, - r0, - r9 subf r9, - r9, - r10 mtctr r9 cmpwi cr0, - r9, - 32 addi r7, - r9, - -32 blt cr0, - lab3 srw r8, - r3, - r7 li r7, - 0 b lab4 lab3 : srw r8, - r4, - r9 subfic r7, - r9, - 32 slw r7, - r3, - r7 or r8, - r8, - r7 srw r7, - r3, - r9 lab4 : cmpwi cr0, - r0, - 32 addic r9, - r0, - -32 blt cr0, - lab5 slw r3, - r4, - r9 li r4, - 0 b lab6 lab5 : slw r3, - r3, - r0 subfic r9, - r0, - 32 srw r9, - r4, - r9 or r3, - r3, - r9 slw r4, - r4, - r0 lab6 : li r10, - -1 addic r7, - r7, - 0 lab7 - : adde r4, - r4, - r4 adde r3, - r3, - r3 adde r8, - r8, - r8 adde r7, - r7, - r7 subfc r0, - r6, - r8 subfe.r9, - r5, - r7 blt cr0, - lab8 mr r8, - r0 mr r7, - r9 addic r0, - r10, - 1 lab8 : bdnz lab7 mr r4, - r8 mr r3, - r7 blr lab9 : blr + nofralloc; + cmpwi cr0, r3, 0; + cntlzw r0, r3; + cntlzw r9, r4; + bne cr0, lab1; + addi r0, r9, 32; +lab1:; + cmpwi cr0, r5, 0; + cntlzw r9, r5; + cntlzw r10, r6; + bne cr0, lab2; + addi r9, r10, 32; +lab2:; + cmpw cr0, r0, r9; + subfic r10, r0, 64; + bgtlr cr0; + addi r9, r9, 1; + subfic r9, r9, 64; + add r0, r0, r9; + subf r9, r9, r10; + mtctr r9; + cmpwi cr0, r9, 32; + addi r7, r9, -32; + blt cr0, lab3; + srw r8, r3, r7; + li r7, 0; + b lab4; +lab3:; + srw r8, r4, r9; + subfic r7, r9, 32; + slw r7, r3, r7; + or r8, r8, r7; + srw r7, r3, r9; +lab4:; + cmpwi cr0, r0, 32; + addic r9, r0, -32; + blt cr0, lab5; + slw r3, r4, r9; + li r4, 0; + b lab6; +lab5:; + slw r3, r3, r0; + subfic r9, r0, 32; + srw r9, r4, r9; + or r3, r3, r9; + slw r4, r4, r0; +lab6:; + li r10, -1; + addic r7, r7, 0; +lab7:; + adde r4, r4, r4; + adde r3, r3, r3; + adde r8, r8, r8; + adde r7, r7, r7; + subfc r0, r6, r8; + subfe.r9, r5, r7; + blt cr0, lab8; + mr r8, r0; + mr r7, r9; + addic r0, r10, 1; +lab8:; + bdnz lab7; + mr r4, r8; + mr r3, r7; + blr; +lab9:; + blr } #pragma pop @@ -551,124 +600,131 @@ asm void __mod2i(void) { nofralloc - cmpwi cr7, - r3, 0 bge cr7, positive1 subfic r4, r4, 0 subfze r3, - r3 positive1 : cmpwi cr0, - r5, - 0 bge cr0, - positive2 subfic r6, - r6, - 0 subfze r5, - r5 positive2 : cmpwi cr0, - r3, - 0 cntlzw r0, - r3 cntlzw r9, - r4 bne cr0, - lab1 addi r0, - r9, - 32 lab1 : cmpwi cr0, - r5, - 0 cntlzw r9, - r5 cntlzw r10, - r6 bne cr0, - lab2 addi r9, - r10, - 32 lab2 : cmpw cr0, - r0, - r9 subfic r10, - r0, - 64 bgt cr0, - lab9 addi r9, - r9, - 1 subfic r9, - r9, - 64 add r0, - r0, - r9 subf r9, - r9, - r10 mtctr r9 cmpwi cr0, - r9, - 32 addi r7, - r9, - -32 blt cr0, - lab3 srw r8, - r3, - r7 li r7, - 0 b lab4 lab3 : srw r8, - r4, - r9 subfic r7, - r9, - 32 slw r7, - r3, - r7 or r8, - r8, - r7 srw r7, - r3, - r9 lab4 : cmpwi cr0, - r0, - 32 addic r9, - r0, - -32 blt cr0, - lab5 slw r3, - r4, - r9 li r4, - 0 b lab6 lab5 - : slw r3, - r3, - r0 subfic r9, - r0, - 32 srw r9, - r4, - r9 or r3, - r3, - r9 slw r4, - r4, - r0 lab6 : li r10, - -1 addic r7, - r7, - 0 lab7 : adde r4, - r4, - r4 adde r3, - r3, - r3 adde r8, - r8, - r8 adde r7, - r7, - r7 subfc r0, - r6, - r8 subfe.r9, - r5, - r7 blt cr0, - lab8 mr r8, - r0 mr r7, - r9 addic r0, - r10, - 1 lab8 : bdnz lab7 mr r4, - r8 mr r3, - r7 lab9 : bgelr cr7 subfic r4, - r4, - 0 subfze r3, - r3 no_adjust : blr + ; + cmpwi cr7, r3, 0; + bge cr7, positive1; + subfic r4, r4, 0; + subfze r3, r3; +positive1:; + cmpwi cr0, r5, 0; + bge cr0, positive2; + subfic r6, r6, 0; + subfze r5, r5; +positive2:; + cmpwi cr0, r3, 0; + cntlzw r0, r3; + cntlzw r9, r4; + bne cr0, lab1; + addi r0, r9, 32; +lab1:; + cmpwi cr0, r5, 0; + cntlzw r9, r5; + cntlzw r10, r6; + bne cr0, lab2; + addi r9, r10, 32; +lab2:; + cmpw cr0, r0, r9; + subfic r10, r0, 64; + bgt cr0, lab9; + addi r9, r9, 1; + subfic r9, r9, 64; + add r0, r0, r9; + subf r9, r9, r10; + mtctr r9; + cmpwi cr0, r9, 32; + addi r7, r9, -32; + blt cr0, lab3; + srw r8, r3, r7; + li r7, 0; + b lab4; +lab3:; + srw r8, r4, r9; + subfic r7, r9, 32; + slw r7, r3, r7; + or r8, r8, r7; + srw r7, r3, r9; +lab4:; + cmpwi cr0, r0, 32; + addic r9, r0, -32; + blt cr0, lab5; + slw r3, r4, r9; + li r4, 0; + b lab6; +lab5:; + slw r3, r3, r0; + subfic r9, r0, 32; + srw r9, r4, r9; + or r3, r3, r9; + slw r4, r4, r0; +lab6:; + li r10, -1; + addic r7, r7, 0; +lab7:; + adde r4, r4, r4; + adde r3, r3, r3; + adde r8, r8, r8; + adde r7, r7, r7; + subfc r0, r6, r8; + subfe.r9, r5, r7; + blt cr0, lab8; + mr r8, r0; + mr r7, r9; + addic r0, r10, 1; +lab8:; + bdnz lab7; + mr r4, r8; + mr r3, r7; +lab9:; + bgelr cr7; + subfic r4, r4, 0; + subfze r3, r3; +no_adjust:; + blr } #pragma pop asm void __shl2i(void) { - nofralloc subfic r8, r5, 32 subic r9, r5, 32 slw r3, r3, r5 srw r10, r4, r8 or r3, r3, - r10 slw r10, r4, r9 or r3, r3, r10 slw r4, r4, r5 blr + nofralloc; + subfic r8, r5, 32; + subic r9, r5, 32; + slw r3, r3, r5; + srw r10, r4, r8; + or r3, r3, r10; + slw r10, r4, r9; + or r3, r3, r10; + slw r4, r4, r5; + blr } //unused asm void __shr2u(void) { - nofralloc subfic r8, r5, 32 subic r9, r5, 32 srw r4, r4, r5 slw r10, r3, r8 or r4, r4, - r10 srw r10, r3, r9 or r4, r4, r10 srw r3, r3, r5 blr + nofralloc; + subfic r8, r5, 32; + subic r9, r5, 32; + srw r4, r4, r5; + slw r10, r3, r8; + or r4, r4, r10; + srw r10, r3, r9; + or r4, r4, r10; + srw r3, r3, r5; + blr } asm void __shr2i(void) { - subfic r8, r5, 0x20 addic.r9, r5, -0x20 srw r4, r4, r5 slw r10, r3, r8 or r4, r4, r10 sraw r10, - r3, r9 ble L_802BA610 or r4, r4, r10 L_802BA610 : sraw r3, r3, r5 blr + subfic r8, r5, 0x20; + addic.r9, r5, -0x20; + srw r4, r4, r5; + slw r10, r3, r8; + or r4, r4, r10; + sraw r10, r3, r9; + ble L_802BA610; + or r4, r4, r10; +L_802BA610:; + sraw r3, r3, r5; + blr } asm void __cvt_sll_dbl(void) @@ -733,38 +789,56 @@ asm void __cvt_ull_dbl(void) asm void __cvt_sll_flt(void) { - stwu r1, -0x10(r1)clrrwi.r5, r3, 31 beq L_802BA62C subfic r4, r4, 0x0 subfze r3, - r3 L_802BA62C : or.r7, r3, r4 li r6, 0x0 beq L_802BA6B4 cntlzw r7, r3 cntlzw r8, - r4 extlwi r9, r7, 5, 26 srawi r9, r9, 31 and r9, r9, r8 add r7, r7, r9 subfic r8, r7, - 0x20 addic r9, r7, -0x20 slw r3, r3, r7 srw r10, r4, r8 or r3, r3, r10 slw r10, r4, - r9 or r3, r3, r10 slw r4, r4, r7 subf r6, r7, r6 clrlwi r7, r4, 21 cmpwi r7, 0x400 addi r6, - r6, 0x43e blt L_802BA69C bgt L_802BA690 rlwinm.r7, r4, 0, 20, - 20 beq L_802BA69C L_802BA690 : addic r4, - r4, - 0x800 addze r3, - r3 addze r6, - r6 L_802BA69C : rotrwi r4, - r4, - 11 rlwimi r4, - r3, - 21, - 0, - 10 extrwi r3, - r3, - 20, - 1 slwi r6, - r6, - 20 or r3, - r6, - r3 or r3, - r5, - r3 L_802BA6B4 : stw r3, - 0x8(r1)stw r4, - 0xc(r1)lfd f1, - 0x8(r1)frsp f1, - f1 addi r1, - r1, - 0x10 blr + stwu r1, -0x10(r1); + clrrwi.r5, r3, 31; + beq L_802BA62C; + subfic r4, r4, 0x0; + subfze r3, r3; +L_802BA62C:; + or.r7, r3, r4; + li r6, 0x0; + beq L_802BA6B4; + cntlzw r7, r3; + cntlzw r8, r4; + extlwi r9, r7, 5, 26; + srawi r9, r9, 31; + and r9, r9, r8; + add r7, r7, r9; + subfic r8, r7, 0x20; + addic r9, r7, -0x20; + slw r3, r3, r7; + srw r10, r4, r8; + or r3, r3, r10; + slw r10, r4, r9; + or r3, r3, r10; + slw r4, r4, r7; + subf r6, r7, r6; + clrlwi r7, r4, 21; + cmpwi r7, 0x400; + addi r6, r6, 0x43e; + blt L_802BA69C; + bgt L_802BA690; + rlwinm.r7, r4, 0, 20, 20; + beq L_802BA69C; +L_802BA690:; + addic r4, r4, 0x800; + addze r3, r3; + addze r6, r6; +L_802BA69C:; + rotrwi r4, r4, 11; + rlwimi r4, r3, 21, 0, 10; + extrwi r3, r3, 20, 1; + slwi r6, r6, 20; + or r3, r6, r3; + or r3, r5, r3; +L_802BA6B4:; + stw r3, 0x8(r1); + stw r4, 0xc(r1); + lfd f1, 0x8(r1); + frsp f1, f1; + addi r1, r1, 0x10; + frfree; // Build error said to add this + blr } //unused @@ -775,144 +849,121 @@ asm void __cvt_ull_flt(void) //unused asm void __cvt_dbl_usll(void) { - nofralloc stwu r1, -16(r1)stfd f1, 8(r1)lwz r3, 8(r1)lwz r4, 12(r1)rlwinm r5, r3, 12, 21, - 31 cmpli cr0, 0, r5, 1023 bge cr0, not_fraction li r3, 0 li r4, - 0 b func_end not_fraction : mr r6, - r3 rlwinm r3, - r3, - 0, - 12, - 31 oris r3, - r3, - 0x0010 addi r5, - r5, - -1075 cmpwi cr0, - r5, - 0 bge cr0, - left neg r5, - r5 subfic r8, - r5, - 32 subic r9, - r5, - 32 srw r4, - r4, - r5 slw r10, - r3, - r8 or r4, - r4, - r10 srw r10, - r3, - r9 or r4, - r4, - r10 srw r3, - r3, - r5 b around left : cmpwi cr0, - r5, - 10 ble + no_overflow rlwinm.r6, - r6, - 0, - 0, - 0 beq cr0, - max_positive lis r3, - 0x8000 li r4, - 0 b func_end max_positive - : lis r3, - 0x7FFF ori r3, - r3, - 0xFFFF li r4, - -1 b func_end no_overflow : subfic r8, - r5, - 32 subic r9, - r5, - 32 slw r3, - r3, - r5 srw r10, - r4, - r8 or r3, - r3, - r10 slw r10, - r4, - r9 or r3, - r3, - r10 slw r4, - r4, - r5 around : rlwinm.r6, - r6, - 0, - 0, - 0 beq cr0, - positive subfic r4, - r4, - 0 subfze r3, - r3 positive : func_end : addi r1, - r1, - 16 blr + nofralloc; + stwu r1, -16(r1); + stfd f1, 8(r1); + lwz r3, 8(r1); + lwz r4, 12(r1); + rlwinm r5, r3, 12, 21, 31; + cmpli cr0, 0, r5, 1023; + bge cr0, not_fraction; + li r3, 0; + li r4, 0; + b func_end; +not_fraction:; + mr r6, r3; + rlwinm r3, r3, 0, 12, 31; + oris r3, r3, 0x0010; + addi r5, r5, -1075; + cmpwi cr0, r5, 0; + bge cr0, left; + neg r5, r5; + subfic r8, r5, 32; + subic r9, r5, 32; + srw r4, r4, r5; + slw r10, r3, r8; + or r4, r4, r10; + srw r10, r3, r9; + or r4, r4, r10; + srw r3, r3, r5; + b around; +left:; + cmpwi cr0, r5, 10; + ble + no_overflow; + rlwinm.r6, r6, 0, 0, 0; + beq cr0, max_positive; + lis r3, 0x8000; + li r4, 0; + b func_end; +max_positive:; + lis r3, 0x7FFF; + ori r3, r3, 0xFFFF; + li r4, -1; + b func_end; +no_overflow:; + subfic r8, r5, 32; + subic r9, r5, 32; + slw r3, r3, r5; + srw r10, r4, r8; + or r3, r3, r10; + slw r10, r4, r9; + or r3, r3, r10; + slw r4, r4, r5; +around:; + rlwinm.r6, r6, 0, 0, 0; + beq cr0, positive; + subfic r4, r4, 0; + subfze r3, r3; +positive: +func_end:; + addi r1, r1, 16; + blr } void __cvt_dbl_ull(void) { - nofralloc stwu r1, -0x10(r1)stfd f1, 8(r1)lwz r3, 8(r1)lwz r4, 0xC(r1)extrwi r5, r3, 11, - 1 cmplwi r5, - 0x3FF bge loc_80518FB4 - - loc_80518FA8 : li r3, - 0 li r4, - 0 b end - - loc_80518FB4 : clrrwi.r6, - r3, - 31 bne loc_80518FA8 clrlwi r3, - r3, - 12 oris r3, - r3, - 0x10 addi r5, - r5, - -0x433 cmpwi r5, - 0 bge loc_80518FF8 neg r5, - r5 subfic r8, - r5, - 0x20 addic r9, - r5, - -0x20 srw r4, - r4, - r5 slw r10, - r3, - r8 or r4, - r4, - r10 srw r10, - r3, - r9 or r4, - r4, - r10 srw r3, - r3, - r5 b end - - loc_80518FF8 : cmpwi r5, - 0xB ble + loc_8051900C li r3, - -1 li r4, - -1 b end - - loc_8051900C : subfic r8, - r5, - 0x20 addic r9, - r5, - -0x20 slw r3, - r3, - r5 srw r10, - r4, - r8 or r3, - r3, - r10 slw r10, - r4, - r9 or r3, - r3, - r10 slw r4, - r4, - r5 - - end : addi r1, - r1, - 0x10 blr + nofralloc; + stwu r1, -0x10(r1); + stfd f1, 8(r1); + lwz r3, 8(r1); + lwz r4, 0xC(r1); + extrwi r5, r3, 11, 1; + cmplwi r5, 0x3FF; + bge loc_80518FB4 + + loc_80518FA8:; + li r3, 0; + li r4, 0; + b end + + loc_80518FB4:; + clrrwi.r6, r3, 31; + bne loc_80518FA8; + clrlwi r3, r3, 12; + oris r3, r3, 0x10; + addi r5, r5, -0x433; + cmpwi r5, 0; + bge loc_80518FF8; + neg r5, r5; + subfic r8, r5, 0x20; + addic r9, r5, -0x20; + srw r4, r4, r5; + slw r10, r3, r8; + or r4, r4, r10; + srw r10, r3, r9; + or r4, r4, r10; + srw r3, r3, r5; + b end + + loc_80518FF8:; + cmpwi r5, 0xB; + ble + loc_8051900C; + li r3, -1; + li r4, -1; + b end + + loc_8051900C:; + subfic r8, r5, 0x20; + addic r9, r5, -0x20; + slw r3, r3, r5; + srw r10, r4, r8; + or r3, r3, r10; + slw r10, r4, r9; + or r3, r3, r10; + slw r4, r4, r5; +end:; + addi r1, r1, 0x10; + blr } #ifdef __cplusplus diff --git a/libs/PowerPC_EABI_Support/src/runtime3/READ_ME.txt b/libs/PowerPC_EABI_Support/src/runtime3/READ_ME.txt deleted file mode 100644 index b2a060cb8..000000000 --- a/libs/PowerPC_EABI_Support/src/runtime3/READ_ME.txt +++ /dev/null @@ -1,6 +0,0 @@ -These files are files that have issues that need to be fixed before the file can be -added back into the "Runtime" folder. - -These are outside of the scope of what I am aiming to do at the moment. - -- Colin \ No newline at end of file diff --git a/libs/PowerPC_EABI_Support/src/runtime3/runtime.c b/libs/PowerPC_EABI_Support/src/runtime3/runtime.c deleted file mode 100644 index 68cb136c6..000000000 --- a/libs/PowerPC_EABI_Support/src/runtime3/runtime.c +++ /dev/null @@ -1,920 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif - -/* macros for GPR/FPR resting and saving */ -#define SAVE_FPR(reg) _savefpr_##reg -#define RESTORE_FPR(reg) _restfpr_##reg -#define SAVE_GPR(reg) _savegpr_##reg -#define RESTORE_GPR(reg) _restgpr_##reg -#define ENTRY_SAVE_FPR(reg) entry SAVE_FPR(reg) -#define ENTRY_RESTORE_FPR(reg) entry RESTORE_FPR(reg) -#define ENTRY_SAVE_GPR(reg) entry SAVE_GPR(reg) -#define ENTRY_RESTORE_GPR(reg) entry RESTORE_GPR(reg) -#define SAVE_FPR2(reg) _savef##reg -#define RESTORE_FPR2(reg) _restf##reg -#define ENTRY_SAVE_FPR2(reg) -#define ENTRY_RESTORE_FPR2(reg) - -#define save_restore_reg r11 - -asm void __div2u(void); -asm void __div2i(void); -asm void __mod2u(void); -asm void __mod2i(void); -asm void __shl2i(void); -asm void __shr2u(void); -asm void __shr2i(void); -asm void __cvt_sll_dbl(void); -asm void __cvt_ull_dbl(void); -asm void __cvt_sll_flt(void); -asm void __cvt_ull_flt(void); -asm void __cvt_dbl_usll(void); -asm void __cvt_dbl_ull(void); - -void SAVE_FPR(14)(void); -void SAVE_FPR(15)(void); -void SAVE_FPR(16)(void); -void SAVE_FPR(17)(void); -void SAVE_FPR(18)(void); -void SAVE_FPR(19)(void); -void SAVE_FPR(20)(void); -void SAVE_FPR(21)(void); -void SAVE_FPR(22)(void); -void SAVE_FPR(23)(void); -void SAVE_FPR(24)(void); -void SAVE_FPR(25)(void); -void SAVE_FPR(26)(void); -void SAVE_FPR(27)(void); -void SAVE_FPR(28)(void); -void SAVE_FPR(29)(void); -void SAVE_FPR(30)(void); -void SAVE_FPR(31)(void); -void SAVE_FPR2(14)(void); -void SAVE_FPR2(15)(void); -void SAVE_FPR2(16)(void); -void SAVE_FPR2(17)(void); -void SAVE_FPR2(18)(void); -void SAVE_FPR2(19)(void); -void SAVE_FPR2(20)(void); -void SAVE_FPR2(21)(void); -void SAVE_FPR2(22)(void); -void SAVE_FPR2(23)(void); -void SAVE_FPR2(24)(void); -void SAVE_FPR2(25)(void); -void SAVE_FPR2(26)(void); -void SAVE_FPR2(27)(void); -void SAVE_FPR2(28)(void); -void SAVE_FPR2(29)(void); -void SAVE_FPR2(30)(void); -void SAVE_FPR2(31)(void); -void RESTORE_FPR(14)(void); -void RESTORE_FPR(15)(void); -void RESTORE_FPR(16)(void); -void RESTORE_FPR(17)(void); -void RESTORE_FPR(18)(void); -void RESTORE_FPR(19)(void); -void RESTORE_FPR(20)(void); -void RESTORE_FPR(21)(void); -void RESTORE_FPR(22)(void); -void RESTORE_FPR(23)(void); -void RESTORE_FPR(24)(void); -void RESTORE_FPR(25)(void); -void RESTORE_FPR(26)(void); -void RESTORE_FPR(27)(void); -void RESTORE_FPR(28)(void); -void RESTORE_FPR(29)(void); -void RESTORE_FPR(30)(void); -void RESTORE_FPR(31)(void); -void RESTORE_FPR2(14)(void); -void RESTORE_FPR2(15)(void); -void RESTORE_FPR2(16)(void); -void RESTORE_FPR2(17)(void); -void RESTORE_FPR2(18)(void); -void RESTORE_FPR2(19)(void); -void RESTORE_FPR2(20)(void); -void RESTORE_FPR2(21)(void); -void RESTORE_FPR2(22)(void); -void RESTORE_FPR2(23)(void); -void RESTORE_FPR2(24)(void); -void RESTORE_FPR2(25)(void); -void RESTORE_FPR2(26)(void); -void RESTORE_FPR2(27)(void); -void RESTORE_FPR2(28)(void); -void RESTORE_FPR2(29)(void); -void RESTORE_FPR2(30)(void); -void RESTORE_FPR2(31)(void); -void SAVE_GPR(14)(void); -void SAVE_GPR(15)(void); -void SAVE_GPR(16)(void); -void SAVE_GPR(17)(void); -void SAVE_GPR(18)(void); -void SAVE_GPR(19)(void); -void SAVE_GPR(20)(void); -void SAVE_GPR(21)(void); -void SAVE_GPR(22)(void); -void SAVE_GPR(23)(void); -void SAVE_GPR(24)(void); -void SAVE_GPR(25)(void); -void SAVE_GPR(26)(void); -void SAVE_GPR(27)(void); -void SAVE_GPR(28)(void); -void SAVE_GPR(29)(void); -void SAVE_GPR(30)(void); -void SAVE_GPR(31)(void); -void RESTORE_GPR(14)(void); -void RESTORE_GPR(15)(void); -void RESTORE_GPR(16)(void); -void RESTORE_GPR(17)(void); -void RESTORE_GPR(18)(void); -void RESTORE_GPR(19)(void); -void RESTORE_GPR(20)(void); -void RESTORE_GPR(21)(void); -void RESTORE_GPR(22)(void); -void RESTORE_GPR(23)(void); -void RESTORE_GPR(24)(void); -void RESTORE_GPR(25)(void); -void RESTORE_GPR(26)(void); -void RESTORE_GPR(27)(void); -void RESTORE_GPR(28)(void); -void RESTORE_GPR(29)(void); -void RESTORE_GPR(30)(void); -void RESTORE_GPR(31)(void); - -static const unsigned long __constants[] = { - 0x00000000, 0x00000000, 0x41F00000, 0x00000000, 0x41E00000, 0x00000000, -}; - -asm unsigned long __cvt_fp2unsigned(register double d) -{ - nofralloc stwu r1, -16(r1)lis r4, __constants @h ori r4, r4, __constants @l li r3, 0 lfd fp0, - 0(r4)lfd fp3, 8(r4)lfd fp4, 16(r4)fcmpu cr0, fp1, fp0 fcmpu cr6, fp1, fp3 blt cr0, - @exit addi r3, r3, -1 bge cr6, @exit fcmpu cr7, fp1, fp4 fmr fp2, fp1 blt cr7, @1 fsub fp2, - fp1, fp4 @1 fctiwz fp2, fp2 stfd fp2, 8(r1)lwz r3, 12(r1)blt cr7, @exit addis r3, r3, - -0x8000 @exit : addi r1, r1, 16 blr -} - -static asm void __save_fpr(void) -{ - nofralloc ENTRY_SAVE_FPR(14) ENTRY_SAVE_FPR2(14) stfd fp14, - -144(save_restore_reg)ENTRY_SAVE_FPR(15) ENTRY_SAVE_FPR2(15) stfd fp15, - -136(save_restore_reg)ENTRY_SAVE_FPR(16) ENTRY_SAVE_FPR2(16) stfd fp16, - -128(save_restore_reg)ENTRY_SAVE_FPR(17) ENTRY_SAVE_FPR2(17) stfd fp17, - -120(save_restore_reg)ENTRY_SAVE_FPR(18) ENTRY_SAVE_FPR2(18) stfd fp18, - -112(save_restore_reg)ENTRY_SAVE_FPR(19) ENTRY_SAVE_FPR2(19) stfd fp19, - -104(save_restore_reg)ENTRY_SAVE_FPR(20) ENTRY_SAVE_FPR2(20) stfd fp20, - -96(save_restore_reg)ENTRY_SAVE_FPR(21) ENTRY_SAVE_FPR2(21) stfd fp21, - -88(save_restore_reg)ENTRY_SAVE_FPR(22) ENTRY_SAVE_FPR2(22) stfd fp22, - -80(save_restore_reg)ENTRY_SAVE_FPR(23) ENTRY_SAVE_FPR2(23) stfd fp23, - -72(save_restore_reg)ENTRY_SAVE_FPR(24) ENTRY_SAVE_FPR2(24) stfd fp24, - -64(save_restore_reg)ENTRY_SAVE_FPR(25) ENTRY_SAVE_FPR2(25) stfd fp25, - -56(save_restore_reg)ENTRY_SAVE_FPR(26) ENTRY_SAVE_FPR2(26) stfd fp26, - -48(save_restore_reg)ENTRY_SAVE_FPR(27) ENTRY_SAVE_FPR2(27) stfd fp27, - -40(save_restore_reg)ENTRY_SAVE_FPR(28) ENTRY_SAVE_FPR2(28) stfd fp28, - -32(save_restore_reg)ENTRY_SAVE_FPR(29) ENTRY_SAVE_FPR2(29) stfd fp29, - -24(save_restore_reg)ENTRY_SAVE_FPR(30) ENTRY_SAVE_FPR2(30) stfd fp30, - -16(save_restore_reg)ENTRY_SAVE_FPR(31) ENTRY_SAVE_FPR2(31) stfd fp31, - -8(save_restore_reg)blr -} - -static asm void __restore_fpr(void) -{ - nofralloc ENTRY_RESTORE_FPR(14) ENTRY_RESTORE_FPR2(14) lfd fp14, - -144(save_restore_reg)ENTRY_RESTORE_FPR(15) ENTRY_RESTORE_FPR2(15) lfd fp15, - -136(save_restore_reg)ENTRY_RESTORE_FPR(16) ENTRY_RESTORE_FPR2(16) lfd fp16, - -128(save_restore_reg)ENTRY_RESTORE_FPR(17) ENTRY_RESTORE_FPR2(17) lfd fp17, - -120(save_restore_reg)ENTRY_RESTORE_FPR(18) ENTRY_RESTORE_FPR2(18) lfd fp18, - -112(save_restore_reg)ENTRY_RESTORE_FPR(19) ENTRY_RESTORE_FPR2(19) lfd fp19, - -104(save_restore_reg)ENTRY_RESTORE_FPR(20) ENTRY_RESTORE_FPR2(20) lfd fp20, - -96(save_restore_reg)ENTRY_RESTORE_FPR(21) ENTRY_RESTORE_FPR2(21) lfd fp21, - -88(save_restore_reg)ENTRY_RESTORE_FPR(22) ENTRY_RESTORE_FPR2(22) lfd fp22, - -80(save_restore_reg)ENTRY_RESTORE_FPR(23) ENTRY_RESTORE_FPR2(23) lfd fp23, - -72(save_restore_reg)ENTRY_RESTORE_FPR(24) ENTRY_RESTORE_FPR2(24) lfd fp24, - -64(save_restore_reg)ENTRY_RESTORE_FPR(25) ENTRY_RESTORE_FPR2(25) lfd fp25, - -56(save_restore_reg)ENTRY_RESTORE_FPR(26) ENTRY_RESTORE_FPR2(26) lfd fp26, - -48(save_restore_reg)ENTRY_RESTORE_FPR(27) ENTRY_RESTORE_FPR2(27) lfd fp27, - -40(save_restore_reg)ENTRY_RESTORE_FPR(28) ENTRY_RESTORE_FPR2(28) lfd fp28, - -32(save_restore_reg)ENTRY_RESTORE_FPR(29) ENTRY_RESTORE_FPR2(29) lfd fp29, - -24(save_restore_reg)ENTRY_RESTORE_FPR(30) ENTRY_RESTORE_FPR2(30) lfd fp30, - -16(save_restore_reg)ENTRY_RESTORE_FPR(31) ENTRY_RESTORE_FPR2(31) lfd fp31, - -8(save_restore_reg)blr -} - -static asm void __save_gpr(void) -{ - nofralloc ENTRY_SAVE_GPR(14) stw r14, -72(save_restore_reg)ENTRY_SAVE_GPR(15) stw r15, - -68(save_restore_reg)ENTRY_SAVE_GPR(16) stw r16, - -64(save_restore_reg)ENTRY_SAVE_GPR(17) stw r17, - -60(save_restore_reg)ENTRY_SAVE_GPR(18) stw r18, - -56(save_restore_reg)ENTRY_SAVE_GPR(19) stw r19, - -52(save_restore_reg)ENTRY_SAVE_GPR(20) stw r20, - -48(save_restore_reg)ENTRY_SAVE_GPR(21) stw r21, - -44(save_restore_reg)ENTRY_SAVE_GPR(22) stw r22, - -40(save_restore_reg)ENTRY_SAVE_GPR(23) stw r23, - -36(save_restore_reg)ENTRY_SAVE_GPR(24) stw r24, - -32(save_restore_reg)ENTRY_SAVE_GPR(25) stw r25, - -28(save_restore_reg)ENTRY_SAVE_GPR(26) stw r26, - -24(save_restore_reg)ENTRY_SAVE_GPR(27) stw r27, - -20(save_restore_reg)ENTRY_SAVE_GPR(28) stw r28, - -16(save_restore_reg)ENTRY_SAVE_GPR(29) stw r29, - -12(save_restore_reg)ENTRY_SAVE_GPR(30) stw r30, - -8(save_restore_reg)ENTRY_SAVE_GPR(31) stw r31, -4(save_restore_reg)blr -} - -static asm void __restore_gpr(void) -{ - nofralloc ENTRY_RESTORE_GPR(14) lwz r14, -72(save_restore_reg)ENTRY_RESTORE_GPR(15) lwz r15, - -68(save_restore_reg)ENTRY_RESTORE_GPR(16) lwz r16, - -64(save_restore_reg)ENTRY_RESTORE_GPR(17) lwz r17, - -60(save_restore_reg)ENTRY_RESTORE_GPR(18) lwz r18, - -56(save_restore_reg)ENTRY_RESTORE_GPR(19) lwz r19, - -52(save_restore_reg)ENTRY_RESTORE_GPR(20) lwz r20, - -48(save_restore_reg)ENTRY_RESTORE_GPR(21) lwz r21, - -44(save_restore_reg)ENTRY_RESTORE_GPR(22) lwz r22, - -40(save_restore_reg)ENTRY_RESTORE_GPR(23) lwz r23, - -36(save_restore_reg)ENTRY_RESTORE_GPR(24) lwz r24, - -32(save_restore_reg)ENTRY_RESTORE_GPR(25) lwz r25, - -28(save_restore_reg)ENTRY_RESTORE_GPR(26) lwz r26, - -24(save_restore_reg)ENTRY_RESTORE_GPR(27) lwz r27, - -20(save_restore_reg)ENTRY_RESTORE_GPR(28) lwz r28, - -16(save_restore_reg)ENTRY_RESTORE_GPR(29) lwz r29, - -12(save_restore_reg)ENTRY_RESTORE_GPR(30) lwz r30, - -8(save_restore_reg)ENTRY_RESTORE_GPR(31) lwz r31, -4(save_restore_reg)blr -} - -asm void __div2u(void) -{ - nofralloc cmpwi cr0, r3, 0 cntlzw r0, r3 cntlzw r9, r4 bne cr0, lab1 addi r0, r9, - 32 lab1 : cmpwi cr0, - r5, - 0 cntlzw r9, - r5 cntlzw r10, - r6 bne cr0, - lab2 addi r9, - r10, - 32 lab2 : cmpw cr0, - r0, - r9 subfic r10, - r0, - 64 bgt cr0, - lab9 addi r9, - r9, - 1 subfic r9, - r9, - 64 add r0, - r0, - r9 subf r9, - r9, - r10 mtctr r9 cmpwi cr0, - r9, - 32 addi r7, - r9, - -32 blt cr0, - lab3 srw r8, - r3, - r7 li r7, - 0 b lab4 lab3 : srw r8, - r4, - r9 subfic r7, - r9, - 32 slw r7, - r3, - r7 or r8, - r8, - r7 srw r7, - r3, - r9 lab4 : cmpwi cr0, - r0, - 32 addic r9, - r0, - -32 blt cr0, - lab5 slw r3, - r4, - r9 li r4, - 0 b lab6 lab5 : slw r3, - r3, - r0 subfic r9, - r0, - 32 srw r9, - r4, - r9 or r3, - r3, - r9 slw r4, - r4, - r0 lab6 : li r10, - -1 addic r7, - r7, - 0 lab7 - : adde r4, - r4, - r4 adde r3, - r3, - r3 adde r8, - r8, - r8 adde r7, - r7, - r7 subfc r0, - r6, - r8 subfe.r9, - r5, - r7 blt cr0, - lab8 mr r8, - r0 mr r7, - r9 addic r0, - r10, - 1 lab8 : bdnz lab7 adde r4, - r4, - r4 adde r3, - r3, - r3 blr lab9 : li r4, - 0 li r3, - 0 blr -} - -#pragma push -#pragma optimization_level 0 -#pragma optimizewithasm off -asm void __div2i(void) -{ - nofralloc stwu r1, -16(r1)rlwinm.r9, r3, 0, 0, 0 beq cr0, positive1 subfic r4, r4, 0 subfze r3, - r3 positive1 : stw r9, - 8(r1)rlwinm.r10, - r5, - 0, - 0, - 0 beq cr0, - positive2 subfic r6, - r6, - 0 subfze r5, - r5 positive2 : stw r10, - 12(r1)cmpwi cr0, - r3, - 0 cntlzw r0, - r3 cntlzw r9, - r4 bne cr0, - lab1 addi r0, - r9, - 32 lab1 : cmpwi cr0, - r5, - 0 cntlzw r9, - r5 cntlzw r10, - r6 bne cr0, - lab2 addi r9, - r10, - 32 lab2 : cmpw cr0, - r0, - r9 subfic r10, - r0, - 64 bgt cr0, - lab9 addi r9, - r9, - 1 subfic r9, - r9, - 64 add r0, - r0, - r9 subf r9, - r9, - r10 mtctr r9 cmpwi cr0, - r9, - 32 addi r7, - r9, - -32 blt cr0, - lab3 srw r8, - r3, - r7 li r7, - 0 b lab4 lab3 : srw r8, - r4, - r9 subfic r7, - r9, - 32 slw r7, - r3, - r7 or r8, - r8, - r7 srw r7, - r3, - r9 lab4 : cmpwi cr0, - r0, - 32 addic r9, - r0, - -32 blt cr0, - lab5 slw r3, - r4, - r9 li r4, - 0 b lab6 lab5 - : slw r3, - r3, - r0 subfic r9, - r0, - 32 srw r9, - r4, - r9 or r3, - r3, - r9 slw r4, - r4, - r0 lab6 : li r10, - -1 addic r7, - r7, - 0 lab7 : adde r4, - r4, - r4 adde r3, - r3, - r3 adde r8, - r8, - r8 adde r7, - r7, - r7 subfc r0, - r6, - r8 subfe.r9, - r5, - r7 blt cr0, - lab8 mr r8, - r0 mr r7, - r9 addic r0, - r10, - 1 lab8 : bdnz lab7 adde r4, - r4, - r4 adde r3, - r3, - r3 lwz r9, - 8(r1)lwz r10, - 12(r1) xor.r7, - r9, - r10 beq func_end cmpwi cr0, - r9, - 0 subfic r4, - r4, - 0 subfze r3, - r3 - - no_adjust : b func_end - - lab9 : li r4, - 0 li r3, - 0 func_end : addi r1, - r1, - 16 blr -} -#pragma pop - -#pragma push -#pragma optimization_level 0 -#pragma optimizewithasm off -asm void __mod2u(void) -{ - nofralloc cmpwi cr0, r3, 0 cntlzw r0, r3 cntlzw r9, r4 bne cr0, lab1 addi r0, r9, - 32 lab1 : cmpwi cr0, - r5, - 0 cntlzw r9, - r5 cntlzw r10, - r6 bne cr0, - lab2 addi r9, - r10, - 32 lab2 : cmpw cr0, - r0, - r9 subfic r10, - r0, - 64 bgtlr cr0 addi r9, - r9, - 1 subfic r9, - r9, - 64 add r0, - r0, - r9 subf r9, - r9, - r10 mtctr r9 cmpwi cr0, - r9, - 32 addi r7, - r9, - -32 blt cr0, - lab3 srw r8, - r3, - r7 li r7, - 0 b lab4 lab3 : srw r8, - r4, - r9 subfic r7, - r9, - 32 slw r7, - r3, - r7 or r8, - r8, - r7 srw r7, - r3, - r9 lab4 : cmpwi cr0, - r0, - 32 addic r9, - r0, - -32 blt cr0, - lab5 slw r3, - r4, - r9 li r4, - 0 b lab6 lab5 : slw r3, - r3, - r0 subfic r9, - r0, - 32 srw r9, - r4, - r9 or r3, - r3, - r9 slw r4, - r4, - r0 lab6 : li r10, - -1 addic r7, - r7, - 0 lab7 - : adde r4, - r4, - r4 adde r3, - r3, - r3 adde r8, - r8, - r8 adde r7, - r7, - r7 subfc r0, - r6, - r8 subfe.r9, - r5, - r7 blt cr0, - lab8 mr r8, - r0 mr r7, - r9 addic r0, - r10, - 1 lab8 : bdnz lab7 mr r4, - r8 mr r3, - r7 blr lab9 : blr -} -#pragma pop - -#pragma push -#pragma optimization_level 0 -#pragma optimizewithasm off -asm void __mod2i(void) -{ - nofralloc - - cmpwi cr7, - r3, 0 bge cr7, positive1 subfic r4, r4, 0 subfze r3, - r3 positive1 : cmpwi cr0, - r5, - 0 bge cr0, - positive2 subfic r6, - r6, - 0 subfze r5, - r5 positive2 : cmpwi cr0, - r3, - 0 cntlzw r0, - r3 cntlzw r9, - r4 bne cr0, - lab1 addi r0, - r9, - 32 lab1 : cmpwi cr0, - r5, - 0 cntlzw r9, - r5 cntlzw r10, - r6 bne cr0, - lab2 addi r9, - r10, - 32 lab2 : cmpw cr0, - r0, - r9 subfic r10, - r0, - 64 bgt cr0, - lab9 addi r9, - r9, - 1 subfic r9, - r9, - 64 add r0, - r0, - r9 subf r9, - r9, - r10 mtctr r9 cmpwi cr0, - r9, - 32 addi r7, - r9, - -32 blt cr0, - lab3 srw r8, - r3, - r7 li r7, - 0 b lab4 lab3 : srw r8, - r4, - r9 subfic r7, - r9, - 32 slw r7, - r3, - r7 or r8, - r8, - r7 srw r7, - r3, - r9 lab4 : cmpwi cr0, - r0, - 32 addic r9, - r0, - -32 blt cr0, - lab5 slw r3, - r4, - r9 li r4, - 0 b lab6 lab5 - : slw r3, - r3, - r0 subfic r9, - r0, - 32 srw r9, - r4, - r9 or r3, - r3, - r9 slw r4, - r4, - r0 lab6 : li r10, - -1 addic r7, - r7, - 0 lab7 : adde r4, - r4, - r4 adde r3, - r3, - r3 adde r8, - r8, - r8 adde r7, - r7, - r7 subfc r0, - r6, - r8 subfe.r9, - r5, - r7 blt cr0, - lab8 mr r8, - r0 mr r7, - r9 addic r0, - r10, - 1 lab8 : bdnz lab7 mr r4, - r8 mr r3, - r7 lab9 : bgelr cr7 subfic r4, - r4, - 0 subfze r3, - r3 no_adjust : blr -} -#pragma pop - -asm void __shl2i(void) -{ - nofralloc subfic r8, r5, 32 subic r9, r5, 32 slw r3, r3, r5 srw r10, r4, r8 or r3, r3, - r10 slw r10, r4, r9 or r3, r3, r10 slw r4, r4, r5 blr -} - -//unused -asm void __shr2u(void) -{ - nofralloc subfic r8, r5, 32 subic r9, r5, 32 srw r4, r4, r5 slw r10, r3, r8 or r4, r4, - r10 srw r10, r3, r9 or r4, r4, r10 srw r3, r3, r5 blr -} - -asm void __shr2i(void) -{ - subfic r8, r5, 0x20 addic.r9, r5, -0x20 srw r4, r4, r5 slw r10, r3, r8 or r4, r4, r10 sraw r10, - r3, r9 ble L_802BA610 or r4, r4, r10 L_802BA610 : sraw r3, r3, r5 blr -} - -asm void __cvt_sll_dbl(void) -{ - // clang-format off - stwu r1, -0x10(r1) - rlwinm. r5, r3, 0, 0, 0 - beq- lbl_802b2b1c - subfic r4, r4, 0x0 - subfze r3, r3 -lbl_802b2b1c: - or. r7, r3, r4 - li r6, 0x0 - beq- lbl_802b2ba4 - cntlzw r7, r3 - cntlzw r8, r4 - rlwinm r9, r7, 0x1a, 0, 4 - srawi r9, r9, 0x1f - and r9, r9, r8 - add r7, r7, r9 - subfic r8, r7, 0x20 - addic r9, r7, -0x20 - slw r3, r3, r7 - srw r10, r4, r8 - or r3, r3, r10 - slw r10, r4, r9 - or r3, r3, r10 - slw r4, r4, r7 - subf r6, r7, r6 - clrlwi r7, r4, 0x15 - cmpwi r7, 0x400 - addi r6, r6, 0x43e - blt- lbl_802b2b8c - bgt- lbl_802b2b80 - rlwinm. r7, r4, 0, 0x14, 0x14 - beq- lbl_802b2b8c -lbl_802b2b80: - addic r4, r4, 0x800 - addze r3, r3 - addze r6, r6 -lbl_802b2b8c: - rotlwi r4, r4, 0x15 - rlwimi r4, r3, 0x15, 0, 0xa - rlwinm r3, r3, 0x15, 0xc, 0x1f - slwi r6, r6, 0x14 - or r3, r6, r3 - or r3, r5, r3 -lbl_802b2ba4: - stw r3, 8(r1) - stw r4, 0xc(r1) - lfd f1, 8(r1) - addi r1, r1, 0x10 - frfree - blr - // clang-format on -} - -//unused -asm void __cvt_ull_dbl(void) -{ -} - -asm void __cvt_sll_flt(void) -{ - stwu r1, -0x10(r1)clrrwi.r5, r3, 31 beq L_802BA62C subfic r4, r4, 0x0 subfze r3, - r3 L_802BA62C : or.r7, r3, r4 li r6, 0x0 beq L_802BA6B4 cntlzw r7, r3 cntlzw r8, - r4 extlwi r9, r7, 5, 26 srawi r9, r9, 31 and r9, r9, r8 add r7, r7, r9 subfic r8, r7, - 0x20 addic r9, r7, -0x20 slw r3, r3, r7 srw r10, r4, r8 or r3, r3, r10 slw r10, r4, - r9 or r3, r3, r10 slw r4, r4, r7 subf r6, r7, r6 clrlwi r7, r4, 21 cmpwi r7, 0x400 addi r6, - r6, 0x43e blt L_802BA69C bgt L_802BA690 rlwinm.r7, r4, 0, 20, - 20 beq L_802BA69C L_802BA690 : addic r4, - r4, - 0x800 addze r3, - r3 addze r6, - r6 L_802BA69C : rotrwi r4, - r4, - 11 rlwimi r4, - r3, - 21, - 0, - 10 extrwi r3, - r3, - 20, - 1 slwi r6, - r6, - 20 or r3, - r6, - r3 or r3, - r5, - r3 L_802BA6B4 : stw r3, - 0x8(r1)stw r4, - 0xc(r1)lfd f1, - 0x8(r1)frsp f1, - f1 addi r1, - r1, - 0x10 blr -} - -//unused -asm void __cvt_ull_flt(void) -{ -} - -//unused -asm void __cvt_dbl_usll(void) -{ - nofralloc stwu r1, -16(r1)stfd f1, 8(r1)lwz r3, 8(r1)lwz r4, 12(r1)rlwinm r5, r3, 12, 21, - 31 cmpli cr0, 0, r5, 1023 bge cr0, not_fraction li r3, 0 li r4, - 0 b func_end not_fraction : mr r6, - r3 rlwinm r3, - r3, - 0, - 12, - 31 oris r3, - r3, - 0x0010 addi r5, - r5, - -1075 cmpwi cr0, - r5, - 0 bge cr0, - left neg r5, - r5 subfic r8, - r5, - 32 subic r9, - r5, - 32 srw r4, - r4, - r5 slw r10, - r3, - r8 or r4, - r4, - r10 srw r10, - r3, - r9 or r4, - r4, - r10 srw r3, - r3, - r5 b around left : cmpwi cr0, - r5, - 10 ble + no_overflow rlwinm.r6, - r6, - 0, - 0, - 0 beq cr0, - max_positive lis r3, - 0x8000 li r4, - 0 b func_end max_positive - : lis r3, - 0x7FFF ori r3, - r3, - 0xFFFF li r4, - -1 b func_end no_overflow : subfic r8, - r5, - 32 subic r9, - r5, - 32 slw r3, - r3, - r5 srw r10, - r4, - r8 or r3, - r3, - r10 slw r10, - r4, - r9 or r3, - r3, - r10 slw r4, - r4, - r5 around : rlwinm.r6, - r6, - 0, - 0, - 0 beq cr0, - positive subfic r4, - r4, - 0 subfze r3, - r3 positive : func_end : addi r1, - r1, - 16 blr -} - -void __cvt_dbl_ull(void) -{ - nofralloc stwu r1, -0x10(r1)stfd f1, 8(r1)lwz r3, 8(r1)lwz r4, 0xC(r1)extrwi r5, r3, 11, - 1 cmplwi r5, - 0x3FF bge loc_80518FB4 - - loc_80518FA8 : li r3, - 0 li r4, - 0 b end - - loc_80518FB4 : clrrwi.r6, - r3, - 31 bne loc_80518FA8 clrlwi r3, - r3, - 12 oris r3, - r3, - 0x10 addi r5, - r5, - -0x433 cmpwi r5, - 0 bge loc_80518FF8 neg r5, - r5 subfic r8, - r5, - 0x20 addic r9, - r5, - -0x20 srw r4, - r4, - r5 slw r10, - r3, - r8 or r4, - r4, - r10 srw r10, - r3, - r9 or r4, - r4, - r10 srw r3, - r3, - r5 b end - - loc_80518FF8 : cmpwi r5, - 0xB ble + loc_8051900C li r3, - -1 li r4, - -1 b end - - loc_8051900C : subfic r8, - r5, - 0x20 addic r9, - r5, - -0x20 slw r3, - r3, - r5 srw r10, - r4, - r8 or r3, - r3, - r10 slw r10, - r4, - r9 or r3, - r3, - r10 slw r4, - r4, - r5 - - end : addi r1, - r1, - 0x10 blr -} - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/libs/dolphin/amcstubs/AmcExi2Stubs.c b/libs/dolphin/amcstubs/AmcExi2Stubs.c index 99073a34c..1deed475a 100644 --- a/libs/dolphin/amcstubs/AmcExi2Stubs.c +++ b/libs/dolphin/amcstubs/AmcExi2Stubs.c @@ -4,26 +4,38 @@ // prototypes int AMC_IsStub(void); -void EXI2_Init(volatile unsigned char **inputPendingPtrRef, EXICallback monitorCallback) {} +void EXI2_Init(volatile unsigned char** inputPendingPtrRef, EXICallback monitorCallback) +{ +} -void EXI2_EnableInterrupts(void) {} +void EXI2_EnableInterrupts(void) +{ +} -int EXI2_Poll(void) { +int EXI2_Poll(void) +{ return 0; } -AmcExiError EXI2_ReadN(void *bytes, unsigned long length) { +AmcExiError EXI2_ReadN(void* bytes, unsigned long length) +{ return AMC_EXI_NO_ERROR; } -AmcExiError EXI2_WriteN(const void *bytes, unsigned long length) { +AmcExiError EXI2_WriteN(const void* bytes, unsigned long length) +{ return AMC_EXI_NO_ERROR; } -void EXI2_Reserve(void) {} +void EXI2_Reserve(void) +{ +} -void EXI2_Unreserve(void) {} +void EXI2_Unreserve(void) +{ +} -int AMC_IsStub(void) { +int AMC_IsStub(void) +{ return 1; -} +} \ No newline at end of file diff --git a/libs/dolphin/ax/AXSPB.c b/libs/dolphin/ax/AXSPB.c index 9a22f943c..141bdafbd 100644 --- a/libs/dolphin/ax/AXSPB.c +++ b/libs/dolphin/ax/AXSPB.c @@ -22,7 +22,7 @@ u32 __AXGetStudio(void) return (u32)&__AXStudio; } -void __AXDepopFade(long* hostSum, long* dspVolume, s16* dspDelta) +inline void __AXDepopFade(long* hostSum, long* dspVolume, s16* dspDelta) { int frames; long delta; diff --git a/libs/dolphin/card/CARDNet.c b/libs/dolphin/card/CARDNet.c index 17d61f429..a99df9e62 100644 --- a/libs/dolphin/card/CARDNet.c +++ b/libs/dolphin/card/CARDNet.c @@ -8,38 +8,38 @@ u16 __CARDVendorID = 0xFFFF; u8 __CARDPermMask = 28; -// 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 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) { diff --git a/libs/dolphin/dsp/dsp.c b/libs/dolphin/dsp/dsp.c index 7459587bb..2d794337a 100644 --- a/libs/dolphin/dsp/dsp.c +++ b/libs/dolphin/dsp/dsp.c @@ -18,6 +18,8 @@ extern DSPTaskInfo* __DSP_tmp_task; extern DSPTaskInfo* __DSP_last_task; extern DSPTaskInfo* __DSP_first_task; extern DSPTaskInfo* __DSP_curr_task; +extern DSPTaskInfo* __DSP_rude_task; +extern s32 __DSP_rude_task_pending; extern void __DSPHandler(__OSInterrupt, OSContext*); extern void __DSP_debug_printf(const char* fmt, ...); @@ -110,6 +112,37 @@ DSPTaskInfo* DSPCancelTask(DSPTaskInfo* task) return task; } +DSPTaskInfo* DSPAssertTask(DSPTaskInfo* task) +{ + s32 old; + + 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) + { + OSDisableInterrupts(); + OSRestoreInterrupts(FALSE); + } + OSRestoreInterrupts(old); + return task; + } + + OSRestoreInterrupts(old); + return NULL; +} + #ifdef __cplusplus } #endif diff --git a/libs/dolphin/dvd/dvderror.c b/libs/dolphin/dvd/dvderror.c index 259e8a5bf..7e292e4ee 100644 --- a/libs/dolphin/dvd/dvderror.c +++ b/libs/dolphin/dvd/dvderror.c @@ -27,7 +27,7 @@ static u8 ErrorCode2Num(u32 errorCode) return 29; } -static u8 Convert(u32 error) +inline u8 Convert(u32 error) { u32 statusCode; u32 errorCode; diff --git a/libs/dolphin/dvd/dvdfs.c b/libs/dolphin/dvd/dvdfs.c index 27e75e9df..021b4d579 100644 --- a/libs/dolphin/dvd/dvdfs.c +++ b/libs/dolphin/dvd/dvdfs.c @@ -46,7 +46,7 @@ void __DVDFSInit() #define filePosition(i) (FstStart[i].parentOrPosition) #define fileLength(i) (FstStart[i].nextEntryOrLength) -static BOOL isSame(const char* path, const char* string) +inline BOOL isSame(const char* path, const char* string) { while (*string != '\0') { @@ -239,7 +239,7 @@ BOOL DVDClose(DVDFileInfo* fileInfo) return TRUE; } -static u32 myStrncpy(char* dest, char* src, u32 maxlen) +inline u32 myStrncpy(char* dest, char* src, u32 maxlen) { u32 i = maxlen; @@ -278,7 +278,7 @@ static u32 entryToPath(u32 entry, char* path, u32 maxlen) return loc; } -static BOOL DVDConvertEntrynumToPath(s32 entrynum, char* path, u32 maxlen) +inline BOOL DVDConvertEntrynumToPath(s32 entrynum, char* path, u32 maxlen) { u32 loc; @@ -310,20 +310,6 @@ BOOL DVDGetCurrentDir(char* path, u32 maxlen) return DVDConvertEntrynumToPath((s32)currentDirectory, path, maxlen); } -BOOL DVDChangeDir(char* dirName) -{ - s32 entry; - entry = DVDConvertPathToEntrynum(dirName); - if ((entry < 0) || (entryIsDir(entry) == FALSE)) - { - return FALSE; - } - - currentDirectory = (u32)entry; - - return TRUE; -} - BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, DVDCallback callback, s32 prio) { @@ -449,307 +435,3 @@ static void cbForSeekAsync(s32 result, DVDCommandBlock* block) (fileInfo->callback)(result, fileInfo); } } -/* This is based on the revolution SDK, these may not match in all cases */ -s32 DVDSeekPrio(DVDFileInfo* fileInfo, s32 offset, s32 prio) -{ - BOOL result; - DVDCommandBlock* block; - s32 state; - BOOL enabled; - s32 retVal; - - block = &(fileInfo->cb); - - result = DVDSeekAbsAsyncPrio(block, (s32)(fileInfo->startAddr + offset), cbForSeekSync, prio); - - 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 = DVD_RESULT_CANCELED; - break; - } - - OSSleepThread(&__DVDThreadQueue); - } - - OSRestoreInterrupts(enabled); - return retVal; -} -/* This is based on the revolution SDK, these may not match in all cases */ -static void cbForSeekSync(s32 result, DVDCommandBlock* block) -{ - OSWakeupThread(&__DVDThreadQueue); -} - -/* This is based on the revolution SDK, these may not match in all cases */ -s32 DVDGetFileInfoStatus(DVDFileInfo* fileInfo) -{ - return DVDGetCommandBlockStatus(&fileInfo->cb); -} - -/* This is based on the revolution SDK, these may not match in all cases */ -BOOL DVDFastOpenDir(s32 entrynum, DVDDir* dir) -{ - if ((entrynum < 0) || (entrynum >= MaxEntryNum) || !entryIsDir(entrynum)) - { - return FALSE; - } - - dir->entryNum = (u32)entrynum; - dir->location = (u32)entrynum + 1; - dir->next = nextDir(entrynum); - - return TRUE; -} - -/* This is based on the revolution SDK, these may not match in all cases */ -BOOL DVDOpenDir(char* dirName, DVDDir* dir) -{ - s32 entry; - char currentDir[128]; - entry = DVDConvertPathToEntrynum(dirName); - - if (entry < 0) - { - DVDGetCurrentDir(currentDir, 128); - OSReport("Warning: DVDOpenDir(): file '%s' was not found under %s.\n", dirName, currentDir); - return FALSE; - } - - if (!entryIsDir(entry)) - { - return FALSE; - } - - dir->entryNum = (u32)entry; - dir->location = (u32)entry + 1; - dir->next = nextDir(entry); - - return TRUE; -} - -BOOL DVDReadDir(DVDDir* dir, DVDDirEntry* dirent) -{ - u32 loc = dir->location; - if ((loc <= dir->entryNum) || (dir->next <= loc)) - return FALSE; - - dirent->entryNum = loc; - dirent->isDir = entryIsDir(loc); - dirent->name = FstStringStart + stringOff(loc); - - dir->location = entryIsDir(loc) ? nextDir(loc) : (loc + 1); - - return TRUE; -} - -/* This is based on the revolution SDK, these may not match in all cases */ -BOOL DVDCloseDir(DVDDir* dir) -{ - return TRUE; -} - -/* This is based on the revolution SDK, these may not match in all cases */ -void DVDRewindDir(DVDDir* dir) -{ - dir->location = dir->entryNum + 1; -} - -/* This is based on the revolution SDK, these may not match in all cases */ -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; - - start = fileInfo->startAddr + offset; - - if (!Is32KBAligned(start)) - { - OSPanic( - __FILE__, 1189, - "DVDPrepareStreamAsync(): Specified start address (filestart(0x%x) + offset(0x%x)) is " - "not 32KB aligned", - fileInfo->startAddr, offset); - } - - if (length == 0) - length = fileInfo->length - offset; - - if (!Is32KBAligned(length)) - { - OSPanic( - __FILE__, 1199, - "DVDPrepareStreamAsync(): Specified length (0x%x) is not a multiple of 32768(32*1024)", - length); - } - - if (!((offset < fileInfo->length) && (offset + length <= fileInfo->length))) - { - OSPanic( - __FILE__, 1207, - "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)); - - if (fileInfo->callback) - { - (fileInfo->callback)(result, fileInfo); - } -} - -/* This is based on the revolution SDK, these may not match in all cases */ -s32 DVDPrepareStream(DVDFileInfo* fileInfo, u32 length, u32 offset) -{ - BOOL result; - DVDCommandBlock* block; - s32 state; - BOOL enabled; - s32 retVal; - u32 start; - start = fileInfo->startAddr + offset; - - if (!Is32KBAligned(start)) - { - OSPanic( - __FILE__, 0, - "DVDPrepareStream(): Specified start address (filestart(0x%x) + offset(0x%x)) is not " - "32KB aligned", - fileInfo->startAddr, offset); - } - - if (length == 0) - length = fileInfo->length - offset; - - if (!Is32KBAligned(length)) - { - OSPanic(__FILE__, 0, - "DVDPrepareStream(): Specified length (0x%x) is not a multiple of 32768(32*1024)", - length); - } - - if (!((offset <= fileInfo->length) && (offset + length <= fileInfo->length))) - { - OSPanic( - __FILE__, 0, - "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 = DVD_RESULT_CANCELED; - break; - } - - OSSleepThread(&__DVDThreadQueue); - } - - OSRestoreInterrupts(enabled); - return retVal; -} - -/* This is based on the revolution SDK, these may not match in all cases */ -static void cbForPrepareStreamSync(s32 result, DVDCommandBlock* block) -{ - OSWakeupThread(&__DVDThreadQueue); -} - -/* This is based on the revolution SDK, these may not match in all cases */ -s32 DVDGetTransferredSize(DVDFileInfo* fileinfo) -{ - s32 bytes; - DVDCommandBlock* cb; - - cb = &(fileinfo->cb); - - switch (cb->state) - { - case DVD_STATE_END: - 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: - bytes = (s32)cb->transferredSize; - break; - - case DVD_STATE_WAITING: - bytes = 0; - break; - - case DVD_STATE_BUSY: - bytes = (s32)(cb->transferredSize + (cb->currTransferSize - DVDLowGetLength())); - break; - - default: - break; - } - - return bytes; -} \ No newline at end of file diff --git a/libs/dolphin/dvd/dvdlow.c b/libs/dolphin/dvd/dvdlow.c index 3c2aab44b..55baa4e3f 100644 --- a/libs/dolphin/dvd/dvdlow.c +++ b/libs/dolphin/dvd/dvdlow.c @@ -50,7 +50,7 @@ void __DVDInitWA() static void Read(void* addr, u32 length, u32 offset, DVDLowCallback callback); -static BOOL ProcessNextCommand() +inline BOOL ProcessNextCommand() { s32 n = NextCommandNumber; ASSERT(n < 3); @@ -218,7 +218,7 @@ static void AlarmHandlerForTimeout(OSAlarm* alarm, OSContext* context) OSSetCurrentContext(context); } -static void SetTimeoutAlarm(OSTime timeout) +inline void SetTimeoutAlarm(OSTime timeout) { OSCreateAlarm(&AlarmForTimeout); OSSetAlarm(&AlarmForTimeout, timeout, AlarmHandlerForTimeout); @@ -249,7 +249,7 @@ static void Read(void* addr, u32 length, u32 offset, DVDLowCallback callback) } } -BOOL HitCache(DVDBuffer* cur, DVDBuffer* prev) +inline BOOL HitCache(DVDBuffer* cur, DVDBuffer* prev) { u32 uVar1 = (prev->offset + prev->length - 1) >> 15; u32 uVar2 = (cur->offset >> 15); @@ -262,7 +262,7 @@ BOOL HitCache(DVDBuffer* cur, DVDBuffer* prev) return FALSE; } -static void DoJustRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) +inline void DoJustRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { CommandList[0].cmd = -1; NextCommandNumber = 0; @@ -293,7 +293,7 @@ static void SeekTwiceBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallba DVDLowSeek(newOffset, callback); } -static void WaitBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback, +inline void WaitBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback, OSTime timeout) { CommandList[0].cmd = 1; @@ -504,16 +504,16 @@ void __DVDLowSetWAType(u32 type, u32 location) OSRestoreInterrupts(enabled); } -BOOL __DVDLowTestAlarm(OSAlarm* alarm) -{ - if (alarm == &AlarmForBreak) - { - return TRUE; - } - if (alarm == &AlarmForTimeout) - { - return TRUE; - } - - return FALSE; -} \ No newline at end of file +// BOOL __DVDLowTestAlarm(OSAlarm* alarm) +// { +// if (alarm == &AlarmForBreak) +// { +// return TRUE; +// } +// if (alarm == &AlarmForTimeout) +// { +// return TRUE; +// } + +// return FALSE; +// } \ No newline at end of file diff --git a/libs/dolphin/eth/base64.c b/libs/dolphin/eth/base64.c new file mode 100644 index 000000000..a2c6b0053 --- /dev/null +++ b/libs/dolphin/eth/base64.c @@ -0,0 +1,70 @@ +#include + +static const char Base64[] = { + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" +}; + +char *__IPEncodeToBase64(void *_src, s32 len , char *dst) { + const u8 *src; + int i; + char *p; + + src = _src; + p = dst; + for (i = 0; i < len - len % 3; i += 3) { + *p++ = Base64[(src[i+0] >> 2) & 0x3f]; + *p++ = Base64[((src[i+0] & 0x3) << 4) | ((src[i+1] >> 4) & 0xf)]; + *p++ = Base64[((src[i+1] & 0xf) << 2) | ((src[i+2] >> 6) & 0x3)]; + *p++ = Base64[src[i+2] & 0x3f]; + } + + i = len - len % 3; + // Encode remaining characters + switch (len % 3) { + case 2: { + *p++ = Base64[(src[i+0] >> 2) & 0x3f]; + *p++ = Base64[((src[i+0] & 0x3) << 4) | ((src[i+1] >> 4) & 0xf)]; + *p++ = Base64[((src[i+1] & 0xf) << 2)]; + *p++ = '='; + break; + } + case 1: { + *p++ = Base64[(src[i+0] >> 2) & 0x3f]; + *p++ = Base64[((src[i+0] & 0x3) << 4)]; + *p++ = '='; + *p++ = '='; + break; + } + } + + return p; +} + +void *__IPDecodeFromBase64(const char *src, long len , void *_dst) { + u8 *dst; + int i; + u8 *p; + + dst = _dst; + p = dst; + for (i = 0; i < len; i += 4) { + int n0; + int n1; + int n2; + int n3; + n0 = strchr(Base64, src[i+0]) - Base64; + n1 = strchr(Base64, src[i+1]) - Base64; + *p++ = (n0 << 2) | (n1 >> 4) & 0x3; + + if (src[i+2] == '=') break; + + n2 = strchr(Base64, src[i+2]) - Base64; + *p++ = ((n1 << 4) & 0xff) | (n2 >> 2) & 0xf; + + if (src[i+3] == '=') break; + + n3 = strchr(Base64, src[i+3]) - Base64; + *p++ = ((n2 << 6) & 0xff) | (n3 & 0x3f); + } + return p; +} diff --git a/libs/dolphin/eth/eth.c b/libs/dolphin/eth/eth.c new file mode 100644 index 000000000..871352662 --- /dev/null +++ b/libs/dolphin/eth/eth.c @@ -0,0 +1,1031 @@ +#include + +#include +#include +#include +#include + +#include "types.h" + +#ifdef DEBUG +const char* __ETHVersion = "<< Dolphin SDK - ETH\tdebug build: Aug 5 2003 17:18:42 (0x2301) >>"; +#else +const char* __ETHVersion = "<< Dolphin SDK - ETH\trelease build: Aug 5 2003 17:18:42 (0x2301) >>"; +#endif + +static u8 broadcastheader[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +static u8 private_macaddr[6]; +static u8 __revid = 0; +static u16 __devid = 0xD107; +static u8 __acstart = 0x4E; +static OSThreadQueue threadQ; +static BOOL lockUpdate = FALSE; +static BOOL __sendbusy = FALSE; +static BOOL sendUpdate = FALSE; +static ETHStat ethstat; +static u16* protoarray = NULL; +static s32 protonum = 0; +static void* (*recvcallback0)(u16, s32, u8) = NULL; +static void (*recvcallback1)(u8*, s32) = NULL; +static BOOL recvcallbackUpdate = FALSE; +static void (*__sendcallback)(u8) = NULL; +static BOOL __recvpriorityflag = FALSE; +static u8* __sendadr = NULL; +static s32 __sendlen = 0; +static s32 __senddmalen = 0; +static s32 __sendimmlen = 0; +static u8 tmppool0[1536] ATTRIBUTE_ALIGN(32); +static u8 tmppool1[1536] ATTRIBUTE_ALIGN(32); +static u32 recvlen0 = 0; +static u32 recvlen1 = 0; + +typedef struct Descriptor { + u8 nextpacketL; + u8 packetlengthL : 4; + u8 nextpacketH : 4; + u8 packetLengthH; + u8 status; +} Descriptor; + +typedef struct Descriptor2 { + u16 nextpacket; + u16 packetlength; + u8 status; +} Descriptor2; + +static Descriptor2 d2; + +static u8* recvaddr = NULL; +static u16 rwp = 0; +static u16 rrp = 0; +static u8 mcastmap[8]; +static BOOL mcastUpdate = FALSE; + + +static BOOL lock(void); +static void unlock(void); + +static void recvsub0(void); +static void recvsub1(void); + +static void sendsub0(void); +static void sendsub1(s32 chan, OSContext* context); + +static void readbuffer0(u16 cmd); +static void readbuffer1(s32 chan, OSContext* context); +static void readbuffersub(s32 chan, OSContext* context); + +static void exiinthandler(s32 chan, OSContext* context); + +static inline u16 swap16(u16 val) { + u16 ret = __lhbrx(&val, 0); + return ret; +} + +static inline u8 higher(u16 val) { + return (val >> 8) & 0xff; +} + +static inline u8 lower(u16 val) { + return val & 0xff; +} + +static void waitexilock(void) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + while (TRUE) { + if (lock() != FALSE) { + OSRestoreInterrupts(enabled); + return; + } + + lockUpdate = TRUE; + OSSleepThread(&threadQ); + OSRestoreInterrupts(enabled); + } +} + +static void waitmicro(s32 usec) { + OSTick start; + OSTick interval; + + start = OSGetTick(); + interval = OSMicrosecondsToTicks(usec); + + while (TRUE) { + if (OSGetTick() - start >= interval) { + break; + } + } +} + +static u8 readEXIcmd(u8 cmd) { + u16 ethcmd; + u8 rdata; + + ethcmd = 0x0000 | (cmd << 8); + EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImm(0, &rdata, sizeof(rdata), EXI_READ, NULL); + EXISync(0); + EXIDeselect(0); + return rdata; +} + +static u8 readEXIcmdWait200Micro(u8 cmd) { + u16 ethcmd; + u8 rdata; + + ethcmd = 0x0000 | (cmd << 8); + EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImm(0, &rdata, sizeof(rdata), EXI_READ, NULL); + EXISync(0); + waitmicro(200); + EXIDeselect(0); + return rdata; +} + +static void writeEXIcmd(u8 cmd, u8 imr) { + BOOL ret; + u16 ethcmd; + + ethcmd = 0x4000 | (cmd << 8); + ret = EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImm(0, &imr, sizeof(imr), EXI_WRITE, NULL); + EXISync(0); + EXIDeselect(0); +} + +static void readEXIcmdLong(u8 cmd, void* address, s32 length) { + u16 ethcmd; + + ethcmd = cmd << 8; + EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImmEx(0, address, length, EXI_READ); + EXIDeselect(0); +} + +static void writeEXIcmdLong(u8 cmd, void* address, s32 length) { + BOOL ret; + u16 ethcmd; + + ethcmd = 0x4000 | (cmd << 8); + ret = EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImmEx(0, address, length, EXI_WRITE); + EXIDeselect(0); +} + +static void readcmdLong(u16 cmd, void* addr, s32 length) { + u32 ethcmd; + + ethcmd = 0x80000000 | (cmd << 8); + EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImmEx(0, addr, length, EXI_READ); + EXIDeselect(0); +} + +static void writecmdLong(u16 cmd, void* addr, s32 length) { + u32 ethcmd = 0xC0000000 | (cmd << 8); + EXISelect(0, 2, 5); + EXIImm(0, ðcmd, sizeof(ethcmd), EXI_WRITE, NULL); + EXISync(0); + EXIImmEx(0, addr, length, EXI_WRITE); + EXIDeselect(0); +} + +static u8 readcmd(u16 cmd) { + u8 val; + + readcmdLong(cmd, &val, sizeof(val)); + return val; +} + +static void writecmd(u16 cmd, u8 val) { + writecmdLong(cmd, &val, sizeof(val)); +} + +static void StaOutput(unsigned int bit) { + writecmd(0x0060, bit * 2); + writecmd(0x0060, 8 + bit * 2); + writecmd(0x0060, 8 + bit * 2); + writecmd(0x0060, bit * 2); +} + +static u8 StaInput(void) { + unsigned char bit; + + writecmd(0x0060, 0x0C); + bit = readcmd(0x0060); + bit &= 1; + writecmd(0x0060, 0x04); + writecmd(0x0060, 0x04); + return bit; +} + +static u16 PhyRead(unsigned int regNo) { + int i; + u16 value; + + /* Clear command */ + for (i = 0; i < 32; i++) { + StaOutput(1); + } + + /* Enter read mode */ + StaOutput(0); + StaOutput(1); + StaOutput(1); + StaOutput(0); + StaOutput(0); + StaOutput(0); + StaOutput(0); + StaOutput(0); + StaOutput(0); + + /* Set register */ + StaOutput((regNo >> 4) & 1); + StaOutput((regNo >> 3) & 1); + StaOutput((regNo >> 2) & 1); + StaOutput((regNo >> 1) & 1); + StaOutput((regNo >> 0) & 1); + writecmd(0x0060, 4); + value = StaInput(); + value = StaInput(); + + /* Read value */ + value = 0; + for (i = 0; i < 16; i++) { + value = value + (StaInput() << (15 - i)); + } + + /* Clear command */ + for (i = 0; i < 32; i++) { + StaOutput(1); + } + + return value; +} + +static void PhyWrite(unsigned int regNo, u16 value) { + int i; + + /* Clear command */ + for (i = 0; i < 32; i++) { + StaOutput(1); + } + + /* Enter write mode */ + StaOutput(0); + StaOutput(1); + StaOutput(0); + StaOutput(1); + StaOutput(0); + StaOutput(0); + StaOutput(0); + StaOutput(0); + StaOutput(0); + + /* Set register */ + StaOutput((regNo >> 4) & 1); + StaOutput((regNo >> 3) & 1); + StaOutput((regNo >> 2) & 1); + StaOutput((regNo >> 1) & 1); + StaOutput((regNo >> 0) & 1); + + StaOutput(1); + StaOutput(0); + + /* Write value */ + for (i = 0; i < 16; i++) { + StaOutput((u8)((value >> (15 - i)) & 1)); + } + + /* Clear command */ + for (i = 0; i < 32; i++) { + StaOutput(1); + } +} + +static void reset(void) { + writecmd(0x0060, 0); + waitmicro(10000); + readEXIcmdWait200Micro(0x0F); + waitmicro(10000); + writecmd(0x0000, 1); + writecmd(0x0000, 0); +} + +static void recvinit(void) { + u8 ncrb; + u16 swapped; + + swapped = higher(0x0001) | (lower(0x0001) << 8); + writecmdLong(0x000A, &swapped, sizeof(swapped)); + writecmdLong(0x0016, &swapped, sizeof(swapped)); + writecmdLong(0x0018, &swapped, sizeof(swapped)); + + swapped = higher(0x000F) | (lower(0x000F) << 8); + writecmdLong(0x001A, &swapped, sizeof(swapped)); + + ncrb = readcmd(0x0001); + ncrb &= ~0b00000011; // ~3 + ncrb |= 0b00010000; // | 0x10 + writecmd(0x0001, ncrb); + writecmd(0x0000, 0x08); + writecmd(0x0032, 0x08); +} + +static void getdescriptor(u16 address) { + Descriptor d; + + readcmdLong(address, &d, sizeof(d)); + d2.nextpacket = (d.nextpacketH << 8) | d.nextpacketL; + d2.packetlength = (d.packetLengthH << 4) | d.packetlengthL; + d2.status = d.status; +} + +static u16 readcmd16(u8 cmd) { + u16 tmp16; + + readcmdLong(cmd, &tmp16, sizeof(tmp16)); + + return swap16(tmp16); +} + +static void writecmd16(u8 cmd, u16 val) { + u16 tmp16; + + tmp16 = swap16(val); + writecmdLong(cmd, &tmp16, sizeof(tmp16)); +} + +static void recvsub0(void) { + rwp = readcmd16(0x16); + rrp = readcmd16(0x18); + recvsub1(); +} + +static void recvsub1(void) { + u16 packettype; + s32 i; + u8 lrps; + u16 address; + + recvlen0 = recvlen1 = 0; + do { + while (rrp != rwp) { + address = (rrp & 0xFF) << 8; + getdescriptor(address); + readcmdLong(address + 0x10U, &packettype, sizeof(packettype)); + + if (protonum > 0) { + for (i = 0; i < protonum; i++) { + if (packettype == protoarray[i]) { + break; + } + } + + if (i == protonum) { + goto update_pointers; + } + } + + if (recvcallback0) { + lrps = d2.status; + recvaddr = (*recvcallback0)(packettype, d2.packetlength, lrps); + + if (recvaddr != NULL) { + if (address + 4U + d2.packetlength > 0x1000U) { + recvlen1 = address - 0x0FFCU + d2.packetlength; + recvlen0 = d2.packetlength - recvlen1; + } else { + recvlen0 = d2.packetlength; + recvlen1 = 0; + } + + readbuffer0(address + 4U); + return; + } + } + +update_pointers: + rrp = d2.nextpacket; + rwp = readcmd16(0x16); + } + + writecmd16(0x18, rwp); + writecmd(0x0009, 0x02); + rwp = readcmd16(0x16); + rrp = readcmd16(0x18); + } while (rwp != rrp); + + writeEXIcmd(0x02, 0xF8); + unlock(); +} + +static void readbuffer0(u16 cmd) { + u32 etcmd; + u32 length; + + length = OSRoundUp32B(recvlen0); + etcmd = 0x80000000 | (cmd << 8); + + EXISelect(0, 2, 5); + EXIImm(0, &etcmd, sizeof(etcmd), EXI_WRITE, NULL); + EXISync(0); + EXIDma(0, tmppool0, length, EXI_READ, recvlen1 != 0 ? &readbuffersub : &readbuffer1); +} + +static void readbuffersub(s32 chan, OSContext* context) { + u32 etcmd; + u32 length; + + length = OSRoundUp32B(recvlen1); + EXIDeselect(0); + + etcmd = 0x80000000 | (0x0100 << 8); + EXISelect(0, 2, 5); + EXIImm(0, &etcmd, sizeof(etcmd), EXI_WRITE, NULL); + EXISync(0); + EXIDma(0, tmppool1, length, EXI_READ, readbuffer1); + __ETHInterruptTime = OSGetTime() - __OSLastInterruptTime; +} + +static void readbuffer1(s32 chan, OSContext* context) { + EXIDeselect(0); + + DCInvalidateRange(tmppool0, OSRoundUp32B(recvlen0)); + if (recvlen1 != 0) { + DCInvalidateRange(tmppool1, OSRoundUp32B(recvlen1)); + } + + if (recvcallback1) { + memcpy(recvaddr, tmppool0, recvlen0); + if (recvlen1 != 0) { + memcpy(recvaddr + recvlen0, tmppool1, recvlen1); + } + __ETHFilter(recvaddr, d2.packetlength); + (*recvcallback1)(recvaddr, d2.packetlength); + } + + rrp = d2.nextpacket; + rwp = readcmd16(0x16); + recvsub1(); + __ETHInterruptTime = OSGetTime() - __OSLastInterruptTime; +} + +#include + +static void patchthru(void) { + u32 rnda; + u32 fa; + + writeEXIcmd(0x05, __acstart); + readEXIcmdLong(0x08, &rnda, sizeof(rnda)); + fa = hashfunc(rnda); + writeEXIcmdLong(0x09, &fa, sizeof(fa)); +} + +static void exiinthandler(s32 chan, OSContext* context) { + u8 ir; + u8 exiisr; + BOOL ret; + BOOL sendcbflag; + u8 ltps; + u8 lrps; + u8 result; + void (*callback)(u8); + + sendcbflag = FALSE; + ret = EXILock(0, 2, &exiinthandler); + if (ret != FALSE) { + exiisr = readEXIcmd(0x03); + writeEXIcmd(0x02, 0x00); + + switch (__cntlzw(exiisr)) { + case 0x18: { + writeEXIcmd(0x03, 0x80); + break; + } + + case 0x1A: { + writeEXIcmd(0x03, 0x20); + writeEXIcmd(0x02, 0xF8); + unlock(); + #ifdef DEBUG + OSPanic(__FILE__, 765, "exi cmderr\n"); + #endif + return; + } + + case 0x19: { + writeEXIcmd(0x03, 0x40); + writeEXIcmd(0x02, 0xF8); + unlock(); + return; + } + + case 0x1B: { + patchthru(); + writeEXIcmd(0x03, 0x10); + writeEXIcmd(0x02, 0xF8); + unlock(); + return; + } + + case 0x1C: { + result = readEXIcmd(0x0B); + writeEXIcmd(0x03, 0x08); + writeEXIcmd(0x02, 0xF8); + unlock(); + + if (result != 1) { + #ifdef DEBUG + OSPanic(__FILE__, 785, "ETHLIB: hash func error\n"); + #endif + } + + return; + } + } + + ir = readcmd(0x0009); + if (__recvpriorityflag == TRUE && (ir & 2) != 0) { + ethstat.rcvcount++; + recvsub0(); + __ETHInterruptTime = OSGetTime() - __OSLastInterruptTime; + } else { + switch (__cntlzw(ir)) { + case 0x18: { + ethstat.rbf++; + writecmd(0x0009, 0x80); + break; + } + + case 0x19: { + writecmd(0x0009, 0x40); + break; + } + + case 0x1A: { + ethstat.fifoe++; + writecmd(0x0009, 0x20); + break; + } + + case 0x1B: { + ethstat.te++; + //ASSERTLINE(816, __sendbusy); + __sendbusy = FALSE; + ltps = readcmd(0x0004); + + if ((ltps & 0x10) != 0) { + ethstat.tx_crs++; + } + + if ((ltps & 0x20) != 0) { + ethstat.tx_uf++; + } + + if ((ltps & 0x40) != 0) { + ethstat.tx_owc++; + } + + sendcbflag = TRUE; + writecmd(0x0009, 0x10); + break; + } + + case 0x1C: { + ethstat.re++; + + lrps = readcmd(0x0005); + if ((lrps & 1) != 0) { + ethstat.rx_bf++; + } + + if ((lrps & 2) != 0) { + ethstat.rx_crc++; + } + + if ((lrps & 4) != 0) { + ethstat.rx_fae++; + } + + if ((lrps & 8) != 0) { + ethstat.rx_fo++; + } + + if ((lrps & 0x10) != 0) { + ethstat.rx_rw++; + } + + if ((lrps & 0x40) != 0) { + ethstat.rx_rf++; + } + + writecmd(0x0009, 0x08); + break; + } + + case 0x1D: { + //ASSERTLINE(868, __sendbusy); + ethstat.sendcount++; + __sendbusy = FALSE; + sendcbflag = TRUE; + ltps = readcmd(0x0004); + writecmd(0x0009, 0x04); + break; + } + + case 0x1E: { + ethstat.rcvcount++; + recvsub0(); + return; + } + + case 0x1F: { + ethstat.cntof++; + writecmd(0x0009, 0x01); + break; + } + } + + writeEXIcmd(0x02, 0xF8); + unlock(); + + if (sendcbflag) { + callback = __sendcallback; + __sendcallback = NULL; + __ETHPostSend(ltps, callback, __sendadr); + } + + __ETHInterruptTime = OSGetTime() - __OSLastInterruptTime; + } + } +} + +s32 ETHInit(s32 mode) { + static BOOL initialized = FALSE; + u32 cid; + u8 fcsr; + u8 phy0r; + + if (initialized == FALSE) { + initialized = TRUE; + OSRegisterVersion(__ETHVersion); + } + + OSInitThreadQueue(&threadQ); + __SIRegs[15] = __SIRegs[15] & ~0x80000000; // turn on 32MHz EXI clock setting allowance + waitexilock(); + __sendbusy = FALSE; + memset(ðstat, 0, sizeof(ethstat)); + protoarray = NULL; + protonum = 0; + recvcallback0 = NULL; + recvcallback1 = NULL; + + cid = 0; + EXIGetID(0, 2, &cid); + if (cid != EXI_ETHER) { + unlock(); + OSReport("cid = %08x\n", cid); + return -1; + } else { + reset(); + readcmdLong(0x0020, private_macaddr, sizeof(private_macaddr)); + __revid = readEXIcmd(0x01); + writeEXIcmdLong(0x04, &__devid, sizeof(__devid)); + writeEXIcmd(0x05, __acstart); + + fcsr = readcmd(0x005B); + fcsr &= ~0x80; + writecmd(0x005B, fcsr); + writecmd(0x005E, 0x01); + + phy0r = readcmd(0x005C); + phy0r |= 0x04; + writecmd(0x005C, phy0r); + + writecmd(0x0001, 0x00); + writecmd(0x0003, 0x2E); + writecmd(0x0050, 0x80); + writecmd(0x0008, 0x00); + writeEXIcmd(0x02, 0xF8); + EXISetExiCallback(2, (EXICallback)&exiinthandler); + unlock(); + + return ETH_OK; + } +} + +void ETHSendAsync(void* addr, s32 length, void (*callback2)(u8)) { + BOOL disabled; + + //ASSERTLINE(985, !__sendbusy); + //ASSERTLINE(986, ((u32) addr % 32) == 0); + DCStoreRange(addr, length); + + disabled = OSDisableInterrupts(); + __sendbusy = TRUE; + __sendadr = addr; + __sendlen = length < 60 ? 60 : length; + __sendcallback = callback2; + sendUpdate = TRUE; + + if (lock()) { + unlock(); + } + + OSRestoreInterrupts(disabled); +} + +static void sendsub0(void) { + u32 etcmd; + + __senddmalen = OSRoundDown32B(__sendlen); + __sendimmlen = __sendlen - __senddmalen; + + etcmd = 0xC0000000 | (0x0048 << 8); + EXISelect(0, 2, 5); + EXIImm(0, &etcmd, sizeof(etcmd), EXI_WRITE, NULL); + EXISync(0); + EXIDma(0, __sendadr, __senddmalen, EXI_WRITE, &sendsub1); +} + +static void sendsub1(s32 chan, OSContext* context) { + u8 ncra; + + if (__sendimmlen != 0) { + EXIImmEx(0, __sendadr + __senddmalen, __sendimmlen, EXI_WRITE); + } + + EXIDeselect(0); + ncra = readcmd(0x0000); + //ASSERTLINE(1033, (ncra & ME_NCRA_TXFIFO) == 0); + ncra |= ME_NCRA_TXFIFO; + writecmd(0x0000, ncra); + unlock(); +} + +void ETHGetMACAddr(u8* macaddr) { + memcpy(macaddr, private_macaddr, sizeof(private_macaddr)); +} + +void ETHSetMACAddr(u8* macaddr) { + memcpy(private_macaddr, macaddr, sizeof(private_macaddr)); + waitexilock(); + writecmdLong(0x0020, private_macaddr, sizeof(private_macaddr)); + unlock(); +} + +void ETHSetRecvCallback(void* (*cb0)(u16, s32, u8), void (*cb1)(u8*, s32)) { + BOOL disabled; + + disabled = OSDisableInterrupts(); + recvcallback0 = cb0; + recvcallback1 = cb1; + recvcallbackUpdate = TRUE; + + if (lock()) { + unlock(); + } + + OSRestoreInterrupts(disabled); +} + +static BOOL linkState(void) { + u8 nways; + + nways = readcmd(0x0031); + if ((nways & 1) != 0 || (nways & 2) != 0) { + return TRUE; + } + + return FALSE; +} + +static BOOL ETHGetLinkState(void) { + BOOL ret; + + waitexilock(); + ret = linkState(); + unlock(); + return ret; +} + +static BOOL linkStateAsyncMain(BOOL* linkstateptr) { + if (EXILock(0, 2, NULL)) { + *linkstateptr = linkState(); + unlock(); + return TRUE; + } + + return FALSE; +} + +BOOL ETHGetLinkStateAsync(BOOL* status) { + //ASSERTLINE(1104, status); + return linkStateAsyncMain(status); +} + +s32 ETHGetNWAYMode(void) { + u8 nways; + + waitexilock(); + nways = readcmd(0x0031); + unlock(); + + if ((nways & 0x10) != 0) { + return 1; + } + + if ((nways & 0x20) != 0) { + return 2; + } + + if ((nways & 0x40) != 0) { + return 3; + } + + if ((nways & 0x80) != 0) { + return 4; + } + + return 5; +} + +void ETHSetProtoType(u16* array, s32 num) { + BOOL flag; + + //ASSERTLINE(1139, (num != 0 && array != NULL) || (num == 0 && array == NULL)); + flag = OSDisableInterrupts(); + protoarray = array; + protonum = num; + OSRestoreInterrupts(flag); +} + +void ETHGetStatus(ETHStat* stat) { + BOOL flag; + + //ASSERTLINE(1150, stat); + flag = OSDisableInterrupts(); + *stat = ethstat; + OSRestoreInterrupts(flag); +} + +s32 ETHGetLibraryVersion(void) { + return 0x506; +} + +s32 ETHGetBBAType(void) { + return 2; +} + +static u16 HashIndex(const u8* address) { + u32 crc; + u16 index; + u32 msb; + u8 byte; + s32 byteLen; + s32 bit; + s32 shift; + + crc = 0xFFFFFFFF; + index = 0; + + for (byteLen = 0; byteLen < 6; byteLen++, address++) { + byte = *address; + bit = 0; + for (bit = 0; bit < 8; bit++, byte >>= 1) { + msb = (crc >> 31) & 1; + crc = crc << 1; + + if (msb ^ (byte & 1)) { + crc ^= 0x04C11DB6; + crc |= 1; + } + } + } + + bit = 31; + for (shift = 5; shift >= 0; shift--, bit--) { + index |= ((crc >> bit) & 1) << shift; + } + + return index; +} + +void ETHAddMulticastAddress(const u8* macaddr) { + BOOL disabled; + u16 index; + u8 marNo; + u8 bitNo; + u8 ncrb; + + if (memcmp(macaddr, broadcastheader, sizeof(broadcastheader)) == 0) { + waitexilock(); + ncrb = readcmd(0x0001); + ncrb |= 4; + writecmd(0x0001, ncrb); + unlock(); + } else { + index = HashIndex(macaddr); + marNo = index / 8; + bitNo = index % 8; + disabled = OSDisableInterrupts(); + mcastmap[marNo] |= 1 << bitNo; + mcastUpdate = TRUE; + + if (lock()) { + unlock(); + } + + OSRestoreInterrupts(disabled); + } +} + +void ETHChangeIntPriority(BOOL flag) { + __recvpriorityflag = flag; +} + +u32 ETHGetREVID(void) { + u32 revid; + + waitexilock(); + revid = readEXIcmd(0x01); + unlock(); + return revid; +} + +void ETHClearMulticastAddresses(void) { + BOOL disabled; + + disabled = OSDisableInterrupts(); + memset(mcastmap, 0, sizeof(mcastmap)); + mcastUpdate = TRUE; + if (lock()) { + unlock(); + } + OSRestoreInterrupts(disabled); +} + +static void unlockcallback(s32 chan, OSContext* context) { + if (lock()) { + unlock(); + } +} + +static BOOL lock() { + return EXILock(0, 2, &unlockcallback); +} + +static void unlock(void) { + BOOL disabled; + + disabled = OSDisableInterrupts(); + + if (mcastUpdate) { + mcastUpdate = FALSE; + writecmdLong(0x0026, mcastmap, sizeof(mcastmap)); + } + + if (recvcallbackUpdate) { + recvcallbackUpdate = FALSE; + + if (recvcallback0 == NULL) { + writecmd(0x0000, 0x00); + writecmd(0x0008, 0x14); + } else { + //ASSERTLINE(1308, recvcallback0 != NULL && recvcallback1 != NULL); + writecmd(0x0008, 0xFF); + recvinit(); + } + } + + if (sendUpdate) { + sendUpdate = FALSE; + sendsub0(); + } else { + EXIUnlock(0); + if (lockUpdate) { + lockUpdate = FALSE; + OSWakeupThread(&threadQ); + } + } + + OSRestoreInterrupts(disabled); +} diff --git a/libs/dolphin/eth/ethsec.c b/libs/dolphin/eth/ethsec.c new file mode 100644 index 000000000..b86953b5e --- /dev/null +++ b/libs/dolphin/eth/ethsec.c @@ -0,0 +1,344 @@ +#include +#include +#include +#include +#include + +#include + +#define IP_MIN_HLEN (s32)sizeof(IPHeader) +#define TCP_MIN_HLEN (s32)sizeof(TCPHeader) + +static TCPResetInfo Ri; +static u8 SendBuf[82]; +static const u8 NintendoAddr[6] = { 0,9,191,0,0,0 }; + +extern u32 __OSGetDIConfig(void); +vu16 __OSDeviceCode : (OS_BASE_CACHED | 0x30E6); + +static inline BOOL CheckConsoleType() { + if (__OSGetDIConfig() == 0xFF) { + switch (__OSDeviceCode) { + case 0x8200: { + return TRUE; + } + case 0x8001: { + if (OSGetPhysicalMemSize() == 0x3000000) { + return TRUE; + } + return FALSE; + } + } + return FALSE; + } + + if ((OSGetConsoleType() & OS_CONSOLE_MASK) == 0) { + return FALSE; + } + + return TRUE; +} + +static s16 AT_IP4_IsMyAddrMask(u8 val) { return 0; } + +/*static inline BOOL IPIsLocalAddr(u32, const u8 *addr) { + return AT_IP4_IsMyAddrMask(*addr) != -1; +}*/ + +static u16 CalcIpCheckSum(IPHeader *ip) { + int len; + u32 sum; + u16 *p; + + sum = 0; + len = (ip->verlen & 0xf) << 2; + p = (u16*)ip; + + while (len > 0) { + sum += *p++; + len -= 2; + } + + sum = (sum & 0xffff) + (sum >> 16); + sum = ((sum & 0xffff) + (sum >> 16)); + return sum ^ 0xffff; +} + +static u16 CalcTcpCheckSum(IPHeader *ip, s32 len) { + s32 hlen; + u16 *p; + u32 sum = 0; + +#line 212 + ASSERT(IP_MIN_HLEN + TCP_MIN_HLEN <= len); +#line 215 + ASSERT(ip->proto == IP_PROTO_TCP); + + hlen = (ip->verlen & 0xf) << 2; + sum += ((u16*)ip->src)[0]; + sum += ((u16*)ip->src)[1]; + sum += ((u16*)ip->dst)[0]; + sum += ((u16*)ip->dst)[1]; + sum += 6; + sum += (u32)len - (u32)hlen; + + p = (u16*)((u32)ip+hlen); + len = len - hlen; + while (len > 1) { + sum += *p++; + len -= 2; + } + + if (len == 1) { + sum += *((u8*)p) * 0x100; + } + + sum = (sum & 0xffff) + (sum >> 16); + sum = (sum & 0xffff) + (sum >> 16); + return sum ^ 0xffff; +} + +static s32 GetTcpSegLen(IPHeader *ip, TCPHeader *tcp) { + s32 len = ip->len - ((ip->verlen & 0xf) << 2) - (s32)(((tcp->flag & 0xf000) >> 10)); + + if (tcp->flag & 2) { + len += 1; + } + + if (tcp->flag & 1) { + len += 1; + } + + return len; +} + +static BOOL VerifyPacket(IPHeader *ip) { + if(ip->verlen >> 4 != 4 || ip->len < ((ip->verlen & 0xf) << 2)) { + return TRUE; + } + + if (CalcIpCheckSum(ip) != 0) { + return TRUE; + } + + if ((ip->dst[0] & 0xf0) == 0xe0 || (ip->src[0] & 0xf0) == 0xe0 || + (ip->dst[0] & 0xf8) == 0xf0 || (ip->src[0] & 0xf8) == 0xf0) { + return TRUE; + } + + ASSERT(ip->proto == IP_PROTO_TCP); + if (CalcTcpCheckSum(ip, ip->len) != 0) { + return TRUE; + } + + return FALSE; +} + +static void CalcDigest(u8 *digest, TCPHeader *tcp) { + MD5Context context; + u64 secret; + + MD5Init(&context); + MD5Update(&context,(u8*)&tcp->seq,sizeof(tcp->seq)); + MD5Update(&context,(u8*)&tcp->ack,sizeof(tcp->ack)); + + secret = ((tcp->seq ^ tcp->ack) * 0x5DEECE66Dll + 0xb) % 0x1000000000000ll; + MD5Update(&context,(u8 *)&secret + 2, sizeof(secret) - 2); + MD5Final(digest,&context); +} + +BOOL __ETHFilter(u8 *buf, s32 len) { + ETHHeader *eh; + IPHeader *ip; + TCPHeader *tcp; + TCPResetInfo *ri; + u8 digest1[16]; + u8 digest2[16]; + + ri = &Ri; + if (CheckConsoleType()) { + return TRUE; + } + + eh = (ETHHeader *)buf; + if (eh->type != 0x800) { + return TRUE; + } + + if (memcmp(eh->src, NintendoAddr, 3) == 0) { + return TRUE; + } + + len = len - sizeof(ETHHeader); + ip = (IPHeader *)(eh + 1); + if (len < IP_MIN_HLEN || len < ip->len) { + return TRUE; + } + + if(ip->proto != IP_PROTO_TCP) { + return TRUE; + } + + tcp = (TCPHeader *)((u32)ip + ((ip->verlen & 0xf) << 2)); + if ((s32)(((tcp->flag & 0xf000) >> 10)) < TCP_MIN_HLEN) { + return TRUE; + } + + if (ip->len < ((ip->verlen & 0xf) << 2) + (s32)(((tcp->flag & 0xf000) >> 10))) { + return TRUE; + } + + if ((tcp->flag & 3) == 2) { + switch(tcp->src) { + case 0x76c: + case 0x35: + return TRUE; + } + + switch (tcp->dst) { + case 0x76c: + return TRUE; + } + + if (IPIsLocalAddr(0, ip->src) == FALSE) { + return TRUE; + } + + if (tcp->flag & 4) { + return TRUE; + } + + if (VerifyPacket(ip)) { + return TRUE; + } + + if (ri->flag == 0) { + memmove(ri->addr, eh->src, sizeof(ri->addr)); + memmove(ri->dstAddr, ip->dst, sizeof(ri->dstAddr)); + memmove(ri->srcAddr, ip->src, sizeof(ri->dstAddr)); + ri->dstPort = tcp->dst; + ri->srcPort = tcp->src; + + if ((tcp->flag & 0x10) == 0) { + ri->seq = 0; + ri->ack = tcp->seq + GetTcpSegLen(ip, tcp); + ri->flag = (0x10 | 0x2 | 0x1); + } + else { + ri->seq = tcp->ack; + ri->ack = 0; + ri->flag = (0x2 | 0x1); + } + ri->id = 0; + return TRUE; + } + ip->len = 0; + return FALSE; + } + + if ((tcp->flag & 3) == 3) { + if ((s32)(((tcp->flag & 0xf000) >> 10)) != TCP_MIN_HLEN) { + return TRUE; + } + + if (ip->len != 0x40) { + return TRUE; + } + + if (IPIsLocalAddr(0, ip->src) == FALSE) { + return TRUE; + } + + if (VerifyPacket(ip)) { + return TRUE; + } + + CalcDigest(digest1, tcp); + __IPDecodeFromBase64(tcp + 1, 0x18, digest2); + + if (memcmp(digest1, digest2, sizeof(digest1))) { + return TRUE; + } + ip->len = 0; + return FALSE; + } + return TRUE; +} + +BOOL __ETHPostSend(u8 ltps , void (*callback)(u8), void *prev) { + ETHHeader *eh; + IPHeader *ip; + TCPHeader *tcp; + TCPResetInfo *ri; + u8 digest[16]; + + ri = &Ri; + + if (ri->flag == 0) { + ri = NULL; + } + else if (prev != SendBuf) { + eh = prev; + ip = (IPHeader *)(eh + 1); + tcp = (TCPHeader *)(ip + 1); + if (*((u32*)ip->dst) == *((u32*)ri->srcAddr) && *((u32*)ip->src) == *((u32*)ri->dstAddr) + && tcp->src == ri->dstPort && tcp->dst == ri->srcPort) { + + if (tcp->flag & 4) { + ri->flag = 0; + ri = NULL; + } + else { + ri->seq = tcp->seq + GetTcpSegLen(ip, tcp); + ri->ack = tcp->ack; + ri->flag |= tcp->flag & 0x10; + + ri->id = ip->id - 0x4000; + if (ri->id == 0) { + ri->id = 1; + } + } + } + } + + if (ri != NULL && ri->id != 0) { + eh = (ETHHeader *)SendBuf; + ip = (IPHeader *)(eh + 1); + eh->type = 0x800; + memmove(SendBuf, ri, 6); + ETHGetMACAddr(eh->src); + + ip->verlen = 0x45; + ip->tos = 0; + ip->len = 0x40; + ip->id = ri->id; + ip->frag = 0x4000; + ip->ttl = 0xff; + ip->proto = IP_PROTO_TCP; + ip->sum = 0; + memmove(ip->dst, ri->srcAddr, sizeof(ip->dst)); + memmove(ip->src, ri->dstAddr, sizeof(ip->src)); + + + tcp = (TCPHeader *)((u32)ip + ((ip->verlen & 0xf) << 2)); + tcp->src = ri->dstPort; + tcp->dst = ri->srcPort; + tcp->seq = ri->seq; + tcp->ack = ri->ack; + tcp->flag = ri->flag & 0x3f | 0x5000; + tcp->win = 0; + tcp->sum = 0; + tcp->urg = 0; + + CalcDigest(digest, tcp); + __IPEncodeToBase64(digest, sizeof(digest), tcp + 1); + ip->sum = CalcIpCheckSum(ip); + tcp->sum = CalcTcpCheckSum(ip, ip->len); + ri->flag = 0; + ETHSendAsync(SendBuf, 0x4e, callback); + } + else if (callback) { + (*callback)(ltps); + } + return ETH_OK; +} diff --git a/libs/dolphin/eth/md5.c b/libs/dolphin/eth/md5.c new file mode 100644 index 000000000..11c6c616d --- /dev/null +++ b/libs/dolphin/eth/md5.c @@ -0,0 +1,285 @@ +/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + rights reserved. + + License to copy and use this software is granted provided that it + is identified as the "RSA Data Security, Inc. MD5 Message-Digest + Algorithm" in all material mentioning or referencing this software + or this function. + + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD5 Message-Digest Algorithm" in all material + mentioning or referencing the derived work. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + */ + +#include +#include + +/* Constants for MD5Transform routine. + */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +static void MD5Transform (u32 state[4], u8 block[64]); +static void Encode(u8* output, u32* input, u32 len); +static void Decode(u32* output, u8* input, u32 len); + +static u8 PADDING[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* F, G, H and I are basic MD5 functions. + */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. + */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +Rotation is separate from addition to prevent recomputation. + */ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (u32)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (u32)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (u32)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (u32)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +/* MD5 initialization. Begins an MD5 operation, writing a new context. + */ +void MD5Init(MD5_CTX *context) +/* context: context */ +{ + context->count[0] = context->count[1] = 0; + /* Load magic initialization constants. */ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* MD5 block update operation. Continues an MD5 message-digest + operation, processing another message block, and updating the + context. + */ +void MD5Update(MD5_CTX *context, u8 *input, u32 inputLen) +/* context: context */ +/* input: input block */ +/* inputlen: length of input block */ +{ + u32 i, index, partLen; + + /* Compute number of bytes mod 64 */ + index = (u32)((context->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + if ((context->count[0] += ((u32)inputLen << 3)) < ((u32)inputLen << 3)) + context->count[1]++; + context->count[1] += ((u32)inputLen >> 29); + partLen = 64 - index; + + /* Transform as many times as possible. */ + if (inputLen >= partLen) { + memcpy(&context->buffer[index], input, partLen); + MD5Transform(context->state, context->buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) { + MD5Transform (context->state, &input[i]); + } + + index = 0; + } else { + i = 0; + } + + /* Buffer remaining input */ + memcpy(&context->buffer[index], &input[i], inputLen - i); +} + +/* MD5 finalization. Ends an MD5 message-digest operation, writing the + the message digest and zeroizing the context. + */ +void MD5Final(u8 digest[16], MD5_CTX *context) +/* digest: message digest */ +/* context: context */ +{ + u8 bits[8]; + u32 index, padLen; + + /* Save number of bits */ + Encode (bits, context->count, 8); + + /* Pad out to 56 mod 64. */ + index = (u32)((context->count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + MD5Update (context, PADDING, padLen); + + /* Append length (before padding) */ + MD5Update (context, bits, 8); + + /* Store state in digest */ + Encode (digest, context->state, 16); + + /* Zeroize sensitive information. */ + memset(context, 0, sizeof(*context)); +} + +/* MD5 basic transformation. Transforms state based on block. + */ +static void MD5Transform (u32 state[4], u8 block[64]) +{ + u32 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode (x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information. */ + memset(x, 0, sizeof(x)); +} + +/* Encodes input (u32) into output (u8). Assumes len is + a multiple of 4. + */ +static void Encode(u8* output, u32* input, u32 len) +{ + u32 i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (u8)(input[i] & 0xff); + output[j+1] = (u8)((input[i] >> 8) & 0xff); + output[j+2] = (u8)((input[i] >> 16) & 0xff); + output[j+3] = (u8)((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (u8) into output (u32). Assumes len is + a multiple of 4. + */ +static void Decode(u32* output, u8* input, u32 len) +{ + u32 i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((u32)input[j]) | (((u32)input[j+1]) << 8) | + (((u32)input[j+2]) << 16) | (((u32)input[j+3]) << 24); +} diff --git a/libs/dolphin/exi/EXIUart.c b/libs/dolphin/exi/EXIUart.c index 73efc2cef..4f3b88b2b 100644 --- a/libs/dolphin/exi/EXIUart.c +++ b/libs/dolphin/exi/EXIUart.c @@ -111,7 +111,7 @@ u32 InitializeUART(u32 baudRate) } } -static int QueueLength(void) +inline int QueueLength(void) { u32 cmd; diff --git a/libs/dolphin/gd/GDBase.c b/libs/dolphin/gd/GDBase.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/gd/GDGeometry.c b/libs/dolphin/gd/GDGeometry.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/hio/hio.c b/libs/dolphin/hio/hio.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IFFifo.c b/libs/dolphin/ip/IFFifo.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IFRing.c b/libs/dolphin/ip/IFRing.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IP.c b/libs/dolphin/ip/IP.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPArp.c b/libs/dolphin/ip/IPArp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPChap.c b/libs/dolphin/ip/IPChap.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPDhcp.c b/libs/dolphin/ip/IPDhcp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPDns.c b/libs/dolphin/ip/IPDns.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPEther.c b/libs/dolphin/ip/IPEther.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPFrag.c b/libs/dolphin/ip/IPFrag.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPIcmp.c b/libs/dolphin/ip/IPIcmp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPIgmp.c b/libs/dolphin/ip/IPIgmp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPIpcp.c b/libs/dolphin/ip/IPIpcp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPLcp.c b/libs/dolphin/ip/IPLcp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPOpt.c b/libs/dolphin/ip/IPOpt.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPPPP.c b/libs/dolphin/ip/IPPPP.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPPPPoE.c b/libs/dolphin/ip/IPPPPoE.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPPap.c b/libs/dolphin/ip/IPPap.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPRoute.c b/libs/dolphin/ip/IPRoute.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPSocket.c b/libs/dolphin/ip/IPSocket.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPTcp.c b/libs/dolphin/ip/IPTcp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPTcpOutput.c b/libs/dolphin/ip/IPTcpOutput.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPTcpTimeWait.c b/libs/dolphin/ip/IPTcpTimeWait.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPTcpTimer.c b/libs/dolphin/ip/IPTcpTimer.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPTcpUser.c b/libs/dolphin/ip/IPTcpUser.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPUdp.c b/libs/dolphin/ip/IPUdp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPUuid.c b/libs/dolphin/ip/IPUuid.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/ip/IPZero.c b/libs/dolphin/ip/IPZero.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/lg/allsrc.c b/libs/dolphin/lg/allsrc.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/os/OSError.c b/libs/dolphin/os/OSError.c index ec942ba48..13c76acce 100644 --- a/libs/dolphin/os/OSError.c +++ b/libs/dolphin/os/OSError.c @@ -10,6 +10,7 @@ volatile OSContext* __OSFPUContext : (OS_BASE_CACHED | 0x00D8); OSErrorHandler __OSErrorTable[OS_ERROR_MAX]; #define FPSCR_ENABLE (FPSCR_VE | FPSCR_OE | FPSCR_UE | FPSCR_ZE | FPSCR_XE) u32 __OSFpscrEnableBits = FPSCR_ENABLE; +extern volatile OSTime __OSLastInterruptTime; __declspec(weak) void OSReport(const char* msg, ...) { diff --git a/libs/dolphin/os/OSFont.c b/libs/dolphin/os/OSFont.c index aaf0a51a6..1457efe4f 100644 --- a/libs/dolphin/os/OSFont.c +++ b/libs/dolphin/os/OSFont.c @@ -1,7 +1,6 @@ #include #include -#include #include typedef char* (*ParseStringCallback)(u16, char*, OSFontHeader**, int*); diff --git a/libs/dolphin/os/__os.h b/libs/dolphin/os/__os.h deleted file mode 100644 index 9808a40da..000000000 --- a/libs/dolphin/os/__os.h +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef _DOLPHIN_OS_INTERNAL_H_ -#define _DOLPHIN_OS_INTERNAL_H_ - -#include -#include -#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/libs/dolphin/os/init/__ppc_eabi_init.cpp b/libs/dolphin/os/init/__ppc_eabi_init.cpp index e276d4a6b..6f5b2765a 100644 --- a/libs/dolphin/os/init/__ppc_eabi_init.cpp +++ b/libs/dolphin/os/init/__ppc_eabi_init.cpp @@ -16,35 +16,37 @@ __declspec(section ".dtors") extern voidfunctionptr _dtors[]; static void __init_cpp(void); // clang-format off -__declspec(section ".init") asm void __init_hardware(void) { +__declspec(section ".init") asm void __init_hardware(void) +{ // clang-format off nofralloc mfmsr r0 - ori r0,r0,0x2000 + ori r0,r0,MSR_FP mtmsr r0 - mflr r31 - bl __OSPSInit - bl __OSFPRInit - bl __OSCacheInit - mtlr r31 + mflr r31 + bl __OSPSInit + bl __OSFPRInit + bl __OSCacheInit + mtlr r31 blr } -__declspec(section ".init") asm void __flush_cache(void) { - nofralloc - lis r5, 0xFFFFFFF1@h - ori r5, r5, 0xFFFFFFF1@l - and r5, r5, r3 - subf r3, r5, r3 - add r4, r4, r3 -loop: - dcbst 0, r5 - sync - icbi 0, r5 - addic r5, r5, 8 - addic. r4, r4, -8 - bge loop - isync - 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 } // clang-format on diff --git a/libs/dolphin/thp/THPAudio.c b/libs/dolphin/thp/THPAudio.c new file mode 100644 index 000000000..147d62180 --- /dev/null +++ b/libs/dolphin/thp/THPAudio.c @@ -0,0 +1,202 @@ +#include + +u32 THPAudioDecode(s16 *audioBuffer, u8 *audioFrame, s32 flag) +{ + THPAudioRecordHeader *header; + THPAudioDecodeInfo decInfo; + u8 *left, *right; + s16 *decLeftPtr, *decRightPtr; + s16 yn1, yn2; + s32 i; + s32 step; + s32 sample; + s64 yn; + + if (audioBuffer == NULL || audioFrame == NULL) + { + return 0; + } + + header = (THPAudioRecordHeader *)audioFrame; + left = audioFrame + sizeof(THPAudioRecordHeader); + right = left + header->offsetNextChannel; + + if (flag == 1) + { + decRightPtr = audioBuffer; + decLeftPtr = audioBuffer + header->sampleSize; + step = 1; + } + else + { + decRightPtr = audioBuffer; + decLeftPtr = audioBuffer + 1; + step = 2; + } + + if (header->offsetNextChannel == 0) + { + __THPAudioInitialize(&decInfo, left); + + yn1 = header->lYn1; + yn2 = header->lYn2; + + for (i = 0; i < header->sampleSize; i++) + { + sample = __THPAudioGetNewSample(&decInfo); + yn = header->lCoef[decInfo.predictor][1] * yn2; + yn += header->lCoef[decInfo.predictor][0] * yn1; + yn += (sample << decInfo.scale) << 11; + yn <<= 5; + + if ((u16)(yn & 0xffff) > 0x8000) + { + yn += 0x10000; + } + else if ((u16)(yn & 0xffff) == 0x8000) + { + if ((yn & 0x10000)) + yn += 0x10000; + } + + if (yn > 2147483647LL) + { + yn = 2147483647LL; + } + + if (yn < -2147483648LL) + { + yn = -2147483648LL; + } + + *decLeftPtr = (s16)(yn >> 16); + decLeftPtr += step; + *decRightPtr = (s16)(yn >> 16); + decRightPtr += step; + yn2 = yn1; + yn1 = (s16)(yn >> 16); + } + } + else + { + __THPAudioInitialize(&decInfo, left); + + yn1 = header->lYn1; + yn2 = header->lYn2; + + for (i = 0; i < header->sampleSize; i++) + { + sample = __THPAudioGetNewSample(&decInfo); + yn = header->lCoef[decInfo.predictor][1] * yn2; + yn += header->lCoef[decInfo.predictor][0] * yn1; + yn += (sample << decInfo.scale) << 11; + yn <<= 5; + if ((u16)(yn & 0xffff) > 0x8000) + { + yn += 0x10000; + } + else + { + if ((u16)(yn & 0xffff) == 0x8000) + { + if ((yn & 0x10000)) + yn += 0x10000; + } + } + + if (yn > 2147483647LL) + { + yn = 2147483647LL; + } + + if (yn < -2147483648LL) + { + yn = -2147483648LL; + } + + *decLeftPtr = (s16)(yn >> 16); + decLeftPtr += step; + yn2 = yn1; + yn1 = (s16)(yn >> 16); + } + + __THPAudioInitialize(&decInfo, right); + + yn1 = header->rYn1; + yn2 = header->rYn2; + + for (i = 0; i < header->sampleSize; i++) + { + sample = __THPAudioGetNewSample(&decInfo); + yn = header->rCoef[decInfo.predictor][1] * yn2; + yn += header->rCoef[decInfo.predictor][0] * yn1; + yn += (sample << decInfo.scale) << 11; + yn <<= 5; + + if ((u16)(yn & 0xffff) > 0x8000) + { + yn += 0x10000; + } + else + { + if ((u16)(yn & 0xffff) == 0x8000) + { + if ((yn & 0x10000)) + yn += 0x10000; + } + } + + if (yn > 2147483647LL) + { + yn = 2147483647LL; + } + + if (yn < -2147483648LL) + { + yn = -2147483648LL; + } + + *decRightPtr = (s16)(yn >> 16); + decRightPtr += step; + yn2 = yn1; + yn1 = (s16)(yn >> 16); + } + } + + return header->sampleSize; +} + +static s32 __THPAudioGetNewSample(THPAudioDecodeInfo *info) +{ + s32 sample; + + if (!(info->offsetNibbles & 0x0f)) + { + info->predictor = (u8)((*(info->encodeData) & 0x70) >> 4); + info->scale = (u8)((*(info->encodeData) & 0xF)); + info->encodeData++; + info->offsetNibbles += 2; + } + + if (info->offsetNibbles & 0x1) + { + sample = (s32)((*(info->encodeData) & 0xF) << 28) >> 28; + info->encodeData++; + } + else + { + sample = (s32)((*(info->encodeData) & 0xF0) << 24) >> 28; + } + + info->offsetNibbles++; + return sample; +} + +static void __THPAudioInitialize(THPAudioDecodeInfo *info, u8 *ptr) +{ + info->encodeData = ptr; + info->offsetNibbles = 2; + info->predictor = (u8)((*(info->encodeData) & 0x70) >> 4); + info->scale = (u8)((*(info->encodeData) & 0xF)); + info->encodeData++; +} \ No newline at end of file diff --git a/libs/dolphin/thp/THPDec.c b/libs/dolphin/thp/THPDec.c new file mode 100644 index 000000000..10ceb6189 --- /dev/null +++ b/libs/dolphin/thp/THPDec.c @@ -0,0 +1,2316 @@ +#include +#include + +const char *__THPVersion = "<< Dolphin SDK - THP\trelease build: Aug 27 2002 20:42:01 >>"; + +static THPHuffmanTab *Ydchuff __attribute__((aligned(32))); +static THPHuffmanTab *Udchuff __attribute__((aligned(32))); +static THPHuffmanTab *Vdchuff __attribute__((aligned(32))); +static THPHuffmanTab *Yachuff __attribute__((aligned(32))); +static THPHuffmanTab *Uachuff __attribute__((aligned(32))); +static THPHuffmanTab *Vachuff __attribute__((aligned(32))); +static f32 __THPIDCTWorkspace[64] __attribute__((aligned(32))); +static u8 *__THPHuffmanBits; +static u8 *__THPHuffmanSizeTab; +static u16 *__THPHuffmanCodeTab; +static THPSample *Gbase __attribute__((aligned(32))); +static u32 Gwid __attribute__((aligned(32))); +static f32 *Gq __attribute__((aligned(32))); +static u8 *__THPLCWork512[3]; +static u8 *__THPLCWork672[3]; +static u32 __THPOldGQR5; +static u32 __THPOldGQR6; +static u8 *__THPWorkArea; +static THPCoeff *__THPMCUBuffer[6]; +static THPFileInfo *__THPInfo; +static BOOL __THPInitFlag = FALSE; + +#define ROUNDUP(a, b) ((((s32)(a)) + ((s32)(b)-1L)) / ((s32)(b))) + +void __THPInverseDCTY8(register THPCoeff *, register u32); + +s32 THPVideoDecode(void *file, void *tileY, void *tileU, void *tileV, void *work) +{ + u8 all_done, status; + s32 errorCode; + + if (!file) + { + goto _err_no_input; + } + + if (tileY == NULL || tileU == NULL || tileV == NULL) + { + goto _err_no_output; + } + + if (!work) + { + goto _err_no_work; + } + + if (!(PPCMfhid2() & 0x10000000)) + { + goto _err_lc_not_enabled; + } + + if (__THPInitFlag == FALSE) + { + goto _err_not_initialized; + } + + __THPWorkArea = (u8 *)work; + __THPInfo = (THPFileInfo *)OSRoundUp32B(__THPWorkArea); + __THPWorkArea = (u8 *)OSRoundUp32B(__THPWorkArea) + sizeof(THPFileInfo); + DCZeroRange(__THPInfo, sizeof(THPFileInfo)); + __THPInfo->cnt = 33; + __THPInfo->decompressedY = 0; + __THPInfo->c = (u8 *)file; + all_done = FALSE; + + for (;;) + { + if ((*(__THPInfo->c)++) != 255) + { + goto _err_bad_syntax; + } + + while (*__THPInfo->c == 255) + { + ((__THPInfo->c)++); + } + + status = (*(__THPInfo->c)++); + + if (status <= 0xD7) + { + if (status == 196) + { + status = __THPReadHuffmanTableSpecification(); + if (status != 0) + { + goto _err_bad_status; + } + } + + else if (status == 192) + { + status = __THPReadFrameHeader(); + if (status != 0) + { + goto _err_bad_status; + } + } + + else + { + goto _err_unsupported_marker; + } + } + + else if (0xD8 <= status && status <= 0xDF) + { + if (status == 221) + { + __THPRestartDefinition(); + } + + else if (status == 219) + { + status = __THPReadQuantizationTable(); + if (status != 0) + { + goto _err_bad_status; + } + } + + else if (status == 218) + { + status = __THPReadScaneHeader(); + if (status != 0) + { + goto _err_bad_status; + } + + all_done = TRUE; + } + else if (status == 216) + { + // empty but required for match + } + else + { + goto _err_unsupported_marker; + } + } + + else if (0xE0 <= status) + { + if ((224 <= status && status <= 239) || status == 254) + { + __THPInfo->c += (__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]; + } + else + { + goto _err_unsupported_marker; + } + } + + if (all_done) + { + break; + } + } + + __THPSetupBuffers(); + __THPDecompressYUV(tileY, tileU, tileV); + return 0; + +_err_no_input: + errorCode = 25; + goto _err_exit; + +_err_no_output: + errorCode = 27; + goto _err_exit; + +_err_no_work: + errorCode = 26; + goto _err_exit; + +_err_unsupported_marker: + errorCode = 11; + goto _err_exit; + +_err_bad_resource: + errorCode = 1; + goto _err_exit; + +_err_no_mem: + errorCode = 6; + goto _err_exit; + +_err_bad_syntax: + errorCode = 3; + goto _err_exit; + +_err_bad_status: + errorCode = status; + goto _err_exit; + +_err_lc_not_enabled: + errorCode = 28; + goto _err_exit; + +_err_not_initialized: + errorCode = 29; + goto _err_exit; + +_err_exit: + return errorCode; +} + +static void __THPSetupBuffers(void) +{ + u8 i; + THPCoeff *buffer; + + buffer = (THPCoeff *)OSRoundUp32B(__THPWorkArea); + + for (i = 0; i < 6; i++) + { + __THPMCUBuffer[i] = &buffer[i * 64]; + } +} + +u8 __THPReadFrameHeader(void) +{ + u8 i, utmp8; + + __THPInfo->c += 2; + + utmp8 = (*(__THPInfo->c)++); + + if (utmp8 != 8) + { + return 10; + } + + __THPInfo->yPixelSize = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); + __THPInfo->c += 2; + __THPInfo->xPixelSize = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); + __THPInfo->c += 2; + + utmp8 = (*(__THPInfo->c)++); + if (utmp8 != 3) + { + return 12; + } + + for (i = 0; i < 3; i++) + { + utmp8 = (*(__THPInfo->c)++); + utmp8 = (*(__THPInfo->c)++); + if ((i == 0 && utmp8 != 0x22) || (i > 0 && utmp8 != 0x11)) + { + return 19; + } + + __THPInfo->components[i].quantizationTableSelector = (*(__THPInfo->c)++); + } + + return 0; +} + +/* there is an EXTREMELY tiny schedule swap but otherwise matching */ +u8 __THPReadScaneHeader(void) +{ + u8 i, utmp8; + __THPInfo->c += 2; + + utmp8 = (*(__THPInfo->c)++); + + if (utmp8 != 3) + { + return 12; + } + + for (i = 0; i < 3; i++) + { + utmp8 = (*(__THPInfo->c)++); + + utmp8 = (*(__THPInfo->c)++); + __THPInfo->components[i].DCTableSelector = (u8)(utmp8 >> 4); + __THPInfo->components[i].ACTableSelector = (u8)(utmp8 & 15); + + if ((__THPInfo->validHuffmanTabs & (1 << ((utmp8 >> 4)))) == 0) + { + return 15; + } + + if ((__THPInfo->validHuffmanTabs & (1 << ((utmp8 & 15) + 1))) == 0) + { + return 15; + } + } + + __THPInfo->c += 3; + __THPInfo->MCUsPerRow = (u16)ROUNDUP(__THPInfo->xPixelSize, 16); + __THPInfo->components[0].predDC = 0; + __THPInfo->components[1].predDC = 0; + __THPInfo->components[2].predDC = 0; + return 0; +} + +u8 __THPReadQuantizationTable(void) +{ + u16 length, id, i, row, col; + f32 q_temp[64]; + + length = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); + __THPInfo->c += 2; + length -= 2; + + for (;;) + { + id = (*(__THPInfo->c)++); + + for (i = 0; i < 64; i++) + { + q_temp[__THPJpegNaturalOrder[i]] = (f32)(*(__THPInfo->c)++); + } + + i = 0; + for (row = 0; row < 8; row++) + { + for (col = 0; col < 8; col++) + { + __THPInfo->quantTabs[id][i] = (f32)((f64)q_temp[i] * __THPAANScaleFactor[row] * __THPAANScaleFactor[col]); + i++; + } + } + + length -= 65; + if (!length) + { + break; + } + } + + return 0; +} + +u8 __THPReadHuffmanTableSpecification(void) +{ + u8 t_class, id, i, tab_index; + u16 length, num_Vij; + + __THPHuffmanSizeTab = __THPWorkArea; + __THPHuffmanCodeTab = (u16 *)((u32)__THPWorkArea + 256 + 1); + length = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); + __THPInfo->c += 2; + length -= 2; + + for (;;) + { + i = (*(__THPInfo->c)++); + id = (u8)(i & 15); + t_class = (u8)(i >> 4); + __THPHuffmanBits = __THPInfo->c; + tab_index = (u8)((id << 1) + t_class); + num_Vij = 0; + + for (i = 0; i < 16; i++) + { + num_Vij += (*(__THPInfo->c)++); + } + + __THPInfo->huffmanTabs[tab_index].Vij = __THPInfo->c; + __THPInfo->c += num_Vij; + __THPHuffGenerateSizeTable(); + __THPHuffGenerateCodeTable(); + __THPHuffGenerateDecoderTables(tab_index); + __THPInfo->validHuffmanTabs |= 1 << tab_index; + length -= 17 + num_Vij; + + if (length == 0) + { + break; + } + } + + return 0; +} + +static void __THPHuffGenerateSizeTable(void) +{ + s32 p, l, i; + p = 0; + + for (l = 1; l <= 16; l++) + { + i = (s32)__THPHuffmanBits[l - 1]; + while (i--) + { + __THPHuffmanSizeTab[p++] = (u8)l; + } + } + + __THPHuffmanSizeTab[p] = 0; +} + +static void __THPHuffGenerateCodeTable(void) +{ + u8 si; + u16 p, code; + + p = 0; + code = 0; + si = __THPHuffmanSizeTab[0]; + + while (__THPHuffmanSizeTab[p]) + { + while (__THPHuffmanSizeTab[p] == si) + { + __THPHuffmanCodeTab[p++] = code; + code++; + } + + code <<= 1; + si++; + } +} + +static void __THPHuffGenerateDecoderTables(u8 tabIndex) +{ + s32 p, l; + THPHuffmanTab *h; + + p = 0; + h = &__THPInfo->huffmanTabs[tabIndex]; + for (l = 1; l <= 16; l++) + { + if (__THPHuffmanBits[l - 1]) + { + h->valPtr[l] = p - __THPHuffmanCodeTab[p]; + p += __THPHuffmanBits[l - 1]; + h->maxCode[l] = __THPHuffmanCodeTab[p - 1]; + } + else + { + h->maxCode[l] = -1; + h->valPtr[l] = -1; + } + } + + h->maxCode[17] = 0xfffffL; +} + +static void __THPRestartDefinition(void) +{ + __THPInfo->RST = TRUE; + __THPInfo->c += 2; + __THPInfo->nMCU = (u16)((__THPInfo->c)[0] << 8 | (__THPInfo->c)[1]); + __THPInfo->c += 2; + __THPInfo->currMCU = __THPInfo->nMCU; +} + +static inline void __THPGQRSetup(void) +{ + register u32 tmp1, tmp2; + + asm { + mfspr tmp1, GQR5; + mfspr tmp2, GQR6; + } + + __THPOldGQR5 = tmp1; + __THPOldGQR6 = tmp2; + + asm { + li r3, 0x0007 + oris r3, r3, 0x0007 + mtspr GQR5, r3 + li r3, 0x3D04 + oris r3, r3, 0x3D04 + mtspr GQR6, r3 + } +} + +static inline void __THPGQRRestore(void) +{ + register u32 tmp1, tmp2; + tmp1 = __THPOldGQR5; + tmp2 = __THPOldGQR6; + + asm { + mtspr GQR5, tmp1; + mtspr GQR6, tmp2; + } +} + +void __THPPrepBitStream(void) +{ + u32 *ptr; + u32 offset, i, j, k; + + ptr = (u32 *)((u32)__THPInfo->c & 0xFFFFFFFC); + offset = (u32)__THPInfo->c & 3; + + if (__THPInfo->cnt != 33) + { + __THPInfo->cnt -= (3 - offset) * 8; + } + else + { + __THPInfo->cnt = (offset * 8) + 1; + } + + __THPInfo->c = (u8 *)ptr; + __THPInfo->currByte = *ptr; + + for (i = 0; i < 4; i++) + { + if (__THPInfo->validHuffmanTabs & (1 << i)) + { + for (j = 0; j < 32; j++) + { + __THPInfo->huffmanTabs[i].quick[j] = 0xFF; + + for (k = 0; k < 5; k++) + { + s32 code = (s32)(j >> (5 - k - 1)); + + if (code <= __THPInfo->huffmanTabs[i].maxCode[k + 1]) + { + __THPInfo->huffmanTabs[i].quick[j] = __THPInfo->huffmanTabs[i].Vij[(s32)(code + __THPInfo->huffmanTabs[i].valPtr[k + 1])]; + __THPInfo->huffmanTabs[i].increment[j] = (u8)(k + 1); + k = 99; + } + else + { + } + } + } + } + } + + { + s32 YdcTab, UdcTab, VdcTab, YacTab, UacTab, VacTab; + + YdcTab = (__THPInfo->components[0].DCTableSelector << 1); + UdcTab = (__THPInfo->components[1].DCTableSelector << 1); + VdcTab = (__THPInfo->components[2].DCTableSelector << 1); + + YacTab = (__THPInfo->components[0].ACTableSelector << 1) + 1; + UacTab = (__THPInfo->components[1].ACTableSelector << 1) + 1; + VacTab = (__THPInfo->components[2].ACTableSelector << 1) + 1; + + Ydchuff = &__THPInfo->huffmanTabs[YdcTab]; + Udchuff = &__THPInfo->huffmanTabs[UdcTab]; + Vdchuff = &__THPInfo->huffmanTabs[VdcTab]; + + Yachuff = &__THPInfo->huffmanTabs[YacTab]; + Uachuff = &__THPInfo->huffmanTabs[UacTab]; + Vachuff = &__THPInfo->huffmanTabs[VacTab]; + } +} + +void __THPDecompressYUV(void *tileY, void *tileU, void *tileV) +{ + u16 currentY, targetY; + __THPInfo->dLC[0] = tileY; + __THPInfo->dLC[1] = tileU; + __THPInfo->dLC[2] = tileV; + + currentY = __THPInfo->decompressedY; + targetY = __THPInfo->yPixelSize; + + __THPGQRSetup(); + __THPPrepBitStream(); + + if (__THPInfo->xPixelSize == 512 && targetY == 448) + { + while (currentY < targetY) + { + __THPDecompressiMCURow512x448(); + currentY += 16; + } + } + else if (__THPInfo->xPixelSize == 640 && targetY == 480) + { + while (currentY < targetY) + { + __THPDecompressiMCURow640x480(); + currentY += 16; + } + } + else + { + while (currentY < targetY) + { + __THPDecompressiMCURowNxN(); + currentY += 16; + } + } + + __THPGQRRestore(); +} + +inline void __THPInverseDCTNoYPos(register THPCoeff *in, register u32 xPos) +{ + register f32 *q, *ws; + register f32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; + register f32 tmp10, tmp11, tmp12, tmp13; + register f32 tmp20, tmp21, tmp22, tmp23; + register f32 cc4 = 1.414213562F; + register f32 cc2 = 1.847759065F; + register f32 cc2c6s = 1.082392200F; + register f32 cc2c6a = -2.613125930F; + register f32 bias = 1024.0F; + q = Gq; + ws = &__THPIDCTWorkspace[0] - 2; + + { + register u32 itmp0, itmp1, itmp2, itmp3; + asm { + li itmp2, 8 + mtctr itmp2 + + _loopHead0: + psq_l tmp10, 0(in), 0, 5 + psq_l tmp11, 0(q), 0, 0 + lwz itmp0, 12(in) + lwz itmp3, 8(in) + ps_mul tmp10, tmp10, tmp11 + lwz itmp1, 4(in) + lhz itmp2, 2(in) + or. itmp0, itmp0, itmp3 + + _loopHead1: + cmpwi itmp0, 0 + bne _regularIDCT + ps_merge00 tmp0, tmp10, tmp10 + cmpwi itmp1, 0 + psq_st tmp0, 8(ws), 0, 0 + bne _halfIDCT + psq_st tmp0, 16(ws), 0, 0 + cmpwi itmp2, 0 + psq_st tmp0, 24(ws), 0, 0 + bne _quarterIDCT + addi q, q, 8*sizeof(f32) + psq_stu tmp0, 32(ws), 0, 0 + addi in, in, 8*sizeof(THPCoeff) + bdnz _loopHead0 + b _loopEnd + + _quarterIDCT: + addi in, in, 8*sizeof(THPCoeff) + ps_msub tmp2, tmp10, cc2, tmp10 + addi q, q, 8*sizeof(f32) + ps_merge00 tmp9, tmp10, tmp10 + lwz itmp1, 4(in) + ps_sub tmp1, cc2, cc2c6s + ps_msub tmp3, tmp10, cc4, tmp2 + lhz itmp2, 2(in) + ps_merge11 tmp5, tmp10, tmp2 + psq_l tmp11, 0(q), 0, 0 + ps_nmsub tmp4, tmp10, tmp1, tmp3 + ps_add tmp7, tmp9, tmp5 + psq_l tmp10, 0(in), 0, 5 + ps_merge11 tmp6, tmp3, tmp4 + ps_sub tmp5, tmp9, tmp5 + lwz itmp0, 12(in) + ps_add tmp8, tmp9, tmp6 + lwz itmp3, 8(in) + ps_sub tmp6, tmp9, tmp6 + psq_stu tmp7, 8(ws), 0, 0 + ps_merge10 tmp6, tmp6, tmp6 + psq_stu tmp8, 8(ws), 0, 0 + ps_merge10 tmp5, tmp5, tmp5 + or itmp0, itmp0, itmp3 + psq_stu tmp6, 8(ws), 0, 0 + ps_mul tmp10, tmp10, tmp11 + psq_stu tmp5, 8(ws), 0, 0 + bdnz _loopHead1 + b _loopEnd + + _halfIDCT: + psq_l tmp1, 4(in), 0, 5 + psq_l tmp9, 8(q), 0, 0 + addi in, in, 8*sizeof(THPCoeff) + ps_mul tmp1, tmp1, tmp9 + addi q, q, 8*sizeof(f32) + ps_sub tmp3, tmp10, tmp1 + ps_add tmp2, tmp10, tmp1 + lwz itmp0, 12(in) + ps_madd tmp4, tmp1, cc4, tmp3 + ps_nmsub tmp5, tmp1, cc4, tmp2 + ps_mul tmp8, tmp3, cc2 + ps_merge00 tmp4, tmp2, tmp4 + lwz itmp3, 8(in) + ps_nmsub tmp6, tmp1, cc2c6a, tmp8 + ps_merge00 tmp5, tmp5, tmp3 + lwz itmp1, 4(in) + ps_sub tmp6, tmp6, tmp2 + ps_nmsub tmp7, tmp10, cc2c6s, tmp8 + lhz itmp2, 2(in) + ps_merge11 tmp2, tmp2, tmp6 + ps_msub tmp8, tmp3, cc4, tmp6 + psq_l tmp10, 0(in), 0, 5 + ps_add tmp9, tmp4, tmp2 + ps_sub tmp7, tmp7, tmp8 + psq_l tmp11, 0(q), 0, 0 + ps_merge11 tmp3, tmp8, tmp7 + ps_sub tmp4, tmp4, tmp2 + psq_stu tmp9, 8(ws), 0, 0 + ps_add tmp0, tmp5, tmp3 + ps_sub tmp1, tmp5, tmp3 + or itmp0, itmp0, itmp3 + psq_stu tmp0, 8(ws), 0, 0 + ps_merge10 tmp1, tmp1, tmp1 + ps_merge10 tmp4, tmp4, tmp4 + psq_stu tmp1, 8(ws), 0, 0 + ps_mul tmp10, tmp10, tmp11 + psq_stu tmp4, 8(ws), 0, 0 + bdnz _loopHead1 + b _loopEnd + + _regularIDCT: + psq_l tmp9, 4(in), 0, 5 + psq_l tmp5, 8(q), 0, 0 + ps_mul tmp9, tmp9, tmp5 + psq_l tmp2, 8(in), 0, 5 + psq_l tmp6, 16(q), 0, 0 + ps_merge01 tmp0, tmp10, tmp9 + psq_l tmp3, 12(in), 0, 5 + ps_merge01 tmp1, tmp9, tmp10 + psq_l tmp7, 24(q), 0, 0 + addi in, in, 8*sizeof(THPCoeff) + ps_madd tmp4, tmp2, tmp6, tmp0 + ps_nmsub tmp5, tmp2, tmp6, tmp0 + ps_madd tmp6, tmp3, tmp7, tmp1 + ps_nmsub tmp7, tmp3, tmp7, tmp1 + addi q, q, 8*sizeof(f32) + ps_add tmp0, tmp4, tmp6 + ps_sub tmp3, tmp4, tmp6 + ps_msub tmp2, tmp7, cc4, tmp6 + lwz itmp0, 12(in) + ps_sub tmp8, tmp7, tmp5 + ps_add tmp1, tmp5, tmp2 + ps_sub tmp2, tmp5, tmp2 + ps_mul tmp8, tmp8, cc2 + lwz itmp3, 8(in) + ps_merge00 tmp1, tmp0, tmp1 + ps_nmsub tmp6, tmp5, cc2c6a, tmp8 + ps_msub tmp4, tmp7, cc2c6s, tmp8 + lwz itmp1, 4(in) + ps_sub tmp6, tmp6, tmp0 + ps_merge00 tmp2, tmp2, tmp3 + lhz itmp2, 2(in) + ps_madd tmp5, tmp3, cc4, tmp6 + ps_merge11 tmp7, tmp0, tmp6 + psq_l tmp10, 0(in), 0, 5 + ps_sub tmp4, tmp4, tmp5 + ps_add tmp3, tmp1, tmp7 + psq_l tmp11, 0(q), 0, 0 + ps_merge11 tmp4, tmp5, tmp4 + ps_sub tmp0, tmp1, tmp7 + ps_mul tmp10, tmp10, tmp11 + ps_add tmp5, tmp2, tmp4 + ps_sub tmp6, tmp2, tmp4 + ps_merge10 tmp5, tmp5, tmp5 + psq_stu tmp3, 8(ws), 0, 0 + ps_merge10 tmp0, tmp0, tmp0 + psq_stu tmp6, 8(ws), 0, 0 + psq_stu tmp5, 8(ws), 0, 0 + or itmp0, itmp0, itmp3 + psq_stu tmp0, 8(ws), 0, 0 + bdnz _loopHead1 + + _loopEnd: + + } + } + + ws = &__THPIDCTWorkspace[0]; + + { + register THPSample *obase = Gbase; + register u32 wid = Gwid; + + register u32 itmp0, off0, off1; + register THPSample *out0, *out1; + + asm { + psq_l tmp10, 8*0*sizeof(f32)(ws), 0, 0 + slwi xPos, xPos, 2 + psq_l tmp11, 8*4*sizeof(f32)(ws), 0, 0 + slwi off1, wid, 2 + psq_l tmp12, 8*2*sizeof(f32)(ws), 0, 0 + mr off0, xPos + ps_add tmp6, tmp10, tmp11 + psq_l tmp13, 8*6*sizeof(f32)(ws), 0, 0 + ps_sub tmp8, tmp10, tmp11 + add off1, off0, off1 + ps_add tmp6, tmp6, bias + li itmp0, 3 + ps_add tmp7, tmp12, tmp13 + add out0, obase, off0 + ps_sub tmp9, tmp12, tmp13 + ps_add tmp0, tmp6, tmp7 + add out1, obase, off1 + ps_add tmp8, tmp8, bias + mtctr itmp0 + + _loopHead10: + psq_l tmp4, 8*1*sizeof(f32)(ws), 0, 0 + ps_msub tmp9, tmp9, cc4, tmp7 + psq_l tmp5, 8*3*sizeof(f32)(ws), 0, 0 + ps_sub tmp3, tmp6, tmp7 + ps_add tmp1, tmp8, tmp9 + psq_l tmp6, 8*5*sizeof(f32)(ws), 0, 0 + ps_sub tmp2, tmp8, tmp9 + psq_l tmp7, 8*7*sizeof(f32)(ws), 0, 0 + ps_add tmp8, tmp6, tmp5 + ps_sub tmp6, tmp6, tmp5 + addi ws, ws, 2*sizeof(f32) + ps_add tmp9, tmp4, tmp7 + ps_sub tmp4, tmp4, tmp7 + psq_l tmp10, 8*0*sizeof(f32)(ws), 0, 0 + ps_add tmp7, tmp9, tmp8 + ps_sub tmp5, tmp9, tmp8 + ps_add tmp8, tmp6, tmp4 + psq_l tmp11, 8*4*sizeof(f32)(ws), 0, 0 + ps_add tmp9, tmp0, tmp7 + ps_mul tmp8, tmp8, cc2 + psq_l tmp12, 8*2*sizeof(f32)(ws), 0, 0 + ps_sub tmp23, tmp0, tmp7 + ps_madd tmp6, tmp6, cc2c6a, tmp8 + psq_l tmp13, 8*6*sizeof(f32)(ws), 0, 0 + ps_sub tmp6, tmp6, tmp7 + addi off0, off0, 2*sizeof(THPSample) + psq_st tmp9, 0(out0), 0, 6 + ps_msub tmp4, tmp4, cc2c6s, tmp8 + ps_add tmp9, tmp1, tmp6 + ps_msub tmp5, tmp5, cc4, tmp6 + ps_sub tmp22, tmp1, tmp6 + psq_st tmp9, 8(out0), 0, 6 + ps_add tmp8, tmp2, tmp5 + ps_add tmp4, tmp4, tmp5 + psq_st tmp8, 16(out0), 0, 6 + addi off1, off1, 2*sizeof(THPSample) + ps_sub tmp9, tmp3, tmp4 + ps_add tmp20, tmp3, tmp4 + psq_st tmp9, 24(out0), 0, 6 + ps_sub tmp21, tmp2, tmp5 + ps_add tmp6, tmp10, tmp11 + psq_st tmp20, 0(out1), 0, 6 + ps_sub tmp8, tmp10, tmp11 + ps_add tmp6, tmp6, bias + psq_st tmp21, 8(out1), 0, 6 + ps_add tmp7, tmp12, tmp13 + ps_sub tmp9, tmp12, tmp13 + psq_st tmp22, 16(out1), 0, 6 + add out0, obase, off0 + ps_add tmp0, tmp6, tmp7 + psq_st tmp23, 24(out1), 0, 6 + ps_add tmp8, tmp8, bias + add out1, obase, off1 + bdnz _loopHead10 + psq_l tmp4, 8*1*sizeof(f32)(ws), 0, 0 + ps_msub tmp9, tmp9, cc4, tmp7 + psq_l tmp5, 8*3*sizeof(f32)(ws), 0, 0 + ps_sub tmp3, tmp6, tmp7 + ps_add tmp1, tmp8, tmp9 + psq_l tmp6, 8*5*sizeof(f32)(ws), 0, 0 + ps_sub tmp2, tmp8, tmp9 + psq_l tmp7, 8*7*sizeof(f32)(ws), 0, 0 + ps_add tmp8, tmp6, tmp5 + ps_sub tmp6, tmp6, tmp5 + ps_add tmp9, tmp4, tmp7 + ps_sub tmp4, tmp4, tmp7 + ps_add tmp7, tmp9, tmp8 + ps_sub tmp5, tmp9, tmp8 + ps_add tmp8, tmp6, tmp4 + ps_add tmp9, tmp0, tmp7 + ps_mul tmp8, tmp8, cc2 + ps_sub tmp23, tmp0, tmp7 + ps_madd tmp6, tmp6, cc2c6a, tmp8 + psq_st tmp9, 0(out0), 0, 6 + ps_sub tmp6, tmp6, tmp7 + ps_msub tmp4, tmp4, cc2c6s, tmp8 + psq_st tmp23, 24(out1), 0, 6 + ps_add tmp9, tmp1, tmp6 + ps_msub tmp5, tmp5, cc4, tmp6 + ps_sub tmp22, tmp1, tmp6 + psq_st tmp9, 8(out0), 0, 6 + ps_add tmp8, tmp2, tmp5 + ps_add tmp4, tmp4, tmp5 + psq_st tmp22, 16(out1), 0, 6 + psq_st tmp8, 16(out0), 0, 6 + ps_sub tmp9, tmp3, tmp4 + ps_add tmp20, tmp3, tmp4 + psq_st tmp9, 24(out0), 0, 6 + ps_sub tmp21, tmp2, tmp5 + psq_st tmp20, 0(out1), 0, 6 + psq_st tmp21, 8(out1), 0, 6 + } + } +} + +inline void __THPInverseDCTY8(register THPCoeff *in, register u32 xPos) +{ + register f32 *q, *ws; + register f32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; + register f32 tmp10, tmp11, tmp12, tmp13; + register f32 tmp20, tmp21, tmp22, tmp23; + register f32 cc4 = 1.414213562F; + register f32 cc2 = 1.847759065F; + register f32 cc2c6s = 1.082392200F; + register f32 cc2c6a = -2.613125930F; + register f32 bias = 1024.0F; + + q = Gq; + ws = &__THPIDCTWorkspace[0] - 2; + + { + register u32 itmp0, itmp1, itmp2, itmp3; + + asm { + li itmp2, 8 + mtctr itmp2 + + _loopHead0: + psq_l tmp10, 0(in), 0, 5 + psq_l tmp11, 0(q), 0, 0 + lwz itmp0, 12(in) + lwz itmp3, 8(in) + ps_mul tmp10, tmp10, tmp11 + lwz itmp1, 4(in) + lhz itmp2, 2(in) + or itmp0, itmp0, itmp3 + + _loopHead1: + cmpwi itmp0, 0 + bne _regularIDCT + ps_merge00 tmp0, tmp10, tmp10 + cmpwi itmp1, 0 + psq_st tmp0, 8(ws), 0, 0 + bne _halfIDCT + psq_st tmp0, 16(ws), 0, 0 + cmpwi itmp2, 0 + psq_st tmp0, 24(ws), 0, 0 + bne _quarterIDCT + addi q, q, 8*sizeof(f32) + psq_stu tmp0, 32(ws), 0, 0 + addi in, in, 8*sizeof(THPCoeff) + bdnz _loopHead0 + b _loopEnd + + _quarterIDCT: + ps_msub tmp2, tmp10, cc2, tmp10 + addi in, in, 8*sizeof(THPCoeff) + ps_merge00 tmp9, tmp10, tmp10 + addi q, q, 8*sizeof(f32) + ps_sub tmp1, cc2, cc2c6s + lwz itmp1, 4(in) + ps_msub tmp3, tmp10, cc4, tmp2 + lhz itmp2, 2(in) + ps_merge11 tmp5, tmp10, tmp2 + psq_l tmp11, 0(q), 0, 0 + ps_nmsub tmp4, tmp10, tmp1, tmp3 + ps_add tmp7, tmp9, tmp5 + psq_l tmp10, 0(in), 0, 5 + ps_merge11 tmp6, tmp3, tmp4 + ps_sub tmp5, tmp9, tmp5 + lwz itmp0, 12(in) + ps_add tmp8, tmp9, tmp6 + lwz itmp3, 8(in) + ps_sub tmp6, tmp9, tmp6 + psq_stu tmp7, 8(ws), 0, 0 + ps_merge10 tmp6, tmp6, tmp6 + psq_stu tmp8, 8(ws), 0, 0 + ps_merge10 tmp5, tmp5, tmp5 + or itmp0, itmp0, itmp3 + psq_stu tmp6, 8(ws), 0, 0 + ps_mul tmp10, tmp10, tmp11 + psq_stu tmp5, 8(ws), 0, 0 + bdnz _loopHead1 + b _loopEnd + + _halfIDCT: + psq_l tmp1, 4(in), 0, 5 + psq_l tmp9, 8(q), 0, 0 + addi in, in, 8*sizeof(THPCoeff) + ps_mul tmp1, tmp1, tmp9 + addi q, q, 8*sizeof(f32) + ps_sub tmp3, tmp10, tmp1 + ps_add tmp2, tmp10, tmp1 + lwz itmp0, 12(in) + ps_madd tmp4, tmp1, cc4, tmp3 + ps_nmsub tmp5, tmp1, cc4, tmp2 + ps_mul tmp8, tmp3, cc2 + ps_merge00 tmp4, tmp2, tmp4 + lwz itmp3, 8(in) + ps_nmsub tmp6, tmp1, cc2c6a, tmp8 + ps_merge00 tmp5, tmp5, tmp3 + lwz itmp1, 4(in) + ps_sub tmp6, tmp6, tmp2 + ps_nmsub tmp7, tmp10, cc2c6s, tmp8 + lhz itmp2, 2(in) + ps_merge11 tmp2, tmp2, tmp6 + ps_msub tmp8, tmp3, cc4, tmp6 + psq_l tmp10, 0(in), 0, 5 + ps_add tmp9, tmp4, tmp2 + ps_sub tmp7, tmp7, tmp8 + psq_l tmp11, 0(q), 0, 0 + ps_merge11 tmp3, tmp8, tmp7 + ps_sub tmp4, tmp4, tmp2 + psq_stu tmp9, 8(ws), 0, 0 + ps_add tmp0, tmp5, tmp3 + ps_sub tmp1, tmp5, tmp3 + or itmp0, itmp0, itmp3 + psq_stu tmp0, 8(ws), 0, 0 + ps_merge10 tmp1, tmp1, tmp1 + ps_merge10 tmp4, tmp4, tmp4 + psq_stu tmp1, 8(ws), 0, 0 + ps_mul tmp10, tmp10, tmp11 + psq_stu tmp4, 8(ws), 0, 0 + bdnz _loopHead1 + b _loopEnd + + _regularIDCT: + psq_l tmp9, 4(in), 0, 5 + psq_l tmp5, 8(q), 0, 0 + ps_mul tmp9, tmp9, tmp5 + psq_l tmp2, 8(in), 0, 5 + psq_l tmp6, 16(q), 0, 0 + ps_merge01 tmp0, tmp10, tmp9 + psq_l tmp3, 12(in), 0, 5 + ps_merge01 tmp1, tmp9, tmp10 + psq_l tmp7, 24(q), 0, 0 + addi in, in, 8*sizeof(THPCoeff) + ps_madd tmp4, tmp2, tmp6, tmp0 + ps_nmsub tmp5, tmp2, tmp6, tmp0 + ps_madd tmp6, tmp3, tmp7, tmp1 + ps_nmsub tmp7, tmp3, tmp7, tmp1 + addi q, q, 8*sizeof(f32) + ps_add tmp0, tmp4, tmp6 + ps_sub tmp3, tmp4, tmp6 + ps_msub tmp2, tmp7, cc4, tmp6 + lwz itmp0, 12(in) + ps_sub tmp8, tmp7, tmp5 + ps_add tmp1, tmp5, tmp2 + ps_sub tmp2, tmp5, tmp2 + ps_mul tmp8, tmp8, cc2 + lwz itmp3, 8(in) + ps_merge00 tmp1, tmp0, tmp1 + ps_nmsub tmp6, tmp5, cc2c6a, tmp8 + ps_msub tmp4, tmp7, cc2c6s, tmp8 + lwz itmp1, 4(in) + ps_sub tmp6, tmp6, tmp0 + ps_merge00 tmp2, tmp2, tmp3 + lhz itmp2, 2(in) + ps_madd tmp5, tmp3, cc4, tmp6 + ps_merge11 tmp7, tmp0, tmp6 + psq_l tmp10, 0(in), 0, 5 + ps_sub tmp4, tmp4, tmp5 + ps_add tmp3, tmp1, tmp7 + psq_l tmp11, 0(q), 0, 0 + ps_merge11 tmp4, tmp5, tmp4 + ps_sub tmp0, tmp1, tmp7 + ps_mul tmp10, tmp10, tmp11 + ps_add tmp5, tmp2, tmp4 + ps_sub tmp6, tmp2, tmp4 + ps_merge10 tmp5, tmp5, tmp5 + psq_stu tmp3, 8(ws), 0, 0 + ps_merge10 tmp0, tmp0, tmp0 + psq_stu tmp6, 8(ws), 0, 0 + psq_stu tmp5, 8(ws), 0, 0 + or itmp0, itmp0, itmp3 + psq_stu tmp0, 8(ws), 0, 0 + bdnz _loopHead1 + + _loopEnd: + + } + } + + ws = &__THPIDCTWorkspace[0]; + + { + register THPSample *obase = Gbase; + register u32 wid = Gwid; + + register u32 itmp0, off0, off1; + register THPSample *out0, *out1; + + asm { + psq_l tmp10, 8*0*sizeof(f32)(ws), 0, 0 + slwi off0, wid, 3; + psq_l tmp11, 8*4*sizeof(f32)(ws), 0, 0 + slwi xPos, xPos, 2 + psq_l tmp12, 8*2*sizeof(f32)(ws), 0, 0 + slwi off1, wid, 2 + ps_add tmp6, tmp10, tmp11 + add off0, off0, xPos + psq_l tmp13, 8*6*sizeof(f32)(ws), 0, 0 + ps_sub tmp8, tmp10, tmp11 + add off1, off0, off1 + ps_add tmp6, tmp6, bias + li itmp0, 3 + ps_add tmp7, tmp12, tmp13 + add out0, obase, off0 + ps_sub tmp9, tmp12, tmp13 + ps_add tmp0, tmp6, tmp7 + add out1, obase, off1 + ps_add tmp8, tmp8, bias + mtctr itmp0 + + _loopHead10: + psq_l tmp4, 8*1*sizeof(f32)(ws), 0, 0 + ps_msub tmp9, tmp9, cc4, tmp7 + psq_l tmp5, 8*3*sizeof(f32)(ws), 0, 0 + ps_sub tmp3, tmp6, tmp7 + ps_add tmp1, tmp8, tmp9 + psq_l tmp6, 8*5*sizeof(f32)(ws), 0, 0 + ps_sub tmp2, tmp8, tmp9 + psq_l tmp7, 8*7*sizeof(f32)(ws), 0, 0 + ps_add tmp8, tmp6, tmp5 + ps_sub tmp6, tmp6, tmp5 + addi ws, ws, 2*sizeof(f32) + ps_add tmp9, tmp4, tmp7 + ps_sub tmp4, tmp4, tmp7 + psq_l tmp10, 8*0*sizeof(f32)(ws), 0, 0 + ps_add tmp7, tmp9, tmp8 + ps_sub tmp5, tmp9, tmp8 + ps_add tmp8, tmp6, tmp4 + psq_l tmp11, 8*4*sizeof(f32)(ws), 0, 0 + ps_add tmp9, tmp0, tmp7 + ps_mul tmp8, tmp8, cc2 + psq_l tmp12, 8*2*sizeof(f32)(ws), 0, 0 + ps_sub tmp23, tmp0, tmp7 + ps_madd tmp6, tmp6, cc2c6a, tmp8 + psq_l tmp13, 8*6*sizeof(f32)(ws), 0, 0 + ps_sub tmp6, tmp6, tmp7 + addi off0, off0, 2*sizeof(THPSample) + psq_st tmp9, 0(out0), 0, 6 + ps_msub tmp4, tmp4, cc2c6s, tmp8 + ps_add tmp9, tmp1, tmp6 + ps_msub tmp5, tmp5, cc4, tmp6 + ps_sub tmp22, tmp1, tmp6 + psq_st tmp9, 8(out0), 0, 6 + ps_add tmp8, tmp2, tmp5 + ps_add tmp4, tmp4, tmp5 + psq_st tmp8, 16(out0), 0, 6 + addi off1, off1, 2*sizeof(THPSample) + ps_sub tmp9, tmp3, tmp4 + ps_add tmp20, tmp3, tmp4 + psq_st tmp9, 24(out0), 0, 6 + ps_sub tmp21, tmp2, tmp5 + ps_add tmp6, tmp10, tmp11 + psq_st tmp20, 0(out1), 0, 6 + ps_sub tmp8, tmp10, tmp11 + ps_add tmp6, tmp6, bias + psq_st tmp21, 8(out1), 0, 6 + ps_add tmp7, tmp12, tmp13 + ps_sub tmp9, tmp12, tmp13 + psq_st tmp22, 16(out1), 0, 6 + add out0, obase, off0 + ps_add tmp0, tmp6, tmp7 + psq_st tmp23, 24(out1), 0, 6 + ps_add tmp8, tmp8, bias + add out1, obase, off1 + + bdnz _loopHead10 + psq_l tmp4, 8*1*sizeof(f32)(ws), 0, 0 + ps_msub tmp9, tmp9, cc4, tmp7 + psq_l tmp5, 8*3*sizeof(f32)(ws), 0, 0 + ps_sub tmp3, tmp6, tmp7 + ps_add tmp1, tmp8, tmp9 + psq_l tmp6, 8*5*sizeof(f32)(ws), 0, 0 + ps_sub tmp2, tmp8, tmp9 + psq_l tmp7, 8*7*sizeof(f32)(ws), 0, 0 + ps_add tmp8, tmp6, tmp5 + ps_sub tmp6, tmp6, tmp5 + ps_add tmp9, tmp4, tmp7 + ps_sub tmp4, tmp4, tmp7 + ps_add tmp7, tmp9, tmp8 + ps_sub tmp5, tmp9, tmp8 + ps_add tmp8, tmp6, tmp4 + ps_add tmp9, tmp0, tmp7 + ps_mul tmp8, tmp8, cc2 + ps_sub tmp23, tmp0, tmp7 + ps_madd tmp6, tmp6, cc2c6a, tmp8 + psq_st tmp9, 0(out0), 0, 6 + ps_sub tmp6, tmp6, tmp7 + ps_msub tmp4, tmp4, cc2c6s, tmp8 + psq_st tmp23, 24(out1), 0, 6 + ps_add tmp9, tmp1, tmp6 + ps_msub tmp5, tmp5, cc4, tmp6 + ps_sub tmp22, tmp1, tmp6 + psq_st tmp9, 8(out0), 0, 6 + ps_add tmp8, tmp2, tmp5 + ps_add tmp4, tmp4, tmp5 + psq_st tmp8, 16(out0), 0, 6 + ps_sub tmp9, tmp3, tmp4 + psq_st tmp22, 16(out1), 0, 6 + ps_add tmp20, tmp3, tmp4 + psq_st tmp9, 24(out0), 0, 6 + ps_sub tmp21, tmp2, tmp5 + psq_st tmp20, 0(out1), 0, 6 + psq_st tmp21, 8(out1), 0, 6 + + } + } +} + +void __THPDecompressiMCURow512x448(void) +{ + u8 cl_num; + u32 x_pos; + THPComponent *comp; + + LCQueueWait(3); + + for (cl_num = 0; cl_num < __THPInfo->MCUsPerRow; cl_num++) + { + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[0]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[1]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[2]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[3]); + __THPHuffDecodeDCTCompU(__THPInfo, __THPMCUBuffer[4]); + __THPHuffDecodeDCTCompV(__THPInfo, __THPMCUBuffer[5]); + + comp = &__THPInfo->components[0]; + Gbase = __THPLCWork512[0]; + Gwid = 512; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + x_pos = (u32)(cl_num * 16); + __THPInverseDCTNoYPos(__THPMCUBuffer[0], x_pos); + __THPInverseDCTNoYPos(__THPMCUBuffer[1], x_pos + 8); + __THPInverseDCTY8(__THPMCUBuffer[2], x_pos); + __THPInverseDCTY8(__THPMCUBuffer[3], x_pos + 8); + + comp = &__THPInfo->components[1]; + Gbase = __THPLCWork512[1]; + Gwid = 256; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + x_pos /= 2; + __THPInverseDCTNoYPos(__THPMCUBuffer[4], x_pos); + comp = &__THPInfo->components[2]; + Gbase = __THPLCWork512[2]; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + __THPInverseDCTNoYPos(__THPMCUBuffer[5], x_pos); + + if (__THPInfo->RST != 0) + { + if ((--__THPInfo->currMCU) == 0) + { + __THPInfo->currMCU = __THPInfo->nMCU; + __THPInfo->cnt = 1 + ((__THPInfo->cnt + 6) & 0xFFFFFFF8); + + if (__THPInfo->cnt > 33) + { + __THPInfo->cnt = 33; + } + + __THPInfo->components[0].predDC = 0; + __THPInfo->components[1].predDC = 0; + __THPInfo->components[2].predDC = 0; + } + } + } + + LCStoreData(__THPInfo->dLC[0], __THPLCWork512[0], 0x2000); + LCStoreData(__THPInfo->dLC[1], __THPLCWork512[1], 0x800); + LCStoreData(__THPInfo->dLC[2], __THPLCWork512[2], 0x800); + + __THPInfo->dLC[0] += 0x2000; + __THPInfo->dLC[1] += 0x800; + __THPInfo->dLC[2] += 0x800; +} + +inline s32 __THPHuffDecodeTab(register THPFileInfo *info, register THPHuffmanTab *h) +{ + register s32 code; + register u32 cnt; + register s32 cb; + register u32 increment; + register s32 tmp; + +#define cnt4 code + asm + { + lwz cnt, info->cnt; + addi increment, h, 32; + lwz cb, info->currByte; + addi cnt4, cnt, 4; + cmpwi cnt, 28; + rlwnm tmp, cb, cnt4, 27, 31; + bgt _notEnoughBits; + lbzx code, h, tmp; + lbzx increment, increment, tmp; + cmpwi code, 0xFF; + beq _FailedCheckEnoughBits; + add cnt, cnt, increment; + stw cnt, info->cnt; + } +_done: + return code; + + { + register u32 maxcodebase; + register u32 tmp2; + + _FailedCheckEnoughBits: + maxcodebase = (u32) & (h->maxCode); + cnt += 5; + + asm { + li tmp2, sizeof(s32)*(5); + li code, 5; + add maxcodebase, maxcodebase, tmp2; + __WHILE_START: + cmpwi cnt, 33; + slwi tmp, tmp, 1 + + beq _FCEB_faster; + rlwnm increment, cb, cnt, 31, 31; + lwzu tmp2, 4(maxcodebase); + or tmp, tmp, increment + addi cnt, cnt, 1; + b __WHILE_CHECK; + + _FCEB_faster: + lwz increment, info->c; + li cnt, 1; + lwzu cb, 4(increment); + lwzu tmp2, 4(maxcodebase); + + stw increment, info->c; + rlwimi tmp, cb, 1,31,31; + stw cb, info->currByte; + b __FL_WHILE_CHECK; + + __FL_WHILE_START: + slwi tmp, tmp, 1; + rlwnm increment, cb, cnt, 31, 31; + lwzu tmp2, 4(maxcodebase); + or tmp, tmp, increment; + + __FL_WHILE_CHECK: + cmpw tmp,tmp2 + addi cnt, cnt, 1; + addi code, code, 1 + bgt __FL_WHILE_START; + b _FCEB_Done; + + __WHILE_CHECK: + cmpw tmp,tmp2 + addi code, code, 1 + bgt __WHILE_START; + } + } +_FCEB_Done: + info->cnt = cnt; + return (h->Vij[(s32)(tmp + h->valPtr[code])]); + + asm + { // 6684 + _notEnoughBits: + cmpwi cnt, 33; + lwz tmp, info->c; + beq _getfullword; + + cmpwi cnt, 32; + rlwnm code, cb, cnt4, 27, 31 + beq _1bitleft; + + lbzx tmp, h, code; + lbzx increment, increment, code; + cmpwi tmp, 0xFF; + add code, cnt, increment; + beq _FailedCheckNoBits0; + + cmpwi code, 33; + stw code, info->cnt; + bgt _FailedCheckNoBits1; + } + return tmp; + + asm + { + _1bitleft: + lwzu cb, 4(tmp); + + stw tmp, info->c; + rlwimi code, cb, 4, 28, 31; + lbzx tmp, h, code; + lbzx increment, increment, code + stw cb, info->currByte; + cmpwi tmp, 0xFF + stw increment, info->cnt; + beq _DammitRead4; + + } + return tmp; + +_DammitRead4: +{ + register u32 maxcodebase = (u32) & (h->maxCode); + register u32 tmp2; + + asm + { + li cnt, sizeof(s32)*5; + add maxcodebase, maxcodebase, cnt; + + slwi tmp, code, 32-5; + li cnt,5; + rlwimi tmp, cb, 32-1, 1,31; + + __DR4_WHILE_START: + + subfic cb, cnt, 31; + lwzu tmp2, 4(maxcodebase); + srw code, tmp, cb; + __DR4_WHILE_CHECK: + cmpw code, tmp2 + addi cnt, cnt, 1 + bgt __DR4_WHILE_START; + + } +} + + info->cnt = cnt; +__CODE_PLUS_VP_CNT: + return (h->Vij[(s32)(code + h->valPtr[cnt])]); + +_getfullword: + asm + { + lwzu cb, 4(tmp); + + rlwinm code, cb, 5, 27, 31 + stw tmp, info->c; + lbzx cnt, h, code; + lbzx increment, increment, code; + cmpwi cnt, 0xFF + stw cb, info->currByte; + addi increment, increment, 1 + beq _FailedCheckEnoughbits_Updated; + + stw increment, info->cnt; + } + return (s32)cnt; + +_FailedCheckEnoughbits_Updated: + + cnt = 5; + do + { + asm + { + subfic tmp, cnt, 31; + addi cnt, cnt, 1; + srw code, cb, tmp; + } + } while (code > h->maxCode[cnt]); + + info->cnt = cnt + 1; + goto __CODE_PLUS_VP_CNT; + +#undef cnt4 + +_FailedCheckNoBits0: +_FailedCheckNoBits1: + +{ + register u32 mask = 0xFFFFFFFF << (33 - cnt); + register u32 tmp2; + + code = (s32)(cb & (~mask)); + mask = (u32) & (h->maxCode); + + asm + { + lwz tmp, info->c; + subfic tmp2, cnt, 33; + addi cnt, tmp2, 1; + slwi tmp2, tmp2, 2; + lwzu cb, 4(tmp); + add mask,mask, tmp2; + stw tmp, info->c; + slwi code, code, 1; + stw cb, info->currByte; + rlwimi code, cb, 1, 31, 31; + lwzu tmp2, 4(mask); + li tmp, 2; + b __FCNB1_WHILE_CHECK; + + __FCNB1_WHILE_START: + slwi code, code, 1; + + addi cnt, cnt, 1; + lwzu tmp2, 4(mask); + add code, code, increment; + addi tmp, tmp, 1; + + __FCNB1_WHILE_CHECK: + cmpw code, tmp2; + rlwnm increment, cb, tmp, 31, 31; + bgt __FCNB1_WHILE_START; + + } +} + + info->cnt = (u32)tmp; + return (h->Vij[(s32)(code + h->valPtr[cnt])]); +} + +void __THPDecompressiMCURow640x480(void) +{ + u8 cl_num; + u32 x_pos; + THPComponent *comp; + + LCQueueWait(3); + + { + for (cl_num = 0; cl_num < __THPInfo->MCUsPerRow; cl_num++) + { + THPFileInfo *um = __THPInfo; + __THPHuffDecodeDCTCompY(um, __THPMCUBuffer[0]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[1]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[2]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[3]); + __THPHuffDecodeDCTCompU(__THPInfo, __THPMCUBuffer[4]); + __THPHuffDecodeDCTCompV(__THPInfo, __THPMCUBuffer[5]); + + comp = &__THPInfo->components[0]; + Gbase = __THPLCWork672[0]; + Gwid = 640; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + x_pos = (u32)(cl_num * 16); + __THPInverseDCTNoYPos(__THPMCUBuffer[0], x_pos); + __THPInverseDCTNoYPos(__THPMCUBuffer[1], x_pos + 8); + __THPInverseDCTY8(__THPMCUBuffer[2], x_pos); + __THPInverseDCTY8(__THPMCUBuffer[3], x_pos + 8); + + comp = &__THPInfo->components[1]; + Gbase = __THPLCWork672[1]; + Gwid = 320; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + x_pos /= 2; + __THPInverseDCTNoYPos(__THPMCUBuffer[4], x_pos); + + comp = &__THPInfo->components[2]; + Gbase = __THPLCWork672[2]; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + __THPInverseDCTNoYPos(__THPMCUBuffer[5], x_pos); + + if (__THPInfo->RST != 0) + { + __THPInfo->currMCU--; + if (__THPInfo->currMCU == 0) + { + __THPInfo->currMCU = __THPInfo->nMCU; + + __THPInfo->cnt = 1 + ((__THPInfo->cnt + 6) & 0xFFFFFFF8); + + if (__THPInfo->cnt > 32) + { + __THPInfo->cnt = 33; + } + + __THPInfo->components[0].predDC = 0; + __THPInfo->components[1].predDC = 0; + __THPInfo->components[2].predDC = 0; + } + } + } + } + + LCStoreData(__THPInfo->dLC[0], __THPLCWork672[0], 0x2800); + LCStoreData(__THPInfo->dLC[1], __THPLCWork672[1], 0xA00); + LCStoreData(__THPInfo->dLC[2], __THPLCWork672[2], 0xA00); + + __THPInfo->dLC[0] += 0x2800; + __THPInfo->dLC[1] += 0xA00; + __THPInfo->dLC[2] += 0xA00; +} + +void __THPDecompressiMCURowNxN(void) +{ + u8 cl_num; + u32 x_pos, x; + THPComponent *comp; + + x = __THPInfo->xPixelSize; + + LCQueueWait(3); + + for (cl_num = 0; cl_num < __THPInfo->MCUsPerRow; cl_num++) + { + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[0]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[1]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[2]); + __THPHuffDecodeDCTCompY(__THPInfo, __THPMCUBuffer[3]); + __THPHuffDecodeDCTCompU(__THPInfo, __THPMCUBuffer[4]); + __THPHuffDecodeDCTCompV(__THPInfo, __THPMCUBuffer[5]); + + comp = &__THPInfo->components[0]; + Gbase = __THPLCWork672[0]; + Gwid = x; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + x_pos = (u32)(cl_num * 16); + __THPInverseDCTNoYPos(__THPMCUBuffer[0], x_pos); + __THPInverseDCTNoYPos(__THPMCUBuffer[1], x_pos + 8); + __THPInverseDCTY8(__THPMCUBuffer[2], x_pos); + __THPInverseDCTY8(__THPMCUBuffer[3], x_pos + 8); + + comp = &__THPInfo->components[1]; + Gbase = __THPLCWork672[1]; + Gwid = x / 2; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + x_pos /= 2; + __THPInverseDCTNoYPos(__THPMCUBuffer[4], x_pos); + + comp = &__THPInfo->components[2]; + Gbase = __THPLCWork672[2]; + Gq = __THPInfo->quantTabs[comp->quantizationTableSelector]; + __THPInverseDCTNoYPos(__THPMCUBuffer[5], x_pos); + + if (__THPInfo->RST != 0) + { + __THPInfo->currMCU--; + if (__THPInfo->currMCU == 0) + { + __THPInfo->currMCU = __THPInfo->nMCU; + __THPInfo->cnt = 1 + ((__THPInfo->cnt + 6) & 0xFFFFFFF8); + + if (__THPInfo->cnt > 32) + { + __THPInfo->cnt = 33; + } + + __THPInfo->components[0].predDC = 0; + __THPInfo->components[1].predDC = 0; + __THPInfo->components[2].predDC = 0; + } + } + } + + LCStoreData(__THPInfo->dLC[0], __THPLCWork672[0], ((4 * sizeof(u8) * 64) * (x / 16))); + LCStoreData(__THPInfo->dLC[1], __THPLCWork672[1], ((sizeof(u8) * 64) * (x / 16))); + LCStoreData(__THPInfo->dLC[2], __THPLCWork672[2], ((sizeof(u8) * 64) * (x / 16))); + __THPInfo->dLC[0] += ((4 * sizeof(u8) * 64) * (x / 16)); + __THPInfo->dLC[1] += ((sizeof(u8) * 64) * (x / 16)); + __THPInfo->dLC[2] += ((sizeof(u8) * 64) * (x / 16)); +} + +void __THPHuffDecodeDCTCompY(register THPFileInfo *info, THPCoeff *block) +{ + { + register s32 t; + THPCoeff dc; + register THPCoeff diff; + + __dcbz((void *)block, 0); + t = __THPHuffDecodeTab(info, Ydchuff); + __dcbz((void *)block, 32); + diff = 0; + __dcbz((void *)block, 64); + + if (t) + { + { + register s32 v; + register u32 cb; + register u32 cnt; + register u32 cnt33; + register u32 tmp; + register u32 cnt1; + register u32 tmp1; + asm { + lwz cnt,info->cnt; + subfic cnt33,cnt,33; + lwz cb,info->currByte; + + subfc. tmp, cnt33, t; + subi cnt1,cnt,1; + + bgt _notEnoughBitsDIFF; + add v,cnt,t; + + slw cnt,cb,cnt1; + stw v,info->cnt; + subfic v,t,32; + srw diff,cnt,v; + } + + asm + { + b _DoneDIFF; + _notEnoughBitsDIFF: + lwz tmp1, info->c; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, cnt33; + stw tmp1, info->c; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, t, 32; + srw diff, v, tmp; + _DoneDIFF: + } + } + + if (__cntlzw((u32)diff) > 32 - t) + { + diff += ((0xFFFFFFFF << t) + 1); + } + }; + + __dcbz((void *)block, 96); + dc = (s16)(info->components[0].predDC + diff); + block[0] = info->components[0].predDC = dc; + } + + { + register s32 k; + register s32 code; + register u32 cnt; + register u32 cb; + register u32 increment; + register s32 tmp; + register THPHuffmanTab *h = Yachuff; + +#define cnt4 code + asm + { + lwz cnt, info->cnt; + addi increment, h, 32; + lwz cb, info->currByte; + } + + for (k = 1; k < 64; k++) + { + register s32 ssss; + register s32 rrrr; + + asm { + addi cnt4, cnt, 4; + cmpwi cnt, 28; + rlwnm tmp, cb, cnt4, 27, 31; + bgt _notEnoughBits; + + lbzx ssss, h, tmp; + lbzx code, increment, tmp; + cmpwi ssss, 0xFF; + + beq _FailedCheckEnoughBits; + add cnt, cnt, code; + b _DoneDecodeTab; + } + + { + register u32 maxcodebase; + register u32 tmp2; + + _FailedCheckEnoughBits: + cnt += 5; + maxcodebase = (u32) & (h->maxCode); + asm { + li tmp2, sizeof(s32)*(5); + li code, 5; + add maxcodebase, maxcodebase, tmp2; + __WHILE_START: + cmpwi cnt, 33; + slwi tmp, tmp, 1 + + beq _FCEB_faster; + rlwnm ssss, cb, cnt, 31, 31; + lwzu tmp2, 4(maxcodebase); + or tmp, tmp, ssss + addi cnt, cnt, 1; + b __WHILE_CHECK; + + _FCEB_faster: + lwz ssss, info->c; + li cnt, 1; + lwzu cb, 4(ssss); + + lwzu tmp2, 4(maxcodebase); + + stw ssss, info->c; + rlwimi tmp, cb, 1,31,31; + b __FL_WHILE_CHECK; + + __FL_WHILE_START: + slwi tmp, tmp, 1; + + rlwnm ssss, cb, cnt, 31, 31; + lwzu tmp2, 4(maxcodebase); + or tmp, tmp, ssss; + + __FL_WHILE_CHECK: + cmpw tmp,tmp2 + addi cnt, cnt, 1; + addi code, code, 1 + bgt __FL_WHILE_START; + b _FCEB_Done; + + __WHILE_CHECK: + cmpw tmp,tmp2 + addi code, code, 1 + bgt __WHILE_START; + } + } + _FCEB_Done: + ssss = (h->Vij[(s32)(tmp + h->valPtr[code])]); + goto _DoneDecodeTab; + + _notEnoughBits: + asm + { + cmpwi cnt, 33; + lwz tmp, info->c; + beq _getfullword; + + cmpwi cnt, 32; + rlwnm code, cb, cnt4, 27, 31 + beq _1bitleft; + + lbzx ssss, h, code; + lbzx rrrr, increment, code; + cmpwi ssss, 0xFF; + add code, cnt, rrrr; + beq _FailedCheckNoBits0; + + cmpwi code, 33; + bgt _FailedCheckNoBits1; + } + cnt = (u32)code; + goto _DoneDecodeTab; + + _getfullword: + { + asm + { + lwzu cb, 4(tmp); + rlwinm code, cb, 5, 27, 31 + stw tmp, info->c; + lbzx ssss, h, code; + lbzx tmp, increment, code; + cmpwi ssss, 0xFF + addi cnt, tmp, 1 + beq _FailedCheckEnoughbits_Updated; + } + } + goto _DoneDecodeTab; + + _FailedCheckEnoughbits_Updated: + ssss = 5; + do + { + asm + { + subfic tmp, ssss, 31; + addi ssss, ssss, 1; + srw code, cb, tmp; + } + } while (code > h->maxCode[ssss]); + + cnt = (u32)(ssss + 1); + ssss = (h->Vij[(s32)(code + h->valPtr[ssss])]); + + goto _DoneDecodeTab; + + _1bitleft: + asm { + lwzu cb, 4(tmp); + + stw tmp, info->c; + rlwimi code, cb, 4, 28, 31; + lbzx ssss, h, code; + lbzx cnt, increment, code + cmpwi ssss, 0xFF + beq _DammitRead4; + + } + + goto _DoneDecodeTab; + + _DammitRead4: + { + register u32 maxcodebase = (u32) & (h->maxCode); + register u32 tmp2; + + asm { + li cnt, sizeof(s32)*5; + add maxcodebase, maxcodebase, cnt; + + slwi tmp, code, 32-5; + li cnt,5; + rlwimi tmp, cb, 32-1, 1,31; + + __DR4_WHILE_START: + + subfic ssss, cnt, 31; + lwzu tmp2, 4(maxcodebase); + srw code, tmp, ssss; + __DR4_WHILE_CHECK: + cmpw code, tmp2 + addi cnt, cnt, 1 + bgt __DR4_WHILE_START; + + } + } + ssss = (h->Vij[(s32)(code + h->valPtr[cnt])]); + goto _DoneDecodeTab; + + _FailedCheckNoBits0: + _FailedCheckNoBits1: + _REALFAILEDCHECKNOBITS: + { + register u32 mask = 0xFFFFFFFF << (33 - cnt); + register u32 tmp2; + register u32 tmp3; + code = (s32)(cb & (~mask)); + mask = (u32) & (h->maxCode); + + asm { + lwz tmp, info->c; + subfic tmp2, cnt, 33; + addi tmp3, tmp2, 1; + slwi tmp2, tmp2, 2; + lwzu cb, 4(tmp); + add mask,mask, tmp2; + stw tmp, info->c; + slwi code, code, 1; + rlwimi code, cb, 1, 31, 31; + lwzu tmp2, 4(mask); + li cnt, 2; + b __FCNB1_WHILE_CHECK; + + __FCNB1_WHILE_START: + slwi code, code, 1; + + addi tmp3, tmp3, 1; + lwzu tmp2, 4(mask); + add code, code, rrrr; + addi cnt, cnt, 1; + + __FCNB1_WHILE_CHECK: + cmpw code, tmp2; + rlwnm rrrr, cb, cnt, 31, 31; + bgt __FCNB1_WHILE_START; + + } + ssss = (h->Vij[(s32)(code + h->valPtr[tmp3])]); + } + + goto _DoneDecodeTab; + + _DoneDecodeTab: + asm { + andi. rrrr, ssss, 15; + srawi ssss, ssss, 4; + beq _RECV_SSSS_ZERO; + } + + { + k += ssss; + { + register s32 v; +#define cnt33 code + register u32 cnt1; + register u32 tmp1; + asm + { + subfic cnt33,cnt,33; + subfc. tmp, cnt33, rrrr; + subi cnt1,cnt,1; + bgt _RECVnotEnoughBits; + add cnt,cnt,rrrr; + slw tmp1,cb,cnt1; + subfic v,rrrr,32; + srw ssss,tmp1,v; + } + asm + { + b _RECVDone; + _RECVnotEnoughBits: + lwz tmp1, info->c; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi cnt, tmp, 1; + stw tmp1, info->c; + srw tmp1, cb, cnt33; + + add v, tmp1, v; + subfic tmp, rrrr, 32; + srw ssss, v, tmp; + _RECVDone: + } + } + +#undef cnt33 + + if (__cntlzw((u32)ssss) > 32 - rrrr) + { + ssss += ((0xFFFFFFFF << rrrr) + 1); + } + + block[__THPJpegNaturalOrder[k]] = (s16)ssss; + goto _RECV_END; + } + + { + _RECV_SSSS_ZERO: + if (ssss != 15) + { + break; + } + + k += 15; + }; + + asm + { + _RECV_END: + } + } + info->cnt = cnt; + info->currByte = cb; + } +#undef cnt4 +} + +void __THPHuffDecodeDCTCompU(register THPFileInfo *info, THPCoeff *block) +{ + register s32 t; + register THPCoeff diff; + THPCoeff dc; + register s32 v; + register u32 cb; + register u32 cnt; + register u32 cnt33; + register u32 tmp; + register u32 cnt1; + register u32 tmp1; + register s32 k; + register s32 ssss; + register s32 rrrr; + + __dcbz((void *)block, 0); + t = __THPHuffDecodeTab(info, Udchuff); + __dcbz((void *)block, 32); + diff = 0; + __dcbz((void *)block, 64); + + if (t) + { + asm + { + lwz cnt,info->cnt; + subfic cnt33,cnt,33; + lwz cb,info->currByte; + subfc. tmp, cnt33, t; + subi cnt1,cnt,1; + bgt _notEnoughBitsDIFF; + add v,cnt,t; + slw cnt,cb,cnt1; + stw v,info->cnt; + subfic v,t,32; + srw diff,cnt,v; + } + + asm + { + b _DoneDIFF; + _notEnoughBitsDIFF: + lwz tmp1, info->c; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, cnt33; + stw tmp1, info->c; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, t, 32; + srw diff, v, tmp; + _DoneDIFF: + } + + if (__cntlzw((u32)diff) > 32 - t) + { + diff += ((0xFFFFFFFF << t) + 1); + } + } + + __dcbz((void *)block, 96); + dc = (s16)(info->components[1].predDC + diff); + block[0] = info->components[1].predDC = dc; + + for (k = 1; k < 64; k++) + { + ssss = __THPHuffDecodeTab(info, Uachuff); + rrrr = ssss >> 4; + ssss &= 15; + + if (ssss) + { + k += rrrr; + asm + { + lwz cnt,info->cnt; + subfic cnt33,cnt,33; + lwz cb,info->currByte; + subf. tmp, cnt33, ssss; + subi cnt1,cnt,1; + bgt _notEnoughBits; + add v,cnt,ssss; + slw cnt,cb,cnt1; + stw v,info->cnt; + subfic v,ssss,32; + srw rrrr,cnt,v; + } + + asm + { + b _Done; + _notEnoughBits: + lwz tmp1, info->c; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, cnt33; + stw tmp1, info->c; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, ssss, 32; + srw rrrr, v, tmp; + _Done: + } + + if (__cntlzw((u32)rrrr) > 32 - ssss) + { + rrrr += ((0xFFFFFFFF << ssss) + 1); + } + + block[__THPJpegNaturalOrder[k]] = (s16)rrrr; + } + + else + { + if (rrrr != 15) + break; + k += 15; + } + } +} + +void __THPHuffDecodeDCTCompV(register THPFileInfo *info, THPCoeff *block) +{ + register s32 t; + register THPCoeff diff; + THPCoeff dc; + register s32 v; + register u32 cb; + register u32 cnt; + register u32 cnt33; + register u32 tmp; + register u32 cnt1; + register u32 tmp1; + register s32 k; + register s32 ssss; + register s32 rrrr; + + __dcbz((void *)block, 0); + t = __THPHuffDecodeTab(info, Vdchuff); + __dcbz((void *)block, 32); + diff = 0; + __dcbz((void *)block, 64); + + if (t) + { + asm + { + lwz cnt,info->cnt; + subfic cnt33,cnt,33; + lwz cb,info->currByte; + subf. tmp, cnt33, t; + subi cnt1,cnt,1; + bgt _notEnoughBitsDIFF; + add v,cnt,t; + slw cnt,cb,cnt1; + stw v,info->cnt; + subfic v,t,32; + srw diff,cnt,v; + } + + asm + { + b _DoneDIFF; + _notEnoughBitsDIFF: + lwz tmp1, info->c; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, cnt33; + stw tmp1, info->c; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, t, 32; + srw diff, v, tmp; + _DoneDIFF: + } + + if (__cntlzw((u32)diff) > 32 - t) + { + diff += ((0xFFFFFFFF << t) + 1); + } + } + + __dcbz((void *)block, 96); + + dc = (s16)(info->components[2].predDC + diff); + block[0] = info->components[2].predDC = dc; + + for (k = 1; k < 64; k++) + { + ssss = __THPHuffDecodeTab(info, Vachuff); + rrrr = ssss >> 4; + ssss &= 15; + + if (ssss) + { + k += rrrr; + + asm + { + lwz cnt,info->cnt; + subfic cnt33,cnt,33; + lwz cb,info->currByte; + + subf. tmp, cnt33, ssss; + subi cnt1,cnt,1; + + bgt _notEnoughBits; + add v,cnt,ssss; + + slw cnt,cb,cnt1; + stw v,info->cnt; + subfic v,ssss,32; + srw rrrr,cnt,v; + } + + asm + { + b _Done; + _notEnoughBits: + lwz tmp1, info->c; + slw v, cb, cnt1; + lwzu cb, 4(tmp1); + addi tmp, tmp, 1; + stw cb, info->currByte; + srw cb, cb, cnt33; + stw tmp1, info->c; + add v, cb, v; + stw tmp, info->cnt; + subfic tmp, ssss, 32; + srw rrrr, v, tmp; + _Done: + } + + if (__cntlzw((u32)rrrr) > 32 - ssss) + { + rrrr += ((0xFFFFFFFF << ssss) + 1); + } + + block[__THPJpegNaturalOrder[k]] = (s16)rrrr; + } + else + { + if (rrrr != 15) + break; + k += 15; + } + } +} + +BOOL THPInit(void) +{ + u8 *base; + OSRegisterVersion(__THPVersion); + base = (u8 *)(0xE000 << 16); // lc base + + __THPLCWork512[0] = base; + base += 0x2000; + __THPLCWork512[1] = base; + base += 0x800; + __THPLCWork512[2] = base; + base += 0x200; + + base = (u8 *)(0xE000 << 16); // lc base + __THPLCWork672[0] = base; + base += 0x2800; + __THPLCWork672[1] = base; + base += 0xA00; + __THPLCWork672[2] = base; + base += 0xA80; + + OSInitFastCast(); + + __THPInitFlag = TRUE; + return TRUE; +} \ No newline at end of file diff --git a/libs/dolphin/upnp/UPnP.c b/libs/dolphin/upnp/UPnP.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/upnp/UPnPHttp.c b/libs/dolphin/upnp/UPnPHttp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/upnp/UPnPHttpd.c b/libs/dolphin/upnp/UPnPHttpd.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/upnp/UPnPHttpdResponse.c b/libs/dolphin/upnp/UPnPHttpdResponse.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/upnp/UPnPSsdp.c b/libs/dolphin/upnp/UPnPSsdp.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/upnp/UPnPUri.c b/libs/dolphin/upnp/UPnPUri.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/dolphin/upnp/UPnPUuid.c b/libs/dolphin/upnp/UPnPUuid.c new file mode 100644 index 000000000..e69de29bb diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Export/mslsupp.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Export/mslsupp.c index e69de29bb..cfe60633e 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Export/mslsupp.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Export/mslsupp.c @@ -0,0 +1,65 @@ +#include +#include "runtime_libs\debugger\embedded\MetroTRK\Os\dolphin\target_options.h" +#include "runtime_libs\debugger\embedded\MetroTRK\Processor\ppc\Export\targsupp.h" + +DSIOResult __read_file(u32 handle, u8* buffer, size_t* count, void* ref_con); +DSIOResult __write_file(u32 handle, u8* buffer, size_t* count, void* ref_con); +DSIOResult __close_file(u32 handle, u8* buffer, size_t* count, void* ref_con); +DSIOResult __access_file(u32 handle, u8* buffer, size_t* count, void* ref_con, + MessageCommandID cmd); + +/* 80372258-80372314 36CB98 00BC+00 0/0 1/0 0/0 .text __read_console */ +DSIOResult __read_console(u32 handle, u8* buffer, size_t* count, void* ref_con) +{ + if (GetUseSerialIO() == 0) + { + return DS_IOError; + } + return __read_file(DS_Stdin, buffer, count, ref_con); +} + +/* 8037219C-80372258 36CADC 00BC+00 0/0 1/1 0/0 .text __TRK_write_console */ +DSIOResult __TRK_write_console(u32 handle, u8* buffer, size_t* count, void* ref_con) +{ + if (GetUseSerialIO() == 0) + { + return DS_IOError; + } + return __write_file(DS_Stdout, buffer, count, ref_con); +} + +static DSIOResult __read_file(u32 handle, u8* buffer, size_t* count, void* ref_con) +{ + return __access_file(handle, buffer, count, ref_con, DSMSG_ReadFile); +} + +static DSIOResult __write_file(u32 handle, u8* buffer, size_t* count, void* ref_con) +{ + return __access_file(handle, buffer, count, ref_con, DSMSG_WriteFile); +} + +static DSIOResult __access_file(u32 handle, u8* buffer, size_t* count, void* ref_con, + MessageCommandID cmd) +{ + size_t countTemp; + u32 r0; + + if (GetTRKConnected() == DS_NoError) + { + return DS_IOError; + } + + countTemp = *count; + r0 = TRKAccessFile(cmd, handle, &countTemp, buffer); + *count = countTemp; + + switch ((u8)r0) + { + case DS_IONoError: + return DS_IONoError; + case DS_IOEOF: + return DS_IOEOF; + } + + return DS_IOError; +} \ No newline at end of file diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c index e69de29bb..f690ba9f7 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c @@ -0,0 +1,168 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +#define EXCEPTIONMASK_ADDR 0x80000044 + +static u32 lc_base; +extern u32 _db_stack_addr; + +static u32 TRK_ISR_OFFSETS[15] = { PPC_SystemReset, + PPC_MachineCheck, + PPC_DataStorage, + PPC_InstructionStorage, + PPC_ExternalInterrupt, + PPC_Alignment, + PPC_Program, + PPC_FloatingPointUnavaiable, + PPC_Decrementer, + PPC_SystemCall, + PPC_Trace, + PPC_PerformanceMonitor, + PPC_InstructionAddressBreakpoint, + PPC_SystemManagementInterrupt, + PPC_ThermalManagementInterrupt }; + +void __TRK_reset() +{ + __TRK_copy_vectors(); +} + +/* + * --INFO-- + * Address: 8021FE60 + * Size: 000094 + */ +ASM void InitMetroTRK() +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + + addi r1, r1, -4 + stw r3, 0(r1) + lis r3, gTRKCPUState@h + ori r3, r3, gTRKCPUState@l + stmw r0, ProcessorState_PPC.Default.GPR(r3) //Save the gprs + lwz r4, 0(r1) + addi r1, r1, 4 + stw r1, ProcessorState_PPC.Default.GPR[1](r3) + stw r4, ProcessorState_PPC.Default.GPR[3](r3) + mflr r4 + stw r4, ProcessorState_PPC.Default.LR(r3) + stw r4, ProcessorState_PPC.Default.PC(r3) + mfcr r4 + stw r4, ProcessorState_PPC.Default.CR(r3) + //??? + mfmsr r4 + ori r3, r4, (1 << (31 - 16)) + xori r3, r3, (1 << (31 - 16)) + mtmsr r3 + mtsrr1 r4 //Copy msr to srr1 + //Save misc registers to gTRKCPUState + bl TRKSaveExtended1Block + lis r3, gTRKCPUState@h + ori r3, r3, gTRKCPUState@l + lmw r0, ProcessorState_PPC.Default.GPR(r3) //Restore the gprs + //Reset IABR and DABR + li r0, 0 + mtspr 0x3f2, r0 + mtspr 0x3f5, r0 + //Restore stack pointer + lis r1, _db_stack_addr@h + ori r1, r1, _db_stack_addr@l + mr r3, r5 + bl InitMetroTRKCommTable //Initialize comm table + /* + If InitMetroTRKCommTable returned 1 (failure), an invalid hardware + id or the id for GDEV was somehow passed. Since only BBA or NDEV + are supported, we return early. Otherwise, we proceed with + starting up TRK. + */ + cmpwi r3, 1 + bne initCommTableSuccess + /* + BUG: The code probably orginally reloaded gTRKCPUState here, but + as is it will read the returned value of InitMetroTRKCommTable + as a TRKCPUState struct pointer, causing the CPU to return to + a garbage code address. + */ + lwz r4, ProcessorState_PPC.Default.LR(r3) + mtlr r4 + lmw r0, ProcessorState_PPC.Default.GPR(r3) //Restore the gprs + blr +initCommTableSuccess: + b TRK_main //Jump to TRK_main +#endif // clang-format on +} + +/* + * --INFO-- + * Address: 8021FEF4 + * Size: 000020 + */ +void EnableMetroTRKInterrupts(void) +{ + EnableEXI2Interrupts(); +} + +/* + * --INFO-- + * Address: 8021FF14 + * Size: 000048 + */ +u32 TRKTargetTranslate(u32 param_0) +{ + if (param_0 >= lc_base) + { + if ((param_0 < lc_base + 0x4000) && ((gTRKCPUState.Extended1.DBAT3U_ & 3) != 0)) + { + return param_0; + } + } + + return param_0 & 0x3FFFFFFF | 0x80000000; +} + +/* + * --INFO-- + * Address: 8021FF5C + * Size: 000060 + */ +void TRK_copy_vector(u32 offset) +{ + void* destPtr = (void*)TRKTargetTranslate(offset); + TRK_memcpy(destPtr, gTRKInterruptVectorTable + offset, 0x100); + TRK_flush_cache(destPtr, 0x100); +} + +/* + * --INFO-- + * Address: 8021FFBC + * Size: 000094 + */ +void __TRK_copy_vectors(void) +{ + int i; + u32 mask; + + mask = *(u32*)TRKTargetTranslate(0x44); + + for (i = 0; i <= 14; ++i) + { + if (mask & (1 << i)) + { + TRK_copy_vector(TRK_ISR_OFFSETS[i]); + } + } +} + +/* + * --INFO-- + * Address: 80220050 + * Size: 000050 + */ +DSError TRKInitializeTarget() +{ + gTRKState.isStopped = TRUE; + gTRKState.msr = __TRK_get_MSR(); + lc_base = 0xE0000000; + return DS_NoError; +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c index e69de29bb..21a02e78b 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c @@ -0,0 +1,259 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" +#include "Dolphin/db.h" + +#define BUFF_LEN 4362 + +u8 gWriteBuf[BUFF_LEN]; +u8 gReadBuf[BUFF_LEN]; +s32 _MetroTRK_Has_Framing; +s32 gReadCount; +s32 gReadPos; +s32 gWritePos; + +DBCommTable gDBCommTable = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; + +/* + * --INFO-- + * Address: 80220460 + * Size: 000088 + */ +ASM void TRKLoadContext(OSContext* ctx, u32 a) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + lwz r0, OSContext.gpr[0](r3) + lwz r1, OSContext.gpr[1](r3) + lwz r2, OSContext.gpr[2](r3) + lhz r5, OSContext.state(r3) + rlwinm. r6, r5, 0, 0x1e, 0x1e + beq lbl_80371C1C + rlwinm r5, r5, 0, 0x1f, 0x1d + sth r5, OSContext.state(r3) + lmw r5, OSContext.gpr[5](r3) + b lbl_80371C20 +lbl_80371C1C: + lmw r13, OSContext.gpr[13](r3) +lbl_80371C20: + mr r31, r3 + mr r3, r4 + lwz r4, OSContext.cr(r31) + mtcrf 0xff, r4 + lwz r4, OSContext.lr(r31) + mtlr r4 + lwz r4, OSContext.ctr(r31) + mtctr r4 + lwz r4, OSContext.xer(r31) + mtxer r4 + mfmsr r4 + rlwinm r4, r4, 0, 0x11, 0xf //Turn off external exceptions + rlwinm r4, r4, 0, 0x1f, 0x1d //Turn off recoverable exception flag + mtmsr r4 + mtsprg 1, r2 + lwz r4, OSContext.gpr[3](r31) + mtsprg 2, r4 + lwz r4, OSContext.gpr[4](r31) + mtsprg 3, r4 + lwz r2, OSContext.srr0(r31) + lwz r4, OSContext.srr1(r31) + lwz r31, OSContext.gpr[31](r31) + b TRKInterruptHandler +#endif // clang-format on +} +/* + * --INFO-- + * Address: 802204E8 + * Size: 000038 + */ +void TRKEXICallBack(__OSInterrupt param_0, OSContext* ctx) +{ + OSEnableScheduler(); + TRKLoadContext(ctx, 0x500); +} + +// int InitMetroTRKCommTable(int hwId) +// { +// int result; + +// if (hwId == HARDWARE_GDEV) { +// result = Hu_IsStub(); + +// gDBCommTable.initialize_func = (DBCommInitFunc)DBInitComm; +// gDBCommTable.init_interrupts_func = (DBCommFunc)DBInitInterrupts; +// gDBCommTable.peek_func = (DBCommFunc)DBQueryData; +// gDBCommTable.read_func = (DBCommReadFunc)DBRead; +// gDBCommTable.write_func = (DBCommWriteFunc)DBWrite; +// gDBCommTable.open_func = (DBCommFunc)DBOpen; +// gDBCommTable.close_func = (DBCommFunc)DBClose; +// } else { +// result = AMC_IsStub(); + +// gDBCommTable.initialize_func = (DBCommInitFunc)EXI2_Init; +// gDBCommTable.init_interrupts_func = (DBCommFunc)EXI2_EnableInterrupts; +// gDBCommTable.peek_func = (DBCommFunc)EXI2_Poll; +// gDBCommTable.read_func = (DBCommReadFunc)EXI2_ReadN; +// gDBCommTable.write_func = (DBCommWriteFunc)EXI2_WriteN; +// gDBCommTable.open_func = (DBCommFunc)EXI2_Reserve; +// gDBCommTable.close_func = (DBCommFunc)EXI2_Unreserve; +// } + +// return result; +// } + +/* + * --INFO-- + * Address: 80220608 + * Size: 000004 + */ +void TRKUARTInterruptHandler(void) +{ +} + +/* + * --INFO-- + * Address: 8022060C + * Size: 000040 + */ +DSError TRKInitializeIntDrivenUART(u32 param_0, u32 param_1, u32 param_2, volatile u8** param_3) +{ + gDBCommTable.initialize_func(param_3, TRKEXICallBack); + return DS_NoError; +} + +/* + * --INFO-- + * Address: 8022064C + * Size: 000030 + */ +void EnableEXI2Interrupts(void) +{ + gDBCommTable.init_interrupts_func(); +} + +/* + * --INFO-- + * Address: 8022067C + * Size: 000030 + */ +int TRKPollUART(void) +{ + return gDBCommTable.peek_func(); +} + +/* + * --INFO-- + * Address: 802206AC + * Size: 000044 + */ +UARTError TRKReadUARTN(void* bytes, u32 length) +{ + int readErr = gDBCommTable.read_func(bytes, length); + return readErr == 0 ? 0 : -1; +} + +/* + * --INFO-- + * Address: 802206F0 + * Size: 000044 + */ +UARTError TRKWriteUARTN(const void* bytes, u32 length) +{ + int writeErr = gDBCommTable.write_func(bytes, length); + return writeErr == 0 ? 0 : -1; +} + +/* + * --INFO-- + * Address: ........ + * Size: 000050 + */ +UARTError WriteUARTFlush(void) +{ + UARTError readErr = 0; + + while (gWritePos < 0x800) + { + gWriteBuf[gWritePos] = 0; + gWritePos++; + } + if (gWritePos != 0) + { + readErr = TRKWriteUARTN(gWriteBuf, gWritePos); + gWritePos = 0; + } + return readErr; +} +/* + * --INFO-- + * Address: ........ + * Size: 00002C + */ +UARTError WriteUART1(u8 arg0) +{ + gWriteBuf[gWritePos++] = arg0; + return 0; +} + +/* + * --INFO-- + * Address: ........ + * Size: 0000F8 + */ +UARTError TRKReadUARTPoll(u8* arg0) +{ + UARTError readErr = 4; + s32 cnt; + + if (gReadPos >= gReadCount) + { + gReadPos = 0; + cnt = gReadCount = TRKPollUART(); + if (cnt > 0) + { + if (cnt > BUFF_LEN) + { + gReadCount = BUFF_LEN; + } + readErr = TRKReadUARTN(gReadBuf, gReadCount); + if (readErr != 0) + { + gReadCount = 0; + } + } + } + if (gReadPos < gReadCount) + { + *arg0 = gReadBuf[gReadPos++]; + readErr = 0; + } + return readErr; +} + +/* + * --INFO-- + * Address: 80220734 + * Size: 000030 + */ +void ReserveEXI2Port(void) +{ + gDBCommTable.open_func(); +} + +/* + * --INFO-- + * Address: 80220764 + * Size: 000030 + */ +void UnreserveEXI2Port(void) +{ + gDBCommTable.close_func(); +} + +/* + * --INFO-- + * Address: 80220794 + * Size: 000024 + */ +void TRK_board_display(char* str) +{ + OSReport(str); +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/targcont.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/targcont.c index e69de29bb..6bbff90b7 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/targcont.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/targcont.c @@ -0,0 +1,16 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +/* + * --INFO-- + * Address: 802207B8 + * Size: 000034 + */ + +DSError TRKTargetContinue(void) +{ + TRKTargetSetStopped(0); + UnreserveEXI2Port(); + TRKSwapAndGo(); + ReserveEXI2Port(); + return 0; +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/target_options.h b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/target_options.h new file mode 100644 index 000000000..c77c54b2b --- /dev/null +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/target_options.h @@ -0,0 +1,17 @@ +#ifndef OS_DOLPHIN_TARGET_OPTIONS_H +#define OS_DOLPHIN_TARGET_OPTIONS_H + +#include "dolphin/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +u8 GetUseSerialIO(void); +void SetUseSerialIO(u8); + +#ifdef __cplusplus +} +#endif + +#endif /* OS_DOLPHIN_TARGET_OPTIONS_H */ diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/usr_put.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/usr_put.c index e69de29bb..084bd755e 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/usr_put.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/usr_put.c @@ -0,0 +1,140 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +/* + * --INFO-- + * Address: ........ + * Size: 000038 + */ +void usr_putchar_serial(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000050 + */ +BOOL usr_puts_serial(const char* msg) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000004 + */ +void usr_put_initialize_ram(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void usr_putchar_ram(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000044 + */ +void usr_puts_ram(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: 8021CEDC + * Size: 000004 + */ +void usr_put_initialize(void) +{ +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void usr_putchar(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void usr_puts(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000024 + */ +void __do_putchar(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000020 + */ +void __do_puts(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 0001B8 + */ +void __do_puthex32(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 0000CC + */ +void __do_puthex8(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000098 + */ +void __do_puthex4(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000068 + */ +void __do_puthex2(void) +{ + // UNUSED FUNCTION +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/dispatch.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/dispatch.c index e69de29bb..cc766cb34 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/dispatch.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/dispatch.c @@ -0,0 +1,60 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +u32 gTRKDispatchTableSize; + +struct DispatchEntry { + DSError (*fn)(TRKBuffer*); +}; + +struct DispatchEntry gTRKDispatchTable[33] = { + { &TRKDoUnsupported }, { &TRKDoConnect }, { &TRKDoDisconnect }, { &TRKDoReset }, { &TRKDoVersions }, + { &TRKDoSupportMask }, { &TRKDoCPUType }, { &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported }, + { &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported }, + { &TRKDoUnsupported }, { &TRKDoReadMemory }, { &TRKDoWriteMemory }, { &TRKDoReadRegisters }, { &TRKDoWriteRegisters }, + { &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoFlushCache }, { &TRKDoUnsupported }, { &TRKDoContinue }, + { &TRKDoStep }, { &TRKDoStop }, { &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported }, + { &TRKDoUnsupported }, { &TRKDoUnsupported }, +}; + +/* + * --INFO-- + * Address: 8021CEE0 + * Size: 000014 + */ +DSError TRKInitializeDispatcher() +{ + gTRKDispatchTableSize = 32; + return DS_NoError; +} + +/* + * --INFO-- + * Address: ........ + * Size: 0000A0 + */ +DSError TRKOverrideDispatch(TRKBuffer* buffer) +{ + return DS_NoError; + + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: 8021CEF4 + * Size: 000084 + */ +DSError TRKDispatchMessage(TRKBuffer* buffer) +{ + DSError error; + u8 command; + + error = DS_DispatchError; + TRKSetBufferPosition(buffer, 0); + TRKReadBuffer1_ui8(buffer, &command); + command &= 0xFF; + if (command < gTRKDispatchTableSize) { + error = gTRKDispatchTable[command].fn(buffer); + } + return error; +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/main_TRK.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/main_TRK.c index e69de29bb..59da56194 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/main_TRK.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/main_TRK.c @@ -0,0 +1,20 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +static DSError TRK_mainError; + +/* + * --INFO-- + * Address: 80220418 + * Size: 000048 + */ +DSError TRK_main(void) +{ + TRK_mainError = TRKInitializeNub(); + + if (TRK_mainError == DS_NoError) { + TRKNubWelcome(); + TRKNubMainLoop(); + } + + return TRK_mainError = TRKTerminateNub(); +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mainloop.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mainloop.c index e69de29bb..b3796184a 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mainloop.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mainloop.c @@ -0,0 +1,76 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +extern TRKEventQueue gTRKEventQueue; +extern TRKState gTRKState; + +void TRKHandleRequestEvent(TRKEvent* event) +{ + TRKBuffer* buffer = TRKGetBuffer(event->msgBufID); + TRKDispatchMessage(buffer); +} + +void TRKHandleSupportEvent(TRKEvent* event) +{ + TRKTargetSupportRequest(); +} + +void TRKIdle() +{ + if (TRKTargetStopped() == FALSE) + { + TRKTargetContinue(); + } +} + +void TRKNubMainLoop(void) +{ + TRKEvent event; + BOOL isShutdownRequested; + BOOL isNewInput; + + isShutdownRequested = FALSE; + isNewInput = FALSE; + while (isShutdownRequested == FALSE) + { + if (TRKGetNextEvent(&event) != FALSE) + { + isNewInput = FALSE; + + switch (event.eventType) + { + case NUBEVENT_Null: + break; + + case NUBEVENT_Request: + TRKHandleRequestEvent(&event); + break; + + case NUBEVENT_Shutdown: + isShutdownRequested = TRUE; + break; + + case NUBEVENT_Breakpoint: + case NUBEVENT_Exception: + TRKTargetInterrupt(&event); + break; + + case NUBEVENT_Support: + TRKHandleSupportEvent(&event); + break; + } + + TRKDestructEvent(&event); + continue; + } + + if ((isNewInput == FALSE) || (*(u8*)gTRKInputPendingPtr != '\0')) + { + isNewInput = TRUE; + TRKGetInput(); + continue; + } + + TRKIdle(); + isNewInput = FALSE; + } +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mem_TRK.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mem_TRK.c index e69de29bb..29ead0b78 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mem_TRK.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mem_TRK.c @@ -0,0 +1,96 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +static void TRK_fill_mem(void* dest, int val, size_t count); + +void* TRK_memcpy(void* dest, const void* src, size_t count) +{ + u8* s = (u8*)src - 1; + u8* d = (u8*)dest - 1; + + count++; + + while (--count) + { + *++d = *++s; + } +} + +void* TRK_memset(void* dest, int val, size_t count) +{ + TRK_fill_mem(dest, val, count); + return dest; +} + +static void TRK_fill_mem(void* dest, int value, size_t length) +{ +#define cDest ((u8*)dest) +#define lDest ((u32*)dest) + u32 val = (u8)value; + u32 i; + lDest = (u32*)dest; + cDest = (u8*)dest; + + cDest--; + + if (length >= 32) + { + i = ~(u32)dest & 3; + + if (i) + { + length -= i; + do + { + *++cDest = val; + } while (--i); + } + + if (val) + { + val |= val << 24 | val << 16 | val << 8; + } + + lDest = (u32*)(cDest + 1) - 1; + + i = length >> 5; + if (i) + { + do + { + *++lDest = val; + *++lDest = val; + *++lDest = val; + *++lDest = val; + *++lDest = val; + *++lDest = val; + *++lDest = val; + *++lDest = val; + } while (--i); + } + + i = (length & 31) >> 2; + + if (i) + { + do + { + *++lDest = val; + } while (--i); + } + + cDest = (u8*)(lDest + 1) - 1; + + length &= 3; + } + + if (length) + { + do + { + *++cDest = val; + } while (--length); + } + +#undef cDest +#undef lDest +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msg.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msg.c index e69de29bb..29533094d 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msg.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msg.c @@ -0,0 +1,33 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +/* + * --INFO-- + * Address: ........ + * Size: 00002C + */ +/* +void TRKMessageAdd(void) +{ + // UNUSED FUNCTION +} +*/ +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +/* +void TRKMessageGet(void) +{ + // UNUSED FUNCTION +} +*/ +/* + * --INFO-- + * Address: 8021C4A4 + * Size: 000028 + */ +DSError TRKMessageSend(TRKBuffer* param_1) +{ + return TRKWriteUARTN(param_1->data, param_1->length); +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c index e69de29bb..cce3a6339 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c @@ -0,0 +1,536 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +TRKBuffer gTRKMsgBufs[3]; + +/* + * --INFO-- + * Address: 8021C4CC + * Size: 000008 + */ +static void TRKSetBufferUsed(TRKBuffer* msg, BOOL state) +{ + msg->isInUse = state; +} + +/* + * --INFO-- + * Address: 8021C4D4 + * Size: 000078 + */ +DSError TRKInitializeMessageBuffers(void) +{ + int i; + for (i = 0; i < 3; i++) { + TRKInitializeMutex(&gTRKMsgBufs[i]); + TRKAcquireMutex(&gTRKMsgBufs[i]); + TRKSetBufferUsed(&gTRKMsgBufs[i], FALSE); + TRKReleaseMutex(&gTRKMsgBufs[i]); + } + + return DS_NoError; +} + +/* + * --INFO-- + * Address: 8021C54C + * Size: 00009C + */ +DSError TRKGetFreeBuffer(int* msgID, TRKBuffer** outMsg) +{ + DSError error = DS_NoMessageBufferAvailable; + int i; + *outMsg = NULL; + + for (i = 0; i < 3; i++) { + TRKBuffer* buf = TRKGetBuffer(i); + + TRKAcquireMutex(buf); + if (!buf->isInUse) { + TRKResetBuffer(buf, 1); + TRKSetBufferUsed(buf, TRUE); + error = DS_NoError; + *outMsg = buf; + *msgID = i; + i = 3; // why not break? weird choice + } + TRKReleaseMutex(buf); + } + + return error; +} + +/* + * --INFO-- + * Address: 8021C5E8 + * Size: 00002C + */ +void* TRKGetBuffer(int idx) +{ + TRKBuffer* buf = NULL; + if (idx >= 0 && idx < 3) { + buf = &gTRKMsgBufs[idx]; + } + + return buf; +} + +/* + * --INFO-- + * Address: 8021C614 + * Size: 000068 + */ +void TRKReleaseBuffer(int idx) +{ + TRKBuffer* msg; + if (idx != -1 && idx >= 0 && idx < 3) { + msg = &gTRKMsgBufs[idx]; + TRKAcquireMutex(msg); + TRKSetBufferUsed(msg, FALSE); + TRKReleaseMutex(msg); + } +} + +/* + * --INFO-- + * Address: 8021C67C + * Size: 000040 + */ +void TRKResetBuffer(TRKBuffer* msg, u8 keepData) +{ + msg->length = 0; + msg->position = 0; + + if (!keepData) { + TRK_memset(msg->data, 0, TRKMSGBUF_SIZE); + } +} + +/* + * --INFO-- + * Address: 8021C6BC + * Size: 000030 + */ +DSError TRKSetBufferPosition(TRKBuffer* msg, u32 pos) +{ + DSError error = DS_NoError; + + if (pos > 0x880) { + error = DS_MessageBufferOverflow; + } else { + msg->position = pos; + // If the new position is past the current length, + // update the length + if (pos > msg->length) { + msg->length = pos; + } + } + + return error; +} + +/* + * --INFO-- + * Address: 8021C6EC + * Size: 0000A4 + */ +#pragma dont_inline on +DSError TRKAppendBuffer(TRKBuffer* msg, const void* data, size_t length) +{ + DSError error = DS_NoError; // r31 + u32 bytesLeft; + + // Return if no bytes to append + if (length == 0) { + return DS_NoError; + } + + bytesLeft = 0x880 - msg->position; + + // If there isn't enough space left in the buffer, change the number + // of bytes to append to the remaning number of bytes + if (bytesLeft < length) { + error = DS_MessageBufferOverflow; + length = bytesLeft; + } + + if (length == 1) { + // If the length of bytes to append is 1, just copy the byte over + msg->data[msg->position] = ((u8*)data)[0]; + } else { + // Otherwise, use memcpy + TRK_memcpy(msg->data + msg->position, data, length); + } + + // Update the position and length + msg->position += length; + msg->length = msg->position; + + return error; +} +#pragma dont_inline reset + +/* + * --INFO-- + * Address: 8021C790 + * Size: 00008C + */ +DSError TRKReadBuffer(TRKBuffer* msg, void* data, size_t length) +{ + DSError error = DS_NoError; + unsigned int bytesLeft; // this has to be unsigned int not u32 to match lmfao. + + // Return if no bytes to read + if (length == 0) { + return DS_NoError; + } + + bytesLeft = msg->length - msg->position; + + // If the number of bytes to read exceeds the buffer length, change + // the length to the remaining number of bytes + if (length > bytesLeft) { + error = DS_MessageBufferReadError; + length = bytesLeft; + } + + TRK_memcpy(data, msg->data + msg->position, length); + msg->position += length; + return error; +} + +/* + * --INFO-- + * Address: 8021C81C + * Size: 000054 + */ +DSError TRKAppendBuffer1_ui16(TRKBuffer* buffer, const u16 data) +{ + u8* bigEndianData; + u8* byteData; + u8 swapBuffer[sizeof(data)]; + + if (gTRKBigEndian) { + bigEndianData = (u8*)&data; + } else { + byteData = (u8*)&data; + bigEndianData = swapBuffer; + + bigEndianData[0] = byteData[1]; + bigEndianData[1] = byteData[0]; + } + + return TRKAppendBuffer(buffer, (const void*)bigEndianData, sizeof(data)); +} + +/* + * --INFO-- + * Address: 8021C870 + * Size: 000064 + */ +DSError TRKAppendBuffer1_ui32(TRKBuffer* buffer, const u32 data) +{ + u8* bigEndianData; + u8* byteData; + u8 swapBuffer[sizeof(data)]; + + if (gTRKBigEndian) { + bigEndianData = (u8*)&data; + } else { + byteData = (u8*)&data; + bigEndianData = swapBuffer; + + bigEndianData[0] = byteData[3]; + bigEndianData[1] = byteData[2]; + bigEndianData[2] = byteData[1]; + bigEndianData[3] = byteData[0]; + } + + return TRKAppendBuffer(buffer, (const void*)bigEndianData, sizeof(data)); +} +/* + * --INFO-- + * Address: 8021C8D4 + * Size: 000088 + */ +DSError TRKAppendBuffer1_ui64(TRKBuffer* buffer, const u64 data) +{ + u8* bigEndianData; + u8* byteData; + u8 swapBuffer[sizeof(data)]; + if (gTRKBigEndian) { + bigEndianData = (u8*)&data; + } else { + byteData = (u8*)&data; + bigEndianData = swapBuffer; + + bigEndianData[0] = byteData[7]; + bigEndianData[1] = byteData[6]; + bigEndianData[2] = byteData[5]; + bigEndianData[3] = byteData[4]; + bigEndianData[4] = byteData[3]; + bigEndianData[5] = byteData[2]; + bigEndianData[6] = byteData[1]; + bigEndianData[7] = byteData[0]; + } + + return TRKAppendBuffer(buffer, (const void*)bigEndianData, sizeof(data)); +} + +/* + * --INFO-- + * Address: ........ + * Size: 0000C4 + */ +void TRKAppendBuffer1_ui128(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: 8021C95C + * Size: 000068 + */ +DSError TRKAppendBuffer_ui8(TRKBuffer* buffer, const u8* data, int count) +{ + DSError err; + int i; + + for (i = 0, err = DS_NoError; err == DS_NoError && i < count; i++) { + err = TRKAppendBuffer1_ui8(buffer, data[i]); + } + + return err; +} + +/* + * --INFO-- + * Address: ........ + * Size: 00007C + */ +void TRKAppendBuffer_ui16(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: 8021C9C4 + * Size: 00007C + */ +DSError TRKAppendBuffer_ui32(TRKBuffer* buffer, const u32* data, int count) +{ + DSError err; + int i; + + for (i = 0, err = DS_NoError; err == DS_NoError && i < count; i++) { + err = TRKAppendBuffer1_ui32(buffer, data[i]); + } + + return err; +} + +/* + * --INFO-- + * Address: ........ + * Size: 000080 + */ +void TRKAppendBuffer_ui64(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 00007C + */ +void TRKAppendBuffer_ui128(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: 8021CA40 + * Size: 000024 + */ +DSError TRKReadBuffer1_ui8(TRKBuffer* buffer, u8* data) +{ + return TRKReadBuffer(buffer, (void*)data, 1); +} + +/* + * --INFO-- + * Address: 8021CA64 + * Size: 000080 + */ +DSError TRKReadBuffer1_ui16(TRKBuffer* buffer, u16* data) +{ + DSError err; + + u8* bigEndianData; + u8* byteData; + u8 swapBuffer[sizeof(data)]; + + if (gTRKBigEndian) { + bigEndianData = (u8*)data; + } else { + bigEndianData = swapBuffer; + } + + err = TRKReadBuffer(buffer, (void*)bigEndianData, sizeof(*data)); + + if (!gTRKBigEndian && err == DS_NoError) { + byteData = (u8*)data; + + byteData[0] = bigEndianData[1]; + byteData[1] = bigEndianData[0]; + } + + return err; +} + +/* + * --INFO-- + * Address: 8021CAE4 + * Size: 000090 + */ +DSError TRKReadBuffer1_ui32(TRKBuffer* buffer, u32* data) +{ + DSError err; + + u8* bigEndianData; + u8* byteData; + u8 swapBuffer[sizeof(data)]; + + if (gTRKBigEndian) { + bigEndianData = (u8*)data; + } else { + bigEndianData = swapBuffer; + } + + err = TRKReadBuffer(buffer, (void*)bigEndianData, sizeof(*data)); + + if (!gTRKBigEndian && err == DS_NoError) { + byteData = (u8*)data; + + byteData[0] = bigEndianData[3]; + byteData[1] = bigEndianData[2]; + byteData[2] = bigEndianData[1]; + byteData[3] = bigEndianData[0]; + } + + return err; +} + +/* + * --INFO-- + * Address: 8021CB74 + * Size: 0000B0 + */ +DSError TRKReadBuffer1_ui64(TRKBuffer* buffer, u64* data) +{ + DSError err; + + u8* bigEndianData; + u8* byteData; + u8 swapBuffer[sizeof(data)]; + + if (gTRKBigEndian) { + bigEndianData = (u8*)data; + } else { + bigEndianData = swapBuffer; + } + + err = TRKReadBuffer(buffer, (void*)bigEndianData, sizeof(*data)); + + if (!gTRKBigEndian && err == 0) { + byteData = (u8*)data; + + byteData[0] = bigEndianData[7]; + byteData[1] = bigEndianData[6]; + byteData[2] = bigEndianData[5]; + byteData[3] = bigEndianData[4]; + byteData[4] = bigEndianData[3]; + byteData[5] = bigEndianData[2]; + byteData[6] = bigEndianData[1]; + byteData[7] = bigEndianData[0]; + } + + return err; +} + +/* + * --INFO-- + * Address: ........ + * Size: 0000F0 + */ +void TRKReadBuffer1_ui128(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: 8021CC24 + * Size: 000074 + */ +DSError TRKReadBuffer_ui8(TRKBuffer* buffer, u8* data, int count) +{ + DSError err; + int i; + + for (i = 0, err = DS_NoError; err == DS_NoError && i < count; i++) { + err = TRKReadBuffer1_ui8(buffer, &(data[i])); + } + + return err; +} + +/* + * --INFO-- + * Address: ........ + * Size: 00007C + */ +void TRKReadBuffer_ui16(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: 8021CC98 + * Size: 00007C + */ +DSError TRKReadBuffer_ui32(TRKBuffer* buffer, u32* data, int count) +{ + DSError err; + s32 i; + + for (i = 0, err = DS_NoError; err == DS_NoError && i < count; i++) { + err = TRKReadBuffer1_ui32(buffer, &(data[i])); + } + + return err; +} + +/* + * --INFO-- + * Address: ........ + * Size: 00007C + */ +void TRKReadBuffer_ui64(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 00007C + */ +void TRKReadBuffer_ui128(void) +{ + // UNUSED FUNCTION +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c index e69de29bb..b13760a05 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c @@ -0,0 +1,741 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +typedef struct _TRK_Msg { + u8 _00[8]; + u32 m_msgLength; + u32 _0C; + u8 m_msg[4]; // TODO: unknown array length +} TRK_Msg; + +/* + * --INFO-- + * Address: 8021CF78 + * Size: 000098 + */ +void TRKMessageIntoReply(TRKBuffer* buffer, MessageCommandID ackCmd, DSReplyError errSentInAck) +{ + TRKResetBuffer(buffer, 1); + + TRKAppendBuffer1_ui8(buffer, ackCmd); + TRKAppendBuffer1_ui8(buffer, errSentInAck); +} + +/* + * --INFO-- + * Address: 8021D010 + * Size: 000050 + */ +DSError TRKSendACK(TRKBuffer* buffer) +{ + DSError err; + int ackTries; + + ackTries = 3; + do { + err = TRKMessageSend(buffer); + --ackTries; + } while (err != DS_NoError && ackTries > 0); + + return err; +} + +/* + * --INFO-- + * Address: 8021D060 + * Size: 000034 + */ +DSError TRKStandardACK(TRKBuffer* buffer, MessageCommandID commandID, DSReplyError replyError) +{ + TRKMessageIntoReply(buffer, commandID, replyError); + return TRKSendACK(buffer); +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void TRKDoError(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: 8021D094 + * Size: 000028 + */ +DSError TRKDoUnsupported(TRKBuffer* buffer) +{ + return TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_UnsupportedCommandError); +} + +/* + * --INFO-- + * Address: 8021D0BC + * Size: 000028 + */ +DSError TRKDoConnect(TRKBuffer* buffer) +{ + return TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NoError); +} + +/* + * --INFO-- + * Address: 8021D0E4 + * Size: 000050 + */ +DSError TRKDoDisconnect(TRKBuffer* buffer) +{ + DSError error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NoError); + TRKEvent event; + + if (error == DS_NoError) { + TRKConstructEvent(&event, 1); + TRKPostEvent(&event); + } + return error; +} + +/* + * --INFO-- + * Address: 8021D134 + * Size: 000030 + */ +DSError TRKDoReset(TRKBuffer* buffer) +{ + TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NoError); + __TRK_reset(); + return DS_NoError; +} + +/* + * --INFO-- + * Address: 8021D164 + * Size: 000184 + */ +DSError TRKDoVersions(TRKBuffer* buffer) +{ + DSError error; + DSVersions versions; + + if (buffer->length != 1) { + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); + } else { + TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError); + error = TRKTargetVersions(&versions); + + if (error == DS_NoError) + error = TRKAppendBuffer1_ui8(buffer, versions.kernelMajor); + if (error == DS_NoError) + error = TRKAppendBuffer1_ui8(buffer, versions.kernelMinor); + if (error == DS_NoError) + error = TRKAppendBuffer1_ui8(buffer, versions.protocolMajor); + if (error == DS_NoError) + error = TRKAppendBuffer1_ui8(buffer, versions.protocolMinor); + + if (error != DS_NoError) + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_CWDSError); + else + error = TRKSendACK(buffer); + } +} + +/* + * --INFO-- + * Address: 8021D2E8 + * Size: 0000DC + */ +DSError TRKDoSupportMask(TRKBuffer* buffer) +{ + DSError error; + u8 mask[32]; + + if (buffer->length != 1) { + TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); + } else { + TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError); + error = TRKTargetSupportMask(mask); + + if (error == DS_NoError) + error = TRKAppendBuffer(buffer, mask, 32); + if (error == DS_NoError) + error = TRKAppendBuffer1_ui8(buffer, 2); + + if (error != DS_NoError) + TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_CWDSError); + else + TRKSendACK(buffer); + } +} + +/* + * --INFO-- + * Address: 8021D3C4 + * Size: 000244 + */ +DSError TRKDoCPUType(TRKBuffer* buffer) +{ + DSError error; + DSCPUType cputype; + + if (buffer->length != 1) { + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); + return; + } + + TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError); + + error = TRKTargetCPUType(&cputype); + + if (error == DS_NoError) + error = TRKAppendBuffer1_ui8(buffer, cputype.cpuMajor); + if (error == DS_NoError) + error = TRKAppendBuffer1_ui8(buffer, cputype.cpuMinor); + if (error == DS_NoError) + error = TRKAppendBuffer1_ui8(buffer, cputype.bigEndian); + if (error == DS_NoError) + error = TRKAppendBuffer1_ui8(buffer, cputype.defaultTypeSize); + if (error == DS_NoError) + error = TRKAppendBuffer1_ui8(buffer, cputype.fpTypeSize); + if (error == DS_NoError) + error = TRKAppendBuffer1_ui8(buffer, cputype.extended1TypeSize); + if (error == DS_NoError) + error = TRKAppendBuffer1_ui8(buffer, cputype.extended2TypeSize); + + if (error != DS_NoError) + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_CWDSError); + else + error = TRKSendACK(buffer); +} + +/* + * --INFO-- + * Address: 8021D608 + * Size: 0001E8 + */ +DSError TRKDoReadMemory(TRKBuffer* buffer) +{ + u8 tempBuf[0x800] ATTRIBUTE_ALIGN(32); + u32 length; + u32 msg_start; + u16 msg_length; + u8 msg_options; + u8 msg_command; + DSReplyError replyError; + DSError error; + + if (buffer->length != 8) { + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); + return error; + } + + TRKSetBufferPosition(buffer, DSREPLY_NoError); + error = TRKReadBuffer1_ui8(buffer, &msg_command); + if (error == DS_NoError) + error = TRKReadBuffer1_ui8(buffer, &msg_options); + + if (error == DS_NoError) + error = TRKReadBuffer1_ui16(buffer, &msg_length); + + if (error == DS_NoError) + error = TRKReadBuffer1_ui32(buffer, &msg_start); + + if (msg_options & 2) { + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_UnsupportedOptionError); + return error; + } + + if (msg_length > 0x800) { + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_ParameterError); + return error; + } + + TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError); + + if (error == DS_NoError) { + length = (u32)msg_length; + error = TRKTargetAccessMemory(tempBuf, msg_start, &length, (msg_options & 8) ? MEMACCESS_UserMemory : MEMACCESS_DebuggerMemory, 1); + msg_length = (u16)length; + if (error == DS_NoError) + error = TRKAppendBuffer1_ui16(buffer, msg_length); + if (error == DS_NoError) + error = TRKAppendBuffer(buffer, tempBuf, length); + } + + if (error != DS_NoError) { + switch (error) { + case DS_CWDSException: + replyError = DSREPLY_CWDSException; + break; + case DS_InvalidMemory: + replyError = DSREPLY_InvalidMemoryRange; + break; + case DS_InvalidProcessID: + replyError = DSREPLY_InvalidProcessID; + break; + case DS_InvalidThreadID: + replyError = DSREPLY_InvalidThreadID; + break; + case DS_OSError: + replyError = DSREPLY_OSError; + break; + default: + replyError = DSREPLY_CWDSError; + break; + } + error = TRKStandardACK(buffer, DSMSG_ReplyACK, replyError); + } else { + error = TRKSendACK(buffer); + } + + return error; +} + +/* + * --INFO-- + * Address: 8021D7F0 + * Size: 0001FC + */ +DSError TRKDoWriteMemory(TRKBuffer* buffer) +{ + u8 tmpBuffer[0x800] ATTRIBUTE_ALIGN(32); + u32 length; + u32 msg_start; + u16 msg_length; + u8 msg_options; + u8 msg_command; + DSReplyError replyError; + DSError error; + + if (buffer->length <= 8) { + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); + return error; + } + + TRKSetBufferPosition(buffer, DSREPLY_NoError); + error = TRKReadBuffer1_ui8(buffer, &msg_command); + if (error == DS_NoError) + error = TRKReadBuffer1_ui8(buffer, &msg_options); + + if (error == DS_NoError) + error = TRKReadBuffer1_ui16(buffer, &msg_length); + + if (error == DS_NoError) + error = TRKReadBuffer1_ui32(buffer, &msg_start); + + if (msg_options & 2) { + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_UnsupportedOptionError); + return error; + } + + if ((buffer->length != msg_length + 8) || (msg_length > 0x800)) { + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_ParameterError); + } else { + if (error == DS_NoError) { + length = (u32)msg_length; + error = TRKReadBuffer(buffer, tmpBuffer, length); + if (error == DS_NoError) { + error = TRKTargetAccessMemory(tmpBuffer, msg_start, &length, + (msg_options & 8) ? MEMACCESS_UserMemory : MEMACCESS_DebuggerMemory, FALSE); + } + msg_length = (u16)length; + } + + if (error == DS_NoError) + TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError); + + if (error == DS_NoError) + error = TRKAppendBuffer1_ui16(buffer, msg_length); + + if (error != DS_NoError) { + switch (error) { + case DS_CWDSException: + replyError = DSREPLY_CWDSException; + break; + case DS_InvalidMemory: + replyError = DSREPLY_InvalidMemoryRange; + break; + case DS_InvalidProcessID: + replyError = DSREPLY_InvalidProcessID; + break; + case DS_InvalidThreadID: + replyError = DSREPLY_InvalidThreadID; + break; + case DS_OSError: + replyError = DSREPLY_OSError; + break; + default: + replyError = DSREPLY_CWDSError; + break; + } + error = TRKStandardACK(buffer, DSMSG_ReplyACK, replyError); + } else { + error = TRKSendACK(buffer); + } + } + + return error; +} + +/* + * --INFO-- + * Address: 8021D9EC + * Size: 000204 + */ +DSError TRKDoReadRegisters(TRKBuffer* buffer) +{ + DSMessageRegisterOptions options; + u32 registerDataLength; + u16 msg_lastRegister; + u16 msg_firstRegister; + u8 msg_options; + u8 msg_command; + DSError error; + DSReplyError replyError; + + if (buffer->length != 6) { + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); + return; + } + TRKSetBufferPosition(buffer, DSREPLY_NoError); + error = TRKReadBuffer1_ui8(buffer, &msg_command); + if (error == DS_NoError) + error = TRKReadBuffer1_ui8(buffer, &msg_options); + + if (error == DS_NoError) + error = TRKReadBuffer1_ui16(buffer, &msg_firstRegister); + + if (error == DS_NoError) + error = TRKReadBuffer1_ui16(buffer, &msg_lastRegister); + + if (msg_firstRegister > msg_lastRegister) { + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_InvalidRegisterRange); + return; + } + + if (error == DS_NoError) + TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError); + + options = (DSMessageRegisterOptions)(msg_options & 7); + switch (options) { + case DSREG_Default: + error = TRKTargetAccessDefault(msg_firstRegister, msg_lastRegister, buffer, ®isterDataLength, TRUE); + break; + case DSREG_FP: + error = TRKTargetAccessFP(msg_firstRegister, msg_lastRegister, buffer, ®isterDataLength, TRUE); + break; + case DSREG_Extended1: + error = TRKTargetAccessExtended1(msg_firstRegister, msg_lastRegister, buffer, ®isterDataLength, TRUE); + break; + case DSREG_Extended2: + error = TRKTargetAccessExtended2(msg_firstRegister, msg_lastRegister, buffer, ®isterDataLength, TRUE); + break; + default: + error = DS_UnsupportedError; + break; + } + + if (error != DS_NoError) { + switch (error) { + case DS_UnsupportedError: + replyError = DSREPLY_UnsupportedOptionError; + break; + case DS_InvalidRegister: + replyError = DSREPLY_InvalidRegisterRange; + break; + case DS_CWDSException: + replyError = DSREPLY_CWDSException; + break; + case DS_InvalidProcessID: + replyError = DSREPLY_InvalidProcessID; + break; + case DS_InvalidThreadID: + replyError = DSREPLY_InvalidThreadID; + break; + case DS_OSError: + replyError = DSREPLY_OSError; + break; + default: + replyError = DSREPLY_CWDSError; + } + + error = TRKStandardACK(buffer, DSMSG_ReplyACK, replyError); + } else { + error = TRKSendACK(buffer); + } +} + +/* + * --INFO-- + * Address: 8021DBF0 + * Size: 000208 + */ +DSError TRKDoWriteRegisters(TRKBuffer* buffer) +{ + DSMessageRegisterOptions options; + u32 registerDataLength; + u16 msg_lastRegister; + u16 msg_firstRegister; + u8 msg_options; + u8 msg_command; + DSError error; + DSReplyError replyError; + + if (buffer->length <= 6) { + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); + return; + } + TRKSetBufferPosition(buffer, DSREPLY_NoError); + error = TRKReadBuffer1_ui8(buffer, &msg_command); + if (error == DS_NoError) + error = TRKReadBuffer1_ui8(buffer, &msg_options); + + if (error == DS_NoError) + error = TRKReadBuffer1_ui16(buffer, &msg_firstRegister); + + if (error == DS_NoError) + error = TRKReadBuffer1_ui16(buffer, &msg_lastRegister); + + if (msg_firstRegister > msg_lastRegister) { + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_InvalidRegisterRange); + return; + } + + options = (DSMessageRegisterOptions)msg_options; + switch (options) { + case DSREG_Default: + error = TRKTargetAccessDefault(msg_firstRegister, msg_lastRegister, buffer, ®isterDataLength, FALSE); + break; + case DSREG_FP: + error = TRKTargetAccessFP(msg_firstRegister, msg_lastRegister, buffer, ®isterDataLength, FALSE); + break; + case DSREG_Extended1: + error = TRKTargetAccessExtended1(msg_firstRegister, msg_lastRegister, buffer, ®isterDataLength, FALSE); + break; + case DSREG_Extended2: + error = TRKTargetAccessExtended2(msg_firstRegister, msg_lastRegister, buffer, ®isterDataLength, FALSE); + break; + default: + error = DS_UnsupportedError; + break; + } + + if (error == DS_NoError) + TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError); + + if (error != DS_NoError) { + switch (error) { + case DS_UnsupportedError: + replyError = DSREPLY_UnsupportedOptionError; + break; + case DS_InvalidRegister: + replyError = DSREPLY_InvalidRegisterRange; + break; + case DS_MessageBufferReadError: + replyError = DSREPLY_PacketSizeError; + break; + case DS_CWDSException: + replyError = DSREPLY_CWDSException; + break; + case DS_InvalidProcessID: + replyError = DSREPLY_InvalidProcessID; + break; + case DS_InvalidThreadID: + replyError = DSREPLY_InvalidThreadID; + break; + case DS_OSError: + replyError = DSREPLY_OSError; + break; + default: + replyError = DSREPLY_CWDSError; + } + + error = TRKStandardACK(buffer, DSMSG_ReplyACK, replyError); + } else { + error = TRKSendACK(buffer); + } +} + +/* + * --INFO-- + * Address: 8021DDF8 + * Size: 000138 + */ +DSError TRKDoFlushCache(TRKBuffer* buffer) +{ + u32 msg_end; + u32 msg_start; + u8 msg_options; + u8 msg_command; + DSError error; + DSReplyError replyErr; + + if (buffer->length != 10) { + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); + return; + } + + TRKSetBufferPosition(buffer, DSREPLY_NoError); + error = TRKReadBuffer1_ui8(buffer, &msg_command); + if (error == DS_NoError) + error = TRKReadBuffer1_ui8(buffer, &msg_options); + if (error == DS_NoError) + error = TRKReadBuffer1_ui32(buffer, &msg_start); + if (error == DS_NoError) + error = TRKReadBuffer1_ui32(buffer, &msg_end); + + if (msg_start > msg_end) { + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_InvalidMemoryRange); + return; + } + + if (error == DS_NoError) + error = TRKTargetFlushCache(msg_options, (void*)msg_start, (void*)msg_end); + + if (error == DS_NoError) + TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError); + + if (error != DS_NoError) { + switch (error) { + case DS_UnsupportedError: + replyErr = DSREPLY_UnsupportedOptionError; + break; + default: + replyErr = DSREPLY_CWDSError; + break; + } + + error = TRKStandardACK(buffer, DSMSG_ReplyACK, replyErr); + } else { + error = TRKSendACK(buffer); + } +} + +/* + * --INFO-- + * Address: 8021DF30 + * Size: 000064 + */ +DSError TRKDoContinue(TRKBuffer* buffer) +{ + DSError error; + + error = TRKTargetStopped(); + if (error == DS_NoError) { + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NotStopped); + return; + } + + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NoError); + if (error == DS_NoError) + error = TRKTargetContinue(); +} + +/* + * --INFO-- + * Address: 8021DF94 + * Size: 000204 + */ +DSError TRKDoStep(TRKBuffer* buffer) +{ + DSError error; + u32 msg_rangeEnd; + u32 msg_rangeStart; + u8 msg_count; + u8 msg_options; + u8 msg_command; + u32 pc; + + if (buffer->length < 3) { + TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); + return; + } + + TRKSetBufferPosition(buffer, DSREPLY_NoError); + + error = TRKReadBuffer1_ui8(buffer, &msg_command); + if (error == DS_NoError) + error = TRKReadBuffer1_ui8(buffer, &msg_options); + + switch (msg_options) { + case DSSTEP_IntoCount: + case DSSTEP_OverCount: + if (error == DS_NoError) + TRKReadBuffer1_ui8(buffer, &msg_count); + if (msg_count >= 1) { + break; + } + TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_ParameterError); + return; + case DSSTEP_IntoRange: + case DSSTEP_OverRange: + if (buffer->length != 10) { + TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); + return; + } + + if (error == DS_NoError) + error = TRKReadBuffer1_ui32(buffer, &msg_rangeStart); + if (error == DS_NoError) + error = TRKReadBuffer1_ui32(buffer, &msg_rangeEnd); + + pc = TRKTargetGetPC(); + if (pc >= msg_rangeStart && pc <= msg_rangeEnd) { + break; + } + TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_ParameterError); + return; + default: + TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_UnsupportedOptionError); + return; + } + + if (!TRKTargetStopped()) { + TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NotStopped); + return; + } + + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NoError); + if (error == DS_NoError) + switch (msg_options) { + case DSSTEP_IntoCount: + case DSSTEP_OverCount: + error = TRKTargetSingleStep(msg_count, (msg_options == DSSTEP_OverCount)); + break; + case DSSTEP_IntoRange: + case DSSTEP_OverRange: + error = TRKTargetStepOutOfRange(msg_rangeStart, msg_rangeEnd, (msg_options == DSSTEP_OverRange)); + break; + } +} + +/* + * --INFO-- + * Address: 8021E198 + * Size: 000084 + */ +DSError TRKDoStop(TRKBuffer* b) +{ + DSReplyError replyError; + + switch (TRKTargetStop()) { + case DS_NoError: + replyError = DSREPLY_NoError; + break; + case DS_InvalidProcessID: + replyError = DSREPLY_InvalidProcessID; + break; + case DS_InvalidThreadID: + replyError = DSREPLY_InvalidThreadID; + break; + case DS_OSError: + replyError = DSREPLY_OSError; + break; + default: + replyError = DSREPLY_Error; + break; + } + + return TRKStandardACK(b, DSMSG_ReplyACK, replyError); +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.h b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.h new file mode 100644 index 000000000..7d1432852 --- /dev/null +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.h @@ -0,0 +1,23 @@ +#ifndef METROTRK_PORTABLE_MSGHNDLR_H +#define METROTRK_PORTABLE_MSGHNDLR_H + +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +void SetTRKConnected(BOOL); +BOOL GetTRKConnected(void); +DSError TRKDoSetOption(TRKBuffer*); +DSError TRKDoStop(TRKBuffer*); +DSError TRKDoStep(TRKBuffer*); +DSError TRKDoContinue(TRKBuffer*); +DSError TRKDoWriteRegisters(TRKBuffer*); +DSError TRKDoReadRegisters(TRKBuffer*); +DSError TRKDoWriteMemory(TRKBuffer*); +DSError TRKDoReadMemory(TRKBuffer*); +DSError TRKDoSupportMask(TRKBuffer*); +DSError TRKDoVersions(TRKBuffer*); +DSError TRKDoOverride(TRKBuffer*); +DSError TRKDoReset(TRKBuffer*); +DSError TRKDoDisconnect(TRKBuffer*); +DSError TRKDoConnect(TRKBuffer*); + +#endif /* METROTRK_PORTABLE_MSGHNDLR_H */ diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mutex_TRK.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mutex_TRK.c index e69de29bb..ad8d6e656 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mutex_TRK.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/mutex_TRK.c @@ -0,0 +1,16 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +DSError TRKReleaseMutex(void*) +{ + return DS_NoError; +} + +DSError TRKAcquireMutex(void*) +{ + return DS_NoError; +} + +DSError TRKInitializeMutex(void*) +{ + return DS_NoError; +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/notify.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/notify.c index e69de29bb..cccdd005b 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/notify.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/notify.c @@ -0,0 +1,51 @@ + +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +inline DSError TRKWaitForACK(TRKBuffer* msg, MessageCommandID cmd) +{ + if (msg->position >= 0x880) + { + return DS_MessageBufferOverflow; + } + msg->data[msg->position++] = cmd; + msg->length += 1; + return DS_NoError; +} + +DSError TRKDoNotifyStopped(u8 cmd) +{ + DSError err; + int reqIdx; + TRKBuffer* msg; + int bufIdx; + + // &msg + // &bufIdx + + err = TRKGetFreeBuffer(&bufIdx, &msg); + if (err == DS_NoError) + { + err = TRKWaitForACK(msg, cmd); + + if (err == DS_NoError) + { + if (cmd == DSMSG_NotifyStopped) + { + TRKTargetAddStopInfo(msg); + } + else + { + TRKTargetAddExceptionInfo(msg); + } + } + + err = TRKRequestSend(msg, &reqIdx, 2, 3, 1); + if (err == DS_NoError) + { + TRKReleaseBuffer(reqIdx); + } + TRKReleaseBuffer(bufIdx); + } + + return err; +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubevent.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubevent.c index e69de29bb..75c3caddd 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubevent.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubevent.c @@ -0,0 +1,106 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +TRKEventQueue gTRKEventQueue; + +/* + * --INFO-- + * Address: 8021C0B4 + * Size: 00005C + */ +DSError TRKInitializeEventQueue() +{ + TRKInitializeMutex(&gTRKEventQueue); + TRKAcquireMutex(&gTRKEventQueue); + gTRKEventQueue.count = 0; + gTRKEventQueue.next = 0; + gTRKEventQueue.eventID = 0x100; + TRKReleaseMutex(&gTRKEventQueue); + return DS_NoError; +} + +/* + * --INFO-- + * Address: 8021C110 + * Size: 000024 + */ +void TRKCopyEvent(TRKEvent* dstEvent, const TRKEvent* srcEvent) +{ + TRK_memcpy(dstEvent, srcEvent, sizeof(TRKEvent)); +} + +/* + * --INFO-- + * Address: 8021C134 + * Size: 0000C0 + */ +BOOL TRKGetNextEvent(TRKEvent* event) +{ + BOOL status = 0; + TRKAcquireMutex(&gTRKEventQueue); + if (0 < gTRKEventQueue.count) + { + TRKCopyEvent(event, &gTRKEventQueue.events[gTRKEventQueue.next]); + gTRKEventQueue.count--; + gTRKEventQueue.next++; + if (gTRKEventQueue.next == 2) + gTRKEventQueue.next = 0; + + status = 1; + } + TRKReleaseMutex(&gTRKEventQueue); + return status; +} + +/* + * --INFO-- + * Address: 8021C1F4 + * Size: 0000E0 + */ +DSError TRKPostEvent(TRKEvent* event) +{ + DSError ret = DS_NoError; + int nextEventID; + + TRKAcquireMutex(&gTRKEventQueue); + + if (gTRKEventQueue.count == 2) + { + ret = DS_EventQueueFull; + } + else + { + nextEventID = (gTRKEventQueue.next + gTRKEventQueue.count) % 2; + TRKCopyEvent(&gTRKEventQueue.events[nextEventID], event); + gTRKEventQueue.events[nextEventID].eventID = gTRKEventQueue.eventID; + gTRKEventQueue.eventID++; + if (gTRKEventQueue.eventID < 0x100) + gTRKEventQueue.eventID = 0x100; + + gTRKEventQueue.count++; + } + + TRKReleaseMutex(&gTRKEventQueue); + return ret; +} + +/* + * --INFO-- + * Address: 8021C2D4 + * Size: 000018 + */ +void TRKConstructEvent(TRKEvent* event, int eventType) +{ + event->eventType = eventType; + event->eventID = 0; + event->msgBufID = -1; +} + +/* + * --INFO-- + * Address: 8021C2EC + * Size: 000024 + */ +void TRKDestructEvent(TRKEvent* event) +{ + TRKReleaseBuffer(event->msgBufID); +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubinit.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubinit.c index e69de29bb..04b5568e1 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubinit.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/nubinit.c @@ -0,0 +1,88 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +BOOL gTRKBigEndian; + +/* + * --INFO-- + * Address: 8021C310 + * Size: 0000D4 + */ +DSError TRKInitializeNub(void) +{ + DSError ret; + DSError uartErr; + + ret = TRKInitializeEndian(); + + if (ret == DS_NoError) + usr_put_initialize(); + if (ret == DS_NoError) + ret = TRKInitializeEventQueue(); + if (ret == DS_NoError) + ret = TRKInitializeMessageBuffers(); + if (ret == DS_NoError) + ret = TRKInitializeDispatcher(); + + if (ret == DS_NoError) { + uartErr = TRKInitializeIntDrivenUART(0x0000e100, 1, 0, (volatile u8**)&gTRKInputPendingPtr); + TRKTargetSetInputPendingPtr(gTRKInputPendingPtr); + if (uartErr != DS_NoError) { + ret = uartErr; + } + } + + if (ret == DS_NoError) + ret = TRKInitializeSerialHandler(); + if (ret == DS_NoError) + ret = TRKInitializeTarget(); + + return ret; +} + +/* + * --INFO-- + * Address: 8021C3E4 + * Size: 000024 + */ +DSError TRKTerminateNub(void) +{ + TRKTerminateSerialHandler(); + return DS_NoError; +} + +/* + * --INFO-- + * Address: 8021C408 + * Size: 000028 + */ +void TRKNubWelcome(void) +{ + TRK_board_display("MetroTRK for Dolphin v0.8"); + return; +} + +/* + * --INFO-- + * Address: 8021C430 + * Size: 000074 + */ +BOOL TRKInitializeEndian(void) +{ + u8 bendian[4]; + BOOL result = FALSE; + gTRKBigEndian = TRUE; + + bendian[0] = 0x12; + bendian[1] = 0x34; + bendian[2] = 0x56; + bendian[3] = 0x78; + + if (*(u32*)bendian == 0x12345678) { + gTRKBigEndian = TRUE; + } else if (*(u32*)bendian == 0x78563412) { + gTRKBigEndian = FALSE; + } else { + result = TRUE; + } + return result; +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/serpoll.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/serpoll.c index e69de29bb..06947aaa7 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/serpoll.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/serpoll.c @@ -0,0 +1,135 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +void* gTRKInputPendingPtr; +static TRKFramingState gTRKFramingState; + +/* + * --INFO-- + * Address: ........ + * Size: 00004C + */ +void TRKDiscardFrame(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000040 + */ +void TRKRejectFrame(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: 8021CD14 + * Size: 0000D0 + */ +TRKBufferID TRKTestForPacket(void) +{ + int bytes; + int batch; + DSError err; + TRKBuffer* b; + int id; + + bytes = TRKPollUART(); + + if (bytes > 0) { + TRKGetFreeBuffer(&id, &b); + if (bytes > 0x880) { + for (; bytes > 0; bytes -= batch) { + batch = bytes > 0x880 ? 0x880 : bytes; + TRKReadUARTN(b->data, batch); + } + TRKStandardACK(b, DSMSG_ReplyNAK, 6); + } else { + err = TRKReadUARTN(b->data, bytes); + if (err == DS_NoError) { + b->length = bytes; + return id; + } + } + } + + if (id != -1) { + TRKReleaseBuffer(id); + } + return -1; +} + +/* + * --INFO-- + * Address: ........ + * Size: 000070 + */ +void TRKProcessFrame(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: 8021CDE4 + * Size: 00007C + */ +void TRKGetInput(void) +{ + TRKBuffer* msgbuffer; + int bufID; + u8 command; + + bufID = TRKTestForPacket(); + + if (bufID != -1) { + msgbuffer = TRKGetBuffer(bufID); + TRKSetBufferPosition(msgbuffer, 0); + TRKReadBuffer1_ui8(msgbuffer, &command); + if (command < 0x80) { + TRKProcessInput(bufID); + } else { + TRKReleaseBuffer(bufID); + } + } +} + +/* + * --INFO-- + * Address: 8021CE60 + * Size: 000050 + */ +void TRKProcessInput(TRKBufferID bufID) +{ + TRKEvent event; + + TRKConstructEvent(&event, 2); + event.msgBufID = bufID; + gTRKFramingState.msgBufID = -1; + TRKPostEvent(&event); +} + +/* + * --INFO-- + * Address: 8021CEB0 + * Size: 000024 + */ +DSError TRKInitializeSerialHandler(void) +{ + gTRKFramingState.msgBufID = -1; + gTRKFramingState.receiveState = 0; + gTRKFramingState.isEscape = 0; + return 0; +} + +/* + * --INFO-- + * Address: 8021CED4 + * Size: 000008 + */ +DSError TRKTerminateSerialHandler(void) +{ + return 0; +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c index e69de29bb..cc1997e3f 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c @@ -0,0 +1,174 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +/* + * --INFO-- + * Address: 8021E21C + * Size: 0002D8 + */ +DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count, u8* io_result, BOOL need_reply, BOOL read) +{ + TRKBuffer* replyBuffer; + int replyBufferId; + u32 length; + TRKBuffer* buffer; + int bufferId; + DSError error; + u32 done; + u16 replyLength; + u8 replyIOResult; + BOOL exit; + + if (data == NULL || *count == 0) { + return DS_ParameterError; + } + + exit = FALSE; + *io_result = DS_IONoError; + done = 0; + error = DS_NoError; + while (!exit && done < *count && error == DS_NoError && *io_result == DS_IONoError) { + if (*count - done > 0x800) { + length = 0x800; + } else { + length = *count - done; + } + + error = TRKGetFreeBuffer(&bufferId, &buffer); + + if (error == DS_NoError) + error = TRKAppendBuffer1_ui8(buffer, read ? DSMSG_ReadFile : DSMSG_WriteFile); + + if (error == DS_NoError) + error = TRKAppendBuffer1_ui32(buffer, file_handle); + + if (error == DS_NoError) + error = TRKAppendBuffer1_ui16(buffer, length); + + if (!read && error == DS_NoError) + error = TRKAppendBuffer_ui8(buffer, data + done, length); + + if (error == DS_NoError) { + if (need_reply) { + replyLength = 0; + replyIOResult = 0; + + error = (0, TRKRequestSend(buffer, &replyBufferId, read ? 5 : 5, 3, !(read && file_handle == 0))); + if (error == DS_NoError) { + replyBuffer = (TRKBuffer*)TRKGetBuffer(replyBufferId); + TRKSetBufferPosition(replyBuffer, 2); + } + + if (error == DS_NoError) + error = TRKReadBuffer1_ui8(replyBuffer, &replyIOResult); + + if (error == DS_NoError) + error = TRKReadBuffer1_ui16(replyBuffer, &replyLength); + + if (read && error == DS_NoError) { + if (replyBuffer->length != replyLength + 5) { + replyLength = replyBuffer->length - 5; + if (replyIOResult == 0) + replyIOResult = 1; + } + + if (replyLength <= length) + error = TRKReadBuffer_ui8(replyBuffer, data + done, replyLength); + } + + if (replyLength != length) { + if ((!read || replyLength >= length) && replyIOResult == 0) + replyIOResult = 1; + length = replyLength; + exit = TRUE; + } + + *io_result = (DSIOResult)replyIOResult; + TRKReleaseBuffer(replyBufferId); + } else { + error = TRKMessageSend(buffer); + } + } + + TRKReleaseBuffer(bufferId); + done += length; + } + + *count = done; + return error; +} + +/* + * --INFO-- + * Address: 8021E4F4 + * Size: 0001A4 + */ +DSError TRKRequestSend(TRKBuffer* msgBuf, int* bufferId, u32 p1, u32 p2, int p3) +{ + int error = DS_NoError; + TRKBuffer* buffer; + u32 timer; + int tries; + u8 msg_error; + u8 msg_command; + BOOL badReply = TRUE; + + *bufferId = -1; + + for (tries = p2 + 1; tries != 0 && *bufferId == -1 && error == DS_NoError; tries--) { + error = TRKMessageSend(msgBuf); + if (error == DS_NoError) { + if (p3) { + timer = 0; + } + + while (TRUE) { + do { + *bufferId = TRKTestForPacket(); + if (*bufferId != -1) + break; + } while (!p3 || ++timer < 79999980); + + if (*bufferId == -1) + break; + + badReply = FALSE; + + buffer = TRKGetBuffer(*bufferId); + TRKSetBufferPosition(buffer, 0); + + if ((error = TRKReadBuffer1_ui8(buffer, &msg_command)) != DS_NoError) + break; + + if (msg_command >= DSMSG_ReplyACK) + break; + + TRKProcessInput(*bufferId); + *bufferId = -1; + } + + if (*bufferId != -1) { + if (buffer->length < p1) { + badReply = TRUE; + } + if (error == DS_NoError && !badReply) { + error = TRKReadBuffer1_ui8(buffer, &msg_error); + } + if (error == DS_NoError && !badReply) { + if (msg_command != DSMSG_ReplyACK || msg_error != DSREPLY_NoError) { + badReply = TRUE; + } + } + if (error != DS_NoError || badReply) { + TRKReleaseBuffer(*bufferId); + *bufferId = -1; + } + } + } + } + + if (*bufferId == -1) { + error = DS_Error800; + } + + return error; +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.h b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.h new file mode 100644 index 000000000..bf0e9b928 --- /dev/null +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.h @@ -0,0 +1,19 @@ +#ifndef PPC_EXPORT_TARGSUPP_H +#define PPC_EXPORT_TARGSUPP_H + +#include "dolphin/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +u32 TRKAccessFile(u32, u32, u32*, u8*); +u32 TRKOpenFile(u32, u32, u32*, u8*); +u32 TRKCloseFile(u32, u32); +u32 TRKPositionFile(u32, u32, u32*, u8*); + +#ifdef __cplusplus +} +#endif + +#endif /* PPC_EXPORT_TARGSUPP_H */ diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s index e69de29bb..0d3813d08 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s @@ -0,0 +1,25 @@ +.include "macros.inc" +# .file "targsupp.s" + +.text +.balign 16 + +.fn TRKAccessFile, global + twui r0, 0x0 + blr +.endfn TRKAccessFile + +.fn TRKOpenFile, global + twui r0, 0x0 + blr +.endfn TRKOpenFile + +.fn TRKCloseFile, global + twui r0, 0x0 + blr +.endfn TRKCloseFile + +.fn TRKPositionFile, global + twui r0, 0x0 + blr +.endfn TRKPositionFile diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s index e69de29bb..c29d815c9 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s @@ -0,0 +1,1998 @@ +.include "macros.inc" + +.section .init, "ax" # 0x80003100 - 0x800054C0 +.global gTRKInterruptVectorTable +gTRKInterruptVectorTable: +.asciz "Metrowerks Target Resident Kernel for PowerPC" +.balign 4 +/* 800034E8 000004E8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800034EC 000004EC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800034F0 000004F0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800034F4 000004F4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800034F8 000004F8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800034FC 000004FC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003500 00000500 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003504 00000504 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003508 00000508 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000350C 0000050C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003510 00000510 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003514 00000514 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003518 00000518 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000351C 0000051C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003520 00000520 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003524 00000524 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003528 00000528 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000352C 0000052C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003530 00000530 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003534 00000534 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003538 00000538 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000353C 0000053C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003540 00000540 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003544 00000544 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003548 00000548 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000354C 0000054C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003550 00000550 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003554 00000554 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003558 00000558 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000355C 0000055C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003560 00000560 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003564 00000564 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003568 00000568 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000356C 0000056C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003570 00000570 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003574 00000574 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003578 00000578 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000357C 0000057C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003580 00000580 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003584 00000584 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003588 00000588 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000358C 0000058C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003590 00000590 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003594 00000594 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003598 00000598 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000359C 0000059C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035A0 000005A0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035A4 000005A4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035A8 000005A8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035AC 000005AC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035B0 000005B0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035B4 000005B4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035B8 000005B8 48 00 1E 34 */ b __TRK_reset +/* 800035BC 000005BC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035C0 000005C0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035C4 000005C4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035C8 000005C8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035CC 000005CC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035D0 000005D0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035D4 000005D4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035D8 000005D8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035DC 000005DC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035E0 000005E0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035E4 000005E4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035E8 000005E8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035EC 000005EC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035F0 000005F0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035F4 000005F4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035F8 000005F8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800035FC 000005FC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003600 00000600 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003604 00000604 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003608 00000608 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000360C 0000060C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003610 00000610 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003614 00000614 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003618 00000618 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000361C 0000061C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003620 00000620 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003624 00000624 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003628 00000628 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000362C 0000062C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003630 00000630 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003634 00000634 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003638 00000638 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000363C 0000063C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003640 00000640 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003644 00000644 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003648 00000648 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000364C 0000064C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003650 00000650 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003654 00000654 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003658 00000658 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000365C 0000065C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003660 00000660 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003664 00000664 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003668 00000668 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000366C 0000066C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003670 00000670 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003674 00000674 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003678 00000678 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000367C 0000067C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003680 00000680 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003684 00000684 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003688 00000688 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000368C 0000068C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003690 00000690 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003694 00000694 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003698 00000698 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000369C 0000069C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800036A0 000006A0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800036A4 000006A4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800036A8 000006A8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800036AC 000006AC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800036B0 000006B0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800036B4 000006B4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800036B8 000006B8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800036BC 000006BC 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 800036C0 000006C0 7C 00 17 AC */ icbi 0, r2 +/* 800036C4 000006C4 7C 53 02 A6 */ mfdar r2 +/* 800036C8 000006C8 7C 00 13 AC */ dcbi 0, r2 +/* 800036CC 000006CC 7C 51 42 A6 */ mfspr r2, 0x111 +/* 800036D0 000006D0 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800036D4 000006D4 7C 72 43 A6 */ mtspr 0x112, r3 +/* 800036D8 000006D8 7C 93 43 A6 */ mtspr 0x113, r4 +/* 800036DC 000006DC 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 800036E0 000006E0 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 800036E4 000006E4 7C 60 00 A6 */ mfmsr r3 +/* 800036E8 000006E8 60 63 00 30 */ ori r3, r3, 0x30 +/* 800036EC 000006EC 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 800036F0 000006F0 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 800036F4 000006F4 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 800036F8 000006F8 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 800036FC 000006FC 38 60 02 00 */ li r3, 0x200 +/* 80003700 00000700 4C 00 00 64 */ rfi +/* 80003704 00000704 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003708 00000708 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000370C 0000070C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003710 00000710 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003714 00000714 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003718 00000718 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000371C 0000071C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003720 00000720 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003724 00000724 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003728 00000728 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000372C 0000072C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003730 00000730 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003734 00000734 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003738 00000738 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000373C 0000073C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003740 00000740 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003744 00000744 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003748 00000748 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000374C 0000074C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003750 00000750 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003754 00000754 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003758 00000758 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000375C 0000075C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003760 00000760 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003764 00000764 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003768 00000768 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000376C 0000076C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003770 00000770 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003774 00000774 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003778 00000778 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000377C 0000077C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003780 00000780 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003784 00000784 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003788 00000788 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000378C 0000078C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003790 00000790 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003794 00000794 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003798 00000798 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000379C 0000079C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800037A0 000007A0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800037A4 000007A4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800037A8 000007A8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800037AC 000007AC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800037B0 000007B0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800037B4 000007B4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800037B8 000007B8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800037BC 000007BC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 800037C0 000007C0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 800037C4 000007C4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 800037C8 000007C8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 800037CC 000007CC 7C 60 00 A6 */ mfmsr r3 +/* 800037D0 000007D0 60 63 00 30 */ ori r3, r3, 0x30 +/* 800037D4 000007D4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 800037D8 000007D8 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 800037DC 000007DC 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 800037E0 000007E0 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 800037E4 000007E4 38 60 03 00 */ li r3, 0x300 +/* 800037E8 000007E8 4C 00 00 64 */ rfi +/* 800037EC 000007EC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800037F0 000007F0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800037F4 000007F4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800037F8 000007F8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800037FC 000007FC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003800 00000800 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003804 00000804 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003808 00000808 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000380C 0000080C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003810 00000810 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003814 00000814 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003818 00000818 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000381C 0000081C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003820 00000820 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003824 00000824 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003828 00000828 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000382C 0000082C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003830 00000830 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003834 00000834 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003838 00000838 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000383C 0000083C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003840 00000840 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003844 00000844 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003848 00000848 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000384C 0000084C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003850 00000850 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003854 00000854 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003858 00000858 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000385C 0000085C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003860 00000860 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003864 00000864 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003868 00000868 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000386C 0000086C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003870 00000870 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003874 00000874 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003878 00000878 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000387C 0000087C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003880 00000880 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003884 00000884 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003888 00000888 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000388C 0000088C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003890 00000890 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003894 00000894 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003898 00000898 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000389C 0000089C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800038A0 000008A0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800038A4 000008A4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800038A8 000008A8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800038AC 000008AC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800038B0 000008B0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800038B4 000008B4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800038B8 000008B8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800038BC 000008BC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 800038C0 000008C0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 800038C4 000008C4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 800038C8 000008C8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 800038CC 000008CC 7C 60 00 A6 */ mfmsr r3 +/* 800038D0 000008D0 60 63 00 30 */ ori r3, r3, 0x30 +/* 800038D4 000008D4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 800038D8 000008D8 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 800038DC 000008DC 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 800038E0 000008E0 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 800038E4 000008E4 38 60 04 00 */ li r3, 0x400 +/* 800038E8 000008E8 4C 00 00 64 */ rfi +/* 800038EC 000008EC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800038F0 000008F0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800038F4 000008F4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800038F8 000008F8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800038FC 000008FC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003900 00000900 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003904 00000904 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003908 00000908 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000390C 0000090C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003910 00000910 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003914 00000914 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003918 00000918 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000391C 0000091C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003920 00000920 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003924 00000924 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003928 00000928 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000392C 0000092C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003930 00000930 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003934 00000934 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003938 00000938 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000393C 0000093C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003940 00000940 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003944 00000944 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003948 00000948 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000394C 0000094C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003950 00000950 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003954 00000954 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003958 00000958 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000395C 0000095C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003960 00000960 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003964 00000964 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003968 00000968 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000396C 0000096C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003970 00000970 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003974 00000974 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003978 00000978 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000397C 0000097C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003980 00000980 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003984 00000984 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003988 00000988 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000398C 0000098C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003990 00000990 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003994 00000994 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003998 00000998 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000399C 0000099C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800039A0 000009A0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800039A4 000009A4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800039A8 000009A8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800039AC 000009AC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800039B0 000009B0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800039B4 000009B4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800039B8 000009B8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800039BC 000009BC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 800039C0 000009C0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 800039C4 000009C4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 800039C8 000009C8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 800039CC 000009CC 7C 60 00 A6 */ mfmsr r3 +/* 800039D0 000009D0 60 63 00 30 */ ori r3, r3, 0x30 +/* 800039D4 000009D4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 800039D8 000009D8 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 800039DC 000009DC 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 800039E0 000009E0 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 800039E4 000009E4 38 60 05 00 */ li r3, 0x500 +/* 800039E8 000009E8 4C 00 00 64 */ rfi +/* 800039EC 000009EC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800039F0 000009F0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800039F4 000009F4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800039F8 000009F8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800039FC 000009FC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A00 00000A00 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A04 00000A04 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A08 00000A08 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A0C 00000A0C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A10 00000A10 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A14 00000A14 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A18 00000A18 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A1C 00000A1C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A20 00000A20 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A24 00000A24 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A28 00000A28 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A2C 00000A2C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A30 00000A30 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A34 00000A34 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A38 00000A38 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A3C 00000A3C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A40 00000A40 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A44 00000A44 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A48 00000A48 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A4C 00000A4C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A50 00000A50 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A54 00000A54 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A58 00000A58 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A5C 00000A5C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A60 00000A60 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A64 00000A64 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A68 00000A68 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A6C 00000A6C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A70 00000A70 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A74 00000A74 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A78 00000A78 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A7C 00000A7C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A80 00000A80 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A84 00000A84 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A88 00000A88 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A8C 00000A8C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A90 00000A90 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A94 00000A94 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A98 00000A98 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003A9C 00000A9C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003AA0 00000AA0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003AA4 00000AA4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003AA8 00000AA8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003AAC 00000AAC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003AB0 00000AB0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003AB4 00000AB4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003AB8 00000AB8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80003ABC 00000ABC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 80003AC0 00000AC0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80003AC4 00000AC4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80003AC8 00000AC8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80003ACC 00000ACC 7C 60 00 A6 */ mfmsr r3 +/* 80003AD0 00000AD0 60 63 00 30 */ ori r3, r3, 0x30 +/* 80003AD4 00000AD4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80003AD8 00000AD8 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 80003ADC 00000ADC 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 80003AE0 00000AE0 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80003AE4 00000AE4 38 60 06 00 */ li r3, 0x600 +/* 80003AE8 00000AE8 4C 00 00 64 */ rfi +/* 80003AEC 00000AEC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003AF0 00000AF0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003AF4 00000AF4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003AF8 00000AF8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003AFC 00000AFC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B00 00000B00 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B04 00000B04 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B08 00000B08 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B0C 00000B0C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B10 00000B10 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B14 00000B14 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B18 00000B18 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B1C 00000B1C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B20 00000B20 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B24 00000B24 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B28 00000B28 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B2C 00000B2C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B30 00000B30 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B34 00000B34 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B38 00000B38 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B3C 00000B3C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B40 00000B40 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B44 00000B44 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B48 00000B48 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B4C 00000B4C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B50 00000B50 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B54 00000B54 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B58 00000B58 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B5C 00000B5C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B60 00000B60 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B64 00000B64 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B68 00000B68 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B6C 00000B6C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B70 00000B70 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B74 00000B74 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B78 00000B78 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B7C 00000B7C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B80 00000B80 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B84 00000B84 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B88 00000B88 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B8C 00000B8C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B90 00000B90 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B94 00000B94 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B98 00000B98 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003B9C 00000B9C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003BA0 00000BA0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003BA4 00000BA4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003BA8 00000BA8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003BAC 00000BAC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003BB0 00000BB0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003BB4 00000BB4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003BB8 00000BB8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80003BBC 00000BBC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 80003BC0 00000BC0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80003BC4 00000BC4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80003BC8 00000BC8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80003BCC 00000BCC 7C 60 00 A6 */ mfmsr r3 +/* 80003BD0 00000BD0 60 63 00 30 */ ori r3, r3, 0x30 +/* 80003BD4 00000BD4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80003BD8 00000BD8 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 80003BDC 00000BDC 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 80003BE0 00000BE0 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80003BE4 00000BE4 38 60 07 00 */ li r3, 0x700 +/* 80003BE8 00000BE8 4C 00 00 64 */ rfi +/* 80003BEC 00000BEC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003BF0 00000BF0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003BF4 00000BF4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003BF8 00000BF8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003BFC 00000BFC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C00 00000C00 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C04 00000C04 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C08 00000C08 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C0C 00000C0C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C10 00000C10 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C14 00000C14 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C18 00000C18 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C1C 00000C1C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C20 00000C20 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C24 00000C24 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C28 00000C28 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C2C 00000C2C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C30 00000C30 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C34 00000C34 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C38 00000C38 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C3C 00000C3C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C40 00000C40 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C44 00000C44 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C48 00000C48 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C4C 00000C4C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C50 00000C50 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C54 00000C54 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C58 00000C58 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C5C 00000C5C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C60 00000C60 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C64 00000C64 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C68 00000C68 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C6C 00000C6C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C70 00000C70 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C74 00000C74 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C78 00000C78 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C7C 00000C7C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C80 00000C80 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C84 00000C84 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C88 00000C88 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C8C 00000C8C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C90 00000C90 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C94 00000C94 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C98 00000C98 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003C9C 00000C9C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003CA0 00000CA0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003CA4 00000CA4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003CA8 00000CA8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003CAC 00000CAC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003CB0 00000CB0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003CB4 00000CB4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003CB8 00000CB8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80003CBC 00000CBC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 80003CC0 00000CC0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80003CC4 00000CC4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80003CC8 00000CC8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80003CCC 00000CCC 7C 60 00 A6 */ mfmsr r3 +/* 80003CD0 00000CD0 60 63 00 30 */ ori r3, r3, 0x30 +/* 80003CD4 00000CD4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80003CD8 00000CD8 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 80003CDC 00000CDC 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 80003CE0 00000CE0 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80003CE4 00000CE4 38 60 08 00 */ li r3, 0x800 +/* 80003CE8 00000CE8 4C 00 00 64 */ rfi +/* 80003CEC 00000CEC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003CF0 00000CF0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003CF4 00000CF4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003CF8 00000CF8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003CFC 00000CFC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D00 00000D00 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D04 00000D04 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D08 00000D08 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D0C 00000D0C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D10 00000D10 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D14 00000D14 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D18 00000D18 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D1C 00000D1C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D20 00000D20 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D24 00000D24 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D28 00000D28 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D2C 00000D2C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D30 00000D30 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D34 00000D34 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D38 00000D38 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D3C 00000D3C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D40 00000D40 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D44 00000D44 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D48 00000D48 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D4C 00000D4C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D50 00000D50 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D54 00000D54 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D58 00000D58 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D5C 00000D5C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D60 00000D60 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D64 00000D64 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D68 00000D68 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D6C 00000D6C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D70 00000D70 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D74 00000D74 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D78 00000D78 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D7C 00000D7C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D80 00000D80 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D84 00000D84 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D88 00000D88 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D8C 00000D8C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D90 00000D90 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D94 00000D94 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D98 00000D98 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003D9C 00000D9C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003DA0 00000DA0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003DA4 00000DA4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003DA8 00000DA8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003DAC 00000DAC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003DB0 00000DB0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003DB4 00000DB4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003DB8 00000DB8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80003DBC 00000DBC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 80003DC0 00000DC0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80003DC4 00000DC4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80003DC8 00000DC8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80003DCC 00000DCC 7C 60 00 A6 */ mfmsr r3 +/* 80003DD0 00000DD0 60 63 00 30 */ ori r3, r3, 0x30 +/* 80003DD4 00000DD4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80003DD8 00000DD8 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 80003DDC 00000DDC 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 80003DE0 00000DE0 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80003DE4 00000DE4 38 60 09 00 */ li r3, 0x900 +/* 80003DE8 00000DE8 4C 00 00 64 */ rfi +/* 80003DEC 00000DEC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003DF0 00000DF0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003DF4 00000DF4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003DF8 00000DF8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003DFC 00000DFC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E00 00000E00 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E04 00000E04 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E08 00000E08 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E0C 00000E0C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E10 00000E10 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E14 00000E14 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E18 00000E18 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E1C 00000E1C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E20 00000E20 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E24 00000E24 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E28 00000E28 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E2C 00000E2C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E30 00000E30 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E34 00000E34 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E38 00000E38 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E3C 00000E3C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E40 00000E40 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E44 00000E44 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E48 00000E48 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E4C 00000E4C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E50 00000E50 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E54 00000E54 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E58 00000E58 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E5C 00000E5C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E60 00000E60 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E64 00000E64 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E68 00000E68 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E6C 00000E6C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E70 00000E70 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E74 00000E74 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E78 00000E78 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E7C 00000E7C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E80 00000E80 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E84 00000E84 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E88 00000E88 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E8C 00000E8C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E90 00000E90 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E94 00000E94 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E98 00000E98 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003E9C 00000E9C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EA0 00000EA0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EA4 00000EA4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EA8 00000EA8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EAC 00000EAC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EB0 00000EB0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EB4 00000EB4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EB8 00000EB8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EBC 00000EBC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EC0 00000EC0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EC4 00000EC4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EC8 00000EC8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003ECC 00000ECC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003ED0 00000ED0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003ED4 00000ED4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003ED8 00000ED8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EDC 00000EDC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EE0 00000EE0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EE4 00000EE4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EE8 00000EE8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EEC 00000EEC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EF0 00000EF0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EF4 00000EF4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EF8 00000EF8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003EFC 00000EFC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F00 00000F00 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F04 00000F04 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F08 00000F08 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F0C 00000F0C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F10 00000F10 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F14 00000F14 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F18 00000F18 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F1C 00000F1C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F20 00000F20 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F24 00000F24 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F28 00000F28 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F2C 00000F2C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F30 00000F30 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F34 00000F34 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F38 00000F38 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F3C 00000F3C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F40 00000F40 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F44 00000F44 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F48 00000F48 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F4C 00000F4C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F50 00000F50 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F54 00000F54 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F58 00000F58 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F5C 00000F5C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F60 00000F60 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F64 00000F64 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F68 00000F68 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F6C 00000F6C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F70 00000F70 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F74 00000F74 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F78 00000F78 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F7C 00000F7C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F80 00000F80 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F84 00000F84 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F88 00000F88 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F8C 00000F8C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F90 00000F90 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F94 00000F94 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F98 00000F98 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003F9C 00000F9C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FA0 00000FA0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FA4 00000FA4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FA8 00000FA8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FAC 00000FAC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FB0 00000FB0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FB4 00000FB4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FB8 00000FB8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FBC 00000FBC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FC0 00000FC0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FC4 00000FC4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FC8 00000FC8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FCC 00000FCC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FD0 00000FD0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FD4 00000FD4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FD8 00000FD8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FDC 00000FDC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FE0 00000FE0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FE4 00000FE4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FE8 00000FE8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FEC 00000FEC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FF0 00000FF0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FF4 00000FF4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FF8 00000FF8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80003FFC 00000FFC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004000 00001000 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004004 00001004 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004008 00001008 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000400C 0000100C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004010 00001010 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004014 00001014 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004018 00001018 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000401C 0000101C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004020 00001020 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004024 00001024 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004028 00001028 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000402C 0000102C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004030 00001030 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004034 00001034 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004038 00001038 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000403C 0000103C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004040 00001040 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004044 00001044 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004048 00001048 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000404C 0000104C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004050 00001050 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004054 00001054 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004058 00001058 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000405C 0000105C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004060 00001060 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004064 00001064 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004068 00001068 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000406C 0000106C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004070 00001070 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004074 00001074 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004078 00001078 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000407C 0000107C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004080 00001080 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004084 00001084 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004088 00001088 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000408C 0000108C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004090 00001090 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004094 00001094 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004098 00001098 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000409C 0000109C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800040A0 000010A0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800040A4 000010A4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800040A8 000010A8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800040AC 000010AC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800040B0 000010B0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800040B4 000010B4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800040B8 000010B8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800040BC 000010BC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 800040C0 000010C0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 800040C4 000010C4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 800040C8 000010C8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 800040CC 000010CC 7C 60 00 A6 */ mfmsr r3 +/* 800040D0 000010D0 60 63 00 30 */ ori r3, r3, 0x30 +/* 800040D4 000010D4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 800040D8 000010D8 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 800040DC 000010DC 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 800040E0 000010E0 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 800040E4 000010E4 38 60 0C 00 */ li r3, 0xc00 +/* 800040E8 000010E8 4C 00 00 64 */ rfi +/* 800040EC 000010EC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800040F0 000010F0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800040F4 000010F4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800040F8 000010F8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800040FC 000010FC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004100 00001100 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004104 00001104 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004108 00001108 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000410C 0000110C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004110 00001110 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004114 00001114 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004118 00001118 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000411C 0000111C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004120 00001120 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004124 00001124 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004128 00001128 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000412C 0000112C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004130 00001130 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004134 00001134 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004138 00001138 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000413C 0000113C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004140 00001140 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004144 00001144 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004148 00001148 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000414C 0000114C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004150 00001150 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004154 00001154 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004158 00001158 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000415C 0000115C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004160 00001160 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004164 00001164 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004168 00001168 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000416C 0000116C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004170 00001170 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004174 00001174 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004178 00001178 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000417C 0000117C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004180 00001180 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004184 00001184 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004188 00001188 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000418C 0000118C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004190 00001190 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004194 00001194 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004198 00001198 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000419C 0000119C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800041A0 000011A0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800041A4 000011A4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800041A8 000011A8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800041AC 000011AC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800041B0 000011B0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800041B4 000011B4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800041B8 000011B8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800041BC 000011BC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 800041C0 000011C0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 800041C4 000011C4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 800041C8 000011C8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 800041CC 000011CC 7C 60 00 A6 */ mfmsr r3 +/* 800041D0 000011D0 60 63 00 30 */ ori r3, r3, 0x30 +/* 800041D4 000011D4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 800041D8 000011D8 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 800041DC 000011DC 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 800041E0 000011E0 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 800041E4 000011E4 38 60 0D 00 */ li r3, 0xd00 +/* 800041E8 000011E8 4C 00 00 64 */ rfi +/* 800041EC 000011EC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800041F0 000011F0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800041F4 000011F4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800041F8 000011F8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800041FC 000011FC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004200 00001200 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004204 00001204 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004208 00001208 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000420C 0000120C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004210 00001210 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004214 00001214 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004218 00001218 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000421C 0000121C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004220 00001220 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004224 00001224 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004228 00001228 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000422C 0000122C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004230 00001230 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004234 00001234 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004238 00001238 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000423C 0000123C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004240 00001240 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004244 00001244 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004248 00001248 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000424C 0000124C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004250 00001250 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004254 00001254 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004258 00001258 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000425C 0000125C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004260 00001260 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004264 00001264 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004268 00001268 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000426C 0000126C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004270 00001270 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004274 00001274 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004278 00001278 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000427C 0000127C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004280 00001280 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004284 00001284 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004288 00001288 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000428C 0000128C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004290 00001290 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004294 00001294 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004298 00001298 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000429C 0000129C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800042A0 000012A0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800042A4 000012A4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800042A8 000012A8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800042AC 000012AC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800042B0 000012B0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800042B4 000012B4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800042B8 000012B8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800042BC 000012BC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 800042C0 000012C0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 800042C4 000012C4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 800042C8 000012C8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 800042CC 000012CC 7C 60 00 A6 */ mfmsr r3 +/* 800042D0 000012D0 60 63 00 30 */ ori r3, r3, 0x30 +/* 800042D4 000012D4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 800042D8 000012D8 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 800042DC 000012DC 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 800042E0 000012E0 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 800042E4 000012E4 38 60 0E 00 */ li r3, 0xe00 +/* 800042E8 000012E8 4C 00 00 64 */ rfi +/* 800042EC 000012EC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800042F0 000012F0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800042F4 000012F4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800042F8 000012F8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800042FC 000012FC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004300 00001300 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004304 00001304 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004308 00001308 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000430C 0000130C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004310 00001310 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004314 00001314 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004318 00001318 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000431C 0000131C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004320 00001320 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004324 00001324 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004328 00001328 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000432C 0000132C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004330 00001330 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004334 00001334 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004338 00001338 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000433C 0000133C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004340 00001340 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004344 00001344 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004348 00001348 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000434C 0000134C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004350 00001350 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004354 00001354 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004358 00001358 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000435C 0000135C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004360 00001360 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004364 00001364 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004368 00001368 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000436C 0000136C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004370 00001370 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004374 00001374 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004378 00001378 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000437C 0000137C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004380 00001380 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004384 00001384 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004388 00001388 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000438C 0000138C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004390 00001390 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004394 00001394 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004398 00001398 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000439C 0000139C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800043A0 000013A0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800043A4 000013A4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800043A8 000013A8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800043AC 000013AC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800043B0 000013B0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800043B4 000013B4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800043B8 000013B8 48 00 00 54 */ b .L_8000440C +/* 800043BC 000013BC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800043C0 000013C0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800043C4 000013C4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800043C8 000013C8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800043CC 000013CC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800043D0 000013D0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800043D4 000013D4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800043D8 000013D8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800043DC 000013DC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 800043E0 000013E0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 800043E4 000013E4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 800043E8 000013E8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 800043EC 000013EC 7C 60 00 A6 */ mfmsr r3 +/* 800043F0 000013F0 60 63 00 30 */ ori r3, r3, 0x30 +/* 800043F4 000013F4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 800043F8 000013F8 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 800043FC 000013FC 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 80004400 00001400 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80004404 00001404 38 60 0F 20 */ li r3, 0xf20 +/* 80004408 00001408 4C 00 00 64 */ rfi +.L_8000440C: +/* 8000440C 0000140C 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80004410 00001410 7C 72 43 A6 */ mtspr 0x112, r3 +/* 80004414 00001414 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80004418 00001418 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 8000441C 0000141C 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80004420 00001420 7C 60 00 A6 */ mfmsr r3 +/* 80004424 00001424 60 63 00 30 */ ori r3, r3, 0x30 +/* 80004428 00001428 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 8000442C 0000142C 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 80004430 00001430 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 80004434 00001434 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80004438 00001438 38 60 0F 00 */ li r3, 0xf00 +/* 8000443C 0000143C 4C 00 00 64 */ rfi +/* 80004440 00001440 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004444 00001444 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004448 00001448 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000444C 0000144C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004450 00001450 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004454 00001454 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004458 00001458 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000445C 0000145C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004460 00001460 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004464 00001464 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004468 00001468 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000446C 0000146C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004470 00001470 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004474 00001474 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004478 00001478 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000447C 0000147C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004480 00001480 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004484 00001484 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004488 00001488 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000448C 0000148C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004490 00001490 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004494 00001494 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004498 00001498 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000449C 0000149C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800044A0 000014A0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800044A4 000014A4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800044A8 000014A8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800044AC 000014AC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800044B0 000014B0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800044B4 000014B4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800044B8 000014B8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800044BC 000014BC 7C 40 00 26 */ mfcr r2 +/* 800044C0 000014C0 7C 52 43 A6 */ mtspr 0x112, r2 +/* 800044C4 000014C4 7C 40 00 A6 */ mfmsr r2 +/* 800044C8 000014C8 74 42 00 02 */ andis. r2, r2, 2 +/* 800044CC 000014CC 41 82 00 1C */ beq .L_800044E8 +/* 800044D0 000014D0 7C 40 00 A6 */ mfmsr r2 +/* 800044D4 000014D4 6C 42 00 02 */ xoris r2, r2, 2 +/* 800044D8 000014D8 7C 00 04 AC */ sync 0 +/* 800044DC 000014DC 7C 40 01 24 */ mtmsr r2 +/* 800044E0 000014E0 7C 00 04 AC */ sync 0 +/* 800044E4 000014E4 7C 51 43 A6 */ mtspr 0x111, r2 +.L_800044E8: +/* 800044E8 000014E8 7C 52 42 A6 */ mfspr r2, 0x112 +/* 800044EC 000014EC 7C 4F F1 20 */ mtcrf 0xff, r2 +/* 800044F0 000014F0 7C 51 42 A6 */ mfspr r2, 0x111 +/* 800044F4 000014F4 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800044F8 000014F8 7C 72 43 A6 */ mtspr 0x112, r3 +/* 800044FC 000014FC 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80004500 00001500 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80004504 00001504 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80004508 00001508 7C 60 00 A6 */ mfmsr r3 +/* 8000450C 0000150C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80004510 00001510 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80004514 00001514 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 80004518 00001518 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 8000451C 0000151C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80004520 00001520 38 60 10 00 */ li r3, 0x1000 +/* 80004524 00001524 4C 00 00 64 */ rfi +/* 80004528 00001528 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000452C 0000152C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004530 00001530 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004534 00001534 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004538 00001538 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000453C 0000153C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004540 00001540 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004544 00001544 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004548 00001548 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000454C 0000154C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004550 00001550 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004554 00001554 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004558 00001558 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000455C 0000155C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004560 00001560 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004564 00001564 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004568 00001568 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000456C 0000156C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004570 00001570 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004574 00001574 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004578 00001578 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000457C 0000157C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004580 00001580 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004584 00001584 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004588 00001588 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000458C 0000158C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004590 00001590 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004594 00001594 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004598 00001598 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000459C 0000159C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800045A0 000015A0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800045A4 000015A4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800045A8 000015A8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800045AC 000015AC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800045B0 000015B0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800045B4 000015B4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800045B8 000015B8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800045BC 000015BC 7C 40 00 26 */ mfcr r2 +/* 800045C0 000015C0 7C 52 43 A6 */ mtspr 0x112, r2 +/* 800045C4 000015C4 7C 40 00 A6 */ mfmsr r2 +/* 800045C8 000015C8 74 42 00 02 */ andis. r2, r2, 2 +/* 800045CC 000015CC 41 82 00 1C */ beq .L_800045E8 +/* 800045D0 000015D0 7C 40 00 A6 */ mfmsr r2 +/* 800045D4 000015D4 6C 42 00 02 */ xoris r2, r2, 2 +/* 800045D8 000015D8 7C 00 04 AC */ sync 0 +/* 800045DC 000015DC 7C 40 01 24 */ mtmsr r2 +/* 800045E0 000015E0 7C 00 04 AC */ sync 0 +/* 800045E4 000015E4 7C 51 43 A6 */ mtspr 0x111, r2 +.L_800045E8: +/* 800045E8 000015E8 7C 52 42 A6 */ mfspr r2, 0x112 +/* 800045EC 000015EC 7C 4F F1 20 */ mtcrf 0xff, r2 +/* 800045F0 000015F0 7C 51 42 A6 */ mfspr r2, 0x111 +/* 800045F4 000015F4 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800045F8 000015F8 7C 72 43 A6 */ mtspr 0x112, r3 +/* 800045FC 000015FC 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80004600 00001600 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80004604 00001604 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80004608 00001608 7C 60 00 A6 */ mfmsr r3 +/* 8000460C 0000160C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80004610 00001610 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80004614 00001614 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 80004618 00001618 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 8000461C 0000161C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80004620 00001620 38 60 11 00 */ li r3, 0x1100 +/* 80004624 00001624 4C 00 00 64 */ rfi +/* 80004628 00001628 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000462C 0000162C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004630 00001630 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004634 00001634 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004638 00001638 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000463C 0000163C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004640 00001640 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004644 00001644 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004648 00001648 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000464C 0000164C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004650 00001650 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004654 00001654 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004658 00001658 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000465C 0000165C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004660 00001660 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004664 00001664 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004668 00001668 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000466C 0000166C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004670 00001670 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004674 00001674 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004678 00001678 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000467C 0000167C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004680 00001680 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004684 00001684 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004688 00001688 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000468C 0000168C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004690 00001690 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004694 00001694 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004698 00001698 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000469C 0000169C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800046A0 000016A0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800046A4 000016A4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800046A8 000016A8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800046AC 000016AC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800046B0 000016B0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800046B4 000016B4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800046B8 000016B8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800046BC 000016BC 7C 40 00 26 */ mfcr r2 +/* 800046C0 000016C0 7C 52 43 A6 */ mtspr 0x112, r2 +/* 800046C4 000016C4 7C 40 00 A6 */ mfmsr r2 +/* 800046C8 000016C8 74 42 00 02 */ andis. r2, r2, 2 +/* 800046CC 000016CC 41 82 00 1C */ beq .L_800046E8 +/* 800046D0 000016D0 7C 40 00 A6 */ mfmsr r2 +/* 800046D4 000016D4 6C 42 00 02 */ xoris r2, r2, 2 +/* 800046D8 000016D8 7C 00 04 AC */ sync 0 +/* 800046DC 000016DC 7C 40 01 24 */ mtmsr r2 +/* 800046E0 000016E0 7C 00 04 AC */ sync 0 +/* 800046E4 000016E4 7C 51 43 A6 */ mtspr 0x111, r2 +.L_800046E8: +/* 800046E8 000016E8 7C 52 42 A6 */ mfspr r2, 0x112 +/* 800046EC 000016EC 7C 4F F1 20 */ mtcrf 0xff, r2 +/* 800046F0 000016F0 7C 51 42 A6 */ mfspr r2, 0x111 +/* 800046F4 000016F4 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800046F8 000016F8 7C 72 43 A6 */ mtspr 0x112, r3 +/* 800046FC 000016FC 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80004700 00001700 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80004704 00001704 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80004708 00001708 7C 60 00 A6 */ mfmsr r3 +/* 8000470C 0000170C 60 63 00 30 */ ori r3, r3, 0x30 +/* 80004710 00001710 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80004714 00001714 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 80004718 00001718 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 8000471C 0000171C 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80004720 00001720 38 60 12 00 */ li r3, 0x1200 +/* 80004724 00001724 4C 00 00 64 */ rfi +/* 80004728 00001728 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000472C 0000172C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004730 00001730 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004734 00001734 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004738 00001738 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000473C 0000173C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004740 00001740 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004744 00001744 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004748 00001748 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000474C 0000174C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004750 00001750 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004754 00001754 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004758 00001758 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000475C 0000175C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004760 00001760 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004764 00001764 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004768 00001768 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000476C 0000176C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004770 00001770 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004774 00001774 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004778 00001778 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000477C 0000177C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004780 00001780 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004784 00001784 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004788 00001788 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000478C 0000178C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004790 00001790 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004794 00001794 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004798 00001798 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000479C 0000179C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800047A0 000017A0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800047A4 000017A4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800047A8 000017A8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800047AC 000017AC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800047B0 000017B0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800047B4 000017B4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800047B8 000017B8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800047BC 000017BC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 800047C0 000017C0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 800047C4 000017C4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 800047C8 000017C8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 800047CC 000017CC 7C 60 00 A6 */ mfmsr r3 +/* 800047D0 000017D0 60 63 00 30 */ ori r3, r3, 0x30 +/* 800047D4 000017D4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 800047D8 000017D8 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 800047DC 000017DC 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 800047E0 000017E0 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 800047E4 000017E4 38 60 13 00 */ li r3, 0x1300 +/* 800047E8 000017E8 4C 00 00 64 */ rfi +/* 800047EC 000017EC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800047F0 000017F0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800047F4 000017F4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800047F8 000017F8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800047FC 000017FC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004800 00001800 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004804 00001804 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004808 00001808 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000480C 0000180C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004810 00001810 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004814 00001814 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004818 00001818 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000481C 0000181C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004820 00001820 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004824 00001824 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004828 00001828 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000482C 0000182C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004830 00001830 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004834 00001834 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004838 00001838 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000483C 0000183C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004840 00001840 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004844 00001844 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004848 00001848 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000484C 0000184C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004850 00001850 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004854 00001854 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004858 00001858 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000485C 0000185C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004860 00001860 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004864 00001864 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004868 00001868 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000486C 0000186C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004870 00001870 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004874 00001874 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004878 00001878 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000487C 0000187C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004880 00001880 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004884 00001884 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004888 00001888 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000488C 0000188C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004890 00001890 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004894 00001894 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004898 00001898 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000489C 0000189C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800048A0 000018A0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800048A4 000018A4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800048A8 000018A8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800048AC 000018AC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800048B0 000018B0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800048B4 000018B4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800048B8 000018B8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800048BC 000018BC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 800048C0 000018C0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 800048C4 000018C4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 800048C8 000018C8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 800048CC 000018CC 7C 60 00 A6 */ mfmsr r3 +/* 800048D0 000018D0 60 63 00 30 */ ori r3, r3, 0x30 +/* 800048D4 000018D4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 800048D8 000018D8 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 800048DC 000018DC 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 800048E0 000018E0 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 800048E4 000018E4 38 60 14 00 */ li r3, 0x1400 +/* 800048E8 000018E8 4C 00 00 64 */ rfi +/* 800048EC 000018EC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800048F0 000018F0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800048F4 000018F4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800048F8 000018F8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800048FC 000018FC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004900 00001900 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004904 00001904 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004908 00001908 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000490C 0000190C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004910 00001910 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004914 00001914 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004918 00001918 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000491C 0000191C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004920 00001920 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004924 00001924 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004928 00001928 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000492C 0000192C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004930 00001930 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004934 00001934 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004938 00001938 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000493C 0000193C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004940 00001940 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004944 00001944 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004948 00001948 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000494C 0000194C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004950 00001950 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004954 00001954 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004958 00001958 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000495C 0000195C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004960 00001960 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004964 00001964 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004968 00001968 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000496C 0000196C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004970 00001970 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004974 00001974 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004978 00001978 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000497C 0000197C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004980 00001980 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004984 00001984 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004988 00001988 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000498C 0000198C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004990 00001990 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004994 00001994 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004998 00001998 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000499C 0000199C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049A0 000019A0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049A4 000019A4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049A8 000019A8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049AC 000019AC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049B0 000019B0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049B4 000019B4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049B8 000019B8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049BC 000019BC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049C0 000019C0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049C4 000019C4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049C8 000019C8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049CC 000019CC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049D0 000019D0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049D4 000019D4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049D8 000019D8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049DC 000019DC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049E0 000019E0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049E4 000019E4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049E8 000019E8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049EC 000019EC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049F0 000019F0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049F4 000019F4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049F8 000019F8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800049FC 000019FC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A00 00001A00 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A04 00001A04 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A08 00001A08 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A0C 00001A0C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A10 00001A10 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A14 00001A14 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A18 00001A18 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A1C 00001A1C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A20 00001A20 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A24 00001A24 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A28 00001A28 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A2C 00001A2C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A30 00001A30 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A34 00001A34 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A38 00001A38 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A3C 00001A3C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A40 00001A40 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A44 00001A44 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A48 00001A48 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A4C 00001A4C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A50 00001A50 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A54 00001A54 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A58 00001A58 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A5C 00001A5C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A60 00001A60 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A64 00001A64 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A68 00001A68 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A6C 00001A6C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A70 00001A70 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A74 00001A74 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A78 00001A78 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A7C 00001A7C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A80 00001A80 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A84 00001A84 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A88 00001A88 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A8C 00001A8C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A90 00001A90 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A94 00001A94 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A98 00001A98 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004A9C 00001A9C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004AA0 00001AA0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004AA4 00001AA4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004AA8 00001AA8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004AAC 00001AAC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004AB0 00001AB0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004AB4 00001AB4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004AB8 00001AB8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80004ABC 00001ABC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 80004AC0 00001AC0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80004AC4 00001AC4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80004AC8 00001AC8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80004ACC 00001ACC 7C 60 00 A6 */ mfmsr r3 +/* 80004AD0 00001AD0 60 63 00 30 */ ori r3, r3, 0x30 +/* 80004AD4 00001AD4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80004AD8 00001AD8 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 80004ADC 00001ADC 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 80004AE0 00001AE0 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80004AE4 00001AE4 38 60 16 00 */ li r3, 0x1600 +/* 80004AE8 00001AE8 4C 00 00 64 */ rfi +/* 80004AEC 00001AEC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004AF0 00001AF0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004AF4 00001AF4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004AF8 00001AF8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004AFC 00001AFC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B00 00001B00 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B04 00001B04 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B08 00001B08 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B0C 00001B0C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B10 00001B10 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B14 00001B14 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B18 00001B18 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B1C 00001B1C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B20 00001B20 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B24 00001B24 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B28 00001B28 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B2C 00001B2C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B30 00001B30 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B34 00001B34 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B38 00001B38 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B3C 00001B3C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B40 00001B40 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B44 00001B44 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B48 00001B48 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B4C 00001B4C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B50 00001B50 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B54 00001B54 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B58 00001B58 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B5C 00001B5C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B60 00001B60 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B64 00001B64 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B68 00001B68 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B6C 00001B6C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B70 00001B70 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B74 00001B74 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B78 00001B78 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B7C 00001B7C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B80 00001B80 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B84 00001B84 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B88 00001B88 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B8C 00001B8C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B90 00001B90 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B94 00001B94 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B98 00001B98 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004B9C 00001B9C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004BA0 00001BA0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004BA4 00001BA4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004BA8 00001BA8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004BAC 00001BAC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004BB0 00001BB0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004BB4 00001BB4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004BB8 00001BB8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 80004BBC 00001BBC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 80004BC0 00001BC0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 80004BC4 00001BC4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 80004BC8 00001BC8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 80004BCC 00001BCC 7C 60 00 A6 */ mfmsr r3 +/* 80004BD0 00001BD0 60 63 00 30 */ ori r3, r3, 0x30 +/* 80004BD4 00001BD4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 80004BD8 00001BD8 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 80004BDC 00001BDC 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 80004BE0 00001BE0 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 80004BE4 00001BE4 38 60 17 00 */ li r3, 0x1700 +/* 80004BE8 00001BE8 4C 00 00 64 */ rfi +/* 80004BEC 00001BEC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004BF0 00001BF0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004BF4 00001BF4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004BF8 00001BF8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004BFC 00001BFC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C00 00001C00 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C04 00001C04 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C08 00001C08 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C0C 00001C0C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C10 00001C10 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C14 00001C14 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C18 00001C18 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C1C 00001C1C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C20 00001C20 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C24 00001C24 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C28 00001C28 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C2C 00001C2C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C30 00001C30 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C34 00001C34 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C38 00001C38 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C3C 00001C3C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C40 00001C40 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C44 00001C44 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C48 00001C48 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C4C 00001C4C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C50 00001C50 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C54 00001C54 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C58 00001C58 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C5C 00001C5C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C60 00001C60 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C64 00001C64 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C68 00001C68 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C6C 00001C6C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C70 00001C70 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C74 00001C74 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C78 00001C78 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C7C 00001C7C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C80 00001C80 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C84 00001C84 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C88 00001C88 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C8C 00001C8C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C90 00001C90 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C94 00001C94 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C98 00001C98 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004C9C 00001C9C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CA0 00001CA0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CA4 00001CA4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CA8 00001CA8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CAC 00001CAC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CB0 00001CB0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CB4 00001CB4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CB8 00001CB8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CBC 00001CBC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CC0 00001CC0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CC4 00001CC4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CC8 00001CC8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CCC 00001CCC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CD0 00001CD0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CD4 00001CD4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CD8 00001CD8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CDC 00001CDC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CE0 00001CE0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CE4 00001CE4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CE8 00001CE8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CEC 00001CEC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CF0 00001CF0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CF4 00001CF4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CF8 00001CF8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004CFC 00001CFC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D00 00001D00 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D04 00001D04 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D08 00001D08 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D0C 00001D0C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D10 00001D10 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D14 00001D14 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D18 00001D18 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D1C 00001D1C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D20 00001D20 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D24 00001D24 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D28 00001D28 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D2C 00001D2C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D30 00001D30 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D34 00001D34 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D38 00001D38 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D3C 00001D3C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D40 00001D40 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D44 00001D44 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D48 00001D48 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D4C 00001D4C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D50 00001D50 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D54 00001D54 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D58 00001D58 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D5C 00001D5C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D60 00001D60 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D64 00001D64 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D68 00001D68 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D6C 00001D6C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D70 00001D70 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D74 00001D74 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D78 00001D78 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D7C 00001D7C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D80 00001D80 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D84 00001D84 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D88 00001D88 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D8C 00001D8C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D90 00001D90 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D94 00001D94 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D98 00001D98 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004D9C 00001D9C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DA0 00001DA0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DA4 00001DA4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DA8 00001DA8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DAC 00001DAC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DB0 00001DB0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DB4 00001DB4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DB8 00001DB8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DBC 00001DBC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DC0 00001DC0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DC4 00001DC4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DC8 00001DC8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DCC 00001DCC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DD0 00001DD0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DD4 00001DD4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DD8 00001DD8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DDC 00001DDC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DE0 00001DE0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DE4 00001DE4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DE8 00001DE8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DEC 00001DEC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DF0 00001DF0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DF4 00001DF4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DF8 00001DF8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004DFC 00001DFC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E00 00001E00 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E04 00001E04 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E08 00001E08 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E0C 00001E0C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E10 00001E10 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E14 00001E14 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E18 00001E18 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E1C 00001E1C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E20 00001E20 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E24 00001E24 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E28 00001E28 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E2C 00001E2C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E30 00001E30 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E34 00001E34 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E38 00001E38 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E3C 00001E3C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E40 00001E40 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E44 00001E44 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E48 00001E48 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E4C 00001E4C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E50 00001E50 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E54 00001E54 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E58 00001E58 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E5C 00001E5C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E60 00001E60 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E64 00001E64 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E68 00001E68 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E6C 00001E6C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E70 00001E70 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E74 00001E74 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E78 00001E78 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E7C 00001E7C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E80 00001E80 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E84 00001E84 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E88 00001E88 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E8C 00001E8C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E90 00001E90 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E94 00001E94 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E98 00001E98 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004E9C 00001E9C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EA0 00001EA0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EA4 00001EA4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EA8 00001EA8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EAC 00001EAC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EB0 00001EB0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EB4 00001EB4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EB8 00001EB8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EBC 00001EBC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EC0 00001EC0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EC4 00001EC4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EC8 00001EC8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004ECC 00001ECC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004ED0 00001ED0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004ED4 00001ED4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004ED8 00001ED8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EDC 00001EDC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EE0 00001EE0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EE4 00001EE4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EE8 00001EE8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EEC 00001EEC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EF0 00001EF0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EF4 00001EF4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EF8 00001EF8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004EFC 00001EFC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F00 00001F00 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F04 00001F04 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F08 00001F08 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F0C 00001F0C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F10 00001F10 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F14 00001F14 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F18 00001F18 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F1C 00001F1C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F20 00001F20 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F24 00001F24 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F28 00001F28 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F2C 00001F2C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F30 00001F30 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F34 00001F34 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F38 00001F38 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F3C 00001F3C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F40 00001F40 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F44 00001F44 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F48 00001F48 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F4C 00001F4C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F50 00001F50 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F54 00001F54 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F58 00001F58 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F5C 00001F5C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F60 00001F60 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F64 00001F64 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F68 00001F68 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F6C 00001F6C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F70 00001F70 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F74 00001F74 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F78 00001F78 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F7C 00001F7C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F80 00001F80 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F84 00001F84 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F88 00001F88 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F8C 00001F8C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F90 00001F90 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F94 00001F94 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F98 00001F98 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004F9C 00001F9C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FA0 00001FA0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FA4 00001FA4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FA8 00001FA8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FAC 00001FAC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FB0 00001FB0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FB4 00001FB4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FB8 00001FB8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FBC 00001FBC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FC0 00001FC0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FC4 00001FC4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FC8 00001FC8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FCC 00001FCC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FD0 00001FD0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FD4 00001FD4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FD8 00001FD8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FDC 00001FDC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FE0 00001FE0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FE4 00001FE4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FE8 00001FE8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FEC 00001FEC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FF0 00001FF0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FF4 00001FF4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FF8 00001FF8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80004FFC 00001FFC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005000 00002000 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005004 00002004 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005008 00002008 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000500C 0000200C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005010 00002010 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005014 00002014 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005018 00002018 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000501C 0000201C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005020 00002020 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005024 00002024 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005028 00002028 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000502C 0000202C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005030 00002030 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005034 00002034 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005038 00002038 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000503C 0000203C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005040 00002040 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005044 00002044 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005048 00002048 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000504C 0000204C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005050 00002050 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005054 00002054 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005058 00002058 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000505C 0000205C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005060 00002060 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005064 00002064 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005068 00002068 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000506C 0000206C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005070 00002070 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005074 00002074 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005078 00002078 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000507C 0000207C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005080 00002080 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005084 00002084 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005088 00002088 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000508C 0000208C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005090 00002090 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005094 00002094 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005098 00002098 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000509C 0000209C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800050A0 000020A0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800050A4 000020A4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800050A8 000020A8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800050AC 000020AC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800050B0 000020B0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800050B4 000020B4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800050B8 000020B8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800050BC 000020BC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 800050C0 000020C0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 800050C4 000020C4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 800050C8 000020C8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 800050CC 000020CC 7C 60 00 A6 */ mfmsr r3 +/* 800050D0 000020D0 60 63 00 30 */ ori r3, r3, 0x30 +/* 800050D4 000020D4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 800050D8 000020D8 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 800050DC 000020DC 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 800050E0 000020E0 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 800050E4 000020E4 38 60 1C 00 */ li r3, 0x1c00 +/* 800050E8 000020E8 4C 00 00 64 */ rfi +/* 800050EC 000020EC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800050F0 000020F0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800050F4 000020F4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800050F8 000020F8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800050FC 000020FC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005100 00002100 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005104 00002104 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005108 00002108 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000510C 0000210C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005110 00002110 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005114 00002114 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005118 00002118 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000511C 0000211C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005120 00002120 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005124 00002124 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005128 00002128 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000512C 0000212C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005130 00002130 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005134 00002134 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005138 00002138 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000513C 0000213C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005140 00002140 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005144 00002144 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005148 00002148 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000514C 0000214C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005150 00002150 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005154 00002154 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005158 00002158 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000515C 0000215C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005160 00002160 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005164 00002164 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005168 00002168 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000516C 0000216C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005170 00002170 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005174 00002174 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005178 00002178 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000517C 0000217C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005180 00002180 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005184 00002184 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005188 00002188 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000518C 0000218C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005190 00002190 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005194 00002194 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005198 00002198 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000519C 0000219C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800051A0 000021A0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800051A4 000021A4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800051A8 000021A8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800051AC 000021AC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800051B0 000021B0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800051B4 000021B4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800051B8 000021B8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800051BC 000021BC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 800051C0 000021C0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 800051C4 000021C4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 800051C8 000021C8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 800051CC 000021CC 7C 60 00 A6 */ mfmsr r3 +/* 800051D0 000021D0 60 63 00 30 */ ori r3, r3, 0x30 +/* 800051D4 000021D4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 800051D8 000021D8 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 800051DC 000021DC 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 800051E0 000021E0 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 800051E4 000021E4 38 60 1D 00 */ li r3, 0x1d00 +/* 800051E8 000021E8 4C 00 00 64 */ rfi +/* 800051EC 000021EC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800051F0 000021F0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800051F4 000021F4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800051F8 000021F8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800051FC 000021FC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005200 00002200 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005204 00002204 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005208 00002208 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000520C 0000220C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005210 00002210 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005214 00002214 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005218 00002218 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000521C 0000221C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005220 00002220 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005224 00002224 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005228 00002228 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000522C 0000222C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005230 00002230 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005234 00002234 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005238 00002238 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000523C 0000223C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005240 00002240 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005244 00002244 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005248 00002248 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000524C 0000224C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005250 00002250 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005254 00002254 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005258 00002258 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000525C 0000225C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005260 00002260 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005264 00002264 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005268 00002268 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000526C 0000226C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005270 00002270 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005274 00002274 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005278 00002278 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000527C 0000227C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005280 00002280 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005284 00002284 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005288 00002288 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000528C 0000228C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005290 00002290 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005294 00002294 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005298 00002298 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000529C 0000229C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800052A0 000022A0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800052A4 000022A4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800052A8 000022A8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800052AC 000022AC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800052B0 000022B0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800052B4 000022B4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800052B8 000022B8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800052BC 000022BC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 800052C0 000022C0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 800052C4 000022C4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 800052C8 000022C8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 800052CC 000022CC 7C 60 00 A6 */ mfmsr r3 +/* 800052D0 000022D0 60 63 00 30 */ ori r3, r3, 0x30 +/* 800052D4 000022D4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 800052D8 000022D8 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 800052DC 000022DC 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 800052E0 000022E0 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 800052E4 000022E4 38 60 1E 00 */ li r3, 0x1e00 +/* 800052E8 000022E8 4C 00 00 64 */ rfi +/* 800052EC 000022EC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800052F0 000022F0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800052F4 000022F4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800052F8 000022F8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800052FC 000022FC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005300 00002300 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005304 00002304 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005308 00002308 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000530C 0000230C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005310 00002310 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005314 00002314 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005318 00002318 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000531C 0000231C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005320 00002320 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005324 00002324 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005328 00002328 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000532C 0000232C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005330 00002330 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005334 00002334 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005338 00002338 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000533C 0000233C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005340 00002340 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005344 00002344 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005348 00002348 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000534C 0000234C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005350 00002350 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005354 00002354 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005358 00002358 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000535C 0000235C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005360 00002360 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005364 00002364 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005368 00002368 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000536C 0000236C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005370 00002370 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005374 00002374 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005378 00002378 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000537C 0000237C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005380 00002380 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005384 00002384 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005388 00002388 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000538C 0000238C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005390 00002390 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005394 00002394 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 80005398 00002398 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 8000539C 0000239C 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800053A0 000023A0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800053A4 000023A4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800053A8 000023A8 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800053AC 000023AC 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800053B0 000023B0 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800053B4 000023B4 00 00 00 00 */ .4byte 0x00000000 /* unknown instruction */ +/* 800053B8 000023B8 7C 51 43 A6 */ mtspr 0x111, r2 +/* 800053BC 000023BC 7C 72 43 A6 */ mtspr 0x112, r3 +/* 800053C0 000023C0 7C 93 43 A6 */ mtspr 0x113, r4 +/* 800053C4 000023C4 7C 5A 02 A6 */ mfspr r2, 0x1a +/* 800053C8 000023C8 7C 9B 02 A6 */ mfspr r4, 0x1b +/* 800053CC 000023CC 7C 60 00 A6 */ mfmsr r3 +/* 800053D0 000023D0 60 63 00 30 */ ori r3, r3, 0x30 +/* 800053D4 000023D4 7C 7B 03 A6 */ mtspr 0x1b, r3 +/* 800053D8 000023D8 3C 60 80 21 */ lis r3, TRKInterruptHandler@h +/* 800053DC 000023DC 60 63 F2 24 */ ori r3, r3, TRKInterruptHandler@l +/* 800053E0 000023E0 7C 7A 03 A6 */ mtspr 0x1a, r3 +/* 800053E4 000023E4 38 60 1F 00 */ li r3, 0x1f00 +/* 800053E8 000023E8 4C 00 00 64 */ rfi +.global gTRKInterruptVectorTableEnd +gTRKInterruptVectorTableEnd: diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c index e69de29bb..56ba33a11 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c @@ -0,0 +1,31 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +/* + * --INFO-- + * Address: 8021E788 + * Size: 000038 + */ +ASM void TRK_flush_cache(register void* param_1, register int param_2) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + + lis r5, 0xFFFF + ori r5, r5, 0xFFF1 + and r5, r5, param_1 + subf r3, r5, param_1 + add r4, param_2, r3 + + loop: + dcbst 0, r5 + dcbf 0, r5 + sync + icbi 0, r5 + addic r5, r5, 8 + addic. r4, r4, -8 + bge loop + + isync + blr + #endif // clang-format on +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c index e69de29bb..5858f4a17 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c @@ -0,0 +1,263 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +/* + * --INFO-- + * Address: 802200A0 + * Size: 0001B8 + */ +ASM void TRKSaveExtended1Block() +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + lis r2, gTRKCPUState@h /* 0x8044F338@h */ + ori r2, r2, gTRKCPUState@l /* 0x8044F338@l */ + mfsr r16, 0 + mfsr r17, 1 + mfsr r18, 2 + mfsr r19, 3 + mfsr r20, 4 + mfsr r21, 5 + mfsr r22, 6 + mfsr r23, 7 + mfsr r24, 8 + mfsr r25, 9 + mfsr r26, 0xa + mfsr r27, 0xb + mfsr r28, 0xc + mfsr r29, 0xd + mfsr r30, 0xe + mfsr r31, 0xf + stmw r16, 0x1a8(r2) + mftb r10, 0x10c + mftbu r11 + mfspr r12, 0x3f0 + mfspr r13, 0x3f1 + mfspr r14, 0x1b + mfpvr r15 + mfibatu r16, 0 + mfibatl r17, 0 + mfibatu r18, 1 + mfibatl r19, 1 + mfibatu r20, 2 + mfibatl r21, 2 + mfibatu r22, 3 + mfibatl r23, 3 + mfdbatu r24, 0 + mfdbatl r25, 0 + mfdbatu r26, 1 + mfdbatl r27, 1 + mfdbatu r28, 2 + mfdbatl r29, 2 + mfdbatu r30, 3 + mfdbatl r31, 3 + stmw r10, 0x1e8(r2) + mfspr r22, 0x19 + mfdar r23 + mfdsisr r24 + mfspr r25, 0x110 + mfspr r26, 0x111 + mfspr r27, 0x112 + mfspr r28, 0x113 + li r29, 0 + mfspr r30, 0x3f2 + mfspr r31, 0x11a + stmw r22, 0x25c(r2) + mfspr r20, 0x390 + mfspr r21, 0x391 + mfspr r22, 0x392 + mfspr r23, 0x393 + mfspr r24, 0x394 + mfspr r25, 0x395 + mfspr r26, 0x396 + mfspr r27, 0x397 + mfspr r28, 0x398 + mfspr r29, 0x399 + mfspr r30, 0x39a + mfspr r31, 0x39b + stmw r20, 0x2fc(r2) + b lbl_80371340 + mfspr r16, 0x3a0 + mfspr r17, 0x3a7 + mfspr r18, 0x3a8 + mfspr r19, 0x3a9 + mfspr r20, 0x3aa + mfspr r21, 0x3ab + mfspr r22, 0x3ac + mfspr r23, 0x3ad + mfspr r24, 0x3ae + mfspr r25, 0x3af + mfspr r26, 0x3b0 + mfspr r27, 0x3b7 + mfspr r28, 0x3bf + mfspr r29, 0x3f6 + mfspr r30, 0x3f7 + mfspr r31, 0x3ff + stmw r16, 0x2b8(r2) + +lbl_80371340: + mfspr r19, 0x3f5 + mfspr r20, 0x3b9 + mfspr r21, 0x3ba + mfspr r22, 0x3bd + mfspr r23, 0x3be + mfspr r24, 0x3bb + mfspr r25, 0x3b8 + mfspr r26, 0x3bc + mfspr r27, 0x3fc + mfspr r28, 0x3fd + mfspr r29, 0x3fe + mfspr r30, 0x3FB + mfspr r31, 0x3f9 + stmw r19, 0x284(r2) + b end + + mfspr r25, 0x3d0 + mfspr r26, 0x3d1 + mfspr r27, 0x3d2 + mfspr r28, 0x3d3 + mfspr r29, 0x3D4 + mfspr r30, 0x3D5 + mfspr r31, 0x3d6 + stmw r25, 0x240(r2) + mfspr r31, 0x16 + stw r31, 0x278(r2) +end: + blr +#endif // clang-format on +} + +/* + * --INFO-- + * Address: 80220258 + * Size: 0001B8 + */ +ASM void TRKRestoreExtended1Block() +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + lis r2, gTRKCPUState@h /* 0x8044F338@h */ + ori r2, r2, gTRKCPUState@l /* 0x8044F338@l */ + lis r5, gTRKRestoreFlags@h /* 0x803D3238@h */ + ori r5, r5, gTRKRestoreFlags@l /* 0x803D3238@l */ + lbz r3, 0(r5) + lbz r6, 1(r5) + li r0, 0 + stb r0, 0(r5) + stb r0, 1(r5) + cmpwi r3, 0 + beq lbl_803713E4 + lwz r24, 0x1e8(r2) + lwz r25, 0x1ec(r2) + mttbl r24 + mttbu r25 +lbl_803713E4: + lmw r20, 0x2fc(r2) + mtspr 0x390, r20 + mtspr 0x391, r21 + mtspr 0x392, r22 + mtspr 0x393, r23 + mtspr 0x394, r24 + mtspr 0x395, r25 + mtspr 0x396, r26 + mtspr 0x397, r27 + mtspr 0x398, r28 + mtspr 0x39a, r30 + mtspr 0x39b, r31 + b lbl_80371430 + lmw r26, 0x2e0(r2) + mtspr 0x3b0, r26 + mtspr 0x3b7, r27 + mtspr 0x3f6, r29 + mtspr 0x3f7, r30 + mtspr 0x3ff, r31 +lbl_80371430: + lmw r19, 0x284(r2) + mtspr 0x3f5, r19 + mtspr 0x3b9, r20 + mtspr 0x3ba, r21 + mtspr 0x3bd, r22 + mtspr 0x3be, r23 + mtspr 0x3bb, r24 + mtspr 0x3b8, r25 + mtspr 0x3bc, r26 + mtspr 0x3fc, r27 + mtspr 0x3fd, r28 + mtspr 0x3fe, r29 + mtspr 0x3FB, r30 + mtspr 0x3f9, r31 + b lbl_8037149C + cmpwi r6, 0 + beq lbl_8037147C + lwz r26, 0x278(r2) + mtspr 0x16, r26 +lbl_8037147C: + lmw r25, 0x240(r2) + mtspr 0x3d0, r25 + mtspr 0x3d1, r26 + mtspr 0x3d2, r27 + mtspr 0x3d3, r28 + mtspr 0x3D4, r29 + mtspr 0x3D5, r30 + mtspr 0x3d6, r31 +lbl_8037149C: + lmw r16, 0x1a8(r2) + mtsr 0, r16 + mtsr 1, r17 + mtsr 2, r18 + mtsr 3, r19 + mtsr 4, r20 + mtsr 5, r21 + mtsr 6, r22 + mtsr 7, r23 + mtsr 8, r24 + mtsr 9, r25 + mtsr 0xa, r26 + mtsr 0xb, r27 + mtsr 0xc, r28 + mtsr 0xd, r29 + mtsr 0xe, r30 + mtsr 0xf, r31 + lmw r12, 0x1f0(r2) + mtspr 0x3f0, r12 + mtspr 0x3f1, r13 + mtspr 0x1b, r14 + mtspr 0x11f, r15 + mtibatu 0, r16 + mtibatl 0, r17 + mtibatu 1, r18 + mtibatl 1, r19 + mtibatu 2, r20 + mtibatl 2, r21 + mtibatu 3, r22 + mtibatl 3, r23 + mtdbatu 0, r24 + mtdbatl 0, r25 + mtdbatu 1, r26 + mtdbatl 1, r27 + mtdbatu 2, r28 + mtdbatl 2, r29 + mtdbatu 3, r30 + mtdbatl 3, r31 + lmw r22, 0x25c(r2) + mtspr 0x19, r22 + mtdar r23 + mtdsisr r24 + mtspr 0x110, r25 + mtspr 0x111, r26 + mtspr 0x112, r27 + mtspr 0x113, r28 + mtspr 0x3f2, r30 + mtspr 0x11a, r31 + blr +#endif // clang-format on +} + +/* + * --INFO-- + * Address: 80220410 + * Size: 000008 + */ +u8 TRKTargetCPUMinorType(void) +{ + return 0x54; +} diff --git a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c index e69de29bb..77ea47844 100644 --- a/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c +++ b/libs/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c @@ -0,0 +1,1494 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +typedef struct memRange { + u8* start; + u8* end; + BOOL readable; + BOOL writeable; +} memRange; + +const memRange gTRKMemMap[1] = { { (u8*)0, (u8*)-1, TRUE, TRUE } }; + +typedef struct StopInfo_PPC { + u32 PC; + u32 PCInstruction; + u16 exceptionID; +} StopInfo_PPC; +typedef struct TRKExceptionStatus { + StopInfo_PPC exceptionInfo; + u8 inTRK; + u8 exceptionDetected; +} TRKExceptionStatus; +typedef struct TRKStepStatus { + BOOL active; // 0x0 + u8 type; // 0x4 + u32 count; // 0x8 + u32 rangeStart; // 0xC + u32 rangeEnd; // 0x10 +} TRKStepStatus; + +// Instruction macros +#define INSTR_NOP 0x60000000 +#define INSTR_BLR 0x4E800020 +#define DSFetch_u32(_p_) (*((u32*)_p_)) +#define DSFetch_u64(_p_) (*((u64*)_p_)) +#define INSTR_PSQ_ST(psr, offset, rDest, w, gqr) (0xF0000000 | (psr << 21) | (rDest << 16) | (w << 15) | (gqr << 12) | offset) +#define INSTR_PSQ_L(psr, offset, rSrc, w, gqr) (0xE0000000 | (psr << 21) | (rSrc << 16) | (w << 15) | (gqr << 12) | offset) +#define INSTR_STW(rSrc, offset, rDest) (0x90000000 | (rSrc << 21) | (rDest << 16) | offset) +#define INSTR_LWZ(rDest, offset, rSrc) (0x80000000 | (rDest << 21) | (rSrc << 16) | offset) +#define INSTR_STFD(fprSrc, offset, rDest) (0xD8000000 | (fprSrc << 21) | (rDest << 16) | offset) +#define INSTR_LFD(fprDest, offset, rSrc) (0xC8000000 | (fprDest << 21) | (rSrc << 16) | offset) +#define INSTR_MFSPR(rDest, spr) (0x7C000000 | (rDest << 21) | ((spr & 0xFE0) << 6) | ((spr & 0x1F) << 16) | 0x2A6) +#define INSTR_MTSPR(spr, rSrc) (0x7C000000 | (rSrc << 21) | ((spr & 0xFE0) << 6) | ((spr & 0x1F) << 16) | 0x3A6) + +ProcessorRestoreFlags_PPC gTRKRestoreFlags = { FALSE, FALSE }; +static TRKExceptionStatus gTRKExceptionStatus = { { 0, 0, 0 }, TRUE, 0 }; +static TRKStepStatus gTRKStepStatus = { FALSE, DSSTEP_IntoCount, 0, 0 }; +static u16 TRK_saved_exceptionID = 0; +ProcessorState_PPC gTRKCPUState; +TRKState gTRKState; + +typedef unsigned char u128[16]; +u128 TRKvalue128_temp; + +Default_PPC gTRKSaveState; +void TRKPostInterruptEvent(void); +void TRKExceptionHandler(u16 a); +void TRKUARTInterruptHandler(void); +void TRKInterruptHandlerEnableInterrupts(void); +DSError TRKPPCAccessSPR(void*, u32, BOOL); +DSError TRKPPCAccessPairedSingleRegister(void*, u32, BOOL); +DSError TRKPPCAccessFPRegister(void*, u32, BOOL); +DSError TRKPPCAccessSpecialReg(void*, u32*, BOOL); + +static BOOL TRKTargetCheckStep(); + +/* + * --INFO-- + * Address: 8021E884 + * Size: 000008 + */ +ASM u32 __TRK_get_MSR() { +#ifdef __MWERKS__ // clang-format off + nofralloc + mfmsr r3 + blr +#endif // clang-format on +} + +/* + * --INFO-- + * Address: 8021E88C + * Size: 000008 + */ +ASM void __TRK_set_MSR(register u32 msr) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + mtmsr msr + blr + #endif // clang-format on +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void __TRK_get_PVR(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void __TRK_get_IBAT0U(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void __TRK_get_IBAT0L(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void __TRK_get_IBAT1U(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void __TRK_get_IBAT1L(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void __TRK_get_IBAT2U(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void __TRK_get_IBAT2L(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void __TRK_get_IBAT3U(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void __TRK_get_IBAT3L(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void __TRK_get_DBAT0U(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void __TRK_get_DBAT0L(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void __TRK_get_DBAT1U(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void __TRK_get_DBAT1L(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void __TRK_get_DBAT2U(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void __TRK_get_DBAT2L(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void __TRK_get_DBAT3U(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: ........ + * Size: 000008 + */ +void __TRK_get_DBAT3L(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: 8021E894 + * Size: 000138 + */ +DSError TRKValidMemory32(const void* addr, size_t length, ValidMemoryOptions readWriteable) +{ + DSError err = DS_InvalidMemory; /* assume range is invalid */ + + const u8* start; + const u8* end; + + int i; + + /* + ** Get start and end addresses for the memory range and + ** verify that they are reasonable. + */ + + start = (const u8*)addr; + end = ((const u8*)addr + (length - 1)); + + if (end < start) + return DS_InvalidMemory; + + /* + ** Iterate through the gTRKMemMap array to determine if the requested + ** range falls within the valid ranges in the map. + */ + + for (i = 0; (i < (s32)(sizeof(gTRKMemMap) / sizeof(memRange))); i++) { + /* + ** If the requested range is not completely above + ** the valid range AND it is not completely below + ** the valid range then it must overlap somewhere. + ** If the requested range overlaps with one of the + ** valid ranges, do some additional checking. + ** + */ + + if ((start <= (const u8*)gTRKMemMap[i].end) && (end >= (const u8*)gTRKMemMap[i].start)) { + /* + ** First, verify that the read/write attributes are + ** acceptable. If so, then recursively check any + ** part of the requested range that falls before or + ** after the valid range. + */ + + if ((((u8)readWriteable == VALIDMEM_Readable) && !gTRKMemMap[i].readable) + || (((u8)readWriteable == VALIDMEM_Writeable) && !gTRKMemMap[i].writeable)) { + err = DS_InvalidMemory; + } else { + err = DS_NoError; + + /* + ** If a portion of the requested range falls before + ** the current valid range, then recursively + ** check it. + */ + + if (start < (const u8*)gTRKMemMap[i].start) + err = TRKValidMemory32(start, (u32)((const u8*)gTRKMemMap[i].start - start), readWriteable); + + /* + ** If a portion of the requested range falls after + ** the current valid range, then recursively + ** check it. + ** Note: Only do this step if the previous check + ** did not detect invalid access. + */ + + if ((err == DS_NoError) && (end > (const u8*)gTRKMemMap[i].end)) + err = TRKValidMemory32((const u8*)gTRKMemMap[i].end, (u32)(end - (const u8*)gTRKMemMap[i].end), readWriteable); + } + + break; + } + } + + return err; +} + +/* + * --INFO-- + * Address: 8021E9CC + * Size: 00003C + */ +static ASM void TRK_ppc_memcpy(register void* dest, register const void* src, register int n, register u32 param_4, register u32 param_5) { +#ifdef __MWERKS__ // clang-format off +#define msr r8 +#define byte r9 +#define count r10 +nofralloc + +mfmsr msr +li count, 0 + +top_loop: +cmpw count, n +beq out_loop + +mtmsr param_5 +sync + +lbzx byte, count, src + +mtmsr param_4 +sync + +stbx byte, count, dest + +addi count, count, 1 + +b top_loop +out_loop: +mtmsr msr +sync + +blr +#undef count +#undef byte +#undef msr +#endif // clang-format on +} + +/* + * --INFO-- + * Address: 8021EA08 + * Size: 000164 + */ +DSError TRKTargetAccessMemory(void* data, u32 start, size_t* length, MemoryAccessOptions accessOptions, BOOL read) +{ + DSError error; + u32 target_msr; + void* addr; + u32 trk_msr; + TRKExceptionStatus tempExceptionStatus = gTRKExceptionStatus; + gTRKExceptionStatus.exceptionDetected = FALSE; + + addr = (void*)TRKTargetTranslate(start); + error = TRKValidMemory32(addr, *length, read ? VALIDMEM_Readable : VALIDMEM_Writeable); + + if (error != DS_NoError) { + *length = 0; + } else { + target_msr = __TRK_get_MSR(); + trk_msr = target_msr | gTRKCPUState.Extended1.MSR & 0x10; + + if (read) { + TRK_ppc_memcpy(data, addr, *length, target_msr, trk_msr); + } else { + TRK_ppc_memcpy(addr, data, *length, trk_msr, target_msr); + TRK_flush_cache(addr, *length); + if ((void*)start != addr) { + TRK_flush_cache((void*)start, *length); + } + } + } + + if (gTRKExceptionStatus.exceptionDetected) { + *length = 0; + error = DS_CWDSException; + } + + gTRKExceptionStatus = tempExceptionStatus; + return error; +} + +/* + * --INFO-- + * Address: 8021EB6C + * Size: 00004C + */ +DSError TRKTargetReadInstruction(void* data, u32 start) +{ + DSError error; + size_t registersLength = 4; + + error = TRKTargetAccessMemory(data, start, ®istersLength, MEMACCESS_UserMemory, TRUE); + + if (error == DS_NoError && registersLength != 4) { + error = DS_InvalidMemory; + } + + return error; +} + +/* + * --INFO-- + * Address: 8021EBB8 + * Size: 0000FC + */ +DSError TRKTargetAccessDefault(u32 firstRegister, u32 lastRegister, TRKBuffer* b, size_t* registersLengthPtr, BOOL read) +{ + DSError error; + u32 count; + u32* data; + TRKExceptionStatus tempExceptionStatus; + + if (lastRegister > 0x24) { + return DS_InvalidRegister; + } + + tempExceptionStatus = gTRKExceptionStatus; + + gTRKExceptionStatus.exceptionDetected = FALSE; + + data = gTRKCPUState.Default.GPR + firstRegister; + + count = (lastRegister - firstRegister) + 1; + + *registersLengthPtr = count * sizeof(u32); + + if (read) { + error = TRKAppendBuffer_ui32(b, data, count); + } else { + error = TRKReadBuffer_ui32(b, data, count); + } + + if (gTRKExceptionStatus.exceptionDetected) { + *registersLengthPtr = 0; + error = DS_CWDSException; + } + + gTRKExceptionStatus = tempExceptionStatus; + return error; +} + +/* + * --INFO-- + * Address: 8021ECB4 + * Size: 000148 + */ +DSError TRKTargetAccessFP(u32 firstRegister, u32 lastRegister, TRKBuffer* b, size_t* registersLengthPtr, BOOL read) +{ + u64 temp; + DSError error; + TRKExceptionStatus tempExceptionStatus; + u32 current; + + if (lastRegister > 0x21) { + return DS_InvalidRegister; + } + + tempExceptionStatus = gTRKExceptionStatus; + gTRKExceptionStatus.exceptionDetected = FALSE; + + __TRK_set_MSR(__TRK_get_MSR() | 0x2000); + + *registersLengthPtr = 0; + error = DS_NoError; + + for (current = firstRegister; (current <= lastRegister) && (error == DS_NoError); current++, *registersLengthPtr += sizeof(f64)) { + if (read) { + TRKPPCAccessFPRegister(&temp, current, read); + error = TRKAppendBuffer1_ui64(b, temp); + } else { + TRKReadBuffer1_ui64(b, &temp); + error = TRKPPCAccessFPRegister(&temp, current, read); + } + } + + if (gTRKExceptionStatus.exceptionDetected) { + *registersLengthPtr = 0; + error = DS_CWDSException; + } + + gTRKExceptionStatus = tempExceptionStatus; + return error; +} + +/* + * --INFO-- + * Address: 8021EDFC + * Size: 000178 + */ +DSError TRKTargetAccessExtended1(u32 firstRegister, u32 lastRegister, TRKBuffer* b, size_t* registersLengthPtr, BOOL read) +{ + TRKExceptionStatus tempExceptionStatus; + int error; + u32* data; + int count; + + if (lastRegister > 0x60) { + return DS_InvalidRegister; + } + + tempExceptionStatus = gTRKExceptionStatus; + gTRKExceptionStatus.exceptionDetected = FALSE; + + *registersLengthPtr = 0; + + if (firstRegister <= lastRegister) { + data = (u32*)&gTRKCPUState.Extended1 + firstRegister; + count = lastRegister - firstRegister + 1; + *registersLengthPtr += count * sizeof(u32); + + if (read) { + error = TRKAppendBuffer_ui32(b, data, count); + } else { + if (data <= &gTRKCPUState.Extended1.TBU && (data + count - 1) >= &gTRKCPUState.Extended1.TBL) { + gTRKRestoreFlags.TBR = 1; + } + + if (data <= &gTRKCPUState.Extended1.DEC && (data + count - 1) >= &gTRKCPUState.Extended1.DEC) { + gTRKRestoreFlags.DEC = 1; + } + error = TRKReadBuffer_ui32(b, data, count); + } + } + if (gTRKExceptionStatus.exceptionDetected) { + *registersLengthPtr = 0; + error = DS_CWDSException; + } + + gTRKExceptionStatus = tempExceptionStatus; + return error; +} + +/* + * --INFO-- + * Address: 8021EF74 + * Size: 00017C + */ +DSError TRKTargetAccessExtended2(u32 firstRegister, u32 lastRegister, TRKBuffer* b, size_t* registerStorageSize, BOOL read) +{ + u32 value_buf[2]; + TRKExceptionStatus savedException; + u32 i; + DSError err; + u32 value_buf0[1]; + + if (lastRegister > 0x1f) + return DS_InvalidRegister; + + /* + ** Save any existing exception status and clear the exception flag. + ** This allows detection of exceptions that occur ONLY within this + ** function. + */ + + savedException = gTRKExceptionStatus; + gTRKExceptionStatus.exceptionDetected = FALSE; + + TRKPPCAccessSPR(value_buf0, SPR_HID2, TRUE); + + value_buf0[0] |= 0xA0000000; + TRKPPCAccessSPR(value_buf0, SPR_HID2, FALSE); + + value_buf0[0] = 0; + TRKPPCAccessSPR(value_buf0, SPR_GQR0, FALSE); + + *registerStorageSize = 0; + err = DS_NoError; + + for (i = firstRegister; (i <= lastRegister) && (err == DS_NoError); i++) { + if (read) { + err = TRKPPCAccessPairedSingleRegister((u64*)value_buf, i, read); + err = TRKAppendBuffer1_ui64(b, *(u64*)value_buf); + } else { + err = TRKReadBuffer1_ui64(b, (u64*)value_buf); + err = TRKPPCAccessPairedSingleRegister((u64*)value_buf, i, read); + } + + *registerStorageSize += sizeof(u64); + } + + if (gTRKExceptionStatus.exceptionDetected) { + *registerStorageSize = 0; + err = DS_CWDSException; + } + + gTRKExceptionStatus = savedException; + + return err; +} + +/* + * --INFO-- + * Address: 8021F0F0 + * Size: 000028 + */ +DSError TRKTargetVersions(DSVersions* versions) +{ + versions->kernelMajor = 0; + versions->kernelMinor = 8; + versions->protocolMajor = 1; + versions->protocolMinor = 10; + return DS_NoError; +} + +/* + * --INFO-- + * Address: 8021F118 + * Size: 0000A4 + */ +DSError TRKTargetSupportMask(u8 mask[32]) +{ + mask[0] = 0x7a; + mask[1] = 0; + mask[2] = 0x4f; + mask[3] = 7; + mask[4] = 0; + mask[5] = 0; + mask[6] = 0; + mask[7] = 0; + mask[8] = 0; + mask[9] = 0; + mask[10] = 0; + mask[0xb] = 0; + mask[0xc] = 0; + mask[0xd] = 0; + mask[0xe] = 0; + mask[0xf] = 0; + mask[0x10] = 1; + mask[0x11] = 0; + mask[0x12] = 3; + mask[0x13] = 0; + mask[0x14] = 0; + mask[0x15] = 0; + mask[0x16] = 0; + mask[0x17] = 0; + mask[0x18] = 0; + mask[0x19] = 0; + mask[0x1a] = 3; + mask[0x1b] = 0; + mask[0x1c] = 0; + mask[0x1d] = 0; + mask[0x1e] = 0; + mask[0x1f] = 0x80; + return DS_NoError; +} + +extern BOOL gTRKBigEndian; +/* + * --INFO-- + * Address: 8021F1BC + * Size: 000068 + */ +DSError TRKTargetCPUType(DSCPUType* cpuType) +{ + cpuType->cpuMajor = 0; + cpuType->cpuMinor = TRKTargetCPUMinorType(); + cpuType->bigEndian = gTRKBigEndian; + cpuType->defaultTypeSize = 4; + cpuType->fpTypeSize = 8; + cpuType->extended1TypeSize = 4; + cpuType->extended2TypeSize = 8; + return DS_NoError; +} + +/* + * --INFO-- + * Address: ........ + * Size: 00002C + */ +void TRKTargetCheckException(void) +{ + // UNUSED FUNCTION +} + +/* + * --INFO-- + * Address: 8021F224 + * Size: 000194 + */ +ASM void TRKInterruptHandler() +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + mtsrr0 r2 + mtsrr1 r4 + mfsprg r4, 3 + mfcr r2 + mtsprg 3, r2 + lis r2, gTRKState@h + ori r2, r2, gTRKState@l + lwz r2, TRKState_PPC.MSR(r2) + ori r2, r2, 0x8002 + xori r2, r2, 0x8002 + sync + mtmsr r2 + sync + lis r2, TRK_saved_exceptionID@h + ori r2, r2, TRK_saved_exceptionID@l + sth r3, 0(r2) + cmpwi r3, 0x500 + bne L_802CF694 + lis r2, gTRKCPUState@h + ori r2, r2, gTRKCPUState@l + mflr r3 + stw r3, ProcessorState_PPC.transport_handler_saved_ra(r2) + bl TRKUARTInterruptHandler + lis r2, gTRKCPUState@h + ori r2, r2, gTRKCPUState@l + lwz r3, ProcessorState_PPC.transport_handler_saved_ra(r2) + mtlr r3 + lis r2, gTRKState@h + ori r2, r2, gTRKState@l + lwz r2, TRKState_PPC.inputPendingPtr(r2) + lbz r2, TRKState_PPC.GPR[0](r2) + cmpwi r2, 0 + beq L_802CF678 + lis r2, gTRKExceptionStatus@h + ori r2, r2, gTRKExceptionStatus@l + lbz r2, TRKExceptionStatus.inTRK(r2) + cmpwi r2, 1 + beq L_802CF678 + lis r2, gTRKState@h + ori r2, r2, gTRKState@l + li r3, 1 + stb r3, TRKState_PPC.inputActivated(r2) + b L_802CF694 +L_802CF678: + lis r2, gTRKSaveState@h + ori r2, r2, gTRKSaveState@l + lwz r3, Default_PPC.CR(r2) + mtcrf 0xff, r3 + lwz r3, Default_PPC.GPR[3](r2) + lwz r2, Default_PPC.GPR[2](r2) + rfi +L_802CF694: + lis r2, TRK_saved_exceptionID@h + ori r2, r2, TRK_saved_exceptionID@l + lhz r3, 0(r2) + lis r2, gTRKExceptionStatus@h + ori r2, r2, gTRKExceptionStatus@l + lbz r2, TRKExceptionStatus.inTRK(r2) + cmpwi r2, 0 + bne TRKExceptionHandler + lis r2, gTRKCPUState@h + ori r2, r2, gTRKCPUState@l + stw r0, ProcessorState_PPC.Default.GPR[0](r2) + stw r1, ProcessorState_PPC.Default.GPR[1](r2) + mfsprg r0, 1 + stw r0, ProcessorState_PPC.Default.GPR[2](r2) + sth r3, ProcessorState_PPC.Extended1.exceptionID(r2) + sth r3, (ProcessorState_PPC.Extended1.exceptionID + 2)(r2) + mfsprg r0, 2 + stw r0, ProcessorState_PPC.Default.GPR[3](r2) + stmw r4, ProcessorState_PPC.Default.GPR[4](r2) + mfsrr0 r27 + mflr r28 + mfsprg r29, 3 + mfctr r30 + mfxer r31 + stmw r27, ProcessorState_PPC.Default.PC(r2) + bl TRKSaveExtended1Block + lis r2, gTRKExceptionStatus@h + ori r2, r2, gTRKExceptionStatus@l + li r3, 1 + stb r3, TRKExceptionStatus.inTRK(r2) + lis r2, gTRKState@h + ori r2, r2, gTRKState@l + lwz r0, TRKState_PPC.MSR(r2) + sync + mtmsr r0 + sync + lwz r0, TRKState_PPC.LR(r2) + mtlr r0 + lwz r0, TRKState_PPC.CTR(r2) + mtctr r0 + lwz r0, TRKState_PPC.XER(r2) + mtxer r0 + lwz r0, TRKState_PPC.DSISR(r2) + mtdsisr r0 + lwz r0, TRKState_PPC.DAR(r2) + mtdar r0 + lmw r3, TRKState_PPC.GPR[3](r2) + lwz r0, TRKState_PPC.GPR[0](r2) + lwz r1, TRKState_PPC.GPR[1](r2) + lwz r2, TRKState_PPC.GPR[2](r2) + b TRKPostInterruptEvent +#endif // clang-format on +} + +/* + * --INFO-- + * Address: 8021F3B8 + * Size: 00009C + */ +ASM void TRKExceptionHandler(u16 a) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + lis r2, gTRKExceptionStatus@h + ori r2, r2, gTRKExceptionStatus@l + sth r3, TRKExceptionStatus.exceptionInfo.exceptionID(r2) + mfsrr0 r3 + stw r3, TRKExceptionStatus.exceptionInfo.PC(r2) + lhz r3, TRKExceptionStatus.exceptionInfo.exceptionID(r2) + cmpwi r3, 0x200 + beq LAB_00010ba4 + cmpwi r3, 0x300 + beq LAB_00010ba4 + cmpwi r3, 0x400 + beq LAB_00010ba4 + cmpwi r3, 0x600 + beq LAB_00010ba4 + cmpwi r3, 0x700 + beq LAB_00010ba4 + cmpwi r3, 0x800 + beq LAB_00010ba4 + cmpwi r3, 0x1000 + beq LAB_00010ba4 + cmpwi r3, 0x1100 + beq LAB_00010ba4 + cmpwi r3, 0x1200 + beq LAB_00010ba4 + cmpwi r3, 0x1300 + beq LAB_00010ba4 + b LAB_00010bb0 +LAB_00010ba4: + mfsrr0 r3 + addi r3, r3, 0x4 + mtsrr0 r3 +LAB_00010bb0: + lis r2, gTRKExceptionStatus@h + ori r2, r2, gTRKExceptionStatus@l + li r3, 0x1 + stb r3, TRKExceptionStatus.exceptionDetected(r2) + mfsprg r3, 3 + mtcrf 0xff, r3 + mfsprg r2, 1 + mfsprg r3, 2 + rfi +#endif // clang-format on +} + +/* + * --INFO-- + * Address: 8021F454 + * Size: 0000B0 + */ +void TRKPostInterruptEvent(void) +{ + TRKEvent event; + NubEventType eventType; + u32 inst; + + if (gTRKState.inputActivated) { + gTRKState.inputActivated = FALSE; + } else { + switch (gTRKCPUState.Extended1.exceptionID & 0xFFFF) { + case 0xd00: + case 0x700: + TRKTargetReadInstruction(&inst, gTRKCPUState.Default.PC); + + if (inst == 0xfe00000) { + eventType = NUBEVENT_Support; + } else { + eventType = NUBEVENT_Breakpoint; + } + break; + default: + eventType = NUBEVENT_Exception; + break; + } + + TRKConstructEvent(&event, eventType); + TRKPostEvent(&event); + } +} + +/* + * --INFO-- + * Address: 8021F504 + * Size: 0000C4 + */ +ASM void TRKSwapAndGo() +{ +#ifdef __MWERKS__ // clang-format off + nofralloc + lis r3, gTRKState@h + ori r3, r3, gTRKState@l + stmw r0, TRKState_PPC.GPR[0](r3) + mfmsr r0 + stw r0, TRKState_PPC.MSR(r3) + mflr r0 + stw r0, TRKState_PPC.LR(r3) + mfctr r0 + stw r0, TRKState_PPC.CTR(r3) + mfxer r0 + stw r0, TRKState_PPC.XER(r3) + mfdsisr r0 + stw r0, TRKState_PPC.DSISR(r3) + mfdar r0 + stw r0, TRKState_PPC.DAR(r3) + li r1, -0x7ffe + nor r1, r1, r1 + mfmsr r3 + and r3, r3, r1 + mtmsr r3 + lis r2, gTRKState@h + ori r2, r2, gTRKState@l + lwz r2, TRKState_PPC.inputPendingPtr(r2) + lbz r2, TRKState_PPC.GPR[0](r2) + cmpwi r2, 0 + beq L_802CF930 + lis r2, gTRKState@h + ori r2, r2, gTRKState@l + li r3, 1 + stb r3, TRKState_PPC.inputActivated(r2) + b TRKInterruptHandlerEnableInterrupts +L_802CF930: + lis r2, gTRKExceptionStatus@h + ori r2, r2, gTRKExceptionStatus@l + li r3, 0 + stb r3, 0xc(r2) + bl TRKRestoreExtended1Block + lis r2, gTRKCPUState@h + ori r2, r2, gTRKCPUState@l + lmw r27, ProcessorState_PPC.Default.PC(r2) + mtsrr0 r27 + mtlr r28 + mtcrf 0xff, r29 + mtctr r30 + mtxer r31 + lmw r3, ProcessorState_PPC.Default.GPR[3](r2) + lwz r0, ProcessorState_PPC.Default.GPR[0](r2) + lwz r1, ProcessorState_PPC.Default.GPR[1](r2) + lwz r2, ProcessorState_PPC.Default.GPR[2](r2) + rfi +#endif // clang-format on +} + +/* + * --INFO-- + * Address: 8021F5C8 + * Size: 000054 + */ +ASM void TRKInterruptHandlerEnableInterrupts(void) +{ +#ifdef __MWERKS__ // clang-format off + nofralloc; + lis r2, gTRKState@h + ori r2, r2, gTRKState@l + lwz r0, TRKState_PPC.MSR(r2) + sync + mtmsr r0 + sync + lwz r0, TRKState_PPC.LR(r2) + mtlr r0 + lwz r0, TRKState_PPC.CTR(r2) + mtctr r0 + lwz r0, TRKState_PPC.XER(r2) + mtxer r0 + lwz r0, TRKState_PPC.DSISR(r2) + mtdsisr r0 + lwz r0, TRKState_PPC.DAR(r2) + mtdar r0 + lmw r3, TRKState_PPC.GPR[3](r2) + lwz r0, TRKState_PPC.GPR[0](r2) + lwz r1, TRKState_PPC.GPR[1](r2) + lwz r2, TRKState_PPC.GPR[2](r2) + b TRKPostInterruptEvent +#endif // clang-format on +} + +/* + * --INFO-- + * Address: 8021F61C + * Size: 000064 + */ +DSError TRKTargetInterrupt(TRKEvent* event) +{ + DSError error = DS_NoError; + switch (event->eventType) { + case NUBEVENT_Breakpoint: + case NUBEVENT_Exception: + if (TRKTargetCheckStep() == FALSE) { + TRKTargetSetStopped(TRUE); + error = TRKDoNotifyStopped(DSMSG_NotifyStopped); + } + break; + default: + break; + } + + return error; +} + +/* + * --INFO-- + * Address: 8021F680 + * Size: 000090 + */ +DSError TRKTargetAddStopInfo(TRKBuffer* buffer) +{ + DSError error; + u32 instruction; + + error = TRKAppendBuffer1_ui32(buffer, gTRKCPUState.Default.PC); + if (error == DS_NoError) { + error = TRKTargetReadInstruction(&instruction, gTRKCPUState.Default.PC); + } + if (error == DS_NoError) + error = TRKAppendBuffer1_ui32(buffer, instruction); + if (error == DS_NoError) + error = TRKAppendBuffer1_ui16(buffer, gTRKCPUState.Extended1.exceptionID); + + return error; +} + +/* + * --INFO-- + * Address: 8021F710 + * Size: 000088 + */ +DSError TRKTargetAddExceptionInfo(TRKBuffer* buffer) +{ + DSError error; + u32 local_10; + + error = TRKAppendBuffer1_ui32(buffer, gTRKExceptionStatus.exceptionInfo.PC); + if (error == 0) { + error = TRKTargetReadInstruction(&local_10, gTRKExceptionStatus.exceptionInfo.PC); + } + if (error == 0) { + error = TRKAppendBuffer1_ui32(buffer, local_10); + } + if (error == 0) { + error = TRKAppendBuffer1_ui16(buffer, gTRKExceptionStatus.exceptionInfo.exceptionID); + } + + return error; +} + +/* + * --INFO-- + * Address: 8021F798 + * Size: 00003C + */ +static DSError TRKTargetEnableTrace(BOOL val) +{ + if (val) { + gTRKCPUState.Extended1.MSR |= 0x400; + } else { + gTRKCPUState.Extended1.MSR &= ~0x400; + } + return DS_NoError; +} + +/* + * --INFO-- + * Address: 8021F7D4 + * Size: 000084 + */ +static BOOL TRKTargetStepDone() +{ + BOOL result = TRUE; + + if (gTRKStepStatus.active && ((u16)gTRKCPUState.Extended1.exceptionID) == PPC_Trace) { + switch (gTRKStepStatus.type) { + case DSSTEP_IntoCount: + if (gTRKStepStatus.count > 0) { + result = FALSE; + } + break; + case DSSTEP_IntoRange: + if (gTRKCPUState.Default.PC >= gTRKStepStatus.rangeStart && gTRKCPUState.Default.PC <= gTRKStepStatus.rangeEnd) { + result = FALSE; + } + break; + default: + break; + } + } + + return result; +} + +/* + * --INFO-- + * Address: 8021F858 + * Size: 000070 + */ +static DSError TRKTargetDoStep() +{ + gTRKStepStatus.active = TRUE; + TRKTargetEnableTrace(TRUE); + + if (gTRKStepStatus.type == DSSTEP_IntoCount || gTRKStepStatus.type == DSSTEP_OverCount) { + gTRKStepStatus.count--; + } + + TRKTargetSetStopped(FALSE); + return DS_NoError; +} + +/* + * --INFO-- + * Address: 8021F8C8 + * Size: 000068 + */ +static BOOL TRKTargetCheckStep() +{ + if (gTRKStepStatus.active) { + TRKTargetEnableTrace(FALSE); + + if (TRKTargetStepDone()) { + gTRKStepStatus.active = FALSE; + } else { + TRKTargetDoStep(); + } + } + + return gTRKStepStatus.active; +} + +/* + * --INFO-- + * Address: 8021F930 + * Size: 000044 + */ +DSError TRKTargetSingleStep(u32 count, BOOL stepOver) +{ + DSError error = DS_NoError; + + if (stepOver) { + error = DS_UnsupportedError; + } else { + gTRKStepStatus.type = DSSTEP_IntoCount; + gTRKStepStatus.count = count; + error = TRKTargetDoStep(); + } + + return error; +} + +/* + * --INFO-- + * Address: 8021F974 + * Size: 000048 + */ +DSError TRKTargetStepOutOfRange(u32 rangeStart, u32 rangeEnd, BOOL stepOver) +{ + DSError error = DS_NoError; + + if (stepOver) { + // Stepping over isn't supported for PowerPC + error = DS_UnsupportedError; + } else { + gTRKStepStatus.type = DSSTEP_IntoRange; + // gTRKStepStatus.active = TRUE; + gTRKStepStatus.rangeStart = rangeStart; + gTRKStepStatus.rangeEnd = rangeEnd; + error = TRKTargetDoStep(); + } + + return error; +} + +/* + * --INFO-- + * Address: 8021F9BC + * Size: 000010 + */ +u32 TRKTargetGetPC() +{ + return gTRKCPUState.Default.PC; +} + +/* + * --INFO-- + * Address: 8021F9CC + * Size: 0000F0 + */ +DSError TRKTargetSupportRequest(void) +{ + DSError error; + // u32 spC; + size_t* length; + TRKEvent event; + u8 ioResult; + u8 commandId; + + commandId = (MessageCommandID)gTRKCPUState.Default.GPR[3]; + if (commandId != DSMSG_ReadFile && commandId != DSMSG_WriteFile) { + TRKConstructEvent(&event, NUBEVENT_Exception); + TRKPostEvent(&event); + return DS_NoError; + } + + length = (size_t*)gTRKCPUState.Default.GPR[5]; + error = TRKSuppAccessFile((u8)gTRKCPUState.Default.GPR[4], (u8*)gTRKCPUState.Default.GPR[6], length, (DSIOResult*)&ioResult, TRUE, + commandId == DSMSG_ReadFile); + if (ioResult == DS_IONoError && error != DS_NoError) { + ioResult = DS_IOError; + } + gTRKCPUState.Default.GPR[3] = ioResult; + if (commandId == DSMSG_ReadFile) { + TRK_flush_cache((void*)gTRKCPUState.Default.GPR[6], *length); + } + gTRKCPUState.Default.PC += 4; + return error; +} + +/* + * --INFO-- + * Address: 8021FABC + * Size: 00003C + */ +DSError TRKTargetFlushCache(u8 a, void* start, void* end) +{ + if (start < end) { + TRK_flush_cache(start, (u8*)end - (u8*)start); + return DS_NoError; + } + + return DS_InvalidMemory; +} + +/* + * --INFO-- + * Address: 8021FAF8 + * Size: 000010 + */ +BOOL TRKTargetStopped() +{ + return gTRKState.isStopped; +} + +/* + * --INFO-- + * Address: 8021FB08 + * Size: 000010 + */ +void TRKTargetSetStopped(uint stopped) +{ + gTRKState.isStopped = stopped; +} + +/* + * --INFO-- + * Address: 8021FB18 + * Size: 000028 + */ +u32 TRKTargetStop() +{ + TRKTargetSetStopped(1); + return 0; +} + +/* + * --INFO-- + * Address: 8021FB40 + * Size: 0000B0 + */ +DSError TRKPPCAccessSPR(void* value, u32 spr_register_num, BOOL read) +{ + /* Initialize instruction array with nop */ + + u32 access_func[5] = { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP }; + /* + ** Construct a small assembly function to perform the + ** requested access and call it. The read/write function + ** is in the form: + ** + ** read: + ** mfspr r4, spr_register_num + ** stw r4, 0(r3) + ** blr + ** + ** write: + ** lwz r4, 0(r3) + ** mtspr spr_register_num, r4 + ** blr + ** + */ + + if (read) { + access_func[0] = INSTR_MFSPR(4, spr_register_num); + access_func[1] = (u32)INSTR_STW(4, 0, 3); + } else { + access_func[0] = (u32)INSTR_LWZ(4, 0, 3); + access_func[1] = INSTR_MTSPR(spr_register_num, 4); + } + + return TRKPPCAccessSpecialReg(value, access_func, read); +} + +/* + * --INFO-- + * Address: 8021FBF0 + * Size: 000078 + */ +DSError TRKPPCAccessPairedSingleRegister(void* srcDestPtr, u32 psr, BOOL read) +{ + // all nop by default + u32 instructionData[] = { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP }; + + if (read) { + instructionData[0] = INSTR_PSQ_ST(psr, 0, 3, 0, 0); // psq_st psr, 0(r3), 0, 0 + } else { + instructionData[0] = INSTR_PSQ_L(psr, 0, 3, 0, 0); // psq_l psr, 0(r3), 0, 0 + } + + return TRKPPCAccessSpecialReg(srcDestPtr, instructionData, read); +} + +#define FP_FPSCR_ACCESS 32 +#define FP_FPECR_ACCESS 33 + +/* + * --INFO-- + * Address: 8021FC68 + * Size: 000180 + */ +DSError TRKPPCAccessFPRegister(void* srcDestPtr, u32 fpr, BOOL read) +{ + DSError error = DS_NoError; + // all nop by default + u32 instructionData1[] = { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP }; + + if (fpr < FP_FPSCR_ACCESS) { + if (read) { + instructionData1[0] = INSTR_STFD(fpr, 0, 3); // stfd fpr, 0(r3) + } else { + instructionData1[0] = INSTR_LFD(fpr, 0, 3); // lfd fpr, 0(r3) + } + + error = TRKPPCAccessSpecialReg(srcDestPtr, instructionData1, read); + + } else if (fpr == FP_FPSCR_ACCESS) { + if (read) { + /* + stfd f1, 0 (r4) + mffs sp + stfd f1, 0 (r3) + lfd f1, 0 (r4) + */ + instructionData1[0] = 0xD8240000; + instructionData1[1] = 0xFC20048E; + instructionData1[2] = 0xD8230000; + instructionData1[3] = 0xC8240000; + } else { + /* + stfd f1, 0 (r4) + lfd f1, 0 (r3) + mtfsf 0xff, f1 + lfd f1, 0 (r4) + */ + instructionData1[0] = 0xD8240000; + instructionData1[1] = 0xC8230000; + instructionData1[2] = 0xFDFE0D8E; + instructionData1[3] = 0xC8240000; + } + + error = TRKPPCAccessSpecialReg(srcDestPtr, instructionData1, read); + *(u64*)srcDestPtr &= 0xFFFFFFFF; + + } else if (fpr == FP_FPECR_ACCESS) { + if (!read) { + *(u32*)srcDestPtr = *((u32*)(srcDestPtr) + 1); + } + error = TRKPPCAccessSPR(srcDestPtr, 1022, read); + if (read) { + DSFetch_u64(srcDestPtr) = DSFetch_u32(srcDestPtr) & 0xffffffffLL; + } + } + + return error; +} + +#define DEBUG_VECTORREG_ACCESS 0 + +/* + * --INFO-- + * Address: 8021FDE8 + * Size: 000068 + */ +DSError TRKPPCAccessSpecialReg(void* value, u32* access_func, BOOL read) +{ + typedef void (*asm_access_type)(void*, void*); + + /* + ** Construct a small assembly function to perform the + ** requested access and call it. The read/write function + ** is in the form: + ** + ** + ** blr + */ + + /* + ** Put blr instruction at the end of access function (it should be + ** a 5-instruction array w/the last one empty). + */ + + access_func[4] = INSTR_BLR; + + /* + ** Now that the instruction array is built, get a function pointer to it. + */ + +#if DEBUG_VECTORREG_ACCESS + + __puts("\r\nasm_access: "); + __puthex8((u32)asm_access); + __puts(" access_func: "); + __puthex8((u32)access_func); + + for (i = 0; i < 10; i++) { + __puts("\r\ninst["); + __puthex2(i); + __puts("]: "); + __puthex8(access_func[i]); + __puts(" ; "); + __puthex8(*((u32*)asm_access + i)); + } + + __puts("\r\n"); + +#endif + + // Flush cache + TRK_flush_cache((void*)(u32)access_func, (sizeof(access_func) * 5)); + ((asm_access_type)access_func)((u32*)value, (void*)&TRKvalue128_temp); + + return DS_NoError; +} + +/* + * --INFO-- + * Address: 8021FE50 + * Size: 000010 + */ +void TRKTargetSetInputPendingPtr(void* ptr) +{ + gTRKState.inputPendingPtr = ptr; +} From 3160fcab787b083e82b10c8d7aae39e7a53b7c26 Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Mon, 26 May 2025 13:38:54 -0400 Subject: [PATCH 13/19] Linked and update more D-SDK files --- configure.py | 32 +- include/dolphin/os.h | 69 ++-- include/rwsdk/rpworld.h | 2 +- include/rwsdk/rtquat.h | 551 ++++++++++++++++++++++++++- include/rwsdk/rtslerp.h | 115 +++--- include/rwsdk/rwcore.h | 2 +- include/rwsdk/rwplcore.h | 3 +- libs/dolphin/ar/ar.c | 4 +- libs/dolphin/exi/EXIBios.c | 4 +- libs/dolphin/gx/GXFrameBuf.c | 2 +- libs/dolphin/gx/GXMisc.c | 8 +- libs/dolphin/os/OSAlarm.c | 2 +- libs/dolphin/os/OSCache.c | 4 +- libs/dolphin/os/OSError.c | 2 +- libs/dolphin/os/OSReset.c | 4 +- libs/dolphin/os/OSTime.c | 6 +- libs/dolphin/pad/Padclamp.c | 2 +- libs/dolphin/vi/vi.c | 617 +++++++++++++++++-------------- libs/rwsdk/plugin/collis/ctbsp.c | 8 + libs/rwsdk/tool/slerp/rtslerp.c | 8 + libs/rwsdk/tool/slerp/rtslerp.h | 231 ++++++++++++ 21 files changed, 1281 insertions(+), 395 deletions(-) create mode 100644 libs/rwsdk/plugin/collis/ctbsp.c create mode 100644 libs/rwsdk/tool/slerp/rtslerp.c create mode 100644 libs/rwsdk/tool/slerp/rtslerp.h diff --git a/configure.py b/configure.py index 582c65c94..040b9dcf1 100644 --- a/configure.py +++ b/configure.py @@ -238,6 +238,19 @@ #"-requireprotos" ] +# Renderware library flags +cflags_renderware = [ + *cflags_base, + "-lang=c", + "-fp fmadd", + "-fp_contract off", + "-char signed", + "-str reuse", + "-common off", + "-O4,p", + #"-requireprotos" +] + # REL flags cflags_rel = [ *cflags_base, @@ -307,8 +320,9 @@ def trkLib(lib_name: str, objects: List[Object]) -> Dict[str, Any]: def RenderWareLib(lib_name: str, objects: List[Object]) -> Dict[str, Any]: return { "lib": lib_name, + "src_dir": "libs", "mw_version": "GC/1.3.2", - "cflags": cflags_base, + "cflags": cflags_renderware, "progress_category": "RW", "objects": objects, } @@ -608,7 +622,7 @@ def MatchingFor(*versions): DolphinLib( "ar", [ - Object(NonMatching, "dolphin/ar/ar.c"), + Object(Matching, "dolphin/ar/ar.c"), Object(Matching, "dolphin/ar/arq.c") ] ), @@ -694,9 +708,9 @@ def MatchingFor(*versions): Object(NonMatching, "dolphin/gx/GXInit.c"), Object(NonMatching, "dolphin/gx/GXFifo.c"), Object(NonMatching, "dolphin/gx/GXAttr.c"), - Object(NonMatching, "dolphin/gx/GXMisc.c"), + Object(Matching, "dolphin/gx/GXMisc.c"), Object(NonMatching, "dolphin/gx/GXGeometry.c"), - Object(NonMatching, "dolphin/gx/GXFrameBuf.c"), + Object(Matching, "dolphin/gx/GXFrameBuf.c"), Object(NonMatching, "dolphin/gx/GXLight.c"), Object(NonMatching, "dolphin/gx/GXTexture.c"), Object(NonMatching, "dolphin/gx/GXBump.c"), @@ -737,11 +751,11 @@ def MatchingFor(*versions): "os", [ Object(NonMatching, "dolphin/os/OS.c"), - Object(NonMatching, "dolphin/os/OSAlarm.c"), + Object(Matching, "dolphin/os/OSAlarm.c"), Object(Matching, "dolphin/os/OSAlloc.c"), Object(Matching, "dolphin/os/OSArena.c"), Object(Matching, "dolphin/os/OSAudioSystem.c"), - Object(NonMatching, "dolphin/os/OSCache.c"), + Object(Matching, "dolphin/os/OSCache.c"), Object(Matching, "dolphin/os/OSContext.c"), Object(NonMatching, "dolphin/os/OSError.c"), Object(NonMatching, "dolphin/os/OSFont.c"), @@ -750,11 +764,11 @@ def MatchingFor(*versions): Object(Matching, "dolphin/os/OSMemory.c"), Object(Matching, "dolphin/os/OSMutex.c"), Object(Matching, "dolphin/os/OSReboot.c"), - Object(NonMatching, "dolphin/os/OSReset.c"), + Object(Matching, "dolphin/os/OSReset.c"), Object(Matching, "dolphin/os/OSResetSW.c"), Object(NonMatching, "dolphin/os/OSRtc.c"), Object(NonMatching, "dolphin/os/OSThread.c"), - Object(NonMatching, "dolphin/os/OSTime.c"), + Object(Matching, "dolphin/os/OSTime.c"), Object(Matching, "dolphin/os/OSSync.c"), Object(NonMatching, "dolphin/os/init/__start.c"), Object(NonMatching, "dolphin/os/init/__ppc_eabi_init.cpp") @@ -777,7 +791,7 @@ def MatchingFor(*versions): DolphinLib( "vi", [ - Object(NonMatching, "dolphin/vi/vi.c"), + Object(Matching, "dolphin/vi/vi.c", extra_cflags=["-DMATCHING"]), ], ), mslLib( diff --git a/include/dolphin/os.h b/include/dolphin/os.h index b5952f99f..89da646e0 100644 --- a/include/dolphin/os.h +++ b/include/dolphin/os.h @@ -5,8 +5,7 @@ #include #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif // Upper words of the masks, since UIMM is only 16 bits @@ -23,26 +22,26 @@ extern "C" #define AT_ADDRESS #endif volatile int __OSTVMode AT_ADDRESS(OS_BASE_CACHED | 0xCC); -u32 __OSBusClock AT_ADDRESS(OS_BASE_CACHED | 0x00F8); // sync with OSLoMem.h +u32 __OSBusClock AT_ADDRESS(OS_BASE_CACHED | 0x00F8); // sync with OSLoMem.h u32 __OSCoreClock AT_ADDRESS(OS_BASE_CACHED | 0x00FC); // sync with OSLoMem.h #define OS_BUS_CLOCK (u32) __OSBusClock #define OS_CORE_CLOCK __OSCoreClock #define OS_TIMER_CLOCK (OS_BUS_CLOCK / 4) #ifndef _DEBUG -#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))) +#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))) #else -u32 OSPhysicalToCached(void *paddr); -u32 OSPhysicalToUncached(void *paddr); -u32 OSCachedToPhysical(void *caddr); -u32 OSUncachedToPhysical(void *ucaddr); -u32 OSCachedToUncached(void *caddr); -u32 OSUncachedToCached(void *ucaddr); +u32 OSPhysicalToCached(void* paddr); +u32 OSPhysicalToUncached(void* paddr); +u32 OSCachedToPhysical(void* caddr); +u32 OSUncachedToPhysical(void* ucaddr); +u32 OSCachedToUncached(void* caddr); +u32 OSUncachedToCached(void* ucaddr); #endif #define OSTicksToCycles(ticks) (((ticks) * ((OS_CORE_CLOCK * 2) / OS_TIMER_CLOCK)) / 2) @@ -60,13 +59,13 @@ u32 OSUncachedToCached(void *ucaddr); #define OSRoundUp32B(v) ((((u32)v + 31) & ~31)) #define OSRoundDown32B(v) (((u32)(v) & ~31)) -void *OSGetArenaHi(void); -void *OSGetArenaLo(void); -void OSSetArenaHi(void *newHi); -void OSSetArenaLo(void *newLo); +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); +void* OSAllocFromArenaLo(u32 size, u32 align); +void* OSAllocFromArenaHi(u32 size, u32 align); void OSInit(); @@ -122,7 +121,7 @@ void OSSetLanguage(u8 language); u32 OSGetEuRgb60Mode(void); void OSSetEuRgb60Mode(u32 on); -void OSRegisterVersion(const char *id); +void OSRegisterVersion(const char* id); BOOL OSDisableInterrupts(void); BOOL OSEnableInterrupts(void); @@ -145,7 +144,7 @@ BOOL OSRestoreInterrupts(BOOL level); #endif #ifndef ASSERTMSG -#if defined(__STDC_VERSION__) && (199901L <= __STDC_VERSION__) || defined(__MWERKS__) || \ +#if defined(__STDC_VERSION__) && (199901L <= __STDC_VERSION__) || defined(__MWERKS__) || \ defined(__SN__) #define ASSERTMSG(exp, ...) (void)((exp) || (OSPanic(__FILE__, __LINE__, __VA_ARGS__), 0)) #else @@ -154,23 +153,23 @@ BOOL OSRestoreInterrupts(BOOL level); #endif #ifndef ASSERTMSG1 -#define ASSERTMSG1(exp, msg, param1) \ - (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1)), 0)) +#define ASSERTMSG1(exp, msg, param1) \ + (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1)), 0)) #endif #ifndef ASSERTMSG2 -#define ASSERTMSG2(exp, msg, param1, param2) \ - (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1), (param2)), 0)) +#define ASSERTMSG2(exp, msg, param1, param2) \ + (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1), (param2)), 0)) #endif #ifndef ASSERTMSG3 -#define ASSERTMSG3(exp, msg, param1, param2, param3) \ - (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1), (param2), (param3)), 0)) +#define ASSERTMSG3(exp, msg, param1, param2, param3) \ + (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1), (param2), (param3)), 0)) #endif #ifndef ASSERTMSG4 -#define ASSERTMSG4(exp, msg, param1, param2, param3, param4) \ - (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1), (param2), (param3), (param4)), 0)) +#define ASSERTMSG4(exp, msg, param1, param2, param3, param4) \ + (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1), (param2), (param3), (param4)), 0)) #endif #else // _DEBUG @@ -180,7 +179,7 @@ BOOL OSRestoreInterrupts(BOOL level); #endif #ifndef ASSERTMSG -#if defined(__STDC_VERSION__) && (199901L <= __STDC_VERSION__) || defined(__MWERKS__) || \ +#if defined(__STDC_VERSION__) && (199901L <= __STDC_VERSION__) || defined(__MWERKS__) || \ defined(__SN__) #define ASSERTMSG(exp, ...) ((void)0) #else @@ -203,9 +202,9 @@ BOOL OSRestoreInterrupts(BOOL level); #endif // _DEBUG -void OSReport(const char *msg, ...); -void OSPanic(const char *file, int line, const char *msg, ...); -void OSFatal(GXColor fg, GXColor bg, const char *msg); +void OSReport(const char* msg, ...); +void OSPanic(const char* file, int line, const char* msg, ...); +void OSFatal(GXColor fg, GXColor bg, const char* msg); #define OSError(...) OSPanic(__FILE__, __LINE__, __VA_ARGS__) #ifndef MATCHING diff --git a/include/rwsdk/rpworld.h b/include/rwsdk/rpworld.h index d24736c5f..b621b4b25 100644 --- a/include/rwsdk/rpworld.h +++ b/include/rwsdk/rpworld.h @@ -1,7 +1,7 @@ #ifndef RPWORLD_H #define RPWORLD_H -#include "rwcore.h" +#include typedef struct RpLight; diff --git a/include/rwsdk/rtquat.h b/include/rwsdk/rtquat.h index f1e957574..ff402d361 100644 --- a/include/rwsdk/rtquat.h +++ b/include/rwsdk/rtquat.h @@ -1,12 +1,555 @@ #ifndef RTQUAT_H #define RTQUAT_H -#include "rwcore.h" +/** + * \defgroup rtquat RtQuat + * \ingroup mathtools + * + * Quaternion Toolkit for RenderWare. + * + * See also http://www.gamasutra.com/features/19980703/quaternions_01.htm + */ +/* + * See http://www-groups.dcs.st-and.ac.uk/~history/Mathematicians/Hamilton.html + * On 16 October 1843 (a Monday) Hamilton was walking in along the Royal + * Canal with his wife to preside at a Council meeting of the Royal Irish + * Academy. + * + * Although his wife talked to him now and again Hamilton hardly + * heard, for the discovery of the quaternions, the first noncommutative + * algebra to be studied, was taking shape in his mind:- + * + * "And here there dawned on me the notion that we must admit, in + * some sense, a fourth dimension of space for the purpose of calculating + * with triples ... An electric circuit seemed to close, and a spark + * flashed forth." + */ + +/**************************************************************************** + Includes + */ + +#include +/* renderware */ +//#include "rwplcore.h" + +//#include "rtquat.rpe" /* automatically generated header file */ + +#define RW_TOL_ORTHONORMAL ((RwReal)0.01) + +/**************************************************************************** + Global Types + */ + +typedef struct RtQuat RtQuat; +/** + * \ingroup rtquat + * \struct RtQuat + * A structure describing a Quaternion + * +*/ struct RtQuat { - RwV3d imag; - RwReal real; + RwV3d imag; /**< The imaginary part(s) */ + RwReal real; /**< The real part */ }; -#endif \ No newline at end of file +/**************************************************************************** + Defines + */ + +#define RtQuatInitMacro(result, _x, _y, _z, _w) \ + MACRO_START \ + { \ + (result)->real = (_w); \ + (result)->imag.x = (_x); \ + (result)->imag.y = (_y); \ + (result)->imag.z = (_z); \ + } \ + MACRO_STOP + +#if (!defined(RtQuatAssignMacro)) +#define RtQuatAssignMacro(_target, _source) (*(_target) = *(_source)) +#endif /* (!defined(RtQuatAssignMacro)) */ + +#define RtQuatAddMacro(result, q1, q2) \ + MACRO_START \ + { \ + (result)->real = (q1)->real + (q2)->real; \ + RwV3dAddMacro(&(result)->imag, &(q1)->imag, &(q2)->imag); \ + } \ + MACRO_STOP + +#define RtQuatIncrementRealPartMacro(result, s, q) \ + MACRO_START \ + { \ + (result)->real = (q)->real + s; \ + (result)->imag.x = (q)->imag.x; \ + (result)->imag.y = (q)->imag.y; \ + (result)->imag.z = (q)->imag.z; \ + } \ + MACRO_STOP + +#define RtQuatDecrementRealPartMacro(result, s, q) \ + MACRO_START \ + { \ + (result)->real = (q)->real - s; \ + (result)->imag.x = (q)->imag.x; \ + (result)->imag.y = (q)->imag.y; \ + (result)->imag.z = (q)->imag.z; \ + } \ + MACRO_STOP + +#define RtQuatIncrementMacro(result, dq) \ + MACRO_START \ + { \ + (result)->real = (result)->real + (dq)->real; \ + RwV3dAddMacro(&(result)->imag, &(result)->imag, &(dq)->imag); \ + } \ + MACRO_STOP + +#define RtQuatSubMacro(result, q1, q2) \ + MACRO_START \ + { \ + (result)->real = (q1)->real - (q2)->real; \ + RwV3dSubMacro(&(result)->imag, &(q1)->imag, &(q2)->imag); \ + } \ + MACRO_STOP + +#define RtQuatNegateMacro(result, q) \ + MACRO_START \ + { \ + (result)->real = -(q)->real; \ + (result)->imag.x = -(q)->imag.x; \ + (result)->imag.y = -(q)->imag.y; \ + (result)->imag.z = -(q)->imag.z; \ + } \ + MACRO_STOP + +#define RtQuatConjugateMacro(result, q) \ + MACRO_START \ + { \ + (result)->real = (q)->real; \ + (result)->imag.x = -(q)->imag.x; \ + (result)->imag.y = -(q)->imag.y; \ + (result)->imag.z = -(q)->imag.z; \ + } \ + MACRO_STOP + +#define RtQuatScaleMacro(result, q, scale) \ + MACRO_START \ + { \ + (result)->real = (q)->real * scale; \ + RwV3dScaleMacro(&(result)->imag, &(q)->imag, scale); \ + } \ + MACRO_STOP + +#define RtQuatModulusSquaredMacro(q) \ + ((q)->real * (q)->real + RwV3dDotProductMacro(&(q)->imag, &(q)->imag)) + +#define RtQuatModulusMacro(result, q) \ + MACRO_START \ + { \ + (result) = RtQuatModulusSquaredMacro(q); \ + rwSqrtMacro(&result, result); \ + } \ + MACRO_STOP + +#define RtQuatMultiplyMacro(result, q1, q2) \ + MACRO_START \ + { \ + /* \ + * Assumes q1 != result != q2 \ + */ \ + (result)->real = (q1)->real * (q2)->real - RwV3dDotProductMacro(&(q1)->imag, &(q2)->imag); \ + RwV3dCrossProductMacro(&(result)->imag, &(q1)->imag, &(q2)->imag); \ + RwV3dIncrementScaledMacro(&(result)->imag, &(q2)->imag, (q1)->real); \ + RwV3dIncrementScaledMacro(&(result)->imag, &(q1)->imag, (q2)->real); \ + } \ + MACRO_STOP + +#define RtQuatReciprocalMacro(result, q) \ + MACRO_START \ + { \ + /* \ + * Assumes result != q \ + */ \ + RwReal val = RtQuatModulusSquaredMacro(q); \ + \ + if (val > (RwReal)0) \ + { \ + val = ((RwReal)1) / val; \ + (result)->real = (q)->real * val; \ + val = -val; \ + RwV3dScaleMacro(&(result)->imag, &(q)->imag, val); \ + } \ + } \ + MACRO_STOP + +#define RtQuatSquareMacro(result, q) \ + MACRO_START \ + { \ + /* \ + * Assumes result != q \ + */ \ + RwReal val = ((RwReal)2) * (q)->real; \ + \ + (result)->real = (q)->real * (q)->real - RwV3dDotProductMacro(&(q)->imag, &(q)->imag); \ + RwV3dScaleMacro(&(result)->imag, &(q)->imag, val); \ + } \ + MACRO_STOP + +#define RtQuatSquareRootMacro(result, q) \ + MACRO_START \ + { \ + /* \ + * Assumes result != q \ + * other root is of course -result \ + */ \ + RwReal val; \ + \ + RtQuatModulusMacro(val, q); \ + val = ((q)->real + val) * ((RwReal)0.5); \ + \ + if (val > ((RwReal)0)) \ + { \ + rwSqrtMacro(&val, val); \ + (result)->real = val; \ + val = ((RwReal)0.5) / val; \ + RwV3dScale(&(result)->imag, &(q)->imag, val); \ + } \ + else \ + { \ + result->imag.x = -(q)->real; \ + rwSqrtMacro(&(result->imag.x), result->imag.x); \ + result->imag.y = ((RwReal)0); \ + result->imag.x = ((RwReal)0); \ + result->real = ((RwReal)0); \ + } \ + } \ + MACRO_STOP + +#define RtQuatLogMacro(result, q) \ + MACRO_START \ + { \ + /* \ + * Assumes result != q \ + */ \ + const RwReal mod2 = RtQuatModulusSquaredMacro(q); \ + RwReal sin_b; \ + RwReal radians; \ + RwReal factor; \ + \ + sin_b = RwV3dDotProduct(&(q)->imag, &(q)->imag); \ + rwSqrtMacro(&sin_b, sin_b); \ + radians = (RwReal)RwATan2(sin_b, (q)->real); \ + factor = (sin_b > (RwReal)0) ? (((RwReal)radians) / sin_b) : 0; \ + \ + RwV3dScaleMacro(&(result)->imag, &(q)->imag, factor); \ + (result)->real = ((RwReal)RwLog(mod2)) * ((RwReal)0.5); \ + } \ + MACRO_STOP + +#define RtQuatExpMacro(result, q) \ + MACRO_START \ + { \ + /* \ + * Assumes result != q \ + */ \ + const RwReal exp_a = (RwReal)RwExp((q)->real); \ + RwReal mod_b; \ + RwReal factor; \ + \ + mod_b = RwV3dDotProduct(&(q)->imag, &(q)->imag); \ + rwSqrtMacro(&mod_b, mod_b); \ + factor = ((mod_b > (RwReal)0) ? (exp_a * ((RwReal)RwSin(mod_b)) / mod_b) : 0); \ + \ + RwV3dScaleMacro(&(result)->imag, &(q)->imag, factor); \ + (result)->real = exp_a * (RwReal)RwCos(mod_b); \ + } \ + MACRO_STOP + +#define RtQuatPowMacro(result, q, e) \ + MACRO_START \ + { \ + RtQuat qLog; \ + \ + RtQuatLogMacro(&qLog, q); \ + RtQuatScaleMacro(&qLog, &qLog, e); \ + RtQuatExpMacro(result, &qLog); \ + } \ + MACRO_STOP + +#define RtQuatUnitLogMacro(result, q) \ + MACRO_START \ + { \ + /* \ + * Assumes result != q \ + */ \ + RwReal sin_b; \ + RwReal radians; \ + RwReal factor; \ + \ + sin_b = RwV3dDotProduct(&(q)->imag, &(q)->imag); \ + rwSqrtMacro(&sin_b, sin_b); \ + radians = (RwReal)RwATan2(sin_b, (q)->real); \ + factor = (sin_b > (RwReal)0) ? (((RwReal)radians) / sin_b) : 0; \ + \ + RwV3dScaleMacro(&(result)->imag, &(q)->imag, factor); \ + (result)->real = (RwReal)0; \ + } \ + MACRO_STOP + +#define RtQuatUnitExpMacro(result, q) \ + MACRO_START \ + { \ + /* \ + * Assumes result != q \ + */ \ + RwReal mod_b; \ + RwReal factor; \ + \ + mod_b = RwV3dDotProduct(&(q)->imag, &(q)->imag); \ + rwSqrtMacro(&mod_b, mod_b); \ + factor = (mod_b > (RwReal)0) ? (((RwReal)RwSin(mod_b)) / mod_b) : 0; \ + \ + RwV3dScaleMacro(&(result)->imag, &(q)->imag, factor); \ + (result)->real = (RwReal)RwCos(mod_b); \ + } \ + MACRO_STOP + +#define RtQuatUnitPowMacro(result, q, e) \ + MACRO_START \ + { \ + RtQuat qLog; \ + \ + RtQuatUnitLogMacro(&qLog, q); \ + RwV3dScaleMacro(&qLog.imag, &qLog.imag, e); \ + RtQuatUnitExpMacro(result, &qLog); \ + } \ + MACRO_STOP + +#define RtQuatConvertToMatrixMacro(qpQuat, mpMatrix) \ + MACRO_START \ + { \ + RwReal rS; \ + RwV3d rV; \ + RwV3d rW; \ + RwV3d square; \ + RwV3d cross; \ + \ + rS = ((RwReal)2) / RtQuatModulusSquaredMacro((qpQuat)); \ + \ + RwV3dScale(&rV, &(qpQuat)->imag, rS); \ + RwV3dScale(&rW, &rV, (qpQuat)->real); \ + \ + square.x = (qpQuat)->imag.x * rV.x; \ + square.y = (qpQuat)->imag.y * rV.y; \ + square.z = (qpQuat)->imag.z * rV.z; \ + \ + cross.x = (qpQuat)->imag.y * rV.z; \ + cross.y = (qpQuat)->imag.z * rV.x; \ + cross.z = (qpQuat)->imag.x * rV.y; \ + \ + (mpMatrix)->right.x = ((RwReal)1) - (square.y + square.z); \ + (mpMatrix)->right.y = cross.z + rW.z; \ + (mpMatrix)->right.z = cross.y - rW.y; \ + \ + (mpMatrix)->up.x = cross.z - rW.z; \ + (mpMatrix)->up.y = ((RwReal)1) - (square.z + square.x); \ + (mpMatrix)->up.z = cross.x + rW.x; \ + \ + (mpMatrix)->at.x = cross.y + rW.y; \ + (mpMatrix)->at.y = cross.x - rW.x; \ + (mpMatrix)->at.z = ((RwReal)1) - (square.x + square.y); \ + \ + /* Set position */ \ + (mpMatrix)->pos.x = ((RwReal)0); \ + (mpMatrix)->pos.y = ((RwReal)0); \ + (mpMatrix)->pos.z = ((RwReal)0); \ + \ + /* Matrix is orthogonal */ \ + rwMatrixSetFlags((mpMatrix), (rwMATRIXTYPEORTHONORMAL & ~rwMATRIXINTERNALIDENTITY)); \ + } \ + MACRO_STOP + +#define RtQuatUnitConvertToMatrixMacro(qpQuat, mpMatrix) \ + MACRO_START \ + { \ + const RwReal x = (qpQuat)->imag.x; \ + const RwReal y = (qpQuat)->imag.y; \ + const RwReal z = (qpQuat)->imag.z; \ + const RwReal w = (qpQuat)->real; \ + RwV3d square; \ + RwV3d cross; \ + RwV3d wimag; \ + \ + square.x = x * x; \ + square.y = y * y; \ + square.z = z * z; \ + \ + cross.x = y * z; \ + cross.y = z * x; \ + cross.z = x * y; \ + \ + wimag.x = w * x; \ + wimag.y = w * y; \ + wimag.z = w * z; \ + \ + (mpMatrix)->right.x = 1 - 2 * (square.y + square.z); \ + (mpMatrix)->right.y = 2 * (cross.z + wimag.z); \ + (mpMatrix)->right.z = 2 * (cross.y - wimag.y); \ + \ + (mpMatrix)->up.x = 2 * (cross.z - wimag.z); \ + (mpMatrix)->up.y = 1 - 2 * (square.x + square.z); \ + (mpMatrix)->up.z = 2 * (cross.x + wimag.x); \ + \ + (mpMatrix)->at.x = 2 * (cross.y + wimag.y); \ + (mpMatrix)->at.y = 2 * (cross.x - wimag.x); \ + (mpMatrix)->at.z = (1 - 2 * (square.x + square.y)); \ + \ + /* Set position */ \ + (mpMatrix)->pos.x = ((RwReal)0); \ + (mpMatrix)->pos.y = ((RwReal)0); \ + (mpMatrix)->pos.z = ((RwReal)0); \ + \ + /* Matrix is orthonormal */ \ + rwMatrixSetFlags((mpMatrix), (rwMATRIXTYPEORTHONORMAL & ~rwMATRIXINTERNALIDENTITY)); \ + } \ + MACRO_STOP + +#if (!(defined(RWDEBUG) || defined(RWSUPPRESSINLINE))) + +#define RtQuatInit(result, _x, _y, _z, _w) RtQuatInitMacro(result, _x, _y, _z, _w) + +#define RtQuatAssign(to, from) RtQuatAssignMacro(to, from) + +#define RtQuatAdd(result, q1, q2) RtQuatAddMacro(result, q1, q2) + +#define RtQuatIncrementRealPart(result, s, q) RtQuatIncrementRealPartMacro(result, s, q) + +#define RtQuatDecrementRealPart(result, s, q) RtQuatDecrementRealPartMacro(result, s, q) + +#define RtQuatIncrement(result, dq) RtQuatIncrementMacro(result, dq) + +#define RtQuatSub(result, q1, q2) RtQuatSubMacro(result, q1, q2) + +#define RtQuatNegate(result, q) RtQuatNegateMacro(result, q) + +#define RtQuatConjugate(result, q) RtQuatConjugateMacro(result, q) + +#define RtQuatScale(result, q, scale) RtQuatScaleMacro(result, q, scale) + +#define RtQuatModulusSquared(q) RtQuatModulusSquaredMacro(q) + +#define RtQuatMultiply(result, q1, q2) RtQuatMultiplyMacro(result, q1, q2) + +#define RtQuatReciprocal(result, q) RtQuatReciprocalMacro(result, q) + +#define RtQuatSquare(result, q) RtQuatSquareMacro(result, q) + +#define RtQuatSquareRoot(result, q) RtQuatSquareRootMacro(result, q) + +#define RtQuatLog(result, q) RtQuatLogMacro(result, q) + +#define RtQuatExp(result, q) RtQuatExpMacro(result, q) + +#define RtQuatPow(result, q, e) RtQuatPowMacro(result, q, e) + +#define RtQuatUnitLog(result, q) RtQuatUnitLogMacro(result, q) + +#define RtQuatUnitExp(result, q) RtQuatUnitExpMacro(result, q) + +#define RtQuatUnitPow(result, q, e) RtQuatUnitPowMacro(result, q, e) + +#define RtQuatConvertToMatrix(qpQuat, mpMatrix) RtQuatConvertToMatrixMacro(qpQuat, mpMatrix) + +#define RtQuatUnitConvertToMatrix(qpQuat, mpMatrix) RtQuatUnitConvertToMatrixMacro(qpQuat, mpMatrix) + +#endif /* (! ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) )) */ + +/**************************************************************************** + Function prototypes + */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +extern RwBool RtQuatConvertFromMatrix(RtQuat* const qpQuat, const RwMatrix* const mpMatrix); + +extern RtQuat* RtQuatRotate(RtQuat* quat, const RwV3d* axis, RwReal angle, + RwOpCombineType combineOp); + +extern const RtQuat* RtQuatQueryRotate(const RtQuat* quat, RwV3d* unitAxis, RwReal* angle); + +extern RwV3d* RtQuatTransformVectors(RwV3d* vectorsOut, const RwV3d* vectorsIn, + const RwInt32 numPoints, const RtQuat* quat); + +extern RwReal RtQuatModulus(RtQuat* q); + +#if (defined(RWDEBUG) || defined(RWSUPPRESSINLINE)) + +extern void RtQuatInit(RtQuat* result, RwReal x, RwReal y, RwReal z, RwReal w); + +extern void RtQuatAssign(RtQuat* to, RtQuat* from); + +extern void RtQuatAdd(RtQuat* result, RtQuat* q1, RtQuat* q2); + +extern void RtQuatIncrementRealPart(RtQuat* result, RwReal s, RtQuat* q); + +extern void RtQuatDecrementRealPart(RtQuat* result, RwReal s, RtQuat* q); + +extern void RtQuatIncrement(RtQuat* result, RtQuat* dq); + +extern void RtQuatSub(RtQuat* result, RtQuat* q1, RtQuat* q2); + +extern void RtQuatNegate(RtQuat* result, RtQuat* q); + +extern void RtQuatConjugate(RtQuat* result, RtQuat* q); + +extern void RtQuatScale(RtQuat* result, RtQuat* q, RwReal scale); + +extern RwReal RtQuatModulusSquared(RtQuat* q); + +extern void RtQuatMultiply(RtQuat* result, RtQuat* q1, RtQuat* q2); + +extern void RtQuatReciprocal(RtQuat* result, RtQuat* q); + +extern void RtQuatSquare(RtQuat* result, RtQuat* q); + +extern void RtQuatSquareRoot(RtQuat* result, RtQuat* q); + +extern void RtQuatLog(RtQuat* result, RtQuat* q); + +extern void RtQuatExp(RtQuat* result, RtQuat* q); + +extern void RtQuatPow(RtQuat* result, RtQuat* q, RwReal e); + +extern void RtQuatUnitLog(RtQuat* result, RtQuat* q); + +extern void RtQuatUnitExp(RtQuat* result, RtQuat* q); + +extern void RtQuatUnitPow(RtQuat* result, RtQuat* q, RwReal e); + +extern void RtQuatConvertToMatrix(const RtQuat* const qpQuat, RwMatrix* const mpMatrix); + +extern void RtQuatUnitConvertToMatrix(const RtQuat* const qpQuat, RwMatrix* const mpMatrix); + +#endif /* ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) ) */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/* + * Backwards compatibility code + */ + +typedef RtQuat RpQuat; + +#define RpAnimQuatConvertFromMatrix(qpQuat, mpMatrix) RtQuatConvertFromMatrix(qpQuat, mpMatrix) + +#define RpAnimQuatConvertToMatrix(qpQuat, mpMatrix) RtQuatUnitConvertToMatrix(qpQuat, mpMatrix) + +#endif /* RTQUAT_H */ diff --git a/include/rwsdk/rtslerp.h b/include/rwsdk/rtslerp.h index e34d76568..616923ae5 100644 --- a/include/rwsdk/rtslerp.h +++ b/include/rwsdk/rtslerp.h @@ -1,68 +1,69 @@ #ifndef RTSLERP_H #define RTSLERP_H -#include "rwcore.h" -#include "rtquat.h" +//#include +//#include +//#include "rtslerp.h" -struct RtQuatSlerpCache -{ - RtQuat raFrom; - RtQuat raTo; - RwReal omega; - RwBool nearlyZeroOm; -}; +// struct RtQuatSlerpCache +// { +// RtQuat raFrom; +// RtQuat raTo; +// RwReal omega; +// RwBool nearlyZeroOm; +// }; -#define RtQuatSlerpMacro(qpResult, qpFrom, qpTo, rT, sCache) \ - MACRO_START \ - { \ - if ((rT) <= ((RwReal)0)) \ - { \ - /* t is before start */ \ - *(qpResult) = *(qpFrom); \ - } \ - else if (((RwReal)1) <= (rT)) \ - { \ - /* t is after end */ \ - *(qpResult) = *(qpTo); \ - } \ - else \ - { \ - /* ... so t must be in the interior then */ \ - /* Calc coefficients rSclFrom, rSclTo */ \ - RwReal rSclFrom = ((RwReal)1) - (rT); \ - RwReal rSclTo = (rT); \ - \ - if (!((sCache)->nearlyZeroOm)) \ - { \ - /* Standard case: slerp */ \ - /* SLERPMESSAGE(("Neither nearly ZERO nor nearly PI")); */ \ - \ - rSclFrom *= (sCache)->omega; \ - RwSinMinusPiToPiMacro(rSclFrom, rSclFrom); \ - rSclTo *= (sCache)->omega; \ - RwSinMinusPiToPiMacro(rSclTo, rSclTo); \ - } \ - \ - /* Calc final values */ \ - RwV3dScaleMacro(&(qpResult)->imag, &(sCache)->raFrom.imag, rSclFrom); \ - RwV3dIncrementScaledMacro(&(qpResult)->imag, &(sCache)->raTo.imag, rSclTo); \ - (qpResult)->real = \ - ((sCache)->raFrom.real * rSclFrom) + ((sCache)->raTo.real * rSclTo); \ - } \ - } \ - MACRO_STOP +// #define RtQuatSlerpMacro(qpResult, qpFrom, qpTo, rT, sCache) \ +// MACRO_START \ +// { \ +// if ((rT) <= ((RwReal)0)) \ +// { \ +// /* t is before start */ \ +// *(qpResult) = *(qpFrom); \ +// } \ +// else if (((RwReal)1) <= (rT)) \ +// { \ +// /* t is after end */ \ +// *(qpResult) = *(qpTo); \ +// } \ +// else \ +// { \ +// /* ... so t must be in the interior then */ \ +// /* Calc coefficients rSclFrom, rSclTo */ \ +// RwReal rSclFrom = ((RwReal)1) - (rT); \ +// RwReal rSclTo = (rT); \ +// \ +// if (!((sCache)->nearlyZeroOm)) \ +// { \ +// /* Standard case: slerp */ \ +// /* SLERPMESSAGE(("Neither nearly ZERO nor nearly PI")); */ \ +// \ +// rSclFrom *= (sCache)->omega; \ +// RwSinMinusPiToPiMacro(rSclFrom, rSclFrom); \ +// rSclTo *= (sCache)->omega; \ +// RwSinMinusPiToPiMacro(rSclTo, rSclTo); \ +// } \ +// \ +// /* Calc final values */ \ +// RwV3dScaleMacro(&(qpResult)->imag, &(sCache)->raFrom.imag, rSclFrom); \ +// RwV3dIncrementScaledMacro(&(qpResult)->imag, &(sCache)->raTo.imag, rSclTo); \ +// (qpResult)->real = \ +// ((sCache)->raFrom.real * rSclFrom) + ((sCache)->raTo.real * rSclTo); \ +// } \ +// } \ +// MACRO_STOP -#define RtQuatSlerp(qpResult, qpFrom, qpTo, rT, sCache) \ - RtQuatSlerpMacro(qpResult, qpFrom, qpTo, rT, sCache) +// #define RtQuatSlerp(qpResult, qpFrom, qpTo, rT, sCache) \ +// RtQuatSlerpMacro(qpResult, qpFrom, qpTo, rT, sCache) -#ifdef __cplusplus -extern "C" { -#endif +// #ifdef __cplusplus +// extern "C" { +// #endif -extern void RtQuatSetupSlerpCache(RtQuat* qpFrom, RtQuat* qpTo, RtQuatSlerpCache* sCache); +// extern void RtQuatSetupSlerpCache(RtQuat* qpFrom, RtQuat* qpTo, RtQuatSlerpCache* sCache); -#ifdef __cplusplus -} -#endif +// #ifdef __cplusplus +// } +// #endif #endif \ No newline at end of file diff --git a/include/rwsdk/rwcore.h b/include/rwsdk/rwcore.h index c35c9e823..311d8bfc1 100644 --- a/include/rwsdk/rwcore.h +++ b/include/rwsdk/rwcore.h @@ -1,7 +1,7 @@ #ifndef RWCORE_H #define RWCORE_H -#include "rwplcore.h" +#include typedef struct _RxObjSpace3DVertex RxObjSpace3DVertex; diff --git a/include/rwsdk/rwplcore.h b/include/rwsdk/rwplcore.h index 6e3b7a5a0..80c5eba6d 100644 --- a/include/rwsdk/rwplcore.h +++ b/include/rwsdk/rwplcore.h @@ -2,13 +2,14 @@ #define RWPLCORE_H #include -//#include +#include #define rwBIGENDIAN typedef long RwFixed; typedef int RwInt32; typedef unsigned int RwUInt32; + typedef short RwInt16; typedef unsigned short RwUInt16; typedef unsigned char RwUInt8; diff --git a/libs/dolphin/ar/ar.c b/libs/dolphin/ar/ar.c index c3ed78946..f1b0a0b03 100644 --- a/libs/dolphin/ar/ar.c +++ b/libs/dolphin/ar/ar.c @@ -145,7 +145,7 @@ static void __ARHandler(__OSInterrupt interrupt, OSContext* context) #define RoundUP32(x) (((u32)(x) + 32 - 1) & ~(32 - 1)) -static void __ARWriteDMA(u32 mmem_addr, u32 aram_addr, u32 length) +inline void __ARWriteDMA(u32 mmem_addr, u32 aram_addr, u32 length) { u16 tmp; __DSPRegs[16] = (u16)((__DSPRegs[16] & ~0x03ff) | (u16)(mmem_addr >> 16)); @@ -168,7 +168,7 @@ static void __ARWriteDMA(u32 mmem_addr, u32 aram_addr, u32 length) __DSPRegs[5] = tmp; } -static void __ARReadDMA(u32 mmem_addr, u32 aram_addr, u32 length) +inline void __ARReadDMA(u32 mmem_addr, u32 aram_addr, u32 length) { u16 tmp; __DSPRegs[16] = (u16)((__DSPRegs[16] & ~0x03ff) | (u16)(mmem_addr >> 16)); diff --git a/libs/dolphin/exi/EXIBios.c b/libs/dolphin/exi/EXIBios.c index 3b50ca02d..0e34b6154 100644 --- a/libs/dolphin/exi/EXIBios.c +++ b/libs/dolphin/exi/EXIBios.c @@ -89,7 +89,7 @@ static void SetExiInterruptMask(s32 chan, EXIControl* exi) } } -static void CompleteTransfer(s32 chan) +inline void CompleteTransfer(s32 chan) { EXIControl* exi = &Ecb[chan]; u8* buf; @@ -366,7 +366,7 @@ s32 EXIProbeEx(s32 chan) } } -static BOOL __EXIAttach(s32 chan, EXICallback extCallback) +inline BOOL __EXIAttach(s32 chan, EXICallback extCallback) { EXIControl* exi = &Ecb[chan]; BOOL enabled; diff --git a/libs/dolphin/gx/GXFrameBuf.c b/libs/dolphin/gx/GXFrameBuf.c index b6a32d569..a4a41105a 100644 --- a/libs/dolphin/gx/GXFrameBuf.c +++ b/libs/dolphin/gx/GXFrameBuf.c @@ -176,7 +176,7 @@ void GXSetCopyClamp(GXFBClamp clamp) SET_REG_FIELD(1439, __GXData->cpTex, 1, 1, clmpB); } -static u32 __GXGetNumXfbLines(u32 efbHt, u32 iScale) +inline u32 __GXGetNumXfbLines(u32 efbHt, u32 iScale) { u32 count; u32 realHt; diff --git a/libs/dolphin/gx/GXMisc.c b/libs/dolphin/gx/GXMisc.c index e3c11f1c5..2337ed9bc 100644 --- a/libs/dolphin/gx/GXMisc.c +++ b/libs/dolphin/gx/GXMisc.c @@ -62,7 +62,7 @@ void GXFlush(void) PPCSync(); } -static void __GXAbortWait(u32 clocks) +inline void __GXAbortWait(u32 clocks) { OSTime time0; OSTime time1; @@ -74,7 +74,7 @@ static void __GXAbortWait(u32 clocks) } while (time1 - time0 <= (clocks / 4)); } -static void __GXAbortWaitPECopyDone(void) +inline void __GXAbortWaitPECopyDone(void) { u32 peCnt0; u32 peCnt1; @@ -126,7 +126,7 @@ u16 GXReadDrawSync(void) return token; } -void GXSetDrawDone(void) +inline void GXSetDrawDone(void) { u32 reg; BOOL enabled; @@ -140,7 +140,7 @@ void GXSetDrawDone(void) OSRestoreInterrupts(enabled); } -void GXWaitDrawDone(void) +inline void GXWaitDrawDone(void) { BOOL enabled; diff --git a/libs/dolphin/os/OSAlarm.c b/libs/dolphin/os/OSAlarm.c index 46eeff622..ae99ea535 100644 --- a/libs/dolphin/os/OSAlarm.c +++ b/libs/dolphin/os/OSAlarm.c @@ -11,7 +11,7 @@ static struct OSAlarmQueue static void DecrementerExceptionHandler(__OSException exception, OSContext* context); static BOOL OnReset(BOOL final); -static void SetTimer(OSAlarm* alarm) +inline void SetTimer(OSAlarm* alarm) { OSTime delta; diff --git a/libs/dolphin/os/OSCache.c b/libs/dolphin/os/OSCache.c index 11ba9094f..c38d0a402 100644 --- a/libs/dolphin/os/OSCache.c +++ b/libs/dolphin/os/OSCache.c @@ -152,7 +152,7 @@ asm void LCDisable() { /* clang-format off */ /* clang-format on */ -static void L2Disable(void) +inline void L2Disable(void) { __sync(); PPCMtl2cr(PPCMfl2cr() & ~0x80000000); @@ -172,7 +172,7 @@ void L2GlobalInvalidate(void) } } -static void L2Init(void) +inline void L2Init(void) { u32 oldMSR; oldMSR = PPCMfmsr(); diff --git a/libs/dolphin/os/OSError.c b/libs/dolphin/os/OSError.c index 13c76acce..dfb4ae31c 100644 --- a/libs/dolphin/os/OSError.c +++ b/libs/dolphin/os/OSError.c @@ -20,7 +20,7 @@ __declspec(weak) void OSReport(const char* msg, ...) va_end(args); } -__declspec(weak) void OSVReport(const char* msg, va_list list) +__declspec(weak) static void OSVReport(const char* msg, va_list list) { vprintf(msg, list); } diff --git a/libs/dolphin/os/OSReset.c b/libs/dolphin/os/OSReset.c index 8a9a2bd34..2b87ffd2a 100644 --- a/libs/dolphin/os/OSReset.c +++ b/libs/dolphin/os/OSReset.c @@ -66,7 +66,7 @@ void OSRegisterResetFunction(OSResetFunctionInfo* func) tmp->next = func; } -BOOL __OSCallResetFunctions(u32 arg0) +inline BOOL __OSCallResetFunctions(u32 arg0) { OSResetFunctionInfo* info; s32 err = 0; @@ -129,7 +129,7 @@ asm void Reset(register s32 resetCode) OSThreadQueue __OSActiveThreadQueue : (OS_BASE_CACHED | 0x00DC); -static void KillThreads(void) +inline void KillThreads(void) { OSThread* thread; OSThread* next; diff --git a/libs/dolphin/os/OSTime.c b/libs/dolphin/os/OSTime.c index 7f893c0a5..33e58ad71 100644 --- a/libs/dolphin/os/OSTime.c +++ b/libs/dolphin/os/OSTime.c @@ -65,17 +65,17 @@ OSTime __OSTimeToSystemTime(OSTime time) return result; } -static BOOL IsLeapYear(s32 year) +inline BOOL IsLeapYear(s32 year) { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); } -static s32 GetYearDays(s32 year, s32 mon) +inline s32 GetYearDays(s32 year, s32 mon) { return (IsLeapYear(year) ? LeapYearDays : YearDays)[mon]; } -static s32 GetLeapDays(s32 year) +inline s32 GetLeapDays(s32 year) { if (year < 1) { diff --git a/libs/dolphin/pad/Padclamp.c b/libs/dolphin/pad/Padclamp.c index e6165d56a..2b6de379c 100644 --- a/libs/dolphin/pad/Padclamp.c +++ b/libs/dolphin/pad/Padclamp.c @@ -96,7 +96,7 @@ static void ClampStick(s8* px, s8* py, s8 max, s8 xy, s8 min) *py = (s8)(signY * y); } -static void ClampTrigger(u8* trigger, u8 min, u8 max) +inline void ClampTrigger(u8* trigger, u8 min, u8 max) { if (*trigger <= min) { diff --git a/libs/dolphin/vi/vi.c b/libs/dolphin/vi/vi.c index 61ed43d58..9d47b7d89 100644 --- a/libs/dolphin/vi/vi.c +++ b/libs/dolphin/vi/vi.c @@ -6,9 +6,9 @@ #include // Useful macros. -#define IS_LOWER_16MB(x) ((x) < 16 * 1024 * 1024) -#define ToPhysical(fb) (u32)(((u32)(fb)) & 0x3FFFFFFF) -#define ONES(x) ((1 << (x)) - 1) +#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))) const char* __VIVersion = "<< Dolphin SDK - VI\trelease build: Apr 17 2003 12:33:22 (0x2301) >>"; @@ -78,47 +78,46 @@ static VITimingInfo timing[10] = { }; // clang-format on -static u16 taps[25] = { 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 }; +static u16 taps[25] = { 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 }; // forward declaring statics static u32 getCurrentFieldEvenOdd(); -static void getEncoderType(void) -{ - // UNUSED FUNCTION -} - -static int cntlzd(u64 bit) +inline int cntlzd(u64 bit) { u32 hi, lo; int value; - hi = (u32)(bit >> 32); - lo = (u32)(bit & 0xFFFFFFFF); + hi = (u32)(bit >> 32); + lo = (u32)(bit & 0xFFFFFFFF); value = __cntlzw(hi); - if (value < 32) { + if (value < 32) + { return value; } return (32 + __cntlzw(lo)); } -static BOOL VISetRegs(void) +inline BOOL VISetRegs(void) { int regIndex; - if (!((shdwChangeMode == 1) && (getCurrentFieldEvenOdd() == 0))) { - while (shdwChanged) { - regIndex = cntlzd(shdwChanged); + if (!((shdwChangeMode == 1) && (getCurrentFieldEvenOdd() == 0))) + { + while (shdwChanged) + { + regIndex = cntlzd(shdwChanged); __VIRegs[regIndex] = shdwRegs[regIndex]; shdwChanged &= ~(VI_BITMASK(regIndex)); } shdwChangeMode = 0; - CurrTiming = HorVer.timing; - CurrTvMode = HorVer.tv; - CurrBufAddr = NextBufAddr; + CurrTiming = HorVer.timing; + CurrTvMode = HorVer.tv; + CurrBufAddr = NextBufAddr; return TRUE; } @@ -132,33 +131,39 @@ static void __VIRetraceHandler(__OSInterrupt interrupt, OSContext* context) u32 inter = 0; viReg = __VIRegs[VI_DISP_INT_0]; - if (viReg & 0x8000) { + if (viReg & 0x8000) + { __VIRegs[VI_DISP_INT_0] = (u16)(viReg & ~0x8000); inter |= 1; } viReg = __VIRegs[VI_DISP_INT_1]; - if (viReg & 0x8000) { + if (viReg & 0x8000) + { __VIRegs[VI_DISP_INT_1] = (u16)(viReg & ~0x8000); inter |= 2; } viReg = __VIRegs[VI_DISP_INT_2]; - if (viReg & 0x8000) { + if (viReg & 0x8000) + { __VIRegs[VI_DISP_INT_2] = (u16)(viReg & ~0x8000); inter |= 4; } viReg = __VIRegs[VI_DISP_INT_3]; - if (viReg & 0x8000) { + if (viReg & 0x8000) + { __VIRegs[VI_DISP_INT_3] = (u16)(viReg & ~0x8000); inter |= 8; } - if ((inter & 4) || (inter & 8)) { + if ((inter & 4) || (inter & 8)) + { OSClearContext(&exceptionContext); OSSetCurrentContext(&exceptionContext); - if (PositionCallback) { + if (PositionCallback) + { s16 x, y; __VIGetCurrentPosition(&x, &y); (*PositionCallback)(x, y); @@ -172,18 +177,22 @@ static void __VIRetraceHandler(__OSInterrupt interrupt, OSContext* context) OSClearContext(&exceptionContext); OSSetCurrentContext(&exceptionContext); - if (PreCB) { + if (PreCB) + { (*PreCB)(retraceCount); } - if (flushFlag) { - if (VISetRegs()) { + if (flushFlag) + { + if (VISetRegs()) + { flushFlag = 0; SIRefreshSamplingRate(); } } - if (PostCB) { + if (PostCB) + { OSClearContext(&exceptionContext); (*PostCB)(retraceCount); } @@ -201,7 +210,7 @@ VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback callback) oldCallback = PreCB; interrupt = OSDisableInterrupts(); - PreCB = callback; + PreCB = callback; OSRestoreInterrupts(interrupt); return oldCallback; @@ -215,7 +224,7 @@ VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback callback) oldCallback = PostCB; interrupt = OSDisableInterrupts(); - PostCB = callback; + PostCB = callback; OSRestoreInterrupts(interrupt); return oldCallback; @@ -223,7 +232,8 @@ VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback callback) static VITimingInfo* getTiming(VITVMode mode) { - switch (mode) { + switch (mode) + { case VI_TVMODE_NTSC_INT: return &timing[0]; case VI_TVMODE_NTSC_DS: @@ -273,14 +283,15 @@ void __VIInit(VITVMode mode) u16 hct, vct; nonInter = mode & 2; - tv = (u32)mode >> 2; + tv = (u32)mode >> 2; *(u32*)OSPhysicalToCached(0xCC) = tv; tm = getTiming(mode); __VIRegs[VI_DISP_CONFIG] = 2; - for (a = 0; a < 1000; a++) { + for (a = 0; a < 1000; a++) + { ; } @@ -295,58 +306,71 @@ void __VIInit(VITVMode mode) __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_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_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_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_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); + __VIRegs[VI_DISP_INT_1] = (1 << 0) | (1 << 12) | (0 << 15); - hct = (tm->hlw + 1); - vct = (tm->numHalfLines / 2 + 1) | (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; - - if (mode != VI_TVMODE_NTSC_PROG && mode != VI_TVMODE_NTSC_3D && mode != VI_TVMODE_GCA_PROG) { - __VIRegs[VI_DISP_CONFIG] = (1 << 0) | (0 << 1) | (nonInter << 2) | (0 << 3) | (0 << 4) | (0 << 6) | (tv << 8); - __VIRegs[VI_CLOCK_SEL] = 0; + __VIRegs[VI_DISP_INT_0] = vct; - } else { - __VIRegs[VI_DISP_CONFIG] = (1 << 0) | (0 << 1) | (1 << 2) | (0 << 3) | (0 << 4) | (0 << 6) | (tv << 8); - __VIRegs[VI_CLOCK_SEL] = 1; + if (mode != VI_TVMODE_NTSC_PROG && mode != VI_TVMODE_NTSC_3D && mode != VI_TVMODE_GCA_PROG) + { + __VIRegs[VI_DISP_CONFIG] = + (1 << 0) | (0 << 1) | (nonInter << 2) | (0 << 3) | (0 << 4) | (0 << 6) | (tv << 8); + __VIRegs[VI_CLOCK_SEL] = 0; + } + else + { + __VIRegs[VI_DISP_CONFIG] = + (1 << 0) | (0 << 1) | (1 << 2) | (0 << 3) | (0 << 4) | (0 << 6) | (tv << 8); + __VIRegs[VI_CLOCK_SEL] = 1; } } -static void AdjustPosition(u16 acv) +inline void AdjustPosition(u16 acv) { s32 coeff, frac; - HorVer.adjDispPosX = (u16)CLAMP(0, 720 - HorVer.dispSizeX, (s16)HorVer.dispPosX + displayOffsetH); + HorVer.adjDispPosX = + (u16)CLAMP(0, 720 - HorVer.dispSizeX, (s16)HorVer.dispPosX + displayOffsetH); coeff = (HorVer.xfbMode == VI_XFBMODE_SF) ? 2 : 1; - frac = HorVer.dispPosY & 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.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); } -static void ImportAdjustingValues(void) +inline void ImportAdjustingValues(void) { displayOffsetH = __OSLockSram()->displayOffsetH; displayOffsetV = 0; @@ -358,54 +382,57 @@ void VIInit(void) u16 dspCfg; u32 value, tv, tvInBootrom; - if (IsInitialized) { + if (IsInitialized) + { return; } OSRegisterVersion(__VIVersion); IsInitialized = TRUE; - encoderType = 1; + encoderType = 1; - if (!(__VIRegs[VI_DISP_CONFIG] & 1)) { + if (!(__VIRegs[VI_DISP_CONFIG] & 1)) + { __VIInit(VI_TVMODE_NTSC_INT); } - retraceCount = 0; - changed = 0; - shdwChanged = 0; - changeMode = 0; + retraceCount = 0; + changed = 0; + shdwChanged = 0; + changeMode = 0; shdwChangeMode = 0; - flushFlag = 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_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_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_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_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_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_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_FCT_6] = ((((taps[23])) << 0) | (((taps[24])) << 8)); __VIRegs[VI_WIDTH] = 640; ImportAdjustingValues(); tvInBootrom = *(u32*)OSPhysicalToCached(0xCC); - dspCfg = __VIRegs[VI_DISP_CONFIG]; + dspCfg = __VIRegs[VI_DISP_CONFIG]; HorVer.nonInter = ((((u32)(dspCfg)) >> 2 & 0x00000001)); - HorVer.tv = ((((u32)(dspCfg)) & 0x00000300) >> 8); + 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)); + tv = (HorVer.tv == VI_DEBUG) ? VI_NTSC : HorVer.tv; + HorVer.timing = getTiming((VITVMode)VI_TVMODE(tv, HorVer.nonInter)); regs[VI_DISP_CONFIG] = dspCfg; CurrTiming = HorVer.timing; @@ -413,36 +440,36 @@ void VIInit(void) HorVer.dispSizeX = 640; HorVer.dispSizeY = (u16)(CurrTiming->acv * 2); - HorVer.dispPosX = (u16)((720 - HorVer.dispSizeX) / 2); - HorVer.dispPosY = 0; + HorVer.dispPosX = (u16)((720 - HorVer.dispSizeX) / 2); + HorVer.dispPosY = 0; AdjustPosition(CurrTiming->acv); - 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.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.std = 40; + HorVer.wpl = 40; + HorVer.xof = 0; + HorVer.isBlack = TRUE; + HorVer.is3D = FALSE; OSInitThreadQueue(&retraceQueue); - value = __VIRegs[VI_DISP_INT_0]; - value = (((u32)(value)) & ~0x00008000) | (((0)) << 15); + 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); + value = __VIRegs[VI_DISP_INT_1]; + value = (((u32)(value)) & ~0x00008000) | (((0)) << 15); __VIRegs[VI_DISP_INT_1] = value; - PreCB = nullptr; + PreCB = nullptr; PostCB = nullptr; __OSSetInterruptHandler(24, __VIRetraceHandler); @@ -454,21 +481,22 @@ void VIWaitForRetrace(void) int interrupt; u32 startCount; - interrupt = OSDisableInterrupts(); + interrupt = OSDisableInterrupts(); startCount = retraceCount; - do { + do + { OSSleepThread(&retraceQueue); } while (startCount == retraceCount); OSRestoreInterrupts(interrupt); } -static void setInterruptRegs(VITimingInfo* tm) +inline void setInterruptRegs(VITimingInfo* tm) { u16 vct, hct, borrow; - vct = (u16)(tm->numHalfLines / 2); + vct = (u16)(tm->numHalfLines / 2); borrow = (u16)(tm->numHalfLines % 2); - hct = (u16)((borrow) ? tm->hlw : (u16)0); + hct = (u16)((borrow) ? tm->hlw : (u16)0); vct++; hct++; @@ -480,45 +508,47 @@ static void setInterruptRegs(VITimingInfo* tm) changed |= VI_BITMASK(VI_DISP_INT_0); } -static void setPicConfig(u16 fbSizeX, VIXFBMode xfbMode, u16 panPosX, u16 panSizeX, u8* wordPerLine, u8* std, u8* wpl, u8* xof) +inline 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); + *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 setBBIntervalRegs(VITimingInfo* tm) +inline void setBBIntervalRegs(VITimingInfo* tm) { u16 val; - val = (u16)((((u32)(tm->bs1))) | (((u32)(tm->be1)) << 5)); + val = (u16)((((u32)(tm->bs1))) | (((u32)(tm->be1)) << 5)); regs[VI_BBI_ODD_U] = val; changed |= VI_BITMASK(VI_BBI_ODD_U); - val = (u16)((((u32)(tm->bs3))) | (((u32)(tm->be3)) << 5)); + val = (u16)((((u32)(tm->bs3))) | (((u32)(tm->be3)) << 5)); regs[VI_BBI_ODD] = val; changed |= VI_BITMASK(VI_BBI_ODD); - val = (u16)((((u32)(tm->bs2))) | (((u32)(tm->be2)) << 5)); + val = (u16)((((u32)(tm->bs2))) | (((u32)(tm->be2)) << 5)); regs[VI_BBI_EVEN_U] = val; changed |= VI_BITMASK(VI_BBI_EVEN_U); - val = (u16)((((u32)(tm->bs4))) | (((u32)(tm->be4)) << 5)); + val = (u16)((((u32)(tm->bs4))) | (((u32)(tm->be4)) << 5)); regs[VI_BBI_EVEN] = val; changed |= VI_BITMASK(VI_BBI_EVEN); } -static void setScalingRegs(u16 panSizeX, u16 dispSizeX, BOOL is3D) +inline void setScalingRegs(u16 panSizeX, u16 dispSizeX, BOOL is3D) { u32 scale; panSizeX = (u16)(is3D ? panSizeX * 2 : panSizeX); - if (panSizeX < dispSizeX) { + if (panSizeX < dispSizeX) + { scale = (256 * (u32)panSizeX + (u32)dispSizeX - 1) / (u32)dispSizeX; regs[VI_HSR] = (u16)((((u32)(scale))) | (((u32)(1)) << 12)); @@ -526,25 +556,29 @@ static void setScalingRegs(u16 panSizeX, u16 dispSizeX, BOOL is3D) regs[VI_WIDTH] = (u16)((((u32)(panSizeX)))); changed |= VI_BITMASK(VI_WIDTH); - } else { + } + else + { regs[VI_HSR] = (u16)((((u32)(256))) | (((u32)(0)) << 12)); changed |= VI_BITMASK(VI_HSR); } } -static void calcFbbs(u32 bufAddr, u16 panPosX, u16 panPosY, u8 wordPerLine, VIXFBMode xfbMode, u16 dispPosY, u32* tfbb, u32* bfbb) +inline 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; + xoffInWords = (u32)panPosX / 16; bytesPerLine = (u32)wordPerLine * 32; *tfbb = bufAddr + xoffInWords * 32 + bytesPerLine * panPosY; *bfbb = (xfbMode == VI_XFBMODE_SF) ? *tfbb : (*tfbb + bytesPerLine); - if (dispPosY % 2 == 1) { + if (dispPosY % 2 == 1) + { u32 tmp = *tfbb; - *tfbb = *bfbb; - *bfbb = tmp; + *tfbb = *bfbb; + *bfbb = tmp; } *tfbb = ToPhysical(*tfbb); @@ -554,19 +588,27 @@ static void calcFbbs(u32 bufAddr, u16 panPosX, u16 panPosY, u8 wordPerLine, VIXF static void setFbbRegs(VIPositionInfo* hv, 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); + 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); + if (hv->is3D) + { + calcFbbs(hv->rbufAddr, hv->panPosX, hv->adjPanPosY, hv->wordPerLine, hv->xfbMode, + hv->adjDispPosY, rtfbb, rbfbb); } - if (IS_LOWER_16MB(*tfbb) && IS_LOWER_16MB(*bfbb) && IS_LOWER_16MB(*rtfbb) && IS_LOWER_16MB(*rbfbb)) { + if (IS_LOWER_16MB(*tfbb) && IS_LOWER_16MB(*bfbb) && IS_LOWER_16MB(*rtfbb) && + IS_LOWER_16MB(*rbfbb)) + { shifted = 0; - } else { + } + else + { shifted = 1; } - if (shifted) { + if (shifted) + { *tfbb >>= 5; *bfbb >>= 5; *rtfbb >>= 5; @@ -585,7 +627,8 @@ static void setFbbRegs(VIPositionInfo* hv, u32* tfbb, u32* bfbb, u32* rtfbb, u32 regs[VI_BTTM_FIELD_BASE_LEFT] = (u16)(*bfbb >> 16); changed |= VI_BITMASK(VI_BTTM_FIELD_BASE_LEFT); - if (hv->is3D) { + if (hv->is3D) + { regs[VI_TOP_FIELD_BASE_RIGHT_U] = *rtfbb & 0xffff; changed |= VI_BITMASK(VI_TOP_FIELD_BASE_RIGHT_U); @@ -600,7 +643,7 @@ static void setFbbRegs(VIPositionInfo* hv, u32* tfbb, u32* bfbb, u32* rtfbb, u32 } } -static void setHorizontalRegs(VITimingInfo* tm, u16 dispPosX, u16 dispSizeX) +inline void setHorizontalRegs(VITimingInfo* tm, u16 dispPosX, u16 dispSizeX) { u32 hbe, hbs, hbeLo, hbeHi; @@ -623,33 +666,41 @@ static void setHorizontalRegs(VITimingInfo* tm, u16 dispPosX, u16 dispSizeX) changed |= VI_BITMASK(VI_HORIZ_TIMING_1L); } -static void setVerticalRegs(u16 dispPosY, u16 dispSizeY, u8 equ, u16 acv, u16 prbOdd, u16 prbEven, u16 psbOdd, u16 psbEven, BOOL black) +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; - if (regs[VI_CLOCK_SEL] & 1) { + if (regs[VI_CLOCK_SEL] & 1) + { c = 1; d = 2; - } else { + } + else + { c = 2; d = 1; } - if (dispPosY % 2 == 0) { - actualPrbOdd = (u16)(prbOdd + d * dispPosY); - actualPsbOdd = (u16)(psbOdd + d * ((c * acv - dispSizeY) - dispPosY)); + 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)); - } else { - actualPrbOdd = (u16)(prbEven + d * dispPosY); - actualPsbOdd = (u16)(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)); } actualAcv = (u16)(dispSizeY / c); - if (black) { + if (black) + { actualPrbOdd += 2 * actualAcv - 2; actualPsbOdd += 2; actualPrbEven += 2 * actualAcv - 2; @@ -673,22 +724,6 @@ static void setVerticalRegs(u16 dispPosY, u16 dispSizeY, u8 equ, u16 acv, u16 pr changed |= VI_BITMASK(VI_VERT_TIMING_EVEN); } -static void PrintDebugPalCaution(void) -{ - static u32 message = 0; - - if (message == 0) { - message = 1; - OSReport("***************************************\n"); - OSReport(" ! ! ! C A U T I O N ! ! ! \n"); - OSReport("This TV format \"DEBUG_PAL\" is only for \n"); - OSReport("temporary solution until PAL DAC board \n"); - OSReport("is available. Please do NOT use this \n"); - OSReport("mode in real games!!! \n"); - OSReport("***************************************\n"); - } -} - void VIConfigure(const GXRenderModeObj* obj) { VITimingInfo* tm; @@ -696,37 +731,56 @@ void VIConfigure(const GXRenderModeObj* obj) BOOL enabled; u32 newNonInter, tvInBootrom, tvInGame; - enabled = OSDisableInterrupts(); + enabled = OSDisableInterrupts(); newNonInter = (u32)obj->viTVmode & 3; - if (HorVer.nonInter != newNonInter) { - changeMode = 1; + if (HorVer.nonInter != newNonInter) + { + changeMode = 1; HorVer.nonInter = newNonInter; } - tvInGame = (u32)obj->viTVmode >> 2; + tvInGame = (u32)obj->viTVmode >> 2; tvInBootrom = *(u32*)OSPhysicalToCached(0xCC); - if (tvInGame == VI_DEBUG_PAL) { - PrintDebugPalCaution(); + if (tvInGame == VI_DEBUG_PAL) + { + static u32 message = 0; + + if (message == 0) + { + message = 1; + OSReport("***************************************\n"); + OSReport(" ! ! ! C A U T I O N ! ! ! \n"); + OSReport("This TV format \"DEBUG_PAL\" is only for \n"); + OSReport("temporary solution until PAL DAC board \n"); + OSReport("is available. Please do NOT use this \n"); + OSReport("mode in real games!!! \n"); + OSReport("***************************************\n"); + } } - switch (tvInBootrom) { + switch (tvInBootrom) + { case VI_MPAL: case VI_NTSC: case VI_GCA: - if (tvInGame == VI_NTSC || tvInGame == VI_MPAL || tvInGame == VI_GCA) { + if (tvInGame == VI_NTSC || tvInGame == VI_MPAL || tvInGame == VI_GCA) + { break; } goto panic; case VI_PAL: case VI_EURGB60: - if (tvInGame == VI_PAL || tvInGame == VI_EURGB60) { + if (tvInGame == VI_PAL || tvInGame == VI_EURGB60) + { break; } default: panic: - OSErrorLine(1908, "VIConfigure(): Tried to change mode from (%d) to (%d), which is forbidden\n", tvInBootrom, tvInGame); + OSErrorLine(1908, + "VIConfigure(): Tried to change mode from (%d) to (%d), which is forbidden\n", + tvInBootrom, tvInGame); } // if (((tvInBootrom != VI_PAL && tvInBootrom != VI_EURGB60) && (tvInGame == VI_PAL || tvInGame == VI_EURGB60)) // || ((tvInBootrom == VI_PAL || tvInBootrom == VI_EURGB60) && (tvInGame != VI_PAL && tvInGame != VI_EURGB60))) { @@ -734,52 +788,63 @@ void VIConfigure(const GXRenderModeObj* obj) // OSErrorLine(1908, "VIConfigure(): Tried to change mode from (%d) to (%d), which is forbidden\n", tvInBootrom, tvInGame); // } - if ((tvInGame == VI_NTSC) || (tvInGame == VI_MPAL)) { + if ((tvInGame == VI_NTSC) || (tvInGame == VI_MPAL)) + { HorVer.tv = tvInBootrom; - } else { + } + else + { HorVer.tv = tvInGame; } - HorVer.dispPosX = obj->viXOrigin; - HorVer.dispPosY = (u16)((HorVer.nonInter == VI_NON_INTERLACE) ? (u16)(obj->viYOrigin * 2) : obj->viYOrigin); + HorVer.dispPosX = obj->viXOrigin; + HorVer.dispPosY = + (u16)((HorVer.nonInter == VI_NON_INTERLACE) ? (u16)(obj->viYOrigin * 2) : obj->viYOrigin); HorVer.dispSizeX = obj->viWidth; - HorVer.fbSizeX = obj->fbWidth; - HorVer.fbSizeY = obj->xfbHeight; - HorVer.xfbMode = obj->xFBmode; - HorVer.panSizeX = HorVer.fbSizeX; - HorVer.panSizeY = HorVer.fbSizeY; - HorVer.panPosX = 0; - HorVer.panPosY = 0; - - 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.fbSizeX = obj->fbWidth; + HorVer.fbSizeY = obj->xfbHeight; + HorVer.xfbMode = obj->xFBmode; + HorVer.panSizeX = HorVer.fbSizeX; + HorVer.panSizeY = HorVer.fbSizeY; + HorVer.panPosX = 0; + HorVer.panPosY = 0; + + 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((VITVMode)VI_TVMODE(HorVer.tv, HorVer.nonInter)); HorVer.timing = tm; AdjustPosition(tm->acv); - if (encoderType == 0) { + if (encoderType == 0) + { HorVer.tv = VI_DEBUG; } setInterruptRegs(tm); regDspCfg = regs[VI_DISP_CONFIG]; // TODO: USE BIT MACROS OR SOMETHING - if ((HorVer.nonInter == VI_PROGRESSIVE) || (HorVer.nonInter == VI_3D)) { + if ((HorVer.nonInter == VI_PROGRESSIVE) || (HorVer.nonInter == VI_3D)) + { regDspCfg = (((u32)(regDspCfg)) & ~0x00000004) | (((u32)(1)) << 2); - } else { + } + else + { regDspCfg = (((u32)(regDspCfg)) & ~0x00000004) | (((u32)(HorVer.nonInter & 1)) << 2); } regDspCfg = (((u32)(regDspCfg)) & ~0x00000008) | (((u32)(HorVer.is3D)) << 3); - if ((HorVer.tv == VI_DEBUG_PAL) || (HorVer.tv == VI_EURGB60) || (HorVer.tv == VI_GCA)) { + if ((HorVer.tv == VI_DEBUG_PAL) || (HorVer.tv == VI_EURGB60) || (HorVer.tv == VI_GCA)) + { regDspCfg = (((u32)(regDspCfg)) & ~0x00000300); - } else { + } + else + { regDspCfg = (((u32)(regDspCfg)) & ~0x00000300) | (((u32)(HorVer.tv)) << 8); } @@ -787,9 +852,13 @@ void VIConfigure(const GXRenderModeObj* obj) changed |= VI_BITMASK(0x01); regDspCfg = regs[VI_CLOCK_SEL]; - if (obj->viTVmode == VI_TVMODE_NTSC_PROG || obj->viTVmode == VI_TVMODE_NTSC_3D || obj->viTVmode == VI_TVMODE_GCA_PROG) { + if (obj->viTVmode == VI_TVMODE_NTSC_PROG || obj->viTVmode == VI_TVMODE_NTSC_3D || + obj->viTVmode == VI_TVMODE_GCA_PROG) + { regDspCfg = (u32)(regDspCfg & ~0x1) | 1; - } else { + } + else + { regDspCfg = (u32)(regDspCfg & ~0x1); } @@ -800,23 +869,19 @@ void VIConfigure(const GXRenderModeObj* obj) setScalingRegs(HorVer.panSizeX, HorVer.dispSizeX, HorVer.is3D); setHorizontalRegs(tm, HorVer.adjDispPosX, HorVer.dispSizeX); setBBIntervalRegs(tm); - setPicConfig(HorVer.fbSizeX, HorVer.xfbMode, HorVer.panPosX, HorVer.panSizeX, &HorVer.wordPerLine, &HorVer.std, &HorVer.wpl, - &HorVer.xof); + setPicConfig(HorVer.fbSizeX, HorVer.xfbMode, HorVer.panPosX, HorVer.panSizeX, + &HorVer.wordPerLine, &HorVer.std, &HorVer.wpl, &HorVer.xof); - if (FBSet) { + if (FBSet) + { 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.adjDispPosY, HorVer.adjDispSizeY, tm->equ, tm->acv, tm->prbOdd, + tm->prbEven, tm->psbOdd, tm->psbEven, HorVer.isBlack); OSRestoreInterrupts(enabled); } -void VIConfigurePan(u16 panPosX, u16 panPosY, u16 panSizeX, u16 panSizeY) -{ - // UNUSED FUNCTION -} - void VIFlush(void) { BOOL enabled; @@ -828,71 +893,57 @@ void VIFlush(void) changeMode = 0; shdwChanged |= changed; - while (changed) { - regIndex = cntlzd(changed); + while (changed) + { + regIndex = cntlzd(changed); shdwRegs[regIndex] = regs[regIndex]; changed &= ~VI_BITMASK(regIndex); } - flushFlag = 1; + flushFlag = 1; NextBufAddr = HorVer.bufAddr; OSRestoreInterrupts(enabled); } void VISetNextFrameBuffer(void* fb) { - BOOL enabled = OSDisableInterrupts(); + BOOL enabled = OSDisableInterrupts(); HorVer.bufAddr = (u32)fb; - FBSet = 1; + FBSet = 1; setFbbRegs(&HorVer, &HorVer.tfbb, &HorVer.bfbb, &HorVer.rtfbb, &HorVer.rbfbb); OSRestoreInterrupts(enabled); } -void* VIGetNextFrameBuffer(void) { return (void*)NextBufAddr; } - -void* VIGetCurrentFrameBuffer(void) { return (void*)CurrBufAddr; } - -void VISetNextRightFrameBuffer(void* fb) -{ - // UNUSED FUNCTION -} - void VISetBlack(BOOL isBlack) { int interrupt; VITimingInfo* tm; - interrupt = OSDisableInterrupts(); + 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); + tm = HorVer.timing; + setVerticalRegs(HorVer.adjDispPosY, HorVer.dispSizeY, tm->equ, tm->acv, tm->prbOdd, tm->prbEven, + tm->psbOdd, tm->psbEven, HorVer.isBlack); OSRestoreInterrupts(interrupt); } -void VISet3D(void) -{ - // UNUSED FUNCTION -} - -u32 VIGetRetraceCount(void) { return retraceCount; } - static void GetCurrentDisplayPosition(u32* hct, u32* vct) { u32 hcount, vcount0, vcount; vcount = __VIRegs[VI_VERT_COUNT] & 0x7FF; - do { + do + { vcount0 = vcount; - hcount = __VIRegs[VI_HORIZ_COUNT] & 0x7FF; - vcount = __VIRegs[VI_VERT_COUNT] & 0x7FF; + hcount = __VIRegs[VI_HORIZ_COUNT] & 0x7FF; + vcount = __VIRegs[VI_VERT_COUNT] & 0x7FF; } while (vcount0 != vcount); *hct = hcount; *vct = vcount; } -static u32 getCurrentHalfLine(void) +inline u32 getCurrentHalfLine(void) { u32 hcount, vcount; GetCurrentDisplayPosition(&hcount, &vcount); @@ -900,7 +951,10 @@ static u32 getCurrentHalfLine(void) return ((vcount - 1) << 1) + ((hcount - 1) / CurrTiming->hlw); } -static u32 getCurrentFieldEvenOdd() { return (getCurrentHalfLine() < CurrTiming->numHalfLines) ? 1 : 0; } +static u32 getCurrentFieldEvenOdd() +{ + return (getCurrentHalfLine() < CurrTiming->numHalfLines) ? 1 : 0; +} u32 VIGetNextField(void) { @@ -919,12 +973,13 @@ u32 VIGetCurrentLine(void) VITimingInfo* tm; int interrupt; - tm = CurrTiming; + tm = CurrTiming; interrupt = OSDisableInterrupts(); - line = getCurrentHalfLine(); + line = getCurrentHalfLine(); OSRestoreInterrupts(interrupt); - if (line >= tm->numHalfLines) { + if (line >= tm->numHalfLines) + { line -= tm->numHalfLines; } @@ -938,7 +993,8 @@ u32 VIGetTvFormat(void) interrupt = OSDisableInterrupts(); - switch (CurrTvMode) { + switch (CurrTvMode) + { case VI_NTSC: case VI_DEBUG: case VI_GCA: @@ -958,70 +1014,95 @@ u32 VIGetTvFormat(void) return fmt; } -u32 VIGetDTVStatus(void) -{ - u32 stat; - int interrupt; - - interrupt = OSDisableInterrupts(); - stat = (__VIRegs[VI_DTV_STAT] & 3); - OSRestoreInterrupts(interrupt); - return (stat & 1); -} - void __VIDisplayPositionToXY(u32 hcount, u32 vcount, s16* x, s16* y) { u32 halfLine = ((vcount - 1) << 1) + ((hcount - 1) / CurrTiming->hlw); - if (HorVer.nonInter == VI_INTERLACE) { - if (halfLine < CurrTiming->numHalfLines) { - if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) { + if (HorVer.nonInter == VI_INTERLACE) + { + if (halfLine < CurrTiming->numHalfLines) + { + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) + { *y = -1; - } else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbOdd) { + } + else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbOdd) + { *y = -1; - } else { + } + else + { *y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd) & ~1); } - } else { + } + else + { halfLine -= CurrTiming->numHalfLines; - if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbEven) { + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbEven) + { *y = -1; - } else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbEven) { + } + else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbEven) + { *y = -1; - } else { + } + else + { *y = (s16)(((halfLine - CurrTiming->equ * 3 - CurrTiming->prbEven) & ~1) + 1); } } - } else if (HorVer.nonInter == VI_NON_INTERLACE) { - if (halfLine >= CurrTiming->numHalfLines) { + } + else if (HorVer.nonInter == VI_NON_INTERLACE) + { + if (halfLine >= CurrTiming->numHalfLines) + { halfLine -= CurrTiming->numHalfLines; } - if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) { + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) + { *y = -1; - } else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbOdd) { + } + else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbOdd) + { *y = -1; - } else { + } + else + { *y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd) & ~1); } - } else if (HorVer.nonInter == VI_PROGRESSIVE) { - if (halfLine < CurrTiming->numHalfLines) { - if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) { + } + else if (HorVer.nonInter == VI_PROGRESSIVE) + { + if (halfLine < CurrTiming->numHalfLines) + { + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbOdd) + { *y = -1; - } else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbOdd) { + } + else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbOdd) + { *y = -1; - } else { + } + else + { *y = (s16)(halfLine - CurrTiming->equ * 3 - CurrTiming->prbOdd); } - } else { + } + else + { halfLine -= CurrTiming->numHalfLines; - if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbEven) { + if (halfLine < CurrTiming->equ * 3 + CurrTiming->prbEven) + { *y = -1; - } else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbEven) { + } + else if (halfLine >= CurrTiming->numHalfLines - CurrTiming->psbEven) + { *y = -1; - } else + } + else *y = (s16)((halfLine - CurrTiming->equ * 3 - CurrTiming->prbEven) & ~1); } } diff --git a/libs/rwsdk/plugin/collis/ctbsp.c b/libs/rwsdk/plugin/collis/ctbsp.c new file mode 100644 index 000000000..ef70eb772 --- /dev/null +++ b/libs/rwsdk/plugin/collis/ctbsp.c @@ -0,0 +1,8 @@ +// #include +// #include +// #include +// #include + +void _rpCollBSPTreeInit() +{ +} \ No newline at end of file diff --git a/libs/rwsdk/tool/slerp/rtslerp.c b/libs/rwsdk/tool/slerp/rtslerp.c new file mode 100644 index 000000000..e3502b87f --- /dev/null +++ b/libs/rwsdk/tool/slerp/rtslerp.c @@ -0,0 +1,8 @@ +//#include "StdInc.h" + +// #include + +// void RtQuatSetupSlerpCache(RtQuat* qpFrom, RtQuat* qpTo, RtQuatSlerpCache* sCache) +// { +// ((void(__cdecl*)(RtQuat*, RtQuat*, RtQuatSlerpCache*))0x7EC220)(qpFrom, qpTo, sCache); +// } diff --git a/libs/rwsdk/tool/slerp/rtslerp.h b/libs/rwsdk/tool/slerp/rtslerp.h new file mode 100644 index 000000000..d6251a3b1 --- /dev/null +++ b/libs/rwsdk/tool/slerp/rtslerp.h @@ -0,0 +1,231 @@ +/* + * Data Structures for Slerps/Spherical Linear Interpolations + * See also GemsIII/quatspin.c in + * http://www.acm.org/pubs/tog/GraphicsGems/gemsiii.zip + * Copyright (c) Criterion Software Limited + */ + +/*************************************************************************** + * * + * Module : rtslerp.h * + * * + * Purpose : Slerp functionality * + * * + **************************************************************************/ + +#ifndef RTSLERP_H +#define RTSLERP_H + +/** + * \defgroup rtslerp RtSlerp + * \ingroup mathtools + * + * Slerp/Spherical Linear Interpolations Toolkit for RenderWare. + * + * See also http://www.cis.ohio-state.edu/~parent/book/Full.html + */ + +#include "rwsdk/rwcore.h" +#include "rwsdk/rtquat.h" + +/**************************************************************************** + Includes + */ + +//#include "rtslerp.rpe" /* automatically generated header file */ + +/**************************************************************************** + Defines + */ + +/* Masks for specifying which matrices to store by reference */ +#define rtSLERPREFNONE 0x00 +#define rtSLERPREFSTARTMAT 0x01 +#define rtSLERPREFENDMAT 0x02 +#define rtSLERPREFALL (~rtSLERPREFNONE) + +/**************************************************************************** + Global Types + */ + +typedef struct RtSlerp RtSlerp; +/** + * \ingroup rtslerp + * \struct RtSlerp + * structure describing a Slerps/Spherical Linear Interpolations. + * See also GemsIII/quatspin.c in + * http://www.acm.org/pubs/tog/GraphicsGems/gemsiii.zip + */ +struct RtSlerp +{ + RwInt32 matRefMask; /**< Which matrices do we NOT own */ + RwMatrix* startMat; /**< The start matrix */ + RwMatrix* endMat; /**< The end matrix */ + RwV3d axis; /**< The axis of rotation for the slerp */ + RwReal angle; /**< The angle (in degrees) between src & dest */ + + /* Though a slerp may be a bad idea and opting for a lerp is better */ + RwBool useLerp; /**< If true, lerps are used. If false, lerps are not used. */ +}; + +/* static frame sequence animation - contains no state */ + +typedef struct RtQuatSlerpCache RtQuatSlerpCache; +/** + * \ingroup rtslerp + * \struct RtQuatSlerpCache + * structure describing a SlerpCache, + * which should be initialized with \ref RtQuatSetupSlerpCache. + */ +struct RtQuatSlerpCache +{ + RtQuat raFrom; /**< Scaled initial quaternion */ + RtQuat raTo; /**< Scaled final quaternion */ + RwReal omega; /**< Angular displacement in radians */ + RwBool nearlyZeroOm; /**< Flags near-zero angular + displacement*/ +}; + +typedef struct RtQuatSlerpArgandCache RtQuatSlerpArgandCache; +/** + * \ingroup rtslerp + * \struct RtQuatSlerpArgandCache + * a structure describing + * an Argand SlerpCache which should be + * initialized with \ref RtQuatSetupSlerpArgandCache. + * See http://www-groups.dcs.st-and.ac.uk/~history/Mathematicians/Argand.html + * Jean Argand was an accountant and amateur mathematician. + * He is famed for his geometrical interpretation of the complex numbers + * where i is interpreted as a rotation through 90. + */ +struct RtQuatSlerpArgandCache +{ + RtQuat logTo; /**< field Logarithm of final quaternion */ + RtQuat logBase; /**< Logarithm of initial relative to final quaternion */ +}; + +#define RtQuatSlerpMacro(qpResult, qpFrom, qpTo, rT, sCache) \ + MACRO_START \ + { \ + if ((rT) <= ((RwReal)0)) \ + { \ + /* t is before start */ \ + *(qpResult) = *(qpFrom); \ + } \ + else if (((RwReal)1) <= (rT)) \ + { \ + /* t is after end */ \ + *(qpResult) = *(qpTo); \ + } \ + else \ + { \ + /* ... so t must be in the interior then */ \ + /* Calc coefficients rSclFrom, rSclTo */ \ + RwReal rSclFrom = ((RwReal)1) - (rT); \ + RwReal rSclTo = (rT); \ + \ + if (!((sCache)->nearlyZeroOm)) \ + { \ + /* Standard case: slerp */ \ + /* SLERPMESSAGE(("Neither nearly ZERO nor nearly PI")); */ \ + \ + rSclFrom *= (sCache)->omega; \ + RwSinMinusPiToPiMacro(rSclFrom, rSclFrom); \ + rSclTo *= (sCache)->omega; \ + RwSinMinusPiToPiMacro(rSclTo, rSclTo); \ + } \ + \ + /* Calc final values */ \ + RwV3dScaleMacro(&(qpResult)->imag, &(sCache)->raFrom.imag, rSclFrom); \ + RwV3dIncrementScaledMacro(&(qpResult)->imag, &(sCache)->raTo.imag, rSclTo); \ + (qpResult)->real = \ + ((sCache)->raFrom.real * rSclFrom) + ((sCache)->raTo.real * rSclTo); \ + } \ + } \ + MACRO_STOP + +#define RtQuatSlerpArgandMacro(qpResult, qpFrom, qpTo, rT, sArgandCache) \ + MACRO_START \ + { \ + if ((rT) <= ((RwReal)0)) \ + { \ + /* t is before start */ \ + *(qpResult) = *(qpFrom); \ + } \ + else if (((RwReal)1) <= (rT)) \ + { \ + /* t is after end */ \ + *(qpResult) = *(qpTo); \ + } \ + else \ + { \ + RtQuat logBlend; \ + \ + /* ... so t must be in the interior then */ \ + \ + logBlend.imag.x = \ + (sArgandCache)->logBase.imag.x + (rT) * (sArgandCache)->logTo.imag.x; \ + logBlend.imag.y = \ + (sArgandCache)->logBase.imag.y + (rT) * (sArgandCache)->logTo.imag.y; \ + logBlend.imag.z = \ + (sArgandCache)->logBase.imag.z + (rT) * (sArgandCache)->logTo.imag.z; \ + logBlend.real = 0; \ + \ + RtQuatUnitExpMacro((qpResult), &logBlend); \ + } \ + } \ + MACRO_STOP + +#if (!(defined(RWDEBUG) || defined(RWSUPPRESSINLINE))) + +#define RtQuatSlerp(qpResult, qpFrom, qpTo, rT, sCache) \ + RtQuatSlerpMacro(qpResult, qpFrom, qpTo, rT, sCache) + +#define RtQuatSlerpArgand(qpResult, qpFrom, qpTo, rT, sArgandCache) \ + RtQuatSlerpArgandMacro(qpResult, qpFrom, qpTo, rT, sArgandCache) + +#endif /* (! ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) )) */ + +/**************************************************************************** + Function prototypes + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Creating and destroying slerps */ + +extern RtSlerp* RtSlerpCreate(RwInt32 nMatRefMask); + +extern void RtSlerpDestroy(RtSlerp* spSlerp); + +/* setting up a slerp */ +extern RtSlerp* RtSlerpInitialize(RtSlerp* spSlerp, RwMatrix* mpMat1, RwMatrix* mpMat2); + +/* Get a matrix */ +extern RwMatrix* RtSlerpGetMatrix(RtSlerp* spSlerp, RwMatrix* mpResultMat, RwReal nDelta); + +/* Set if lerp or slerp */ +extern RtSlerp* RtSlerpSetLerp(RtSlerp* spSlerp, RwBool bUseLerp); + +extern void RtQuatSetupSlerpCache(RtQuat* qpFrom, RtQuat* qpTo, RtQuatSlerpCache* sCache); + +extern void RtQuatSetupSlerpArgandCache(RtQuat* qpFrom, RtQuat* qpTo, + RtQuatSlerpArgandCache* sArgandCache); + +#if (defined(RWDEBUG) || defined(RWSUPPRESSINLINE)) + +extern void RtQuatSlerp(RtQuat* qpResult, RtQuat* qpFrom, RtQuat* qpTo, RwReal rT, + RtQuatSlerpCache* sCache); + +extern void RtQuatSlerpArgand(RtQuat* qpResult, RtQuat* qpFrom, RtQuat* qpTo, RwReal rT, + RtQuatSlerpArgandCache* sArgandCache); + +#endif /* ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) ) */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* RTSLERP_H */ From 5ffc89989141ce678f76231a98bf47ef5546a4dc Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Mon, 26 May 2025 21:34:29 -0400 Subject: [PATCH 14/19] build fix --- include/rwsdk/rtslerp.h | 116 ++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/include/rwsdk/rtslerp.h b/include/rwsdk/rtslerp.h index 616923ae5..ae07ff8b9 100644 --- a/include/rwsdk/rtslerp.h +++ b/include/rwsdk/rtslerp.h @@ -1,69 +1,69 @@ #ifndef RTSLERP_H #define RTSLERP_H -//#include -//#include -//#include "rtslerp.h" +#include +#include +#include "rtslerp.h" -// struct RtQuatSlerpCache -// { -// RtQuat raFrom; -// RtQuat raTo; -// RwReal omega; -// RwBool nearlyZeroOm; -// }; +struct RtQuatSlerpCache +{ + RtQuat raFrom; + RtQuat raTo; + RwReal omega; + RwBool nearlyZeroOm; +}; -// #define RtQuatSlerpMacro(qpResult, qpFrom, qpTo, rT, sCache) \ -// MACRO_START \ -// { \ -// if ((rT) <= ((RwReal)0)) \ -// { \ -// /* t is before start */ \ -// *(qpResult) = *(qpFrom); \ -// } \ -// else if (((RwReal)1) <= (rT)) \ -// { \ -// /* t is after end */ \ -// *(qpResult) = *(qpTo); \ -// } \ -// else \ -// { \ -// /* ... so t must be in the interior then */ \ -// /* Calc coefficients rSclFrom, rSclTo */ \ -// RwReal rSclFrom = ((RwReal)1) - (rT); \ -// RwReal rSclTo = (rT); \ -// \ -// if (!((sCache)->nearlyZeroOm)) \ -// { \ -// /* Standard case: slerp */ \ -// /* SLERPMESSAGE(("Neither nearly ZERO nor nearly PI")); */ \ -// \ -// rSclFrom *= (sCache)->omega; \ -// RwSinMinusPiToPiMacro(rSclFrom, rSclFrom); \ -// rSclTo *= (sCache)->omega; \ -// RwSinMinusPiToPiMacro(rSclTo, rSclTo); \ -// } \ -// \ -// /* Calc final values */ \ -// RwV3dScaleMacro(&(qpResult)->imag, &(sCache)->raFrom.imag, rSclFrom); \ -// RwV3dIncrementScaledMacro(&(qpResult)->imag, &(sCache)->raTo.imag, rSclTo); \ -// (qpResult)->real = \ -// ((sCache)->raFrom.real * rSclFrom) + ((sCache)->raTo.real * rSclTo); \ -// } \ -// } \ -// MACRO_STOP +#define RtQuatSlerpMacro(qpResult, qpFrom, qpTo, rT, sCache) \ + MACRO_START \ + { \ + if ((rT) <= ((RwReal)0)) \ + { \ + /* t is before start */ \ + *(qpResult) = *(qpFrom); \ + } \ + else if (((RwReal)1) <= (rT)) \ + { \ + /* t is after end */ \ + *(qpResult) = *(qpTo); \ + } \ + else \ + { \ + /* ... so t must be in the interior then */ \ + /* Calc coefficients rSclFrom, rSclTo */ \ + RwReal rSclFrom = ((RwReal)1) - (rT); \ + RwReal rSclTo = (rT); \ + \ + if (!((sCache)->nearlyZeroOm)) \ + { \ + /* Standard case: slerp */ \ + /* SLERPMESSAGE(("Neither nearly ZERO nor nearly PI")); */ \ + \ + rSclFrom *= (sCache)->omega; \ + RwSinMinusPiToPiMacro(rSclFrom, rSclFrom); \ + rSclTo *= (sCache)->omega; \ + RwSinMinusPiToPiMacro(rSclTo, rSclTo); \ + } \ + \ + /* Calc final values */ \ + RwV3dScaleMacro(&(qpResult)->imag, &(sCache)->raFrom.imag, rSclFrom); \ + RwV3dIncrementScaledMacro(&(qpResult)->imag, &(sCache)->raTo.imag, rSclTo); \ + (qpResult)->real = \ + ((sCache)->raFrom.real * rSclFrom) + ((sCache)->raTo.real * rSclTo); \ + } \ + } \ + MACRO_STOP -// #define RtQuatSlerp(qpResult, qpFrom, qpTo, rT, sCache) \ -// RtQuatSlerpMacro(qpResult, qpFrom, qpTo, rT, sCache) +#define RtQuatSlerp(qpResult, qpFrom, qpTo, rT, sCache) \ + RtQuatSlerpMacro(qpResult, qpFrom, qpTo, rT, sCache) -// #ifdef __cplusplus -// extern "C" { -// #endif +#ifdef __cplusplus +extern "C" { +#endif -// extern void RtQuatSetupSlerpCache(RtQuat* qpFrom, RtQuat* qpTo, RtQuatSlerpCache* sCache); +extern void RtQuatSetupSlerpCache(RtQuat* qpFrom, RtQuat* qpTo, RtQuatSlerpCache* sCache); -// #ifdef __cplusplus -// } -// #endif +#ifdef __cplusplus +} +#endif #endif \ No newline at end of file From 1281769f02443e28cb8839ba82b0ca488ec13356 Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Tue, 27 May 2025 12:44:12 -0400 Subject: [PATCH 15/19] CI test --- configure.py | 9 +-- libs/dolphin/OdemuExi2/DebuggerDriver.c | 14 ++--- libs/dolphin/os/OSRtc.c | 74 +------------------------ libs/dolphin/os/OSThread.c | 6 +- 4 files changed, 18 insertions(+), 85 deletions(-) diff --git a/configure.py b/configure.py index 040b9dcf1..11f42aaa6 100644 --- a/configure.py +++ b/configure.py @@ -205,6 +205,7 @@ "-i libs", f"-i build/{config.version}/include", f"-DBUILD_VERSION={version_num}", + f"-DBUILD_VERSION{version_num}", # test for github f"-DVERSION_{config.version}", ] @@ -738,7 +739,7 @@ def MatchingFor(*versions): DolphinLib( "OdemuExi2", [ - Object(NonMatching, "dolphin/OdemuExi2/DebuggerDriver.c") + Object(Matching, "dolphin/OdemuExi2/DebuggerDriver.c", extra_cflags=["-inline on, deferred"]) ] ), DolphinLib( @@ -766,8 +767,8 @@ def MatchingFor(*versions): Object(Matching, "dolphin/os/OSReboot.c"), Object(Matching, "dolphin/os/OSReset.c"), Object(Matching, "dolphin/os/OSResetSW.c"), - Object(NonMatching, "dolphin/os/OSRtc.c"), - Object(NonMatching, "dolphin/os/OSThread.c"), + Object(Matching, "dolphin/os/OSRtc.c"), + Object(Matching, "dolphin/os/OSThread.c"), Object(Matching, "dolphin/os/OSTime.c"), Object(Matching, "dolphin/os/OSSync.c"), Object(NonMatching, "dolphin/os/init/__start.c"), @@ -777,7 +778,7 @@ def MatchingFor(*versions): DolphinLib( "pad", [ - Object(NonMatching, "dolphin/pad/Padclamp.c"), + Object(Matching, "dolphin/pad/Padclamp.c"), Object(NonMatching, "dolphin/pad/Pad.c") ] ), diff --git a/libs/dolphin/OdemuExi2/DebuggerDriver.c b/libs/dolphin/OdemuExi2/DebuggerDriver.c index c2c5e7c3d..e5377fc63 100644 --- a/libs/dolphin/OdemuExi2/DebuggerDriver.c +++ b/libs/dolphin/OdemuExi2/DebuggerDriver.c @@ -19,7 +19,7 @@ static u8 SendCount = 0x80; #define IS_FALSE(x) !IS_TRUE(x) #define ROUND_UP(x, align) (((x) + (align)-1) & (-(align))) -void DBGEXIInit() +inline void DBGEXIInit() { __OSMaskInterrupts(0x18000); __EXIRegs[10] = 0; @@ -31,7 +31,7 @@ void DBGEXIInit() * Size: 000028 */ -static u32 DBGEXISelect(u32 v) +inline u32 DBGEXISelect(u32 v) { u32 regs = __EXIRegs[10]; regs &= 0x405; @@ -45,7 +45,7 @@ static u32 DBGEXISelect(u32 v) * Address: ........ * Size: 00001C */ -BOOL DBGEXIDeselect(void) +inline BOOL DBGEXIDeselect(void) { __EXIRegs[10] &= 0x405; return TRUE; @@ -56,7 +56,7 @@ BOOL DBGEXIDeselect(void) * Address: ........ * Size: 00001C */ -static BOOL DBGEXISync() +inline BOOL DBGEXISync() { while (__EXIRegs[13] & 1) ; @@ -108,7 +108,7 @@ static BOOL DBGEXIImm(void* buffer, s32 bytecounter, u32 write) * Address: ........ * Size: 00008C */ -static BOOL DBGWriteMailbox(u32 p1) +inline BOOL DBGWriteMailbox(u32 p1) { BOOL total = FALSE; u32 v; @@ -326,7 +326,7 @@ void DBInitInterrupts(void) * Address: ........ * Size: 000150 */ -static void CheckMailBox(void) +inline void CheckMailBox(void) { u32 v; DBGReadStatus(&v); @@ -358,8 +358,8 @@ u32 DBQueryData(void) { interrupts = OSDisableInterrupts(); CheckMailBox(); + OSRestoreInterrupts(interrupts); } - OSRestoreInterrupts(interrupts); return RecvDataLeng; } diff --git a/libs/dolphin/os/OSRtc.c b/libs/dolphin/os/OSRtc.c index eab1d5301..7a329c87f 100644 --- a/libs/dolphin/os/OSRtc.c +++ b/libs/dolphin/os/OSRtc.c @@ -23,7 +23,7 @@ typedef struct SramControlBlock static SramControlBlock Scb ALIGN(32); -static BOOL ReadSram(void* buffer) +inline BOOL ReadSram(void* buffer) { BOOL err; u32 cmd; @@ -98,7 +98,7 @@ void __OSInitSram() OSSetGbsMode(OSGetGbsMode()); } -static void* LockSram(u32 offset) +inline void* LockSram(u32 offset) { BOOL enabled; enabled = OSDisableInterrupts(); @@ -252,74 +252,6 @@ void OSSetSoundMode(u32 mode) __OSUnlockSram(TRUE); } -u32 OSGetProgressiveMode() -{ - OSSram* sram; - u32 mode; - - sram = __OSLockSramHACK(); - mode = (sram->flags & 0x80) >> 7; - __OSUnlockSram(FALSE); - return mode; -} - -void OSSetProgressiveMode(u32 mode) -{ - OSSram* sram; - mode <<= 7; - mode &= 0x80; - - sram = __OSLockSramHACK(); - if (mode == (sram->flags & 0x80)) - { - __OSUnlockSram(FALSE); - return; - } - - sram->flags &= ~0x80; - sram->flags |= mode; - __OSUnlockSram(TRUE); -} - -u8 OSGetLanguage() -{ - OSSram* sram; - u8 language; - - sram = __OSLockSramHACK(); - language = sram->language; - __OSUnlockSram(FALSE); - return language; -} - -u32 OSGetEuRgb60Mode() -{ - OSSram* sram; - u32 on; - sram = __OSLockSramHACK(); - on = (sram->ntd >> 6) & 0x1; - __OSUnlockSram(FALSE); - return on; -} - -void OSSetEuRgb60Mode(u32 mode) -{ - OSSram* sram; - mode <<= 6; - mode &= 0x40; - - sram = __OSLockSramHACK(); - if (mode == (sram->ntd & 0x40)) - { - __OSUnlockSram(FALSE); - return; - } - - sram->ntd &= ~0x40; - sram->ntd |= mode; - __OSUnlockSram(TRUE); -} - u16 OSGetWirelessID(s32 channel) { OSSramEx* sram; @@ -370,7 +302,7 @@ void OSSetGbsMode(u16 mode) sram = __OSLockSramEx(); if (mode == sram->gbs) { - __OSUnlockSramEx(FALSE); + UnlockSram(FALSE, FALSE); return; } diff --git a/libs/dolphin/os/OSThread.c b/libs/dolphin/os/OSThread.c index e0a46b506..4d3dddf37 100644 --- a/libs/dolphin/os/OSThread.c +++ b/libs/dolphin/os/OSThread.c @@ -149,7 +149,7 @@ OSThread* OSGetCurrentThread() return __OSCurrentThread; } -static void __OSSwitchThread(OSThread* nextThread) +inline void __OSSwitchThread(OSThread* nextThread) { OSSetCurrentThread(nextThread); OSSetCurrentContext(&nextThread->context); @@ -178,7 +178,7 @@ s32 OSEnableScheduler() return count; } -static void SetRun(OSThread* thread) +inline void SetRun(OSThread* thread) { thread->queue = &RunQueue[thread->priority]; AddTail(thread->queue, thread, link); @@ -241,7 +241,7 @@ static OSThread* SetEffectivePriority(OSThread* thread, OSPriority priority) return NULL; } -static void UpdatePriority(OSThread* thread) +inline void UpdatePriority(OSThread* thread) { OSPriority priority; From b9f640b9f6b11d61a94ef07cb9152841d6bb78d6 Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Tue, 27 May 2025 13:15:10 -0400 Subject: [PATCH 16/19] WChar test --- configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.py b/configure.py index 11f42aaa6..d6c21939a 100644 --- a/configure.py +++ b/configure.py @@ -189,6 +189,7 @@ "-Cpp_exceptions off", "-W err", # "-W all", + "-wchar_t on", "-O4,p", "-inline auto", '-pragma "cats off"', @@ -205,7 +206,6 @@ "-i libs", f"-i build/{config.version}/include", f"-DBUILD_VERSION={version_num}", - f"-DBUILD_VERSION{version_num}", # test for github f"-DVERSION_{config.version}", ] From 1c3dd1b7847fa3d10e222c118167b299266316a4 Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Tue, 27 May 2025 13:23:57 -0400 Subject: [PATCH 17/19] CI test 3 --- configure.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/configure.py b/configure.py index d6c21939a..b66907de9 100644 --- a/configure.py +++ b/configure.py @@ -189,7 +189,6 @@ "-Cpp_exceptions off", "-W err", # "-W all", - "-wchar_t on", "-O4,p", "-inline auto", '-pragma "cats off"', @@ -905,7 +904,7 @@ def MatchingFor(*versions): Object(Matching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s"), Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c"), - Object(Matching, "debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s"), + Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s"), Object(Matching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/usr_put.c"), From 74886072e280bb4b79f564bb34545067586a874c Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Tue, 27 May 2025 13:30:57 -0400 Subject: [PATCH 18/19] ci test 4 --- config/GQPE78/splits.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/GQPE78/splits.txt b/config/GQPE78/splits.txt index dd9a38a4a..5903819e7 100644 --- a/config/GQPE78/splits.txt +++ b/config/GQPE78/splits.txt @@ -3217,10 +3217,10 @@ debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c: .data start:0x802B7628 end:0x802B7658 .bss start:0x80380CD0 end:0x80381250 -debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s: comment:0 +debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s: .text start:0x801F5760 end:0x801F5780 -debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s: comment:0 +debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s: .init start:0x800035E4 end:0x80005518 debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c: From 7040d1bb34a2eab11a4f4151bfefe752552dfd16 Mon Sep 17 00:00:00 2001 From: Colin Miller Date: Tue, 27 May 2025 13:33:45 -0400 Subject: [PATCH 19/19] Commented out the .s files. Workflow needs fixed --- config/GQPE78/splits.txt | 4 ++-- configure.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/GQPE78/splits.txt b/config/GQPE78/splits.txt index 5903819e7..dd9a38a4a 100644 --- a/config/GQPE78/splits.txt +++ b/config/GQPE78/splits.txt @@ -3217,10 +3217,10 @@ debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c: .data start:0x802B7628 end:0x802B7658 .bss start:0x80380CD0 end:0x80381250 -debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s: +debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s: comment:0 .text start:0x801F5760 end:0x801F5780 -debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s: +debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s: comment:0 .init start:0x800035E4 end:0x80005518 debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c: diff --git a/configure.py b/configure.py index b66907de9..beee995c9 100644 --- a/configure.py +++ b/configure.py @@ -902,9 +902,9 @@ def MatchingFor(*versions): Object(NonMatching, "debugger/embedded/MetroTRK/Portable/mem_TRK.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/string_TRK.c"), Object(Matching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s"), + #Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s"), Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s"), + #Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s"), Object(Matching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/usr_put.c"),